* 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:
parent
14b3d9c967
commit
c9049d301b
7 changed files with 454 additions and 508 deletions
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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;
|
||||||
|
|
170
gas/subsegs.c
170
gas/subsegs.c
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
21
gas/write.c
21
gas/write.c
|
@ -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. */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue