summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/binutils/gas/write.c
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1996-06-10 10:55:58 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1996-06-10 10:55:58 +0000
commita7e831079363e3bb45f3172f6e59ba48e335682b (patch)
treeee4324eac9a9d66f189fab60498ec42b8226b7fc /gnu/usr.bin/binutils/gas/write.c
parent467cb0a471d13c5186a6ee166e60b47c30da64e9 (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.c50
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 (&notes, 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 ();