[lld] r253049 - [ELF2] - Implemented R_X86_64_GOTTPOFF relocation
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 13 08:28:53 PST 2015
Author: grimar
Date: Fri Nov 13 10:28:53 2015
New Revision: 253049
URL: http://llvm.org/viewvc/llvm-project?rev=253049&view=rev
Log:
[ELF2] - Implemented R_X86_64_GOTTPOFF relocation
Generates single GOT entry, R_X86_64_TPOFF64 is added to RelaDyn.
Differential revision: http://reviews.llvm.org/D14621
Added:
lld/trunk/test/elf2/Inputs/tls-got.s
lld/trunk/test/elf2/tls-got.s
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
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Nov 13 10:28:53 2015
@@ -140,7 +140,7 @@ void InputSectionBase<ELFT>::relocate(
Type = Target->getPLTRefReloc(Type);
} else if (Target->relocNeedsGot(Type, Body)) {
SymVA = Out<ELFT>::Got->getEntryAddr(Body);
- Type = Target->getGotRefReloc();
+ Type = Body.isTLS() ? Target->getTlsGotReloc() : Target->getGotRefReloc();
} else if (Target->relocPointsToGot(Type)) {
SymVA = Out<ELFT>::Got->getVA();
Type = Target->getPCRelReloc();
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Nov 13 10:28:53 2015
@@ -80,9 +80,13 @@ GotSection<ELFT>::GotSection()
template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
Entries.push_back(Sym);
+}
+
+template <class ELFT> void GotSection<ELFT>::addDynTlsEntry(SymbolBody *Sym) {
+ Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
// Global Dynamic TLS entries take two GOT slots.
- if (Sym->isTLS())
- Entries.push_back(nullptr);
+ Entries.push_back(Sym);
+ Entries.push_back(nullptr);
}
template <class ELFT> uint32_t GotSection<ELFT>::addLocalModuleTlsIndex() {
@@ -231,10 +235,11 @@ template <class ELFT> void RelocationSec
Target->relocNeedsPlt(Type, *Body);
if (CanBePreempted) {
+ unsigned GotReloc =
+ Body->isTLS() ? Target->getTlsGotReloc() : Target->getGotReloc();
if (NeedsGot)
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
- LazyReloc ? Target->getPltReloc()
- : Target->getGotReloc(),
+ LazyReloc ? Target->getPltReloc() : GotReloc,
Config->Mips64EL);
else
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Nov 13 10:28:53 2015
@@ -118,6 +118,7 @@ public:
void finalize() override;
void writeTo(uint8_t *Buf) override;
void addEntry(SymbolBody *Sym);
+ void addDynTlsEntry(SymbolBody *Sym);
uint32_t addLocalModuleTlsIndex();
bool empty() const { return Entries.empty(); }
uintX_t getEntryAddr(const SymbolBody &B) const;
Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Nov 13 10:28:53 2015
@@ -215,10 +215,12 @@ X86_64TargetInfo::X86_64TargetInfo() {
GotRefReloc = R_X86_64_PC32;
PltReloc = R_X86_64_JUMP_SLOT;
RelativeReloc = R_X86_64_RELATIVE;
+ TlsGotReloc = R_X86_64_TPOFF64;
TlsLocalDynamicReloc = R_X86_64_TLSLD;
TlsGlobalDynamicReloc = R_X86_64_TLSGD;
TlsModuleIndexReloc = R_X86_64_DTPMOD64;
TlsOffsetReloc = R_X86_64_DTPOFF64;
+ TlsPcRelGotReloc = R_X86_64_GOTTPOFF;
LazyRelocations = true;
PltEntrySize = 16;
PltZeroEntrySize = 16;
@@ -266,7 +268,8 @@ bool X86_64TargetInfo::relocNeedsCopy(ui
}
bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
- return Type == R_X86_64_GOTPCREL || relocNeedsPlt(Type, S);
+ return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_GOTPCREL ||
+ relocNeedsPlt(Type, S);
}
unsigned X86_64TargetInfo::getPLTRefReloc(unsigned Type) const {
@@ -338,6 +341,7 @@ void X86_64TargetInfo::relocateOne(uint8
case R_X86_64_PLT32:
case R_X86_64_TLSLD:
case R_X86_64_TLSGD:
+ case R_X86_64_TPOFF64:
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=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Fri Nov 13 10:28:53 2015
@@ -29,6 +29,8 @@ public:
unsigned getPltReloc() const { return PltReloc; }
unsigned getGotRefReloc() const { return GotRefReloc; }
unsigned getRelativeReloc() const { return RelativeReloc; }
+ unsigned getTlsGotReloc() const { return TlsGotReloc; }
+ unsigned getTlsPcRelGotReloc() const { return TlsPcRelGotReloc; }
bool isTlsLocalDynamicReloc(unsigned Type) const {
return Type == TlsLocalDynamicReloc;
}
@@ -75,10 +77,12 @@ protected:
unsigned GotReloc;
unsigned PltReloc;
unsigned RelativeReloc;
+ unsigned TlsGotReloc = 0;
unsigned TlsLocalDynamicReloc = 0;
unsigned TlsGlobalDynamicReloc = 0;
unsigned TlsModuleIndexReloc;
unsigned TlsOffsetReloc;
+ unsigned TlsPcRelGotReloc = 0;
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=253049&r1=253048&r2=253049&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Nov 13 10:28:53 2015
@@ -216,18 +216,19 @@ void Writer<ELFT>::scanRelocs(
if (Body)
Body = Body->repl();
- if (Body && Body->isTLS()) {
- if (!Target->isTlsGlobalDynamicReloc(Type))
- continue;
+ if (Body && Body->isTLS() && Target->isTlsGlobalDynamicReloc(Type)) {
if (Body->isInGot())
continue;
- Out<ELFT>::Got->addEntry(Body);
+ Out<ELFT>::Got->addDynTlsEntry(Body);
Out<ELFT>::RelaDyn->addReloc({&C, &RI});
Out<ELFT>::RelaDyn->addReloc({nullptr, nullptr});
Body->setUsedInDynamicReloc();
continue;
}
+ if ((Body && Body->isTLS()) && Type != Target->getTlsPcRelGotReloc())
+ continue;
+
bool NeedsGot = false;
bool NeedsPlt = false;
if (Body) {
Added: lld/trunk/test/elf2/Inputs/tls-got.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/tls-got.s?rev=253049&view=auto
==============================================================================
--- lld/trunk/test/elf2/Inputs/tls-got.s (added)
+++ lld/trunk/test/elf2/Inputs/tls-got.s Fri Nov 13 10:28:53 2015
@@ -0,0 +1,14 @@
+.type tls0, at object
+.section .tbss,"awT", at nobits
+.globl tls0
+.align 4
+tls0:
+ .long 0
+ .size tls0, 4
+
+.type tls1, at object
+.globl tls1
+.align 4
+tls1:
+ .long 0
+ .size tls1, 4
Added: lld/trunk/test/elf2/tls-got.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/tls-got.s?rev=253049&view=auto
==============================================================================
--- lld/trunk/test/elf2/tls-got.s (added)
+++ lld/trunk/test/elf2/tls-got.s Fri Nov 13 10:28:53 2015
@@ -0,0 +1,58 @@
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got.s -o %t2.o
+// RUN: ld.lld2 -shared %t2.o -o %t2.so
+// RUN: ld.lld2 -e main %t1.o %t2.so -o %t3
+// RUN: llvm-readobj -s -r %t3 | FileCheck %s
+// RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM %s
+
+// CHECK: Section {
+// CHECK: Index: 8
+// CHECK-NEXT: Name: .got
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: [[ADDR:.*]]
+// CHECK-NEXT: Offset: 0x20A0
+// CHECK-NEXT: Size: 16
+// CHECK-NEXT: Link: 0
+// CHECK-NEXT: Info: 0
+// CHECK-NEXT: AddressAlignment: 8
+// CHECK-NEXT: EntrySize: 0
+// CHECK-NEXT: }
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section (4) .rela.dyn {
+// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
+// CHECK-NEXT: 0x120A8 R_X86_64_TPOFF64 tls0 0x0
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+
+//0x11000 + 4249 + 7 = 0x120A0
+//0x1100A + 4247 + 7 = 0x120A8
+//0x11014 + 4237 + 7 = 0x120A8
+//DISASM: Disassembly of section .text:
+//DISASM-NEXT: main:
+//DISASM-NEXT: 11000: 48 8b 05 99 10 00 00 movq 4249(%rip), %rax
+//DISASM-NEXT: 11007: 64 8b 00 movl %fs:(%rax), %eax
+//DISASM-NEXT: 1100a: 48 8b 05 97 10 00 00 movq 4247(%rip), %rax
+//DISASM-NEXT: 11011: 64 8b 00 movl %fs:(%rax), %eax
+//DISASM-NEXT: 11014: 48 8b 05 8d 10 00 00 movq 4237(%rip), %rax
+//DISASM-NEXT: 1101b: 64 8b 00 movl %fs:(%rax), %eax
+//DISASM-NEXT: 1101e: c3 retq
+
+.section .tdata,"awT", at progbits
+
+.text
+ .globl main
+ .align 16, 0x90
+ .type main, at function
+main:
+ movq tls1 at GOTTPOFF(%rip), %rax
+ movl %fs:0(%rax), %eax
+ movq tls0 at GOTTPOFF(%rip), %rax
+ movl %fs:0(%rax), %eax
+ movq tls0 at GOTTPOFF(%rip), %rax
+ movl %fs:0(%rax), %eax
+ ret
More information about the llvm-commits
mailing list