aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-08-30 20:35:09 +0930
committerAlan Modra <amodra@gmail.com>2017-08-30 20:35:09 +0930
commitb9f04fe0dfe64bc6224e7bb96378607f17da7446 (patch)
treec97562790bfe1c4b7e81aab4a9368666ef177a6b /bfd
parentc7dffc390cf861b313001fd08049a5fd8d758d0d (diff)
downloadgdb-b9f04fe0dfe64bc6224e7bb96378607f17da7446.zip
gdb-b9f04fe0dfe64bc6224e7bb96378607f17da7446.tar.gz
gdb-b9f04fe0dfe64bc6224e7bb96378607f17da7446.tar.bz2
PowerPC64 __tls_get_addr sequence optimization
There isn't a good reason for ld.bfd to behave differently from gold in the code generated by TLS GD/LD to LE optimization. bfd/ * elf64-ppc.c (ppc64_elf_relocate_section): When optimizing __tls_get_addr call sequences to LE, don't move the addi down to the nop. Replace the bl with addi and leave the nop alone. ld/ * testsuite/ld-powerpc/tls.d: Update. * testsuite/ld-powerpc/tlsexe.d: Update. * testsuite/ld-powerpc/tlsexetoc.d: Update. * testsuite/ld-powerpc/tlsld.d: Update. * testsuite/ld-powerpc/tlsmark.d: Update. * testsuite/ld-powerpc/tlsopt4.d: Update. * testsuite/ld-powerpc/tlstoc.d: Update.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf64-ppc.c37
2 files changed, 10 insertions, 33 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1d54f03..ec74d9d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2017-08-30 Alan Modra <amodra@gmail.com>
+
+ * elf64-ppc.c (ppc64_elf_relocate_section): When optimizing
+ __tls_get_addr call sequences to LE, don't move the addi down
+ to the nop. Replace the bl with addi and leave the nop alone.
+
2017-08-29 H.J. Lu <hongjiu.lu@intel.com>
* elf32-i386.c (elf_i386_pie_finish_undefweak_symbol):
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 7245038..5b96a04 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -13916,7 +13916,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_GOT_TLSLD16_LO:
if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
{
- unsigned int insn1, insn2, insn3;
+ unsigned int insn1, insn2;
bfd_vma offset;
tls_ldgd_opt:
@@ -13995,18 +13995,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
bfd_put_32 (input_bfd, insn1,
contents + rel->r_offset - d_offset);
if (offset != (bfd_vma) -1)
- {
- insn3 = bfd_get_32 (input_bfd,
- contents + offset + 4);
- if (insn3 == NOP
- || insn3 == CROR_151515 || insn3 == CROR_313131)
- {
- rel[1].r_offset += 4;
- bfd_put_32 (input_bfd, insn2, contents + offset + 4);
- insn2 = NOP;
- }
- bfd_put_32 (input_bfd, insn2, contents + offset);
- }
+ bfd_put_32 (input_bfd, insn2, contents + offset);
if ((tls_mask & tls_gd) == 0
&& (tls_gd == 0 || toc_symndx != 0))
{
@@ -14020,7 +14009,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_TLSGD:
if (tls_mask != 0 && (tls_mask & TLS_GD) == 0)
{
- unsigned int insn2, insn3;
+ unsigned int insn2;
bfd_vma offset = rel->r_offset;
if ((tls_mask & TLS_TPRELGD) != 0)
@@ -14045,15 +14034,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
/* Zap the reloc on the _tls_get_addr call too. */
BFD_ASSERT (offset == rel[1].r_offset);
rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
- insn3 = bfd_get_32 (input_bfd,
- contents + offset + 4);
- if (insn3 == NOP
- || insn3 == CROR_151515 || insn3 == CROR_313131)
- {
- rel->r_offset += 4;
- bfd_put_32 (input_bfd, insn2, contents + offset + 4);
- insn2 = NOP;
- }
bfd_put_32 (input_bfd, insn2, contents + offset);
if ((tls_mask & TLS_TPRELGD) == 0 && toc_symndx != 0)
goto again;
@@ -14063,7 +14043,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_TLSLD:
if (tls_mask != 0 && (tls_mask & TLS_LD) == 0)
{
- unsigned int insn2, insn3;
+ unsigned int insn2;
bfd_vma offset = rel->r_offset;
if (toc_symndx)
@@ -14088,15 +14068,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
BFD_ASSERT (offset == rel[1].r_offset);
rel[1].r_info = ELF64_R_INFO (STN_UNDEF, R_PPC64_NONE);
insn2 = 0x38630000; /* addi 3,3,0 */
- insn3 = bfd_get_32 (input_bfd,
- contents + offset + 4);
- if (insn3 == NOP
- || insn3 == CROR_151515 || insn3 == CROR_313131)
- {
- rel->r_offset += 4;
- bfd_put_32 (input_bfd, insn2, contents + offset + 4);
- insn2 = NOP;
- }
bfd_put_32 (input_bfd, insn2, contents + offset);
goto again;
}