]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
AArch64: When DF_BIND_NOW don't use TLSDESC GOT value.
authorTamar Christina <tamar.christina@arm.com>
Thu, 11 Apr 2019 10:27:28 +0000 (11:27 +0100)
committerTamar Christina <tamar.christina@arm.com>
Thu, 18 Apr 2019 14:28:40 +0000 (15:28 +0100)
When using DF_BIND_NOW on AArch64 we don't reserve the GOT slot for a TLSDESC,
but we still emitted DT_TLSDESC_GOT and DT_TLSDESC_PLT.  This caused random
memory corruption as the "special" value of (bfd_vma)-1 would be set for
dt_tlsdesc_got.

Since we don't have a value of dt_tlsdesc_got I also don't emit DT_TLSDESC_PLT
now becuase it would point to an incomplete PLT. To be able to write the PLT
entry DT_TLSDESC_GOT is needed and since we don't have one we can't write the
PLT entry either.

It is my understanding that GLIBC doesn't need these two entries when not lazy
loading.  Conversely AArch32 does not reserve neither the GOT not the PLT slot
when doing DF_BIND_NOW.

AArch32 does not need these checks because these values are initialized to 0
and so the if (...) checks don't pass, but on AArch64 these are initialized
to (bfd_vma)-1 and thus we need some extra checks.

bfd/ChangeLog:

PR ld/24302
* elfnn-aarch64.c (elfNN_aarch64_size_dynamic_sections): Don't emit
DT_TLSDESC_GOT and DT_TLSDESC_PLT when DF_BIND_NOW.
(elfNN_aarch64_finish_dynamic_sections): Don't write PLT if DF_BIND_NOW.

ld/ChangeLog:

PR ld/24302
* testsuite/ld-aarch64/aarch64-elf.exp: Add new test.
* testsuite/ld-aarch64/tls-relax-gdesc-le-now.d: New test.

(cherry picked from commit ce12121b63145322b4961bbb2b94b939cb916ba7)

bfd/ChangeLog
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/tls-relax-gdesc-le-now.d [new file with mode: 0644]

index 45255c0168addcfa24492c8d7427e0239e77c52c..e6979c1a44bfc866094768b88abce5899dedff54 100644 (file)
@@ -1,3 +1,13 @@
+2019-04-18  Tamar Christina  <tamar.christina@arm.com>
+
+       Backport from mainline.
+       2019-04-11  Tamar Christina  <tamar.christina@arm.com>
+
+       PR ld/24302
+       * elfnn-aarch64.c (elfNN_aarch64_size_dynamic_sections): Don't emit
+       DT_TLSDESC_GOT and DT_TLSDESC_PLT when DF_BIND_NOW.
+       (elfNN_aarch64_finish_dynamic_sections): Don't write PLT if DF_BIND_NOW.
+
 2019-04-17  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/24458
index faa27611d466ce75e5c02d8bbcfca6459618d4bd..9652cf3878e037e94a09121762043066fd61c4f1 100644 (file)
@@ -8848,13 +8848,14 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (htab->root.splt->size == 0)
        htab->root.splt->size += PLT_ENTRY_SIZE;
 
-      htab->tlsdesc_plt = htab->root.splt->size;
-      htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE;
 
       /* If we're not using lazy TLS relocations, don't generate the
-        GOT entry required.  */
+        GOT and PLT entry required.  */
       if (!(info->flags & DF_BIND_NOW))
        {
+         htab->tlsdesc_plt = htab->root.splt->size;
+         htab->root.splt->size += PLT_TLSDESC_ENTRY_SIZE;
+
          htab->dt_tlsdesc_got = htab->root.sgot->size;
          htab->root.sgot->size += GOT_ENTRY_SIZE;
        }
@@ -8958,6 +8959,7 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
            return FALSE;
 
          if (htab->tlsdesc_plt
+             && !(info->flags & DF_BIND_NOW)
              && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
                  || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
            return FALSE;
@@ -9445,6 +9447,7 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
 
            case DT_TLSDESC_GOT:
              s = htab->root.sgot;
+             BFD_ASSERT (htab->dt_tlsdesc_got != (bfd_vma)-1);
              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
                + htab->dt_tlsdesc_got;
              break;
@@ -9464,8 +9467,9 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
        this_hdr.sh_entsize = htab->plt_entry_size;
 
 
-      if (htab->tlsdesc_plt)
+      if (htab->tlsdesc_plt && !(info->flags & DF_BIND_NOW))
        {
+         BFD_ASSERT (htab->dt_tlsdesc_got != (bfd_vma)-1);
          bfd_put_NN (output_bfd, (bfd_vma) 0,
                      htab->root.sgot->contents + htab->dt_tlsdesc_got);
 
index f4b12a2f0a85ebfaa146a705e521b46025b1242b..6add6bb0314bb0b1bf307d1a67e776ce76611ac8 100644 (file)
@@ -1,3 +1,13 @@
+2019-04-18  Tamar Christina  <tamar.christina@arm.com>
+
+       Backport from mainline.
+       2019-04-11  Tamar Christina  <tamar.christina@arm.com>
+
+       PR ld/24302
+       * testsuite/ld-aarch64/aarch64-elf.exp: Add new test.
+       * testsuite/ld-aarch64/tls-relax-gdesc-le-now.d: New test.
+
+
 2019-04-17  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/24458
index 2b9fad5604b64d44e0fe48aa471bc726d9ce4332..ad0f8d9081da7b636e49939ef17a4942c6aebcdd 100644 (file)
@@ -256,6 +256,7 @@ run_dump_test "tls-relax-all-ilp32"
 run_dump_test "tls-relax-gd-le"
 run_dump_test "tls-relax-gd-le-ilp32"
 run_dump_test "tls-relax-gdesc-le"
+run_dump_test "tls-relax-gdesc-le-now"
 run_dump_test "tls-relax-gdesc-le-ilp32"
 run_dump_test "tls-relax-gd-ie"
 run_dump_test "tls-relax-gd-ie-ilp32"
diff --git a/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-now.d b/ld/testsuite/ld-aarch64/tls-relax-gdesc-le-now.d
new file mode 100644 (file)
index 0000000..f1565e9
--- /dev/null
@@ -0,0 +1,19 @@
+#source: tls-relax-gdesc-le.s
+#ld: -shared -z now
+#readelf: -dr
+#...
+ 0x.+ \(STRTAB\)   \s+0x.+
+ 0x.+ \(SYMTAB\)   \s+0x.+
+ 0x.+ \(STRSZ\)    \s+.+ \(bytes\)
+ 0x.+ \(SYMENT\)   \s+.+ \(bytes\)
+ 0x.+ \(PLTGOT\)   \s+0x.+
+ 0x.+ \(PLTRELSZ\) \s+.+ \(bytes\)
+ 0x.+ \(PLTREL\)   \s+RELA
+ 0x.+ \(JMPREL\)   \s+0x.+
+ 0x.+ \(BIND_NOW\) \s+
+ 0x.+ \(FLAGS_1\)  \s+   Flags: NOW
+ 0x.+ \(NULL\)     \s+   0x0
+
+Relocation section '\.rela\.plt' at offset .+ contains 1 entry:
+  Offset          Info           Type           Sym\. Value    Sym\. Name \+ Addend
+.+  .+ R_AARCH64_TLSDESC                    0