diff options
-rw-r--r-- | lld/ELF/OutputSections.cpp | 8 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 3 | ||||
-rw-r--r-- | lld/test/ELF/aarch64-tls-static.s | 36 |
3 files changed, 41 insertions, 6 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index a795ce56e27..ae15bcc73bb 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -145,9 +145,9 @@ template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody &Sym) { } template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) { - if (Sym.symbol()->GlobalDynIndex != -1U) + if (Sym.GlobalDynIndex != -1U) return false; - Sym.symbol()->GlobalDynIndex = Entries.size(); + Sym.GlobalDynIndex = Entries.size(); // Global Dynamic TLS entries take two GOT slots. Entries.push_back(&Sym); Entries.push_back(nullptr); @@ -187,13 +187,13 @@ GotSection<ELFT>::getMipsLocalEntryOffset(uintX_t EntryValue) { template <class ELFT> typename GotSection<ELFT>::uintX_t GotSection<ELFT>::getGlobalDynAddr(const SymbolBody &B) const { - return this->getVA() + B.symbol()->GlobalDynIndex * sizeof(uintX_t); + return this->getVA() + B.GlobalDynIndex * sizeof(uintX_t); } template <class ELFT> typename GotSection<ELFT>::uintX_t GotSection<ELFT>::getGlobalDynOffset(const SymbolBody &B) const { - return B.symbol()->GlobalDynIndex * sizeof(uintX_t); + return B.GlobalDynIndex * sizeof(uintX_t); } template <class ELFT> diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index e719d574e23..2b6908dcebd 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -91,6 +91,7 @@ public: uint32_t GotPltIndex = -1; uint32_t PltIndex = -1; uint32_t ThunkIndex = -1; + uint32_t GlobalDynIndex = -1; bool isInGot() const { return GotIndex != -1U; } bool isInPlt() const { return PltIndex != -1U; } bool hasThunk() const { return ThunkIndex != -1U; } @@ -395,8 +396,6 @@ template <class ELFT> SymbolBody *ElfSym<ELFT>::MipsGpDisp; // stored in the Body field of this object as it resolves symbols. Symbol also // holds computed properties of symbol names. struct Symbol { - uint32_t GlobalDynIndex = -1; - // Symbol binding. This is on the Symbol to track changes during resolution. // In particular: // An undefined weak is still weak when it resolves to a shared library. diff --git a/lld/test/ELF/aarch64-tls-static.s b/lld/test/ELF/aarch64-tls-static.s new file mode 100644 index 00000000000..2ba22fa8928 --- /dev/null +++ b/lld/test/ELF/aarch64-tls-static.s @@ -0,0 +1,36 @@ +// RUN: llvm-mc %s -o %t.o -triple aarch64-pc-linux -filetype=obj +// RUN: ld.lld %t.o -o %t.so -shared +// RUN: llvm-readobj -s %t.so | FileCheck --check-prefix=SEC %s +// RUN: llvm-objdump -d %t.so | FileCheck %s + +foo: + adrp x0, :tlsdesc:bar + ldr x1, [x0, :tlsdesc_lo12:bar] + add x0, x0, :tlsdesc_lo12:bar + .tlsdesccall bar + blr x1 + + + .section .tdata,"awT",@progbits +bar: + .word 42 + + +// SEC: Name: .got +// SEC-NEXT: Type: SHT_PROGBITS +// SEC-NEXT: Flags [ +// SEC-NEXT: SHF_ALLOC +// SEC-NEXT: SHF_WRITE +// SEC-NEXT: ] +// SEC-NEXT: Address: 0x2098 +// SEC-NEXT: Offset: 0x2098 +// SEC-NEXT: Size: 16 + +// page(0x2098) - page(0x1000) = 4096 +// 0x98 = 152 + +// CHECK: foo: +// CHECK-NEXT: 1000: {{.*}} adrp x0, #4096 +// CHECK-NEXT: 1004: {{.*}} ldr x1, [x0, #152] +// CHECK-NEXT: 1008: {{.*}} add x0, x0, #152 +// CHECK-NEXT: 100c: {{.*}} blr x1 |