aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-01-20 12:38:00 +1030
committerAlan Modra <amodra@gmail.com>2020-01-22 17:14:08 +1030
commit9e7028aa1e788d666bad91fb20159da6c95bbab1 (patch)
tree6c11e81207599183a4d222248ca2a26f282db861 /ld/emultempl
parentabc489c64a3137f3751797e8ce60d53a2c432e1d (diff)
downloadgdb-9e7028aa1e788d666bad91fb20159da6c95bbab1.zip
gdb-9e7028aa1e788d666bad91fb20159da6c95bbab1.tar.gz
gdb-9e7028aa1e788d666bad91fb20159da6c95bbab1.tar.bz2
PowerPC64 __tls_get_addr_desc
This implements register saving and restoring in the __tls_get_addr call stub, so that when glibc supports the optimized tls call stub gcc can generate code that assumes only r0, r12 and of course r3 are changed on a __tls_get_addr call. When gcc expects __tls_get_addr calls to preserve registers the call will be to __tls_get_addr_desc, which will be translated by the linker to a call to __tls_get_addr_opt. bfd/ * elf64-ppc.h (struct ppc64_elf_params): Add no_tls_get_addr_regsave. * elf64-ppc.c (struct ppc_link_hash_table): Add tga_desc and tga_desc_fd. (is_tls_get_addr): Match tga_desc and tga_desc_df too. (STDU_R1_0R1, ADDI_R1_R1): Define. (tls_get_addr_prologue, tls_get_addr_epilogue): New functions. (ppc64_elf_tls_setup): Set up tga_desc and tga_desc_fd. Indirect tga_desc_fd to opt_fd, and tga_desc to opt. Set no_tls_get_addr_regsave. (branch_reloc_hash_match): Add hash3 and hash4. (ppc64_elf_tls_optimize): Handle tga_desc_fd and tga_desc too. (ppc64_elf_size_dynamic_sections): Likewise. (ppc64_elf_relocate_section): Likewise. (plt_stub_size, build_plt_stub): Likewise. Size regsave __tls_get_addr stub. (build_tls_get_addr_stub): Build regsave __tls_get_addr stub and eh_frame. (ppc_size_one_stub): Handle tga_desc_fd and tga_desc too. Size eh_frame for regsave __tls_get_addr. gas/ * config/tc-ppc.c (parse_tls_arg): Handle tls arg for __tls_get_addr_desc and __tls_get_addr_opt. ld/ * emultempl/ppc64elf.em (ppc64_opt, PARSE_AND_LIST_LONGOPTS), (PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Support --tls-get-addr-regsave and --no-tls-get-addr-regsave. (params): Init new field. * ld.texi (--tls-get-addr-regsave, --no-tls-get-addr-regsave): Document. * testsuite/ld-powerpc/tlsdesc.s, * testsuite/ld-powerpc/tlsdesc.d, * testsuite/ld-powerpc/tlsdesc.wf, * testsuite/ld-powerpc/tlsdesc2.d, * testsuite/ld-powerpc/tlsdesc2.wf, * testsuite/ld-powerpc/tlsexenors.d, * testsuite/ld-powerpc/tlsexenors.r, * testsuite/ld-powerpc/tlsexers.d, * testsuite/ld-powerpc/tlsexers.r, * testsuite/ld-powerpc/tlsexetocnors.d, * testsuite/ld-powerpc/tlsexetocrs.d, * testsuite/ld-powerpc/tlsexetocrs.r, * testsuite/ld-powerpc/tlsopt6.d, * testsuite/ld-powerpc/tlsopt6.wf: New. * testsuite/ld-powerpc/powerpc.exp: Run new tests.
Diffstat (limited to 'ld/emultempl')
-rw-r--r--ld/emultempl/ppc64elf.em20
1 files changed, 19 insertions, 1 deletions
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index caa4f82..6633f81 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -36,7 +36,7 @@ static void ppc_layout_sections_again (void);
static struct ppc64_elf_params params = { NULL,
&ppc_add_stub_section,
&ppc_layout_sections_again,
- 1, -1, 0,
+ 1, -1, -1, 0,
${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 5,
-1, 0, -1, -1, 0};
@@ -694,6 +694,8 @@ enum ppc64_opt
OPTION_NO_TLS_OPT,
OPTION_TLS_GET_ADDR_OPT,
OPTION_NO_TLS_GET_ADDR_OPT,
+ OPTION_TLS_GET_ADDR_REGSAVE,
+ OPTION_NO_TLS_GET_ADDR_REGSAVE,
OPTION_NO_OPD_OPT,
OPTION_NO_INLINE_OPT,
OPTION_NO_TOC_OPT,
@@ -722,6 +724,8 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
{ "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
{ "tls-get-addr-optimize", no_argument, NULL, OPTION_TLS_GET_ADDR_OPT },
{ "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
+ { "tls-get-addr-regsave", no_argument, NULL, OPTION_TLS_GET_ADDR_REGSAVE },
+ { "no-tls-get-addr-regsave", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_REGSAVE},
{ "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
{ "no-inline-optimize", no_argument, NULL, OPTION_NO_INLINE_OPT },
{ "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
@@ -798,6 +802,12 @@ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
--no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call\n"
));
fprintf (file, _("\
+ --tls-get-addr-regsave Force register save __tls_get_addr stub\n"
+ ));
+ fprintf (file, _("\
+ --no-tls-get-addr-regsave Don'\''t use register save __tls_get_addr stub\n"
+ ));
+ fprintf (file, _("\
--no-opd-optimize Don'\''t optimize the OPD section\n"
));
fprintf (file, _("\
@@ -905,6 +915,14 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
params.tls_get_addr_opt = 0;
break;
+ case OPTION_TLS_GET_ADDR_REGSAVE:
+ params.no_tls_get_addr_regsave = 0;
+ break;
+
+ case OPTION_NO_TLS_GET_ADDR_REGSAVE:
+ params.no_tls_get_addr_regsave = 1;
+ break;
+
case OPTION_NO_OPD_OPT:
no_opd_opt = 1;
break;