From a58374d72ad744346e0cd66fcab1faa53e8adda9 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 17 Nov 1993 23:06:12 +0000 Subject: [PATCH] * write.c (is_dnrange): Do not define if md_relax_frag is defined. (relax_segment): If md_relax_frag is defined, use it to handle a frag of type rs_machine_dependent rather than looking through md_relax_table. * write.c (relax_and_size_seg): Don't set SEC_HAS_CONTENTS for a bss section. Set SEC_RELOC if there are any relocations, even for a zero size section. * write.c (write_relocs): In RELOC_EXPANSION_POSSIBLE case, based data offset on reloc[0]->address rather than reloc[j]->address, so that multiple relocs can affect different memory locations. * write.c (chain_frchains_together, relax_and_size_seg, adjust_reloc_syms, write_relocs): Make third argument PTR, not char *, to match definition of bfd_map_over_sections. --- gas/write.c | 72 ++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/gas/write.c b/gas/write.c index b36eb3b..677079e 100644 --- a/gas/write.c +++ b/gas/write.c @@ -117,13 +117,11 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel, fixP->fx_bit_fixP = 0; fixP->fx_addnumber = 0; fixP->tc_fix_data = NULL; + fixP->fx_tcbit = 0; #ifdef TC_something fixP->fx_bsr = 0; #endif -#ifdef TC_I960 - fixP->fx_callj = 0; -#endif as_where (&fixP->fx_file, &fixP->fx_line); @@ -297,7 +295,7 @@ static void chain_frchains_together (abfd, section, xxx) bfd *abfd; /* unused */ segT section; - char *xxx; /* unused */ + PTR xxx; /* unused */ { segment_info_type *info; @@ -408,7 +406,7 @@ static void relax_and_size_seg (abfd, sec, xxx) bfd *abfd; asection *sec; - char *xxx; + PTR xxx; { flagword flags; fragS *fragp; @@ -432,17 +430,18 @@ relax_and_size_seg (abfd, sec, xxx) } else size = 0; - if (size > 0) - { - flags |= SEC_HAS_CONTENTS; - /* @@ This is just an approximation. */ - if (seginfo->fix_root) - flags |= SEC_RELOC; - else - flags &= ~SEC_RELOC; - x = bfd_set_section_flags (abfd, sec, flags); - assert (x == true); - } + + if (size > 0 && ! seginfo->bss) + flags |= SEC_HAS_CONTENTS; + + /* @@ This is just an approximation. */ + if (seginfo->fix_root) + flags |= SEC_RELOC; + else + flags &= ~SEC_RELOC; + x = bfd_set_section_flags (abfd, sec, flags); + assert (x == true); + newsize = md_section_align (sec, size); x = bfd_set_section_size (abfd, sec, newsize); assert (x == true); @@ -503,7 +502,7 @@ static void adjust_reloc_syms (abfd, sec, xxx) bfd *abfd; asection *sec; - char *xxx; + PTR xxx; { segment_info_type *seginfo = seg_info (sec); fixS *fixp; @@ -520,8 +519,11 @@ adjust_reloc_syms (abfd, sec, xxx) asection *symsec = sym->bsym->section; segment_info_type *symseginfo = seg_info (symsec); - /* If it's one of these sections, assume the symbol is definitely - going to be output. */ + /* If it's one of these sections, assume the symbol is + definitely going to be output. The code in + md_estimate_size_before_relax in tc-mips.c uses this test + as well, so if you change this code you should look at that + code. */ if (symsec == &bfd_und_section || symsec == &bfd_abs_section || bfd_is_com_section (symsec)) @@ -587,7 +589,7 @@ static void write_relocs (abfd, sec, xxx) bfd *abfd; asection *sec; - char *xxx; + PTR xxx; { segment_info_type *seginfo = seg_info (sec); int i; @@ -691,7 +693,8 @@ write_relocs (abfd, sec, xxx) abort (); for (j = 0; reloc[j]; j++) { - s = bfd_perform_relocation (stdoutput, reloc[j], data - reloc[j]->address, + s = bfd_perform_relocation (stdoutput, reloc[j], + data - reloc[0]->address, sec, stdoutput); switch (s) { @@ -732,7 +735,7 @@ static void write_contents (abfd, sec, xxx) bfd *abfd; asection *sec; - char *xxx; + PTR xxx; { segment_info_type *seginfo = seg_info (sec); unsigned long offset = 0; @@ -1449,6 +1452,8 @@ write_object_file () * these frag addresses may not be the same as final object-file addresses. */ +#ifndef md_relax_frag + /* Subroutines of relax_segment. */ static int is_dnrange (f1, f2) @@ -1461,6 +1466,8 @@ is_dnrange (f1, f2) return 0; } +#endif /* ! defined (md_relax_frag) */ + /* Relax_align. Advance location counter to next address that has 'alignment' lowest order bits all 0s, return size of adjustment made. */ static relax_addressT @@ -1664,6 +1671,11 @@ relax_segment (segment_frag_root, segment) break; case rs_machine_dependent: +#ifdef md_relax_frag + growth = md_relax_frag (fragP, stretch); +#else + /* The default way to relax a frag is to look through + md_relax_table. */ { const relax_typeS *this_type; const relax_typeS *start_type; @@ -1756,6 +1768,7 @@ relax_segment (segment_frag_root, segment) if (growth != 0) fragP->fr_subtype = this_state; } +#endif break; default: @@ -1831,7 +1844,7 @@ fixup_segment (fixP, this_segment_type) size = fixP->fx_size; add_symbolP = fixP->fx_addsy; #ifdef TC_I960 - if (fixP->fx_callj && TC_S_IS_CALLNAME (add_symbolP)) + if (fixP->fx_tcbit && TC_S_IS_CALLNAME (add_symbolP)) { /* Relocation should be done via the associated 'bal' entry point symbol. */ @@ -1874,7 +1887,7 @@ fixup_segment (fixP, this_segment_type) #ifdef TC_I960 /* Makes no sense to use the difference of 2 arbitrary symbols as the target of a call instruction. */ - if (fixP->fx_callj) + if (fixP->fx_tcbit) { as_bad ("callj to difference of 2 symbols"); } @@ -1885,7 +1898,6 @@ fixup_segment (fixP, this_segment_type) add_symbolP = NULL; fixP->fx_addsy = NULL; } -#if !defined(SEG_DIFF_ALLOWED) && !defined (GLOBAL_DIFF_ALLOWED) else { /* Different segments in subtraction. */ @@ -1925,14 +1937,6 @@ fixup_segment (fixP, this_segment_type) S_GET_NAME (sub_symbolP), buf); } } -#else - else - { - seg_reloc_count++; - fixP->fx_addnumber = add_number; /* Remember value for emit_reloc */ - continue; - } /* if absolute */ -#endif } if (add_symbolP) @@ -2069,7 +2073,7 @@ fixup_segment (fixP, this_segment_type) /* two relocs per callj under coff. */ for (fixP = topP; fixP; fixP = fixP->fx_next) - if (fixP->fx_callj && fixP->fx_addsy != 0) + if (fixP->fx_tcbit && fixP->fx_addsy != 0) ++seg_reloc_count; } #endif /* OBJ_COFF && TC_I960 */ -- 2.7.4