[llvm] 171ffd4 - [ORC] StaticLibraryDefinitionGenerator -- support in-memory universal binaries.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 13 08:54:01 PST 2023
Author: Lang Hames
Date: 2023-02-13T08:53:53-08:00
New Revision: 171ffd499e16f365ab1987697922c5e5b3efa113
URL: https://github.com/llvm/llvm-project/commit/171ffd499e16f365ab1987697922c5e5b3efa113
DIFF: https://github.com/llvm/llvm-project/commit/171ffd499e16f365ab1987697922c5e5b3efa113.diff
LOG: [ORC] StaticLibraryDefinitionGenerator -- support in-memory universal binaries.
Add new StaticLibraryDefinitionGenerator::Create methods to support construction
from in-memory universal binaries.
Added:
Modified:
llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index 812313b68c7e2..4d2b228bea807 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -36,6 +36,10 @@ class Function;
class Module;
class Value;
+namespace object {
+class MachOUniversalBinary;
+}
+
namespace orc {
class ObjectLayer;
@@ -281,6 +285,13 @@ class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
Load(ObjectLayer &L, const char *FileName, const Triple &TT,
GetObjectFileInterface GetObjFileInterface = GetObjectFileInterface());
+ /// Try to create a StaticLibrarySearchGenerator from the given memory buffer
+ /// and Archive object.
+ static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
+ Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
+ std::unique_ptr<object::Archive> Archive,
+ GetObjectFileInterface GetObjFileInterface = GetObjectFileInterface());
+
/// Try to create a StaticLibrarySearchGenerator from the given memory buffer.
/// This call will succeed if the buffer contains a valid archive, otherwise
/// it will return an error.
@@ -288,6 +299,16 @@ class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
GetObjectFileInterface GetObjFileInterface = GetObjectFileInterface());
+ /// Try to create a StaticLibrarySearchGenerator from the given memory buffer.
+ ///
+ /// This call will succeed if the buffer contains a valid static library or a
+ /// MachO universal binary containing a static library that is compatible
+ /// with the given triple. Otherwise it will return an error.
+ static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
+ Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
+ const Triple &TT,
+ GetObjectFileInterface GetObjFileInterface = GetObjectFileInterface());
+
/// Returns a list of filenames of dynamic libraries that this archive has
/// imported. This class does not load these libraries by itself. User is
/// responsible for making sure these libraries are avaliable to the JITDylib.
@@ -302,11 +323,14 @@ class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
private:
StaticLibraryDefinitionGenerator(ObjectLayer &L,
std::unique_ptr<MemoryBuffer> ArchiveBuffer,
+ std::unique_ptr<object::Archive> Archive,
GetObjectFileInterface GetObjFileInterface,
Error &Err);
-
Error buildObjectFilesMap();
+ static Expected<std::pair<size_t, size_t>>
+ getSliceRangeForArch(object::MachOUniversalBinary &UB, const Triple &TT);
+
ObjectLayer &L;
GetObjectFileInterface GetObjFileInterface;
std::set<std::string> ImportedDynamicLibraries;
diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
index 409174dac3c28..b21c81abbfec1 100644
--- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -299,32 +299,22 @@ StaticLibraryDefinitionGenerator::Load(
// If this is a universal binary then search for a slice matching the given
// Triple.
if (auto *UB = cast<object::MachOUniversalBinary>(B->getBinary())) {
- for (const auto &Obj : UB->objects()) {
- auto ObjTT = Obj.getTriple();
- if (ObjTT.getArch() == TT.getArch() &&
- ObjTT.getSubArch() == TT.getSubArch() &&
- (TT.getVendor() == Triple::UnknownVendor ||
- ObjTT.getVendor() == TT.getVendor())) {
- // We found a match. Create an instance from a buffer covering this
- // slice.
- auto SliceBuffer = MemoryBuffer::getFileSlice(FileName, Obj.getSize(),
- Obj.getOffset());
- if (!SliceBuffer)
- return make_error<StringError>(
- Twine("Could not create buffer for ") + TT.str() + " slice of " +
- FileName + ": [ " + formatv("{0:x}", Obj.getOffset()) +
- " .. " + formatv("{0:x}", Obj.getOffset() + Obj.getSize()) +
- ": " + SliceBuffer.getError().message(),
- SliceBuffer.getError());
- return Create(L, std::move(*SliceBuffer),
- std::move(GetObjFileInterface));
- }
- }
- return make_error<StringError>(Twine("Universal binary ") + FileName +
- " does not contain a slice for " +
- TT.str(),
- inconvertibleErrorCode());
+ auto SliceRange = getSliceRangeForArch(*UB, TT);
+ if (!SliceRange)
+ return SliceRange.takeError();
+
+ auto SliceBuffer = MemoryBuffer::getFileSlice(FileName, SliceRange->second,
+ SliceRange->first);
+ if (!SliceBuffer)
+ return make_error<StringError>(
+ Twine("Could not create buffer for ") + TT.str() + " slice of " +
+ FileName + ": [ " + formatv("{0:x}", SliceRange->first) + " .. " +
+ formatv("{0:x}", SliceRange->first + SliceRange->second) + ": " +
+ SliceBuffer.getError().message(),
+ SliceBuffer.getError());
+
+ return Create(L, std::move(*SliceBuffer), std::move(GetObjFileInterface));
}
return make_error<StringError>(Twine("Unrecognized file type for ") +
@@ -335,12 +325,15 @@ StaticLibraryDefinitionGenerator::Load(
Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
StaticLibraryDefinitionGenerator::Create(
ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
+ std::unique_ptr<object::Archive> Archive,
GetObjectFileInterface GetObjFileInterface) {
+
Error Err = Error::success();
std::unique_ptr<StaticLibraryDefinitionGenerator> ADG(
new StaticLibraryDefinitionGenerator(
- L, std::move(ArchiveBuffer), std::move(GetObjFileInterface), Err));
+ L, std::move(ArchiveBuffer), std::move(Archive),
+ std::move(GetObjFileInterface), Err));
if (Err)
return std::move(Err);
@@ -348,6 +341,57 @@ StaticLibraryDefinitionGenerator::Create(
return std::move(ADG);
}
+Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
+StaticLibraryDefinitionGenerator::Create(
+ ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
+ GetObjectFileInterface GetObjFileInterface) {
+
+ auto Archive = object::Archive::create(ArchiveBuffer->getMemBufferRef());
+ if (!Archive)
+ return Archive.takeError();
+
+ return Create(L, std::move(ArchiveBuffer), std::move(*Archive),
+ std::move(GetObjFileInterface));
+}
+
+Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
+StaticLibraryDefinitionGenerator::Create(
+ ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
+ const Triple &TT, GetObjectFileInterface GetObjFileInterface) {
+
+ auto B = object::createBinary(ArchiveBuffer->getMemBufferRef());
+ if (!B)
+ return B.takeError();
+
+ // If this is a regular archive then create an instance from it.
+ if (isa<object::Archive>(*B))
+ return Create(L, std::move(ArchiveBuffer), std::move(GetObjFileInterface));
+
+ // If this is a universal binary then search for a slice matching the given
+ // Triple.
+ if (auto *UB = cast<object::MachOUniversalBinary>(B->get())) {
+ auto SliceRange = getSliceRangeForArch(*UB, TT);
+ if (!SliceRange)
+ return SliceRange.takeError();
+
+ MemoryBufferRef SliceRef(
+ StringRef(ArchiveBuffer->getBufferStart() + SliceRange->first,
+ SliceRange->second),
+ ArchiveBuffer->getBufferIdentifier());
+
+ auto Archive = object::Archive::create(SliceRef);
+ if (!Archive)
+ return Archive.takeError();
+
+ return Create(L, std::move(ArchiveBuffer), std::move(*Archive),
+ std::move(GetObjFileInterface));
+ }
+
+ return make_error<StringError>(Twine("Unrecognized file type for ") +
+ ArchiveBuffer->getBufferIdentifier(),
+ inconvertibleErrorCode());
+}
+
Error StaticLibraryDefinitionGenerator::tryToGenerate(
LookupState &LS, LookupKind K, JITDylib &JD,
JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) {
@@ -417,12 +461,33 @@ Error StaticLibraryDefinitionGenerator::buildObjectFilesMap() {
return Error::success();
}
+Expected<std::pair<size_t, size_t>>
+StaticLibraryDefinitionGenerator::getSliceRangeForArch(
+ object::MachOUniversalBinary &UB, const Triple &TT) {
+
+ for (const auto &Obj : UB.objects()) {
+ auto ObjTT = Obj.getTriple();
+ if (ObjTT.getArch() == TT.getArch() &&
+ ObjTT.getSubArch() == TT.getSubArch() &&
+ (TT.getVendor() == Triple::UnknownVendor ||
+ ObjTT.getVendor() == TT.getVendor())) {
+ // We found a match. Return the range for the slice.
+ return std::make_pair(Obj.getOffset(), Obj.getSize());
+ }
+ }
+
+ return make_error<StringError>(Twine("Universal binary ") + UB.getFileName() +
+ " does not contain a slice for " +
+ TT.str(),
+ inconvertibleErrorCode());
+}
+
StaticLibraryDefinitionGenerator::StaticLibraryDefinitionGenerator(
ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
+ std::unique_ptr<object::Archive> Archive,
GetObjectFileInterface GetObjFileInterface, Error &Err)
: L(L), GetObjFileInterface(std::move(GetObjFileInterface)),
- ArchiveBuffer(std::move(ArchiveBuffer)),
- Archive(std::make_unique<object::Archive>(*this->ArchiveBuffer, Err)) {
+ ArchiveBuffer(std::move(ArchiveBuffer)), Archive(std::move(Archive)) {
ErrorAsOutParameter _(&Err);
if (!this->GetObjFileInterface)
this->GetObjFileInterface = getObjectFileInterface;
More information about the llvm-commits
mailing list