diff options
-rw-r--r-- | lld/ELF/OutputSections.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/Relocations.cpp | 10 | ||||
-rw-r--r-- | lld/test/ELF/x86-64-tls-gd-local.s | 52 |
3 files changed, 60 insertions, 4 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 8998968d8c9..b8f1adfa579 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -149,8 +149,8 @@ template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) { return false; Sym.GlobalDynIndex = Entries.size(); // Global Dynamic TLS entries take two GOT slots. - Entries.push_back(&Sym); Entries.push_back(nullptr); + Entries.push_back(&Sym); return true; } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 70e31e8a565..64ac84802dd 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -136,9 +136,13 @@ static unsigned handleTlsRelocation(uint32_t Type, SymbolBody &Body, uintX_t Off = Out<ELFT>::Got->getGlobalDynOffset(Body); Out<ELFT>::RelaDyn->addReloc( {Target->TlsModuleIndexRel, Out<ELFT>::Got, Off, false, &Body, 0}); - Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, Out<ELFT>::Got, - Off + (uintX_t)sizeof(uintX_t), false, - &Body, 0}); + + // If the symbol is preemptible we need the dynamic linker to write + // the offset too. + if (Body.isPreemptible()) + Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, Out<ELFT>::Got, + Off + (uintX_t)sizeof(uintX_t), false, + &Body, 0}); } C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; diff --git a/lld/test/ELF/x86-64-tls-gd-local.s b/lld/test/ELF/x86-64-tls-gd-local.s new file mode 100644 index 00000000000..843b891be56 --- /dev/null +++ b/lld/test/ELF/x86-64-tls-gd-local.s @@ -0,0 +1,52 @@ +// REQUIRES: x86 +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s + + .byte 0x66 + leaq foo@tlsgd(%rip), %rdi + .value 0x6666 + rex64 + call __tls_get_addr@PLT + + .byte 0x66 + leaq bar@tlsgd(%rip), %rdi + .value 0x6666 + rex64 + call __tls_get_addr@PLT + + .section .tbss,"awT",@nobits + + .hidden foo + .globl foo +foo: + .zero 4 + + .hidden bar + .globl bar +bar: + .zero 4 + + +// CHECK: Name: .got +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC (0x2) +// CHECK-NEXT: SHF_WRITE (0x1) +// CHECK-NEXT: ] +// CHECK-NEXT: Address: 0x20D0 +// CHECK-NEXT: Offset: 0x20D0 +// CHECK-NEXT: Size: 32 +// CHECK-NEXT: Link: 0 +// CHECK-NEXT: Info: 0 +// CHECK-NEXT: AddressAlignment: 8 +// CHECK-NEXT: EntrySize: 0 +// CHECK-NEXT: SectionData ( +// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................| +// CHECK-NEXT: 0010: 00000000 00000000 04000000 00000000 |................| +// CHECK-NEXT: ) + +// CHECK: Section ({{.*}}) .rela.dyn { +// CHECK-NEXT: 0x20D0 R_X86_64_DTPMOD64 - 0x0 +// CHECK-NEXT: 0x20E0 R_X86_64_DTPMOD64 - 0x0 +// CHECK-NEXT: } |