PR ld/22570: MIPS/BFD: Fix TLS relocation resolution for PIE executables
authorMaciej W. Rozycki <macro@mips.com>
Wed, 11 Jul 2018 16:44:45 +0000 (17:44 +0100)
committerMaciej W. Rozycki <macro@mips.com>
Wed, 11 Jul 2018 16:44:45 +0000 (17:44 +0100)
Correct a commit 0e1862bb401f ("Add output_type to bfd_link_info") issue
and use `bfd_link_dll' rather than `bfd_link_pic' in determining whether
to fully resolve GD, LD and IE TLS relocations referring to symbols
locally defined rather than deferring them to the load time by means of
dynamic relocations.

Such symbols cannot be preempted in PIE executables, which are
necessarily PIC, and therefore their values (thread pointer offsets) are
fixed at the static link time as is the associated module ID of the main
executable.

Given the `tlsbin-o32.s' and `tlsdyn-o32.s' sources from our test suite
this removes the absolute TLS relocations from the static:

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
00000000 R_MIPS_NONE       *ABS*
1000002c R_MIPS_TLS_TPREL32  *ABS*
10000030 R_MIPS_TLS_DTPMOD32  *ABS*
10000038 R_MIPS_TLS_DTPMOD32  *ABS*

and the dynamic:

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
00000000 R_MIPS_NONE       *ABS*
1000002c R_MIPS_TLS_TPREL32  *ABS*
10000038 R_MIPS_TLS_DTPMOD32  *ABS*
10000044 R_MIPS_TLS_DTPMOD32  *ABS*
10000030 R_MIPS_TLS_DTPMOD32  tlsvar_gd
10000034 R_MIPS_TLS_DTPREL32  tlsvar_gd
10000040 R_MIPS_TLS_TPREL32  tlsvar_ie

PIE executable respectively, as reported by `objdump -R', and fills the
corresponding GOT slots with the values expected, as recorded with the
test cases added.  The new output from `objdump -R' is:

DYNAMIC RELOCATION RECORDS (none)

and:

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
00000000 R_MIPS_NONE       *ABS*
10000030 R_MIPS_TLS_DTPMOD32  tlsvar_gd
10000034 R_MIPS_TLS_DTPREL32  tlsvar_gd
10000040 R_MIPS_TLS_TPREL32  tlsvar_ie

for the static and the dynamic executable respectively.

2018-07-11  Maciej W. Rozycki  <macro@mips.com>
            Rich Felker  <bugdal@aerifal.cx>

bfd/
PR ld/22570
* elfxx-mips.c (mips_tls_got_relocs): Use `bfd_link_dll' rather
than `bfd_link_pic' to determine whether dynamic relocations are
to be produced.
(mips_elf_initialize_tls_slots): Likewise.

ld/
PR ld/22570
* testsuite/ld-mips-elf/tlsbin-pie-o32.d: New test.
* testsuite/ld-mips-elf/tlsbin-pie-o32.got: New test.
* testsuite/ld-mips-elf/tlsdyn-pie-o32.d: New test.
* testsuite/ld-mips-elf/tlsdyn-pie-o32.got: New test.
* testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.

bfd/ChangeLog
bfd/elfxx-mips.c
ld/ChangeLog
ld/testsuite/ld-mips-elf/mips-elf.exp
ld/testsuite/ld-mips-elf/tlsbin-pie-o32.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/tlsbin-pie-o32.got [new file with mode: 0644]
ld/testsuite/ld-mips-elf/tlsdyn-pie-o32.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/tlsdyn-pie-o32.got [new file with mode: 0644]

index dd6ecd959d74b5f45277e216bea61ff94f66528e..402cdc49deb32a5a7b2565a0e07ad45e1fd5215f 100644 (file)
@@ -1,3 +1,12 @@
+2018-07-11  Maciej W. Rozycki  <macro@mips.com>
+           Rich Felker  <bugdal@aerifal.cx>
+
+       PR ld/22570
+       * elfxx-mips.c (mips_tls_got_relocs): Use `bfd_link_dll' rather
+       than `bfd_link_pic' to determine whether dynamic relocations are
+       to be produced.
+       (mips_elf_initialize_tls_slots): Likewise.
+
 2018-07-10  Maciej W. Rozycki  <macro@mips.com>
 
        * elflink.c (bfd_elf_final_link): Rename `remove' local variable
index 990e3a1e551c19a321ee64c24de3b6a1bf4965d4..a35390783b22fed07592510336b9c849ecaebe37 100644 (file)
@@ -3255,7 +3255,7 @@ mips_tls_got_relocs (struct bfd_link_info *info, unsigned char tls_type,
       && (!bfd_link_pic (info) || !SYMBOL_REFERENCES_LOCAL (info, h)))
     indx = h->dynindx;
 
-  if ((bfd_link_pic (info) || indx != 0)
+  if ((bfd_link_dll (info) || indx != 0)
       && (h == NULL
          || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
          || h->root.type != bfd_link_hash_undefweak))
@@ -3273,7 +3273,7 @@ mips_tls_got_relocs (struct bfd_link_info *info, unsigned char tls_type,
       return 1;
 
     case GOT_TLS_LDM:
-      return bfd_link_pic (info) ? 1 : 0;
+      return bfd_link_dll (info) ? 1 : 0;
 
     default:
       return 0;
@@ -3367,7 +3367,7 @@ mips_elf_initialize_tls_slots (bfd *abfd, struct bfd_link_info *info,
   if (entry->tls_initialized)
     return;
 
-  if ((bfd_link_pic (info) || indx != 0)
+  if ((bfd_link_dll (info) || indx != 0)
       && (h == NULL
          || ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT
          || h->root.type != bfd_link_hash_undefweak))
@@ -3442,7 +3442,7 @@ mips_elf_initialize_tls_slots (bfd *abfd, struct bfd_link_info *info,
                         sgot->contents + got_offset
                         + MIPS_ELF_GOT_SIZE (abfd));
 
-      if (!bfd_link_pic (info))
+      if (!bfd_link_dll (info))
        MIPS_ELF_PUT_WORD (abfd, 1,
                           sgot->contents + got_offset);
       else
index f2c1103e741138519fa36e89b40477c49d5b4aa4..ea5468f7bf59cd469c529cd9304396a8a8479e96 100644 (file)
@@ -1,3 +1,12 @@
+2018-07-11  Maciej W. Rozycki  <macro@mips.com>
+
+       PR ld/22570
+       * testsuite/ld-mips-elf/tlsbin-pie-o32.d: New test.
+       * testsuite/ld-mips-elf/tlsbin-pie-o32.got: New test.
+       * testsuite/ld-mips-elf/tlsdyn-pie-o32.d: New test.
+       * testsuite/ld-mips-elf/tlsdyn-pie-o32.got: New test.
+       * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
+
 2018-07-11  Alan Modra  <amodra@gmail.com>
 
        * testsuite/ld-elf/hash.d: Comment on mips xfail.
index 6aae2f9959081dd16b4191ba38b70b5c9d33f884..ba3f16168edb5ac2c20f384112b3aefb176ab588 100644 (file)
@@ -863,6 +863,12 @@ set mips_tls_tests {
      "-EB -march=mips1 -32 -KPIC" {tlsbin-o32.s}
      {{objdump {-dr -m mips:isa32r2} tlsbin-o32.d} {objdump -srj.got tlsbin-o32.got}}
      "tls-static-o32"}
+    {"Static PIE executable with TLS"
+     "-static -pie -melf32btsmip -T mips-dyn.ld" ""
+     "-EB -march=mips1 -32 -KPIC" {tlsbin-o32.s}
+     {{objdump {-dr -m mips:isa32r2} tlsbin-pie-o32.d}
+      {objdump -Rsj.got tlsbin-pie-o32.got}}
+     "tls-static-pie-o32"}
     {"Shared library with TLS" "-shared -melf32btsmip -T mips-lib.ld" ""
      "-EB -march=mips1 -32 -KPIC" {tlslib-o32.s}
      {{objdump {-dr -m mips:isa32r2} tlslib-o32.d} {objdump -Rsj.got tlslib-o32.got}}
@@ -872,6 +878,12 @@ set mips_tls_tests {
      "-EB -march=mips1 -32 -KPIC" {tlsdyn-o32.s}
      {{objdump {-dr -m mips:isa32r2} tlsdyn-o32.d} {objdump -Rsj.got tlsdyn-o32.got}}
      "tls-dynamic-o32"}
+    {"Dynamic PIE executable with TLS"
+     "-pie -melf32btsmip -T mips-dyn.ld tmpdir/tlslib-o32.so" ""
+     "-EB -march=mips1 -32 -KPIC" {tlsdyn-o32.s}
+     {{objdump {-dr -m mips:isa32r2} tlsdyn-pie-o32.d}
+      {objdump -Rsj.got tlsdyn-pie-o32.got}}
+     "tls-dynamic-pie-o32"}
     {"Shared library with multiple GOTs and TLS"
      "-shared -melf32btsmip -T mips-lib.ld" ""
      "-EB -march=mips1 -32 -KPIC" {tls-multi-got-1-1.s tls-multi-got-1-2.s}
diff --git a/ld/testsuite/ld-mips-elf/tlsbin-pie-o32.d b/ld/testsuite/ld-mips-elf/tlsbin-pie-o32.d
new file mode 100644 (file)
index 0000000..1d6536d
--- /dev/null
@@ -0,0 +1,43 @@
+.*:     file format elf32-tradbigmips
+
+Disassembly of section \.text:
+
+.* <__start>:
+  .*:  3c1c0fc0        lui     gp,0xfc0
+  .*:  279c7d20        addiu   gp,gp,32032
+  .*:  0399e021        addu    gp,gp,t9
+  .*:  27bdfff0        addiu   sp,sp,-16
+  .*:  afbe0008        sw      s8,8\(sp\)
+  .*:  03a0f025        move    s8,sp
+  .*:  afbc0000        sw      gp,0\(sp\)
+  .*:  8f998018        lw      t9,-32744\(gp\)
+  .*:  27848020        addiu   a0,gp,-32736
+  .*:  0320f809        jalr    t9
+  .*:  00000000        nop
+  .*:  8fdc0000        lw      gp,0\(s8\)
+  .*:  00000000        nop
+  .*:  8f998018        lw      t9,-32744\(gp\)
+  .*:  27848028        addiu   a0,gp,-32728
+  .*:  0320f809        jalr    t9
+  .*:  00000000        nop
+  .*:  8fdc0000        lw      gp,0\(s8\)
+  .*:  00401025        move    v0,v0
+  .*:  3c030000        lui     v1,0x0
+  .*:  24638000        addiu   v1,v1,-32768
+  .*:  00621821        addu    v1,v1,v0
+  .*:  7c02283b        rdhwr   v0,\$5
+  .*:  8f83801c        lw      v1,-32740\(gp\)
+  .*:  00000000        nop
+  .*:  00621821        addu    v1,v1,v0
+  .*:  7c02283b        rdhwr   v0,\$5
+  .*:  3c030000        lui     v1,0x0
+  .*:  24639004        addiu   v1,v1,-28668
+  .*:  00621821        addu    v1,v1,v0
+  .*:  03c0e825        move    sp,s8
+  .*:  8fbe0008        lw      s8,8\(sp\)
+  .*:  03e00008        jr      ra
+  .*:  27bd0010        addiu   sp,sp,16
+
+.* <__tls_get_addr>:
+  .*:  03e00008        jr      ra
+  .*:  00000000        nop
diff --git a/ld/testsuite/ld-mips-elf/tlsbin-pie-o32.got b/ld/testsuite/ld-mips-elf/tlsbin-pie-o32.got
new file mode 100644 (file)
index 0000000..c5efbb7
--- /dev/null
@@ -0,0 +1,7 @@
+.*:     file format elf32-tradbigmips
+
+DYNAMIC RELOCATION RECORDS \(none\)
+
+Contents of section \.got:
+ 10000020 00000000 80000000 00400378 ffff900c  .*
+ 10000030 00000001 ffff8008 00000001 00000000  .*
diff --git a/ld/testsuite/ld-mips-elf/tlsdyn-pie-o32.d b/ld/testsuite/ld-mips-elf/tlsdyn-pie-o32.d
new file mode 100644 (file)
index 0000000..4df024f
--- /dev/null
@@ -0,0 +1,53 @@
+.*:     file format elf32-tradbigmips
+
+Disassembly of section \.text:
+
+.* <__start>:
+  .*:  3c1c0fc0        lui     gp,0xfc0
+  .*:  279c7bd0        addiu   gp,gp,31696
+  .*:  0399e021        addu    gp,gp,t9
+  .*:  27bdfff0        addiu   sp,sp,-16
+  .*:  afbe0008        sw      s8,8\(sp\)
+  .*:  03a0f025        move    s8,sp
+  .*:  afbc0000        sw      gp,0\(sp\)
+  .*:  8f998018        lw      t9,-32744\(gp\)
+  .*:  27848034        addiu   a0,gp,-32716
+  .*:  0320f809        jalr    t9
+  .*:  00000000        nop
+  .*:  8fdc0000        lw      gp,0\(s8\)
+  .*:  00000000        nop
+  .*:  8f998018        lw      t9,-32744\(gp\)
+  .*:  27848020        addiu   a0,gp,-32736
+  .*:  0320f809        jalr    t9
+  .*:  00000000        nop
+  .*:  8fdc0000        lw      gp,0\(s8\)
+  .*:  00000000        nop
+  .*:  8f998018        lw      t9,-32744\(gp\)
+  .*:  27848028        addiu   a0,gp,-32728
+  .*:  0320f809        jalr    t9
+  .*:  00000000        nop
+  .*:  8fdc0000        lw      gp,0\(s8\)
+  .*:  00401025        move    v0,v0
+  .*:  3c030000        lui     v1,0x0
+  .*:  24638000        addiu   v1,v1,-32768
+  .*:  00621821        addu    v1,v1,v0
+  .*:  7c02283b        rdhwr   v0,\$5
+  .*:  8f83801c        lw      v1,-32740\(gp\)
+  .*:  00000000        nop
+  .*:  00621821        addu    v1,v1,v0
+  .*:  8f838030        lw      v1,-32720\(gp\)
+  .*:  00000000        nop
+  .*:  00621821        addu    v1,v1,v0
+  .*:  7c02283b        rdhwr   v0,\$5
+  .*:  3c030000        lui     v1,0x0
+  .*:  24639004        addiu   v1,v1,-28668
+  .*:  00621821        addu    v1,v1,v0
+  .*:  03c0e825        move    sp,s8
+  .*:  8fbe0008        lw      s8,8\(sp\)
+  .*:  03e00008        jr      ra
+  .*:  27bd0010        addiu   sp,sp,16
+
+.* <__tls_get_addr>:
+  .*:  03e00008        jr      ra
+  .*:  00000000        nop
+       \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/tlsdyn-pie-o32.got b/ld/testsuite/ld-mips-elf/tlsdyn-pie-o32.got
new file mode 100644 (file)
index 0000000..c5dd695
--- /dev/null
@@ -0,0 +1,13 @@
+.*:     file format elf32-tradbigmips
+
+DYNAMIC RELOCATION RECORDS
+OFFSET   TYPE              VALUE 
+00000000 R_MIPS_NONE       \*ABS\*
+10000030 R_MIPS_TLS_DTPMOD32  tlsvar_gd
+10000034 R_MIPS_TLS_DTPREL32  tlsvar_gd
+10000040 R_MIPS_TLS_TPREL32  tlsvar_ie
+
+Contents of section .got:
+ 10000020 00000000 80000000 004004ec ffff900c  .*
+ 10000030 00000000 00000000 00000001 00000000  .*
+ 10000040 00000000 00000001 ffff8008           .*