aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-08-29 13:28:21 +0930
committerAlan Modra <amodra@gmail.com>2018-08-31 22:15:05 +0930
commit4a9699735b04d4629bd3dc418c265e7f0bc1f9ce (patch)
tree6f92e1b94b3aa09e8a36e65d8d83823c94278ec3 /gas/config/tc-ppc.c
parentf891966ff66639673a5207b94bd68ec928fb68bc (diff)
downloadgdb-4a9699735b04d4629bd3dc418c265e7f0bc1f9ce.zip
gdb-4a9699735b04d4629bd3dc418c265e7f0bc1f9ce.tar.gz
gdb-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/tc-ppc.c')
-rw-r--r--gas/config/tc-ppc.c36
1 files changed, 30 insertions, 6 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: