aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-08-03 16:41:22 +0930
committerAlan Modra <amodra@gmail.com>2018-08-05 12:11:51 +0930
commit05d0e962f08af24f18cc79b890a68176b42bcb78 (patch)
tree2c8f894a6415dfe2260ff0e9bd7a9b46f7451b8a /gas
parent3f6ff4799bc50e6030bb707b2b2b525fcfdd2216 (diff)
downloadfsf-binutils-gdb-05d0e962f08af24f18cc79b890a68176b42bcb78.zip
fsf-binutils-gdb-05d0e962f08af24f18cc79b890a68176b42bcb78.tar.gz
fsf-binutils-gdb-05d0e962f08af24f18cc79b890a68176b42bcb78.tar.bz2
R_PPC64_REL24_NOTOC support
R_PPC64_REL24_NOTOC is used on calls like "bl foo@notoc" to tell the linker that linkage stubs for PLT calls or long branches can't use r2 for pic addressing. Instead, new stubs that generate pc-relative addresses are used. One complication is that pc-relative offsets to the PLT may need to be 64-bit in large programs, in contrast to the toc-relative addressing used by older PLT linkage stubs where a 32-bit offset is sufficient until the PLT itself exceeds 2G in size. .eh_frame info to cover the _notoc stubs is yet to be implemented. bfd/ * elf64-ppc.c (ADDI_R12_R11, ADDI_R12_R12, LIS_R12), (ADDIS_R12_R11, ORIS_R12_R12_0, ORI_R12_R12_0), (SLDI_R12_R12_32, LDX_R12_R11_R12, ADD_R12_R11_R12): Define. (ppc64_elf_howto_raw): Add R_PPC64_REL24_NOTOC entry. (ppc64_elf_reloc_type_lookup): Support R_PPC64_REL24_NOTOC. (ppc_stub_type): Add ppc_stub_long_branch_notoc, ppc_stub_long_branch_both, ppc_stub_plt_branch_notoc, ppc_stub_plt_branch_both, ppc_stub_plt_call_notoc, and ppc_stub_plt_call_both. (is_branch_reloc): Add R_PPC64_REL24_NOTOC. (build_offset, size_offset): New functions. (plt_stub_size): Support plt_call_notoc and plt_call_both. (ppc_build_one_stub, ppc_size_one_stub): Support new stubs. (toc_adjusting_stub_needed): Handle R_PPC64_REL24_NOTOC. (ppc64_elf_size_stubs): Likewise, and new stubs. (ppc64_elf_build_stubs, ppc64_elf_relocate_section): Likewise. * reloc.c: Add BFD_RELOC_PPC64_REL24_NOTOC. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. gas/ * config/tc-ppc.c (ppc_elf_suffix): Support @notoc. (ppc_force_relocation, ppc_fix_adjustable): Handle REL24_NOTOC. ld/ * testsuite/ld-powerpc/ext.d, * testsuite/ld-powerpc/ext.s, * testsuite/ld-powerpc/ext.lnk, * testsuite/ld-powerpc/notoc.d, * testsuite/ld-powerpc/notoc.s: New tests. * testsuite/ld-powerpc/powerpc.exp: Run them.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-ppc.c3
2 files changed, 8 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index b704d8c..94b496b 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-05 Alan Modra <amodra@gmail.com>
+
+ * config/tc-ppc.c (ppc_elf_suffix): Support @notoc.
+ (ppc_force_relocation, ppc_fix_adjustable): Handle REL24_NOTOC.
+
2018-08-03 Dimitar Dimitrov <dimitar@dinux.eu>
* config/tc-pru.c (pru_regname_to_dw2regnum): Return the starting HW
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index eaa866d..6135cb4 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -2085,6 +2085,7 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p)
MAP64 ("tprel@highera", BFD_RELOC_PPC64_TPREL16_HIGHERA),
MAP64 ("tprel@highest", BFD_RELOC_PPC64_TPREL16_HIGHEST),
MAP64 ("tprel@highesta", BFD_RELOC_PPC64_TPREL16_HIGHESTA),
+ MAP64 ("notoc", BFD_RELOC_PPC64_REL24_NOTOC),
{ (char *) 0, 0, 0, 0, BFD_RELOC_NONE }
};
@@ -6416,6 +6417,7 @@ ppc_force_relocation (fixS *fix)
case BFD_RELOC_PPC_BA26:
case BFD_RELOC_PPC_B16:
case BFD_RELOC_PPC_BA16:
+ case BFD_RELOC_PPC64_REL24_NOTOC:
/* All branch fixups targeting a localentry symbol must
force a relocation. */
if (fix->fx_addsy)
@@ -6454,6 +6456,7 @@ ppc_fix_adjustable (fixS *fix)
case BFD_RELOC_PPC_B16_BRNTAKEN:
case BFD_RELOC_PPC_BA16_BRTAKEN:
case BFD_RELOC_PPC_BA16_BRNTAKEN:
+ case BFD_RELOC_PPC64_REL24_NOTOC:
if (fix->fx_addsy)
{
asymbol *bfdsym = symbol_get_bfdsym (fix->fx_addsy);