diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h index 1b8c4d4e181c..75f9f4bbe614 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h @@ -25,6 +25,7 @@ #include "llvm/Support/Memory.h" #include "llvm/Support/RecyclingAllocator.h" +#include #include #include #include @@ -363,7 +364,9 @@ public: static Expected> Create(); /// Create an instance using the given page size. - InProcessMemoryManager(uint64_t PageSize) : PageSize(PageSize) {} + InProcessMemoryManager(uint64_t PageSize) : PageSize(PageSize) { + assert(isPowerOf2_64(PageSize) && "PageSize must be a power of 2"); + } void allocate(const JITLinkDylib *JD, LinkGraph &G, OnAllocatedFunction OnAllocated) override; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LoadLinkableFile.h b/llvm/include/llvm/ExecutionEngine/Orc/LoadLinkableFile.h new file mode 100644 index 000000000000..5cc1b2ef7959 --- /dev/null +++ b/llvm/include/llvm/ExecutionEngine/Orc/LoadLinkableFile.h @@ -0,0 +1,64 @@ +//===--- LoadLinkableFile.h -- Load relocatables and archives ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// A wrapper for `MemoryBuffer::getFile` / `MemoryBuffer::getFileSlice` that: +// +// 1. Handles relocatable object files, archives, and macho universal +// binaries. +// 2. Adds file paths to errors by default. +// 3. Checks architecture compatibility up-front. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_LOADLINKABLEFILE_H +#define LLVM_EXECUTIONENGINE_ORC_LOADLINKABLEFILE_H + +#include "llvm/Support/Error.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/TargetParser/Triple.h" + +namespace llvm { +namespace orc { + +enum class LinkableFileKind { Archive, RelocatableObject }; + +enum LoadArchives { + Never, // Linkable file must not be an archive. + Allowed, // Linkable file is allowed to be an archive. + Required // Linkable file is required to be an archive. +}; + +/// Create a MemoryBuffer covering the "linkable" part of the given path. +/// +/// The path must contain a relocatable object file or universal binary, or +/// (if AllowArchives is true) an archive. +/// +/// If the path is a universal binary then it must contain a slice whose +/// architecture matches the architecture in the triple (an error will be +/// returned if there is no such slice, or if the triple does not specify an +/// architectur). +/// +/// If the path (or universal binary slice) is a relocatable object file then +/// its architecture must match the architecture in the triple (if given). +/// +/// If the path (or universal binary slice) is a relocatable object file then +/// its format must match the format in the triple (if given). +/// +/// No verification (e.g. architecture or format) is performed on the contents +/// of archives. +/// +/// If IdentifierOverride is provided then it will be used as the name of the +/// resulting buffer, rather than Path. +Expected, LinkableFileKind>> +loadLinkableFile(StringRef Path, const Triple &TT, LoadArchives LA, + std::optional IdentifierOverride = std::nullopt); + +} // End namespace orc +} // End namespace llvm + +#endif // LLVM_EXECUTIONENGINE_ORC_LOADLINKABLEFILE_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LoadRelocatableObject.h b/llvm/include/llvm/ExecutionEngine/Orc/LoadRelocatableObject.h deleted file mode 100644 index c79c3e316e38..000000000000 --- a/llvm/include/llvm/ExecutionEngine/Orc/LoadRelocatableObject.h +++ /dev/null @@ -1,37 +0,0 @@ -//===---- LoadRelocatableObject.h - Load relocatable objects ----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// A wrapper for `MemoryBuffer::getFile` / `MemoryBuffer::getFileSlice` that: -// -// 1. Adds file paths to errors by default. -// 2. Checks architecture compatibility up-front. -// 3. Handles MachO universal binaries, returning the MemoryBuffer for the -// requested slice only. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_ORC_LOADRELOCATABLEOBJECT_H -#define LLVM_EXECUTIONENGINE_ORC_LOADRELOCATABLEOBJECT_H - -#include "llvm/Support/Error.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/TargetParser/Triple.h" - -namespace llvm { -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> loadRelocatableObject( - StringRef Path, const Triple &TT, - std::optional IdentifierOverride = std::nullopt); - -} // End namespace orc -} // End namespace llvm - -#endif // LLVM_EXECUTIONENGINE_ORC_LOADRELOCATABLEOBJECT_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/MachO.h b/llvm/include/llvm/ExecutionEngine/Orc/MachO.h index 8bf2550d2d4f..0ae7fc80acad 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/MachO.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/MachO.h @@ -13,6 +13,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_MACHO_H #define LLVM_EXECUTIONENGINE_ORC_MACHO_H +#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h" #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/TargetParser/Triple.h" @@ -45,16 +46,21 @@ checkMachORelocatableObject(std::unique_ptr 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> loadMachORelocatableObject( - StringRef Path, const Triple &TT, +Expected, LinkableFileKind>> +loadMachOLinkableFile( + StringRef Path, const Triple &TT, LoadArchives LA, std::optional IdentifierOverride = std::nullopt); /// Load a compatible relocatable object (if available) from a MachO universal /// binary. -Expected> -loadMachORelocatableObjectFromUniversalBinary( - StringRef UBPath, std::unique_ptr UBBuf, const Triple &TT, - std::optional IdentifierOverride = std::nullopt); +/// Path is only used for error reporting. Identifier will be used to name the +/// resulting buffer. +Expected, LinkableFileKind>> +loadLinkableSliceFromMachOUniversalBinary(sys::fs::file_t FD, + std::unique_ptr UBBuf, + const Triple &TT, LoadArchives LA, + StringRef UBPath, + StringRef Identifier); /// Utility for identifying the file-slice compatible with TT in a universal /// binary. diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp index dacf0e6c8aa4..42a77a52beef 100644 --- a/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/JITLinkMemoryManager.cpp @@ -326,22 +326,21 @@ private: Expected> InProcessMemoryManager::Create() { - if (auto PageSize = sys::Process::getPageSize()) + if (auto PageSize = sys::Process::getPageSize()) { + // FIXME: Just check this once on startup. + if (!isPowerOf2_64((uint64_t)*PageSize)) + return make_error( + "Could not create InProcessMemoryManager: Page size " + + Twine(*PageSize) + " is not a power of 2", + inconvertibleErrorCode()); + return std::make_unique(*PageSize); - else + } else return PageSize.takeError(); } void InProcessMemoryManager::allocate(const JITLinkDylib *JD, LinkGraph &G, OnAllocatedFunction OnAllocated) { - - // FIXME: Just check this once on startup. - if (!isPowerOf2_64((uint64_t)PageSize)) { - OnAllocated(make_error("Page size is not a power of 2", - inconvertibleErrorCode())); - return; - } - BasicLayout BL(G); /// Scan the request and calculate the group and total sizes. diff --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt index 7565b4762bb9..5dfd621781e4 100644 --- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt +++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt @@ -29,7 +29,7 @@ add_llvm_component_library(LLVMOrcJIT JITTargetMachineBuilder.cpp LazyReexports.cpp Layer.cpp - LoadRelocatableObject.cpp + LoadLinkableFile.cpp LookupAndRecordAddrs.cpp LLJIT.cpp MachO.cpp diff --git a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp index 36bd425beab8..c4a65ebbe5a3 100644 --- a/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp @@ -9,6 +9,7 @@ #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/ExecutionEngine/JITLink/x86_64.h" #include "llvm/ExecutionEngine/Orc/Layer.h" +#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h" #include "llvm/ExecutionEngine/Orc/MachO.h" #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" #include "llvm/IR/Constants.h" @@ -277,45 +278,12 @@ StaticLibraryDefinitionGenerator::Load( ObjectLayer &L, const char *FileName, GetObjectFileInterface GetObjFileInterface) { - auto B = object::createBinary(FileName); - if (!B) - return createFileError(FileName, B.takeError()); + const auto &TT = L.getExecutionSession().getTargetTriple(); + auto Linkable = loadLinkableFile(FileName, TT, LoadArchives::Required); + if (!Linkable) + return Linkable.takeError(); - // If this is a regular archive then create an instance from it. - if (isa(B->getBinary())) { - auto [Archive, ArchiveBuffer] = B->takeBinary(); - return Create(L, std::move(ArchiveBuffer), - std::unique_ptr( - static_cast(Archive.release())), - std::move(GetObjFileInterface)); - } - - // If this is a universal binary then search for a slice matching the given - // Triple. - if (auto *UB = dyn_cast(B->getBinary())) { - - const auto &TT = L.getExecutionSession().getTargetTriple(); - - auto SliceRange = getMachOSliceRangeForTriple(*UB, TT); - if (!SliceRange) - return SliceRange.takeError(); - - auto SliceBuffer = MemoryBuffer::getFileSlice(FileName, SliceRange->second, - SliceRange->first); - if (!SliceBuffer) - return make_error( - 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(Twine("Unrecognized file type for ") + - FileName, - inconvertibleErrorCode()); + return Create(L, std::move(Linkable->first), std::move(GetObjFileInterface)); } Expected> diff --git a/llvm/lib/ExecutionEngine/Orc/LoadLinkableFile.cpp b/llvm/lib/ExecutionEngine/Orc/LoadLinkableFile.cpp new file mode 100644 index 000000000000..77ae7c7ca2e0 --- /dev/null +++ b/llvm/lib/ExecutionEngine/Orc/LoadLinkableFile.cpp @@ -0,0 +1,121 @@ +//===------- LoadLinkableFile.cpp -- Load relocatables and archives -------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h" + +#include "llvm/ADT/ScopeExit.h" +#include "llvm/BinaryFormat/Magic.h" +#include "llvm/ExecutionEngine/Orc/MachO.h" +#include "llvm/Support/FileSystem.h" + +#define DEBUG_TYPE "orc" + +namespace llvm { +namespace orc { + +static Expected> +checkCOFFRelocatableObject(std::unique_ptr Obj, + const Triple &TT) { + // TODO: Actually check the architecture of the file. + return std::move(Obj); +} + +static Expected> +checkELFRelocatableObject(std::unique_ptr Obj, const Triple &TT) { + // TODO: Actually check the architecture of the file. + return std::move(Obj); +} + +Expected, LinkableFileKind>> +loadLinkableFile(StringRef Path, const Triple &TT, LoadArchives LA, + std::optional IdentifierOverride) { + if (!IdentifierOverride) + IdentifierOverride = Path; + + Expected FDOrErr = + sys::fs::openNativeFileForRead(Path, sys::fs::OF_None); + if (!FDOrErr) + return createFileError(Path, FDOrErr.takeError()); + sys::fs::file_t FD = *FDOrErr; + auto CloseFile = make_scope_exit([&]() { sys::fs::closeFile(FD); }); + + auto Buf = + MemoryBuffer::getOpenFile(FD, *IdentifierOverride, /*FileSize=*/-1); + if (!Buf) + return make_error( + StringRef("Could not load object at path ") + Path, Buf.getError()); + + std::optional RequireFormat; + if (TT.getObjectFormat() != Triple::UnknownObjectFormat) + RequireFormat = TT.getObjectFormat(); + + switch (identify_magic((*Buf)->getBuffer())) { + case file_magic::archive: + if (LA != LoadArchives::Never) + return std::make_pair(std::move(*Buf), LinkableFileKind::Archive); + return make_error( + Path + " does not contain a relocatable object file", + inconvertibleErrorCode()); + case file_magic::coff_object: + if (LA == LoadArchives::Required) + return make_error(Path + " does not contain an archive", + inconvertibleErrorCode()); + + if (!RequireFormat || *RequireFormat == Triple::COFF) { + auto CheckedBuf = checkCOFFRelocatableObject(std::move(*Buf), TT); + if (!CheckedBuf) + return CheckedBuf.takeError(); + return std::make_pair(std::move(*CheckedBuf), + LinkableFileKind::RelocatableObject); + } + break; + case file_magic::elf_relocatable: + if (LA == LoadArchives::Required) + return make_error(Path + " does not contain an archive", + inconvertibleErrorCode()); + + if (!RequireFormat || *RequireFormat == Triple::ELF) { + auto CheckedBuf = checkELFRelocatableObject(std::move(*Buf), TT); + if (!CheckedBuf) + return CheckedBuf.takeError(); + return std::make_pair(std::move(*CheckedBuf), + LinkableFileKind::RelocatableObject); + } + break; + case file_magic::macho_object: + if (LA == LoadArchives::Required) + return make_error(Path + " does not contain an archive", + inconvertibleErrorCode()); + + if (!RequireFormat || *RequireFormat == Triple::MachO) { + auto CheckedBuf = checkMachORelocatableObject(std::move(*Buf), TT, false); + if (!CheckedBuf) + return CheckedBuf.takeError(); + return std::make_pair(std::move(*CheckedBuf), + LinkableFileKind::RelocatableObject); + } + break; + case file_magic::macho_universal_binary: + if (!RequireFormat || *RequireFormat == Triple::MachO) + return loadLinkableSliceFromMachOUniversalBinary( + FD, std::move(*Buf), TT, LA, Path, *IdentifierOverride); + break; + default: + break; + } + + return make_error( + Path + + " does not contain a relocatable object file or archive compatible " + "with " + + TT.str(), + inconvertibleErrorCode()); +} + +} // End namespace orc. +} // End namespace llvm. diff --git a/llvm/lib/ExecutionEngine/Orc/LoadRelocatableObject.cpp b/llvm/lib/ExecutionEngine/Orc/LoadRelocatableObject.cpp deleted file mode 100644 index 0a32a768313f..000000000000 --- a/llvm/lib/ExecutionEngine/Orc/LoadRelocatableObject.cpp +++ /dev/null @@ -1,82 +0,0 @@ -//===----- LoadRelocatableObject.cpp -- Load relocatable object files -----===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#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" - -namespace llvm { -namespace orc { - -static Expected> -checkCOFFRelocatableObject(std::unique_ptr Obj, - const Triple &TT) { - // TODO: Actually check the architecture of the file. - return std::move(Obj); -} - -static Expected> -checkELFRelocatableObject(std::unique_ptr Obj, const Triple &TT) { - // TODO: Actually check the architecture of the file. - return std::move(Obj); -} - -Expected> -loadRelocatableObject(StringRef Path, const Triple &TT, - std::optional IdentifierOverride) { - if (!IdentifierOverride) - IdentifierOverride = Path; - - Expected 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 make_error( - StringRef("Could not load object at path ") + Path, Buf.getError()); - - std::optional RequireFormat; - if (TT.getObjectFormat() != Triple::UnknownObjectFormat) - RequireFormat = TT.getObjectFormat(); - - switch (identify_magic((*Buf)->getBuffer())) { - case file_magic::coff_object: - if (!RequireFormat || *RequireFormat == Triple::COFF) - return checkCOFFRelocatableObject(std::move(*Buf), TT); - break; - case file_magic::elf_relocatable: - if (!RequireFormat || *RequireFormat == Triple::ELF) - return checkELFRelocatableObject(std::move(*Buf), TT); - break; - case file_magic::macho_object: - if (!RequireFormat || *RequireFormat == Triple::MachO) - return checkMachORelocatableObject(std::move(*Buf), TT, false); - break; - case file_magic::macho_universal_binary: - if (!RequireFormat || *RequireFormat == Triple::MachO) - return loadMachORelocatableObjectFromUniversalBinary( - Path, std::move(*Buf), TT, IdentifierOverride); - break; - default: - break; - } - return make_error( - Path + " does not contain a relocatable object file compatible with " + - TT.str(), - inconvertibleErrorCode()); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/llvm/lib/ExecutionEngine/Orc/MachO.cpp b/llvm/lib/ExecutionEngine/Orc/MachO.cpp index 7fab56f393c5..f6da924e48af 100644 --- a/llvm/lib/ExecutionEngine/Orc/MachO.cpp +++ b/llvm/lib/ExecutionEngine/Orc/MachO.cpp @@ -8,6 +8,7 @@ #include "llvm/ExecutionEngine/Orc/MachO.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Support/FileSystem.h" @@ -92,8 +93,8 @@ checkMachORelocatableObject(std::unique_ptr Obj, const Triple &TT, return std::move(Obj); } -Expected> -loadMachORelocatableObject(StringRef Path, const Triple &TT, +Expected, LinkableFileKind>> +loadMachORelocatableObject(StringRef Path, const Triple &TT, LoadArchives LA, std::optional IdentifierOverride) { assert((TT.getObjectFormat() == Triple::UnknownObjectFormat || TT.getObjectFormat() == Triple::MachO) && @@ -107,20 +108,27 @@ loadMachORelocatableObject(StringRef Path, const Triple &TT, if (!FDOrErr) return createFileError(Path, FDOrErr.takeError()); sys::fs::file_t FD = *FDOrErr; + auto CloseFile = make_scope_exit([&]() { sys::fs::closeFile(FD); }); + auto Buf = MemoryBuffer::getOpenFile(FD, *IdentifierOverride, /*FileSize=*/-1); - sys::fs::closeFile(FD); if (!Buf) return make_error( StringRef("Could not load MachO object at path ") + Path, Buf.getError()); switch (identify_magic((*Buf)->getBuffer())) { - case file_magic::macho_object: - return checkMachORelocatableObject(std::move(*Buf), TT, false); + case file_magic::macho_object: { + auto CheckedObj = checkMachORelocatableObject(std::move(*Buf), TT, false); + if (!CheckedObj) + return CheckedObj.takeError(); + return std::make_pair(std::move(*CheckedObj), + LinkableFileKind::RelocatableObject); + } case file_magic::macho_universal_binary: - return loadMachORelocatableObjectFromUniversalBinary(Path, std::move(*Buf), - TT); + return loadLinkableSliceFromMachOUniversalBinary(FD, std::move(*Buf), TT, + LoadArchives::Never, Path, + *IdentifierOverride); default: return make_error( Path + " does not contain a relocatable object file compatible with " + @@ -129,10 +137,12 @@ loadMachORelocatableObject(StringRef Path, const Triple &TT, } } -Expected> -loadMachORelocatableObjectFromUniversalBinary( - StringRef UBPath, std::unique_ptr UBBuf, const Triple &TT, - std::optional IdentifierOverride) { +Expected, LinkableFileKind>> +loadLinkableSliceFromMachOUniversalBinary(sys::fs::file_t FD, + std::unique_ptr UBBuf, + const Triple &TT, LoadArchives LA, + StringRef UBPath, + StringRef Identifier) { auto UniversalBin = object::MachOUniversalBinary::create(UBBuf->getMemBufferRef()); @@ -143,26 +153,47 @@ loadMachORelocatableObjectFromUniversalBinary( if (!SliceRange) return SliceRange.takeError(); - Expected 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); + auto Buf = MemoryBuffer::getOpenFileSlice(FD, Identifier, SliceRange->second, + SliceRange->first); if (!Buf) return make_error( "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) - return createFileError(UBPath, ObjBuf.takeError()); + switch (identify_magic((*Buf)->getBuffer())) { + case file_magic::archive: + if (LA != LoadArchives::Never) + return std::make_pair(std::move(*Buf), LinkableFileKind::Archive); + break; + case file_magic::macho_object: { + if (LA != LoadArchives::Required) { + auto CheckedObj = checkMachORelocatableObject(std::move(*Buf), TT, true); + if (!CheckedObj) + return CheckedObj.takeError(); + return std::make_pair(std::move(*CheckedObj), + LinkableFileKind::RelocatableObject); + } + break; + } + default: + break; + } - return checkMachORelocatableObject(std::move(*ObjBuf), TT, true); + auto FT = [&] { + switch (LA) { + case LoadArchives::Never: + return "a mach-o relocatable object file"; + case LoadArchives::Allowed: + return "a mach-o relocatable object file or archive"; + case LoadArchives::Required: + return "an archive"; + } + }; + + return make_error(TT.getArchName() + " slice of " + UBPath + + " does not contain " + FT(), + inconvertibleErrorCode()); } Expected> diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp index 01f2033c397f..f4dea2995f7d 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -29,7 +29,7 @@ #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" -#include "llvm/ExecutionEngine/Orc/LoadRelocatableObject.h" +#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h" #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" #include "llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h" #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" @@ -1108,7 +1108,9 @@ Session::Session(std::unique_ptr EPC, Error &Err) HarnessFiles.insert(HarnessFile); auto ObjBuffer = - ExitOnErr(loadRelocatableObject(HarnessFile, ES.getTargetTriple())); + ExitOnErr(loadLinkableFile(HarnessFile, ES.getTargetTriple(), + LoadArchives::Never)) + .first; auto ObjInterface = ExitOnErr(getObjectFileInterface(ES, ObjBuffer->getMemBufferRef())); @@ -1772,10 +1774,11 @@ static Error addTestHarnesses(Session &S) { LLVM_DEBUG(dbgs() << "Adding test harness objects...\n"); for (auto HarnessFile : TestHarnesses) { LLVM_DEBUG(dbgs() << " " << HarnessFile << "\n"); - auto ObjBuffer = loadRelocatableObject(HarnessFile, S.ES.getTargetTriple()); - if (!ObjBuffer) - return ObjBuffer.takeError(); - if (auto Err = S.ObjLayer.add(*S.MainJD, std::move(*ObjBuffer))) + auto Linkable = loadLinkableFile(HarnessFile, S.ES.getTargetTriple(), + LoadArchives::Never); + if (!Linkable) + return Linkable.takeError(); + if (auto Err = S.ObjLayer.add(*S.MainJD, std::move(Linkable->first))) return Err; } return Error::success(); @@ -1797,21 +1800,22 @@ static Error addObjects(Session &S, auto &JD = *std::prev(IdxToJD.lower_bound(InputFileArgIdx))->second; LLVM_DEBUG(dbgs() << " " << InputFileArgIdx << ": \"" << InputFile << "\" to " << JD.getName() << "\n";); - auto ObjBuffer = loadRelocatableObject(InputFile, S.ES.getTargetTriple()); + auto ObjBuffer = loadLinkableFile(InputFile, S.ES.getTargetTriple(), + LoadArchives::Never); if (!ObjBuffer) return ObjBuffer.takeError(); if (S.HarnessFiles.empty()) { - if (auto Err = S.ObjLayer.add(JD, std::move(*ObjBuffer))) + if (auto Err = S.ObjLayer.add(JD, std::move(ObjBuffer->first))) return Err; } else { // We're in -harness mode. Use a custom interface for this // test object. auto ObjInterface = - getTestObjectFileInterface(S, (*ObjBuffer)->getMemBufferRef()); + getTestObjectFileInterface(S, ObjBuffer->first->getMemBufferRef()); if (!ObjInterface) return ObjInterface.takeError(); - if (auto Err = S.ObjLayer.add(JD, std::move(*ObjBuffer), + if (auto Err = S.ObjLayer.add(JD, std::move(ObjBuffer->first), std::move(*ObjInterface))) return Err; }