summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2013-01-20 22:54:14 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2013-01-20 22:54:14 +0000
commita540a47404b680dce4311c282165236af4117324 (patch)
tree6654d8dadc79a319336572f57c96028f4a19a61e
parentf8d2d1bc00a4e38b20e04a32364d436b07904801 (diff)
Implement tc_fix_adjustable() on ELF, and use it to prevent #got_rel
relocations to local symbols to be rewritten as relocations to the beginning of the section they are in, plus an addend, as addend can't work for these relocations, the way the got is set up. Inspired by tc-ppc.
-rw-r--r--gnu/usr.bin/binutils/gas/config/tc-m88k.c15
-rw-r--r--gnu/usr.bin/binutils/gas/config/tc-m88k.h4
2 files changed, 19 insertions, 0 deletions
diff --git a/gnu/usr.bin/binutils/gas/config/tc-m88k.c b/gnu/usr.bin/binutils/gas/config/tc-m88k.c
index 432535bc5a1..4f54f7d1407 100644
--- a/gnu/usr.bin/binutils/gas/config/tc-m88k.c
+++ b/gnu/usr.bin/binutils/gas/config/tc-m88k.c
@@ -1639,6 +1639,21 @@ m88k_parse_name (name, expressionP, nextcharP)
return 1;
}
+
+int
+m88k_fix_adjustable (fix)
+ fixS *fix;
+{
+ return (fix->fx_r_type != BFD_RELOC_LO16_GOTOFF
+ && fix->fx_r_type != BFD_RELOC_HI16_GOTOFF
+ && fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
+ && fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY
+ && (fix->fx_pcrel
+ || (fix->fx_subsy != NULL
+ && (S_GET_SEGMENT (fix->fx_subsy)
+ == S_GET_SEGMENT (fix->fx_addsy)))
+ || S_IS_LOCAL (fix->fx_addsy)));
+}
#endif /* OBJ_ELF */
#ifdef OBJ_AOUT
diff --git a/gnu/usr.bin/binutils/gas/config/tc-m88k.h b/gnu/usr.bin/binutils/gas/config/tc-m88k.h
index 53fbcbe6eab..93bb32bb273 100644
--- a/gnu/usr.bin/binutils/gas/config/tc-m88k.h
+++ b/gnu/usr.bin/binutils/gas/config/tc-m88k.h
@@ -105,6 +105,10 @@ extern int m88k_parse_name (const char *, expressionS *, char *);
|| (FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \
|| TC_FORCE_RELOCATION (FIX))
+/* Keep relocations relative to the GOT, or non-PC relative. */
+#define tc_fix_adjustable(FIX) m88k_fix_adjustable (FIX)
+extern int m88k_fix_adjustable PARAMS ((struct fix *));
+
#endif /* OBJ_ELF */
#ifndef OBJ_ELF