PowerPC64 @notoc in non-power10 code

R_PPC64_REL24_P9NOTOC is a variant of R_PPC64_REL24_NOTOC for use on
@notoc cals from non-power10 code in the rare case that using such a
construct is useful.  R_PPC64_REL24_P9NOTOC will be emitted by gas
rather than R_PPC64_REL24_NOTOC when @notoc is used in a branch
instruction if power10 instructions are not enabled at that point.
The new relocation tells the linker to not use power10 instructions on
any stub emitted for that branch, unless overridden by
--power10-stubs=yes.

The current linker heuristic of only generating power10 instructions
for stubs if power10-only relocations are detected, continues to be
used.

include/
	* elf/ppc64.h (R_PPC64_REL24_P9NOTOC): Define.
bfd/
	* reloc.c (BFD_RELOC_PPC64_REL24_P9NOTOC): Define.
	* elf64-ppc.c (ppc64_elf_howto_raw): Add entry for new reloc.
	(ppc64_elf_reloc_type_lookup): Handle it.
	(enum ppc_stub_type): Delete.
	(enum ppc_stub_main_type, ppc_stub_sub_type): New.
	(struct ppc_stub_type): New.
	(struct ppc_stub_hash_entry): Use the above new type.
	(struct ppc_link_hash_table): Update stub_count.
	(is_branch_reloc, ppc64_elf_check_relocs),
	(toc_adjusting_stub_needed): Handle new reloc.
	(stub_hash_newfunc, select_alt_stub, ppc_merge_stub),
	(ppc_type_of_stub, plt_stub_size, build_plt_stub),
	(build_tls_get_addr_head, build_tls_get_addr_tail),
	(ppc_build_one_stub, ppc_size_one_stub, ppc64_elf_size_stubs),
	(ppc64_elf_build_stubs, ppc64_elf_relocate_section): Handle new
	reloc.  Modify stub handling to suit new scheme.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.
gas/
	* config/tc-ppc.c (ppc_elf_suffix): When power10 is not enabled
	return BFD_RELOC_PPC64_REL24_P9NOTOC for @notoc.
	(fixup_size, ppc_force_relocation, ppc_fix_adjustable): Handle
	BFD_RELOC_PPC64_REL24_P9NOTOC.
ld/
	* testsuite/ld-powerpc/callstub-2.s: Add .machine power10.
This commit is contained in:
Alan Modra 2021-11-10 08:49:05 +10:30
parent 64f5c8167b
commit 7aba54da42
7 changed files with 354 additions and 396 deletions

View file

@ -2957,6 +2957,7 @@ instruction. */
BFD_RELOC_PPC64_ADDR64_LOCAL,
BFD_RELOC_PPC64_ENTRY,
BFD_RELOC_PPC64_REL24_NOTOC,
BFD_RELOC_PPC64_REL24_P9NOTOC,
BFD_RELOC_PPC64_D34,
BFD_RELOC_PPC64_D34_LO,
BFD_RELOC_PPC64_D34_HI30,

File diff suppressed because it is too large Load diff

View file

@ -1549,6 +1549,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_PPC64_ADDR64_LOCAL",
"BFD_RELOC_PPC64_ENTRY",
"BFD_RELOC_PPC64_REL24_NOTOC",
"BFD_RELOC_PPC64_REL24_P9NOTOC",
"BFD_RELOC_PPC64_D34",
"BFD_RELOC_PPC64_D34_LO",
"BFD_RELOC_PPC64_D34_HI30",

View file

@ -2902,6 +2902,8 @@ ENUMX
BFD_RELOC_PPC64_ENTRY
ENUMX
BFD_RELOC_PPC64_REL24_NOTOC
ENUMX
BFD_RELOC_PPC64_REL24_P9NOTOC
ENUMX
BFD_RELOC_PPC64_D34
ENUMX

View file

@ -2255,6 +2255,10 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
exp_p->X_add_symbol = &abs_symbol;
}
if (reloc == BFD_RELOC_PPC64_REL24_NOTOC
&& (ppc_cpu & PPC_OPCODE_POWER10) == 0)
reloc = BFD_RELOC_PPC64_REL24_P9NOTOC;
return (bfd_reloc_code_real_type) reloc;
}
@ -3128,6 +3132,7 @@ fixup_size (bfd_reloc_code_real_type reloc, bool *pc_relative)
case BFD_RELOC_32_PCREL:
case BFD_RELOC_32_PLT_PCREL:
case BFD_RELOC_PPC64_REL24_NOTOC:
case BFD_RELOC_PPC64_REL24_P9NOTOC:
#ifndef OBJ_XCOFF
case BFD_RELOC_PPC_B16:
#endif
@ -6557,6 +6562,7 @@ ppc_force_relocation (fixS *fix)
case BFD_RELOC_PPC_B16:
case BFD_RELOC_PPC_BA16:
case BFD_RELOC_PPC64_REL24_NOTOC:
case BFD_RELOC_PPC64_REL24_P9NOTOC:
/* All branch fixups targeting a localentry symbol must
force a relocation. */
if (fix->fx_addsy)
@ -6595,6 +6601,7 @@ ppc_fix_adjustable (fixS *fix)
case BFD_RELOC_PPC_BA16_BRTAKEN:
case BFD_RELOC_PPC_BA16_BRNTAKEN:
case BFD_RELOC_PPC64_REL24_NOTOC:
case BFD_RELOC_PPC64_REL24_P9NOTOC:
if (fix->fx_addsy)
{
asymbol *bfdsym = symbol_get_bfdsym (fix->fx_addsy);

View file

@ -162,6 +162,7 @@ START_RELOC_NUMBERS (elf_ppc64_reloc_type)
RELOC_NUMBER (R_PPC64_PLTSEQ_NOTOC, 121)
RELOC_NUMBER (R_PPC64_PLTCALL_NOTOC, 122)
RELOC_NUMBER (R_PPC64_PCREL_OPT, 123)
RELOC_NUMBER (R_PPC64_REL24_P9NOTOC, 124)
RELOC_NUMBER (R_PPC64_D34, 128)
RELOC_NUMBER (R_PPC64_D34_LO, 129)

View file

@ -1,6 +1,7 @@
#notoc call stubs, no pcrel insns
.text
.abiversion 2
.machine power10
_start:
bl f1
nop