diff options
author | Alan Modra <amodra@gmail.com> | 2018-08-29 13:28:21 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2018-08-31 22:15:05 +0930 |
commit | 4a9699735b04d4629bd3dc418c265e7f0bc1f9ce (patch) | |
tree | 6f92e1b94b3aa09e8a36e65d8d83823c94278ec3 /gas/config | |
parent | f891966ff66639673a5207b94bd68ec928fb68bc (diff) | |
download | binutils-4a9699735b04d4629bd3dc418c265e7f0bc1f9ce.zip binutils-4a9699735b04d4629bd3dc418c265e7f0bc1f9ce.tar.gz binutils-4a9699735b04d4629bd3dc418c265e7f0bc1f9ce.tar.bz2 |
PowerPC64 higher REL16 relocations
There are occasions where someone might want to build a 64-bit
pc-relative offset from 16-bit pieces. This adds the necessary REL16
relocs corresponding to existing ADDR16 relocs that can be used to
build 64-bit absolute values.
include/
* elf/ppc64.h (R_PPC64_REL16_HIGH, R_PPC64_REL16_HIGHA),
(R_PPC64_REL16_HIGHER, R_PPC64_REL16_HIGHERA),
(R_PPC64_REL16_HIGHEST, R_PPC64_REL16_HIGHESTA): Define.
(R_PPC64_LO_DS_OPT, R_PPC64_16DX_HA): Bump value.
bfd/
* reloc.c (BFD_RELOC_PPC64_REL16_HIGH, BFD_RELOC_PPC64_REL16_HIGHA),
(BFD_RELOC_PPC64_REL16_HIGHER, BFD_RELOC_PPC64_REL16_HIGHERA),
(BFD_RELOC_PPC64_REL16_HIGHEST, BFD_RELOC_PPC64_REL16_HIGHESTA):
Define.
* elf64-ppc.c (ppc64_elf_howto_raw): Add new REL16 howtos.
(ppc64_elf_reloc_type_lookup): Translate new REL16 relocs.
(ppc64_elf_check_relocs, ppc64_elf_relocate_section): Handle them.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
gas/
* config/tc-ppc.h (TC_FORCE_RELOCATION_SUB_LOCAL): Allow ADDR16
HIGH, HIGHA, HIGHER, HIGHERA, HIGHEST, and HIGHESTA relocs.
Group 16-bit relocs.
* config/tc-ppc.c (md_apply_fix): Translate those ADDR16 relocs
to REL16 when pcrel. Sort relocs.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-ppc.c | 36 | ||||
-rw-r--r-- | gas/config/tc-ppc.h | 20 |
2 files changed, 43 insertions, 13 deletions
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index d4cc2ff..a44b300 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -6624,6 +6624,18 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) { switch (fixP->fx_r_type) { + case BFD_RELOC_64: + fixP->fx_r_type = BFD_RELOC_64_PCREL; + break; + + case BFD_RELOC_32: + fixP->fx_r_type = BFD_RELOC_32_PCREL; + break; + + case BFD_RELOC_16: + fixP->fx_r_type = BFD_RELOC_16_PCREL; + break; + case BFD_RELOC_LO16: fixP->fx_r_type = BFD_RELOC_LO16_PCREL; break; @@ -6636,16 +6648,28 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL; break; - case BFD_RELOC_64: - fixP->fx_r_type = BFD_RELOC_64_PCREL; + case BFD_RELOC_PPC64_ADDR16_HIGH: + fixP->fx_r_type = BFD_RELOC_PPC64_REL16_HIGH; break; - case BFD_RELOC_32: - fixP->fx_r_type = BFD_RELOC_32_PCREL; + case BFD_RELOC_PPC64_ADDR16_HIGHA: + fixP->fx_r_type = BFD_RELOC_PPC64_REL16_HIGHA; break; - case BFD_RELOC_16: - fixP->fx_r_type = BFD_RELOC_16_PCREL; + case BFD_RELOC_PPC64_HIGHER: + fixP->fx_r_type = BFD_RELOC_PPC64_REL16_HIGHER; + break; + + case BFD_RELOC_PPC64_HIGHER_S: + fixP->fx_r_type = BFD_RELOC_PPC64_REL16_HIGHERA; + break; + + case BFD_RELOC_PPC64_HIGHEST: + fixP->fx_r_type = BFD_RELOC_PPC64_REL16_HIGHEST; + break; + + case BFD_RELOC_PPC64_HIGHEST_S: + fixP->fx_r_type = BFD_RELOC_PPC64_REL16_HIGHESTA; break; case BFD_RELOC_PPC_16DX_HA: diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index cf627de..7047fe7 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -264,13 +264,19 @@ extern int ppc_force_relocation (struct fix *); /* Don't allow the generic code to convert fixups involving the subtraction of a label in the current section to pc-relative if we don't have the necessary pc-relative relocation. */ -#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) \ - (!((FIX)->fx_r_type == BFD_RELOC_LO16 \ - || (FIX)->fx_r_type == BFD_RELOC_HI16 \ - || (FIX)->fx_r_type == BFD_RELOC_HI16_S \ - || (FIX)->fx_r_type == BFD_RELOC_64 \ - || (FIX)->fx_r_type == BFD_RELOC_32 \ - || (FIX)->fx_r_type == BFD_RELOC_16 \ +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) \ + (!((FIX)->fx_r_type == BFD_RELOC_64 \ + || (FIX)->fx_r_type == BFD_RELOC_32 \ + || (FIX)->fx_r_type == BFD_RELOC_16 \ + || (FIX)->fx_r_type == BFD_RELOC_LO16 \ + || (FIX)->fx_r_type == BFD_RELOC_HI16 \ + || (FIX)->fx_r_type == BFD_RELOC_HI16_S \ + || (FIX)->fx_r_type == BFD_RELOC_PPC64_ADDR16_HIGH \ + || (FIX)->fx_r_type == BFD_RELOC_PPC64_ADDR16_HIGHA \ + || (FIX)->fx_r_type == BFD_RELOC_PPC64_HIGHER \ + || (FIX)->fx_r_type == BFD_RELOC_PPC64_HIGHER_S \ + || (FIX)->fx_r_type == BFD_RELOC_PPC64_HIGHEST \ + || (FIX)->fx_r_type == BFD_RELOC_PPC64_HIGHEST_S \ || (FIX)->fx_r_type == BFD_RELOC_PPC_16DX_HA)) #endif |