+2015-09-18 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.h (struct ppc64_elf_params <tls_get_addr_opt>): 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 <amodra@gmail.com>
PR 18867
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;
}
}
}
- 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);
}
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)
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;
}
&& 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))
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);
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. */
}
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;
2015-09-18 Alan Modra <amodra@gmail.com>
+ * 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 <amodra@gmail.com>
+
PR ld/18963
* ldexp.h (struct ldexp_control): Add rel_from_abs.
(ldexp_finalize_syms): Declare.
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};
#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)
{ "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 },
--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, _("\
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:
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;
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