[lld] r252979 - [elf2] Implement global dynamic tls.
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 13 07:34:38 PST 2015
Now all tests pass is a stage2 build of llvm+clang+lld when linking with lld :-)
On 12 November 2015 at 19:28, Michael J. Spencer via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: mspencer
> Date: Thu Nov 12 18:28:34 2015
> New Revision: 252979
>
> URL: http://llvm.org/viewvc/llvm-project?rev=252979&view=rev
> Log:
> [elf2] Implement global dynamic tls.
>
> Modified:
> lld/trunk/ELF/InputSection.cpp
> lld/trunk/ELF/OutputSections.cpp
> lld/trunk/ELF/OutputSections.h
> lld/trunk/ELF/Target.cpp
> lld/trunk/ELF/Target.h
> lld/trunk/ELF/Writer.cpp
> lld/trunk/test/elf2/tls-dynamic.s
>
> Modified: lld/trunk/ELF/InputSection.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=252979&r1=252978&r2=252979&view=diff
> ==============================================================================
> --- lld/trunk/ELF/InputSection.cpp (original)
> +++ lld/trunk/ELF/InputSection.cpp Thu Nov 12 18:28:34 2015
> @@ -126,6 +126,14 @@ void InputSectionBase<ELFT>::relocate(
> }
>
> SymbolBody &Body = *File->getSymbolBody(SymIndex)->repl();
> +
> + if (Type == Target->getTlsGlobalDynamicReloc()) {
> + Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
> + Out<ELFT>::Got->getEntryAddr(Body) +
> + getAddend<ELFT>(RI));
> + continue;
> + }
> +
> uintX_t SymVA = getSymVA<ELFT>(Body);
> if (Target->relocNeedsPlt(Type, Body)) {
> SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=252979&r1=252978&r2=252979&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Thu Nov 12 18:28:34 2015
> @@ -80,6 +80,9 @@ GotSection<ELFT>::GotSection()
> template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
> Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
> Entries.push_back(Sym);
> + // Global Dynamic TLS entries take two GOT slots.
> + if (Sym->isTLS())
> + Entries.push_back(nullptr);
> }
>
> template <class ELFT> uint32_t GotSection<ELFT>::addLocalModuleTlsIndex() {
> @@ -187,8 +190,13 @@ template <class ELFT> void RelocationSec
> auto *P = reinterpret_cast<Elf_Rel *>(Buf);
> Buf += EntrySize;
>
> - InputSectionBase<ELFT> &C = Rel.C;
> - const Elf_Rel &RI = Rel.RI;
> + // Skip placeholder for global dynamic TLS relocation pair. It was already
> + // handled by the previous relocation.
> + if (!Rel.C || !Rel.RI)
> + continue;
> +
> + InputSectionBase<ELFT> &C = *Rel.C;
> + const Elf_Rel &RI = *Rel.RI;
> uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
> const ObjectFile<ELFT> &File = *C.getFile();
> SymbolBody *Body = File.getSymbolBody(SymIndex);
> @@ -205,6 +213,17 @@ template <class ELFT> void RelocationSec
> continue;
> }
>
> + if (Body && Type == Target->getTlsGlobalDynamicReloc()) {
> + P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
> + Target->getTlsModuleIndexReloc(), Config->Mips64EL);
> + P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body);
> + auto *PNext = reinterpret_cast<Elf_Rel *>(Buf);
> + PNext->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
> + Target->getTlsOffsetReloc(), Config->Mips64EL);
> + PNext->r_offset = Out<ELFT>::Got->getEntryAddr(*Body) + sizeof(uintX_t);
> + continue;
> + }
> +
> bool NeedsCopy = Body && Target->relocNeedsCopy(Type, *Body);
> bool NeedsGot = Body && Target->relocNeedsGot(Type, *Body);
> bool CanBePreempted = canBePreempted(Body, NeedsGot);
>
> Modified: lld/trunk/ELF/OutputSections.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=252979&r1=252978&r2=252979&view=diff
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.h (original)
> +++ lld/trunk/ELF/OutputSections.h Thu Nov 12 18:28:34 2015
> @@ -170,8 +170,8 @@ private:
>
> template <class ELFT> struct DynamicReloc {
> typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
> - InputSectionBase<ELFT> &C;
> - const Elf_Rel &RI;
> + InputSectionBase<ELFT> *C;
> + const Elf_Rel *RI;
> };
>
> template <class ELFT>
>
> Modified: lld/trunk/ELF/Target.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=252979&r1=252978&r2=252979&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Target.cpp (original)
> +++ lld/trunk/ELF/Target.cpp Thu Nov 12 18:28:34 2015
> @@ -216,7 +216,9 @@ X86_64TargetInfo::X86_64TargetInfo() {
> PltReloc = R_X86_64_JUMP_SLOT;
> RelativeReloc = R_X86_64_RELATIVE;
> TlsLocalDynamicReloc = R_X86_64_TLSLD;
> + TlsGlobalDynamicReloc = R_X86_64_TLSGD;
> TlsModuleIndexReloc = R_X86_64_DTPMOD64;
> + TlsOffsetReloc = R_X86_64_DTPOFF64;
> LazyRelocations = true;
> PltEntrySize = 16;
> PltZeroEntrySize = 16;
> @@ -335,6 +337,7 @@ void X86_64TargetInfo::relocateOne(uint8
> case R_X86_64_GOTPCREL:
> case R_X86_64_PLT32:
> case R_X86_64_TLSLD:
> + case R_X86_64_TLSGD:
> write32le(Loc, SA - P);
> break;
> case R_X86_64_64:
>
> Modified: lld/trunk/ELF/Target.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=252979&r1=252978&r2=252979&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Target.h (original)
> +++ lld/trunk/ELF/Target.h Thu Nov 12 18:28:34 2015
> @@ -30,7 +30,9 @@ public:
> unsigned getGotRefReloc() const { return GotRefReloc; }
> unsigned getRelativeReloc() const { return RelativeReloc; }
> unsigned getTlsLocalDynamicReloc() const { return TlsLocalDynamicReloc; }
> + unsigned getTlsGlobalDynamicReloc() const { return TlsGlobalDynamicReloc; }
> unsigned getTlsModuleIndexReloc() const { return TlsModuleIndexReloc; }
> + unsigned getTlsOffsetReloc() const { return TlsOffsetReloc; }
> unsigned getPltZeroEntrySize() const { return PltZeroEntrySize; }
> unsigned getPltEntrySize() const { return PltEntrySize; }
> bool supportsLazyRelocations() const { return LazyRelocations; }
> @@ -70,7 +72,9 @@ protected:
> unsigned PltReloc;
> unsigned RelativeReloc;
> unsigned TlsLocalDynamicReloc = 0;
> + unsigned TlsGlobalDynamicReloc = 0;
> unsigned TlsModuleIndexReloc;
> + unsigned TlsOffsetReloc;
> unsigned PltEntrySize = 8;
> unsigned PltZeroEntrySize = 0;
> unsigned GotHeaderEntriesNum = 0;
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=252979&r1=252978&r2=252979&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Thu Nov 12 18:28:34 2015
> @@ -203,7 +203,7 @@ void Writer<ELFT>::scanRelocs(
> if (Out<ELFT>::LocalModuleTlsIndexOffset == uint32_t(-1)) {
> Out<ELFT>::LocalModuleTlsIndexOffset =
> Out<ELFT>::Got->addLocalModuleTlsIndex();
> - Out<ELFT>::RelaDyn->addReloc({C, RI});
> + Out<ELFT>::RelaDyn->addReloc({&C, &RI});
> }
> continue;
> }
> @@ -215,6 +215,19 @@ void Writer<ELFT>::scanRelocs(
>
> if (Body)
> Body = Body->repl();
> +
> + if (Body && Body->isTLS()) {
> + if (Type != Target->getTlsGlobalDynamicReloc())
> + continue;
> + if (Body->isInGot())
> + continue;
> + Out<ELFT>::Got->addEntry(Body);
> + Out<ELFT>::RelaDyn->addReloc({&C, &RI});
> + Out<ELFT>::RelaDyn->addReloc({nullptr, nullptr});
> + Body->setUsedInDynamicReloc();
> + continue;
> + }
> +
> bool NeedsGot = false;
> bool NeedsPlt = false;
> if (Body) {
> @@ -257,9 +270,9 @@ void Writer<ELFT>::scanRelocs(
> if (CBP)
> Body->setUsedInDynamicReloc();
> if (NeedsPlt && Target->supportsLazyRelocations())
> - Out<ELFT>::RelaPlt->addReloc({C, RI});
> + Out<ELFT>::RelaPlt->addReloc({&C, &RI});
> else
> - Out<ELFT>::RelaDyn->addReloc({C, RI});
> + Out<ELFT>::RelaDyn->addReloc({&C, &RI});
> }
> }
>
>
> Modified: lld/trunk/test/elf2/tls-dynamic.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/tls-dynamic.s?rev=252979&r1=252978&r2=252979&view=diff
> ==============================================================================
> --- lld/trunk/test/elf2/tls-dynamic.s (original)
> +++ lld/trunk/test/elf2/tls-dynamic.s Thu Nov 12 18:28:34 2015
> @@ -11,6 +11,10 @@
> leaq a at dtpoff(%rax), %rcx
> leaq b at dtpoff(%rax), %rcx
> .long b at dtpoff, 0
> + leaq c at tlsgd(%rip), %rdi
> + rex64
> + callq __tls_get_addr at PLT
> + leaq c at dtpoff(%rax), %rcx
>
> .global a
> .hidden a
> @@ -23,8 +27,14 @@ a:
> .align 4
> b:
> .long 0
> +
> + .global c
> + .section .tbss,"awT", at nobits
> + .align 4
> +c:
> + .long 0
>
> -// Get the address of the got, and check that it has two entries.
> +// Get the address of the got, and check that it has 4 entries.
>
> // CHECK: Sections [
> // CHECK: Name: .got
> @@ -35,15 +45,18 @@ b:
> // CHECK-NEXT: ]
> // CHECK-NEXT: Address: 0x20D0
> // CHECK-NEXT: Offset:
> -// CHECK-NEXT: Size: 16
> +// CHECK-NEXT: Size: 32
>
> // CHECK: Relocations [
> // CHECK: Section ({{.+}}) .rela.dyn {
> // CHECK-NEXT: 0x20D0 R_X86_64_DTPMOD64 - 0x0
> +// CHECK-NEXT: 0x20E0 R_X86_64_DTPMOD64 c 0x0
> +// CHECK-NEXT: 0x20E8 R_X86_64_DTPOFF64 c 0x0
> // CHECK-NEXT: }
>
> // 4297 = (0x20D0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
> // 4285 = (0x20D0 + -4) - (0x100c + 3) // PC relative offset to got entry.
> +// 4267 = (0x20E0 + -4) - (0x102e + 3) // PC relative offset to got entry.
>
> // DIS: Disassembly of section .text:
> // DIS-NEXT: .text:
> @@ -57,3 +70,6 @@ b:
> // DIS-NEXT: 1028: 00 00
> // DIS-NEXT: 102a: 00 00
> // DIS-NEXT: 102c: 00 00
> +// DIS-NEXT: 102e: {{.+}} leaq 4267(%rip), %rdi
> +// DIS-NEXT: 1035: {{.+}} callq
> +// DIS-NEXT: 103b: {{.+}} leaq 8(%rax), %rcx
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list