Commit c9049d30 authored by Alan Modra's avatar Alan Modra

* subsegs.h (struct frchain): Delete frch_seg.

	(frchain_root): Delete.
	(seg_info): Define as macro.
	* subsegs.c (frchain_root): Delete.
	(abs_seg_info, und_seg_info, absolute_frchain): Delete.
	(subsegs_begin, subseg_change): Adjust for above.
	(subseg_set_rest): Likewise.  Add new frchain structs to seginfo
	rather than to one big list.
	(subseg_get): Don't special case abs, und sections.
	(subseg_new, subseg_force_new): Don't set frchainP here.
	(seg_info): Delete.
	(subsegs_print_statistics): Adjust frag chain control list traversal.
	* debug.c (dmp_frags):  Likewise.
	* dwarf2dbg.c (first_frag_for_seg): Don't start looking for frag
	at frchain_root.  Make use of known frchain ordering.
	(last_frag_for_seg): Likewise.
	(get_frag_fix): Likewise.  Add seg param.
	(process_entries, out_debug_aranges): Adjust get_frag_fix calls.
	* write.c (chain_frchains_together_1): Adjust for struct frchain.
	(SUB_SEGMENT_ALIGN): Likewise.
	(subsegs_finish): Adjust frchain list traversal.
	* config/tc-xtensa.c (xtensa_cleanup_align_frags): Likewise.
	(xtensa_fix_target_frags, xtensa_mark_narrow_branches): Likewise.
	(xtensa_mark_zcl_first_insns, xtensa_fix_a0_b_retw_frags): Likewise.
	(xtensa_fix_b_j_loop_end_frags): Likewise.
	(xtensa_fix_close_loop_end_frags): Likewise.
	(xtensa_fix_short_loop_frags, xtensa_sanity_check): Likewise.
	(retrieve_segment_info): Delete frch_seg initialisation.
parent 14b3d9c9
2006-05-04 Alan Modra <amodra@bigpond.net.au>
* subsegs.h (struct frchain): Delete frch_seg.
(frchain_root): Delete.
(seg_info): Define as macro.
* subsegs.c (frchain_root): Delete.
(abs_seg_info, und_seg_info, absolute_frchain): Delete.
(subsegs_begin, subseg_change): Adjust for above.
(subseg_set_rest): Likewise. Add new frchain structs to seginfo
rather than to one big list.
(subseg_get): Don't special case abs, und sections.
(subseg_new, subseg_force_new): Don't set frchainP here.
(seg_info): Delete.
(subsegs_print_statistics): Adjust frag chain control list traversal.
* debug.c (dmp_frags): Likewise.
* dwarf2dbg.c (first_frag_for_seg): Don't start looking for frag
at frchain_root. Make use of known frchain ordering.
(last_frag_for_seg): Likewise.
(get_frag_fix): Likewise. Add seg param.
(process_entries, out_debug_aranges): Adjust get_frag_fix calls.
* write.c (chain_frchains_together_1): Adjust for struct frchain.
(SUB_SEGMENT_ALIGN): Likewise.
(subsegs_finish): Adjust frchain list traversal.
* config/tc-xtensa.c (xtensa_cleanup_align_frags): Likewise.
(xtensa_fix_target_frags, xtensa_mark_narrow_branches): Likewise.
(xtensa_mark_zcl_first_insns, xtensa_fix_a0_b_retw_frags): Likewise.
(xtensa_fix_b_j_loop_end_frags): Likewise.
(xtensa_fix_close_loop_end_frags): Likewise.
(xtensa_fix_short_loop_frags, xtensa_sanity_check): Likewise.
(retrieve_segment_info): Delete frch_seg initialisation.
2006-05-03 Alan Modra <amodra@bigpond.net.au>
* subsegs.c (subseg_get): Don't call obj_sec_set_private_data.
......
This diff is collapsed.
/* This file is debug.c
Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2000
Copyright 1987, 1988, 1989, 1990, 1991, 1992, 2000, 2006
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
......@@ -25,26 +25,28 @@
dmp_frags ()
{
asection *s;
frchainS *chp;
char *p;
for (chp = frchain_root; chp; chp = chp->frch_next)
{
switch (chp->frch_seg)
{
case SEG_DATA:
p = "Data";
break;
case SEG_TEXT:
p = "Text";
break;
default:
p = "???";
break;
}
printf ("\nSEGMENT %s %d\n", p, chp->frch_subseg);
dmp_frag (chp->frch_root, "\t");
}
for (s = stdoutput->sections; s; s = s->next)
for (chp = seg_info (s)->frchainP; chp; chp = chp->frch_next)
{
switch (s)
{
case SEG_DATA:
p = "Data";
break;
case SEG_TEXT:
p = "Text";
break;
default:
p = "???";
break;
}
printf ("\nSEGMENT %s %d\n", p, chp->frch_subseg);
dmp_frag (chp->frch_root, "\t");
}
}
dmp_frag (fp, indent)
......
......@@ -169,7 +169,7 @@ static void out_two (int);
static void out_four (int);
static void out_abbrev (int, int);
static void out_uleb128 (addressT);
static offsetT get_frag_fix (fragS *);
static offsetT get_frag_fix (fragS *, segT);
static void out_set_addr (symbolS *);
static int size_inc_line_addr (int, addressT);
static void emit_inc_line_addr (int, addressT, char *, int);
......@@ -670,27 +670,18 @@ dwarf2_directive_loc_mark_labels (int dummy ATTRIBUTE_UNUSED)
static struct frag *
first_frag_for_seg (segT seg)
{
frchainS *f, *first = NULL;
for (f = frchain_root; f; f = f->frch_next)
if (f->frch_seg == seg
&& (! first || first->frch_subseg > f->frch_subseg))
first = f;
return first ? first->frch_root : NULL;
return seg_info (seg)->frchainP->frch_root;
}
static struct frag *
last_frag_for_seg (segT seg)
{
frchainS *f, *last = NULL;
frchainS *f = seg_info (seg)->frchainP;
for (f = frchain_root; f; f = f->frch_next)
if (f->frch_seg == seg
&& (! last || last->frch_subseg < f->frch_subseg))
last= f;
while (f->frch_next != NULL)
f = f->frch_next;
return last ? last->frch_last : NULL;
return f->frch_last;
}
/* Emit a single byte into the current segment. */
......@@ -745,7 +736,7 @@ out_abbrev (int name, int form)
/* Get the size of a fragment. */
static offsetT
get_frag_fix (fragS *frag)
get_frag_fix (fragS *frag, segT seg)
{
frchainS *fr;
......@@ -755,7 +746,7 @@ get_frag_fix (fragS *frag)
/* If a fragment is the last in the chain, special measures must be
taken to find its size before relaxation, since it may be pending
on some subsegment chain. */
for (fr = frchain_root; fr; fr = fr->frch_next)
for (fr = seg_info (seg)->frchainP; fr; fr = fr->frch_next)
if (fr->frch_last == frag)
return (char *) obstack_next_free (&fr->frch_obstack) - frag->fr_literal;
......@@ -1134,7 +1125,7 @@ process_entries (segT seg, struct line_entry *e)
/* Emit a DW_LNE_end_sequence for the end of the section. */
frag = last_frag_for_seg (seg);
frag_ofs = get_frag_fix (frag);
frag_ofs = get_frag_fix (frag, seg);
if (frag == last_frag)
out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs);
else
......@@ -1332,7 +1323,7 @@ out_debug_aranges (segT aranges_seg, segT info_seg)
s->text_start = beg;
frag = last_frag_for_seg (s->seg);
end = symbol_temp_new (s->seg, get_frag_fix (frag), frag);
end = symbol_temp_new (s->seg, get_frag_fix (frag, s->seg), frag);
s->text_end = end;
expr.X_op = O_symbol;
......
......@@ -27,20 +27,12 @@
#include "subsegs.h"
#include "obstack.h"
frchainS *frchain_root, *frchain_now;
frchainS *frchain_now;
static struct obstack frchains;
/* Gas segment information for bfd_abs_section_ptr and
bfd_und_section_ptr. */
static segment_info_type *abs_seg_info;
static segment_info_type *und_seg_info;
static void subseg_set_rest (segT, subsegT);
static fragS dummy_frag;
static frchainS absolute_frchain;
void
subsegs_begin (void)
......@@ -50,16 +42,8 @@ subsegs_begin (void)
obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
#endif
frchain_root = NULL;
frchain_now = NULL; /* Warn new_subseg() that we are booting. */
frag_now = &dummy_frag;
absolute_frchain.frch_seg = absolute_section;
absolute_frchain.frch_subseg = 0;
absolute_frchain.fix_root = absolute_frchain.fix_tail = 0;
absolute_frchain.frch_frag_now = &zero_address_frag;
absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag;
}
/*
......@@ -75,14 +59,10 @@ subsegs_begin (void)
void
subseg_change (register segT seg, register int subseg)
{
segment_info_type *seginfo;
segment_info_type *seginfo = seg_info (seg);
now_seg = seg;
now_subseg = subseg;
if (now_seg == absolute_section)
return;
seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg);
if (! seginfo)
{
seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
......@@ -91,21 +71,17 @@ subseg_change (register segT seg, register int subseg)
seginfo->fix_tail = NULL;
seginfo->bfd_section = seg;
seginfo->sym = 0;
if (seg == bfd_abs_section_ptr)
abs_seg_info = seginfo;
else if (seg == bfd_und_section_ptr)
und_seg_info = seginfo;
else
bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo);
bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo);
}
}
static void
subseg_set_rest (segT seg, subsegT subseg)
{
register frchainS *frcP; /* crawl frchain chain */
register frchainS **lastPP; /* address of last pointer */
frchainS *frcP; /* crawl frchain chain */
frchainS **lastPP; /* address of last pointer */
frchainS *newP; /* address of new frchain */
segment_info_type *seginfo;
mri_common_symbol = NULL;
......@@ -113,72 +89,26 @@ subseg_set_rest (segT seg, subsegT subseg)
frchain_now->frch_frag_now = frag_now;
assert (frchain_now == 0
|| now_seg == undefined_section
|| now_seg == absolute_section
|| frchain_now->frch_last == frag_now);
subseg_change (seg, (int) subseg);
if (seg == absolute_section)
{
frchain_now = &absolute_frchain;
frag_now = &zero_address_frag;
return;
}
assert (frchain_now == 0
|| now_seg == undefined_section
|| frchain_now->frch_last == frag_now);
seginfo = seg_info (seg);
/*
* Attempt to find or make a frchain for that sub seg.
* Crawl along chain of frchainSs, begins @ frchain_root.
* If we need to make a frchainS, link it into correct
* position of chain rooted in frchain_root.
*/
for (frcP = *(lastPP = &frchain_root);
frcP && frcP->frch_seg <= seg;
/* Attempt to find or make a frchain for that subsection.
We keep the list sorted by subsection number. */
for (frcP = *(lastPP = &seginfo->frchainP);
frcP != NULL;
frcP = *(lastPP = &frcP->frch_next))
if (frcP->frch_subseg >= subseg)
break;
if (frcP == NULL || frcP->frch_subseg != subseg)
{
if (frcP->frch_seg == seg
&& frcP->frch_subseg >= subseg)
{
break;
}
}
/*
* frcP: Address of the 1st frchainS in correct segment with
* frch_subseg >= subseg.
* We want to either use this frchainS, or we want
* to insert a new frchainS just before it.
*
* If frcP==NULL, then we are at the end of the chain
* of frchainS-s. A NULL frcP means we fell off the end
* of the chain looking for a
* frch_subseg >= subseg, so we
* must make a new frchainS.
*
* If we ever maintain a pointer to
* the last frchainS in the chain, we change that pointer
* ONLY when frcP==NULL.
*
* lastPP: Address of the pointer with value frcP;
* Never NULL.
* May point to frchain_root.
*
*/
if (!frcP
|| (frcP->frch_seg > seg
|| frcP->frch_subseg > subseg)) /* Kinky logic only works with 2 segments. */
{
/*
* This should be the only code that creates a frchainS.
*/
segment_info_type *seginfo;
/* This should be the only code that creates a frchainS. */
newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
newP->frch_subseg = subseg;
newP->frch_seg = seg;
newP->fix_root = NULL;
newP->fix_tail = NULL;
obstack_begin (&newP->frch_obstack, chunksize);
......@@ -191,17 +121,10 @@ subseg_set_rest (segT seg, subsegT subseg)
newP->frch_root = newP->frch_last = newP->frch_frag_now;
*lastPP = newP;
newP->frch_next = frcP; /* perhaps NULL */
seginfo = seg_info (seg);
if (seginfo && (!seginfo->frchainP || seginfo->frchainP == frcP))
seginfo->frchainP = newP;
newP->frch_next = frcP;
frcP = newP;
}
/*
* Here with frcP pointing to the frchainS for subseg.
*/
frchain_now = frcP;
frag_now = frcP->frch_frag_now;
......@@ -221,7 +144,6 @@ subseg_set_rest (segT seg, subsegT subseg)
* Out: now_subseg, now_seg updated.
* Frchain_now points to the (possibly new) struct frchain for this
* sub-segment.
* Frchain_root updated if needed.
*/
segT
......@@ -247,21 +169,13 @@ subseg_get (const char *segname, int force_new)
seginfo = seg_info (secptr);
if (! seginfo)
{
/* Check whether output_section is set first because secptr may
be bfd_abs_section_ptr. */
if (secptr->output_section != secptr)
secptr->output_section = secptr;
secptr->output_section = secptr;
seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
memset ((PTR) seginfo, 0, sizeof (*seginfo));
seginfo->fix_root = NULL;
seginfo->fix_tail = NULL;
seginfo->bfd_section = secptr;
if (secptr == bfd_abs_section_ptr)
abs_seg_info = seginfo;
else if (secptr == bfd_und_section_ptr)
und_seg_info = seginfo;
else
bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo);
bfd_set_section_userdata (stdoutput, secptr, (PTR) seginfo);
seginfo->frchainP = NULL;
seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL;
seginfo->sym = NULL;
......@@ -274,13 +188,9 @@ segT
subseg_new (const char *segname, subsegT subseg)
{
segT secptr;
segment_info_type *seginfo;
secptr = subseg_get (segname, 0);
subseg_set_rest (secptr, subseg);
seginfo = seg_info (secptr);
if (! seginfo->frchainP)
seginfo->frchainP = frchain_now;
return secptr;
}
......@@ -290,13 +200,9 @@ segT
subseg_force_new (const char *segname, subsegT subseg)
{
segT secptr;
segment_info_type *seginfo;
secptr = subseg_get (segname, 1);
subseg_set_rest (secptr, subseg);
seginfo = seg_info (secptr);
if (! seginfo->frchainP)
seginfo->frchainP = frchain_now;
return secptr;
}
......@@ -312,19 +218,6 @@ subseg_set (segT secptr, subsegT subseg)
#define obj_sec_sym_ok_for_reloc(SEC) 0
#endif
/* Get the gas information we are storing for a section. */
segment_info_type *
seg_info (segT sec)
{
if (sec == bfd_abs_section_ptr)
return abs_seg_info;
else if (sec == bfd_und_section_ptr)
return und_seg_info;
else
return (segment_info_type *) bfd_get_section_userdata (stdoutput, sec);
}
symbolS *
section_symbol (segT sec)
{
......@@ -414,28 +307,33 @@ void
subsegs_print_statistics (FILE *file)
{
frchainS *frchp;
asection *s;
fprintf (file, "frag chains:\n");
for (frchp = frchain_root; frchp; frchp = frchp->frch_next)
for (s = stdoutput->sections; s; s = s->next)
{
int count = 0;
fragS *fragp;
segment_info_type *seginfo;
/* If frch_subseg is non-zero, it's probably been chained onto
the end of a previous subsection. Don't count it again. */
if (frchp->frch_subseg != 0)
/* Skip gas-internal sections. */
if (segment_name (s)[0] == '*')
continue;
/* Skip gas-internal sections. */
if (segment_name (frchp->frch_seg)[0] == '*')
seginfo = seg_info (s);
if (!seginfo)
continue;
for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
for (frchp = seginfo->frchainP; frchp; frchp = frchp->frch_next)
{
count++;
int count = 0;
fragS *fragp;
for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
count++;
fprintf (file, "\n");
fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp,
segment_name (s), count);
}
fprintf (file, "\n");
fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp,
segment_name (frchp->frch_seg), count);
}
}
......
/* subsegs.h -> subsegs.c
Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2003, 2005
Free Software Foundation, Inc.
Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2003, 2005,
2006 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
......@@ -45,7 +45,6 @@ struct frchain /* control building of a frag chain */
struct frag *frch_root; /* 1st struct frag in chain, or NULL */
struct frag *frch_last; /* last struct frag in chain, or NULL */
struct frchain *frch_next; /* next in chain of struct frchain-s */
segT frch_seg; /* SEG_TEXT or SEG_DATA. */
subsegT frch_subseg; /* subsegment number of this chain */
fixS *fix_root; /* Root of fixups for this subsegment. */
fixS *fix_tail; /* Last fixup for this subsegment. */
......@@ -55,9 +54,6 @@ struct frchain /* control building of a frag chain */
typedef struct frchain frchainS;
/* All subsegments' chains hang off here. NULL means no frchains yet. */
extern frchainS *frchain_root;
/* Frchain we are assembling into now. That is, the current segment's
frag chain, even if it contains no (complete) frags. */
extern frchainS *frchain_now;
......@@ -109,7 +105,10 @@ typedef struct segment_info_struct {
#endif
} segment_info_type;
extern segment_info_type *seg_info (segT);
#define seg_info(sec) \
((segment_info_type *) bfd_get_section_userdata (stdoutput, sec))
extern symbolS *section_symbol (segT);
extern void subsegs_print_statistics (FILE *);
/* write.c - emit .o file
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
......@@ -379,7 +379,7 @@ chain_frchains_together_1 (segT section, struct frchain *frchp)
fragS dummy, *prev_frag = &dummy;
fixS fix_dummy, *prev_fix = &fix_dummy;
for (; frchp && frchp->frch_seg == section; frchp = frchp->frch_next)
for (; frchp; frchp = frchp->frch_next)
{
prev_frag->fr_next = frchp->frch_root;
prev_frag = frchp->frch_last;
......@@ -1136,8 +1136,7 @@ set_symtab (void)
of the section. This allows proper nop-filling at the end of
code-bearing sections. */
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
(!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \
? get_recorded_alignment (SEG) : 0)
(!(FRCHAIN)->frch_next ? get_recorded_alignment (SEG) : 0)
#else
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
#endif
......@@ -1147,48 +1146,58 @@ void
subsegs_finish (void)
{
struct frchain *frchainP;
asection *s;
for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
for (s = stdoutput->sections; s; s = s->next)
{
int alignment = 0;
segment_info_type *seginfo = seg_info (s);
if (!seginfo)
continue;
subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
/* This now gets called even if we had errors. In that case,
any alignment is meaningless, and, moreover, will look weird
if we are generating a listing. */
if (!had_errors ())
for (frchainP = seginfo->frchainP;
frchainP != NULL;
frchainP = frchainP->frch_next)
{
alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE)
&& now_seg->entsize)
{
unsigned int entsize = now_seg->entsize;
int entalign = 0;
int alignment = 0;
subseg_set (s, frchainP->frch_subseg);
while ((entsize & 1) == 0)
/* This now gets called even if we had errors. In that case,
any alignment is meaningless, and, moreover, will look weird
if we are generating a listing. */
if (!had_errors ())
{
alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE)
&& now_seg->entsize)
{
++entalign;
entsize >>= 1;
unsigned int entsize = now_seg->entsize;
int entalign = 0;
while ((entsize & 1) == 0)
{
++entalign;
entsize >>= 1;
}
if (entalign > alignment)
alignment = entalign;
}
if (entalign > alignment)
alignment = entalign;
}
}
if (subseg_text_p (now_seg))
frag_align_code (alignment, 0);
else
frag_align (alignment, 0, 0);
if (subseg_text_p (now_seg))
frag_align_code (alignment, 0);
else
frag_align (alignment, 0, 0);
/* frag_align will have left a new frag.
Use this last frag for an empty ".fill".
/* frag_align will have left a new frag.
Use this last frag for an empty ".fill".
For this segment ...
Create a last frag. Do not leave a "being filled in frag". */
frag_wane (frag_now);
frag_now->fr_fix = 0;
know (frag_now->fr_next == NULL);
For this segment ...
Create a last frag. Do not leave a "being filled in frag". */
frag_wane (frag_now);
frag_now->fr_fix = 0;
know (frag_now->fr_next == NULL);
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment