[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