diff options
author | Alan Modra <amodra@gmail.com> | 2017-08-26 20:26:13 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-08-26 20:52:07 +0930 |
commit | 7c8bbca5e670b5ea44b61ff30c5c7fcec47ee405 (patch) | |
tree | 4ac61df0b1b27367f5d47c71e2f7c361e2cfea5e /bfd/elf64-ppc.c | |
parent | 988f6b3dc615173d6d78a76ac26c109b4582da74 (diff) | |
download | gdb-7c8bbca5e670b5ea44b61ff30c5c7fcec47ee405.zip gdb-7c8bbca5e670b5ea44b61ff30c5c7fcec47ee405.tar.gz gdb-7c8bbca5e670b5ea44b61ff30c5c7fcec47ee405.tar.bz2 |
PowerPC TPREL reloc handling
Tidy how these are handled in PIEs.
* elf32-ppc.c (must_be_dyn_reloc): Use bfd_link_dll. Comment.
(ppc_elf_check_relocs): Only set DF_STATIC_TLS in shared libs.
(ppc_elf_relocate_section): Comment fix.
* elf64-ppc.c (must_be_dyn_reloc): Use bfd_link_dll. Comment.
(ppc64_elf_check_relocs): Only set DF_STATIC_TLS in shared libs.
Support dynamic relocs for TPREL16 when non-pic too.
(dec_dynrel_count): Adjust TPREL16 handling as per check_relocs.
(ppc64_elf_relocate_section): Support dynamic relocs for TPREL16
when non-pic too.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r-- | bfd/elf64-ppc.c | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index f0fde1d..7245038 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -3785,9 +3785,9 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, calls may use the function descriptor symbol, ie. "bl foo". This behaves exactly as "bl .foo". */ -/* Of those relocs that might be copied as dynamic relocs, this function - selects those that must be copied when linking a shared library, - even when the symbol is local. */ +/* Of those relocs that might be copied as dynamic relocs, this + function selects those that must be copied when linking a shared + library or PIE, even when the symbol is local. */ static int must_be_dyn_reloc (struct bfd_link_info *info, @@ -3796,6 +3796,10 @@ must_be_dyn_reloc (struct bfd_link_info *info, switch (r_type) { default: + /* Only relative relocs can be resolved when the object load + address isn't fixed. DTPREL64 is excluded because the + dynamic linker needs to differentiate global dynamic from + local dynamic __tls_index pairs when PPC64_OPT_TLS is set. */ return 1; case R_PPC64_REL32: @@ -3816,7 +3820,9 @@ must_be_dyn_reloc (struct bfd_link_info *info, case R_PPC64_TPREL16_HIGHEST: case R_PPC64_TPREL16_HIGHESTA: case R_PPC64_TPREL64: - return !bfd_link_executable (info); + /* These relocations are relative but in a shared library the + linker doesn't know the thread pointer base. */ + return bfd_link_dll (info); } } @@ -5496,7 +5502,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_PPC64_GOT_TPREL16_LO_DS: case R_PPC64_GOT_TPREL16_HI: case R_PPC64_GOT_TPREL16_HA: - if (bfd_link_pic (info)) + if (bfd_link_dll (info)) info->flags |= DF_STATIC_TLS; tls_type = TLS_TLS | TLS_TPREL; goto dogottls; @@ -5758,7 +5764,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_PPC64_TPREL64: tls_type = TLS_EXPLICIT | TLS_TLS | TLS_TPREL; - if (bfd_link_pic (info)) + if (bfd_link_dll (info)) info->flags |= DF_STATIC_TLS; goto dotlstoc; @@ -5834,12 +5840,9 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_PPC64_TPREL16_HIGHERA: case R_PPC64_TPREL16_HIGHEST: case R_PPC64_TPREL16_HIGHESTA: - if (bfd_link_pic (info)) - { - info->flags |= DF_STATIC_TLS; - goto dodyn; - } - break; + if (bfd_link_dll (info)) + info->flags |= DF_STATIC_TLS; + goto dodyn; case R_PPC64_ADDR64: if (opd_sym_map != NULL @@ -7798,9 +7801,6 @@ dec_dynrel_count (bfd_vma r_info, case R_PPC64_TPREL16_HIGHERA: case R_PPC64_TPREL16_HIGHEST: case R_PPC64_TPREL16_HIGHESTA: - if (!bfd_link_pic (info)) - return TRUE; - case R_PPC64_TPREL64: case R_PPC64_DTPMOD64: case R_PPC64_DTPREL64: @@ -14882,12 +14882,10 @@ ppc64_elf_relocate_section (bfd *output_bfd, } if (htab->elf.tls_sec != NULL) addend -= htab->elf.tls_sec->vma + TP_OFFSET; - if (bfd_link_pic (info)) - /* The TPREL16 relocs shouldn't really be used in shared - libs as they will result in DT_TEXTREL being set, but - support them anyway. */ - goto dodyn; - break; + /* The TPREL16 relocs shouldn't really be used in shared + libs or with non-local symbols as that will result in + DT_TEXTREL being set, but support them anyway. */ + goto dodyn; case R_PPC64_DTPREL16: case R_PPC64_DTPREL16_LO: |