diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1996-06-10 10:55:58 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1996-06-10 10:55:58 +0000 |
commit | a7e831079363e3bb45f3172f6e59ba48e335682b (patch) | |
tree | ee4324eac9a9d66f189fab60498ec42b8226b7fc /gnu/usr.bin/binutils/gas/write.c | |
parent | 467cb0a471d13c5186a6ee166e60b47c30da64e9 (diff) |
Bring Cygnus versions into the trunk, keeping our local patches
Diffstat (limited to 'gnu/usr.bin/binutils/gas/write.c')
-rw-r--r-- | gnu/usr.bin/binutils/gas/write.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/gnu/usr.bin/binutils/gas/write.c b/gnu/usr.bin/binutils/gas/write.c index 506644f234e..10aba1e481d 100644 --- a/gnu/usr.bin/binutils/gas/write.c +++ b/gnu/usr.bin/binutils/gas/write.c @@ -1,5 +1,5 @@ /* write.c - emit .o file - Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 1995 + Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -94,6 +94,8 @@ int magic_number_for_object_file = DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE; #endif /* BFD_ASSEMBLER */ +static int n_fixups; + #ifdef BFD_ASSEMBLER static fixS *fix_new_internal PARAMS ((fragS *, int where, int size, symbolS *add, symbolS *sub, @@ -133,6 +135,8 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel, { fixS *fixP; + n_fixups++; + fixP = (fixS *) obstack_alloc (¬es, sizeof (fixS)); fixP->fx_frag = frag; @@ -268,11 +272,13 @@ fix_new_exp (frag, where, size, exp, pcrel, r_type) #if defined(BFD_ASSEMBLER) r_type = BFD_RELOC_RVA; -#elif defined(TC_RVA_RELOC) +#else +#if defined(TC_RVA_RELOC) r_type = TC_RVA_RELOC; #else as_fatal("rva not supported"); #endif +#endif break; case O_uminus: @@ -799,12 +805,23 @@ write_relocs (abfd, sec, xxx) { arelent *reloc; bfd_reloc_status_type s; + symbolS *sym; if (fixp->fx_done) { n--; continue; } + + /* If this is an undefined symbol which was equated to another + symbol, then use generate the reloc against the latter symbol + rather than the former. */ + sym = fixp->fx_addsy; + while (sym->sy_value.X_op == O_symbol + && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym))) + sym = sym->sy_value.X_add_symbol; + fixp->fx_addsy = sym; + reloc = tc_gen_reloc (sec, fixp); if (!reloc) { @@ -844,6 +861,7 @@ write_relocs (abfd, sec, xxx) arelent **reloc; char *data; bfd_reloc_status_type s; + symbolS *sym; int j; if (fixp->fx_done) @@ -851,6 +869,16 @@ write_relocs (abfd, sec, xxx) n--; continue; } + + /* If this is an undefined symbol which was equated to another + symbol, then use generate the reloc against the latter symbol + rather than the former. */ + sym = fixp->fx_addsy; + while (sym->sy_value.X_op == O_symbol + && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym))) + sym = sym->sy_value.X_add_symbol; + fixp->fx_addsy = sym; + reloc = tc_gen_reloc (sec, fixp); for (j = 0; reloc[j]; j++) @@ -1642,6 +1670,15 @@ write_object_file () resolve_symbol_value (symp); } + /* Skip symbols which were equated to undefined or common + symbols. */ + if (symp->sy_value.X_op == O_symbol + && (! S_IS_DEFINED (symp) || S_IS_COMMON (symp))) + { + symbol_remove (symp, &symbol_rootP, &symbol_lastP); + continue; + } + /* So far, common symbols have been treated like undefined symbols. Put them in the common section now. */ if (S_IS_DEFINED (symp) == 0 @@ -2405,9 +2442,11 @@ fixup_segment (fixP, this_segment_type) else { seg_reloc_count++; +#if !(defined (TC_M68K) && defined (OBJ_ELF)) #if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF)) add_number += S_GET_VALUE (add_symbolP); #endif +#endif } } } @@ -2534,6 +2573,13 @@ number_to_chars_littleendian (buf, val, n) } } +void +write_print_statistics (file) + FILE *file; +{ + fprintf (stderr, "fixups: %d\n", n_fixups); +} + /* for debugging */ extern int indent_level; extern void print_symbol_value_1 (); |