[lld] 7fefd03 - [ELF][MIPS] Emit dynamic relocations for PIC non-preemptible static TLS

Jessica Clarke via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 27 11:05:02 PDT 2021


Author: Jessica Clarke
Date: 2021-04-27T19:04:50+01:00
New Revision: 7fefd032cb260f96191089c9d817c61276d8bf66

URL: https://github.com/llvm/llvm-project/commit/7fefd032cb260f96191089c9d817c61276d8bf66
DIFF: https://github.com/llvm/llvm-project/commit/7fefd032cb260f96191089c9d817c61276d8bf66.diff

LOG: [ELF][MIPS] Emit dynamic relocations for PIC non-preemptible static TLS

This is the same problem as 127176e59eb9, but for static TLS rather than
dynamic TLS. Although we know the symbol will be the one in our own TLS
segment, and thus the offset of it within that, we don't know where in
the static TLS block our data will be allocated and thus we must emit a
dynamic relocation for this case.

Reviewed By: MaskRay, atanasyan

Differential Revision: https://reviews.llvm.org/D101381

Added: 
    

Modified: 
    lld/ELF/SyntheticSections.cpp
    lld/test/ELF/mips-tls-64.s
    lld/test/ELF/mips-tls.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 818bbdd0d42a..ab8e76f5c6f7 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -998,7 +998,10 @@ void MipsGotSection::build() {
     for (std::pair<Symbol *, size_t> &p : got.tls) {
       Symbol *s = p.first;
       uint64_t offset = p.second * config->wordsize;
-      if (s->isPreemptible)
+      // When building a shared library we still need a dynamic relocation
+      // for the TP-relative offset as we don't know how much other data will
+      // be allocated before us in the static TLS block.
+      if (s->isPreemptible || config->shared)
         mainPart->relaDyn->addReloc(target->tlsGotRel, this, offset, s);
     }
     for (std::pair<Symbol *, size_t> &p : got.dynTlsSymbols) {
@@ -1117,7 +1120,8 @@ void MipsGotSection::writeTo(uint8_t *buf) {
     for (const std::pair<Symbol *, size_t> &p : g.relocs)
       write(p.second, p.first, 0);
     for (const std::pair<Symbol *, size_t> &p : g.tls)
-      write(p.second, p.first, p.first->isPreemptible ? 0 : -0x7000);
+      write(p.second, p.first,
+            p.first->isPreemptible || config->shared ? 0 : -0x7000);
     for (const std::pair<Symbol *, size_t> &p : g.dynTlsSymbols) {
       if (p.first == nullptr && !config->shared)
         write(p.second, nullptr, 1);

diff  --git a/lld/test/ELF/mips-tls-64.s b/lld/test/ELF/mips-tls-64.s
index 5f22156ab531..4a191959ff5d 100644
--- a/lld/test/ELF/mips-tls-64.s
+++ b/lld/test/ELF/mips-tls-64.s
@@ -32,23 +32,25 @@
 
 # DIS:      Contents of section .got:
 # DIS-NEXT:  30000 00000000 00000000 80000000 00000000
-# DIS-NEXT:  30010 00000000 00000000 ffffffff ffff9004
-# DIS-NEXT:  30020 00000000 00000000 00000000 00000000
-# DIS-NEXT:  30030 00000000 00000001 00000000 00000000
-# DIS-NEXT:  30040 00000000 00000001 ffffffff ffff8004
+# DIS-NEXT:  30010 00000000 00000000 ffffffff ffff9000
+# DIS-NEXT:  30020 ffffffff ffff9004 00000000 00000000
+# DIS-NEXT:  30030 00000000 00000000 00000000 00000001
+# DIS-NEXT:  30040 00000000 00000000 00000000 00000001
+# DIS-NEXT:  30050 ffffffff ffff8004
 
 # DIS:      <__start>:
-# DIS-NEXT:    addiu   $2, $3, -32720
+# DIS-NEXT:    addiu   $2, $3, -32712
 # DIS-NEXT:    addiu   $2, $3, -32736
-# DIS-NEXT:    addiu   $2, $3, -32704
-# DIS-NEXT:    addiu   $2, $3, -32688
+# DIS-NEXT:    addiu   $2, $3, -32696
 # DIS-NEXT:    addiu   $2, $3, -32728
+# DIS-NEXT:    addiu   $2, $3, -32680
+# DIS-NEXT:    addiu   $2, $3, -32720
 
 # CHECK:      Relocations [
 # CHECK-NEXT:   Section (7) .rel.dyn {
 # CHECK-NEXT:     0x30010 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo
-# CHECK-NEXT:     0x30020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo
-# CHECK-NEXT:     0x30028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo
+# CHECK-NEXT:     0x30028 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo
+# CHECK-NEXT:     0x30030 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 # CHECK:      Primary GOT {
@@ -59,32 +61,35 @@
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   Global entries [
 # CHECK-NEXT:   ]
-# CHECK-NEXT:   Number of TLS and multi-GOT entries: 8
+# CHECK-NEXT:   Number of TLS and multi-GOT entries: 9
 #               ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64  foo
-#               ^-- -32728 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar
-#               ^-- -32720 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD64 foo
-#               ^-- -32712                     R_MIPS_TLS_DTPREL64 foo
-#               ^-- -32704 R_MIPS_TLS_LDM      1 loc
-#               ^-- -32696                     0 loc
-#               ^-- -32688 R_MIPS_TLS_GD       1 bar
-#               ^-- -32680                     VA - 0x8000 bar
+#               ^-- -32728 R_MIPS_TLS_GOTTPREL VA - 0x7000 loc
+#               ^-- -32720 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar
+#               ^-- -32712 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD64 foo
+#               ^-- -32704                     R_MIPS_TLS_DTPREL64 foo
+#               ^-- -32696 R_MIPS_TLS_LDM      1 loc
+#               ^-- -32688                     0 loc
+#               ^-- -32680 R_MIPS_TLS_GD       1 bar
+#               ^-- -32672                     VA - 0x8000 bar
 
 # DIS-SO:      Contents of section .got:
 # DIS-SO-NEXT:  30000 00000000 00000000 80000000 00000000
-# DIS-SO-NEXT:  30010 00000000 00000000 00000000 00000004
-# DIS-SO-NEXT:  30020 00000000 00000000 00000000 00000000
+# DIS-SO-NEXT:  30010 00000000 00000000 00000000 00000000
+# DIS-SO-NEXT:  30020 00000000 00000004 00000000 00000000
 # DIS-SO-NEXT:  30030 00000000 00000000 00000000 00000000
 # DIS-SO-NEXT:  30040 00000000 00000000 00000000 00000000
+# DIS-SO-NEXT:  30050 00000000 00000000
 
 # SO:      Relocations [
 # SO-NEXT:   Section (7) .rel.dyn {
-# SO-NEXT:     0x30030 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE -
+# SO-NEXT:     0x30018 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE -
+# SO-NEXT:     0x30038 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE -
 # SO-NEXT:     0x30010 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo
-# SO-NEXT:     0x30020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo
-# SO-NEXT:     0x30028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo
-# SO-NEXT:     0x30018 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE bar
-# SO-NEXT:     0x30040 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE bar
-# SO-NEXT:     0x30048 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE bar
+# SO-NEXT:     0x30028 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo
+# SO-NEXT:     0x30030 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo
+# SO-NEXT:     0x30020 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE bar
+# SO-NEXT:     0x30048 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE bar
+# SO-NEXT:     0x30050 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE bar
 # SO-NEXT:   }
 # SO-NEXT: ]
 # SO:      Primary GOT {
@@ -95,15 +100,16 @@
 # SO-NEXT:   ]
 # SO-NEXT:   Global entries [
 # SO-NEXT:   ]
-# SO-NEXT:   Number of TLS and multi-GOT entries: 8
+# SO-NEXT:   Number of TLS and multi-GOT entries: 9
 #            ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64  foo
-#            ^-- -32728 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64  bar
-#            ^-- -32720 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD64 foo
-#            ^-- -32712                     R_MIPS_TLS_DTPREL64 foo
-#            ^-- -32704 R_MIPS_TLS_LDM      R_MIPS_TLS_DTPMOD64 loc
-#            ^-- -32696                     0 loc
-#            ^-- -32688 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD64 bar
-#            ^-- -32680                     R_MIPS_TLS_DTPREL64 bar
+#            ^-- -32728 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64  loc
+#            ^-- -32720 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64  bar
+#            ^-- -32712 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD64 foo
+#            ^-- -32704                     R_MIPS_TLS_DTPREL64 foo
+#            ^-- -32696 R_MIPS_TLS_LDM      R_MIPS_TLS_DTPMOD64 loc
+#            ^-- -32688                     0 loc
+#            ^-- -32680 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD64 bar
+#            ^-- -32672                     R_MIPS_TLS_DTPREL64 bar
 
   .text
   .global  __start
@@ -111,6 +117,7 @@ __start:
   addiu $2, $3, %tlsgd(foo)     # R_MIPS_TLS_GD
   addiu $2, $3, %gottprel(foo)  # R_MIPS_TLS_GOTTPREL
   addiu $2, $3, %tlsldm(loc)    # R_MIPS_TLS_LDM
+  addiu $2, $3, %gottprel(loc)  # R_MIPS_TLS_GOTTPREL
   addiu $2, $3, %tlsgd(bar)     # R_MIPS_TLS_GD
   addiu $2, $3, %gottprel(bar)  # R_MIPS_TLS_GOTTPREL
 

diff  --git a/lld/test/ELF/mips-tls.s b/lld/test/ELF/mips-tls.s
index 4976ec3ecbcd..d93f03688b80 100644
--- a/lld/test/ELF/mips-tls.s
+++ b/lld/test/ELF/mips-tls.s
@@ -31,22 +31,23 @@
 # DIS: 00000004 g      .tdata          00000000 bar
 
 # DIS:      Contents of section .got:
-# DIS-NEXT:  30000 00000000 80000000 00000000 ffff9004
-# DIS-NEXT:  30010 00000000 00000000 00000001 00000000
-# DIS-NEXT:  30020 00000001 ffff8004
+# DIS-NEXT:  30000 00000000 80000000 00000000 ffff9000
+# DIS-NEXT:  30010 ffff9004 00000000 00000000 00000001
+# DIS-NEXT:  30020 00000000 00000001 ffff8004
 
 # DIS:      <__start>:
-# DIS-NEXT:    addiu   $2, $3, -32736
+# DIS-NEXT:    addiu   $2, $3, -32732
 # DIS-NEXT:    addiu   $2, $3, -32744
-# DIS-NEXT:    addiu   $2, $3, -32728
-# DIS-NEXT:    addiu   $2, $3, -32720
+# DIS-NEXT:    addiu   $2, $3, -32724
 # DIS-NEXT:    addiu   $2, $3, -32740
+# DIS-NEXT:    addiu   $2, $3, -32716
+# DIS-NEXT:    addiu   $2, $3, -32736
 
 # CHECK:      Relocations [
 # CHECK-NEXT:   Section (7) .rel.dyn {
 # CHECK-NEXT:     0x30008 R_MIPS_TLS_TPREL32 foo
-# CHECK-NEXT:     0x30010 R_MIPS_TLS_DTPMOD32 foo
-# CHECK-NEXT:     0x30014 R_MIPS_TLS_DTPREL32 foo
+# CHECK-NEXT:     0x30014 R_MIPS_TLS_DTPMOD32 foo
+# CHECK-NEXT:     0x30018 R_MIPS_TLS_DTPREL32 foo
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 # CHECK:      Primary GOT {
@@ -57,30 +58,32 @@
 # CHECK-NEXT:   ]
 # CHECK-NEXT:   Global entries [
 # CHECK-NEXT:   ]
-# CHECK-NEXT:   Number of TLS and multi-GOT entries: 8
+# CHECK-NEXT:   Number of TLS and multi-GOT entries: 9
 #               ^-- -32744 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32  foo
-#               ^-- -32740 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar
-#               ^-- -32736 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD32 foo
-#               ^-- -32732                     R_MIPS_TLS_DTPREL32 foo
-#               ^-- -32728 R_MIPS_TLS_LDM      1 loc
-#               ^-- -32724                     0 loc
-#               ^-- -32720 R_MIPS_TLS_GD       1 bar
-#               ^-- -32716                     VA - 0x8000 bar
+#               ^-- -32740 R_MIPS_TLS_GOTTPREL VA - 0x7000 loc
+#               ^-- -32736 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar
+#               ^-- -32732 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD32 foo
+#               ^-- -32728                     R_MIPS_TLS_DTPREL32 foo
+#               ^-- -32724 R_MIPS_TLS_LDM      1 loc
+#               ^-- -32720                     0 loc
+#               ^-- -32716 R_MIPS_TLS_GD       1 bar
+#               ^-- -32712                     VA - 0x8000 bar
 
 # DIS-SO:      Contents of section .got:
-# DIS-SO-NEXT:  30000 00000000 80000000 00000000 00000004
-# DIS-SO-NEXT:  30010 00000000 00000000 00000000 00000000
-# DIS-SO-NEXT:  30020 00000000 00000000
+# DIS-SO-NEXT:  30000 00000000 80000000 00000000 00000000
+# DIS-SO-NEXT:  30010 00000004 00000000 00000000 00000000
+# DIS-SO-NEXT:  30020 00000000 00000000 00000000
 
 # SO:      Relocations [
 # SO-NEXT:   Section (7) .rel.dyn {
-# SO-NEXT:     0x30018 R_MIPS_TLS_DTPMOD32 -
+# SO-NEXT:     0x3000C R_MIPS_TLS_TPREL32 -
+# SO-NEXT:     0x3001C R_MIPS_TLS_DTPMOD32 -
 # SO-NEXT:     0x30008 R_MIPS_TLS_TPREL32 foo
-# SO-NEXT:     0x30010 R_MIPS_TLS_DTPMOD32 foo
-# SO-NEXT:     0x30014 R_MIPS_TLS_DTPREL32 foo
-# SO-NEXT:     0x3000C R_MIPS_TLS_TPREL32 bar
-# SO-NEXT:     0x30020 R_MIPS_TLS_DTPMOD32 bar
-# SO-NEXT:     0x30024 R_MIPS_TLS_DTPREL32 bar
+# SO-NEXT:     0x30014 R_MIPS_TLS_DTPMOD32 foo
+# SO-NEXT:     0x30018 R_MIPS_TLS_DTPREL32 foo
+# SO-NEXT:     0x30010 R_MIPS_TLS_TPREL32 bar
+# SO-NEXT:     0x30024 R_MIPS_TLS_DTPMOD32 bar
+# SO-NEXT:     0x30028 R_MIPS_TLS_DTPREL32 bar
 # SO-NEXT:   }
 # SO-NEXT: ]
 # SO:      Primary GOT {
@@ -91,15 +94,16 @@
 # SO-NEXT:   ]
 # SO-NEXT:   Global entries [
 # SO-NEXT:   ]
-# SO-NEXT:   Number of TLS and multi-GOT entries: 8
+# SO-NEXT:   Number of TLS and multi-GOT entries: 9
 #            ^-- -32744 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32  foo
-#            ^-- -32740 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32  bar
-#            ^-- -32736 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD32 foo
-#            ^-- -32732 R_MIPS_TLS_DTPREL32 foo
-#            ^-- -32728 R_MIPS_TLS_LDM      R_MIPS_TLS_DTPMOD32 loc
-#            ^-- -32724 0 loc
-#            ^-- -32720 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD32 bar
-#            ^-- -32716 R_MIPS_TLS_DTPREL32 bar
+#            ^-- -32740 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32  loc
+#            ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32  bar
+#            ^-- -32732 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD32 foo
+#            ^-- -32728 R_MIPS_TLS_DTPREL32 foo
+#            ^-- -32724 R_MIPS_TLS_LDM      R_MIPS_TLS_DTPMOD32 loc
+#            ^-- -32720 0 loc
+#            ^-- -32716 R_MIPS_TLS_GD       R_MIPS_TLS_DTPMOD32 bar
+#            ^-- -32712 R_MIPS_TLS_DTPREL32 bar
 
   .text
   .global  __start
@@ -107,6 +111,7 @@ __start:
   addiu $2, $3, %tlsgd(foo)     # R_MIPS_TLS_GD
   addiu $2, $3, %gottprel(foo)  # R_MIPS_TLS_GOTTPREL
   addiu $2, $3, %tlsldm(loc)    # R_MIPS_TLS_LDM
+  addiu $2, $3, %gottprel(loc)  # R_MIPS_TLS_GOTTPREL
   addiu $2, $3, %tlsgd(bar)     # R_MIPS_TLS_GD
   addiu $2, $3, %gottprel(bar)  # R_MIPS_TLS_GOTTPREL
 


        


More information about the llvm-commits mailing list