diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2013-01-20 22:54:14 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2013-01-20 22:54:14 +0000 |
commit | a540a47404b680dce4311c282165236af4117324 (patch) | |
tree | 6654d8dadc79a319336572f57c96028f4a19a61e | |
parent | f8d2d1bc00a4e38b20e04a32364d436b07904801 (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.c | 15 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gas/config/tc-m88k.h | 4 |
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 |