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) {
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);
# 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 {
# 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 {
# 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
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
# 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 {
# 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 {
# 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
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