Skip to content

Commit a0a5964

Browse files
committed
[RuntimeDyld] Implemented relocation of TLS symbols in ELF
Differential Revision: https://reviews.llvm.org/D105466
1 parent f687378 commit a0a5964

File tree

6 files changed

+617
-5
lines changed

6 files changed

+617
-5
lines changed

llvm/include/llvm/ExecutionEngine/RuntimeDyld.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,20 @@ class RuntimeDyld {
112112
StringRef SectionName,
113113
bool IsReadOnly) = 0;
114114

115+
/// An allocated TLS section
116+
struct TLSSection {
117+
/// The pointer to the initialization image
118+
uint8_t *InitializationImage;
119+
/// The TLS offset
120+
intptr_t Offset;
121+
};
122+
123+
/// Allocate a memory block of (at least) the given size to be used for
124+
/// thread-local storage (TLS).
125+
virtual TLSSection allocateTLSSection(uintptr_t Size, unsigned Alignment,
126+
unsigned SectionID,
127+
StringRef SectionName);
128+
115129
/// Inform the memory manager about the total amount of memory required to
116130
/// allocate all sections to be loaded:
117131
/// \p CodeSize - the total size of all code sections

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,13 @@ static bool isZeroInit(const SectionRef Section) {
520520
SectionType == MachO::S_GB_ZEROFILL;
521521
}
522522

523+
static bool isTLS(const SectionRef Section) {
524+
const ObjectFile *Obj = Section.getObject();
525+
if (isa<object::ELFObjectFileBase>(Obj))
526+
return ELFSectionRef(Section).getFlags() & ELF::SHF_TLS;
527+
return false;
528+
}
529+
523530
// Compute an upper bound of the memory size that is required to load all
524531
// sections
525532
Error RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
@@ -549,6 +556,7 @@ Error RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
549556
unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
550557
bool IsCode = Section.isText();
551558
bool IsReadOnly = isReadOnlyData(Section);
559+
bool IsTLS = isTLS(Section);
552560

553561
Expected<StringRef> NameOrErr = Section.getName();
554562
if (!NameOrErr)
@@ -582,7 +590,7 @@ Error RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
582590
} else if (IsReadOnly) {
583591
RODataAlign = std::max(RODataAlign, Alignment);
584592
ROSectionSizes.push_back(SectionSize);
585-
} else {
593+
} else if (!IsTLS) {
586594
RWDataAlign = std::max(RWDataAlign, Alignment);
587595
RWSectionSizes.push_back(SectionSize);
588596
}
@@ -800,6 +808,7 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
800808
bool IsVirtual = Section.isVirtual();
801809
bool IsZeroInit = isZeroInit(Section);
802810
bool IsReadOnly = isReadOnlyData(Section);
811+
bool IsTLS = isTLS(Section);
803812
uint64_t DataSize = Section.getSize();
804813

805814
// An alignment of 0 (at least with ELF) is identical to an alignment of 1,
@@ -823,6 +832,7 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
823832
uintptr_t Allocate;
824833
unsigned SectionID = Sections.size();
825834
uint8_t *Addr;
835+
uint64_t LoadAddress = 0;
826836
const char *pData = nullptr;
827837

828838
// If this section contains any bits (i.e. isn't a virtual or bss section),
@@ -851,10 +861,17 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
851861
Allocate = DataSize + PaddingSize + StubBufSize;
852862
if (!Allocate)
853863
Allocate = 1;
854-
Addr = IsCode ? MemMgr.allocateCodeSection(Allocate, Alignment, SectionID,
855-
Name)
856-
: MemMgr.allocateDataSection(Allocate, Alignment, SectionID,
857-
Name, IsReadOnly);
864+
if (IsTLS) {
865+
auto TLSSection =
866+
MemMgr.allocateTLSSection(Allocate, Alignment, SectionID, Name);
867+
Addr = TLSSection.InitializationImage;
868+
LoadAddress = TLSSection.Offset;
869+
} else if (IsCode) {
870+
Addr = MemMgr.allocateCodeSection(Allocate, Alignment, SectionID, Name);
871+
} else {
872+
Addr = MemMgr.allocateDataSection(Allocate, Alignment, SectionID, Name,
873+
IsReadOnly);
874+
}
858875
if (!Addr)
859876
report_fatal_error("Unable to allocate section memory!");
860877

@@ -897,6 +914,10 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
897914
Sections.push_back(
898915
SectionEntry(Name, Addr, DataSize, Allocate, (uintptr_t)pData));
899916

917+
// The load address of a TLS section is not equal to the address of its
918+
// initialization image
919+
if (IsTLS)
920+
Sections.back().setLoadAddress(LoadAddress);
900921
// Debug info sections are linked as if their load address was zero
901922
if (!IsRequired)
902923
Sections.back().setLoadAddress(0);
@@ -1261,6 +1282,14 @@ uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress(
12611282
return 0;
12621283
}
12631284

1285+
RuntimeDyld::MemoryManager::TLSSection
1286+
RuntimeDyld::MemoryManager::allocateTLSSection(uintptr_t Size,
1287+
unsigned Alignment,
1288+
unsigned SectionID,
1289+
StringRef SectionName) {
1290+
report_fatal_error("allocation of TLS not implemented");
1291+
}
1292+
12641293
void RuntimeDyld::MemoryManager::anchor() {}
12651294
void JITSymbolResolver::anchor() {}
12661295
void LegacyJITSymbolResolver::anchor() {}

0 commit comments

Comments
 (0)