Skip to content

Commit

Permalink
[ORC] Add an identifier-override argument to loadRelocatableObject an…
Browse files Browse the repository at this point in the history
…d friends.

API clients may want to use things other than paths as the buffer identifiers.

No testcase -- I haven't thought of a good way to expose this via the regression
testing tools.

rdar://133536831
  • Loading branch information
lhames committed Aug 23, 2024
1 parent 62da359 commit e15abb7
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 14 deletions.
5 changes: 3 additions & 2 deletions llvm/include/llvm/ExecutionEngine/Orc/LoadRelocatableObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ namespace orc {

// Load an object file compatible with the given triple (if given) from the
// given path. May return a file slice if the path contains a universal binary.
Expected<std::unique_ptr<MemoryBuffer>> loadRelocatableObject(StringRef Path,
const Triple &TT);
Expected<std::unique_ptr<MemoryBuffer>> loadRelocatableObject(
StringRef Path, const Triple &TT,
std::optional<StringRef> IdentifierOverride = std::nullopt);

} // End namespace orc
} // End namespace llvm
Expand Down
8 changes: 5 additions & 3 deletions llvm/include/llvm/ExecutionEngine/Orc/MachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ checkMachORelocatableObject(std::unique_ptr<MemoryBuffer> Obj, const Triple &TT,
/// Load a relocatable object compatible with TT from Path.
/// If Path is a universal binary, this function will return a buffer for the
/// slice compatible with Triple (if one is present).
Expected<std::unique_ptr<MemoryBuffer>>
loadMachORelocatableObject(StringRef Path, const Triple &TT);
Expected<std::unique_ptr<MemoryBuffer>> loadMachORelocatableObject(
StringRef Path, const Triple &TT,
std::optional<StringRef> IdentifierOverride = std::nullopt);

/// Load a compatible relocatable object (if available) from a MachO universal
/// binary.
Expected<std::unique_ptr<MemoryBuffer>>
loadMachORelocatableObjectFromUniversalBinary(
StringRef UBPath, std::unique_ptr<MemoryBuffer> UBBuf, const Triple &TT);
StringRef UBPath, std::unique_ptr<MemoryBuffer> UBBuf, const Triple &TT,
std::optional<StringRef> IdentifierOverride = std::nullopt);

/// Utility for identifying the file-slice compatible with TT in a universal
/// binary.
Expand Down
23 changes: 18 additions & 5 deletions llvm/lib/ExecutionEngine/Orc/LoadRelocatableObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "llvm/ExecutionEngine/Orc/LoadRelocatableObject.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/ExecutionEngine/Orc/MachO.h"
#include "llvm/Support/FileSystem.h"

#define DEBUG_TYPE "orc"

Expand All @@ -29,10 +30,22 @@ checkELFRelocatableObject(std::unique_ptr<MemoryBuffer> Obj, const Triple &TT) {
}

Expected<std::unique_ptr<MemoryBuffer>>
loadRelocatableObject(StringRef Path, const Triple &TT) {
auto Buf = MemoryBuffer::getFile(Path);
loadRelocatableObject(StringRef Path, const Triple &TT,
std::optional<StringRef> IdentifierOverride) {
if (!IdentifierOverride)
IdentifierOverride = Path;

Expected<sys::fs::file_t> FDOrErr =
sys::fs::openNativeFileForRead(Path, sys::fs::OF_None);
if (!FDOrErr)
return createFileError(Path, FDOrErr.takeError());
sys::fs::file_t FD = *FDOrErr;
auto Buf =
MemoryBuffer::getOpenFile(FD, *IdentifierOverride, /*FileSize=*/-1);
sys::fs::closeFile(FD);
if (!Buf)
return createFileError(Path, Buf.getError());
return make_error<StringError>(
StringRef("Could not load object at path ") + Path, Buf.getError());

std::optional<Triple::ObjectFormatType> RequireFormat;
if (TT.getObjectFormat() != Triple::UnknownObjectFormat)
Expand All @@ -53,8 +66,8 @@ loadRelocatableObject(StringRef Path, const Triple &TT) {
break;
case file_magic::macho_universal_binary:
if (!RequireFormat || *RequireFormat == Triple::MachO)
return loadMachORelocatableObjectFromUniversalBinary(Path,
std::move(*Buf), TT);
return loadMachORelocatableObjectFromUniversalBinary(
Path, std::move(*Buf), TT, IdentifierOverride);
break;
default:
break;
Expand Down
37 changes: 33 additions & 4 deletions llvm/lib/ExecutionEngine/Orc/MachO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Support/FileSystem.h"

#define DEBUG_TYPE "orc"

Expand Down Expand Up @@ -85,14 +86,27 @@ checkMachORelocatableObject(std::unique_ptr<MemoryBuffer> Obj, const Triple &TT,
}

Expected<std::unique_ptr<MemoryBuffer>>
loadMachORelocatableObject(StringRef Path, const Triple &TT) {
loadMachORelocatableObject(StringRef Path, const Triple &TT,
std::optional<StringRef> IdentifierOverride) {
assert((TT.getObjectFormat() == Triple::UnknownObjectFormat ||
TT.getObjectFormat() == Triple::MachO) &&
"TT must specify MachO or Unknown object format");

auto Buf = MemoryBuffer::getFile(Path);
if (!IdentifierOverride)
IdentifierOverride = Path;

Expected<sys::fs::file_t> FDOrErr =
sys::fs::openNativeFileForRead(Path, sys::fs::OF_None);
if (!FDOrErr)
return createFileError(Path, FDOrErr.takeError());
sys::fs::file_t FD = *FDOrErr;
auto Buf =
MemoryBuffer::getOpenFile(FD, *IdentifierOverride, /*FileSize=*/-1);
sys::fs::closeFile(FD);
if (!Buf)
return createFileError(Path, Buf.getError());
return make_error<StringError>(
StringRef("Could not load MachO object at path ") + Path,
Buf.getError());

switch (identify_magic((*Buf)->getBuffer())) {
case file_magic::macho_object:
Expand All @@ -110,7 +124,8 @@ loadMachORelocatableObject(StringRef Path, const Triple &TT) {

Expected<std::unique_ptr<MemoryBuffer>>
loadMachORelocatableObjectFromUniversalBinary(
StringRef UBPath, std::unique_ptr<MemoryBuffer> UBBuf, const Triple &TT) {
StringRef UBPath, std::unique_ptr<MemoryBuffer> UBBuf, const Triple &TT,
std::optional<StringRef> IdentifierOverride) {

auto UniversalBin =
object::MachOUniversalBinary::create(UBBuf->getMemBufferRef());
Expand All @@ -121,6 +136,20 @@ loadMachORelocatableObjectFromUniversalBinary(
if (!SliceRange)
return SliceRange.takeError();

Expected<sys::fs::file_t> FDOrErr =
sys::fs::openNativeFileForRead(UBPath, sys::fs::OF_None);
if (!FDOrErr)
return createFileError(UBPath, FDOrErr.takeError());
sys::fs::file_t FD = *FDOrErr;
auto Buf = MemoryBuffer::getOpenFileSlice(
FD, *IdentifierOverride, SliceRange->second, SliceRange->first);
sys::fs::closeFile(FD);
if (!Buf)
return make_error<StringError>(
"Could not load " + TT.getArchName() +
" slice of MachO universal binary at path " + UBPath,
Buf.getError());

auto ObjBuf = errorOrToExpected(MemoryBuffer::getFileSlice(
UBPath, SliceRange->second, SliceRange->first, false));
if (!ObjBuf)
Expand Down

0 comments on commit e15abb7

Please sign in to comment.