* 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.
This commit is contained in:
Alan Modra 2006-05-03 23:52:15 +00:00
parent 14b3d9c967
commit c9049d301b
7 changed files with 454 additions and 508 deletions

View file

@ -1,3 +1,34 @@
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> 2006-05-03 Alan Modra <amodra@bigpond.net.au>
* subsegs.c (subseg_get): Don't call obj_sec_set_private_data. * subsegs.c (subseg_get): Don't call obj_sec_set_private_data.

View file

@ -6954,8 +6954,10 @@ static void
xtensa_cleanup_align_frags (void) xtensa_cleanup_align_frags (void)
{ {
frchainS *frchP; frchainS *frchP;
asection *s;
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
/* Walk over all of the fragments in a subsection. */ /* Walk over all of the fragments in a subsection. */
@ -7004,10 +7006,12 @@ static void
xtensa_fix_target_frags (void) xtensa_fix_target_frags (void)
{ {
frchainS *frchP; frchainS *frchP;
asection *s;
/* When this routine is called, all of the subsections are still intact /* When this routine is called, all of the subsections are still intact
so we walk over subsections instead of sections. */ so we walk over subsections instead of sections. */
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
@ -7033,8 +7037,10 @@ static void
xtensa_mark_narrow_branches (void) xtensa_mark_narrow_branches (void)
{ {
frchainS *frchP; frchainS *frchP;
asection *s;
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
/* Walk over all of the fragments in a subsection. */ /* Walk over all of the fragments in a subsection. */
@ -7119,8 +7125,10 @@ static void
xtensa_mark_zcl_first_insns (void) xtensa_mark_zcl_first_insns (void)
{ {
frchainS *frchP; frchainS *frchP;
asection *s;
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
/* Walk over all of the fragments in a subsection. */ /* Walk over all of the fragments in a subsection. */
@ -7175,10 +7183,12 @@ static void
xtensa_fix_a0_b_retw_frags (void) xtensa_fix_a0_b_retw_frags (void)
{ {
frchainS *frchP; frchainS *frchP;
asection *s;
/* When this routine is called, all of the subsections are still intact /* When this routine is called, all of the subsections are still intact
so we walk over subsections instead of sections. */ so we walk over subsections instead of sections. */
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
@ -7285,10 +7295,12 @@ static void
xtensa_fix_b_j_loop_end_frags (void) xtensa_fix_b_j_loop_end_frags (void)
{ {
frchainS *frchP; frchainS *frchP;
asection *s;
/* When this routine is called, all of the subsections are still intact /* When this routine is called, all of the subsections are still intact
so we walk over subsections instead of sections. */ so we walk over subsections instead of sections. */
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
@ -7349,10 +7361,12 @@ static void
xtensa_fix_close_loop_end_frags (void) xtensa_fix_close_loop_end_frags (void)
{ {
frchainS *frchP; frchainS *frchP;
asection *s;
/* When this routine is called, all of the subsections are still intact /* When this routine is called, all of the subsections are still intact
so we walk over subsections instead of sections. */ so we walk over subsections instead of sections. */
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
@ -7512,10 +7526,12 @@ static void
xtensa_fix_short_loop_frags (void) xtensa_fix_short_loop_frags (void)
{ {
frchainS *frchP; frchainS *frchP;
asection *s;
/* When this routine is called, all of the subsections are still intact /* When this routine is called, all of the subsections are still intact
so we walk over subsections instead of sections. */ so we walk over subsections instead of sections. */
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
fragS *current_target = NULL; fragS *current_target = NULL;
@ -7697,11 +7713,12 @@ xtensa_sanity_check (void)
{ {
char *file_name; char *file_name;
unsigned line; unsigned line;
frchainS *frchP; frchainS *frchP;
asection *s;
as_where (&file_name, &line); as_where (&file_name, &line);
for (frchP = frchain_root; frchP; frchP = frchP->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (frchP = seg_info (s)->frchainP; frchP; frchP = frchP->frch_next)
{ {
fragS *fragP; fragS *fragP;
@ -10384,7 +10401,6 @@ retrieve_segment_info (segT seg)
frchainP->frch_root = NULL; frchainP->frch_root = NULL;
frchainP->frch_last = NULL; frchainP->frch_last = NULL;
frchainP->frch_next = NULL; frchainP->frch_next = NULL;
frchainP->frch_seg = seg;
frchainP->frch_subseg = 0; frchainP->frch_subseg = 0;
frchainP->fix_root = NULL; frchainP->fix_root = NULL;
frchainP->fix_tail = NULL; frchainP->fix_tail = NULL;

View file

@ -1,5 +1,5 @@
/* This file is debug.c /* 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. Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler. This file is part of GAS, the GNU Assembler.
@ -25,12 +25,14 @@
dmp_frags () dmp_frags ()
{ {
asection *s;
frchainS *chp; frchainS *chp;
char *p; char *p;
for (chp = frchain_root; chp; chp = chp->frch_next) for (s = stdoutput->sections; s; s = s->next)
for (chp = seg_info (s)->frchainP; chp; chp = chp->frch_next)
{ {
switch (chp->frch_seg) switch (s)
{ {
case SEG_DATA: case SEG_DATA:
p = "Data"; p = "Data";

View file

@ -169,7 +169,7 @@ static void out_two (int);
static void out_four (int); static void out_four (int);
static void out_abbrev (int, int); static void out_abbrev (int, int);
static void out_uleb128 (addressT); 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 void out_set_addr (symbolS *);
static int size_inc_line_addr (int, addressT); static int size_inc_line_addr (int, addressT);
static void emit_inc_line_addr (int, addressT, char *, int); 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 * static struct frag *
first_frag_for_seg (segT seg) first_frag_for_seg (segT seg)
{ {
frchainS *f, *first = NULL; return seg_info (seg)->frchainP->frch_root;
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;
} }
static struct frag * static struct frag *
last_frag_for_seg (segT seg) 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) while (f->frch_next != NULL)
if (f->frch_seg == seg f = f->frch_next;
&& (! last || last->frch_subseg < f->frch_subseg))
last= f;
return last ? last->frch_last : NULL; return f->frch_last;
} }
/* Emit a single byte into the current segment. */ /* Emit a single byte into the current segment. */
@ -745,7 +736,7 @@ out_abbrev (int name, int form)
/* Get the size of a fragment. */ /* Get the size of a fragment. */
static offsetT static offsetT
get_frag_fix (fragS *frag) get_frag_fix (fragS *frag, segT seg)
{ {
frchainS *fr; frchainS *fr;
@ -755,7 +746,7 @@ get_frag_fix (fragS *frag)
/* If a fragment is the last in the chain, special measures must be /* 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 taken to find its size before relaxation, since it may be pending
on some subsegment chain. */ 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) if (fr->frch_last == frag)
return (char *) obstack_next_free (&fr->frch_obstack) - frag->fr_literal; 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. */ /* Emit a DW_LNE_end_sequence for the end of the section. */
frag = last_frag_for_seg (seg); frag = last_frag_for_seg (seg);
frag_ofs = get_frag_fix (frag); frag_ofs = get_frag_fix (frag, seg);
if (frag == last_frag) if (frag == last_frag)
out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs); out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs);
else else
@ -1332,7 +1323,7 @@ out_debug_aranges (segT aranges_seg, segT info_seg)
s->text_start = beg; s->text_start = beg;
frag = last_frag_for_seg (s->seg); 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; s->text_end = end;
expr.X_op = O_symbol; expr.X_op = O_symbol;

View file

@ -27,20 +27,12 @@
#include "subsegs.h" #include "subsegs.h"
#include "obstack.h" #include "obstack.h"
frchainS *frchain_root, *frchain_now; frchainS *frchain_now;
static struct obstack frchains; 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 fragS dummy_frag;
static frchainS absolute_frchain;
void void
subsegs_begin (void) subsegs_begin (void)
@ -50,16 +42,8 @@ subsegs_begin (void)
obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1; obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
#endif #endif
frchain_root = NULL;
frchain_now = NULL; /* Warn new_subseg() that we are booting. */ frchain_now = NULL; /* Warn new_subseg() that we are booting. */
frag_now = &dummy_frag; 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 void
subseg_change (register segT seg, register int subseg) subseg_change (register segT seg, register int subseg)
{ {
segment_info_type *seginfo; segment_info_type *seginfo = seg_info (seg);
now_seg = seg; now_seg = seg;
now_subseg = subseg; now_subseg = subseg;
if (now_seg == absolute_section)
return;
seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg);
if (! seginfo) if (! seginfo)
{ {
seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo)); seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
@ -91,11 +71,6 @@ subseg_change (register segT seg, register int subseg)
seginfo->fix_tail = NULL; seginfo->fix_tail = NULL;
seginfo->bfd_section = seg; seginfo->bfd_section = seg;
seginfo->sym = 0; 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);
} }
} }
@ -103,9 +78,10 @@ subseg_change (register segT seg, register int subseg)
static void static void
subseg_set_rest (segT seg, subsegT subseg) subseg_set_rest (segT seg, subsegT subseg)
{ {
register frchainS *frcP; /* crawl frchain chain */ frchainS *frcP; /* crawl frchain chain */
register frchainS **lastPP; /* address of last pointer */ frchainS **lastPP; /* address of last pointer */
frchainS *newP; /* address of new frchain */ frchainS *newP; /* address of new frchain */
segment_info_type *seginfo;
mri_common_symbol = NULL; mri_common_symbol = NULL;
@ -113,72 +89,26 @@ subseg_set_rest (segT seg, subsegT subseg)
frchain_now->frch_frag_now = frag_now; frchain_now->frch_frag_now = frag_now;
assert (frchain_now == 0 assert (frchain_now == 0
|| now_seg == undefined_section
|| now_seg == absolute_section
|| frchain_now->frch_last == frag_now); || frchain_now->frch_last == frag_now);
subseg_change (seg, (int) subseg); subseg_change (seg, (int) subseg);
if (seg == absolute_section) seginfo = seg_info (seg);
{
frchain_now = &absolute_frchain;
frag_now = &zero_address_frag;
return;
}
assert (frchain_now == 0 /* Attempt to find or make a frchain for that subsection.
|| now_seg == undefined_section We keep the list sorted by subsection number. */
|| frchain_now->frch_last == frag_now); for (frcP = *(lastPP = &seginfo->frchainP);
frcP != NULL;
/*
* 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;
frcP = *(lastPP = &frcP->frch_next)) frcP = *(lastPP = &frcP->frch_next))
{ if (frcP->frch_subseg >= subseg)
if (frcP->frch_seg == seg
&& frcP->frch_subseg >= subseg)
{
break; break;
}
} if (frcP == NULL || frcP->frch_subseg != subseg)
/*
* 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. */
* This should be the only code that creates a frchainS.
*/
segment_info_type *seginfo;
newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS)); newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
newP->frch_subseg = subseg; newP->frch_subseg = subseg;
newP->frch_seg = seg;
newP->fix_root = NULL; newP->fix_root = NULL;
newP->fix_tail = NULL; newP->fix_tail = NULL;
obstack_begin (&newP->frch_obstack, chunksize); 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; newP->frch_root = newP->frch_last = newP->frch_frag_now;
*lastPP = newP; *lastPP = newP;
newP->frch_next = frcP; /* perhaps NULL */ newP->frch_next = frcP;
seginfo = seg_info (seg);
if (seginfo && (!seginfo->frchainP || seginfo->frchainP == frcP))
seginfo->frchainP = newP;
frcP = newP; frcP = newP;
} }
/*
* Here with frcP pointing to the frchainS for subseg.
*/
frchain_now = frcP; frchain_now = frcP;
frag_now = frcP->frch_frag_now; frag_now = frcP->frch_frag_now;
@ -221,7 +144,6 @@ subseg_set_rest (segT seg, subsegT subseg)
* Out: now_subseg, now_seg updated. * Out: now_subseg, now_seg updated.
* Frchain_now points to the (possibly new) struct frchain for this * Frchain_now points to the (possibly new) struct frchain for this
* sub-segment. * sub-segment.
* Frchain_root updated if needed.
*/ */
segT segT
@ -247,20 +169,12 @@ subseg_get (const char *segname, int force_new)
seginfo = seg_info (secptr); seginfo = seg_info (secptr);
if (! seginfo) 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)); seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo));
memset ((PTR) seginfo, 0, sizeof (*seginfo)); memset ((PTR) seginfo, 0, sizeof (*seginfo));
seginfo->fix_root = NULL; seginfo->fix_root = NULL;
seginfo->fix_tail = NULL; seginfo->fix_tail = NULL;
seginfo->bfd_section = secptr; 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->frchainP = NULL;
seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL; seginfo->lineno_list_head = seginfo->lineno_list_tail = NULL;
@ -274,13 +188,9 @@ segT
subseg_new (const char *segname, subsegT subseg) subseg_new (const char *segname, subsegT subseg)
{ {
segT secptr; segT secptr;
segment_info_type *seginfo;
secptr = subseg_get (segname, 0); secptr = subseg_get (segname, 0);
subseg_set_rest (secptr, subseg); subseg_set_rest (secptr, subseg);
seginfo = seg_info (secptr);
if (! seginfo->frchainP)
seginfo->frchainP = frchain_now;
return secptr; return secptr;
} }
@ -290,13 +200,9 @@ segT
subseg_force_new (const char *segname, subsegT subseg) subseg_force_new (const char *segname, subsegT subseg)
{ {
segT secptr; segT secptr;
segment_info_type *seginfo;
secptr = subseg_get (segname, 1); secptr = subseg_get (segname, 1);
subseg_set_rest (secptr, subseg); subseg_set_rest (secptr, subseg);
seginfo = seg_info (secptr);
if (! seginfo->frchainP)
seginfo->frchainP = frchain_now;
return secptr; return secptr;
} }
@ -312,19 +218,6 @@ subseg_set (segT secptr, subsegT subseg)
#define obj_sec_sym_ok_for_reloc(SEC) 0 #define obj_sec_sym_ok_for_reloc(SEC) 0
#endif #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 * symbolS *
section_symbol (segT sec) section_symbol (segT sec)
{ {
@ -414,28 +307,33 @@ void
subsegs_print_statistics (FILE *file) subsegs_print_statistics (FILE *file)
{ {
frchainS *frchp; frchainS *frchp;
asection *s;
fprintf (file, "frag chains:\n"); fprintf (file, "frag chains:\n");
for (frchp = frchain_root; frchp; frchp = frchp->frch_next) for (s = stdoutput->sections; s; s = s->next)
{
segment_info_type *seginfo;
/* Skip gas-internal sections. */
if (segment_name (s)[0] == '*')
continue;
seginfo = seg_info (s);
if (!seginfo)
continue;
for (frchp = seginfo->frchainP; frchp; frchp = frchp->frch_next)
{ {
int count = 0; int count = 0;
fragS *fragp; fragS *fragp;
/* 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)
continue;
/* Skip gas-internal sections. */
if (segment_name (frchp->frch_seg)[0] == '*')
continue;
for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next) for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
{
count++; count++;
}
fprintf (file, "\n"); fprintf (file, "\n");
fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp, fprintf (file, "\t%p %-10s\t%10d frags\n", (void *) frchp,
segment_name (frchp->frch_seg), count); segment_name (s), count);
}
} }
} }

View file

@ -1,6 +1,6 @@
/* subsegs.h -> subsegs.c /* subsegs.h -> subsegs.c
Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2003, 2005 Copyright 1987, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2003, 2005,
Free Software Foundation, Inc. 2006 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler. 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_root; /* 1st struct frag in chain, or NULL */
struct frag *frch_last; /* last 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 */ 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 */ subsegT frch_subseg; /* subsegment number of this chain */
fixS *fix_root; /* Root of fixups for this subsegment. */ fixS *fix_root; /* Root of fixups for this subsegment. */
fixS *fix_tail; /* Last fixup 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; 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 /* Frchain we are assembling into now. That is, the current segment's
frag chain, even if it contains no (complete) frags. */ frag chain, even if it contains no (complete) frags. */
extern frchainS *frchain_now; extern frchainS *frchain_now;
@ -109,7 +105,10 @@ typedef struct segment_info_struct {
#endif #endif
} segment_info_type; } 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 symbolS *section_symbol (segT);
extern void subsegs_print_statistics (FILE *); extern void subsegs_print_statistics (FILE *);

View file

@ -1,6 +1,6 @@
/* write.c - emit .o file /* write.c - emit .o file
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 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. Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler. 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; fragS dummy, *prev_frag = &dummy;
fixS fix_dummy, *prev_fix = &fix_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->fr_next = frchp->frch_root;
prev_frag = frchp->frch_last; prev_frag = frchp->frch_last;
@ -1136,8 +1136,7 @@ set_symtab (void)
of the section. This allows proper nop-filling at the end of of the section. This allows proper nop-filling at the end of
code-bearing sections. */ code-bearing sections. */
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \ #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
(!(FRCHAIN)->frch_next || (FRCHAIN)->frch_next->frch_seg != (SEG) \ (!(FRCHAIN)->frch_next ? get_recorded_alignment (SEG) : 0)
? get_recorded_alignment (SEG) : 0)
#else #else
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
#endif #endif
@ -1147,12 +1146,21 @@ void
subsegs_finish (void) subsegs_finish (void)
{ {
struct frchain *frchainP; struct frchain *frchainP;
asection *s;
for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next) for (s = stdoutput->sections; s; s = s->next)
{
segment_info_type *seginfo = seg_info (s);
if (!seginfo)
continue;
for (frchainP = seginfo->frchainP;
frchainP != NULL;
frchainP = frchainP->frch_next)
{ {
int alignment = 0; int alignment = 0;
subseg_set (frchainP->frch_seg, frchainP->frch_subseg); subseg_set (s, frchainP->frch_subseg);
/* This now gets called even if we had errors. In that case, /* This now gets called even if we had errors. In that case,
any alignment is meaningless, and, moreover, will look weird any alignment is meaningless, and, moreover, will look weird
@ -1191,6 +1199,7 @@ subsegs_finish (void)
know (frag_now->fr_next == NULL); know (frag_now->fr_next == NULL);
} }
} }
}
/* Write the object file. */ /* Write the object file. */