aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-08-26 20:26:13 +0930
committerAlan Modra <amodra@gmail.com>2017-08-26 20:52:07 +0930
commit7c8bbca5e670b5ea44b61ff30c5c7fcec47ee405 (patch)
tree4ac61df0b1b27367f5d47c71e2f7c361e2cfea5e
parent988f6b3dc615173d6d78a76ac26c109b4582da74 (diff)
downloadgdb-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.
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/elf32-ppc.c24
-rw-r--r--bfd/elf64-ppc.c40
3 files changed, 46 insertions, 30 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index cefe1f1..e785d0e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2017-08-26 Alan Modra <amodra@gmail.com>
+
+ * 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.
+
2017-08-25 H.J. Lu <hongjiu.lu@intel.com>
* elf32-i386.c (elf_i386_link_hash_entry): Remove redundant
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index ac3b12bb..a5d8193 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -3192,9 +3192,9 @@ struct plt_entry
bfd_vma glink_offset;
};
-/* 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,
@@ -3203,6 +3203,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. DTPREL32 is excluded because the
+ dynamic linker needs to differentiate global dynamic from
+ local dynamic __tls_index pairs when PPC_OPT_TLS is set. */
return 1;
case R_PPC_REL24:
@@ -3217,7 +3221,9 @@ must_be_dyn_reloc (struct bfd_link_info *info,
case R_PPC_TPREL16_LO:
case R_PPC_TPREL16_HI:
case R_PPC_TPREL16_HA:
- 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);
}
}
@@ -4151,7 +4157,7 @@ ppc_elf_check_relocs (bfd *abfd,
case R_PPC_GOT_TPREL16_LO:
case R_PPC_GOT_TPREL16_HI:
case R_PPC_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;
@@ -4430,13 +4436,13 @@ ppc_elf_check_relocs (bfd *abfd,
return FALSE;
break;
- /* We shouldn't really be seeing these. */
+ /* We shouldn't really be seeing TPREL32. */
case R_PPC_TPREL32:
case R_PPC_TPREL16:
case R_PPC_TPREL16_LO:
case R_PPC_TPREL16_HI:
case R_PPC_TPREL16_HA:
- if (bfd_link_pic (info))
+ if (bfd_link_dll (info))
info->flags |= DF_STATIC_TLS;
goto dodyn;
@@ -8783,8 +8789,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
if (htab->elf.tls_sec != NULL)
addend -= htab->elf.tls_sec->vma + TP_OFFSET;
/* The TPREL16 relocs shouldn't really be used in shared
- libs as they will result in DT_TEXTREL being set, but
- support them anyway. */
+ libs or with non-local symbols as that will result in
+ DT_TEXTREL being set, but support them anyway. */
goto dodyn;
case R_PPC_TPREL32:
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: