aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp')
-rw-r--r--contrib/llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp74
1 files changed, 62 insertions, 12 deletions
diff --git a/contrib/llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/contrib/llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
index f02d8981b30e..21339a3f8f3d 100644
--- a/contrib/llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/contrib/llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -24,6 +24,7 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/SymbolSize.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DynamicLibrary.h"
@@ -33,7 +34,6 @@
#include "llvm/Support/Memory.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
@@ -206,6 +206,9 @@ public:
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID, StringRef SectionName,
bool IsReadOnly) override;
+ TrivialMemoryManager::TLSSection
+ allocateTLSSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
+ StringRef SectionName) override;
/// If non null, records subsequent Name -> SectionID mappings.
void setSectionIDsMap(SectionIDMap *SecIDMap) {
@@ -252,7 +255,8 @@ public:
sys::Memory::MF_WRITE,
EC);
if (!MB.base())
- report_fatal_error("Can't allocate enough memory: " + EC.message());
+ report_fatal_error(Twine("Can't allocate enough memory: ") +
+ EC.message());
PreallocSlab = MB;
UsePreallocation = true;
@@ -282,6 +286,9 @@ private:
uintptr_t SlabSize = 0;
uintptr_t CurrentSlabOffset = 0;
SectionIDMap *SecIDMap = nullptr;
+#if defined(__x86_64__) && defined(__ELF__)
+ unsigned UsedTLSStorage = 0;
+#endif
};
uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
@@ -306,7 +313,8 @@ uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
sys::Memory::MF_WRITE,
EC);
if (!MB.base())
- report_fatal_error("MemoryManager allocation failed: " + EC.message());
+ report_fatal_error(Twine("MemoryManager allocation failed: ") +
+ EC.message());
FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID));
return (uint8_t*)MB.base();
}
@@ -334,11 +342,52 @@ uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
sys::Memory::MF_WRITE,
EC);
if (!MB.base())
- report_fatal_error("MemoryManager allocation failed: " + EC.message());
+ report_fatal_error(Twine("MemoryManager allocation failed: ") +
+ EC.message());
DataMemory.push_back(SectionInfo(SectionName, MB, SectionID));
return (uint8_t*)MB.base();
}
+// In case the execution needs TLS storage, we define a very small TLS memory
+// area here that will be used in allocateTLSSection().
+#if defined(__x86_64__) && defined(__ELF__)
+extern "C" {
+alignas(16) __attribute__((visibility("hidden"), tls_model("initial-exec"),
+ used)) thread_local char LLVMRTDyldTLSSpace[16];
+}
+#endif
+
+TrivialMemoryManager::TLSSection
+TrivialMemoryManager::allocateTLSSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName) {
+#if defined(__x86_64__) && defined(__ELF__)
+ if (Size + UsedTLSStorage > sizeof(LLVMRTDyldTLSSpace)) {
+ return {};
+ }
+
+ // Get the offset of the TLSSpace in the TLS block by using a tpoff
+ // relocation here.
+ int64_t TLSOffset;
+ asm("leaq LLVMRTDyldTLSSpace@tpoff, %0" : "=r"(TLSOffset));
+
+ TLSSection Section;
+ // We use the storage directly as the initialization image. This means that
+ // when a new thread is spawned after this allocation, it will not be
+ // initialized correctly. This means, llvm-rtdyld will only support TLS in a
+ // single thread.
+ Section.InitializationImage =
+ reinterpret_cast<uint8_t *>(LLVMRTDyldTLSSpace + UsedTLSStorage);
+ Section.Offset = TLSOffset + UsedTLSStorage;
+
+ UsedTLSStorage += Size;
+
+ return Section;
+#else
+ return {};
+#endif
+}
+
static const char *ProgramName;
static void ErrorAndExit(const Twine &Msg) {
@@ -349,10 +398,10 @@ static void ErrorAndExit(const Twine &Msg) {
static void loadDylibs() {
for (const std::string &Dylib : Dylibs) {
if (!sys::fs::is_regular_file(Dylib))
- report_fatal_error("Dylib not found: '" + Dylib + "'.");
+ report_fatal_error(Twine("Dylib not found: '") + Dylib + "'.");
std::string ErrMsg;
if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg))
- report_fatal_error("Error loading '" + Dylib + "': " + ErrMsg);
+ report_fatal_error(Twine("Error loading '") + Dylib + "': " + ErrMsg);
}
}
@@ -413,8 +462,9 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
}
}
- std::unique_ptr<DIContext> Context =
- DWARFContext::create(*SymbolObj, LoadedObjInfo.get());
+ std::unique_ptr<DIContext> Context = DWARFContext::create(
+ *SymbolObj, DWARFContext::ProcessDebugRelocations::Process,
+ LoadedObjInfo.get());
std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
object::computeSymbolSizes(*SymbolObj);
@@ -710,15 +760,15 @@ static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
size_t EqualsIdx = Mapping.find_first_of('=');
if (EqualsIdx == StringRef::npos)
- report_fatal_error("Invalid dummy symbol specification '" + Mapping +
- "'. Should be '<symbol name>=<addr>'");
+ report_fatal_error(Twine("Invalid dummy symbol specification '") +
+ Mapping + "'. Should be '<symbol name>=<addr>'");
std::string Symbol = Mapping.substr(0, EqualsIdx);
std::string AddrStr = Mapping.substr(EqualsIdx + 1);
uint64_t Addr;
if (StringRef(AddrStr).getAsInteger(0, Addr))
- report_fatal_error("Invalid symbol mapping '" + Mapping + "'.");
+ report_fatal_error(Twine("Invalid symbol mapping '") + Mapping + "'.");
MemMgr.addDummySymbol(Symbol, Addr);
}
@@ -974,7 +1024,7 @@ int main(int argc, char **argv) {
Timers = ShowTimes ? std::make_unique<RTDyldTimers>() : nullptr;
- int Result;
+ int Result = 0;
switch (Action) {
case AC_Execute:
Result = executeInput();