aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp')
-rw-r--r--llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp163
1 files changed, 153 insertions, 10 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index 95cf89ec3f8b..377a59993eb0 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
+#include "llvm/ExecutionEngine/JITLink/x86_64.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
#include "llvm/IR/Constants.h"
@@ -350,7 +351,6 @@ StaticLibraryDefinitionGenerator::Create(
Error StaticLibraryDefinitionGenerator::tryToGenerate(
LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
-
// Don't materialize symbols from static archives unless this is a static
// lookup.
if (K != LookupKind::Static)
@@ -364,16 +364,11 @@ Error StaticLibraryDefinitionGenerator::tryToGenerate(
for (const auto &KV : Symbols) {
const auto &Name = KV.first;
- auto Child = Archive->findSym(*Name);
- if (!Child)
- return Child.takeError();
- if (*Child == None)
+ if (!ObjectFilesMap.count(Name))
continue;
- auto ChildBuffer = (*Child)->getMemoryBufferRef();
- if (!ChildBuffer)
- return ChildBuffer.takeError();
+ auto ChildBuffer = ObjectFilesMap[Name];
ChildBufferInfos.insert(
- {ChildBuffer->getBuffer(), ChildBuffer->getBufferIdentifier()});
+ {ChildBuffer.getBuffer(), ChildBuffer.getBufferIdentifier()});
}
for (auto ChildBufferInfo : ChildBufferInfos) {
@@ -392,15 +387,163 @@ Error StaticLibraryDefinitionGenerator::tryToGenerate(
return Error::success();
}
+Error StaticLibraryDefinitionGenerator::buildObjectFilesMap() {
+ DenseMap<uint64_t, MemoryBufferRef> MemoryBuffers;
+ DenseSet<uint64_t> Visited;
+ DenseSet<uint64_t> Excluded;
+ for (auto &S : Archive->symbols()) {
+ StringRef SymName = S.getName();
+ auto Member = S.getMember();
+ if (!Member)
+ return Member.takeError();
+ auto DataOffset = Member->getDataOffset();
+ if (!Visited.count(DataOffset)) {
+ Visited.insert(DataOffset);
+ auto Child = Member->getAsBinary();
+ if (!Child)
+ return Child.takeError();
+ if ((*Child)->isCOFFImportFile()) {
+ ImportedDynamicLibraries.insert((*Child)->getFileName().str());
+ Excluded.insert(DataOffset);
+ continue;
+ }
+ MemoryBuffers[DataOffset] = (*Child)->getMemoryBufferRef();
+ }
+ if (!Excluded.count(DataOffset))
+ ObjectFilesMap[L.getExecutionSession().intern(SymName)] =
+ MemoryBuffers[DataOffset];
+ }
+
+ return Error::success();
+}
+
StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator(
ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
GetObjectFileInterface GetObjFileInterface, Error &Err)
: L(L), GetObjFileInterface(std::move(GetObjFileInterface)),
ArchiveBuffer(std::move(ArchiveBuffer)),
Archive(std::make_unique<object::Archive>(*this->ArchiveBuffer, Err)) {
-
+ ErrorAsOutParameter _(&Err);
if (!this->GetObjFileInterface)
this->GetObjFileInterface = getObjectFileInterface;
+ if (!Err)
+ Err = buildObjectFilesMap();
+}
+
+std::unique_ptr<DLLImportDefinitionGenerator>
+DLLImportDefinitionGenerator::Create(ExecutionSession &ES,
+ ObjectLinkingLayer &L) {
+ return std::unique_ptr<DLLImportDefinitionGenerator>(
+ new DLLImportDefinitionGenerator(ES, L));
+}
+
+Error DLLImportDefinitionGenerator::tryToGenerate(
+ LookupState &LS, LookupKind K, JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
+ JITDylibSearchOrder LinkOrder;
+ JD.withLinkOrderDo([&](const JITDylibSearchOrder &LO) {
+ LinkOrder.reserve(LO.size());
+ for (auto &KV : LO) {
+ if (KV.first == &JD)
+ continue;
+ LinkOrder.push_back(KV);
+ }
+ });
+
+ // FIXME: if regular symbol name start with __imp_ we have to issue lookup of
+ // both __imp_ and stripped name and use the lookup information to resolve the
+ // real symbol name.
+ SymbolLookupSet LookupSet;
+ DenseMap<StringRef, SymbolLookupFlags> ToLookUpSymbols;
+ for (auto &KV : Symbols) {
+ StringRef Deinterned = *KV.first;
+ if (Deinterned.startswith(getImpPrefix()))
+ Deinterned = Deinterned.drop_front(StringRef(getImpPrefix()).size());
+ // Don't degrade the required state
+ if (ToLookUpSymbols.count(Deinterned) &&
+ ToLookUpSymbols[Deinterned] == SymbolLookupFlags::RequiredSymbol)
+ continue;
+ ToLookUpSymbols[Deinterned] = KV.second;
+ }
+
+ for (auto &KV : ToLookUpSymbols)
+ LookupSet.add(ES.intern(KV.first), KV.second);
+
+ auto Resolved =
+ ES.lookup(LinkOrder, LookupSet, LookupKind::DLSym, SymbolState::Resolved);
+ if (!Resolved)
+ return Resolved.takeError();
+
+ auto G = createStubsGraph(*Resolved);
+ if (!G)
+ return G.takeError();
+ return L.add(JD, std::move(*G));
+}
+
+Expected<unsigned>
+DLLImportDefinitionGenerator::getTargetPointerSize(const Triple &TT) {
+ switch (TT.getArch()) {
+ case Triple::x86_64:
+ return 8;
+ default:
+ return make_error<StringError>(
+ "architecture unsupported by DLLImportDefinitionGenerator",
+ inconvertibleErrorCode());
+ }
+}
+
+Expected<support::endianness>
+DLLImportDefinitionGenerator::getTargetEndianness(const Triple &TT) {
+ switch (TT.getArch()) {
+ case Triple::x86_64:
+ return support::endianness::little;
+ default:
+ return make_error<StringError>(
+ "architecture unsupported by DLLImportDefinitionGenerator",
+ inconvertibleErrorCode());
+ }
+}
+
+Expected<std::unique_ptr<jitlink::LinkGraph>>
+DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) {
+ Triple TT = ES.getExecutorProcessControl().getTargetTriple();
+ auto PointerSize = getTargetEndianness(TT);
+ if (!PointerSize)
+ return PointerSize.takeError();
+ auto Endianness = getTargetEndianness(TT);
+ if (!Endianness)
+ return Endianness.takeError();
+
+ auto G = std::make_unique<jitlink::LinkGraph>(
+ "<DLLIMPORT_STUBS>", TT, *PointerSize, *Endianness,
+ jitlink::getGenericEdgeKindName);
+ jitlink::Section &Sec =
+ G->createSection(getSectionName(), MemProt::Read | MemProt::Exec);
+
+ for (auto &KV : Resolved) {
+ jitlink::Symbol &Target = G->addAbsoluteSymbol(
+ *KV.first, ExecutorAddr(KV.second.getAddress()), *PointerSize,
+ jitlink::Linkage::Strong, jitlink::Scope::Local, false);
+
+ // Create __imp_ symbol
+ jitlink::Symbol &Ptr =
+ jitlink::x86_64::createAnonymousPointer(*G, Sec, &Target);
+ auto NameCopy = G->allocateString(Twine(getImpPrefix()) + *KV.first);
+ StringRef NameCopyRef = StringRef(NameCopy.data(), NameCopy.size());
+ Ptr.setName(NameCopyRef);
+ Ptr.setLinkage(jitlink::Linkage::Strong);
+ Ptr.setScope(jitlink::Scope::Default);
+
+ // Create PLT stub
+ // FIXME: check PLT stub of data symbol is not accessed
+ jitlink::Block &StubBlock =
+ jitlink::x86_64::createPointerJumpStubBlock(*G, Sec, Ptr);
+ G->addDefinedSymbol(StubBlock, 0, *KV.first, StubBlock.getSize(),
+ jitlink::Linkage::Strong, jitlink::Scope::Default, true,
+ false);
+ }
+
+ return std::move(G);
}
} // End namespace orc.