forked from OSchip/llvm-project
parent
a6f103f705
commit
627ae703b5
|
@ -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);
|
||||
|
|
|
@ -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 RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
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 RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
|
|||
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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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_t *Loc, uint8_t *BufEnd, uint32_t Type,
|
|||
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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
leaq a@dtpoff(%rax), %rcx
|
||||
leaq b@dtpoff(%rax), %rcx
|
||||
.long b@dtpoff, 0
|
||||
leaq c@tlsgd(%rip), %rdi
|
||||
rex64
|
||||
callq __tls_get_addr@PLT
|
||||
leaq c@dtpoff(%rax), %rcx
|
||||
|
||||
.global a
|
||||
.hidden a
|
||||
|
@ -23,8 +27,14 @@ a:
|
|||
.align 4
|
||||
b:
|
||||
.long 0
|
||||
|
||||
.global c
|
||||
.section .tbss,"awT",@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
|
||||
|
|
Loading…
Reference in New Issue