From 7c9cf4158452094f4c463676e5122c5c4ce64de8 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 18 Sep 2015 16:17:49 +0930 Subject: [PATCH] Add PowerPC64 ld --tls-get-addr-optimize. Sometimes it may be of benefit to force use of the __tls_get_addr_opt call stub even when the glibc being used during linking does not advertise __tls_get_addr_opt. bfd/ * elf64-ppc.h (struct ppc64_elf_params ): Rename from no_tls_get_addr_opt. * elf64-ppc.c: Update for rename and inversion of tls_get_addr_opt. (ppc64_elf_tls_setup): Set tls_get_addr_opt to 0 only when at default of -1. ld/ * emultempl/ppc64elf.em (params): Init tls_get_addr_opt field to -1. (OPTION_TLS_GET_ADDR_OPT): Define. (PARSE_AND_LIST_LONGOPTS): Handle --tls-get-addr-opt. (PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Likewise. * ld.texinfo: Document --tls-get-addr-optimize and --no-tls-get-addr-optimize. --- bfd/ChangeLog | 8 ++++++++ bfd/elf64-ppc.c | 16 ++++++++-------- bfd/elf64-ppc.h | 2 +- ld/ChangeLog | 9 +++++++++ ld/emultempl/ppc64elf.em | 17 +++++++++++++---- ld/ld.texinfo | 15 +++++++++++++++ 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 26a0537..3e0c7b8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2015-09-18 Alan Modra + + * elf64-ppc.h (struct ppc64_elf_params ): Rename + from no_tls_get_addr_opt. + * elf64-ppc.c: Update for rename and inversion of tls_get_addr_opt. + (ppc64_elf_tls_setup): Set tls_get_addr_opt to 0 only when at + default of -1. + 2015-09-17 Alan Modra PR 18867 diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index f179f6d..5ad5f48 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -8136,7 +8136,7 @@ ppc64_elf_tls_setup (struct bfd_link_info *info) htab->tls_get_addr_fd = ((struct ppc_link_hash_entry *) elf_link_hash_lookup (&htab->elf, "__tls_get_addr", FALSE, FALSE, TRUE)); - if (!htab->params->no_tls_get_addr_opt) + if (htab->params->tls_get_addr_opt) { struct elf_link_hash_entry *opt, *opt_fd, *tga, *tga_fd; @@ -8203,8 +8203,8 @@ ppc64_elf_tls_setup (struct bfd_link_info *info) } } } - else - htab->params->no_tls_get_addr_opt = TRUE; + else if (htab->params->tls_get_addr_opt < 0) + htab->params->tls_get_addr_opt = 0; } return _bfd_elf_tls_setup (info->output_bfd, info); } @@ -10125,7 +10125,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd, return FALSE; } - tls_opt = (!htab->params->no_tls_get_addr_opt + tls_opt = (htab->params->tls_get_addr_opt && htab->tls_get_addr_fd != NULL && htab->tls_get_addr_fd->elf.plt.plist != NULL); if (tls_opt || !htab->opd_abi) @@ -10310,7 +10310,7 @@ plt_stub_size (struct ppc_link_hash_table *htab, if (stub_entry->h != NULL && (stub_entry->h == htab->tls_get_addr_fd || stub_entry->h == htab->tls_get_addr) - && !htab->params->no_tls_get_addr_opt) + && htab->params->tls_get_addr_opt) size += 13 * 4; return size; } @@ -10354,7 +10354,7 @@ build_plt_stub (struct ppc_link_hash_table *htab, && plt_thread_safe && !((stub_entry->h == htab->tls_get_addr_fd || stub_entry->h == htab->tls_get_addr) - && !htab->params->no_tls_get_addr_opt)) + && htab->params->tls_get_addr_opt)) { bfd_vma pltoff = stub_entry->plt_ent->plt.offset & ~1; bfd_vma pltindex = ((pltoff - PLT_INITIAL_ENTRY_SIZE (htab)) @@ -11005,7 +11005,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) if (stub_entry->h != NULL && (stub_entry->h == htab->tls_get_addr_fd || stub_entry->h == htab->tls_get_addr) - && !htab->params->no_tls_get_addr_opt) + && htab->params->tls_get_addr_opt) p = build_tls_get_addr_stub (htab, stub_entry, loc, off, r); else p = build_plt_stub (htab, stub_entry, loc, off, r); @@ -13911,7 +13911,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, if (h != NULL && (h == htab->tls_get_addr_fd || h == htab->tls_get_addr) - && !htab->params->no_tls_get_addr_opt) + && htab->params->tls_get_addr_opt) { /* Special stub used, leave nop alone. */ } diff --git a/bfd/elf64-ppc.h b/bfd/elf64-ppc.h index 19f72b5..d035ffc 100644 --- a/bfd/elf64-ppc.h +++ b/bfd/elf64-ppc.h @@ -34,7 +34,7 @@ struct ppc64_elf_params bfd_signed_vma group_size; /* Whether to use a special call stub for __tls_get_addr. */ - int no_tls_get_addr_opt; + int tls_get_addr_opt; /* Whether to allow multiple toc sections. */ int no_multi_toc; diff --git a/ld/ChangeLog b/ld/ChangeLog index 96359f5..f495ed2 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,14 @@ 2015-09-18 Alan Modra + * emultempl/ppc64elf.em (params): Init tls_get_addr_opt field to -1. + (OPTION_TLS_GET_ADDR_OPT): Define. + (PARSE_AND_LIST_LONGOPTS): Handle --tls-get-addr-opt. + (PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Likewise. + * ld.texinfo: Document --tls-get-addr-optimize and + --no-tls-get-addr-optimize. + +2015-09-18 Alan Modra + PR ld/18963 * ldexp.h (struct ldexp_control): Add rel_from_abs. (ldexp_finalize_syms): Declare. diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em index 41942f9..08bd5d4 100644 --- a/ld/emultempl/ppc64elf.em +++ b/ld/emultempl/ppc64elf.em @@ -37,7 +37,7 @@ static void ppc_layout_sections_again (void); static struct ppc64_elf_params params = { NULL, &ppc_add_stub_section, &ppc_layout_sections_again, - 1, 0, 0, + 1, -1, 0, ${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 0, 0, -1, -1, 0}; @@ -699,7 +699,8 @@ PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}' #define OPTION_DOTSYMS (OPTION_NO_SAVRES + 1) #define OPTION_NO_DOTSYMS (OPTION_DOTSYMS + 1) #define OPTION_NO_TLS_OPT (OPTION_NO_DOTSYMS + 1) -#define OPTION_NO_TLS_GET_ADDR_OPT (OPTION_NO_TLS_OPT + 1) +#define OPTION_TLS_GET_ADDR_OPT (OPTION_NO_TLS_OPT + 1) +#define OPTION_NO_TLS_GET_ADDR_OPT (OPTION_TLS_GET_ADDR_OPT + 1) #define OPTION_NO_OPD_OPT (OPTION_NO_TLS_GET_ADDR_OPT + 1) #define OPTION_NO_TOC_OPT (OPTION_NO_OPD_OPT + 1) #define OPTION_NO_MULTI_TOC (OPTION_NO_TOC_OPT + 1) @@ -722,6 +723,7 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}' { "save-restore-funcs", no_argument, NULL, OPTION_SAVRES }, { "no-save-restore-funcs", no_argument, NULL, OPTION_NO_SAVRES }, { "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 }, { "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT }, { "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT }, @@ -786,6 +788,9 @@ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}' --no-tls-optimize Don'\''t try to optimize TLS accesses.\n" )); fprintf (file, _("\ + --tls-get-addr-optimize Force use of special __tls_get_addr call.\n" + )); + fprintf (file, _("\ --no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call.\n" )); fprintf (file, _("\ @@ -877,8 +882,12 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}' no_tls_opt = 1; break; + case OPTION_TLS_GET_ADDR_OPT: + params.tls_get_addr_opt = 1; + break; + case OPTION_NO_TLS_GET_ADDR_OPT: - params.no_tls_get_addr_opt = 1; + params.tls_get_addr_opt = 0; break; case OPTION_NO_OPD_OPT: @@ -903,7 +912,7 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}' case OPTION_TRADITIONAL_FORMAT: no_tls_opt = 1; - params.no_tls_get_addr_opt = 1; + params.tls_get_addr_opt = 0; no_opd_opt = 1; no_toc_opt = 1; params.no_multi_toc = 1; diff --git a/ld/ld.texinfo b/ld/ld.texinfo index be1d490..57f1730 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -7133,6 +7133,21 @@ PowerPC64 @command{ld} normally performs some optimization of code sequences used to access Thread-Local Storage. Use this option to disable the optimization. +@cindex PowerPC64 __tls_get_addr optimization +@kindex --tls-get-addr-optimize +@kindex --no-tls-get-addr-optimize +@item --tls-get-addr-optimize, --no-tls-get-addr-optimize +These options control whether PowerPC64 @command{ld} uses a special +stub to call __tls_get_addr. PowerPC64 glibc 2.22 and later support +an optimization that allows the second and subsequent calls to +@code{__tls_get_addr} for a given symbol to be resolved by the special +stub without calling in to glibc. By default the linker enables this +option when glibc advertises the availability of __tls_get_addr_opt. +Forcing this option on when using an older glibc won't do much besides +slow down your applications, but may be useful if linking an +application against an older glibc with the expectation that it will +normally be used on systems having a newer glibc. + @cindex PowerPC64 OPD optimization @kindex --no-opd-optimize @item --no-opd-optimize -- 2.7.4