From: Alan Modra Date: Fri, 30 Mar 2001 03:11:28 +0000 (+0000) Subject: rth's fix for relaxation ordering problem. X-Git-Tag: binutils-2_11~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5f3d2cc93c1fdc995ac1724b6abf5ba823d948da;p=thirdparty%2Fbinutils-gdb.git rth's fix for relaxation ordering problem. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 555748a2cbd..5f222e0285a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2001-03-30 Richard Henderson + + * write.c (relax_seg, size_seg): Split from relax_and_size_seg. + (write_object_file): Relax code then data, then size sections. + + * config/tc-i386.c (md_convert_frag): Don't die on local symbols + that have been finalized. + 2001-03-28 Alan Modra * config/tc-hppa.c (DEFAULT_LEVEL): Define. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 6e9fda2b916..05bdcdcfcbd 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -3981,7 +3981,12 @@ md_convert_frag (abfd, sec, fragP) target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; #ifdef BFD_ASSEMBLER /* Not needed otherwise? */ - target_address += symbol_get_frag (fragP->fr_symbol)->fr_address; + { + /* Local symbols which have already been resolved have a NULL frags. */ + fragS *sym_frag = symbol_get_frag (fragP->fr_symbol); + if (sym_frag) + target_address += sym_frag->fr_address; + } #endif /* Address opcode resides at in file space. */ diff --git a/gas/write.c b/gas/write.c index 24b387e649f..9ef356fe55e 100644 --- a/gas/write.c +++ b/gas/write.c @@ -121,7 +121,8 @@ static fragS *chain_frchains_together_1 PARAMS ((segT, struct frchain *)); #ifdef BFD_ASSEMBLER static void chain_frchains_together PARAMS ((bfd *, segT, PTR)); static void cvt_frag_to_fill PARAMS ((segT, fragS *)); -static void relax_and_size_seg PARAMS ((bfd *, asection *, PTR)); +static void relax_seg PARAMS ((bfd *, asection *, PTR)); +static void size_seg PARAMS ((bfd *, asection *, PTR)); static void adjust_reloc_syms PARAMS ((bfd *, asection *, PTR)); static void write_relocs PARAMS ((bfd *, asection *, PTR)); static void write_contents PARAMS ((bfd *, asection *, PTR)); @@ -593,7 +594,21 @@ cvt_frag_to_fill (headersP, sec, fragP) #ifdef BFD_ASSEMBLER static void -relax_and_size_seg (abfd, sec, xxx) +relax_seg (abfd, sec, do_code) + bfd *abfd; + asection *sec; + PTR do_code; +{ + flagword flags = bfd_get_section_flags (abfd, sec); + segment_info_type *seginfo = seg_info (sec); + + if (!(flags & SEC_CODE) == !do_code + && seginfo && seginfo->frchainP) + relax_segment (seginfo->frchainP->frch_root, sec); +} + +static void +size_seg (abfd, sec, xxx) bfd *abfd; asection *sec; PTR xxx ATTRIBUTE_UNUSED; @@ -606,12 +621,9 @@ relax_and_size_seg (abfd, sec, xxx) subseg_change (sec, 0); - flags = bfd_get_section_flags (abfd, sec); - seginfo = seg_info (sec); if (seginfo && seginfo->frchainP) { - relax_segment (seginfo->frchainP->frch_root, sec); for (fragp = seginfo->frchainP->frch_root; fragp; fragp = fragp->fr_next) cvt_frag_to_fill (sec, fragp); for (fragp = seginfo->frchainP->frch_root; @@ -624,6 +636,8 @@ relax_and_size_seg (abfd, sec, xxx) else size = 0; + flags = bfd_get_section_flags (abfd, sec); + if (size > 0 && ! seginfo->bss) flags |= SEC_HAS_CONTENTS; @@ -1514,7 +1528,9 @@ write_object_file () #endif #ifdef BFD_ASSEMBLER - bfd_map_over_sections (stdoutput, relax_and_size_seg, (char *) 0); + bfd_map_over_sections (stdoutput, relax_seg, (char *) 1); + bfd_map_over_sections (stdoutput, relax_seg, (char *) 0); + bfd_map_over_sections (stdoutput, size_seg, (char *) 0); #else relax_and_size_all_segments (); #endif /* BFD_ASSEMBLER */