binutils-gdb/bfd/elf64-ppc.h
Alan Modra 9e7028aa1e 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.
2020-01-22 17:14:08 +10:30

105 lines
3.4 KiB
C

/* PowerPC64-specific support for 64-bit ELF.
Copyright (C) 2002-2020 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
/* Used to pass info between ld and bfd. */
struct ppc64_elf_params
{
/* Linker stub bfd. */
bfd *stub_bfd;
/* Linker call-backs. */
asection * (*add_stub_section) (const char *, asection *);
void (*layout_sections_again) (void);
/* Maximum size of a group of input sections that can be handled by
one stub section. A value of +/-1 indicates the bfd back-end
should use a suitable default size. */
bfd_signed_vma group_size;
/* Whether to use a special call stub for __tls_get_addr. */
int tls_get_addr_opt;
/* Whether the special call stub should save r4..r12. */
int no_tls_get_addr_regsave;
/* Whether to allow multiple toc sections. */
int no_multi_toc;
/* Set if PLT call stubs should load r11. */
int plt_static_chain;
/* Set if PLT call stubs need to be thread safe on power7+. */
int plt_thread_safe;
/* Set if individual PLT call stubs should be aligned. */
int plt_stub_align;
/* Set if PLT call stubs for localentry:0 functions should omit r2 save. */
int plt_localentry0;
/* Whether to canonicalize .opd so that there are no overlapping
.opd entries. */
int non_overlapping_opd;
/* Whether to emit symbols for stubs. */
int emit_stub_syms;
/* Whether to generate out-of-line register save/restore for gcc -Os code. */
int save_restore_funcs;
/* Set when a potential variable is detected in .toc. */
int object_in_toc;
};
bfd_boolean ppc64_elf_init_stub_bfd
(struct bfd_link_info *, struct ppc64_elf_params *);
bfd_boolean ppc64_elf_edit_opd
(struct bfd_link_info *);
bfd_boolean ppc64_elf_inline_plt
(struct bfd_link_info *);
asection *ppc64_elf_tls_setup
(struct bfd_link_info *);
bfd_boolean ppc64_elf_tls_optimize
(struct bfd_link_info *);
bfd_boolean ppc64_elf_edit_toc
(struct bfd_link_info *);
bfd_boolean ppc64_elf_has_small_toc_reloc
(asection *);
bfd_vma ppc64_elf_set_toc
(struct bfd_link_info *, bfd *);
int ppc64_elf_setup_section_lists
(struct bfd_link_info *);
void ppc64_elf_start_multitoc_partition
(struct bfd_link_info *);
bfd_boolean ppc64_elf_next_toc_section
(struct bfd_link_info *, asection *);
bfd_boolean ppc64_elf_layout_multitoc
(struct bfd_link_info *);
void ppc64_elf_finish_multitoc_partition
(struct bfd_link_info *);
bfd_boolean ppc64_elf_check_init_fini
(struct bfd_link_info *);
bfd_boolean ppc64_elf_next_input_section
(struct bfd_link_info *, asection *);
bfd_boolean ppc64_elf_size_stubs
(struct bfd_link_info *);
bfd_boolean ppc64_elf_build_stubs
(struct bfd_link_info *, char **);