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.
This commit is contained in:
Alan Modra 2018-08-29 13:28:21 +09:30
parent f891966ff6
commit 4a9699735b
10 changed files with 150 additions and 18 deletions

View 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.

View 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,

View 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:

View 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",

View 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

View 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

View 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:

View 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

View 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.

View 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)