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 <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.
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.
This commit is contained in:
Alan Modra 2015-09-18 16:17:49 +09:30
parent 975f8a9e31
commit 7c9cf41584
6 changed files with 54 additions and 13 deletions

View File

@ -1,3 +1,11 @@
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

View File

@ -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. */
}

View File

@ -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;

View File

@ -1,3 +1,12 @@
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

View File

@ -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;

View File

@ -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