aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ExecutionEngine
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2024-01-05 15:32:29 -0800
committerGitHub <noreply@github.com>2024-01-05 15:32:29 -0800
commit08c5f1fede969e687e77d0508008682e5f188f49 (patch)
treeba88473632bf946f18fdbf8581ae7d7bf251c9cb /llvm/lib/ExecutionEngine
parenta9c5bddc8f18926bac6dc224144a32512207bd38 (diff)
downloadllvm-08c5f1fede969e687e77d0508008682e5f188f49.zip
llvm-08c5f1fede969e687e77d0508008682e5f188f49.tar.gz
llvm-08c5f1fede969e687e77d0508008682e5f188f49.tar.bz2
[ORC] Add absoluteSymbolsLinkGraph to expose absolute symbols to platform (#77008)
Adds a function to create a LinkGraph of absolute symbols, and a callback in dynamic library search generators to enable using it to expose its symbols to the platform/orc runtime. This allows e.g. using __orc_rt_run_program to run a precompiled function that was found via dlsym. Ideally we would use this in llvm-jitlink's own search generator, but it will require more work to align with the Process/Platform JITDylib split, so not handled here. As part of this change we need to handle LinkGraphs that only have absolute symbols.
Diffstat (limited to 'llvm/lib/ExecutionEngine')
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLink.cpp35
-rw-r--r--llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp14
-rw-r--r--llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp12
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp12
-rw-r--r--llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp2
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp14
6 files changed, 78 insertions, 11 deletions
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
index d86ceb99..7f743db 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp
@@ -468,6 +468,41 @@ createLinkGraphFromObject(MemoryBufferRef ObjectBuffer) {
};
}
+std::unique_ptr<LinkGraph> absoluteSymbolsLinkGraph(const Triple &TT,
+ orc::SymbolMap Symbols) {
+ unsigned PointerSize;
+ endianness Endianness =
+ TT.isLittleEndian() ? endianness::little : endianness::big;
+ switch (TT.getArch()) {
+ case Triple::aarch64:
+ case llvm::Triple::riscv64:
+ case Triple::x86_64:
+ PointerSize = 8;
+ break;
+ case llvm::Triple::arm:
+ case llvm::Triple::riscv32:
+ case llvm::Triple::x86:
+ PointerSize = 4;
+ break;
+ default:
+ llvm::report_fatal_error("unhandled target architecture");
+ }
+
+ static std::atomic<uint64_t> Counter = {0};
+ auto Index = Counter.fetch_add(1, std::memory_order_relaxed);
+ auto G = std::make_unique<LinkGraph>(
+ "<Absolute Symbols " + std::to_string(Index) + ">", TT, PointerSize,
+ Endianness, /*GetEdgeKindName=*/nullptr);
+ for (auto &[Name, Def] : Symbols) {
+ auto &Sym =
+ G->addAbsoluteSymbol(*Name, Def.getAddress(), /*Size=*/0,
+ Linkage::Strong, Scope::Default, /*IsLive=*/true);
+ Sym.setCallable(Def.getFlags().isCallable());
+ }
+
+ return G;
+}
+
void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx) {
switch (G->getTargetTriple().getObjectFormat()) {
case Triple::MachO:
diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
index 5361272..0114476 100644
--- a/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
@@ -48,6 +48,14 @@ void JITLinkerBase::linkPhase1(std::unique_ptr<JITLinkerBase> Self) {
if (auto Err = runPasses(Passes.PostPrunePasses))
return Ctx->notifyFailed(std::move(Err));
+ // Skip straight to phase 2 if the graph is empty with no associated actions.
+ if (G->allocActions().empty() && llvm::all_of(G->sections(), [](Section &S) {
+ return S.getMemLifetime() == orc::MemLifetime::NoAlloc;
+ })) {
+ linkPhase2(std::move(Self), nullptr);
+ return;
+ }
+
Ctx->getMemoryManager().allocate(
Ctx->getJITLinkDylib(), *G,
[S = std::move(Self)](AllocResult AR) mutable {
@@ -163,6 +171,12 @@ void JITLinkerBase::linkPhase3(std::unique_ptr<JITLinkerBase> Self,
if (auto Err = runPasses(Passes.PostFixupPasses))
return abandonAllocAndBailOut(std::move(Self), std::move(Err));
+ // Skip straight to phase 4 if the graph has no allocation.
+ if (!Alloc) {
+ linkPhase4(std::move(Self), JITLinkMemoryManager::FinalizedAlloc{});
+ return;
+ }
+
Alloc->finalize([S = std::move(Self)](FinalizeResult FR) mutable {
// FIXME: Once MSVC implements c++17 order of evaluation rules for calls
// this can be simplified to
diff --git a/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp b/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp
index 2e2e7a9..460f4e1 100644
--- a/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.cpp
@@ -12,15 +12,15 @@ namespace llvm {
namespace orc {
Expected<std::unique_ptr<EPCDynamicLibrarySearchGenerator>>
-EPCDynamicLibrarySearchGenerator::Load(ExecutionSession &ES,
- const char *LibraryPath,
- SymbolPredicate Allow) {
+EPCDynamicLibrarySearchGenerator::Load(
+ ExecutionSession &ES, const char *LibraryPath, SymbolPredicate Allow,
+ AddAbsoluteSymbolsFn AddAbsoluteSymbols) {
auto Handle = ES.getExecutorProcessControl().loadDylib(LibraryPath);
if (!Handle)
return Handle.takeError();
- return std::make_unique<EPCDynamicLibrarySearchGenerator>(ES, *Handle,
- std::move(Allow));
+ return std::make_unique<EPCDynamicLibrarySearchGenerator>(
+ ES, *Handle, std::move(Allow), std::move(AddAbsoluteSymbols));
}
Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
@@ -62,6 +62,8 @@ Error EPCDynamicLibrarySearchGenerator::tryToGenerate(
return Error::success();
// Define resolved symbols.
+ if (AddAbsoluteSymbols)
+ return AddAbsoluteSymbols(JD, std::move(NewSymbols));
return JD.define(absoluteSymbols(std::move(NewSymbols)));
}
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index 8d5608c..3952445 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -218,19 +218,23 @@ void ItaniumCXAAtExitSupport::runAtExits(void *DSOHandle) {
}
DynamicLibrarySearchGenerator::DynamicLibrarySearchGenerator(
- sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow)
+ sys::DynamicLibrary Dylib, char GlobalPrefix, SymbolPredicate Allow,
+ AddAbsoluteSymbolsFn AddAbsoluteSymbols)
: Dylib(std::move(Dylib)), Allow(std::move(Allow)),
+ AddAbsoluteSymbols(std::move(AddAbsoluteSymbols)),
GlobalPrefix(GlobalPrefix) {}
Expected<std::unique_ptr<DynamicLibrarySearchGenerator>>
DynamicLibrarySearchGenerator::Load(const char *FileName, char GlobalPrefix,
- SymbolPredicate Allow) {
+ SymbolPredicate Allow,
+ AddAbsoluteSymbolsFn AddAbsoluteSymbols) {
std::string ErrMsg;
auto Lib = sys::DynamicLibrary::getPermanentLibrary(FileName, &ErrMsg);
if (!Lib.isValid())
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
return std::make_unique<DynamicLibrarySearchGenerator>(
- std::move(Lib), GlobalPrefix, std::move(Allow));
+ std::move(Lib), GlobalPrefix, std::move(Allow),
+ std::move(AddAbsoluteSymbols));
}
Error DynamicLibrarySearchGenerator::tryToGenerate(
@@ -261,6 +265,8 @@ Error DynamicLibrarySearchGenerator::tryToGenerate(
if (NewSymbols.empty())
return Error::success();
+ if (AddAbsoluteSymbols)
+ return AddAbsoluteSymbols(JD, std::move(NewSymbols));
return JD.define(absoluteSymbols(std::move(NewSymbols)));
}
diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
index 9057300..6c17f14 100644
--- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
@@ -1608,6 +1608,8 @@ Error MachOPlatform::MachOPlatformPlugin::prepareSymbolTableRegistration(
SmallVector<jitlink::Symbol *> SymsToProcess;
for (auto *Sym : G.defined_symbols())
SymsToProcess.push_back(Sym);
+ for (auto *Sym : G.absolute_symbols())
+ SymsToProcess.push_back(Sym);
for (auto *Sym : SymsToProcess) {
if (!Sym->hasName())
diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
index 3d77f82..b828294 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
@@ -93,15 +93,20 @@ private:
Interface LGI;
- for (auto *Sym : G.defined_symbols()) {
+ auto AddSymbol = [&](Symbol *Sym) {
// Skip local symbols.
if (Sym->getScope() == Scope::Local)
- continue;
+ return;
assert(Sym->hasName() && "Anonymous non-local symbol?");
LGI.SymbolFlags[ES.intern(Sym->getName())] =
getJITSymbolFlagsForSymbol(*Sym);
- }
+ };
+
+ for (auto *Sym : G.defined_symbols())
+ AddSymbol(Sym);
+ for (auto *Sym : G.absolute_symbols())
+ AddSymbol(Sym);
if (hasInitializerSection(G))
LGI.InitSymbol = makeInitSymbol(ES, G);
@@ -705,6 +710,9 @@ Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR,
if (Err)
return Err;
+ if (!FA)
+ return Error::success();
+
return MR.withResourceKeyDo(
[&](ResourceKey K) { Allocs[K].push_back(std::move(FA)); });
}