PowerPC64 higher REL16 relocations
authorAlan Modra <amodra@gmail.com>
Wed, 29 Aug 2018 03:58:21 +0000 (13:28 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 31 Aug 2018 12:45:05 +0000 (22:15 +0930)
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.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf64-ppc.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-ppc.c
gas/config/tc-ppc.h
include/ChangeLog
include/elf/ppc64.h

index 35c4efa8f705e20c05c25579828cc409addc2da7..8538bcd943f5a2c3ace4066140f548e374ce283b 100644 (file)
@@ -1,3 +1,15 @@
+2018-08-31  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2018-08-31  Alan Modra  <amodra@gmail.com>
 
        * elf64-ppc.c: Correct _notoc stub comments.
index 1412f8934f243db27616ad4392c06c7712472b94..e5f7101e52aa47e61475fff0ef0a0dbaaa96839e 100644 (file)
@@ -3436,6 +3436,12 @@ instruction.  */
   BFD_RELOC_PPC64_PLTGOT16_LO_DS,
   BFD_RELOC_PPC64_ADDR16_HIGH,
   BFD_RELOC_PPC64_ADDR16_HIGHA,
+  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,
   BFD_RELOC_PPC64_ADDR64_LOCAL,
   BFD_RELOC_PPC64_ENTRY,
   BFD_RELOC_PPC64_REL24_NOTOC,
index e6fe2601da9b46be2d64087f18c7839ccca744da..5826c2288aa988b57a183007e71d095267a1dc78 100644 (file)
@@ -820,6 +820,24 @@ static reloc_howto_type ppc64_elf_howto_raw[] =
   HOW (R_PPC64_REL16_HA, 1, 16, 0xffff, 16, TRUE, signed,
        ppc64_elf_ha_reloc),
 
+  HOW (R_PPC64_REL16_HIGH, 1, 16, 0xffff, 16, TRUE, dont,
+       bfd_elf_generic_reloc),
+
+  HOW (R_PPC64_REL16_HIGHA, 1, 16, 0xffff, 16, TRUE, dont,
+       ppc64_elf_ha_reloc),
+
+  HOW (R_PPC64_REL16_HIGHER, 1, 16, 0xffff, 32, TRUE, dont,
+       bfd_elf_generic_reloc),
+
+  HOW (R_PPC64_REL16_HIGHERA, 1, 16, 0xffff, 32, TRUE, dont,
+       ppc64_elf_ha_reloc),
+
+  HOW (R_PPC64_REL16_HIGHEST, 1, 16, 0xffff, 48, TRUE, dont,
+       bfd_elf_generic_reloc),
+
+  HOW (R_PPC64_REL16_HIGHESTA, 1, 16, 0xffff, 48, TRUE, dont,
+       ppc64_elf_ha_reloc),
+
   /* Like R_PPC64_REL16_HA but for split field in addpcis.  */
   HOW (R_PPC64_REL16DX_HA, 2, 16, 0x1fffc1, 16, TRUE, signed,
        ppc64_elf_ha_reloc),
@@ -1129,6 +1147,18 @@ ppc64_elf_reloc_type_lookup (bfd *abfd,
       break;
     case BFD_RELOC_HI16_S_PCREL:               r = R_PPC64_REL16_HA;
       break;
+    case BFD_RELOC_PPC64_REL16_HIGH:           r = R_PPC64_REL16_HIGH;
+      break;
+    case BFD_RELOC_PPC64_REL16_HIGHA:          r = R_PPC64_REL16_HIGHA;
+      break;
+    case BFD_RELOC_PPC64_REL16_HIGHER:         r = R_PPC64_REL16_HIGHER;
+      break;
+    case BFD_RELOC_PPC64_REL16_HIGHERA:                r = R_PPC64_REL16_HIGHERA;
+      break;
+    case BFD_RELOC_PPC64_REL16_HIGHEST:                r = R_PPC64_REL16_HIGHEST;
+      break;
+    case BFD_RELOC_PPC64_REL16_HIGHESTA:       r = R_PPC64_REL16_HIGHESTA;
+      break;
     case BFD_RELOC_PPC_16DX_HA:                        r = R_PPC64_16DX_HA;
       break;
     case BFD_RELOC_PPC_REL16DX_HA:             r = R_PPC64_REL16DX_HA;
@@ -4474,6 +4504,12 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case R_PPC64_REL16_LO:
        case R_PPC64_REL16_HI:
        case R_PPC64_REL16_HA:
+       case R_PPC64_REL16_HIGH:
+       case R_PPC64_REL16_HIGHA:
+       case R_PPC64_REL16_HIGHER:
+       case R_PPC64_REL16_HIGHERA:
+       case R_PPC64_REL16_HIGHEST:
+       case R_PPC64_REL16_HIGHESTA:
        case R_PPC64_REL16DX_HA:
          break;
 
@@ -14557,6 +14593,12 @@ ppc64_elf_relocate_section (bfd *output_bfd,
        case R_PPC64_REL16_LO:
        case R_PPC64_REL16_HI:
        case R_PPC64_REL16_HA:
+       case R_PPC64_REL16_HIGH:
+       case R_PPC64_REL16_HIGHA:
+       case R_PPC64_REL16_HIGHER:
+       case R_PPC64_REL16_HIGHERA:
+       case R_PPC64_REL16_HIGHEST:
+       case R_PPC64_REL16_HIGHESTA:
        case R_PPC64_REL16DX_HA:
          break;
 
@@ -15038,6 +15080,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
          break;
 
        case R_PPC64_REL16_HA:
+       case R_PPC64_REL16_HIGHA:
+       case R_PPC64_REL16_HIGHERA:
+       case R_PPC64_REL16_HIGHESTA:
        case R_PPC64_REL16DX_HA:
        case R_PPC64_ADDR16_HA:
        case R_PPC64_ADDR16_HIGHA:
index 6c1e1ea9a597fcac1d33ceef2c4f6b887077b524..34f05dd2e70d61dae16ed896f69358b8ed3feca3 100644 (file)
@@ -1467,6 +1467,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_PPC64_PLTGOT16_LO_DS",
   "BFD_RELOC_PPC64_ADDR16_HIGH",
   "BFD_RELOC_PPC64_ADDR16_HIGHA",
+  "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",
   "BFD_RELOC_PPC64_ADDR64_LOCAL",
   "BFD_RELOC_PPC64_ENTRY",
   "BFD_RELOC_PPC64_REL24_NOTOC",
index 0dcf2be9a0299dab4e049e2963a6f3ed5db1d2af..eba6091891272d0d10d92dad4656635f738adcfc 100644 (file)
@@ -2853,6 +2853,18 @@ ENUMX
   BFD_RELOC_PPC64_ADDR16_HIGH
 ENUMX
   BFD_RELOC_PPC64_ADDR16_HIGHA
+ENUMX
+  BFD_RELOC_PPC64_REL16_HIGH
+ENUMX
+  BFD_RELOC_PPC64_REL16_HIGHA
+ENUMX
+  BFD_RELOC_PPC64_REL16_HIGHER
+ENUMX
+  BFD_RELOC_PPC64_REL16_HIGHERA
+ENUMX
+  BFD_RELOC_PPC64_REL16_HIGHEST
+ENUMX
+  BFD_RELOC_PPC64_REL16_HIGHESTA
 ENUMX
   BFD_RELOC_PPC64_ADDR64_LOCAL
 ENUMX
index d4ec42ba4171a5edb17514441200d4ec0d1a7a3a..83249990b8344fdbefa23f8cbccbee8fe19e2ebf 100644 (file)
@@ -1,3 +1,11 @@
+2018-08-31  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2018-08-31  H.J. Lu  <hongjiu.lu@intel.com>
 
        * testsuite/gas/elf/elf.exp: Pass -mx86-used-note=no to
index d4cc2ff09ecb4d3a388046aef8e2d0d6368c209a..a44b30068f2a9a756f3871b53dcb36285a32e454 100644 (file)
@@ -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:
index cf627dec262e45281be0e3ac73f8f3774c969843..7047fe74919287b5680b180eed6f92ff65561a3c 100644 (file)
@@ -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
 
index b8fcefdf6e13be6538e9e0c03cc8ce98929f7fd6..63fdde6349146db375554790d48b988b1851c043 100644 (file)
@@ -1,3 +1,10 @@
+2018-08-31  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2018-08-30  Kito Cheng  <kito@andestech.com>
 
        * opcode/riscv.h (MAX_SUBSET_NUM): New.
index 387c1d64043cdb6e205d219a4d5f139c682e7ede..700c9a44032c9f7581d3bb984526e23a3178b363 100644 (file)
@@ -159,14 +159,20 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
   RELOC_NUMBER (R_PPC64_PLTCALL,          120)
 
 #ifndef RELOC_MACROS_GEN_FUNC
-/* Relocation only used internally by ld.  If you need to use these
-   reloc numbers, you can change them to some other unused value
+/* Relocation only used internally by gas or ld.  If you need to use
+   these reloc numbers, you can change them to some other unused value
    without affecting the ABI.  They will never appear in object files.  */
-  RELOC_NUMBER (R_PPC64_LO_DS_OPT,        128)
-/* Reloc only used internally by gas.  As above, value is unimportant.  */
-  RELOC_NUMBER (R_PPC64_16DX_HA,          129)
+  RELOC_NUMBER (R_PPC64_LO_DS_OPT,        200)
+  RELOC_NUMBER (R_PPC64_16DX_HA,          201)
 #endif
 
+  RELOC_NUMBER (R_PPC64_REL16_HIGH,       240)
+  RELOC_NUMBER (R_PPC64_REL16_HIGHA,      241)
+  RELOC_NUMBER (R_PPC64_REL16_HIGHER,     242)
+  RELOC_NUMBER (R_PPC64_REL16_HIGHERA,    243)
+  RELOC_NUMBER (R_PPC64_REL16_HIGHEST,    244)
+  RELOC_NUMBER (R_PPC64_REL16_HIGHESTA,           245)
+
 /* Power9 split rel16 for addpcis.  */
   RELOC_NUMBER (R_PPC64_REL16DX_HA,       246)