Skip to content

Commit 687138c

Browse files
author
George Rimar
committedNov 13, 2015
[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 llvm-svn: 253049
1 parent 225d65f commit 687138c

File tree

8 files changed

+97
-10
lines changed

8 files changed

+97
-10
lines changed
 

‎lld/ELF/InputSection.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ void InputSectionBase<ELFT>::relocate(
140140
Type = Target->getPLTRefReloc(Type);
141141
} else if (Target->relocNeedsGot(Type, Body)) {
142142
SymVA = Out<ELFT>::Got->getEntryAddr(Body);
143-
Type = Target->getGotRefReloc();
143+
Type = Body.isTLS() ? Target->getTlsGotReloc() : Target->getGotRefReloc();
144144
} else if (Target->relocPointsToGot(Type)) {
145145
SymVA = Out<ELFT>::Got->getVA();
146146
Type = Target->getPCRelReloc();

‎lld/ELF/OutputSections.cpp

+9-4
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,13 @@ GotSection<ELFT>::GotSection()
8080
template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
8181
Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
8282
Entries.push_back(Sym);
83+
}
84+
85+
template <class ELFT> void GotSection<ELFT>::addDynTlsEntry(SymbolBody *Sym) {
86+
Sym->GotIndex = Target->getGotHeaderEntriesNum() + Entries.size();
8387
// Global Dynamic TLS entries take two GOT slots.
84-
if (Sym->isTLS())
85-
Entries.push_back(nullptr);
88+
Entries.push_back(Sym);
89+
Entries.push_back(nullptr);
8690
}
8791

8892
template <class ELFT> uint32_t GotSection<ELFT>::addLocalModuleTlsIndex() {
@@ -231,10 +235,11 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
231235
Target->relocNeedsPlt(Type, *Body);
232236

233237
if (CanBePreempted) {
238+
unsigned GotReloc =
239+
Body->isTLS() ? Target->getTlsGotReloc() : Target->getGotReloc();
234240
if (NeedsGot)
235241
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),
236-
LazyReloc ? Target->getPltReloc()
237-
: Target->getGotReloc(),
242+
LazyReloc ? Target->getPltReloc() : GotReloc,
238243
Config->Mips64EL);
239244
else
240245
P->setSymbolAndType(Body->getDynamicSymbolTableIndex(),

‎lld/ELF/OutputSections.h

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ template <class ELFT> class GotSection final : public OutputSectionBase<ELFT> {
118118
void finalize() override;
119119
void writeTo(uint8_t *Buf) override;
120120
void addEntry(SymbolBody *Sym);
121+
void addDynTlsEntry(SymbolBody *Sym);
121122
uint32_t addLocalModuleTlsIndex();
122123
bool empty() const { return Entries.empty(); }
123124
uintX_t getEntryAddr(const SymbolBody &B) const;

‎lld/ELF/Target.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,12 @@ X86_64TargetInfo::X86_64TargetInfo() {
215215
GotRefReloc = R_X86_64_PC32;
216216
PltReloc = R_X86_64_JUMP_SLOT;
217217
RelativeReloc = R_X86_64_RELATIVE;
218+
TlsGotReloc = R_X86_64_TPOFF64;
218219
TlsLocalDynamicReloc = R_X86_64_TLSLD;
219220
TlsGlobalDynamicReloc = R_X86_64_TLSGD;
220221
TlsModuleIndexReloc = R_X86_64_DTPMOD64;
221222
TlsOffsetReloc = R_X86_64_DTPOFF64;
223+
TlsPcRelGotReloc = R_X86_64_GOTTPOFF;
222224
LazyRelocations = true;
223225
PltEntrySize = 16;
224226
PltZeroEntrySize = 16;
@@ -266,7 +268,8 @@ bool X86_64TargetInfo::relocNeedsCopy(uint32_t Type,
266268
}
267269

268270
bool X86_64TargetInfo::relocNeedsGot(uint32_t Type, const SymbolBody &S) const {
269-
return Type == R_X86_64_GOTPCREL || relocNeedsPlt(Type, S);
271+
return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_GOTPCREL ||
272+
relocNeedsPlt(Type, S);
270273
}
271274

272275
unsigned X86_64TargetInfo::getPLTRefReloc(unsigned Type) const {
@@ -338,6 +341,7 @@ void X86_64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
338341
case R_X86_64_PLT32:
339342
case R_X86_64_TLSLD:
340343
case R_X86_64_TLSGD:
344+
case R_X86_64_TPOFF64:
341345
write32le(Loc, SA - P);
342346
break;
343347
case R_X86_64_64:

‎lld/ELF/Target.h

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class TargetInfo {
2929
unsigned getPltReloc() const { return PltReloc; }
3030
unsigned getGotRefReloc() const { return GotRefReloc; }
3131
unsigned getRelativeReloc() const { return RelativeReloc; }
32+
unsigned getTlsGotReloc() const { return TlsGotReloc; }
33+
unsigned getTlsPcRelGotReloc() const { return TlsPcRelGotReloc; }
3234
bool isTlsLocalDynamicReloc(unsigned Type) const {
3335
return Type == TlsLocalDynamicReloc;
3436
}
@@ -75,10 +77,12 @@ class TargetInfo {
7577
unsigned GotReloc;
7678
unsigned PltReloc;
7779
unsigned RelativeReloc;
80+
unsigned TlsGotReloc = 0;
7881
unsigned TlsLocalDynamicReloc = 0;
7982
unsigned TlsGlobalDynamicReloc = 0;
8083
unsigned TlsModuleIndexReloc;
8184
unsigned TlsOffsetReloc;
85+
unsigned TlsPcRelGotReloc = 0;
8286
unsigned PltEntrySize = 8;
8387
unsigned PltZeroEntrySize = 0;
8488
unsigned GotHeaderEntriesNum = 0;

‎lld/ELF/Writer.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -216,18 +216,19 @@ void Writer<ELFT>::scanRelocs(
216216
if (Body)
217217
Body = Body->repl();
218218

219-
if (Body && Body->isTLS()) {
220-
if (!Target->isTlsGlobalDynamicReloc(Type))
221-
continue;
219+
if (Body && Body->isTLS() && Target->isTlsGlobalDynamicReloc(Type)) {
222220
if (Body->isInGot())
223221
continue;
224-
Out<ELFT>::Got->addEntry(Body);
222+
Out<ELFT>::Got->addDynTlsEntry(Body);
225223
Out<ELFT>::RelaDyn->addReloc({&C, &RI});
226224
Out<ELFT>::RelaDyn->addReloc({nullptr, nullptr});
227225
Body->setUsedInDynamicReloc();
228226
continue;
229227
}
230228

229+
if ((Body && Body->isTLS()) && Type != Target->getTlsPcRelGotReloc())
230+
continue;
231+
231232
bool NeedsGot = false;
232233
bool NeedsPlt = false;
233234
if (Body) {

‎lld/test/elf2/Inputs/tls-got.s

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.type tls0,@object
2+
.section .tbss,"awT",@nobits
3+
.globl tls0
4+
.align 4
5+
tls0:
6+
.long 0
7+
.size tls0, 4
8+
9+
.type tls1,@object
10+
.globl tls1
11+
.align 4
12+
tls1:
13+
.long 0
14+
.size tls1, 4

‎lld/test/elf2/tls-got.s

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
2+
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got.s -o %t2.o
3+
// RUN: ld.lld2 -shared %t2.o -o %t2.so
4+
// RUN: ld.lld2 -e main %t1.o %t2.so -o %t3
5+
// RUN: llvm-readobj -s -r %t3 | FileCheck %s
6+
// RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM %s
7+
8+
// CHECK: Section {
9+
// CHECK: Index: 8
10+
// CHECK-NEXT: Name: .got
11+
// CHECK-NEXT: Type: SHT_PROGBITS
12+
// CHECK-NEXT: Flags [
13+
// CHECK-NEXT: SHF_ALLOC
14+
// CHECK-NEXT: SHF_WRITE
15+
// CHECK-NEXT: ]
16+
// CHECK-NEXT: Address: [[ADDR:.*]]
17+
// CHECK-NEXT: Offset: 0x20A0
18+
// CHECK-NEXT: Size: 16
19+
// CHECK-NEXT: Link: 0
20+
// CHECK-NEXT: Info: 0
21+
// CHECK-NEXT: AddressAlignment: 8
22+
// CHECK-NEXT: EntrySize: 0
23+
// CHECK-NEXT: }
24+
25+
// CHECK: Relocations [
26+
// CHECK-NEXT: Section (4) .rela.dyn {
27+
// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
28+
// CHECK-NEXT: 0x120A8 R_X86_64_TPOFF64 tls0 0x0
29+
// CHECK-NEXT: }
30+
// CHECK-NEXT: ]
31+
32+
//0x11000 + 4249 + 7 = 0x120A0
33+
//0x1100A + 4247 + 7 = 0x120A8
34+
//0x11014 + 4237 + 7 = 0x120A8
35+
//DISASM: Disassembly of section .text:
36+
//DISASM-NEXT: main:
37+
//DISASM-NEXT: 11000: 48 8b 05 99 10 00 00 movq 4249(%rip), %rax
38+
//DISASM-NEXT: 11007: 64 8b 00 movl %fs:(%rax), %eax
39+
//DISASM-NEXT: 1100a: 48 8b 05 97 10 00 00 movq 4247(%rip), %rax
40+
//DISASM-NEXT: 11011: 64 8b 00 movl %fs:(%rax), %eax
41+
//DISASM-NEXT: 11014: 48 8b 05 8d 10 00 00 movq 4237(%rip), %rax
42+
//DISASM-NEXT: 1101b: 64 8b 00 movl %fs:(%rax), %eax
43+
//DISASM-NEXT: 1101e: c3 retq
44+
45+
.section .tdata,"awT",@progbits
46+
47+
.text
48+
.globl main
49+
.align 16, 0x90
50+
.type main,@function
51+
main:
52+
movq tls1@GOTTPOFF(%rip), %rax
53+
movl %fs:0(%rax), %eax
54+
movq tls0@GOTTPOFF(%rip), %rax
55+
movl %fs:0(%rax), %eax
56+
movq tls0@GOTTPOFF(%rip), %rax
57+
movl %fs:0(%rax), %eax
58+
ret

0 commit comments

Comments
 (0)
Please sign in to comment.