[llvm] REAPPLY [ORC] Add automatic shared library resolver for unresolved symbols. #148410 (PR #164551)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 22 01:57:09 PDT 2025
https://github.com/SahilPatidar updated https://github.com/llvm/llvm-project/pull/164551
>From 1e9d2b2d28f662636369e0eac399a8777b51432f Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Wed, 22 Oct 2025 09:29:02 +0530
Subject: [PATCH 1/3] Reapply [ORC] Add automatic shared library resolver for
unresolved symbols.
---
.../ExecutionEngine/Orc/Shared/SymbolFilter.h | 173 +++
.../Orc/TargetProcess/LibraryResolver.h | 514 ++++++++
.../Orc/TargetProcess/LibraryScanner.h | 474 +++++++
.../Orc/TargetProcess/CMakeLists.txt | 2 +
.../Orc/TargetProcess/LibraryResolver.cpp | 369 ++++++
.../Orc/TargetProcess/LibraryScanner.cpp | 1159 +++++++++++++++++
.../ExecutionEngine/Orc/CMakeLists.txt | 1 +
.../ExecutionEngine/Orc/Inputs/A/A_linux.yaml | 460 +++++++
.../ExecutionEngine/Orc/Inputs/A/A_macho.yaml | 723 ++++++++++
.../ExecutionEngine/Orc/Inputs/B/B_linux.yaml | 460 +++++++
.../ExecutionEngine/Orc/Inputs/B/B_macho.yaml | 723 ++++++++++
.../ExecutionEngine/Orc/Inputs/C/C_linux.yaml | 461 +++++++
.../ExecutionEngine/Orc/Inputs/C/C_macho.yaml | 915 +++++++++++++
.../ExecutionEngine/Orc/Inputs/D/D_linux.yaml | 479 +++++++
.../ExecutionEngine/Orc/Inputs/D/D_macho.yaml | 801 ++++++++++++
.../ExecutionEngine/Orc/Inputs/Z/Z_linux.yaml | 460 +++++++
.../ExecutionEngine/Orc/Inputs/Z/Z_macho.yaml | 723 ++++++++++
.../Orc/LibraryResolverTest.cpp | 886 +++++++++++++
18 files changed, 9783 insertions(+)
create mode 100644 llvm/include/llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h
create mode 100644 llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h
create mode 100644 llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h
create mode 100644 llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryResolver.cpp
create mode 100644 llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_linux.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_macho.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_linux.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_macho.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_linux.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_macho.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/D/D_linux.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/D/D_macho.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_linux.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_macho.yaml
create mode 100644 llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h
new file mode 100644
index 0000000000000..517089341978a
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h
@@ -0,0 +1,173 @@
+//===- SymbolFilter.h - Utilities for Symbol Filtering ---------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H
+#define LLVM_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H
+
+#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
+
+#include <cmath>
+#include <type_traits>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+namespace shared {
+using SPSBloomFilter =
+ SPSTuple<bool, uint32_t, uint32_t, uint32_t, SPSSequence<uint64_t>>;
+}
+
+class BloomFilter {
+public:
+ using HashFunc = std::function<uint32_t(StringRef)>;
+
+ BloomFilter() = default;
+ BloomFilter(BloomFilter &&) noexcept = default;
+ BloomFilter &operator=(BloomFilter &&) noexcept = default;
+ BloomFilter(const BloomFilter &) = delete;
+ BloomFilter &operator=(const BloomFilter &) = delete;
+
+ BloomFilter(uint32_t SymbolCount, float FalsePositiveRate, HashFunc hashFn)
+ : HashFn(std::move(hashFn)) {
+ initialize(SymbolCount, FalsePositiveRate);
+ }
+ bool isInitialized() const { return Initialized; }
+
+ void add(StringRef Sym) {
+ assert(Initialized);
+ addHash(HashFn(Sym));
+ }
+
+ bool mayContain(StringRef Sym) const {
+ return !isEmpty() && testHash(HashFn(Sym));
+ }
+
+ bool isEmpty() const { return SymbolCount == 0; }
+
+private:
+ friend class shared::SPSSerializationTraits<shared::SPSBloomFilter,
+ BloomFilter>;
+ static constexpr uint32_t BitsPerEntry = 64;
+
+ bool Initialized = false;
+ uint32_t SymbolCount = 0;
+ uint32_t BloomSize = 0;
+ uint32_t BloomShift = 0;
+ std::vector<uint64_t> BloomTable;
+ HashFunc HashFn;
+
+ void initialize(uint32_t SymCount, float FalsePositiveRate) {
+ assert(SymCount > 0);
+ SymbolCount = SymCount;
+ Initialized = true;
+
+ float ln2 = std::log(2.0f);
+ float M = -1.0f * SymbolCount * std::log(FalsePositiveRate) / (ln2 * ln2);
+ BloomSize = static_cast<uint32_t>(std::ceil(M / BitsPerEntry));
+ BloomShift = std::min(6u, log2ceil(SymbolCount));
+ BloomTable.resize(BloomSize, 0);
+ }
+
+ void addHash(uint32_t Hash) {
+ uint32_t Hash2 = Hash >> BloomShift;
+ uint32_t N = (Hash / BitsPerEntry) % BloomSize;
+ uint64_t Mask =
+ (1ULL << (Hash % BitsPerEntry)) | (1ULL << (Hash2 % BitsPerEntry));
+ BloomTable[N] |= Mask;
+ }
+
+ bool testHash(uint32_t Hash) const {
+ uint32_t Hash2 = Hash >> BloomShift;
+ uint32_t N = (Hash / BitsPerEntry) % BloomSize;
+ uint64_t Mask =
+ (1ULL << (Hash % BitsPerEntry)) | (1ULL << (Hash2 % BitsPerEntry));
+ return (BloomTable[N] & Mask) == Mask;
+ }
+
+ static constexpr uint32_t log2ceil(uint32_t V) {
+ return V <= 1 ? 0 : 32 - countl_zero(V - 1);
+ }
+};
+
+class BloomFilterBuilder {
+public:
+ using HashFunc = BloomFilter::HashFunc;
+
+ BloomFilterBuilder() = default;
+
+ BloomFilterBuilder &setFalsePositiveRate(float Rate) {
+ assert(Rate > 0.0f && Rate < 1.0f);
+ FalsePositiveRate = Rate;
+ return *this;
+ }
+
+ BloomFilterBuilder &setHashFunction(HashFunc Fn) {
+ HashFn = std::move(Fn);
+ return *this;
+ }
+
+ BloomFilter build(ArrayRef<StringRef> Symbols) const {
+ assert(!Symbols.empty() && "Cannot build filter from empty symbol list.");
+ BloomFilter F(static_cast<uint32_t>(Symbols.size()), FalsePositiveRate,
+ HashFn);
+ for (const auto &Sym : Symbols)
+ F.add(Sym);
+
+ return F;
+ }
+
+private:
+ float FalsePositiveRate = 0.02f;
+ HashFunc HashFn = [](StringRef S) -> uint32_t {
+ uint32_t H = 5381;
+ for (char C : S)
+ H = ((H << 5) + H) + static_cast<uint8_t>(C); // H * 33 + C
+ return H;
+ };
+};
+
+namespace shared {
+
+template <> class SPSSerializationTraits<SPSBloomFilter, BloomFilter> {
+public:
+ static size_t size(const BloomFilter &Filter) {
+ return SPSBloomFilter::AsArgList::size(
+ Filter.Initialized, Filter.SymbolCount, Filter.BloomSize,
+ Filter.BloomShift, Filter.BloomTable);
+ }
+
+ static bool serialize(SPSOutputBuffer &OB, const BloomFilter &Filter) {
+ return SPSBloomFilter::AsArgList::serialize(
+ OB, Filter.Initialized, Filter.SymbolCount, Filter.BloomSize,
+ Filter.BloomShift, Filter.BloomTable);
+ }
+
+ static bool deserialize(SPSInputBuffer &IB, BloomFilter &Filter) {
+ bool IsInitialized;
+ uint32_t SymbolCount = 0, BloomSize = 0, BloomShift = 0;
+ std::vector<uint64_t> BloomTable;
+
+ if (!SPSBloomFilter::AsArgList::deserialize(
+ IB, IsInitialized, SymbolCount, BloomSize, BloomShift, BloomTable))
+ return false;
+
+ Filter.Initialized = IsInitialized;
+ Filter.SymbolCount = SymbolCount;
+ Filter.BloomSize = BloomSize;
+ Filter.BloomShift = BloomShift;
+ Filter.BloomTable = std::move(BloomTable);
+
+ return true;
+ }
+};
+
+} // end namespace shared
+} // end namespace orc
+} // end namespace llvm
+#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SYMBOLFILTER_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h
new file mode 100644
index 0000000000000..50d4f6d041da4
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h
@@ -0,0 +1,514 @@
+//===- LibraryResolver.h - Automatic Library Symbol Resolution -*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides support for automatically searching symbols across
+// dynamic libraries that have not yet been loaded.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ExecutionEngine/Orc/Shared/SymbolFilter.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h"
+#include "llvm/Support/Path.h"
+
+#include <atomic>
+#include <shared_mutex>
+#include <unordered_map>
+
+namespace llvm {
+namespace orc {
+
+/// Manages library metadata and state for symbol resolution.
+///
+/// Tracks libraries by load state and kind (user/system), and stores
+/// associated Bloom filters and hash maps to speed up symbol lookups.
+/// Thread-safe for concurrent access.
+class LibraryManager {
+public:
+ enum class LibState : uint8_t { Unloaded = 0, Loaded = 1, Queried = 2 };
+
+ class LibraryInfo {
+ public:
+ LibraryInfo(const LibraryInfo &) = delete;
+ LibraryInfo &operator=(const LibraryInfo &) = delete;
+
+ LibraryInfo(std::string FilePath, LibState S, PathType K,
+ std::optional<BloomFilter> Filter = std::nullopt)
+ : FilePath(std::move(FilePath)), S(S), K(K), Filter(std::move(Filter)) {
+ }
+
+ StringRef getBasePath() const { return sys::path::parent_path(FilePath); }
+ StringRef getFileName() const { return sys::path::filename(FilePath); }
+
+ std::string getFullPath() const { return FilePath; }
+
+ bool setFilter(BloomFilter F) {
+ std::lock_guard<std::shared_mutex> Lock(Mtx);
+ if (Filter)
+ return false;
+ Filter.emplace(std::move(F));
+ return true;
+ }
+
+ bool ensureFilterBuilt(const BloomFilterBuilder &FB,
+ ArrayRef<StringRef> Symbols) {
+ std::lock_guard<std::shared_mutex> Lock(Mtx);
+ if (Filter)
+ return false;
+ Filter.emplace(FB.build(Symbols));
+ return true;
+ }
+
+ bool mayContain(StringRef Symbol) const {
+ assert(hasFilter());
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ return Filter->mayContain(Symbol);
+ }
+
+ bool hasFilter() const {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ return Filter.has_value();
+ }
+
+ LibState getState() const { return S.load(); }
+ PathType getKind() const { return K; }
+
+ void setState(LibState s) { S.store(s); }
+
+ bool operator==(const LibraryInfo &other) const {
+ return FilePath == other.FilePath;
+ }
+
+ private:
+ std::string FilePath;
+ std::atomic<LibState> S;
+ PathType K;
+ std::optional<BloomFilter> Filter;
+ mutable std::shared_mutex Mtx;
+ };
+
+ /// A read-only view of libraries filtered by state and kind.
+ ///
+ /// Lets you loop over only the libraries in a map that match a given State
+ /// and PathType.
+ class FilteredView {
+ public:
+ using Map = StringMap<std::shared_ptr<LibraryInfo>>;
+ using Iterator = typename Map::const_iterator;
+ class FilterIterator {
+ public:
+ FilterIterator(Iterator it_, Iterator end_, LibState S, PathType K)
+ : it(it_), end(end_), S(S), K(K) {
+ advance();
+ }
+
+ bool operator!=(const FilterIterator &other) const {
+ return it != other.it;
+ }
+
+ const std::shared_ptr<LibraryInfo> &operator*() const {
+ return it->second;
+ }
+
+ FilterIterator &operator++() {
+ ++it;
+ advance();
+ return *this;
+ }
+
+ private:
+ void advance() {
+ for (; it != end; ++it)
+ if (it->second->getState() == S && it->second->getKind() == K)
+ break;
+ }
+ Iterator it;
+ Iterator end;
+ LibState S;
+ PathType K;
+ };
+ FilteredView(Iterator begin, Iterator end, LibState s, PathType k)
+ : mapBegin(begin), mapEnd(end), state(s), kind(k) {}
+
+ FilterIterator begin() const {
+ return FilterIterator(mapBegin, mapEnd, state, kind);
+ }
+
+ FilterIterator end() const {
+ return FilterIterator(mapEnd, mapEnd, state, kind);
+ }
+
+ private:
+ Iterator mapBegin;
+ Iterator mapEnd;
+ LibState state;
+ PathType kind;
+ };
+
+private:
+ StringMap<std::shared_ptr<LibraryInfo>> Libraries;
+ mutable std::shared_mutex Mtx;
+
+public:
+ using LibraryVisitor = std::function<bool(const LibraryInfo &)>;
+
+ LibraryManager() = default;
+ ~LibraryManager() = default;
+
+ bool addLibrary(std::string Path, PathType Kind,
+ std::optional<BloomFilter> Filter = std::nullopt) {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ if (Libraries.count(Path) > 0)
+ return false;
+ Libraries.insert({std::move(Path),
+ std::make_shared<LibraryInfo>(Path, LibState::Unloaded,
+ Kind, std::move(Filter))});
+ return true;
+ }
+
+ bool hasLibrary(StringRef Path) const {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ if (Libraries.count(Path) > 0)
+ return true;
+ return false;
+ }
+
+ bool removeLibrary(StringRef Path) {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ auto I = Libraries.find(Path);
+ if (I == Libraries.end())
+ return false;
+ Libraries.erase(I);
+ return true;
+ }
+
+ void markLoaded(StringRef Path) {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ if (auto It = Libraries.find(Path); It != Libraries.end())
+ It->second->setState(LibState::Loaded);
+ }
+
+ void markQueried(StringRef Path) {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ if (auto It = Libraries.find(Path); It != Libraries.end())
+ It->second->setState(LibState::Queried);
+ }
+
+ std::shared_ptr<LibraryInfo> getLibrary(StringRef Path) {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ if (auto It = Libraries.find(Path); It != Libraries.end())
+ return It->second;
+ return nullptr;
+ }
+
+ FilteredView getView(LibState S, PathType K) const {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ return FilteredView(Libraries.begin(), Libraries.end(), S, K);
+ }
+
+ void forEachLibrary(const LibraryVisitor &visitor) const {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ for (const auto &[_, entry] : Libraries) {
+ if (!visitor(*entry))
+ break;
+ }
+ }
+
+ bool isLoaded(StringRef Path) const {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ if (auto It = Libraries.find(Path.str()); It != Libraries.end())
+ return It->second->getState() == LibState::Loaded;
+ return false;
+ }
+
+ bool isQueried(StringRef Path) const {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ if (auto It = Libraries.find(Path.str()); It != Libraries.end())
+ return It->second->getState() == LibState::Queried;
+ return false;
+ }
+
+ void clear() {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ Libraries.clear();
+ }
+};
+
+using LibraryInfo = LibraryManager::LibraryInfo;
+
+struct SearchPlanEntry {
+ LibraryManager::LibState State; // Loaded, Queried, Unloaded
+ PathType Type; // User, System
+};
+
+struct SearchPolicy {
+ std::vector<SearchPlanEntry> Plan;
+
+ static SearchPolicy defaultPlan() {
+ return {{{LibraryManager::LibState::Loaded, PathType::User},
+ {LibraryManager::LibState::Queried, PathType::User},
+ {LibraryManager::LibState::Unloaded, PathType::User},
+ {LibraryManager::LibState::Loaded, PathType::System},
+ {LibraryManager::LibState::Queried, PathType::System},
+ {LibraryManager::LibState::Unloaded, PathType::System}}};
+ }
+};
+
+struct SymbolEnumeratorOptions {
+ enum Filter : uint32_t {
+ None = 0,
+ IgnoreUndefined = 1 << 0,
+ IgnoreWeak = 1 << 1,
+ IgnoreIndirect = 1 << 2,
+ IgnoreHidden = 1 << 3,
+ IgnoreNonGlobal = 1 << 4
+ };
+
+ static SymbolEnumeratorOptions defaultOptions() {
+ return {Filter::IgnoreUndefined | Filter::IgnoreWeak |
+ Filter::IgnoreIndirect};
+ }
+ uint32_t FilterFlags = Filter::None;
+};
+
+struct SearchConfig {
+ SearchPolicy Policy;
+ SymbolEnumeratorOptions Options;
+
+ SearchConfig()
+ : Policy(SearchPolicy::defaultPlan()), // default plan
+ Options(SymbolEnumeratorOptions::defaultOptions()) {}
+};
+
+/// Scans libraries and resolves Symbols across user and system paths.
+///
+/// Supports symbol enumeration and filtering via SymbolEnumerator, and tracks
+/// symbol resolution results through SymbolQuery. Thread-safe and uses
+/// LibraryScanHelper for efficient path resolution and caching.
+class LibraryResolver {
+ friend class LibraryResolutionDriver;
+
+public:
+ class SymbolEnumerator {
+ public:
+ enum class EnumerateResult { Continue, Stop, Error };
+
+ using OnEachSymbolFn = std::function<EnumerateResult(StringRef Sym)>;
+
+ static bool enumerateSymbols(StringRef Path, OnEachSymbolFn OnEach,
+ const SymbolEnumeratorOptions &Opts);
+ };
+
+ /// Tracks a set of symbols and the libraries where they are resolved.
+ ///
+ /// SymbolQuery is used to keep track of which symbols have been resolved
+ /// to which libraries. It supports concurrent read/write access using a
+ /// shared mutex, allowing multiple readers or a single writer at a time.
+ class SymbolQuery {
+ public:
+ /// Holds the result for a single symbol.
+ struct Result {
+ std::string Name;
+ std::string ResolvedLibPath;
+ };
+
+ private:
+ mutable std::shared_mutex Mtx;
+ StringMap<Result> Results;
+ std::atomic<size_t> ResolvedCount = 0;
+
+ public:
+ explicit SymbolQuery(const std::vector<std::string> &Symbols) {
+ for (const auto &s : Symbols) {
+ if (!Results.contains(s))
+ Results.insert({s, Result{s, ""}});
+ }
+ }
+
+ SmallVector<StringRef> getUnresolvedSymbols() const {
+ SmallVector<StringRef> Unresolved;
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ for (const auto &[name, res] : Results) {
+ if (res.ResolvedLibPath.empty())
+ Unresolved.push_back(name);
+ }
+ return Unresolved;
+ }
+
+ void resolve(StringRef Sym, const std::string &LibPath) {
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ auto It = Results.find(Sym);
+ if (It != Results.end() && It->second.ResolvedLibPath.empty()) {
+ It->second.ResolvedLibPath = LibPath;
+ ResolvedCount.fetch_add(1, std::memory_order_relaxed);
+ }
+ }
+
+ bool allResolved() const {
+ return ResolvedCount.load(std::memory_order_relaxed) == Results.size();
+ }
+
+ bool hasUnresolved() const {
+ return ResolvedCount.load(std::memory_order_relaxed) < Results.size();
+ }
+
+ std::optional<StringRef> getResolvedLib(StringRef Sym) const {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ auto It = Results.find(Sym);
+ if (It != Results.end() && !It->second.ResolvedLibPath.empty())
+ return StringRef(It->second.ResolvedLibPath);
+ return std::nullopt;
+ }
+
+ bool isResolved(StringRef Sym) const {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ auto It = Results.find(Sym.str());
+ return It != Results.end() && !It->second.ResolvedLibPath.empty();
+ }
+
+ std::vector<const Result *> getAllResults() const {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ std::vector<const Result *> Out;
+ Out.reserve(Results.size());
+ for (const auto &[_, res] : Results)
+ Out.push_back(&res);
+ return Out;
+ }
+ };
+
+ struct Setup {
+ std::vector<std::string> BasePaths;
+ std::shared_ptr<LibraryPathCache> Cache;
+ std::shared_ptr<PathResolver> PResolver;
+
+ size_t ScanBatchSize = 0;
+
+ LibraryScanner::ShouldScanFn ShouldScanCall = [](StringRef) {
+ return true;
+ };
+
+ BloomFilterBuilder FilterBuilder = BloomFilterBuilder();
+
+ static Setup
+ create(std::vector<std::string> BasePaths,
+ std::shared_ptr<LibraryPathCache> existingCache = nullptr,
+ std::shared_ptr<PathResolver> existingResolver = nullptr,
+ LibraryScanner::ShouldScanFn customShouldScan = nullptr) {
+ Setup S;
+ S.BasePaths = std::move(BasePaths);
+
+ S.Cache =
+ existingCache ? existingCache : std::make_shared<LibraryPathCache>();
+
+ S.PResolver = existingResolver ? existingResolver
+ : std::make_shared<PathResolver>(S.Cache);
+
+ if (customShouldScan)
+ S.ShouldScanCall = std::move(customShouldScan);
+
+ return S;
+ }
+ };
+
+ LibraryResolver() = delete;
+ explicit LibraryResolver(const Setup &S);
+ ~LibraryResolver() = default;
+
+ using OnSearchComplete = unique_function<void(SymbolQuery &)>;
+
+ void dump() {
+ int i = 0;
+ LibMgr.forEachLibrary([&](const LibraryInfo &Lib) -> bool {
+ dbgs() << ++i << ". Library Path : " << Lib.getFullPath() << " -> \n\t\t:"
+ << " ({Type : ("
+ << (Lib.getKind() == PathType::User ? "User" : "System")
+ << ") }, { State : "
+ << (Lib.getState() == LibraryManager::LibState::Loaded
+ ? "Loaded"
+ : "Unloaded")
+ << "})\n";
+ return true;
+ });
+ }
+
+ void searchSymbolsInLibraries(std::vector<std::string> &SymList,
+ OnSearchComplete OnComplete,
+ const SearchConfig &Config = SearchConfig());
+
+private:
+ bool scanLibrariesIfNeeded(PathType K, size_t BatchSize = 0);
+ void resolveSymbolsInLibrary(LibraryInfo &Lib, SymbolQuery &Q,
+ const SymbolEnumeratorOptions &Opts);
+ bool
+ symbolExistsInLibrary(const LibraryInfo &Lib, StringRef Sym,
+ std::vector<std::string> *MatchedSymbols = nullptr);
+
+ bool symbolExistsInLibrary(const LibraryInfo &Lib, StringRef SymName,
+ std::vector<std::string> *AllSymbols,
+ const SymbolEnumeratorOptions &Opts);
+
+ std::shared_ptr<LibraryPathCache> LibPathCache;
+ std::shared_ptr<PathResolver> LibPathResolver;
+ LibraryScanHelper ScanHelper;
+ BloomFilterBuilder FB;
+ LibraryManager LibMgr;
+ LibraryScanner::ShouldScanFn ShouldScanCall;
+ size_t scanBatchSize;
+};
+
+using SymbolEnumerator = LibraryResolver::SymbolEnumerator;
+using SymbolQuery = LibraryResolver::SymbolQuery;
+using EnumerateResult = SymbolEnumerator::EnumerateResult;
+
+class LibraryResolutionDriver {
+public:
+ static std::unique_ptr<LibraryResolutionDriver>
+ create(const LibraryResolver::Setup &S);
+
+ void addScanPath(const std::string &Path, PathType Kind);
+ bool markLibraryLoaded(StringRef Path);
+ bool markLibraryUnLoaded(StringRef Path);
+ bool isLibraryLoaded(StringRef Path) const {
+ return LR->LibMgr.isLoaded(Path);
+ }
+
+ void resetAll() {
+ LR->LibMgr.clear();
+ LR->ScanHelper.resetToScan();
+ LR->LibPathCache->clear();
+ }
+
+ void scanAll(size_t BatchSize = 0) {
+ LR->scanLibrariesIfNeeded(PathType::User, BatchSize);
+ LR->scanLibrariesIfNeeded(PathType::System, BatchSize);
+ }
+
+ void scan(PathType PK, size_t BatchSize = 0) {
+ LR->scanLibrariesIfNeeded(PK, BatchSize);
+ }
+
+ void resolveSymbols(std::vector<std::string> Symbols,
+ LibraryResolver::OnSearchComplete OnCompletion,
+ const SearchConfig &Config = SearchConfig());
+
+ ~LibraryResolutionDriver() = default;
+
+private:
+ LibraryResolutionDriver(std::unique_ptr<LibraryResolver> L)
+ : LR(std::move(L)) {}
+
+ std::unique_ptr<LibraryResolver> LR;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYRESOLVER_H
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h
new file mode 100644
index 0000000000000..d1c201306bf54
--- /dev/null
+++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h
@@ -0,0 +1,474 @@
+//===- LibraryScanner.h - Scanner for Shared Libraries ---------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides functionality for scanning dynamic (shared) libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYSCANNER_H
+#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYSCANNER_H
+
+#include "llvm/ADT/FunctionExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/StringSaver.h"
+
+#include <atomic>
+#include <mutex>
+#include <queue>
+#include <shared_mutex>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+
+namespace llvm {
+namespace orc {
+
+class LibraryManager;
+
+class LibraryPathCache {
+ friend class PathResolver;
+
+public:
+ LibraryPathCache() = default;
+
+ void clear(bool isRealPathCache = false) {
+ std::unique_lock<std::shared_mutex> lock(Mtx);
+ Seen.clear();
+ if (isRealPathCache) {
+ RealPathCache.clear();
+#ifndef _WIN32
+ ReadlinkCache.clear();
+ LstatCache.clear();
+#endif
+ }
+ }
+
+ void markSeen(const std::string &CanonPath) {
+ std::unique_lock<std::shared_mutex> lock(Mtx);
+ Seen.insert(CanonPath);
+ }
+
+ bool hasSeen(StringRef CanonPath) const {
+ std::shared_lock<std::shared_mutex> lock(Mtx);
+ return Seen.contains(CanonPath);
+ }
+
+ bool hasSeenOrMark(StringRef CanonPath) {
+ std::string s = CanonPath.str();
+ {
+ std::shared_lock<std::shared_mutex> lock(Mtx);
+ if (Seen.contains(s))
+ return true;
+ }
+ {
+ std::unique_lock<std::shared_mutex> lock(Mtx);
+ Seen.insert(s);
+ }
+ return false;
+ }
+
+private:
+ mutable std::shared_mutex Mtx;
+
+ struct PathInfo {
+ std::string canonicalPath;
+ std::error_code ErrnoCode;
+ };
+
+ void insert_realpath(StringRef Path, const PathInfo &Info) {
+ std::unique_lock<std::shared_mutex> lock(Mtx);
+ RealPathCache.insert({Path, Info});
+ }
+
+ std::optional<PathInfo> read_realpath(StringRef Path) const {
+ std::shared_lock<std::shared_mutex> lock(Mtx);
+ auto It = RealPathCache.find(Path);
+ if (It != RealPathCache.end())
+ return It->second;
+
+ return std::nullopt;
+ }
+
+ StringSet<> Seen;
+ StringMap<PathInfo> RealPathCache;
+
+#ifndef _WIN32
+ StringMap<std::string> ReadlinkCache;
+ StringMap<mode_t> LstatCache;
+
+ void insert_link(StringRef Path, const std::string &s) {
+ std::unique_lock<std::shared_mutex> lock(Mtx);
+ ReadlinkCache.insert({Path, s});
+ }
+
+ std::optional<std::string> read_link(StringRef Path) const {
+ std::shared_lock<std::shared_mutex> lock(Mtx);
+ auto It = ReadlinkCache.find(Path);
+ if (It != ReadlinkCache.end())
+ return It->second;
+
+ return std::nullopt;
+ }
+
+ void insert_lstat(StringRef Path, mode_t m) {
+ std::unique_lock<std::shared_mutex> lock(Mtx);
+ LstatCache.insert({Path, m});
+ }
+
+ std::optional<mode_t> read_lstat(StringRef Path) const {
+ std::shared_lock<std::shared_mutex> lock(Mtx);
+ auto It = LstatCache.find(Path);
+ if (It != LstatCache.end())
+ return It->second;
+
+ return std::nullopt;
+ }
+
+#endif
+};
+
+/// Resolves file system paths with optional caching of results.
+///
+/// Supports lstat, readlink, and realpath operations. Can resolve paths
+/// relative to a base and handle symbolic links. Caches results to reduce
+/// repeated system calls when enabled.
+class PathResolver {
+private:
+ std::shared_ptr<LibraryPathCache> LibPathCache;
+
+public:
+ PathResolver(std::shared_ptr<LibraryPathCache> cache)
+ : LibPathCache(std::move(cache)) {}
+
+ std::optional<std::string> resolve(StringRef Path, std::error_code &ec) {
+ return realpathCached(Path, ec);
+ }
+#ifndef _WIN32
+ mode_t lstatCached(StringRef Path);
+ std::optional<std::string> readlinkCached(StringRef Path);
+#endif
+ std::optional<std::string> realpathCached(StringRef Path, std::error_code &ec,
+ StringRef base = "",
+ bool baseIsResolved = false,
+ long symloopLevel = 40);
+};
+
+/// Performs placeholder substitution in dynamic library paths.
+///
+/// Configures known placeholders (like @loader_path) and replaces them
+/// in input paths with their resolved values.
+class DylibSubstitutor {
+public:
+ void configure(StringRef loaderPath);
+
+ std::string substitute(StringRef input) const {
+ for (const auto &[ph, value] : Placeholders) {
+ if (input.starts_with_insensitive(ph))
+ return (Twine(value) + input.drop_front(ph.size())).str();
+ }
+ return input.str();
+ }
+
+private:
+ StringMap<std::string> Placeholders;
+};
+
+/// Validates and normalizes dynamic library paths.
+///
+/// Uses a `PathResolver` to resolve paths to their canonical form and
+/// checks whether they point to valid shared libraries.
+class DylibPathValidator {
+public:
+ DylibPathValidator(PathResolver &PR) : LibPathResolver(PR) {}
+
+ static bool isSharedLibrary(StringRef Path);
+
+ std::optional<std::string> normalize(StringRef Path) const {
+ std::error_code ec;
+ auto real = LibPathResolver.resolve(Path, ec);
+ if (!real || ec)
+ return std::nullopt;
+
+ return real;
+ }
+
+ /// Validate the given path as a shared library.
+ std::optional<std::string> validate(StringRef Path) const {
+ auto realOpt = normalize(Path);
+ if (!realOpt)
+ return std::nullopt;
+
+ if (!isSharedLibrary(*realOpt))
+ return std::nullopt;
+
+ return realOpt;
+ }
+
+private:
+ PathResolver &LibPathResolver;
+};
+
+enum class SearchPathType {
+ RPath,
+ UsrOrSys,
+ RunPath,
+};
+
+struct SearchPathConfig {
+ ArrayRef<StringRef> Paths;
+ SearchPathType type;
+};
+
+class SearchPathResolver {
+public:
+ SearchPathResolver(const SearchPathConfig &Cfg,
+ StringRef PlaceholderPrefix = "")
+ : Kind(Cfg.type), PlaceholderPrefix(PlaceholderPrefix) {
+ for (auto &path : Cfg.Paths)
+ Paths.emplace_back(path.str());
+ }
+
+ std::optional<std::string> resolve(StringRef libStem,
+ const DylibSubstitutor &Subst,
+ DylibPathValidator &Validator) const;
+ SearchPathType searchPathType() const { return Kind; }
+
+private:
+ std::vector<std::string> Paths;
+ SearchPathType Kind;
+ std::string PlaceholderPrefix;
+};
+
+class DylibResolverImpl {
+public:
+ DylibResolverImpl(DylibSubstitutor Substitutor, DylibPathValidator &Validator,
+ std::vector<SearchPathResolver> Resolvers)
+ : Substitutor(std::move(Substitutor)), Validator(Validator),
+ Resolvers(std::move(Resolvers)) {}
+
+ std::optional<std::string> resolve(StringRef Stem,
+ bool VariateLibStem = false) const;
+
+private:
+ std::optional<std::string> tryWithExtensions(StringRef libstem) const;
+
+ DylibSubstitutor Substitutor;
+ DylibPathValidator &Validator;
+ std::vector<SearchPathResolver> Resolvers;
+};
+
+class DylibResolver {
+public:
+ DylibResolver(DylibPathValidator &Validator) : Validator(Validator) {}
+
+ void configure(StringRef loaderPath,
+ ArrayRef<SearchPathConfig> SearchPathCfg) {
+ DylibSubstitutor Substitutor;
+ Substitutor.configure(loaderPath);
+
+ std::vector<SearchPathResolver> Resolvers;
+ for (const auto &cfg : SearchPathCfg) {
+ Resolvers.emplace_back(cfg,
+ cfg.type == SearchPathType::RPath ? "@rpath" : "");
+ }
+
+ impl_ = std::make_unique<DylibResolverImpl>(
+ std::move(Substitutor), Validator, std::move(Resolvers));
+ }
+
+ std::optional<std::string> resolve(StringRef libStem,
+ bool VariateLibStem = false) const {
+ if (!impl_)
+ return std::nullopt;
+ return impl_->resolve(libStem, VariateLibStem);
+ }
+
+ static std::string resolvelinkerFlag(StringRef libStem,
+ StringRef loaderPath) {
+ DylibSubstitutor Substitutor;
+ Substitutor.configure(loaderPath);
+ return Substitutor.substitute(libStem);
+ }
+
+private:
+ DylibPathValidator &Validator;
+ std::unique_ptr<DylibResolverImpl> impl_;
+};
+
+enum class PathType : uint8_t { User, System, Unknown };
+
+enum class ScanState : uint8_t { NotScanned, Scanning, Scanned };
+
+struct LibrarySearchPath {
+ std::string BasePath; // Canonical base directory path
+ PathType Kind; // User or System
+ std::atomic<ScanState> State;
+
+ LibrarySearchPath(std::string Base, PathType K)
+ : BasePath(std::move(Base)), Kind(K), State(ScanState::NotScanned) {}
+};
+
+/// Scans and tracks libraries for symbol resolution.
+///
+/// Maintains a list of library paths to scan, caches scanned units,
+/// and resolves paths canonically for consistent tracking.
+class LibraryScanHelper {
+public:
+ explicit LibraryScanHelper(const std::vector<std::string> &SPaths,
+ std::shared_ptr<LibraryPathCache> LibPathCache,
+ std::shared_ptr<PathResolver> LibPathResolver)
+ : LibPathCache(std::move(LibPathCache)),
+ LibPathResolver(std::move(LibPathResolver)) {
+ DEBUG_WITH_TYPE(
+ "orc", dbgs() << "LibraryScanHelper::LibraryScanHelper: base paths : "
+ << SPaths.size() << "\n";);
+ for (const auto &p : SPaths)
+ addBasePath(p);
+ }
+
+ void
+ addBasePath(const std::string &P,
+ PathType Kind =
+ PathType::Unknown); // Add a canonical directory for scanning
+ std::vector<std::shared_ptr<LibrarySearchPath>>
+ getNextBatch(PathType Kind, size_t batchSize);
+
+ bool leftToScan(PathType K) const;
+ void resetToScan();
+
+ bool isTrackedBasePath(StringRef P) const;
+ std::vector<std::shared_ptr<LibrarySearchPath>> getAllUnits() const;
+
+ SmallVector<StringRef> getSearchPaths() const {
+ SmallVector<StringRef> SearchPaths;
+ for (const auto &[_, SP] : LibSearchPaths)
+ SearchPaths.push_back(SP->BasePath);
+ return SearchPaths;
+ }
+
+ PathResolver &getPathResolver() const { return *LibPathResolver; }
+
+ LibraryPathCache &getCache() const { return *LibPathCache; }
+
+ bool hasSeenOrMark(StringRef P) const {
+ return LibPathCache->hasSeenOrMark(P);
+ }
+
+ std::optional<std::string> resolve(StringRef P, std::error_code &ec) const {
+ return LibPathResolver->resolve(P.str(), ec);
+ }
+
+private:
+ std::string resolveCanonical(StringRef P, std::error_code &ec) const;
+ PathType classifyKind(StringRef P) const;
+
+ mutable std::shared_mutex Mtx;
+ std::shared_ptr<LibraryPathCache> LibPathCache;
+ std::shared_ptr<PathResolver> LibPathResolver;
+
+ StringMap<std::shared_ptr<LibrarySearchPath>>
+ LibSearchPaths; // key: canonical path
+ std::deque<StringRef> UnscannedUsr;
+ std::deque<StringRef> UnscannedSys;
+};
+
+/// Loads an object file and provides access to it.
+///
+/// Owns the underlying `ObjectFile` and ensures it is valid.
+/// Any errors encountered during construction are stored and
+/// returned when attempting to access the file.
+class ObjectFileLoader {
+public:
+ /// Construct an object file loader from the given path.
+ explicit ObjectFileLoader(StringRef Path) {
+ auto ObjOrErr = loadObjectFileWithOwnership(Path);
+ if (ObjOrErr)
+ Obj = std::move(*ObjOrErr);
+ else {
+ consumeError(std::move(Err));
+ Err = ObjOrErr.takeError();
+ }
+ }
+
+ ObjectFileLoader(const ObjectFileLoader &) = delete;
+ ObjectFileLoader &operator=(const ObjectFileLoader &) = delete;
+
+ ObjectFileLoader(ObjectFileLoader &&) = default;
+ ObjectFileLoader &operator=(ObjectFileLoader &&) = default;
+
+ /// Get the loaded object file, or return an error if loading failed.
+ Expected<object::ObjectFile &> getObjectFile() {
+ if (Err)
+ return std::move(Err);
+ return *Obj.getBinary();
+ }
+
+ static bool isArchitectureCompatible(const object::ObjectFile &Obj);
+
+private:
+ object::OwningBinary<object::ObjectFile> Obj;
+ Error Err = Error::success();
+
+ static Expected<object::OwningBinary<object::ObjectFile>>
+ loadObjectFileWithOwnership(StringRef FilePath);
+};
+
+/// Scans libraries, resolves dependencies, and registers them.
+class LibraryScanner {
+public:
+ using ShouldScanFn = std::function<bool(StringRef)>;
+
+ LibraryScanner(
+ LibraryScanHelper &H, LibraryManager &LibMgr,
+ ShouldScanFn ShouldScanCall = [](StringRef path) { return true; })
+ : ScanHelper(H), LibMgr(LibMgr),
+ ShouldScanCall(std::move(ShouldScanCall)) {}
+
+ void scanNext(PathType Kind, size_t batchSize = 1);
+
+ /// Dependency info for a library.
+ struct LibraryDepsInfo {
+ llvm::BumpPtrAllocator Alloc;
+ llvm::StringSaver Saver{Alloc};
+
+ SmallVector<StringRef, 2> rpath;
+ SmallVector<StringRef, 2> runPath;
+ SmallVector<StringRef, 4> deps;
+ bool isPIE = false;
+
+ void addRPath(StringRef s) { rpath.push_back(Saver.save(s)); }
+
+ void addRunPath(StringRef s) { runPath.push_back(Saver.save(s)); }
+
+ void addDep(StringRef s) { deps.push_back(Saver.save(s)); }
+ };
+
+private:
+ LibraryScanHelper &ScanHelper;
+ LibraryManager &LibMgr;
+ ShouldScanFn ShouldScanCall;
+
+ std::optional<std::string> shouldScan(StringRef FilePath);
+ Expected<LibraryDepsInfo> extractDeps(StringRef FilePath);
+
+ void handleLibrary(StringRef P, PathType K, int level = 1);
+
+ void scanBaseDir(std::shared_ptr<LibrarySearchPath> U);
+};
+
+using LibraryDepsInfo = LibraryScanner::LibraryDepsInfo;
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_LIBRARYSCANNER_H
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
index 927558649eb4d..c5f6f52baae19 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
@@ -16,9 +16,11 @@ add_llvm_component_library(LLVMOrcTargetProcess
ExecutorSharedMemoryMapperService.cpp
DefaultHostBootstrapValues.cpp
ExecutorResolver.cpp
+ LibraryResolver.cpp
JITLoaderGDB.cpp
JITLoaderPerf.cpp
JITLoaderVTune.cpp
+ LibraryScanner.cpp
OrcRTBootstrap.cpp
RegisterEHFrames.cpp
SimpleExecutorDylibManager.cpp
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryResolver.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryResolver.cpp
new file mode 100644
index 0000000000000..9d25b748ed565
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryResolver.cpp
@@ -0,0 +1,369 @@
+//===- LibraryResolver.cpp - Library Resolution of Unresolved Symbols ---===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Library resolution impl for unresolved symbols
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h"
+
+#include "llvm/ADT/StringSet.h"
+
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+
+#include <mutex>
+#include <thread>
+
+#define DEBUG_TYPE "orc-resolver"
+
+namespace llvm::orc {
+
+LibraryResolver::LibraryResolver(const LibraryResolver::Setup &S)
+ : LibPathCache(S.Cache ? S.Cache : std::make_shared<LibraryPathCache>()),
+ LibPathResolver(S.PResolver
+ ? S.PResolver
+ : std::make_shared<PathResolver>(LibPathCache)),
+ ScanHelper(S.BasePaths, LibPathCache, LibPathResolver),
+ FB(S.FilterBuilder), LibMgr(),
+ ShouldScanCall(S.ShouldScanCall ? S.ShouldScanCall
+ : [](StringRef) -> bool { return true; }),
+ scanBatchSize(S.ScanBatchSize) {
+
+ if (ScanHelper.getAllUnits().empty()) {
+ LLVM_DEBUG(dbgs() << "Warning: No base paths provided for scanning.\n");
+ }
+}
+
+std::unique_ptr<LibraryResolutionDriver>
+LibraryResolutionDriver::create(const LibraryResolver::Setup &S) {
+ auto LR = std::make_unique<LibraryResolver>(S);
+ return std::unique_ptr<LibraryResolutionDriver>(
+ new LibraryResolutionDriver(std::move(LR)));
+}
+
+void LibraryResolutionDriver::addScanPath(const std::string &Path, PathType K) {
+ LR->ScanHelper.addBasePath(Path, K);
+}
+
+bool LibraryResolutionDriver::markLibraryLoaded(StringRef Path) {
+ auto Lib = LR->LibMgr.getLibrary(Path);
+ if (!Lib)
+ return false;
+
+ Lib->setState(LibraryManager::LibState::Loaded);
+
+ return true;
+}
+
+bool LibraryResolutionDriver::markLibraryUnLoaded(StringRef Path) {
+ auto Lib = LR->LibMgr.getLibrary(Path);
+ if (!Lib)
+ return false;
+
+ Lib->setState(LibraryManager::LibState::Unloaded);
+
+ return true;
+}
+
+void LibraryResolutionDriver::resolveSymbols(
+ std::vector<std::string> Syms,
+ LibraryResolver::OnSearchComplete OnCompletion,
+ const SearchConfig &Config) {
+ LR->searchSymbolsInLibraries(Syms, std::move(OnCompletion), Config);
+}
+
+static bool shouldIgnoreSymbol(const object::SymbolRef &Sym,
+ uint32_t IgnoreFlags) {
+ Expected<uint32_t> FlagsOrErr = Sym.getFlags();
+ if (!FlagsOrErr) {
+ consumeError(FlagsOrErr.takeError());
+ return true;
+ }
+
+ uint32_t Flags = *FlagsOrErr;
+
+ using Filter = SymbolEnumeratorOptions;
+ if ((IgnoreFlags & Filter::IgnoreUndefined) &&
+ (Flags & object::SymbolRef::SF_Undefined))
+ return true;
+ if ((IgnoreFlags & Filter::IgnoreIndirect) &&
+ (Flags & object::SymbolRef::SF_Indirect))
+ return true;
+ if ((IgnoreFlags & Filter::IgnoreWeak) &&
+ (Flags & object::SymbolRef::SF_Weak))
+ return true;
+
+ return false;
+}
+
+bool SymbolEnumerator::enumerateSymbols(StringRef Path, OnEachSymbolFn OnEach,
+ const SymbolEnumeratorOptions &Opts) {
+ if (Path.empty())
+ return false;
+
+ ObjectFileLoader ObjLoader(Path);
+
+ auto ObjOrErr = ObjLoader.getObjectFile();
+ if (!ObjOrErr) {
+ std::string ErrMsg;
+ handleAllErrors(ObjOrErr.takeError(),
+ [&](const ErrorInfoBase &EIB) { ErrMsg = EIB.message(); });
+ LLVM_DEBUG(dbgs() << "Failed loading object file: " << Path
+ << "\nError: " << ErrMsg << "\n");
+ return false;
+ }
+
+ object::ObjectFile *Obj = &ObjOrErr.get();
+
+ auto processSymbolRange =
+ [&](object::ObjectFile::symbol_iterator_range Range) -> EnumerateResult {
+ for (const auto &Sym : Range) {
+ if (shouldIgnoreSymbol(Sym, Opts.FilterFlags))
+ continue;
+
+ auto NameOrErr = Sym.getName();
+ if (!NameOrErr) {
+ consumeError(NameOrErr.takeError());
+ continue;
+ }
+
+ StringRef Name = *NameOrErr;
+ if (Name.empty())
+ continue;
+
+ EnumerateResult Res = OnEach(Name);
+ if (Res != EnumerateResult::Continue)
+ return Res;
+ }
+ return EnumerateResult::Continue;
+ };
+
+ EnumerateResult Res = processSymbolRange(Obj->symbols());
+ if (Res != EnumerateResult::Continue)
+ return Res == EnumerateResult::Stop;
+
+ if (Obj->isELF()) {
+ const auto *ElfObj = cast<object::ELFObjectFileBase>(Obj);
+ Res = processSymbolRange(ElfObj->getDynamicSymbolIterators());
+ if (Res != EnumerateResult::Continue)
+ return Res == EnumerateResult::Stop;
+ } else if (Obj->isCOFF()) {
+ const auto *CoffObj = cast<object::COFFObjectFile>(Obj);
+ for (auto I = CoffObj->export_directory_begin(),
+ E = CoffObj->export_directory_end();
+ I != E; ++I) {
+ StringRef Name;
+ if (I->getSymbolName(Name))
+ continue;
+ if (Name.empty())
+ continue;
+
+ if (OnEach(Name) != EnumerateResult::Continue)
+ return false;
+ }
+ } else if (Obj->isMachO()) {
+ }
+
+ return true;
+}
+
+class SymbolSearchContext {
+public:
+ SymbolSearchContext(SymbolQuery &Q) : Q(Q) {}
+
+ bool hasSearched(LibraryInfo *Lib) const { return Searched.count(Lib); }
+
+ void markSearched(LibraryInfo *Lib) { Searched.insert(Lib); }
+
+ inline bool allResolved() const { return Q.allResolved(); }
+
+ SymbolQuery &query() { return Q; }
+
+private:
+ SymbolQuery &Q;
+ DenseSet<LibraryInfo *> Searched;
+};
+
+void LibraryResolver::resolveSymbolsInLibrary(
+ LibraryInfo &Lib, SymbolQuery &UnresolvedSymbols,
+ const SymbolEnumeratorOptions &Opts) {
+ LLVM_DEBUG(dbgs() << "Checking unresolved symbols "
+ << " in library : " << Lib.getFileName() << "\n";);
+ StringSet<> DiscoveredSymbols;
+
+ if (!UnresolvedSymbols.hasUnresolved()) {
+ LLVM_DEBUG(dbgs() << "Skipping library: " << Lib.getFullPath()
+ << " — unresolved symbols exist.\n";);
+ return;
+ }
+
+ bool HasEnumerated = false;
+ auto enumerateSymbolsIfNeeded = [&]() {
+ if (HasEnumerated)
+ return;
+
+ HasEnumerated = true;
+
+ LLVM_DEBUG(dbgs() << "Enumerating symbols in library: " << Lib.getFullPath()
+ << "\n";);
+ SymbolEnumerator::enumerateSymbols(
+ Lib.getFullPath(),
+ [&](StringRef sym) {
+ DiscoveredSymbols.insert(sym);
+ return EnumerateResult::Continue;
+ },
+ Opts);
+
+ if (DiscoveredSymbols.empty()) {
+ LLVM_DEBUG(dbgs() << " No symbols and remove library : "
+ << Lib.getFullPath() << "\n";);
+ LibMgr.removeLibrary(Lib.getFullPath());
+ return;
+ }
+ };
+
+ if (!Lib.hasFilter()) {
+ LLVM_DEBUG(dbgs() << "Building filter for library: " << Lib.getFullPath()
+ << "\n";);
+ enumerateSymbolsIfNeeded();
+ SmallVector<StringRef> SymbolVec;
+ SymbolVec.reserve(DiscoveredSymbols.size());
+ for (const auto &KV : DiscoveredSymbols)
+ SymbolVec.push_back(KV.first());
+
+ Lib.ensureFilterBuilt(FB, SymbolVec);
+ LLVM_DEBUG({
+ dbgs() << "DiscoveredSymbols : " << DiscoveredSymbols.size() << "\n";
+ for (const auto &KV : DiscoveredSymbols)
+ dbgs() << "DiscoveredSymbols : " << KV.first() << "\n";
+ });
+ }
+
+ const auto &Unresolved = UnresolvedSymbols.getUnresolvedSymbols();
+ bool HadAnySym = false;
+ LLVM_DEBUG(dbgs() << "Total unresolved symbols : " << Unresolved.size()
+ << "\n";);
+ for (const auto &Sym : Unresolved) {
+ if (Lib.mayContain(Sym)) {
+ LLVM_DEBUG(dbgs() << "Checking symbol '" << Sym
+ << "' in library: " << Lib.getFullPath() << "\n";);
+ enumerateSymbolsIfNeeded();
+ if (DiscoveredSymbols.count(Sym) > 0) {
+ LLVM_DEBUG(dbgs() << " Resolved symbol: " << Sym
+ << " in library: " << Lib.getFullPath() << "\n";);
+ UnresolvedSymbols.resolve(Sym, Lib.getFullPath());
+ HadAnySym = true;
+ }
+ }
+ }
+
+ using LibraryState = LibraryManager::LibState;
+ if (HadAnySym && Lib.getState() != LibraryState::Loaded)
+ Lib.setState(LibraryState::Queried);
+}
+
+void LibraryResolver::searchSymbolsInLibraries(
+ std::vector<std::string> &SymbolList, OnSearchComplete OnComplete,
+ const SearchConfig &Config) {
+ SymbolQuery Q(SymbolList);
+
+ using LibraryState = LibraryManager::LibState;
+ using LibraryType = PathType;
+ auto tryResolveFrom = [&](LibraryState S, LibraryType K) {
+ LLVM_DEBUG(dbgs() << "Trying resolve from state=" << static_cast<int>(S)
+ << " type=" << static_cast<int>(K) << "\n";);
+
+ SymbolSearchContext Ctx(Q);
+ while (!Ctx.allResolved()) {
+
+ for (auto &Lib : LibMgr.getView(S, K)) {
+ if (Ctx.hasSearched(Lib.get()))
+ continue;
+
+ // can use Async here?
+ resolveSymbolsInLibrary(*Lib, Ctx.query(), Config.Options);
+ Ctx.markSearched(Lib.get());
+
+ if (Ctx.allResolved())
+ return;
+ }
+
+ if (Ctx.allResolved())
+ return;
+
+ if (!scanLibrariesIfNeeded(K, scanBatchSize))
+ break; // no more new libs to scan
+ }
+ };
+
+ for (const auto &[St, Ty] : Config.Policy.Plan) {
+ tryResolveFrom(St, Ty);
+ if (Q.allResolved())
+ break;
+ }
+
+ // done:
+ LLVM_DEBUG({
+ dbgs() << "Search complete.\n";
+ for (const auto &r : Q.getAllResults())
+ dbgs() << "Resolved Symbol:" << r->Name << " -> " << r->ResolvedLibPath
+ << "\n";
+ });
+
+ OnComplete(Q);
+}
+
+bool LibraryResolver::scanLibrariesIfNeeded(PathType PK, size_t BatchSize) {
+ LLVM_DEBUG(dbgs() << "LibraryResolver::scanLibrariesIfNeeded: Scanning for "
+ << (PK == PathType::User ? "User" : "System")
+ << " libraries\n";);
+ if (!ScanHelper.leftToScan(PK))
+ return false;
+
+ LibraryScanner Scanner(ScanHelper, LibMgr, ShouldScanCall);
+ Scanner.scanNext(PK, BatchSize);
+ return true;
+}
+
+bool LibraryResolver::symbolExistsInLibrary(const LibraryInfo &Lib,
+ StringRef SymName,
+ std::vector<std::string> *AllSyms) {
+ SymbolEnumeratorOptions Opts;
+ return symbolExistsInLibrary(Lib, SymName, AllSyms, Opts);
+}
+
+bool LibraryResolver::symbolExistsInLibrary(
+ const LibraryInfo &Lib, StringRef SymName,
+ std::vector<std::string> *AllSyms, const SymbolEnumeratorOptions &Opts) {
+ bool Found = false;
+
+ SymbolEnumerator::enumerateSymbols(
+ Lib.getFullPath(),
+ [&](StringRef Sym) {
+ if (AllSyms)
+ AllSyms->emplace_back(Sym.str());
+
+ if (Sym == SymName) {
+ Found = true;
+ }
+
+ return EnumerateResult::Continue;
+ },
+ Opts);
+
+ return Found;
+}
+
+} // end namespace llvm::orc
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp
new file mode 100644
index 0000000000000..72c1968df55fc
--- /dev/null
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/LibraryScanner.cpp
@@ -0,0 +1,1159 @@
+//===- LibraryScanner.cpp - Provide Library Scanning Implementation ----===//
+//
+// 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/TargetProcess/LibraryScanner.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h"
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/TargetParser/Host.h"
+#include "llvm/TargetParser/Triple.h"
+
+#ifdef LLVM_ON_UNIX
+#include <sys/stat.h>
+#include <unistd.h>
+#endif // LLVM_ON_UNIX
+
+#ifdef __APPLE__
+#include <sys/stat.h>
+#undef LC_LOAD_DYLIB
+#undef LC_RPATH
+#endif // __APPLE__
+
+#define DEBUG_TYPE "orc-scanner"
+
+namespace llvm::orc {
+
+void handleError(Error Err, StringRef context = "") {
+ consumeError(handleErrors(std::move(Err), [&](const ErrorInfoBase &EIB) {
+ dbgs() << "LLVM Error";
+ if (!context.empty())
+ dbgs() << " [" << context << "]";
+ dbgs() << ": " << EIB.message() << "\n";
+ }));
+}
+
+bool ObjectFileLoader::isArchitectureCompatible(const object::ObjectFile &Obj) {
+ Triple HostTriple(sys::getDefaultTargetTriple());
+ Triple ObjTriple = Obj.makeTriple();
+
+ LLVM_DEBUG({
+ dbgs() << "Host triple: " << HostTriple.str()
+ << ", Object triple: " << ObjTriple.str() << "\n";
+ });
+
+ if (ObjTriple.getArch() != Triple::UnknownArch &&
+ HostTriple.getArch() != ObjTriple.getArch())
+ return false;
+
+ if (ObjTriple.getOS() != Triple::UnknownOS &&
+ HostTriple.getOS() != ObjTriple.getOS())
+ return false;
+
+ if (ObjTriple.getEnvironment() != Triple::UnknownEnvironment &&
+ HostTriple.getEnvironment() != Triple::UnknownEnvironment &&
+ HostTriple.getEnvironment() != ObjTriple.getEnvironment())
+ return false;
+
+ return true;
+}
+
+Expected<object::OwningBinary<object::ObjectFile>>
+ObjectFileLoader::loadObjectFileWithOwnership(StringRef FilePath) {
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Attempting to open file " << FilePath
+ << "\n";);
+ auto BinOrErr = object::createBinary(FilePath);
+ if (!BinOrErr) {
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Failed to open file " << FilePath
+ << "\n";);
+ return BinOrErr.takeError();
+ }
+
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Successfully opened file " << FilePath
+ << "\n";);
+
+ auto OwningBin = BinOrErr->takeBinary();
+ object::Binary *Bin = OwningBin.first.get();
+
+ if (Bin->isArchive()) {
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: File is an archive, not supported: "
+ << FilePath << "\n";);
+ return createStringError(std::errc::invalid_argument,
+ "Archive files are not supported: %s",
+ FilePath.str().c_str());
+ }
+
+#if defined(__APPLE__)
+ if (auto *UB = dyn_cast<object::MachOUniversalBinary>(Bin)) {
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Detected Mach-O universal binary: "
+ << FilePath << "\n";);
+ for (auto ObjForArch : UB->objects()) {
+ auto ObjOrErr = ObjForArch.getAsObjectFile();
+ if (!ObjOrErr) {
+ LLVM_DEBUG(
+ dbgs()
+ << "ObjectFileLoader: Skipping invalid architecture slice\n";);
+
+ consumeError(ObjOrErr.takeError());
+ continue;
+ }
+
+ std::unique_ptr<object::ObjectFile> Obj = std::move(ObjOrErr.get());
+ if (isArchitectureCompatible(*Obj)) {
+ LLVM_DEBUG(
+ dbgs() << "ObjectFileLoader: Found compatible object slice\n";);
+
+ return object::OwningBinary<object::ObjectFile>(
+ std::move(Obj), std::move(OwningBin.second));
+
+ } else {
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Incompatible architecture "
+ "slice skipped\n";);
+ }
+ }
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: No compatible slices found in "
+ "universal binary\n";);
+ return createStringError(inconvertibleErrorCode(),
+ "No compatible object found in fat binary: %s",
+ FilePath.str().c_str());
+ }
+#endif
+
+ auto ObjOrErr =
+ object::ObjectFile::createObjectFile(Bin->getMemoryBufferRef());
+ if (!ObjOrErr) {
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Failed to create object file\n";);
+ return ObjOrErr.takeError();
+ }
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Detected object file\n";);
+
+ std::unique_ptr<object::ObjectFile> Obj = std::move(*ObjOrErr);
+ if (!isArchitectureCompatible(*Obj)) {
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Incompatible architecture: "
+ << FilePath << "\n";);
+ return createStringError(inconvertibleErrorCode(),
+ "Incompatible object file: %s",
+ FilePath.str().c_str());
+ }
+
+ LLVM_DEBUG(dbgs() << "ObjectFileLoader: Object file is compatible\n";);
+
+ return object::OwningBinary<object::ObjectFile>(std::move(Obj),
+ std::move(OwningBin.second));
+}
+
+template <class ELFT>
+bool isELFSharedLibrary(const object::ELFFile<ELFT> &ELFObj) {
+ if (ELFObj.getHeader().e_type != ELF::ET_DYN)
+ return false;
+
+ auto PHOrErr = ELFObj.program_headers();
+ if (!PHOrErr) {
+ consumeError(PHOrErr.takeError());
+ return true;
+ }
+
+ for (auto Phdr : *PHOrErr) {
+ if (Phdr.p_type == ELF::PT_INTERP)
+ return false;
+ }
+
+ return true;
+}
+
+bool isSharedLibraryObject(object::ObjectFile &Obj) {
+ if (Obj.isELF()) {
+ if (auto *ELF32LE = dyn_cast<object::ELF32LEObjectFile>(&Obj))
+ return isELFSharedLibrary(ELF32LE->getELFFile());
+ if (auto *ELF64LE = dyn_cast<object::ELF64LEObjectFile>(&Obj))
+ return isELFSharedLibrary(ELF64LE->getELFFile());
+ if (auto *ELF32BE = dyn_cast<object::ELF32BEObjectFile>(&Obj))
+ return isELFSharedLibrary(ELF32BE->getELFFile());
+ if (auto *ELF64BE = dyn_cast<object::ELF64BEObjectFile>(&Obj))
+ return isELFSharedLibrary(ELF64BE->getELFFile());
+ } else if (Obj.isMachO()) {
+ const object::MachOObjectFile *MachO =
+ dyn_cast<object::MachOObjectFile>(&Obj);
+ if (!MachO) {
+ LLVM_DEBUG(dbgs() << "Failed to cast to MachOObjectFile.\n";);
+ return false;
+ }
+ LLVM_DEBUG({
+ bool Result =
+ MachO->getHeader().filetype == MachO::HeaderFileType::MH_DYLIB;
+ dbgs() << "Mach-O filetype: " << MachO->getHeader().filetype
+ << " (MH_DYLIB == " << MachO::HeaderFileType::MH_DYLIB
+ << "), shared: " << Result << "\n";
+ });
+
+ return MachO->getHeader().filetype == MachO::HeaderFileType::MH_DYLIB;
+ } else if (Obj.isCOFF()) {
+ const object::COFFObjectFile *coff = dyn_cast<object::COFFObjectFile>(&Obj);
+ if (!coff)
+ return false;
+ return coff->getCharacteristics() & COFF::IMAGE_FILE_DLL;
+ } else {
+ LLVM_DEBUG(dbgs() << "Binary is not an ObjectFile.\n";);
+ }
+
+ return false;
+}
+
+bool DylibPathValidator::isSharedLibrary(StringRef Path) {
+ LLVM_DEBUG(dbgs() << "Checking if path is a shared library: " << Path
+ << "\n";);
+
+ auto FileType = sys::fs::get_file_type(Path, /*Follow*/ true);
+ if (FileType != sys::fs::file_type::regular_file) {
+ LLVM_DEBUG(dbgs() << "File type is not a regular file for path: " << Path
+ << "\n";);
+ return false;
+ }
+
+ file_magic MagicCode;
+ identify_magic(Path, MagicCode);
+
+ // Skip archives.
+ if (MagicCode == file_magic::archive)
+ return false;
+
+ // Universal binary handling.
+#if defined(__APPLE__)
+ if (MagicCode == file_magic::macho_universal_binary) {
+ ObjectFileLoader ObjLoader(Path);
+ auto ObjOrErr = ObjLoader.getObjectFile();
+ if (!ObjOrErr) {
+ consumeError(ObjOrErr.takeError());
+ return false;
+ }
+ return isSharedLibraryObject(ObjOrErr.get());
+ }
+#endif
+
+ // Object file inspection for PE/COFF, ELF, and Mach-O
+ bool NeedsObjectInspection =
+#if defined(_WIN32)
+ (MagicCode == file_magic::pecoff_executable);
+#elif defined(__APPLE__)
+ (MagicCode == file_magic::macho_fixed_virtual_memory_shared_lib ||
+ MagicCode == file_magic::macho_dynamically_linked_shared_lib ||
+ MagicCode == file_magic::macho_dynamically_linked_shared_lib_stub);
+#elif defined(LLVM_ON_UNIX)
+#ifdef __CYGWIN__
+ (MagicCode == file_magic::pecoff_executable);
+#else
+ (MagicCode == file_magic::elf_shared_object);
+#endif
+#else
+#error "Unsupported platform."
+#endif
+
+ if (NeedsObjectInspection) {
+ ObjectFileLoader ObjLoader(Path);
+ auto ObjOrErr = ObjLoader.getObjectFile();
+ if (!ObjOrErr) {
+ consumeError(ObjOrErr.takeError());
+ return false;
+ }
+ return isSharedLibraryObject(ObjOrErr.get());
+ }
+
+ LLVM_DEBUG(dbgs() << "Path is not identified as a shared library: " << Path
+ << "\n";);
+ return false;
+}
+
+void DylibSubstitutor::configure(StringRef LoaderPath) {
+ SmallString<512> ExecPath(sys::fs::getMainExecutable(nullptr, nullptr));
+ sys::path::remove_filename(ExecPath);
+
+ SmallString<512> LoaderDir;
+ if (LoaderPath.empty()) {
+ LoaderDir = ExecPath;
+ } else {
+ LoaderDir = LoaderPath.str();
+ if (!sys::fs::is_directory(LoaderPath))
+ sys::path::remove_filename(LoaderDir);
+ }
+
+#ifdef __APPLE__
+ Placeholders["@loader_path"] = std::string(LoaderDir);
+ Placeholders["@executable_path"] = std::string(ExecPath);
+#else
+ Placeholders["$origin"] = std::string(LoaderDir);
+#endif
+}
+
+std::optional<std::string>
+SearchPathResolver::resolve(StringRef Stem, const DylibSubstitutor &Subst,
+ DylibPathValidator &Validator) const {
+ for (const auto &SP : Paths) {
+ std::string Base = Subst.substitute(SP);
+
+ SmallString<512> FullPath(Base);
+ if (!PlaceholderPrefix.empty() &&
+ Stem.starts_with_insensitive(PlaceholderPrefix))
+ FullPath.append(Stem.drop_front(PlaceholderPrefix.size()));
+ else
+ sys::path::append(FullPath, Stem);
+
+ LLVM_DEBUG(dbgs() << "SearchPathResolver::resolve FullPath = " << FullPath
+ << "\n";);
+
+ if (auto Valid = Validator.validate(FullPath.str()))
+ return Valid;
+ }
+
+ return std::nullopt;
+}
+
+std::optional<std::string>
+DylibResolverImpl::tryWithExtensions(StringRef LibStem) const {
+ LLVM_DEBUG(dbgs() << "tryWithExtensions: baseName = " << LibStem << "\n";);
+ SmallVector<SmallString<256>, 8> Candidates;
+
+ // Add extensions by platform
+#if defined(__APPLE__)
+ Candidates.emplace_back(LibStem);
+ Candidates.back() += ".dylib";
+#elif defined(_WIN32)
+ Candidates.emplace_back(LibStem);
+ Candidates.back() += ".dll";
+#else
+ Candidates.emplace_back(LibStem);
+ Candidates.back() += ".so";
+#endif
+
+ // Optionally try "lib" prefix if not already there
+ StringRef FileName = sys::path::filename(LibStem);
+ StringRef Base = sys::path::parent_path(LibStem);
+ if (!FileName.starts_with("lib")) {
+ SmallString<256> WithPrefix(Base);
+ if (!WithPrefix.empty())
+ sys::path::append(WithPrefix, ""); // ensure separator if needed
+ WithPrefix += "lib";
+ WithPrefix += FileName;
+
+#if defined(__APPLE__)
+ WithPrefix += ".dylib";
+#elif defined(_WIN32)
+ WithPrefix += ".dll";
+#else
+ WithPrefix += ".so";
+#endif
+
+ Candidates.push_back(std::move(WithPrefix));
+ }
+
+ LLVM_DEBUG({
+ dbgs() << " Candidates to try:\n";
+ for (const auto &C : Candidates)
+ dbgs() << " " << C << "\n";
+ });
+
+ // Try all variants using tryAllPaths
+ for (const auto &Name : Candidates) {
+
+ LLVM_DEBUG(dbgs() << " Trying candidate: " << Name << "\n";);
+
+ for (const auto &R : Resolvers) {
+ if (auto Res = R.resolve(Name, Substitutor, Validator))
+ return Res;
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << " -> No candidate Resolved.\n";);
+
+ return std::nullopt;
+}
+
+std::optional<std::string>
+DylibResolverImpl::resolve(StringRef LibStem, bool VariateLibStem) const {
+ LLVM_DEBUG(dbgs() << "Resolving library stem: " << LibStem << "\n";);
+
+ // If it is an absolute path, don't try iterate over the paths.
+ if (sys::path::is_absolute(LibStem)) {
+ LLVM_DEBUG(dbgs() << " -> Absolute path detected.\n";);
+ return Validator.validate(LibStem);
+ }
+
+ if (!LibStem.starts_with_insensitive("@rpath")) {
+ if (auto norm = Validator.validate(Substitutor.substitute(LibStem))) {
+ LLVM_DEBUG(dbgs() << " -> Resolved after substitution: " << *norm
+ << "\n";);
+
+ return norm;
+ }
+ }
+
+ for (const auto &R : Resolvers) {
+ LLVM_DEBUG(dbgs() << " -> Resolving via search path ... \n";);
+ if (auto Result = R.resolve(LibStem, Substitutor, Validator)) {
+ LLVM_DEBUG(dbgs() << " -> Resolved via search path: " << *Result
+ << "\n";);
+
+ return Result;
+ }
+ }
+
+ // Expand libStem with paths, extensions, etc.
+ // std::string foundName;
+ if (VariateLibStem) {
+ LLVM_DEBUG(dbgs() << " -> Trying with extensions...\n";);
+
+ if (auto Norm = tryWithExtensions(LibStem)) {
+ LLVM_DEBUG(dbgs() << " -> Resolved via tryWithExtensions: " << *Norm
+ << "\n";);
+
+ return Norm;
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << " -> Could not resolve: " << LibStem << "\n";);
+
+ return std::nullopt;
+}
+
+#ifndef _WIN32
+mode_t PathResolver::lstatCached(StringRef Path) {
+ // If already cached - retun cached result
+ if (auto Cache = LibPathCache->read_lstat(Path))
+ return *Cache;
+
+ // Not cached: perform lstat and store
+ struct stat buf{};
+ mode_t st_mode = (lstat(Path.str().c_str(), &buf) == -1) ? 0 : buf.st_mode;
+
+ LibPathCache->insert_lstat(Path, st_mode);
+
+ return st_mode;
+}
+
+std::optional<std::string> PathResolver::readlinkCached(StringRef Path) {
+ // If already cached - retun cached result
+ if (auto Cache = LibPathCache->read_link(Path))
+ return Cache;
+
+ // If result not in cache - call system function and cache result
+ char buf[PATH_MAX];
+ ssize_t len;
+ if ((len = readlink(Path.str().c_str(), buf, sizeof(buf))) != -1) {
+ buf[len] = '\0';
+ std::string s(buf);
+ LibPathCache->insert_link(Path, s);
+ return s;
+ }
+ return std::nullopt;
+}
+
+void createComponent(StringRef Path, StringRef BasePath, bool BaseIsResolved,
+ SmallVector<StringRef, 16> &Component) {
+ StringRef Separator = sys::path::get_separator();
+ if (!BaseIsResolved) {
+ if (Path[0] == '~' &&
+ (Path.size() == 1 || sys::path::is_separator(Path[1]))) {
+ static SmallString<128> HomeP;
+ if (HomeP.str().empty())
+ sys::path::home_directory(HomeP);
+ StringRef(HomeP).split(Component, Separator, /*MaxSplit*/ -1,
+ /*KeepEmpty*/ false);
+ } else if (BasePath.empty()) {
+ static SmallString<256> CurrentPath;
+ if (CurrentPath.str().empty())
+ sys::fs::current_path(CurrentPath);
+ StringRef(CurrentPath)
+ .split(Component, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false);
+ } else {
+ BasePath.split(Component, Separator, /*MaxSplit*/ -1,
+ /*KeepEmpty*/ false);
+ }
+ }
+
+ Path.split(Component, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false);
+}
+
+void normalizePathSegments(SmallVector<StringRef, 16> &PathParts) {
+ SmallVector<StringRef, 16> NormalizedPath;
+ for (auto &Part : PathParts) {
+ if (Part == ".") {
+ continue;
+ } else if (Part == "..") {
+ if (!NormalizedPath.empty() && NormalizedPath.back() != "..") {
+ NormalizedPath.pop_back();
+ } else {
+ NormalizedPath.push_back("..");
+ }
+ } else {
+ NormalizedPath.push_back(Part);
+ }
+ }
+ PathParts.swap(NormalizedPath);
+}
+#endif
+
+std::optional<std::string> PathResolver::realpathCached(StringRef Path,
+ std::error_code &EC,
+ StringRef Base,
+ bool BaseIsResolved,
+ long SymLoopLevel) {
+ EC.clear();
+
+ if (Path.empty()) {
+ EC = std::make_error_code(std::errc::no_such_file_or_directory);
+ LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Empty path\n";);
+
+ return std::nullopt;
+ }
+
+ if (SymLoopLevel <= 0) {
+ EC = std::make_error_code(std::errc::too_many_symbolic_link_levels);
+ LLVM_DEBUG(
+ dbgs() << "PathResolver::realpathCached: Too many Symlink levels: "
+ << Path << "\n";);
+
+ return std::nullopt;
+ }
+
+ // If already cached - retun cached result
+ bool isRelative = sys::path::is_relative(Path);
+ if (!isRelative) {
+ if (auto Cached = LibPathCache->read_realpath(Path)) {
+ EC = Cached->ErrnoCode;
+ if (EC) {
+ LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Cached (error) for "
+ << Path << "\n";);
+ } else {
+ LLVM_DEBUG(
+ dbgs() << "PathResolver::realpathCached: Cached (success) for "
+ << Path << " => " << Cached->canonicalPath << "\n";);
+ }
+ return Cached->canonicalPath.empty()
+ ? std::nullopt
+ : std::make_optional(Cached->canonicalPath);
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Resolving path: " << Path
+ << "\n";);
+
+ // If result not in cache - call system function and cache result
+
+ StringRef Separator(sys::path::get_separator());
+ SmallString<256> Resolved(Separator);
+#ifndef _WIN32
+ SmallVector<StringRef, 16> Components;
+
+ if (isRelative) {
+ if (BaseIsResolved) {
+ Resolved.assign(Base);
+ LLVM_DEBUG(dbgs() << " Using Resolved base: " << Base << "\n";);
+ }
+ createComponent(Path, Base, BaseIsResolved, Components);
+ } else {
+ Path.split(Components, Separator, /*MaxSplit*/ -1, /*KeepEmpty*/ false);
+ }
+
+ normalizePathSegments(Components);
+ LLVM_DEBUG({
+ for (auto &C : Components)
+ dbgs() << " " << C << " ";
+
+ dbgs() << "\n";
+ });
+
+ // Handle path list items
+ for (const auto &Component : Components) {
+ if (Component == ".")
+ continue;
+ if (Component == "..") {
+ // collapse "a/b/../c" to "a/c"
+ size_t S = Resolved.rfind(Separator);
+ if (S != llvm::StringRef::npos)
+ Resolved.resize(S);
+ if (Resolved.empty())
+ Resolved = Separator;
+ continue;
+ }
+
+ size_t oldSize = Resolved.size();
+ sys::path::append(Resolved, Component);
+ const char *ResolvedPath = Resolved.c_str();
+ LLVM_DEBUG(dbgs() << " Processing Component: " << Component << " => "
+ << ResolvedPath << "\n";);
+ mode_t st_mode = lstatCached(ResolvedPath);
+
+ if (S_ISLNK(st_mode)) {
+ LLVM_DEBUG(dbgs() << " Found symlink: " << ResolvedPath << "\n";);
+
+ auto SymlinkOpt = readlinkCached(ResolvedPath);
+ if (!SymlinkOpt) {
+ EC = std::make_error_code(std::errc::no_such_file_or_directory);
+ LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC});
+ LLVM_DEBUG(dbgs() << " Failed to read symlink: " << ResolvedPath
+ << "\n";);
+
+ return std::nullopt;
+ }
+
+ StringRef Symlink = *SymlinkOpt;
+ LLVM_DEBUG(dbgs() << " Symlink points to: " << Symlink << "\n";);
+
+ std::string resolvedBase = "";
+ if (sys::path::is_relative(Symlink)) {
+ Resolved.resize(oldSize);
+ resolvedBase = Resolved.str().str();
+ }
+
+ auto RealSymlink =
+ realpathCached(Symlink, EC, resolvedBase,
+ /*BaseIsResolved=*/true, SymLoopLevel - 1);
+ if (!RealSymlink) {
+ LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC});
+ LLVM_DEBUG(dbgs() << " Failed to resolve symlink target: " << Symlink
+ << "\n";);
+
+ return std::nullopt;
+ }
+
+ Resolved.assign(*RealSymlink);
+ LLVM_DEBUG(dbgs() << " Symlink Resolved to: " << Resolved << "\n";);
+
+ } else if (st_mode == 0) {
+ EC = std::make_error_code(std::errc::no_such_file_or_directory);
+ LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{"", EC});
+ LLVM_DEBUG(dbgs() << " Component does not exist: " << ResolvedPath
+ << "\n";);
+
+ return std::nullopt;
+ }
+ }
+#else
+ sys::fs::real_path(Path, Resolved); // Windows fallback
+#endif
+
+ std::string Canonical = Resolved.str().str();
+ {
+ LibPathCache->insert_realpath(Path, LibraryPathCache::PathInfo{
+ Canonical,
+ std::error_code() // success
+ });
+ }
+ LLVM_DEBUG(dbgs() << "PathResolver::realpathCached: Final Resolved: " << Path
+ << " => " << Canonical << "\n";);
+ return Canonical;
+}
+
+void LibraryScanHelper::addBasePath(const std::string &Path, PathType K) {
+ std::error_code EC;
+ std::string Canon = resolveCanonical(Path, EC);
+ if (EC) {
+ LLVM_DEBUG(
+ dbgs()
+ << "LibraryScanHelper::addBasePath: Failed to canonicalize path: "
+ << Path << "\n";);
+ return;
+ }
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+ if (LibSearchPaths.count(Canon)) {
+ LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Already added: "
+ << Canon << "\n";);
+ return;
+ }
+ K = K == PathType::Unknown ? classifyKind(Canon) : K;
+ auto SP = std::make_shared<LibrarySearchPath>(Canon, K);
+ LibSearchPaths[Canon] = SP;
+
+ if (K == PathType::User) {
+ LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Added User path: "
+ << Canon << "\n";);
+ UnscannedUsr.push_back(StringRef(SP->BasePath));
+ } else {
+ LLVM_DEBUG(dbgs() << "LibraryScanHelper::addBasePath: Added System path: "
+ << Canon << "\n";);
+ UnscannedSys.push_back(StringRef(SP->BasePath));
+ }
+}
+
+std::vector<std::shared_ptr<LibrarySearchPath>>
+LibraryScanHelper::getNextBatch(PathType K, size_t BatchSize) {
+ std::vector<std::shared_ptr<LibrarySearchPath>> Result;
+ auto &Queue = (K == PathType::User) ? UnscannedUsr : UnscannedSys;
+
+ std::unique_lock<std::shared_mutex> Lock(Mtx);
+
+ while (!Queue.empty() && (BatchSize == 0 || Result.size() < BatchSize)) {
+ StringRef Base = Queue.front();
+ auto It = LibSearchPaths.find(Base);
+ if (It != LibSearchPaths.end()) {
+ auto &SP = It->second;
+ ScanState Expected = ScanState::NotScanned;
+ if (SP->State.compare_exchange_strong(Expected, ScanState::Scanning)) {
+ Result.push_back(SP);
+ }
+ }
+ Queue.pop_front();
+ }
+
+ return Result;
+}
+
+bool LibraryScanHelper::isTrackedBasePath(StringRef Path) const {
+ std::error_code EC;
+ std::string Canon = resolveCanonical(Path, EC);
+ if (EC)
+ return false;
+
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ return LibSearchPaths.count(Canon) > 0;
+}
+
+bool LibraryScanHelper::leftToScan(PathType K) const {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ for (const auto &KV : LibSearchPaths) {
+ const auto &SP = KV.second;
+ if (SP->Kind == K && SP->State == ScanState::NotScanned)
+ return true;
+ }
+ return false;
+}
+
+void LibraryScanHelper::resetToScan() {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+
+ for (auto &[_, SP] : LibSearchPaths) {
+ ScanState Expected = ScanState::Scanned;
+
+ if (!SP->State.compare_exchange_strong(Expected, ScanState::NotScanned))
+ continue;
+
+ auto &TargetList =
+ (SP->Kind == PathType::User) ? UnscannedUsr : UnscannedSys;
+ TargetList.emplace_back(SP->BasePath);
+ }
+}
+
+std::vector<std::shared_ptr<LibrarySearchPath>>
+LibraryScanHelper::getAllUnits() const {
+ std::shared_lock<std::shared_mutex> Lock(Mtx);
+ std::vector<std::shared_ptr<LibrarySearchPath>> Result;
+ Result.reserve(LibSearchPaths.size());
+ for (const auto &[_, SP] : LibSearchPaths) {
+ Result.push_back(SP);
+ }
+ return Result;
+}
+
+std::string LibraryScanHelper::resolveCanonical(StringRef Path,
+ std::error_code &EC) const {
+ auto Canon = LibPathResolver->resolve(Path, EC);
+ return EC ? Path.str() : *Canon;
+}
+
+PathType LibraryScanHelper::classifyKind(StringRef Path) const {
+ // Detect home directory
+ const char *Home = getenv("HOME");
+ if (Home && Path.find(Home) == 0)
+ return PathType::User;
+
+ static const std::array<std::string, 5> UserPrefixes = {
+ "/usr/local", // often used by users for manual installs
+ "/opt/homebrew", // common on macOS
+ "/opt/local", // MacPorts
+ "/home", // Linux home dirs
+ "/Users", // macOS user dirs
+ };
+
+ for (const auto &Prefix : UserPrefixes) {
+ if (Path.find(Prefix) == 0)
+ return PathType::User;
+ }
+
+ return PathType::System;
+}
+
+Expected<LibraryDepsInfo> parseMachODeps(const object::MachOObjectFile &Obj) {
+ LibraryDepsInfo Libdeps;
+ LLVM_DEBUG(dbgs() << "Parsing Mach-O dependencies...\n";);
+ for (const auto &Command : Obj.load_commands()) {
+ switch (Command.C.cmd) {
+ case MachO::LC_LOAD_DYLIB: {
+ MachO::dylib_command dylibCmd = Obj.getDylibIDLoadCommand(Command);
+ const char *name = Command.Ptr + dylibCmd.dylib.name;
+ Libdeps.addDep(name);
+ LLVM_DEBUG(dbgs() << " Found LC_LOAD_DYLIB: " << name << "\n";);
+ } break;
+ case MachO::LC_LOAD_WEAK_DYLIB:
+ case MachO::LC_REEXPORT_DYLIB:
+ case MachO::LC_LOAD_UPWARD_DYLIB:
+ case MachO::LC_LAZY_LOAD_DYLIB:
+ break;
+ case MachO::LC_RPATH: {
+ // Extract RPATH
+ MachO::rpath_command rpathCmd = Obj.getRpathCommand(Command);
+ const char *rpath = Command.Ptr + rpathCmd.path;
+ LLVM_DEBUG(dbgs() << " Found LC_RPATH: " << rpath << "\n";);
+
+ SmallVector<StringRef, 4> RawPaths;
+ SplitString(StringRef(rpath), RawPaths,
+ sys::EnvPathSeparator == ':' ? ":" : ";");
+
+ for (const auto &raw : RawPaths) {
+ Libdeps.addRPath(raw.str()); // Convert to std::string
+ LLVM_DEBUG(dbgs() << " Parsed RPATH entry: " << raw << "\n";);
+ }
+ break;
+ }
+ }
+ }
+ return Libdeps;
+}
+
+template <class ELFT>
+static Expected<StringRef> getDynamicStrTab(const object::ELFFile<ELFT> &Elf) {
+ auto DynamicEntriesOrError = Elf.dynamicEntries();
+ if (!DynamicEntriesOrError)
+ return DynamicEntriesOrError.takeError();
+
+ for (const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
+ if (Dyn.d_tag == ELF::DT_STRTAB) {
+ auto MappedAddrOrError = Elf.toMappedAddr(Dyn.getPtr());
+ if (!MappedAddrOrError)
+ return MappedAddrOrError.takeError();
+ return StringRef(reinterpret_cast<const char *>(*MappedAddrOrError));
+ }
+ }
+
+ // If the dynamic segment is not present, we fall back on the sections.
+ auto SectionsOrError = Elf.sections();
+ if (!SectionsOrError)
+ return SectionsOrError.takeError();
+
+ for (const typename ELFT::Shdr &Sec : *SectionsOrError) {
+ if (Sec.sh_type == ELF::SHT_DYNSYM)
+ return Elf.getStringTableForSymtab(Sec);
+ }
+
+ return make_error<StringError>("dynamic string table not found",
+ inconvertibleErrorCode());
+}
+
+template <typename ELFT>
+Expected<LibraryDepsInfo> parseELF(const object::ELFFile<ELFT> &Elf) {
+ LibraryDepsInfo Deps;
+ Expected<StringRef> StrTabOrErr = getDynamicStrTab(Elf);
+ if (!StrTabOrErr)
+ return StrTabOrErr.takeError();
+
+ const char *Data = StrTabOrErr->data();
+
+ auto DynamicEntriesOrError = Elf.dynamicEntries();
+ if (!DynamicEntriesOrError) {
+ return DynamicEntriesOrError.takeError();
+ }
+
+ for (const typename ELFT::Dyn &Dyn : *DynamicEntriesOrError) {
+ switch (Dyn.d_tag) {
+ case ELF::DT_NEEDED:
+ Deps.addDep(Data + Dyn.d_un.d_val);
+ break;
+ case ELF::DT_RPATH: {
+ SmallVector<StringRef, 4> RawPaths;
+ SplitString(Data + Dyn.d_un.d_val, RawPaths,
+ sys::EnvPathSeparator == ':' ? ":" : ";");
+ for (const auto &raw : RawPaths)
+ Deps.addRPath(raw.str());
+ break;
+ }
+ case ELF::DT_RUNPATH: {
+ SmallVector<StringRef, 4> RawPaths;
+ SplitString(Data + Dyn.d_un.d_val, RawPaths,
+ sys::EnvPathSeparator == ':' ? ":" : ";");
+ for (const auto &raw : RawPaths)
+ Deps.addRunPath(raw.str());
+ break;
+ }
+ case ELF::DT_FLAGS_1:
+ // Check if this is not a pie executable.
+ if (Dyn.d_un.d_val & ELF::DF_1_PIE)
+ Deps.isPIE = true;
+ break;
+ // (Dyn.d_tag == ELF::DT_NULL) continue;
+ // (Dyn.d_tag == ELF::DT_AUXILIARY || Dyn.d_tag == ELF::DT_FILTER)
+ default:
+ break;
+ }
+ }
+ return Deps;
+}
+
+Expected<LibraryDepsInfo> parseELFDeps(const object::ELFObjectFileBase &Obj) {
+ using namespace object;
+ LLVM_DEBUG(dbgs() << "parseELFDeps: Detected ELF object\n";);
+ if (const auto *ELF = dyn_cast<ELF32LEObjectFile>(&Obj))
+ return parseELF(ELF->getELFFile());
+ else if (const auto *ELF = dyn_cast<ELF32BEObjectFile>(&Obj))
+ return parseELF(ELF->getELFFile());
+ else if (const auto *ELF = dyn_cast<ELF64LEObjectFile>(&Obj))
+ return parseELF(ELF->getELFFile());
+ else if (const auto *ELF = dyn_cast<ELF64BEObjectFile>(&Obj))
+ return parseELF(ELF->getELFFile());
+
+ LLVM_DEBUG(dbgs() << "parseELFDeps: Unknown ELF format\n";);
+ return createStringError(std::errc::not_supported, "Unknown ELF format");
+}
+
+Expected<LibraryDepsInfo> LibraryScanner::extractDeps(StringRef FilePath) {
+ LLVM_DEBUG(dbgs() << "extractDeps: Attempting to open file " << FilePath
+ << "\n";);
+
+ ObjectFileLoader ObjLoader(FilePath);
+ auto ObjOrErr = ObjLoader.getObjectFile();
+ if (!ObjOrErr) {
+ LLVM_DEBUG(dbgs() << "extractDeps: Failed to open " << FilePath << "\n";);
+ return ObjOrErr.takeError();
+ }
+
+ object::ObjectFile *Obj = &ObjOrErr.get();
+
+ if (auto *elfObj = dyn_cast<object::ELFObjectFileBase>(Obj)) {
+ LLVM_DEBUG(dbgs() << "extractDeps: File " << FilePath
+ << " is an ELF object\n";);
+
+ return parseELFDeps(*elfObj);
+ }
+
+ if (auto *macho = dyn_cast<object::MachOObjectFile>(Obj)) {
+ LLVM_DEBUG(dbgs() << "extractDeps: File " << FilePath
+ << " is a Mach-O object\n";);
+ return parseMachODeps(*macho);
+ }
+
+ if (Obj->isCOFF()) {
+ // TODO: COFF support
+ return LibraryDepsInfo();
+ }
+
+ LLVM_DEBUG(dbgs() << "extractDeps: Unsupported binary format for file "
+ << FilePath << "\n";);
+ return createStringError(inconvertibleErrorCode(),
+ "Unsupported binary format: %s",
+ FilePath.str().c_str());
+}
+
+std::optional<std::string> LibraryScanner::shouldScan(StringRef FilePath) {
+ std::error_code EC;
+
+ LLVM_DEBUG(dbgs() << "[shouldScan] Checking: " << FilePath << "\n";);
+
+ // [1] Check file existence early
+ if (!sys::fs::exists(FilePath)) {
+ LLVM_DEBUG(dbgs() << " -> Skipped: file does not exist.\n";);
+
+ return std::nullopt;
+ }
+
+ // [2] Resolve to canonical path
+ auto CanonicalPathOpt = ScanHelper.resolve(FilePath, EC);
+ if (EC || !CanonicalPathOpt) {
+ LLVM_DEBUG(dbgs() << " -> Skipped: failed to resolve path (EC="
+ << EC.message() << ").\n";);
+
+ return std::nullopt;
+ }
+
+ const std::string &CanonicalPath = *CanonicalPathOpt;
+ LLVM_DEBUG(dbgs() << " -> Canonical path: " << CanonicalPath << "\n");
+
+ // [3] Check if it's a directory — skip directories
+ if (sys::fs::is_directory(CanonicalPath)) {
+ LLVM_DEBUG(dbgs() << " -> Skipped: path is a directory.\n";);
+
+ return std::nullopt;
+ }
+
+ // [4] Skip if it's not a shared library.
+ if (!DylibPathValidator::isSharedLibrary(CanonicalPath)) {
+ LLVM_DEBUG(dbgs() << " -> Skipped: not a shared library.\n";);
+ return std::nullopt;
+ }
+
+ // [5] Skip if we've already seen this path (via cache)
+ if (ScanHelper.hasSeenOrMark(CanonicalPath)) {
+ LLVM_DEBUG(dbgs() << " -> Skipped: already seen.\n";);
+
+ return std::nullopt;
+ }
+
+ // [6] Already tracked in LibraryManager?
+ if (LibMgr.hasLibrary(CanonicalPath)) {
+ LLVM_DEBUG(dbgs() << " -> Skipped: already tracked by LibraryManager.\n";);
+
+ return std::nullopt;
+ }
+
+ // [7] Run user-defined hook (default: always true)
+ if (!ShouldScanCall(CanonicalPath)) {
+ LLVM_DEBUG(dbgs() << " -> Skipped: user-defined hook rejected.\n";);
+
+ return std::nullopt;
+ }
+
+ LLVM_DEBUG(dbgs() << " -> Accepted: ready to scan " << CanonicalPath
+ << "\n";);
+ return CanonicalPath;
+}
+
+void LibraryScanner::handleLibrary(StringRef FilePath, PathType K, int level) {
+ LLVM_DEBUG(dbgs() << "LibraryScanner::handleLibrary: Scanning: " << FilePath
+ << ", level=" << level << "\n";);
+ auto CanonPathOpt = shouldScan(FilePath);
+ if (!CanonPathOpt) {
+ LLVM_DEBUG(dbgs() << " Skipped (shouldScan returned false): " << FilePath
+ << "\n";);
+
+ return;
+ }
+ const std::string CanonicalPath = *CanonPathOpt;
+
+ auto DepsOrErr = extractDeps(CanonicalPath);
+ if (!DepsOrErr) {
+ LLVM_DEBUG(dbgs() << " Failed to extract deps for: " << CanonicalPath
+ << "\n";);
+ handleError(DepsOrErr.takeError());
+ return;
+ }
+
+ LibraryDepsInfo &Deps = *DepsOrErr;
+
+ LLVM_DEBUG({
+ dbgs() << " Found deps : \n";
+ for (const auto &dep : Deps.deps)
+ dbgs() << " : " << dep << "\n";
+ dbgs() << " Found @rpath : " << Deps.rpath.size() << "\n";
+ for (const auto &r : Deps.rpath)
+ dbgs() << " : " << r << "\n";
+ dbgs() << " Found @runpath : \n";
+ for (const auto &r : Deps.runPath)
+ dbgs() << " : " << r << "\n";
+ });
+
+ if (Deps.isPIE && level == 0) {
+ LLVM_DEBUG(dbgs() << " Skipped PIE executable at top level: "
+ << CanonicalPath << "\n";);
+
+ return;
+ }
+
+ bool Added = LibMgr.addLibrary(CanonicalPath, K);
+ if (!Added) {
+ LLVM_DEBUG(dbgs() << " Already added: " << CanonicalPath << "\n";);
+ return;
+ }
+
+ // Heuristic 1: No RPATH/RUNPATH, skip deps
+ if (Deps.rpath.empty() && Deps.runPath.empty()) {
+ LLVM_DEBUG(
+ dbgs() << "LibraryScanner::handleLibrary: Skipping deps (Heuristic1): "
+ << CanonicalPath << "\n";);
+ return;
+ }
+
+ // Heuristic 2: All RPATH and RUNPATH already tracked
+ auto allTracked = [&](const auto &Paths) {
+ LLVM_DEBUG(dbgs() << " Checking : " << Paths.size() << "\n";);
+ return std::all_of(Paths.begin(), Paths.end(), [&](StringRef P) {
+ LLVM_DEBUG(dbgs() << " Checking isTrackedBasePath : " << P << "\n";);
+ return ScanHelper.isTrackedBasePath(
+ DylibResolver::resolvelinkerFlag(P, CanonicalPath));
+ });
+ };
+
+ if (allTracked(Deps.rpath) && allTracked(Deps.runPath)) {
+ LLVM_DEBUG(
+ dbgs() << "LibraryScanner::handleLibrary: Skipping deps (Heuristic2): "
+ << CanonicalPath << "\n";);
+ return;
+ }
+
+ DylibPathValidator Validator(ScanHelper.getPathResolver());
+ DylibResolver Resolver(Validator);
+ Resolver.configure(CanonicalPath,
+ {{Deps.rpath, SearchPathType::RPath},
+ {ScanHelper.getSearchPaths(), SearchPathType::UsrOrSys},
+ {Deps.runPath, SearchPathType::RunPath}});
+ for (StringRef Dep : Deps.deps) {
+ LLVM_DEBUG(dbgs() << " Resolving dep: " << Dep << "\n";);
+ auto DepFullOpt = Resolver.resolve(Dep);
+ if (!DepFullOpt) {
+ LLVM_DEBUG(dbgs() << " Failed to resolve dep: " << Dep << "\n";);
+
+ continue;
+ }
+ LLVM_DEBUG(dbgs() << " Resolved dep to: " << *DepFullOpt << "\n";);
+
+ handleLibrary(*DepFullOpt, K, level + 1);
+ }
+}
+
+void LibraryScanner::scanBaseDir(std::shared_ptr<LibrarySearchPath> SP) {
+ if (!sys::fs::is_directory(SP->BasePath) || SP->BasePath.empty()) {
+ LLVM_DEBUG(
+ dbgs() << "LibraryScanner::scanBaseDir: Invalid or empty basePath: "
+ << SP->BasePath << "\n";);
+ return;
+ }
+
+ LLVM_DEBUG(dbgs() << "LibraryScanner::scanBaseDir: Scanning directory: "
+ << SP->BasePath << "\n";);
+ std::error_code EC;
+
+ SP->State.store(ScanState::Scanning);
+
+ for (sys::fs::directory_iterator It(SP->BasePath, EC), end; It != end && !EC;
+ It.increment(EC)) {
+ auto Entry = *It;
+ if (!Entry.status())
+ continue;
+
+ auto Status = *Entry.status();
+ if (sys::fs::is_regular_file(Status) || sys::fs::is_symlink_file(Status)) {
+ LLVM_DEBUG(dbgs() << " Found file: " << Entry.path() << "\n";);
+ // async support ?
+ handleLibrary(Entry.path(), SP->Kind);
+ }
+ }
+
+ SP->State.store(ScanState::Scanned);
+}
+
+void LibraryScanner::scanNext(PathType K, size_t BatchSize) {
+ LLVM_DEBUG(dbgs() << "LibraryScanner::scanNext: Scanning next batch of size "
+ << BatchSize << " for kind "
+ << (K == PathType::User ? "User" : "System") << "\n";);
+
+ auto SearchPaths = ScanHelper.getNextBatch(K, BatchSize);
+ for (auto &SP : SearchPaths) {
+ LLVM_DEBUG(dbgs() << " Scanning unit with basePath: " << SP->BasePath
+ << "\n";);
+
+ scanBaseDir(SP);
+ }
+}
+
+} // end namespace llvm::orc
diff --git a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
index a2bbb10039c9a..df26c94788d8f 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
+++ b/llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
@@ -25,6 +25,7 @@ add_llvm_unittest(OrcJITTests
IndirectionUtilsTest.cpp
JITTargetMachineBuilderTest.cpp
LazyCallThroughAndReexportsTest.cpp
+ LibraryResolverTest.cpp
LookupAndRecordAddrsTest.cpp
MachOPlatformTest.cpp
MapperJITLinkMemoryManagerTest.cpp
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_linux.yaml
new file mode 100644
index 0000000000000..afd1d9e69448d
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_linux.yaml
@@ -0,0 +1,460 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .rela.plt
+ Align: 0x1000
+ Offset: 0x0
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .init
+ LastSec: .fini
+ VAddr: 0x1000
+ Align: 0x1000
+ Offset: 0x1000
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .rodata
+ LastSec: .eh_frame
+ VAddr: 0x2000
+ Align: 0x1000
+ Offset: 0x2000
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .init_array
+ LastSec: .bss
+ VAddr: 0x3E10
+ Align: 0x1000
+ Offset: 0x2E10
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x3E20
+ Align: 0x8
+ Offset: 0x2E20
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.build-id
+ LastSec: .note.gnu.build-id
+ VAddr: 0x2C8
+ Align: 0x4
+ Offset: 0x2C8
+ - Type: PT_GNU_PROPERTY
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_GNU_EH_FRAME
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame_hdr
+ VAddr: 0x2010
+ Align: 0x4
+ Offset: 0x2010
+ - Type: PT_GNU_STACK
+ Flags: [ PF_W, PF_R ]
+ Align: 0x10
+ Offset: 0x0
+ - Type: PT_GNU_RELRO
+ Flags: [ PF_R ]
+ FirstSec: .init_array
+ LastSec: .got
+ VAddr: 0x3E10
+ Offset: 0x2E10
+Sections:
+ - Name: .note.gnu.property
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2A8
+ AddressAlign: 0x8
+ Notes:
+ - Name: GNU
+ Desc: 020000C0040000000300000000000000
+ Type: NT_GNU_PROPERTY_TYPE_0
+ - Name: .note.gnu.build-id
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2C8
+ AddressAlign: 0x4
+ Notes:
+ - Name: GNU
+ Desc: 73604396C95840D5C380A0950F085A778F94EE7C
+ Type: NT_PRPSINFO
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2F0
+ Link: .dynsym
+ AddressAlign: 0x8
+ Header:
+ SymNdx: 0x6
+ Shift2: 0x6
+ BloomFilter: [ 0x400000080000 ]
+ HashBuckets: [ 0x0, 0x6 ]
+ HashValues: [ 0x7C9DCB93 ]
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Address: 0x318
+ Link: .dynstr
+ AddressAlign: 0x8
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x3C0
+ AddressAlign: 0x1
+ - Name: .gnu.version
+ Type: SHT_GNU_versym
+ Flags: [ SHF_ALLOC ]
+ Address: 0x436
+ Link: .dynsym
+ AddressAlign: 0x2
+ Entries: [ 0, 1, 2, 1, 1, 2, 1 ]
+ - Name: .gnu.version_r
+ Type: SHT_GNU_verneed
+ Flags: [ SHF_ALLOC ]
+ Address: 0x448
+ Link: .dynstr
+ AddressAlign: 0x8
+ Dependencies:
+ - Version: 1
+ File: libc.so.6
+ Entries:
+ - Name: GLIBC_2.2.5
+ Hash: 157882997
+ Flags: 0
+ Other: 2
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x468
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x3E10
+ Type: R_X86_64_RELATIVE
+ Addend: 4368
+ - Offset: 0x3E18
+ Type: R_X86_64_RELATIVE
+ Addend: 4304
+ - Offset: 0x4020
+ Type: R_X86_64_RELATIVE
+ Addend: 16416
+ - Offset: 0x3FE0
+ Symbol: _ITM_deregisterTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FE8
+ Symbol: __gmon_start__
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF0
+ Symbol: _ITM_registerTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF8
+ Symbol: __cxa_finalize
+ Type: R_X86_64_GLOB_DAT
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x510
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x4018
+ Symbol: puts
+ Type: R_X86_64_JUMP_SLOT
+ - Name: .init
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Offset: 0x1000
+ Content: F30F1EFA4883EC08488B05D92F00004885C07402FFD04883C408C3
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1020
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90
+ - Name: .plt.got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1040
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF25AD2F00000F1F440000
+ - Name: .plt.sec
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1050
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF25BD2F00000F1F440000
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1060
+ AddressAlign: 0x10
+ Content: 488D3DC12F0000488D05BA2F00004839F87415488B05662F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D912F0000488D358A2F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05352F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D4D2F000000752B5548833D122F0000004889E5740C488B3D2E2F0000E849FFFFFFE864FFFFFFC605252F0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5488D05D80E00004889C7E820FFFFFF905DC3
+ - Name: .fini
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1134
+ AddressAlign: 0x4
+ Content: F30F1EFA4883EC084883C408C3
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2000
+ AddressAlign: 0x1
+ Offset: 0x2000
+ Content: 48656C6C6F2066726F6D204100
+ - Name: .eh_frame_hdr
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2010
+ AddressAlign: 0x4
+ Content: 011B033B2C0000000400000010F0FFFF4800000030F0FFFF7000000040F0FFFF8800000009F1FFFFA0000000
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2040
+ AddressAlign: 0x8
+ Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000C0EFFFFF20000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000B8EFFFFF100000000000000000000000140000005C000000B0EFFFFF1000000000000000000000001C0000007400000061F0FFFF1A00000000450E108602430D06510C070800000000000000
+ - Name: .init_array
+ Type: SHT_INIT_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E10
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Offset: 0x2E10
+ Content: '1011000000000000'
+ - Name: .fini_array
+ Type: SHT_FINI_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E18
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: D010000000000000
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E20
+ Link: .dynstr
+ AddressAlign: 0x8
+ Entries:
+ - Tag: DT_NEEDED
+ Value: 0x5F
+ - Tag: DT_INIT
+ Value: 0x1000
+ - Tag: DT_FINI
+ Value: 0x1134
+ - Tag: DT_INIT_ARRAY
+ Value: 0x3E10
+ - Tag: DT_INIT_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_FINI_ARRAY
+ Value: 0x3E18
+ - Tag: DT_FINI_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_GNU_HASH
+ Value: 0x2F0
+ - Tag: DT_STRTAB
+ Value: 0x3C0
+ - Tag: DT_SYMTAB
+ Value: 0x318
+ - Tag: DT_STRSZ
+ Value: 0x75
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_PLTGOT
+ Value: 0x4000
+ - Tag: DT_PLTRELSZ
+ Value: 0x18
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_JMPREL
+ Value: 0x510
+ - Tag: DT_RELA
+ Value: 0x468
+ - Tag: DT_RELASZ
+ Value: 0xA8
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_VERNEED
+ Value: 0x448
+ - Tag: DT_VERNEEDNUM
+ Value: 0x1
+ - Tag: DT_VERSYM
+ Value: 0x436
+ - Tag: DT_RELACOUNT
+ Value: 0x3
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Name: .got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3FE0
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '0000000000000000000000000000000000000000000000000000000000000000'
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4000
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '203E000000000000000000000000000000000000000000003010000000000000'
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4020
+ AddressAlign: 0x8
+ Content: '2040000000000000'
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4028
+ AddressAlign: 0x1
+ Size: 0x8
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000
+Symbols:
+ - Name: crtstuff.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: deregister_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1060
+ - Name: register_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1090
+ - Name: __do_global_dtors_aux
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x10D0
+ - Name: completed.0
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x4028
+ Size: 0x1
+ - Name: __do_global_dtors_aux_fini_array_entry
+ Type: STT_OBJECT
+ Section: .fini_array
+ Value: 0x3E18
+ - Name: frame_dummy
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1110
+ - Name: __frame_dummy_init_array_entry
+ Type: STT_OBJECT
+ Section: .init_array
+ Value: 0x3E10
+ - Name: libA.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: 'crtstuff.c (1)'
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: __FRAME_END__
+ Type: STT_OBJECT
+ Section: .eh_frame
+ Value: 0x20D0
+ - Type: STT_FILE
+ Index: SHN_ABS
+ - Name: _fini
+ Type: STT_FUNC
+ Section: .fini
+ Value: 0x1134
+ - Name: __dso_handle
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4020
+ - Name: _DYNAMIC
+ Type: STT_OBJECT
+ Section: .dynamic
+ Value: 0x3E20
+ - Name: __GNU_EH_FRAME_HDR
+ Section: .eh_frame_hdr
+ Value: 0x2010
+ - Name: __TMC_END__
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4028
+ - Name: _GLOBAL_OFFSET_TABLE_
+ Type: STT_OBJECT
+ Section: .got.plt
+ Value: 0x4000
+ - Name: _init
+ Type: STT_FUNC
+ Section: .init
+ Value: 0x1000
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: 'puts at GLIBC_2.2.5'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: sayA
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1119
+ Size: 0x1A
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: '__cxa_finalize at GLIBC_2.2.5'
+ Type: STT_FUNC
+ Binding: STB_WEAK
+DynamicSymbols:
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: puts
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: __cxa_finalize
+ Type: STT_FUNC
+ Binding: STB_WEAK
+ - Name: sayA
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1119
+ Size: 0x1A
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_macho.yaml
new file mode 100644
index 0000000000000..2e851a90c21ed
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/A/A_macho.yaml
@@ -0,0 +1,723 @@
+--- !fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 3
+FatArchs:
+ - cputype: 0x1000007
+ cpusubtype: 0x3
+ offset: 0x1000
+ size: 8376
+ align: 12
+ - cputype: 0x100000C
+ cpusubtype: 0x0
+ offset: 0x4000
+ size: 33376
+ align: 14
+ - cputype: 0x100000C
+ cpusubtype: 0x80000002
+ offset: 0x10000
+ size: 33376
+ align: 14
+Slices:
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x1000007
+ cpusubtype: 0x3
+ filetype: 0x6
+ ncmds: 14
+ sizeofcmds: 960
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4096
+ fileoff: 0
+ filesize: 4096
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0xF80
+ size: 20
+ offset: 0xF80
+ align: 4
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 554889E5488D3D0F000000B000E8020000005DC3
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0xF94
+ size: 6
+ offset: 0xF94
+ align: 1
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x6
+ reserved3: 0x0
+ content: FF2566000000
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0xF9A
+ size: 14
+ offset: 0xF9A
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D20410A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0xFA8
+ size: 88
+ offset: 0xFA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000800F00004000000040000000940F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 4096
+ vmsize: 4096
+ fileoff: 4096
+ filesize: 4096
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x1000
+ size: 8
+ offset: 0x1000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 8192
+ vmsize: 4096
+ fileoff: 8192
+ filesize: 184
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 8192
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 8288
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 8320
+ nsyms: 2
+ stroff: 8360
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 8352
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: ADFFA141-C3EE-37CD-B1E7-906D69F81BCB
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 8312
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 8320
+ datasize: 0
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayA
+ Flags: 0x0
+ Address: 0xF80
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 3968
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayA
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0xF80 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0,
+ 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x6
+ ncmds: 15
+ sizeofcmds: 976
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F70
+ size: 28
+ offset: 0x3F70
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8C0035FD6
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0x3F8C
+ size: 12
+ offset: 0x3F8C
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0xC
+ reserved3: 0x0
+ content: 100000B0100240F900021FD6
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0x3F98
+ size: 14
+ offset: 0x3F98
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D20410A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000703F000040000000400000008C3F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 8
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 608
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32864
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32896
+ nsyms: 2
+ stroff: 32936
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 32928
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: C45227E0-C6C0-3137-969B-36AABF9D5487
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32896
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 32960
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayA
+ Flags: 0x0
+ Address: 0x3F70
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16240
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayA
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0x3F70 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x80000002
+ filetype: 0x6
+ ncmds: 15
+ sizeofcmds: 976
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F68
+ size: 32
+ offset: 0x3F68
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 7F2303D5FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8FF0F5FD6
+ - sectname: __auth_stubs
+ segname: __TEXT
+ addr: 0x3F88
+ size: 16
+ offset: 0x3F88
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x10
+ reserved3: 0x0
+ content: 110000B031020091300240F9110A1FD7
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0x3F98
+ size: 14
+ offset: 0x3F98
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D20410A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000683F00004000000040000000883F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __auth_got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 8
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00000000000001C0
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 608
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32864
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32896
+ nsyms: 2
+ stroff: 32936
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 32928
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: C9DC00C2-E721-365C-9C2D-E9FDB7C838BB
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32896
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 32960
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayA
+ Flags: 0x0
+ Address: 0x3F68
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16232
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayA
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0x3F68 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_linux.yaml
new file mode 100644
index 0000000000000..fe4393e108d96
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_linux.yaml
@@ -0,0 +1,460 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .rela.plt
+ Align: 0x1000
+ Offset: 0x0
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .init
+ LastSec: .fini
+ VAddr: 0x1000
+ Align: 0x1000
+ Offset: 0x1000
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .rodata
+ LastSec: .eh_frame
+ VAddr: 0x2000
+ Align: 0x1000
+ Offset: 0x2000
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .init_array
+ LastSec: .bss
+ VAddr: 0x3E10
+ Align: 0x1000
+ Offset: 0x2E10
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x3E20
+ Align: 0x8
+ Offset: 0x2E20
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.build-id
+ LastSec: .note.gnu.build-id
+ VAddr: 0x2C8
+ Align: 0x4
+ Offset: 0x2C8
+ - Type: PT_GNU_PROPERTY
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_GNU_EH_FRAME
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame_hdr
+ VAddr: 0x2010
+ Align: 0x4
+ Offset: 0x2010
+ - Type: PT_GNU_STACK
+ Flags: [ PF_W, PF_R ]
+ Align: 0x10
+ Offset: 0x0
+ - Type: PT_GNU_RELRO
+ Flags: [ PF_R ]
+ FirstSec: .init_array
+ LastSec: .got
+ VAddr: 0x3E10
+ Offset: 0x2E10
+Sections:
+ - Name: .note.gnu.property
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2A8
+ AddressAlign: 0x8
+ Notes:
+ - Name: GNU
+ Desc: 020000C0040000000300000000000000
+ Type: NT_GNU_PROPERTY_TYPE_0
+ - Name: .note.gnu.build-id
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2C8
+ AddressAlign: 0x4
+ Notes:
+ - Name: GNU
+ Desc: 6337F7C1BF21A1DE17630C55602EB4CAC50435BB
+ Type: NT_PRPSINFO
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2F0
+ Link: .dynsym
+ AddressAlign: 0x8
+ Header:
+ SymNdx: 0x6
+ Shift2: 0x6
+ BloomFilter: [ 0x400000100000 ]
+ HashBuckets: [ 0x6, 0x0 ]
+ HashValues: [ 0x7C9DCB95 ]
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Address: 0x318
+ Link: .dynstr
+ AddressAlign: 0x8
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x3C0
+ AddressAlign: 0x1
+ - Name: .gnu.version
+ Type: SHT_GNU_versym
+ Flags: [ SHF_ALLOC ]
+ Address: 0x436
+ Link: .dynsym
+ AddressAlign: 0x2
+ Entries: [ 0, 1, 2, 1, 1, 2, 1 ]
+ - Name: .gnu.version_r
+ Type: SHT_GNU_verneed
+ Flags: [ SHF_ALLOC ]
+ Address: 0x448
+ Link: .dynstr
+ AddressAlign: 0x8
+ Dependencies:
+ - Version: 1
+ File: libc.so.6
+ Entries:
+ - Name: GLIBC_2.2.5
+ Hash: 157882997
+ Flags: 0
+ Other: 2
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x468
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x3E10
+ Type: R_X86_64_RELATIVE
+ Addend: 4368
+ - Offset: 0x3E18
+ Type: R_X86_64_RELATIVE
+ Addend: 4304
+ - Offset: 0x4020
+ Type: R_X86_64_RELATIVE
+ Addend: 16416
+ - Offset: 0x3FE0
+ Symbol: _ITM_deregisterTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FE8
+ Symbol: __gmon_start__
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF0
+ Symbol: _ITM_registerTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF8
+ Symbol: __cxa_finalize
+ Type: R_X86_64_GLOB_DAT
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x510
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x4018
+ Symbol: puts
+ Type: R_X86_64_JUMP_SLOT
+ - Name: .init
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Offset: 0x1000
+ Content: F30F1EFA4883EC08488B05D92F00004885C07402FFD04883C408C3
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1020
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90
+ - Name: .plt.got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1040
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF25AD2F00000F1F440000
+ - Name: .plt.sec
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1050
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF25BD2F00000F1F440000
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1060
+ AddressAlign: 0x10
+ Content: 488D3DC12F0000488D05BA2F00004839F87415488B05662F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D912F0000488D358A2F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05352F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D4D2F000000752B5548833D122F0000004889E5740C488B3D2E2F0000E849FFFFFFE864FFFFFFC605252F0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5488D05D80E00004889C7E820FFFFFF905DC3
+ - Name: .fini
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1134
+ AddressAlign: 0x4
+ Content: F30F1EFA4883EC084883C408C3
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2000
+ AddressAlign: 0x1
+ Offset: 0x2000
+ Content: 48656C6C6F2066726F6D204200
+ - Name: .eh_frame_hdr
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2010
+ AddressAlign: 0x4
+ Content: 011B033B2C0000000400000010F0FFFF4800000030F0FFFF7000000040F0FFFF8800000009F1FFFFA0000000
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2040
+ AddressAlign: 0x8
+ Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000C0EFFFFF20000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000B8EFFFFF100000000000000000000000140000005C000000B0EFFFFF1000000000000000000000001C0000007400000061F0FFFF1A00000000450E108602430D06510C070800000000000000
+ - Name: .init_array
+ Type: SHT_INIT_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E10
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Offset: 0x2E10
+ Content: '1011000000000000'
+ - Name: .fini_array
+ Type: SHT_FINI_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E18
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: D010000000000000
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E20
+ Link: .dynstr
+ AddressAlign: 0x8
+ Entries:
+ - Tag: DT_NEEDED
+ Value: 0x5F
+ - Tag: DT_INIT
+ Value: 0x1000
+ - Tag: DT_FINI
+ Value: 0x1134
+ - Tag: DT_INIT_ARRAY
+ Value: 0x3E10
+ - Tag: DT_INIT_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_FINI_ARRAY
+ Value: 0x3E18
+ - Tag: DT_FINI_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_GNU_HASH
+ Value: 0x2F0
+ - Tag: DT_STRTAB
+ Value: 0x3C0
+ - Tag: DT_SYMTAB
+ Value: 0x318
+ - Tag: DT_STRSZ
+ Value: 0x75
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_PLTGOT
+ Value: 0x4000
+ - Tag: DT_PLTRELSZ
+ Value: 0x18
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_JMPREL
+ Value: 0x510
+ - Tag: DT_RELA
+ Value: 0x468
+ - Tag: DT_RELASZ
+ Value: 0xA8
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_VERNEED
+ Value: 0x448
+ - Tag: DT_VERNEEDNUM
+ Value: 0x1
+ - Tag: DT_VERSYM
+ Value: 0x436
+ - Tag: DT_RELACOUNT
+ Value: 0x3
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Name: .got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3FE0
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '0000000000000000000000000000000000000000000000000000000000000000'
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4000
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '203E000000000000000000000000000000000000000000003010000000000000'
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4020
+ AddressAlign: 0x8
+ Content: '2040000000000000'
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4028
+ AddressAlign: 0x1
+ Size: 0x8
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000
+Symbols:
+ - Name: crtstuff.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: deregister_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1060
+ - Name: register_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1090
+ - Name: __do_global_dtors_aux
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x10D0
+ - Name: completed.0
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x4028
+ Size: 0x1
+ - Name: __do_global_dtors_aux_fini_array_entry
+ Type: STT_OBJECT
+ Section: .fini_array
+ Value: 0x3E18
+ - Name: frame_dummy
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1110
+ - Name: __frame_dummy_init_array_entry
+ Type: STT_OBJECT
+ Section: .init_array
+ Value: 0x3E10
+ - Name: libB.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: 'crtstuff.c (1)'
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: __FRAME_END__
+ Type: STT_OBJECT
+ Section: .eh_frame
+ Value: 0x20D0
+ - Type: STT_FILE
+ Index: SHN_ABS
+ - Name: _fini
+ Type: STT_FUNC
+ Section: .fini
+ Value: 0x1134
+ - Name: __dso_handle
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4020
+ - Name: _DYNAMIC
+ Type: STT_OBJECT
+ Section: .dynamic
+ Value: 0x3E20
+ - Name: __GNU_EH_FRAME_HDR
+ Section: .eh_frame_hdr
+ Value: 0x2010
+ - Name: __TMC_END__
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4028
+ - Name: _GLOBAL_OFFSET_TABLE_
+ Type: STT_OBJECT
+ Section: .got.plt
+ Value: 0x4000
+ - Name: _init
+ Type: STT_FUNC
+ Section: .init
+ Value: 0x1000
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: 'puts at GLIBC_2.2.5'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: sayB
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1119
+ Size: 0x1A
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: '__cxa_finalize at GLIBC_2.2.5'
+ Type: STT_FUNC
+ Binding: STB_WEAK
+DynamicSymbols:
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: puts
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: __cxa_finalize
+ Type: STT_FUNC
+ Binding: STB_WEAK
+ - Name: sayB
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1119
+ Size: 0x1A
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_macho.yaml
new file mode 100644
index 0000000000000..3d57c4f9271c6
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/B/B_macho.yaml
@@ -0,0 +1,723 @@
+--- !fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 3
+FatArchs:
+ - cputype: 0x1000007
+ cpusubtype: 0x3
+ offset: 0x1000
+ size: 8376
+ align: 12
+ - cputype: 0x100000C
+ cpusubtype: 0x0
+ offset: 0x4000
+ size: 33376
+ align: 14
+ - cputype: 0x100000C
+ cpusubtype: 0x80000002
+ offset: 0x10000
+ size: 33376
+ align: 14
+Slices:
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x1000007
+ cpusubtype: 0x3
+ filetype: 0x6
+ ncmds: 14
+ sizeofcmds: 960
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4096
+ fileoff: 0
+ filesize: 4096
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0xF80
+ size: 20
+ offset: 0xF80
+ align: 4
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 554889E5488D3D0F000000B000E8020000005DC3
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0xF94
+ size: 6
+ offset: 0xF94
+ align: 1
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x6
+ reserved3: 0x0
+ content: FF2566000000
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0xF9A
+ size: 14
+ offset: 0xF9A
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D20420A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0xFA8
+ size: 88
+ offset: 0xFA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000800F00004000000040000000940F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 4096
+ vmsize: 4096
+ fileoff: 4096
+ filesize: 4096
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x1000
+ size: 8
+ offset: 0x1000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 8192
+ vmsize: 4096
+ fileoff: 8192
+ filesize: 184
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libB.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 8192
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 8288
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 8320
+ nsyms: 2
+ stroff: 8360
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 8352
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 88B60B3C-13D3-3D7E-AEED-5F3E991FDF08
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 8312
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 8320
+ datasize: 0
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayB
+ Flags: 0x0
+ Address: 0xF80
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 3968
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayB
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0xF80 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0,
+ 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x6
+ ncmds: 15
+ sizeofcmds: 976
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F70
+ size: 28
+ offset: 0x3F70
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8C0035FD6
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0x3F8C
+ size: 12
+ offset: 0x3F8C
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0xC
+ reserved3: 0x0
+ content: 100000B0100240F900021FD6
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0x3F98
+ size: 14
+ offset: 0x3F98
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D20420A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000703F000040000000400000008C3F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 8
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 608
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libB.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32864
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32896
+ nsyms: 2
+ stroff: 32936
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 32928
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 90C3787A-22E1-35AE-9284-97A4842F88AF
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32896
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 32960
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayB
+ Flags: 0x0
+ Address: 0x3F70
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16240
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayB
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0x3F70 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x80000002
+ filetype: 0x6
+ ncmds: 15
+ sizeofcmds: 976
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F68
+ size: 32
+ offset: 0x3F68
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 7F2303D5FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8FF0F5FD6
+ - sectname: __auth_stubs
+ segname: __TEXT
+ addr: 0x3F88
+ size: 16
+ offset: 0x3F88
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x10
+ reserved3: 0x0
+ content: 110000B031020091300240F9110A1FD7
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0x3F98
+ size: 14
+ offset: 0x3F98
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D20420A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000683F00004000000040000000883F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __auth_got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 8
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00000000000001C0
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 608
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libB.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32864
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32896
+ nsyms: 2
+ stroff: 32936
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 32928
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 76B41B3A-00EC-388B-A432-478A96772CC4
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32896
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 32960
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayB
+ Flags: 0x0
+ Address: 0x3F68
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16232
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayB
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0x3F68 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_linux.yaml
new file mode 100644
index 0000000000000..8b75b1e5159cf
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_linux.yaml
@@ -0,0 +1,461 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .rela.plt
+ Align: 0x1000
+ Offset: 0x0
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .init
+ LastSec: .fini
+ VAddr: 0x1000
+ Align: 0x1000
+ Offset: 0x1000
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame
+ VAddr: 0x2000
+ Align: 0x1000
+ Offset: 0x2000
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .init_array
+ LastSec: .bss
+ VAddr: 0x3E00
+ Align: 0x1000
+ Offset: 0x2E00
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x3E10
+ Align: 0x8
+ Offset: 0x2E10
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.build-id
+ LastSec: .note.gnu.build-id
+ VAddr: 0x2C8
+ Align: 0x4
+ Offset: 0x2C8
+ - Type: PT_GNU_PROPERTY
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_GNU_EH_FRAME
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame_hdr
+ VAddr: 0x2000
+ Align: 0x4
+ Offset: 0x2000
+ - Type: PT_GNU_STACK
+ Flags: [ PF_W, PF_R ]
+ Align: 0x10
+ Offset: 0x0
+ - Type: PT_GNU_RELRO
+ Flags: [ PF_R ]
+ FirstSec: .init_array
+ LastSec: .got
+ VAddr: 0x3E00
+ Offset: 0x2E00
+Sections:
+ - Name: .note.gnu.property
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2A8
+ AddressAlign: 0x8
+ Notes:
+ - Name: GNU
+ Desc: 020000C0040000000300000000000000
+ Type: NT_GNU_PROPERTY_TYPE_0
+ - Name: .note.gnu.build-id
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2C8
+ AddressAlign: 0x4
+ Notes:
+ - Name: GNU
+ Desc: C5C3C9594A5D3556DC54D70850C6DBC316710857
+ Type: NT_PRPSINFO
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2F0
+ Link: .dynsym
+ AddressAlign: 0x8
+ Header:
+ SymNdx: 0x9
+ Shift2: 0x6
+ BloomFilter: [ 0x400000200000 ]
+ HashBuckets: [ 0x0, 0x9 ]
+ HashValues: [ 0x7C9DCB95 ]
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Address: 0x318
+ Link: .dynstr
+ AddressAlign: 0x8
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x408
+ AddressAlign: 0x1
+ Content: "6C6962412E736F006C6962422E736F006C6962442E736F006C69625A2E736F00244F524947494E2F2E2E2F413A244F524947494E2F2E2E2F423A244F524947494E2F2E2E2F443A244F524947494E2F2E2E2F5A"
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x4D0
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x3E00
+ Type: R_X86_64_RELATIVE
+ Addend: 4464
+ - Offset: 0x3E08
+ Type: R_X86_64_RELATIVE
+ Addend: 4400
+ - Offset: 0x4038
+ Type: R_X86_64_RELATIVE
+ Addend: 16440
+ - Offset: 0x3FE0
+ Symbol: __cxa_finalize
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FE8
+ Symbol: _ITM_registerTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF0
+ Symbol: _ITM_deregisterTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF8
+ Symbol: __gmon_start__
+ Type: R_X86_64_GLOB_DAT
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x578
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x4018
+ Symbol: sayD
+ Type: R_X86_64_JUMP_SLOT
+ - Offset: 0x4020
+ Symbol: sayA
+ Type: R_X86_64_JUMP_SLOT
+ - Offset: 0x4028
+ Symbol: sayB
+ Type: R_X86_64_JUMP_SLOT
+ - Offset: 0x4030
+ Symbol: sayZ
+ Type: R_X86_64_JUMP_SLOT
+ - Name: .init
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Offset: 0x1000
+ Content: F30F1EFA4883EC08488B05E92F00004885C07402FFD04883C408C3
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1020
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90F30F1EFA6801000000F2E9D1FFFFFF90F30F1EFA6802000000F2E9C1FFFFFF90F30F1EFA6803000000F2E9B1FFFFFF90
+ - Name: .plt.got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1070
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF25652F00000F1F440000
+ - Name: .plt.sec
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1080
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF258D2F00000F1F440000F30F1EFAF2FF25852F00000F1F440000F30F1EFAF2FF257D2F00000F1F440000F30F1EFAF2FF25752F00000F1F440000
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x10C0
+ AddressAlign: 0x10
+ Content: 488D3D792F0000488D05722F00004839F87415488B05162F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D492F0000488D35422F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05CD2E00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D052F000000752B5548833D9A2E0000004889E5740C488B3DE62E0000E819FFFFFFE864FFFFFFC605DD2E0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5B800000000E805FFFFFFB800000000E80BFFFFFFB800000000E8E1FEFFFFB800000000E807FFFFFF905DC3
+ - Name: .fini
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x11AC
+ AddressAlign: 0x4
+ Content: F30F1EFA4883EC084883C408C3
+ - Name: .eh_frame_hdr
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2000
+ AddressAlign: 0x4
+ Offset: 0x2000
+ Content: 011B033B2C0000000400000020F0FFFF4800000070F0FFFF7000000080F0FFFF8800000079F1FFFFA0000000
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2030
+ AddressAlign: 0x8
+ Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000D0EFFFFF50000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000F8EFFFFF100000000000000000000000140000005C000000F0EFFFFF4000000000000000000000001C00000074000000D1F0FFFF3300000000450E108602430D066A0C070800000000000000
+ - Name: .init_array
+ Type: SHT_INIT_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E00
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Offset: 0x2E00
+ Content: '7011000000000000'
+ - Name: .fini_array
+ Type: SHT_FINI_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E08
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '3011000000000000'
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E10
+ Link: .dynstr
+ AddressAlign: 0x8
+ Entries:
+ - Tag: DT_NEEDED
+ Value: 0x0
+ - Tag: DT_NEEDED
+ Value: 0x8
+ - Tag: DT_NEEDED
+ Value: 0x10
+ - Tag: DT_NEEDED
+ Value: 0x18
+ - Tag: DT_RUNPATH
+ Value: 0x20
+ - Tag: DT_INIT
+ Value: 0x1000
+ - Tag: DT_FINI
+ Value: 0x11AC
+ - Tag: DT_INIT_ARRAY
+ Value: 0x3E00
+ - Tag: DT_INIT_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_FINI_ARRAY
+ Value: 0x3E08
+ - Tag: DT_FINI_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_GNU_HASH
+ Value: 0x2F0
+ - Tag: DT_STRTAB
+ Value: 0x408
+ - Tag: DT_SYMTAB
+ Value: 0x318
+ - Tag: DT_STRSZ
+ Value: 0xC2
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_PLTGOT
+ Value: 0x4000
+ - Tag: DT_PLTRELSZ
+ Value: 0x60
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_JMPREL
+ Value: 0x578
+ - Tag: DT_RELA
+ Value: 0x4D0
+ - Tag: DT_RELASZ
+ Value: 0xA8
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_RELACOUNT
+ Value: 0x3
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Name: .got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3FE0
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '0000000000000000000000000000000000000000000000000000000000000000'
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4000
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '103E000000000000000000000000000000000000000000003010000000000000401000000000000050100000000000006010000000000000'
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4038
+ AddressAlign: 0x8
+ Content: '3840000000000000'
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4040
+ AddressAlign: 0x1
+ Size: 0x8
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000
+Symbols:
+ - Name: crtstuff.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: deregister_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x10C0
+ - Name: register_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x10F0
+ - Name: __do_global_dtors_aux
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1130
+ - Name: completed.0
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x4040
+ Size: 0x1
+ - Name: __do_global_dtors_aux_fini_array_entry
+ Type: STT_OBJECT
+ Section: .fini_array
+ Value: 0x3E08
+ - Name: frame_dummy
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1170
+ - Name: __frame_dummy_init_array_entry
+ Type: STT_OBJECT
+ Section: .init_array
+ Value: 0x3E00
+ - Name: libC.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: 'crtstuff.c (1)'
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: __FRAME_END__
+ Type: STT_OBJECT
+ Section: .eh_frame
+ Value: 0x20C0
+ - Type: STT_FILE
+ Index: SHN_ABS
+ - Name: _DYNAMIC
+ Type: STT_OBJECT
+ Section: .dynamic
+ Value: 0x3E10
+ - Name: __TMC_END__
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4040
+ - Name: __dso_handle
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4038
+ - Name: _init
+ Type: STT_FUNC
+ Section: .init
+ Value: 0x1000
+ - Name: __GNU_EH_FRAME_HDR
+ Section: .eh_frame_hdr
+ Value: 0x2000
+ - Name: _fini
+ Type: STT_FUNC
+ Section: .fini
+ Value: 0x11AC
+ - Name: _GLOBAL_OFFSET_TABLE_
+ Type: STT_OBJECT
+ Section: .got.plt
+ Value: 0x4000
+ - Name: sayD
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __cxa_finalize
+ Binding: STB_WEAK
+ - Name: sayC
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1179
+ Size: 0x33
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: sayA
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: sayB
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: sayZ
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+DynamicSymbols:
+ - Name: sayD
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __cxa_finalize
+ Binding: STB_WEAK
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: sayA
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: sayB
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: sayZ
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: sayC
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1179
+ Size: 0x33
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_macho.yaml
new file mode 100644
index 0000000000000..f6ad08190e6d5
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/C/C_macho.yaml
@@ -0,0 +1,915 @@
+--- !fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 3
+FatArchs:
+ - cputype: 0x1000007
+ cpusubtype: 0x3
+ offset: 0x1000
+ size: 8488
+ align: 12
+ - cputype: 0x100000C
+ cpusubtype: 0x0
+ offset: 0x4000
+ size: 33488
+ align: 14
+ - cputype: 0x100000C
+ cpusubtype: 0x80000002
+ offset: 0x10000
+ size: 33488
+ align: 14
+Slices:
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x1000007
+ cpusubtype: 0x3
+ filetype: 0x6
+ ncmds: 22
+ sizeofcmds: 1200
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 312
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4096
+ fileoff: 0
+ filesize: 4096
+ maxprot: 5
+ initprot: 5
+ nsects: 3
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0xF60
+ size: 34
+ offset: 0xF60
+ align: 4
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 554889E5B000E817000000B000E816000000B000E815000000B000E8140000005DC3
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0xF82
+ size: 24
+ offset: 0xF82
+ align: 1
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x6
+ reserved3: 0x0
+ content: FF2578000000FF257A000000FF257C000000FF257E000000
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0xF9C
+ size: 88
+ offset: 0xF9C
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000600F00004000000040000000820F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 4096
+ vmsize: 4096
+ fileoff: 4096
+ filesize: 4096
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x1000
+ size: 32
+ offset: 0x1000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x4
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000000001080010000000000108002000000000010800300000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 8192
+ vmsize: 4096
+ fileoff: 8192
+ filesize: 296
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libC.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 8192
+ datasize: 120
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 8312
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 8344
+ nsyms: 5
+ stroff: 8456
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 4
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 8424
+ nindirectsyms: 8
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 2A1F4EC3-CD6C-3293-9D2B-5D8E42FE51EF
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libB.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libD.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libZ.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../A'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../B'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../D'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../Z'
+ ZeroPadBytes: 3
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 8336
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 8344
+ datasize: 0
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayC
+ Flags: 0x0
+ Address: 0xF60
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 3936
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ - n_strx: 14
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 512
+ n_value: 0
+ - n_strx: 20
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 768
+ n_value: 0
+ - n_strx: 26
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 1024
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayC
+ - _sayA
+ - _sayB
+ - _sayD
+ - _sayZ
+ IndirectSymbols: [ 0x1, 0x2, 0x3, 0x4, 0x1, 0x2, 0x3, 0x4 ]
+ FunctionStarts: [ 0xF60 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x4, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0,
+ 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x2, 0xE, 0x0, 0x0, 0x3, 0x1A, 0x0, 0x0,
+ 0x4, 0x26, 0x0, 0x0, 0x0, 0x5F, 0x73, 0x61, 0x79,
+ 0x41, 0x0, 0x5F, 0x73, 0x61, 0x79, 0x42, 0x0,
+ 0x5F, 0x73, 0x61, 0x79, 0x44, 0x0, 0x5F, 0x73,
+ 0x61, 0x79, 0x5A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x6
+ ncmds: 23
+ sizeofcmds: 1216
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 312
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 3
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F58
+ size: 32
+ offset: 0x3F58
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FD7BBFA9FD03009106000094080000940A0000940C000094FD7BC1A8C0035FD6
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0x3F78
+ size: 48
+ offset: 0x3F78
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0xC
+ reserved3: 0x0
+ content: 100000B0100240F900021FD6100000B0100640F900021FD6100000B0100A40F900021FD6100000B0100E40F900021FD6
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000583F00004000000040000000783F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 32
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x4
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000000001080010000000000108002000000000010800300000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 720
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libC.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 120
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32920
+ nsyms: 5
+ stroff: 33032
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 4
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 33000
+ nindirectsyms: 8
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 6DE75070-D632-398D-8BB5-06C8C8B29147
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libB.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libD.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libZ.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../A'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../B'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../D'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../Z'
+ ZeroPadBytes: 3
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32912
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32920
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 33072
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayC
+ Flags: 0x0
+ Address: 0x3F58
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16216
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ - n_strx: 14
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 512
+ n_value: 0
+ - n_strx: 20
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 768
+ n_value: 0
+ - n_strx: 26
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 1024
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayC
+ - _sayA
+ - _sayB
+ - _sayD
+ - _sayZ
+ IndirectSymbols: [ 0x1, 0x2, 0x3, 0x4, 0x1, 0x2, 0x3, 0x4 ]
+ FunctionStarts: [ 0x3F58 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x4, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x2, 0xE, 0x0, 0x0, 0x3, 0x1A, 0x0, 0x0,
+ 0x4, 0x26, 0x0, 0x0, 0x0, 0x5F, 0x73, 0x61, 0x79,
+ 0x41, 0x0, 0x5F, 0x73, 0x61, 0x79, 0x42, 0x0,
+ 0x5F, 0x73, 0x61, 0x79, 0x44, 0x0, 0x5F, 0x73,
+ 0x61, 0x79, 0x5A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x80000002
+ filetype: 0x6
+ ncmds: 23
+ sizeofcmds: 1216
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 312
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 3
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F44
+ size: 36
+ offset: 0x3F44
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 7F2303D5FD7BBFA9FD03009106000094090000940C0000940F000094FD7BC1A8FF0F5FD6
+ - sectname: __auth_stubs
+ segname: __TEXT
+ addr: 0x3F68
+ size: 64
+ offset: 0x3F68
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x10
+ reserved3: 0x0
+ content: 110000B031020091300240F9110A1FD7110000B031220091300240F9110A1FD7110000B031420091300240F9110A1FD7110000B031620091300240F9110A1FD7
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000443F00004000000040000000683F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __auth_got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 32
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x4
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00000000000009C001000000000009C002000000000009C003000000000001C0
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 720
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libC.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 120
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32920
+ nsyms: 5
+ stroff: 33032
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 4
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 33000
+ nindirectsyms: 8
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: C1E8A3F5-14B1-3BF2-B737-18AB98364487
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libB.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libD.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libZ.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../A'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../B'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../D'
+ ZeroPadBytes: 3
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../Z'
+ ZeroPadBytes: 3
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32912
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32920
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 33072
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayC
+ Flags: 0x0
+ Address: 0x3F44
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16196
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ - n_strx: 14
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 512
+ n_value: 0
+ - n_strx: 20
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 768
+ n_value: 0
+ - n_strx: 26
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 1024
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayC
+ - _sayA
+ - _sayB
+ - _sayD
+ - _sayZ
+ IndirectSymbols: [ 0x1, 0x2, 0x3, 0x4, 0x1, 0x2, 0x3, 0x4 ]
+ FunctionStarts: [ 0x3F44 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, 0x4, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x2, 0xE, 0x0, 0x0, 0x3, 0x1A, 0x0, 0x0,
+ 0x4, 0x26, 0x0, 0x0, 0x0, 0x5F, 0x73, 0x61, 0x79,
+ 0x41, 0x0, 0x5F, 0x73, 0x61, 0x79, 0x42, 0x0,
+ 0x5F, 0x73, 0x61, 0x79, 0x44, 0x0, 0x5F, 0x73,
+ 0x61, 0x79, 0x5A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0 ]
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/D/D_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/D/D_linux.yaml
new file mode 100644
index 0000000000000..f4f2f36b1486d
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/D/D_linux.yaml
@@ -0,0 +1,479 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .rela.plt
+ Align: 0x1000
+ Offset: 0x0
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .init
+ LastSec: .fini
+ VAddr: 0x1000
+ Align: 0x1000
+ Offset: 0x1000
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .rodata
+ LastSec: .eh_frame
+ VAddr: 0x2000
+ Align: 0x1000
+ Offset: 0x2000
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .init_array
+ LastSec: .bss
+ VAddr: 0x3DF0
+ Align: 0x1000
+ Offset: 0x2DF0
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x3E00
+ Align: 0x8
+ Offset: 0x2E00
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.build-id
+ LastSec: .note.gnu.build-id
+ VAddr: 0x2C8
+ Align: 0x4
+ Offset: 0x2C8
+ - Type: PT_GNU_PROPERTY
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_GNU_EH_FRAME
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame_hdr
+ VAddr: 0x2010
+ Align: 0x4
+ Offset: 0x2010
+ - Type: PT_GNU_STACK
+ Flags: [ PF_W, PF_R ]
+ Align: 0x10
+ Offset: 0x0
+ - Type: PT_GNU_RELRO
+ Flags: [ PF_R ]
+ FirstSec: .init_array
+ LastSec: .got
+ VAddr: 0x3DF0
+ Offset: 0x2DF0
+Sections:
+ - Name: .note.gnu.property
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2A8
+ AddressAlign: 0x8
+ Notes:
+ - Name: GNU
+ Desc: 020000C0040000000300000000000000
+ Type: NT_GNU_PROPERTY_TYPE_0
+ - Name: .note.gnu.build-id
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2C8
+ AddressAlign: 0x4
+ Notes:
+ - Name: GNU
+ Desc: 6A0CC906C743C23E1400FDD239CF755466AB3E7B
+ Type: NT_PRPSINFO
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2F0
+ Link: .dynsym
+ AddressAlign: 0x8
+ Header:
+ SymNdx: 0x7
+ Shift2: 0x6
+ BloomFilter: [ 0x400000400000 ]
+ HashBuckets: [ 0x7, 0x0 ]
+ HashValues: [ 0x7C9DCB97 ]
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Address: 0x318
+ Link: .dynstr
+ AddressAlign: 0x8
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x3D8
+ AddressAlign: 0x1
+ Content: "6C6962412E736F006C6962632E736F2E3600244F524947494E2F2E2E2F4100"
+ - Name: .gnu.version
+ Type: SHT_GNU_versym
+ Flags: [ SHF_ALLOC ]
+ Address: 0x468
+ Link: .dynsym
+ AddressAlign: 0x2
+ Entries: [ 0, 1, 2, 1, 1, 1, 2, 1 ]
+ - Name: .gnu.version_r
+ Type: SHT_GNU_verneed
+ Flags: [ SHF_ALLOC ]
+ Address: 0x478
+ Link: .dynstr
+ AddressAlign: 0x8
+ Dependencies:
+ - Version: 1
+ File: libc.so.6
+ Entries:
+ - Name: GLIBC_2.2.5
+ Hash: 157882997
+ Flags: 0
+ Other: 2
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x498
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x3DF0
+ Type: R_X86_64_RELATIVE
+ Addend: 4400
+ - Offset: 0x3DF8
+ Type: R_X86_64_RELATIVE
+ Addend: 4336
+ - Offset: 0x4028
+ Type: R_X86_64_RELATIVE
+ Addend: 16424
+ - Offset: 0x3FE0
+ Symbol: _ITM_deregisterTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FE8
+ Symbol: __gmon_start__
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF0
+ Symbol: _ITM_registerTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF8
+ Symbol: __cxa_finalize
+ Type: R_X86_64_GLOB_DAT
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x540
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x4018
+ Symbol: puts
+ Type: R_X86_64_JUMP_SLOT
+ - Offset: 0x4020
+ Symbol: sayA
+ Type: R_X86_64_JUMP_SLOT
+ - Name: .init
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Offset: 0x1000
+ Content: F30F1EFA4883EC08488B05D92F00004885C07402FFD04883C408C3
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1020
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90F30F1EFA6801000000F2E9D1FFFFFF90
+ - Name: .plt.got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1050
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF259D2F00000F1F440000
+ - Name: .plt.sec
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1060
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF25AD2F00000F1F440000F30F1EFAF2FF25A52F00000F1F440000
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1080
+ AddressAlign: 0x10
+ Content: 488D3DA92F0000488D05A22F00004839F87415488B05462F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D792F0000488D35722F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05152F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D352F000000752B5548833DF22E0000004889E5740C488B3D162F0000E839FFFFFFE864FFFFFFC6050D2F0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5B800000000E825FFFFFF905DC3F30F1EFA554889E5488D05A30E00004889C7E8FBFEFFFF905DC3
+ - Name: .fini
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1168
+ AddressAlign: 0x4
+ Content: F30F1EFA4883EC084883C408C3
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2000
+ AddressAlign: 0x1
+ Offset: 0x2000
+ Content: 48656C6C6F2066726F6D20442100
+ - Name: .eh_frame_hdr
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2010
+ AddressAlign: 0x4
+ Content: 011B033B340000000500000010F0FFFF5000000040F0FFFF7800000050F0FFFF9000000029F1FFFFA80000003EF1FFFFC8000000
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2048
+ AddressAlign: 0x8
+ Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000B8EFFFFF30000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000C0EFFFFF100000000000000000000000140000005C000000B8EFFFFF2000000000000000000000001C0000007400000079F0FFFF1500000000450E108602430D064C0C07080000001C000000940000006EF0FFFF1A00000000450E108602430D06510C070800000000000000
+ - Name: .init_array
+ Type: SHT_INIT_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3DF0
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Offset: 0x2DF0
+ Content: '3011000000000000'
+ - Name: .fini_array
+ Type: SHT_FINI_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3DF8
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: F010000000000000
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E00
+ Link: .dynstr
+ AddressAlign: 0x8
+ Entries:
+ - Tag: DT_NEEDED
+ Value: 0x00
+ - Tag: DT_NEEDED
+ Value: 0x08
+ - Tag: DT_RUNPATH
+ Value: 0x12
+ - Tag: DT_INIT
+ Value: 0x1000
+ - Tag: DT_FINI
+ Value: 0x1168
+ - Tag: DT_INIT_ARRAY
+ Value: 0x3DF0
+ - Tag: DT_INIT_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_FINI_ARRAY
+ Value: 0x3DF8
+ - Tag: DT_FINI_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_GNU_HASH
+ Value: 0x2F0
+ - Tag: DT_STRTAB
+ Value: 0x3D8
+ - Tag: DT_SYMTAB
+ Value: 0x318
+ - Tag: DT_STRSZ
+ Value: 0x8F
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_PLTGOT
+ Value: 0x4000
+ - Tag: DT_PLTRELSZ
+ Value: 0x30
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_JMPREL
+ Value: 0x540
+ - Tag: DT_RELA
+ Value: 0x498
+ - Tag: DT_RELASZ
+ Value: 0xA8
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_VERNEED
+ Value: 0x478
+ - Tag: DT_VERNEEDNUM
+ Value: 0x1
+ - Tag: DT_VERSYM
+ Value: 0x468
+ - Tag: DT_RELACOUNT
+ Value: 0x3
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Name: .got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3FE0
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '0000000000000000000000000000000000000000000000000000000000000000'
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4000
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '003E0000000000000000000000000000000000000000000030100000000000004010000000000000'
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4028
+ AddressAlign: 0x8
+ Content: '2840000000000000'
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4030
+ AddressAlign: 0x1
+ Size: 0x8
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000
+Symbols:
+ - Name: crtstuff.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: deregister_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1080
+ - Name: register_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x10B0
+ - Name: __do_global_dtors_aux
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x10F0
+ - Name: completed.0
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x4030
+ Size: 0x1
+ - Name: __do_global_dtors_aux_fini_array_entry
+ Type: STT_OBJECT
+ Section: .fini_array
+ Value: 0x3DF8
+ - Name: frame_dummy
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1130
+ - Name: __frame_dummy_init_array_entry
+ Type: STT_OBJECT
+ Section: .init_array
+ Value: 0x3DF0
+ - Name: libD.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: keepSayA
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1139
+ Size: 0x15
+ - Name: 'crtstuff.c (1)'
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: __FRAME_END__
+ Type: STT_OBJECT
+ Section: .eh_frame
+ Value: 0x20F8
+ - Type: STT_FILE
+ Index: SHN_ABS
+ - Name: _fini
+ Type: STT_FUNC
+ Section: .fini
+ Value: 0x1168
+ - Name: __dso_handle
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4028
+ - Name: _DYNAMIC
+ Type: STT_OBJECT
+ Section: .dynamic
+ Value: 0x3E00
+ - Name: __GNU_EH_FRAME_HDR
+ Section: .eh_frame_hdr
+ Value: 0x2010
+ - Name: __TMC_END__
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4030
+ - Name: _GLOBAL_OFFSET_TABLE_
+ Type: STT_OBJECT
+ Section: .got.plt
+ Value: 0x4000
+ - Name: _init
+ Type: STT_FUNC
+ Section: .init
+ Value: 0x1000
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: 'puts at GLIBC_2.2.5'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: sayA
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: sayD
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x114E
+ Size: 0x1A
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: '__cxa_finalize at GLIBC_2.2.5'
+ Type: STT_FUNC
+ Binding: STB_WEAK
+DynamicSymbols:
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: puts
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: sayA
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: __cxa_finalize
+ Type: STT_FUNC
+ Binding: STB_WEAK
+ - Name: sayD
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x114E
+ Size: 0x1A
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/D/D_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/D/D_macho.yaml
new file mode 100644
index 0000000000000..1f80c1d21dbd3
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/D/D_macho.yaml
@@ -0,0 +1,801 @@
+--- !fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 3
+FatArchs:
+ - cputype: 0x1000007
+ cpusubtype: 0x3
+ offset: 0x1000
+ size: 8432
+ align: 12
+ - cputype: 0x100000C
+ cpusubtype: 0x0
+ offset: 0x4000
+ size: 33424
+ align: 14
+ - cputype: 0x100000C
+ cpusubtype: 0x80000002
+ offset: 0x10000
+ size: 33424
+ align: 14
+Slices:
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x1000007
+ cpusubtype: 0x3
+ filetype: 0x6
+ ncmds: 16
+ sizeofcmds: 1040
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4096
+ fileoff: 0
+ filesize: 4096
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0xF60
+ size: 36
+ offset: 0xF60
+ align: 4
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 554889E5B000E81F0000005DC30F1F00554889E5488D3D15000000B000E8020000005DC3
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0xF84
+ size: 12
+ offset: 0xF84
+ align: 1
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x6
+ reserved3: 0x0
+ content: FF2576000000FF2578000000
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0xF90
+ size: 15
+ offset: 0xF90
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D2044210A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0xFA0
+ size: 88
+ offset: 0xFA0
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000600F00004000000040000000840F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 4096
+ vmsize: 4096
+ fileoff: 4096
+ filesize: 4096
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x1000
+ size: 16
+ offset: 0x1000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x2
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '00000000000010800100000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 8192
+ vmsize: 4096
+ fileoff: 8192
+ filesize: 240
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libD.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 8192
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 8288
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 8320
+ nsyms: 4
+ stroff: 8400
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 1
+ iextdefsym: 1
+ nextdefsym: 1
+ iundefsym: 2
+ nundefsym: 2
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 8384
+ nindirectsyms: 4
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 8B5D4A65-6C4F-3D34-9294-26E03CFBD3AE
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../A'
+ ZeroPadBytes: 3
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 8312
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 8320
+ datasize: 0
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayD
+ Flags: 0x0
+ Address: 0xF70
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 22
+ n_type: 0xE
+ n_sect: 1
+ n_desc: 0
+ n_value: 3936
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 3952
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 512
+ n_value: 0
+ - n_strx: 16
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayD
+ - _printf
+ - _sayA
+ - _keepSayA
+ IndirectSymbols: [ 0x2, 0x3, 0x2, 0x3 ]
+ FunctionStarts: [ 0xF60, 0xF70 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x2, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0,
+ 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x2, 0x0,
+ 0x0, 0x1, 0x12, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x5F, 0x73, 0x61,
+ 0x79, 0x41, 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x6
+ ncmds: 17
+ sizeofcmds: 1056
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F50
+ size: 48
+ offset: 0x3F50
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FD7BBFA9FD0300910D000094FD7BC1A8C0035FD6FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8C0035FD6
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0x3F80
+ size: 24
+ offset: 0x3F80
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0xC
+ reserved3: 0x0
+ content: 100000B0100240F900021FD6100000B0100640F900021FD6
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0x3F98
+ size: 15
+ offset: 0x3F98
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D2044210A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000503F00004000000040000000803F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 16
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x2
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '00000000000010800100000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 656
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libD.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32864
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32896
+ nsyms: 4
+ stroff: 32976
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 1
+ iextdefsym: 1
+ nextdefsym: 1
+ iundefsym: 2
+ nundefsym: 2
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 32960
+ nindirectsyms: 4
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 5898A6CE-0F78-3CA2-8F7D-B1AAAF26C49F
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../A'
+ ZeroPadBytes: 3
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32896
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 33008
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayD
+ Flags: 0x0
+ Address: 0x3F64
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 22
+ n_type: 0xE
+ n_sect: 1
+ n_desc: 0
+ n_value: 16208
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16228
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 512
+ n_value: 0
+ - n_strx: 16
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayD
+ - _printf
+ - _sayA
+ - _keepSayA
+ IndirectSymbols: [ 0x2, 0x3, 0x2, 0x3 ]
+ FunctionStarts: [ 0x3F50, 0x3F64 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x2, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x2, 0x0,
+ 0x0, 0x1, 0x12, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x5F, 0x73, 0x61,
+ 0x79, 0x41, 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x80000002
+ filetype: 0x6
+ ncmds: 17
+ sizeofcmds: 1056
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F40
+ size: 56
+ offset: 0x3F40
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 7F2303D5FD7BBFA9FD0300910F000094FD7BC1A8FF0F5FD67F2303D5FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8FF0F5FD6
+ - sectname: __auth_stubs
+ segname: __TEXT
+ addr: 0x3F78
+ size: 32
+ offset: 0x3F78
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x10
+ reserved3: 0x0
+ content: 110000B031020091300240F9110A1FD7110000B031220091300240F9110A1FD7
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0x3F98
+ size: 15
+ offset: 0x3F98
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D2044210A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000403F00004000000040000000783F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __auth_got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 16
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x2
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00000000000009C001000000000001C0
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 656
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libD.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32864
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32896
+ nsyms: 4
+ stroff: 32976
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 1
+ iextdefsym: 1
+ nextdefsym: 1
+ iundefsym: 2
+ nundefsym: 2
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 32960
+ nindirectsyms: 4
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 81A288C4-6F51-3913-9330-EDE155D1DD35
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libA.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_RPATH
+ cmdsize: 32
+ path: 12
+ Content: '@loader_path/../A'
+ ZeroPadBytes: 3
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32896
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 33008
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayD
+ Flags: 0x0
+ Address: 0x3F58
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 22
+ n_type: 0xE
+ n_sect: 1
+ n_desc: 0
+ n_value: 16192
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16216
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 512
+ n_value: 0
+ - n_strx: 16
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayD
+ - _printf
+ - _sayA
+ - _keepSayA
+ IndirectSymbols: [ 0x2, 0x3, 0x2, 0x3 ]
+ FunctionStarts: [ 0x3F40, 0x3F58 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x2, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x2, 0x0,
+ 0x0, 0x1, 0x12, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x5F, 0x73, 0x61,
+ 0x79, 0x41, 0x0, 0x0 ]
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_linux.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_linux.yaml
new file mode 100644
index 0000000000000..5561f29a93602
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_linux.yaml
@@ -0,0 +1,460 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_DYN
+ Machine: EM_X86_64
+ProgramHeaders:
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .rela.plt
+ Align: 0x1000
+ Offset: 0x0
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .init
+ LastSec: .fini
+ VAddr: 0x1000
+ Align: 0x1000
+ Offset: 0x1000
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .rodata
+ LastSec: .eh_frame
+ VAddr: 0x2000
+ Align: 0x1000
+ Offset: 0x2000
+ - Type: PT_LOAD
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .init_array
+ LastSec: .bss
+ VAddr: 0x3E10
+ Align: 0x1000
+ Offset: 0x2E10
+ - Type: PT_DYNAMIC
+ Flags: [ PF_W, PF_R ]
+ FirstSec: .dynamic
+ LastSec: .dynamic
+ VAddr: 0x3E20
+ Align: 0x8
+ Offset: 0x2E20
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_NOTE
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.build-id
+ LastSec: .note.gnu.build-id
+ VAddr: 0x2C8
+ Align: 0x4
+ Offset: 0x2C8
+ - Type: PT_GNU_PROPERTY
+ Flags: [ PF_R ]
+ FirstSec: .note.gnu.property
+ LastSec: .note.gnu.property
+ VAddr: 0x2A8
+ Align: 0x8
+ Offset: 0x2A8
+ - Type: PT_GNU_EH_FRAME
+ Flags: [ PF_R ]
+ FirstSec: .eh_frame_hdr
+ LastSec: .eh_frame_hdr
+ VAddr: 0x2010
+ Align: 0x4
+ Offset: 0x2010
+ - Type: PT_GNU_STACK
+ Flags: [ PF_W, PF_R ]
+ Align: 0x10
+ Offset: 0x0
+ - Type: PT_GNU_RELRO
+ Flags: [ PF_R ]
+ FirstSec: .init_array
+ LastSec: .got
+ VAddr: 0x3E10
+ Offset: 0x2E10
+Sections:
+ - Name: .note.gnu.property
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2A8
+ AddressAlign: 0x8
+ Notes:
+ - Name: GNU
+ Desc: 020000C0040000000300000000000000
+ Type: NT_GNU_PROPERTY_TYPE_0
+ - Name: .note.gnu.build-id
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2C8
+ AddressAlign: 0x4
+ Notes:
+ - Name: GNU
+ Desc: 640A4A3AC0DF6BA3DAC3B51CCD727245117E0B30
+ Type: NT_PRPSINFO
+ - Name: .gnu.hash
+ Type: SHT_GNU_HASH
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2F0
+ Link: .dynsym
+ AddressAlign: 0x8
+ Header:
+ SymNdx: 0x6
+ Shift2: 0x6
+ BloomFilter: [ 0x500000000000 ]
+ HashBuckets: [ 0x6, 0x0 ]
+ HashValues: [ 0x7C9DCBAD ]
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ Flags: [ SHF_ALLOC ]
+ Address: 0x318
+ Link: .dynstr
+ AddressAlign: 0x8
+ - Name: .dynstr
+ Type: SHT_STRTAB
+ Flags: [ SHF_ALLOC ]
+ Address: 0x3C0
+ AddressAlign: 0x1
+ - Name: .gnu.version
+ Type: SHT_GNU_versym
+ Flags: [ SHF_ALLOC ]
+ Address: 0x436
+ Link: .dynsym
+ AddressAlign: 0x2
+ Entries: [ 0, 1, 2, 1, 1, 2, 1 ]
+ - Name: .gnu.version_r
+ Type: SHT_GNU_verneed
+ Flags: [ SHF_ALLOC ]
+ Address: 0x448
+ Link: .dynstr
+ AddressAlign: 0x8
+ Dependencies:
+ - Version: 1
+ File: libc.so.6
+ Entries:
+ - Name: GLIBC_2.2.5
+ Hash: 157882997
+ Flags: 0
+ Other: 2
+ - Name: .rela.dyn
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC ]
+ Address: 0x468
+ Link: .dynsym
+ AddressAlign: 0x8
+ Relocations:
+ - Offset: 0x3E10
+ Type: R_X86_64_RELATIVE
+ Addend: 4368
+ - Offset: 0x3E18
+ Type: R_X86_64_RELATIVE
+ Addend: 4304
+ - Offset: 0x4020
+ Type: R_X86_64_RELATIVE
+ Addend: 16416
+ - Offset: 0x3FE0
+ Symbol: _ITM_deregisterTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FE8
+ Symbol: __gmon_start__
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF0
+ Symbol: _ITM_registerTMCloneTable
+ Type: R_X86_64_GLOB_DAT
+ - Offset: 0x3FF8
+ Symbol: __cxa_finalize
+ Type: R_X86_64_GLOB_DAT
+ - Name: .rela.plt
+ Type: SHT_RELA
+ Flags: [ SHF_ALLOC, SHF_INFO_LINK ]
+ Address: 0x510
+ Link: .dynsym
+ AddressAlign: 0x8
+ Info: .got.plt
+ Relocations:
+ - Offset: 0x4018
+ Symbol: puts
+ Type: R_X86_64_JUMP_SLOT
+ - Name: .init
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1000
+ AddressAlign: 0x4
+ Offset: 0x1000
+ Content: F30F1EFA4883EC08488B05D92F00004885C07402FFD04883C408C3
+ - Name: .plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1020
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: FF35E22F0000F2FF25E32F00000F1F00F30F1EFA6800000000F2E9E1FFFFFF90
+ - Name: .plt.got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1040
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF25AD2F00000F1F440000
+ - Name: .plt.sec
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1050
+ AddressAlign: 0x10
+ EntSize: 0x10
+ Content: F30F1EFAF2FF25BD2F00000F1F440000
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1060
+ AddressAlign: 0x10
+ Content: 488D3DC12F0000488D05BA2F00004839F87415488B05662F00004885C07409FFE00F1F8000000000C30F1F8000000000488D3D912F0000488D358A2F00004829FE4889F048C1EE3F48C1F8034801C648D1FE7414488B05352F00004885C07408FFE0660F1F440000C30F1F8000000000F30F1EFA803D4D2F000000752B5548833D122F0000004889E5740C488B3D2E2F0000E849FFFFFFE864FFFFFFC605252F0000015DC30F1F00C30F1F8000000000F30F1EFAE977FFFFFFF30F1EFA554889E5488D05D80E00004889C7E820FFFFFF905DC3
+ - Name: .fini
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x1134
+ AddressAlign: 0x4
+ Content: F30F1EFA4883EC084883C408C3
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2000
+ AddressAlign: 0x1
+ Offset: 0x2000
+ Content: 48656C6C6F2066726F6D205A00
+ - Name: .eh_frame_hdr
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2010
+ AddressAlign: 0x4
+ Content: 011B033B2C0000000400000010F0FFFF4800000030F0FFFF7000000040F0FFFF8800000009F1FFFFA0000000
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x2040
+ AddressAlign: 0x8
+ Content: 1400000000000000017A5200017810011B0C070890010000240000001C000000C0EFFFFF20000000000E10460E184A0F0B770880003F1A3A2A332422000000001400000044000000B8EFFFFF100000000000000000000000140000005C000000B0EFFFFF1000000000000000000000001C0000007400000061F0FFFF1A00000000450E108602430D06510C070800000000000000
+ - Name: .init_array
+ Type: SHT_INIT_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E10
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Offset: 0x2E10
+ Content: '1011000000000000'
+ - Name: .fini_array
+ Type: SHT_FINI_ARRAY
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E18
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: D010000000000000
+ - Name: .dynamic
+ Type: SHT_DYNAMIC
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3E20
+ Link: .dynstr
+ AddressAlign: 0x8
+ Entries:
+ - Tag: DT_NEEDED
+ Value: 0x5F
+ - Tag: DT_INIT
+ Value: 0x1000
+ - Tag: DT_FINI
+ Value: 0x1134
+ - Tag: DT_INIT_ARRAY
+ Value: 0x3E10
+ - Tag: DT_INIT_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_FINI_ARRAY
+ Value: 0x3E18
+ - Tag: DT_FINI_ARRAYSZ
+ Value: 0x8
+ - Tag: DT_GNU_HASH
+ Value: 0x2F0
+ - Tag: DT_STRTAB
+ Value: 0x3C0
+ - Tag: DT_SYMTAB
+ Value: 0x318
+ - Tag: DT_STRSZ
+ Value: 0x75
+ - Tag: DT_SYMENT
+ Value: 0x18
+ - Tag: DT_PLTGOT
+ Value: 0x4000
+ - Tag: DT_PLTRELSZ
+ Value: 0x18
+ - Tag: DT_PLTREL
+ Value: 0x7
+ - Tag: DT_JMPREL
+ Value: 0x510
+ - Tag: DT_RELA
+ Value: 0x468
+ - Tag: DT_RELASZ
+ Value: 0xA8
+ - Tag: DT_RELAENT
+ Value: 0x18
+ - Tag: DT_VERNEED
+ Value: 0x448
+ - Tag: DT_VERNEEDNUM
+ Value: 0x1
+ - Tag: DT_VERSYM
+ Value: 0x436
+ - Tag: DT_RELACOUNT
+ Value: 0x3
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Tag: DT_NULL
+ Value: 0x0
+ - Name: .got
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x3FE0
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '0000000000000000000000000000000000000000000000000000000000000000'
+ - Name: .got.plt
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4000
+ AddressAlign: 0x8
+ EntSize: 0x8
+ Content: '203E000000000000000000000000000000000000000000003010000000000000'
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4020
+ AddressAlign: 0x8
+ Content: '2040000000000000'
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x4028
+ AddressAlign: 0x1
+ Size: 0x8
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 4743433A20285562756E74752031312E342E302D317562756E7475317E32322E30342E32292031312E342E3000
+Symbols:
+ - Name: crtstuff.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: deregister_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1060
+ - Name: register_tm_clones
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1090
+ - Name: __do_global_dtors_aux
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x10D0
+ - Name: completed.0
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x4028
+ Size: 0x1
+ - Name: __do_global_dtors_aux_fini_array_entry
+ Type: STT_OBJECT
+ Section: .fini_array
+ Value: 0x3E18
+ - Name: frame_dummy
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1110
+ - Name: __frame_dummy_init_array_entry
+ Type: STT_OBJECT
+ Section: .init_array
+ Value: 0x3E10
+ - Name: libZ.c
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: 'crtstuff.c (1)'
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: __FRAME_END__
+ Type: STT_OBJECT
+ Section: .eh_frame
+ Value: 0x20D0
+ - Type: STT_FILE
+ Index: SHN_ABS
+ - Name: _fini
+ Type: STT_FUNC
+ Section: .fini
+ Value: 0x1134
+ - Name: __dso_handle
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4020
+ - Name: _DYNAMIC
+ Type: STT_OBJECT
+ Section: .dynamic
+ Value: 0x3E20
+ - Name: __GNU_EH_FRAME_HDR
+ Section: .eh_frame_hdr
+ Value: 0x2010
+ - Name: __TMC_END__
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x4028
+ - Name: _GLOBAL_OFFSET_TABLE_
+ Type: STT_OBJECT
+ Section: .got.plt
+ Value: 0x4000
+ - Name: _init
+ Type: STT_FUNC
+ Section: .init
+ Value: 0x1000
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: 'puts at GLIBC_2.2.5'
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: sayZ
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1119
+ Size: 0x1A
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: '__cxa_finalize at GLIBC_2.2.5'
+ Type: STT_FUNC
+ Binding: STB_WEAK
+DynamicSymbols:
+ - Name: _ITM_deregisterTMCloneTable
+ Binding: STB_WEAK
+ - Name: puts
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ - Name: __gmon_start__
+ Binding: STB_WEAK
+ - Name: _ITM_registerTMCloneTable
+ Binding: STB_WEAK
+ - Name: __cxa_finalize
+ Type: STT_FUNC
+ Binding: STB_WEAK
+ - Name: sayZ
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x1119
+ Size: 0x1A
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_macho.yaml b/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_macho.yaml
new file mode 100644
index 0000000000000..c0c18265ab667
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/Inputs/Z/Z_macho.yaml
@@ -0,0 +1,723 @@
+--- !fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 3
+FatArchs:
+ - cputype: 0x1000007
+ cpusubtype: 0x3
+ offset: 0x1000
+ size: 8376
+ align: 12
+ - cputype: 0x100000C
+ cpusubtype: 0x0
+ offset: 0x4000
+ size: 33376
+ align: 14
+ - cputype: 0x100000C
+ cpusubtype: 0x80000002
+ offset: 0x10000
+ size: 33376
+ align: 14
+Slices:
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x1000007
+ cpusubtype: 0x3
+ filetype: 0x6
+ ncmds: 14
+ sizeofcmds: 960
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4096
+ fileoff: 0
+ filesize: 4096
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0xF80
+ size: 20
+ offset: 0xF80
+ align: 4
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 554889E5488D3D0F000000B000E8020000005DC3
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0xF94
+ size: 6
+ offset: 0xF94
+ align: 1
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x6
+ reserved3: 0x0
+ content: FF2566000000
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0xF9A
+ size: 14
+ offset: 0xF9A
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D205A0A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0xFA8
+ size: 88
+ offset: 0xFA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000800F00004000000040000000940F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000100000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 4096
+ vmsize: 4096
+ fileoff: 4096
+ filesize: 4096
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x1000
+ size: 8
+ offset: 0x1000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 8192
+ vmsize: 4096
+ fileoff: 8192
+ filesize: 184
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libZ.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 8192
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 8288
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 8320
+ nsyms: 2
+ stroff: 8360
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 8352
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 399E203C-FF9A-3B80-872C-85F3A759A78B
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 8312
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 8320
+ datasize: 0
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayZ
+ Flags: 0x0
+ Address: 0xF80
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 3968
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayZ
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0xF80 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x10, 0x6, 0x0,
+ 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x6
+ ncmds: 15
+ sizeofcmds: 976
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F70
+ size: 28
+ offset: 0x3F70
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8C0035FD6
+ - sectname: __stubs
+ segname: __TEXT
+ addr: 0x3F8C
+ size: 12
+ offset: 0x3F8C
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0xC
+ reserved3: 0x0
+ content: 100000B0100240F900021FD6
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0x3F98
+ size: 14
+ offset: 0x3F98
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D205A0A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000703F000040000000400000008C3F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 8
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000000000080'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 608
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libZ.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32864
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32896
+ nsyms: 2
+ stroff: 32936
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 32928
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 6E8E78AF-EDB2-3830-BE1E-013390302CC5
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32896
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 32960
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayZ
+ Flags: 0x0
+ Address: 0x3F70
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16240
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayZ
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0x3F70 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0x6, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x80000002
+ filetype: 0x6
+ ncmds: 15
+ sizeofcmds: 976
+ flags: 0x100085
+ reserved: 0x0
+ LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 392
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 4
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x3F68
+ size: 32
+ offset: 0x3F68
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 7F2303D5FD7BBFA9FD0300910000009000603E9103000094FD7BC1A8FF0F5FD6
+ - sectname: __auth_stubs
+ segname: __TEXT
+ addr: 0x3F88
+ size: 16
+ offset: 0x3F88
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000408
+ reserved1: 0x0
+ reserved2: 0x10
+ reserved3: 0x0
+ content: 110000B031020091300240F9110A1FD7
+ - sectname: __cstring
+ segname: __TEXT
+ addr: 0x3F98
+ size: 14
+ offset: 0x3F98
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x2
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 48656C6C6F2066726F6D205A0A00
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x3FA8
+ size: 88
+ offset: 0x3FA8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000683F00004000000040000000883F00000000000040000000000000000000000000000000030000000C00010010000100000000000000000400000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 16384
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __auth_got
+ segname: __DATA_CONST
+ addr: 0x4000
+ size: 8
+ offset: 0x4000
+ align: 3
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x6
+ reserved1: 0x1
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 00000000000001C0
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 16384
+ fileoff: 32768
+ filesize: 608
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 1
+ current_version: 0
+ compatibility_version: 0
+ Content: '@rpath/libZ.dylib'
+ ZeroPadBytes: 7
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 32768
+ datasize: 96
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 32864
+ datasize: 24
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 32896
+ nsyms: 2
+ stroff: 32936
+ strsize: 16
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 32928
+ nindirectsyms: 2
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: E74F368D-238F-31FA-BF40-FA2964FED986
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 983040
+ sdk: 983552
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 73074435
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 32888
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 32896
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 32960
+ datasize: 416
+ LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 13
+ Name: _sayZ
+ Flags: 0x0
+ Address: 0x3F68
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 16232
+ - n_strx: 8
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - _sayZ
+ - _printf
+ IndirectSymbols: [ 0x1, 0x1 ]
+ FunctionStarts: [ 0x3F68 ]
+ ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x48,
+ 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x1, 0x0,
+ 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x40, 0xC, 0x0,
+ 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x2, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5F, 0x70, 0x72,
+ 0x69, 0x6E, 0x74, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0 ]
+...
diff --git a/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp
new file mode 100644
index 0000000000000..637621311e65a
--- /dev/null
+++ b/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp
@@ -0,0 +1,886 @@
+//===- LibraryResolverTest.cpp - Unit tests for LibraryResolver -===//
+//
+// 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/TargetProcess/LibraryResolver.h"
+#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
+#include "llvm/ExecutionEngine/Orc/TargetProcess/LibraryScanner.h"
+#include "llvm/ObjectYAML/MachOYAML.h"
+#include "llvm/ObjectYAML/yaml2obj.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "llvm/Testing/Support/SupportHelpers.h"
+
+#include "gtest/gtest.h"
+
+#include <algorithm>
+#include <optional>
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::orc;
+
+#if defined(__APPLE__) || defined(__linux__)
+// TODO: Add COFF (Windows) support for these tests.
+// this facility also works correctly on Windows (COFF),
+// so we should eventually enable and run these tests for that platform as well.
+namespace {
+
+#if defined(__APPLE__)
+constexpr const char *ext = ".dylib";
+#elif defined(_WIN32)
+constexpr const char *ext = ".dll";
+#else
+constexpr const char *ext = ".so";
+#endif
+
+bool EnvReady = false;
+
+Triple getTargetTriple() {
+ auto JTMB = JITTargetMachineBuilder::detectHost();
+ if (!JTMB) {
+ consumeError(JTMB.takeError());
+ return Triple();
+ }
+ return JTMB->getTargetTriple();
+}
+
+static bool CheckHostSupport() {
+ auto Triple = getTargetTriple();
+ // TODO: Extend support to COFF (Windows) once test setup and YAML conversion
+ // are verified.
+ if (!Triple.isOSBinFormatMachO() &&
+ !(Triple.isOSBinFormatELF() && Triple.getArch() == Triple::x86_64))
+ return false;
+
+ return true;
+}
+
+std::string getYamlFilePlatformExt() {
+ auto Triple = getTargetTriple();
+ if (Triple.isOSBinFormatMachO())
+ return "_macho";
+ else if (Triple.isOSBinFormatELF())
+ return "_linux";
+
+ return "";
+}
+
+unsigned getYamlDocNum() {
+ // auto Triple = getTargetTriple();
+ // if (Triple.isOSBinFormatELF())
+ // return 1;
+
+ return 1;
+}
+
+class LibraryTestEnvironment : public ::testing::Environment {
+ std::vector<std::string> CreatedDylibsDir;
+ std::vector<std::string> CreatedDylibs;
+ SmallVector<char, 128> DirPath;
+
+public:
+ void SetUp() override {
+ if (!CheckHostSupport()) {
+ EnvReady = false;
+ return;
+ }
+
+ StringRef ThisFile = __FILE__;
+ SmallVector<char, 128> InputDirPath(ThisFile.begin(), ThisFile.end());
+ sys::path::remove_filename(InputDirPath);
+ sys::path::append(InputDirPath, "Inputs");
+ if (!sys::fs::exists(InputDirPath))
+ return;
+
+ SmallString<128> UniqueDir;
+ sys::path::append(UniqueDir, InputDirPath);
+ std::error_code EC = sys::fs::createUniqueDirectory(UniqueDir, DirPath);
+
+ if (EC)
+ return;
+
+ // given yamlPath + DylibPath, validate + convert
+ auto processYamlToDylib = [&](const SmallVector<char, 128> &YamlPath,
+ const SmallVector<char, 128> &DylibPath,
+ unsigned DocNum) -> bool {
+ if (!sys::fs::exists(YamlPath)) {
+ errs() << "YAML file missing: "
+ << StringRef(YamlPath.data(), YamlPath.size()) << "\n";
+ EnvReady = false;
+ return false;
+ }
+
+ auto BufOrErr = MemoryBuffer::getFile(YamlPath);
+ if (!BufOrErr) {
+ errs() << "Failed to read "
+ << StringRef(YamlPath.data(), YamlPath.size()) << ": "
+ << BufOrErr.getError().message() << "\n";
+ EnvReady = false;
+ return false;
+ }
+
+ yaml::Input yin(BufOrErr->get()->getBuffer());
+ std::error_code EC;
+ raw_fd_ostream outFile(StringRef(DylibPath.data(), DylibPath.size()), EC,
+ sys::fs::OF_None);
+
+ if (EC) {
+ errs() << "Failed to open "
+ << StringRef(DylibPath.data(), DylibPath.size())
+ << " for writing: " << EC.message() << "\n";
+ EnvReady = false;
+ return false;
+ }
+
+ if (!yaml::convertYAML(
+ yin, outFile,
+ [](const Twine &M) {
+ // Handle or ignore errors here
+ errs() << "Yaml Error :" << M << "\n";
+ },
+ DocNum)) {
+ errs() << "Failed to convert "
+ << StringRef(YamlPath.data(), YamlPath.size()) << " to "
+ << StringRef(DylibPath.data(), DylibPath.size()) << "\n";
+ EnvReady = false;
+ return false;
+ }
+
+ CreatedDylibsDir.push_back(std::string(sys::path::parent_path(
+ StringRef(DylibPath.data(), DylibPath.size()))));
+ CreatedDylibs.push_back(std::string(DylibPath.begin(), DylibPath.end()));
+ return true;
+ };
+
+ std::vector<const char *> LibDirs = {"Z", "A", "B", "C", "D"};
+
+ unsigned DocNum = getYamlDocNum();
+ std::string YamlPltExt = getYamlFilePlatformExt();
+ for (const auto &LibdirName : LibDirs) {
+ // YAML path
+ SmallVector<char, 128> YamlPath(InputDirPath.begin(), InputDirPath.end());
+ SmallVector<char, 128> YamlFileName;
+ YamlFileName.append(LibdirName, LibdirName + strlen(LibdirName));
+ YamlFileName.append(YamlPltExt.begin(), YamlPltExt.end());
+ sys::path::append(YamlPath, LibdirName, YamlFileName);
+ sys::path::replace_extension(YamlPath, ".yaml");
+
+ // dylib path
+ SmallVector<char, 128> DylibPath(DirPath.begin(), DirPath.end());
+ SmallVector<char, 128> DylibFileName;
+ StringRef prefix("lib");
+ DylibFileName.append(prefix.begin(), prefix.end());
+ DylibFileName.append(LibdirName, LibdirName + strlen(LibdirName));
+
+ sys::path::append(DylibPath, LibdirName);
+ if (!sys::fs::exists(DylibPath)) {
+ auto EC = sys::fs::create_directory(DylibPath);
+ if (EC)
+ return;
+ }
+ sys::path::append(DylibPath, DylibFileName);
+ sys::path::replace_extension(DylibPath, ext);
+ if (!processYamlToDylib(YamlPath, DylibPath, DocNum))
+ return;
+ }
+
+ EnvReady = true;
+ }
+
+ void TearDown() override { sys::fs::remove_directories(DirPath); }
+
+ std::string getBaseDir() const {
+ return std::string(DirPath.begin(), DirPath.end());
+ }
+
+ std::vector<std::string> getDylibPaths() const { return CreatedDylibs; }
+};
+
+static LibraryTestEnvironment *GlobalEnv =
+ static_cast<LibraryTestEnvironment *>(
+ ::testing::AddGlobalTestEnvironment(new LibraryTestEnvironment()));
+
+inline std::string libPath(const std::string &BaseDir,
+ const std::string &name) {
+#if defined(__APPLE__)
+ return BaseDir + "/" + name + ".dylib";
+#elif defined(_WIN32)
+ return BaseDir + "/" + name + ".dll";
+#else
+ return BaseDir + "/" + name + ".so";
+#endif
+}
+
+inline std::string withext(const std::string &lib) {
+ SmallString<128> P(lib);
+ sys::path::replace_extension(P, ext);
+ return P.str().str();
+}
+
+inline std::string platformSymbolName(const std::string &name) {
+#if defined(__APPLE__)
+ return "_" + name; // macOS prepends underscore
+#else
+ return name;
+#endif
+}
+
+struct TestLibrary {
+ std::string path;
+ std::vector<std::string> Syms;
+};
+
+class LibraryResolverIT : public ::testing::Test {
+protected:
+ std::string BaseDir;
+ std::unordered_map<std::string, TestLibrary> libs;
+ void SetUp() override {
+ if (!EnvReady)
+ GTEST_SKIP() << "Skipping test: environment setup failed.";
+
+ ASSERT_NE(GlobalEnv, nullptr);
+ BaseDir = GlobalEnv->getBaseDir();
+ libs["A"] = {libPath(BaseDir, "A/libA"), {platformSymbolName("sayA")}};
+ libs["B"] = {libPath(BaseDir, "B/libB"), {platformSymbolName("sayB")}};
+ libs["C"] = {libPath(BaseDir, "C/libC"), {platformSymbolName("sayC")}};
+ libs["D"] = {libPath(BaseDir, "D/libD"), {platformSymbolName("sayD")}};
+ libs["Z"] = {libPath(BaseDir, "Z/libZ"), {platformSymbolName("sayZ")}};
+ for (const auto &P : GlobalEnv->getDylibPaths()) {
+ if (!sys::fs::exists(P))
+ GTEST_SKIP();
+ }
+ }
+
+ const std::vector<std::string> &sym(const std::string &key) {
+ return libs[key].Syms;
+ }
+ const std::string &lib(const std::string &key) { return libs[key].path; }
+ const std::string libdir(const std::string &key) {
+ SmallString<512> P(libs[key].path);
+ sys::path::remove_filename(P);
+ return P.str().str();
+ }
+ const std::string libname(const std::string &key) {
+ return sys::path::filename(libs[key].path).str();
+ }
+};
+
+// Helper: allow either "sayA" or "_sayA" depending on how your SymbolEnumerator
+// reports.
+static bool matchesEitherUnderscore(const std::string &got,
+ const std::string &bare) {
+ return got == bare || got == ("_" + bare);
+}
+
+// Helper: normalize path ending check (we only care that it resolved to the
+// right dylib)
+static bool endsWith(const std::string &s, const std::string &suffix) {
+ if (s.size() < suffix.size())
+ return false;
+ return std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
+}
+
+// --- 1) SymbolEnumerator enumerates real exports from libC.dylib ---
+TEST_F(LibraryResolverIT, EnumerateSymbolsFromARespectsDefaults) {
+ const std::string libC = lib("C");
+
+ SymbolEnumeratorOptions Opts = SymbolEnumeratorOptions::defaultOptions();
+
+ std::vector<std::string> seen;
+ auto onEach = [&](llvm::StringRef sym) -> EnumerateResult {
+ seen.emplace_back(sym.str());
+ return EnumerateResult::Continue;
+ };
+
+ const bool ok = SymbolEnumerator::enumerateSymbols(libC, onEach, Opts);
+ ASSERT_TRUE(ok) << "enumerateSymbols failed on " << libC;
+
+ // We expect to see sayA (export) and not an undefined reference to printf.
+ bool foundSayA = false;
+ for (const auto &s : seen) {
+ if (matchesEitherUnderscore(s, "sayA")) {
+ foundSayA = true;
+ break;
+ }
+ }
+ EXPECT_FALSE(foundSayA) << "Expected exported symbol sayA in libC";
+}
+
+TEST_F(LibraryResolverIT, EnumerateSymbols_ExportsOnly_DefaultFlags) {
+ const std::string libC = lib("C");
+ SymbolEnumeratorOptions Opts = SymbolEnumeratorOptions::defaultOptions();
+
+ std::vector<std::string> seen;
+ auto onEach = [&](llvm::StringRef sym) -> EnumerateResult {
+ seen.emplace_back(sym.str());
+ return EnumerateResult::Continue;
+ };
+
+ ASSERT_TRUE(SymbolEnumerator::enumerateSymbols(libC, onEach, Opts));
+
+ // sayC is exported, others are undefined → only sayC expected
+ EXPECT_TRUE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayC");
+ }));
+ EXPECT_FALSE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayA");
+ }));
+ EXPECT_FALSE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayB");
+ }));
+ EXPECT_FALSE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayZ");
+ }));
+}
+
+TEST_F(LibraryResolverIT, EnumerateSymbols_IncludesUndefineds) {
+ const std::string libC = lib("C");
+
+ SymbolEnumeratorOptions Opts;
+ Opts.FilterFlags =
+ SymbolEnumeratorOptions::IgnoreWeak |
+ SymbolEnumeratorOptions::IgnoreIndirect; // no IgnoreUndefined
+
+ std::vector<std::string> seen;
+ auto onEach = [&](llvm::StringRef sym) -> EnumerateResult {
+ seen.emplace_back(sym.str());
+ return EnumerateResult::Continue;
+ };
+
+ ASSERT_TRUE(SymbolEnumerator::enumerateSymbols(libC, onEach, Opts));
+
+ // Now we should see both sayC (export) and the undefined refs sayA, sayB,
+ // sayZ
+ EXPECT_TRUE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayC");
+ }));
+ EXPECT_TRUE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayA");
+ }));
+ EXPECT_TRUE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayB");
+ }));
+ EXPECT_TRUE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayZ");
+ }));
+}
+
+TEST_F(LibraryResolverIT, EnumerateSymbols_IndirectExportRespected) {
+ const std::string libD = lib("D");
+
+ SymbolEnumeratorOptions Opts;
+ Opts.FilterFlags = SymbolEnumeratorOptions::IgnoreWeak; // allow indirects
+
+ std::vector<std::string> seen;
+ auto onEach = [&](llvm::StringRef sym) -> EnumerateResult {
+ seen.emplace_back(sym.str());
+ return EnumerateResult::Continue;
+ };
+
+ ASSERT_TRUE(SymbolEnumerator::enumerateSymbols(libD, onEach, Opts));
+
+ // sayA is re-exported from A, so should appear unless IgnoreIndirect was set
+ EXPECT_TRUE(any_of(seen, [&](const std::string &s) {
+ return matchesEitherUnderscore(s, "sayA");
+ }));
+}
+
+// --- 2) Filters: if we remove IgnoreUndefined, we should also see undefineds
+// like printf ---
+TEST_F(LibraryResolverIT, EnumerateSymbolsIncludesUndefWhenNotIgnored) {
+ const std::string libA = lib("A");
+
+ SymbolEnumeratorOptions Opts = SymbolEnumeratorOptions::defaultOptions();
+ // Start from defaults but allow undefined
+ Opts.FilterFlags &= ~SymbolEnumeratorOptions::IgnoreUndefined;
+
+ bool SawPrintf = false;
+ auto onEach = [&](llvm::StringRef sym) -> EnumerateResult {
+ if (matchesEitherUnderscore(sym.str(), "printf") ||
+ matchesEitherUnderscore(sym.str(), "puts"))
+ SawPrintf = true;
+ return EnumerateResult::Continue;
+ };
+
+ ASSERT_TRUE(SymbolEnumerator::enumerateSymbols(libA, onEach, Opts));
+ EXPECT_TRUE(SawPrintf)
+ << "Expected to see undefined symbol printf when not filtered";
+}
+
+// --- 3) Full resolution via LibraryResolutionDriver/LibraryResolver ---
+TEST_F(LibraryResolverIT, DriverResolvesSymbolsToCorrectLibraries) {
+ // Create the resolver from real base paths (our fixtures dir)
+ auto Stup = LibraryResolver::Setup::create({BaseDir});
+
+ // Full system behavior: no mocks
+ auto Driver = LibraryResolutionDriver::create(Stup);
+ ASSERT_NE(Driver, nullptr);
+
+ // Tell the Driver about the scan path kinds (User/System) as your production
+ // code expects.
+ Driver->addScanPath(libdir("A"), PathType::User);
+ Driver->addScanPath(libdir("B"), PathType::User);
+ Driver->addScanPath(libdir("Z"), PathType::User);
+
+ // Symbols to resolve (bare names; class handles underscore differences
+ // internally)
+ std::vector<std::string> Syms = {platformSymbolName("sayA"),
+ platformSymbolName("sayB"),
+ platformSymbolName("sayZ")};
+
+ bool CallbackRan = false;
+ Driver->resolveSymbols(Syms, [&](SymbolQuery &Q) {
+ CallbackRan = true;
+
+ // sayA should resolve to A.dylib
+ {
+ auto lib = Q.getResolvedLib(platformSymbolName("sayA"));
+ ASSERT_TRUE(lib.has_value()) << "sayA should be resolved";
+ EXPECT_TRUE(endsWith(lib->str(), libname("A")))
+ << "sayA resolved to: " << lib->str();
+ }
+
+ // sayB should resolve to B.dylib
+ {
+ auto lib = Q.getResolvedLib(platformSymbolName("sayB"));
+ ASSERT_TRUE(lib.has_value()) << "sayB should be resolved";
+ EXPECT_TRUE(endsWith(lib->str(), libname("B")))
+ << "sayB resolved to: " << lib->str();
+ }
+
+ // sayZ should resolve to B.dylib
+ {
+ auto lib = Q.getResolvedLib(platformSymbolName("sayZ"));
+ ASSERT_TRUE(lib.has_value()) << "sayZ should be resolved";
+ EXPECT_TRUE(endsWith(lib->str(), libname("Z")))
+ << "sayZ resolved to: " << lib->str();
+ }
+
+ EXPECT_TRUE(Q.allResolved());
+ });
+
+ EXPECT_TRUE(CallbackRan);
+}
+
+// --- 4) Cross-library reference visibility (C references A) ---
+TEST_F(LibraryResolverIT, EnumeratorSeesInterLibraryRelationship) {
+ const std::string libC = lib("C");
+
+ SymbolEnumeratorOptions OnlyUndef = SymbolEnumeratorOptions::defaultOptions();
+ // Show only undefined (drop IgnoreUndefined) to see C's reference to sayA
+ OnlyUndef.FilterFlags &= ~SymbolEnumeratorOptions::IgnoreUndefined;
+
+ bool SawSayAAsUndef = false;
+ auto onEach = [&](llvm::StringRef sym) -> EnumerateResult {
+ if (matchesEitherUnderscore(sym.str(), "sayA"))
+ SawSayAAsUndef = true;
+ return EnumerateResult::Continue;
+ };
+
+ ASSERT_TRUE(SymbolEnumerator::enumerateSymbols(libC, onEach, OnlyUndef));
+ EXPECT_TRUE(SawSayAAsUndef)
+ << "libC should have an undefined reference to sayA (defined in libA)";
+}
+
+// // // --- 5) Optional: stress SymbolQuery with the real resolve flow
+// // // And resolve libC dependency libA, libB, libZ ---
+TEST_F(LibraryResolverIT, ResolveManySymbols) {
+ auto Stup = LibraryResolver::Setup::create({BaseDir});
+ auto Driver = LibraryResolutionDriver::create(Stup);
+ ASSERT_NE(Driver, nullptr);
+ Driver->addScanPath(libdir("C"), PathType::User);
+
+ // Many duplicates to provoke concurrent updates inside SymbolQuery
+ std::vector<std::string> Syms = {
+ platformSymbolName("sayA"), platformSymbolName("sayB"),
+ platformSymbolName("sayA"), platformSymbolName("sayB"),
+ platformSymbolName("sayZ"), platformSymbolName("sayZ"),
+ platformSymbolName("sayZ"), platformSymbolName("sayZ"),
+ platformSymbolName("sayA"), platformSymbolName("sayB"),
+ platformSymbolName("sayA"), platformSymbolName("sayB")};
+
+ bool CallbackRan = false;
+ Driver->resolveSymbols(Syms, [&](SymbolQuery &Q) {
+ CallbackRan = true;
+ EXPECT_TRUE(Q.isResolved(platformSymbolName("sayA")));
+ EXPECT_TRUE(Q.isResolved(platformSymbolName("sayB")));
+ EXPECT_TRUE(Q.isResolved(platformSymbolName("sayZ")));
+
+ auto A = Q.getResolvedLib(platformSymbolName("sayA"));
+ auto B = Q.getResolvedLib(platformSymbolName("sayB"));
+ auto Z = Q.getResolvedLib(platformSymbolName("sayZ"));
+ ASSERT_TRUE(A.has_value());
+ ASSERT_TRUE(B.has_value());
+ ASSERT_TRUE(Z.has_value());
+ EXPECT_TRUE(endsWith(A->str(), libname("A")));
+ EXPECT_TRUE(endsWith(B->str(), libname("B")));
+ EXPECT_TRUE(endsWith(Z->str(), libname("Z")));
+ EXPECT_TRUE(Q.allResolved());
+ });
+
+ EXPECT_TRUE(CallbackRan);
+}
+
+// // // --- 5) Optional: stress SymbolQuery with the real resolve flow
+// // // And resolve libD dependency libA ---
+TEST_F(LibraryResolverIT, ResolveManySymbols2) {
+ auto Stup = LibraryResolver::Setup::create({BaseDir});
+ auto Driver = LibraryResolutionDriver::create(Stup);
+ ASSERT_NE(Driver, nullptr);
+ Driver->addScanPath(libdir("D"), PathType::User);
+
+ // Many duplicates to provoke concurrent updates inside SymbolQuery
+ std::vector<std::string> Syms = {
+ platformSymbolName("sayA"), platformSymbolName("sayB"),
+ platformSymbolName("sayA"), platformSymbolName("sayB"),
+ platformSymbolName("sayZ"), platformSymbolName("sayZ"),
+ platformSymbolName("sayZ"), platformSymbolName("sayZ"),
+ platformSymbolName("sayD"), platformSymbolName("sayD"),
+ platformSymbolName("sayA"), platformSymbolName("sayB"),
+ platformSymbolName("sayA"), platformSymbolName("sayB")};
+
+ Driver->resolveSymbols(Syms, [&](SymbolQuery &Q) {
+ EXPECT_TRUE(Q.isResolved(platformSymbolName("sayA")));
+ EXPECT_TRUE(Q.isResolved(platformSymbolName("sayD")));
+
+ auto A = Q.getResolvedLib(platformSymbolName("sayA"));
+ auto D = Q.getResolvedLib(platformSymbolName("sayD"));
+ ASSERT_TRUE(A.has_value());
+ ASSERT_TRUE(D.has_value());
+ EXPECT_TRUE(endsWith(A->str(), libname("A")));
+ EXPECT_TRUE(endsWith(D->str(), libname("D")));
+ EXPECT_FALSE(Q.allResolved());
+ });
+}
+
+TEST_F(LibraryResolverIT, ScanSingleUserPath) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+ LibraryScanHelper ScanH({}, LibPathCache, PResolver);
+
+ ScanH.addBasePath(libdir("C"), PathType::User);
+
+ std::error_code EC;
+ auto libCPathOpt = PResolver->resolve(lib("C"), EC);
+
+ if (!libCPathOpt || EC) {
+ FAIL();
+ }
+
+ std::string libCPath = *libCPathOpt;
+
+ LibraryManager LibMgr;
+ LibraryScanner Scanner(ScanH, LibMgr);
+
+ Scanner.scanNext(PathType::User, 0);
+
+ bool found = false;
+ LibMgr.forEachLibrary([&](const LibraryInfo &lib) {
+ if (lib.getFullPath() == libCPath) {
+ found = true;
+ }
+ return true;
+ });
+ EXPECT_TRUE(found) << "Expected to find " << libCPath;
+}
+
+TEST_F(LibraryResolverIT, ScanAndCheckDeps) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+ LibraryScanHelper ScanH({}, LibPathCache, PResolver);
+
+ ScanH.addBasePath(libdir("C"), PathType::User);
+
+ LibraryManager LibMgr;
+ LibraryScanner Scanner(ScanH, LibMgr);
+
+ Scanner.scanNext(PathType::User, 0);
+
+ size_t count = 0;
+ LibMgr.forEachLibrary([&](const LibraryInfo &) {
+ count++;
+ return true;
+ });
+
+ EXPECT_GE(count, 3u) << "Should find at least libA in multiple paths";
+}
+
+TEST_F(LibraryResolverIT, ScanEmptyPath) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+ LibraryScanHelper ScanH({}, LibPathCache, PResolver);
+
+ ScanH.addBasePath("/tmp/empty", PathType::User);
+
+ LibraryManager LibMgr;
+ LibraryScanner Scanner(ScanH, LibMgr);
+
+ Scanner.scanNext(PathType::User, 0);
+
+ size_t count = 0;
+ LibMgr.forEachLibrary([&](const LibraryInfo &) {
+ count++;
+ return true;
+ });
+ EXPECT_EQ(count, 0u);
+}
+
+TEST_F(LibraryResolverIT, PathResolverResolvesKnownPaths) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+
+ std::error_code EC;
+ auto Missing = PResolver->resolve("temp/foo/bar", EC);
+ EXPECT_FALSE(Missing.has_value()) << "Unexpectedly resolved a bogus path";
+ EXPECT_TRUE(EC) << "Expected error resolving path";
+
+ auto DirPath = PResolver->resolve(BaseDir, EC);
+ ASSERT_TRUE(DirPath.has_value());
+ EXPECT_FALSE(EC) << "Expected no error resolving path";
+ EXPECT_EQ(*DirPath, BaseDir);
+
+ auto DylibPath = PResolver->resolve(lib("C"), EC);
+ ASSERT_TRUE(DylibPath.has_value());
+ EXPECT_FALSE(EC) << "Expected no error resolving path";
+ EXPECT_EQ(*DylibPath, lib("C"));
+}
+
+TEST_F(LibraryResolverIT, PathResolverNormalizesDotAndDotDot) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+
+ std::error_code EC;
+
+ // e.g. BaseDir + "/./C/../C/C.dylib" → BaseDir + "/C.dylib"
+ std::string Messy = BaseDir + "/C/./../C/./libC" + ext;
+ auto Resolved = PResolver->resolve(Messy, EC);
+ ASSERT_TRUE(Resolved.has_value());
+ EXPECT_FALSE(EC);
+ EXPECT_EQ(*Resolved, lib("C")) << "Expected realpath to collapse . and ..";
+}
+
+#if !defined(_WIN32)
+TEST_F(LibraryResolverIT, PathResolverFollowsSymlinks) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+
+ std::error_code EC;
+
+ // Create a symlink temp -> BaseDir (only if filesystem allows it)
+ std::string linkName = BaseDir + withext("/link_to_C");
+ std::string target = lib("C");
+ ::symlink(target.c_str(), linkName.c_str());
+
+ auto resolved = PResolver->resolve(linkName, EC);
+ ASSERT_TRUE(resolved.has_value());
+ EXPECT_FALSE(EC);
+ EXPECT_EQ(*resolved, target);
+
+ ::unlink(linkName.c_str()); // cleanup
+}
+
+TEST_F(LibraryResolverIT, PathResolverCachesResults) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+
+ SmallString<128> TmpDylib;
+ sys::fs::createUniqueFile(withext("A-copy"), TmpDylib);
+ sys::fs::copy_file(lib("A"), TmpDylib);
+
+ std::error_code EC;
+
+ // First resolve -> should populate LibPathCache
+ auto first = PResolver->resolve(TmpDylib, EC);
+ ASSERT_TRUE(first.has_value());
+
+ // Forcefully remove the file from disk
+ ::unlink(TmpDylib.c_str());
+
+ // Second resolve -> should still succeed from LibPathCache
+ auto second = PResolver->resolve(TmpDylib, EC);
+ EXPECT_TRUE(second.has_value());
+ EXPECT_EQ(*second, *first);
+}
+#endif
+
+TEST_F(LibraryResolverIT, LoaderPathSubstitutionAndResolve) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+
+ DylibSubstitutor substitutor;
+ substitutor.configure(libdir("C"));
+#if defined(__APPLE__)
+ // Substitute @loader_path with BaseDir
+ std::string substituted =
+ substitutor.substitute(withext("@loader_path/libC"));
+#elif defined(__linux__)
+ // Substitute $origin with BaseDir
+ std::string substituted = substitutor.substitute(withext("$ORIGIN/libC"));
+#endif
+ ASSERT_FALSE(substituted.empty());
+ EXPECT_EQ(substituted, lib("C"));
+
+ // Now try resolving the substituted path
+ std::error_code EC;
+ auto resolved = PResolver->resolve(substituted, EC);
+ ASSERT_TRUE(resolved.has_value()) << "Expected to resolve substituted dylib";
+ EXPECT_EQ(*resolved, lib("C"));
+ EXPECT_FALSE(EC) << "Expected no error resolving substituted dylib";
+}
+
+TEST_F(LibraryResolverIT, ResolveFromUsrOrSystemPaths) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+
+ DylibPathValidator validator(*PResolver);
+
+ std::vector<std::string> Paths = {"/foo/bar/", "temp/foo", libdir("C"),
+ libdir("A"), libdir("B"), libdir("Z")};
+
+ SmallVector<StringRef> P(Paths.begin(), Paths.end());
+
+ DylibResolver Resolver(validator);
+ Resolver.configure("", {{P, SearchPathType::UsrOrSys}});
+
+ // Check "C"
+ auto ValOptC = Resolver.resolve("libC", true);
+ EXPECT_TRUE(ValOptC.has_value());
+ EXPECT_EQ(*ValOptC, lib("C"));
+
+ auto ValOptCdylib = Resolver.resolve(withext("libC"));
+ EXPECT_TRUE(ValOptCdylib.has_value());
+ EXPECT_EQ(*ValOptCdylib, lib("C"));
+
+ // Check "A"
+ auto ValOptA = Resolver.resolve("libA", true);
+ EXPECT_TRUE(ValOptA.has_value());
+ EXPECT_EQ(*ValOptA, lib("A"));
+
+ auto ValOptAdylib = Resolver.resolve(withext("libA"));
+ EXPECT_TRUE(ValOptAdylib.has_value());
+ EXPECT_EQ(*ValOptAdylib, lib("A"));
+
+ // Check "B"
+ auto ValOptB = Resolver.resolve("libB", true);
+ EXPECT_TRUE(ValOptB.has_value());
+ EXPECT_EQ(*ValOptB, lib("B"));
+
+ auto ValOptBdylib = Resolver.resolve(withext("libB"));
+ EXPECT_TRUE(ValOptBdylib.has_value());
+ EXPECT_EQ(*ValOptBdylib, lib("B"));
+
+ // Check "Z"
+ auto ValOptZ = Resolver.resolve("libZ", true);
+ EXPECT_TRUE(ValOptZ.has_value());
+ EXPECT_EQ(*ValOptZ, lib("Z"));
+
+ auto ValOptZdylib = Resolver.resolve(withext("libZ"));
+ EXPECT_TRUE(ValOptZdylib.has_value());
+ EXPECT_EQ(*ValOptZdylib, lib("Z"));
+}
+
+#if defined(__APPLE__)
+TEST_F(LibraryResolverIT, ResolveViaLoaderPathAndRPathSubstitution) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+
+ DylibPathValidator validator(*PResolver);
+
+ std::vector<std::string> Paths = {"@loader_path/../A", "@loader_path/../B",
+ "@loader_path/../D", "@loader_path/../Z"};
+
+ SmallVector<StringRef> P(Paths.begin(), Paths.end());
+
+ DylibResolver Resolver(validator);
+
+ // Use only RPath config
+ Resolver.configure(lib("C"), {{P, SearchPathType::RPath}});
+
+ // --- Check A ---
+ auto ValOptA = Resolver.resolve("@rpath/libA", true);
+ EXPECT_TRUE(ValOptA.has_value());
+ EXPECT_EQ(*ValOptA, lib("A"));
+
+ auto ValOptAdylib = Resolver.resolve(withext("@rpath/libA"));
+ EXPECT_TRUE(ValOptAdylib.has_value());
+ EXPECT_EQ(*ValOptAdylib, lib("A"));
+
+ // --- Check B ---
+ auto ValOptB = Resolver.resolve("@rpath/libB", true);
+ EXPECT_TRUE(ValOptB.has_value());
+ EXPECT_EQ(*ValOptB, lib("B"));
+
+ auto ValOptBdylib = Resolver.resolve(withext("@rpath/libB"));
+ EXPECT_TRUE(ValOptBdylib.has_value());
+ EXPECT_EQ(*ValOptBdylib, lib("B"));
+
+ // --- Check Z ---
+ auto ValOptZ = Resolver.resolve("@rpath/libZ", true);
+ EXPECT_TRUE(ValOptZ.has_value());
+ EXPECT_EQ(*ValOptZ, lib("Z"));
+
+ auto ValOptZdylib = Resolver.resolve(withext("@rpath/libZ"));
+ EXPECT_TRUE(ValOptZdylib.has_value());
+ EXPECT_EQ(*ValOptZdylib, lib("Z"));
+}
+#endif
+
+#if defined(__linux__)
+TEST_F(LibraryResolverIT, ResolveViaOriginAndRPathSubstitution) {
+ auto LibPathCache = std::make_shared<LibraryPathCache>();
+ auto PResolver = std::make_shared<PathResolver>(LibPathCache);
+
+ DylibPathValidator validator(*PResolver);
+
+ // On Linux, $ORIGIN works like @loader_path
+ std::vector<std::string> Paths = {"$ORIGIN/../A", "$ORIGIN/../B",
+ "$ORIGIN/../D", "$ORIGIN/../Z"};
+
+ SmallVector<StringRef> P(Paths.begin(), Paths.end());
+
+ DylibResolver Resolver(validator);
+
+ // Use only RPath config
+ Resolver.configure(lib("C"), {{P, SearchPathType::RunPath}});
+
+ // --- Check A ---
+ auto ValOptA = Resolver.resolve("libA", true);
+ EXPECT_TRUE(ValOptA.has_value());
+ EXPECT_EQ(*ValOptA, lib("A"));
+
+ auto valOptASO = Resolver.resolve(withext("libA"));
+ EXPECT_TRUE(valOptASO.has_value());
+ EXPECT_EQ(*valOptASO, lib("A"));
+
+ // --- Check B ---
+ auto ValOptB = Resolver.resolve("libB", true);
+ EXPECT_TRUE(ValOptB.has_value());
+ EXPECT_EQ(*ValOptB, lib("B"));
+
+ auto valOptBSO = Resolver.resolve(withext("libB"));
+ EXPECT_TRUE(valOptBSO.has_value());
+ EXPECT_EQ(*valOptBSO, lib("B"));
+
+ // --- Check Z ---
+ auto ValOptZ = Resolver.resolve("libZ", true);
+ EXPECT_TRUE(ValOptZ.has_value());
+ EXPECT_EQ(*ValOptZ, lib("Z"));
+
+ auto valOptZSO = Resolver.resolve(withext("libZ"));
+ EXPECT_TRUE(valOptZSO.has_value());
+ EXPECT_EQ(*valOptZSO, lib("Z"));
+}
+#endif
+} // namespace
+#endif // defined(__APPLE__)
>From f7250832d9d0a430ef4155d63ee610bc5b8bd428 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Wed, 22 Oct 2025 09:45:02 +0530
Subject: [PATCH 2/3] Update test setup
---
.../Orc/TargetProcess/CMakeLists.txt | 1 +
.../Orc/LibraryResolverTest.cpp | 20 ++++++++++++++-----
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
index c5f6f52baae19..a11b3320f3577 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
@@ -38,6 +38,7 @@ add_llvm_component_library(LLVMOrcTargetProcess
LINK_COMPONENTS
${intel_jit_profiling}
+ Object
OrcShared
Support
TargetParser
diff --git a/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp
index 637621311e65a..f6990ee968663 100644
--- a/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/LibraryResolverTest.cpp
@@ -245,21 +245,31 @@ class LibraryResolverIT : public ::testing::Test {
protected:
std::string BaseDir;
std::unordered_map<std::string, TestLibrary> libs;
+
+ void addLib(const std::string &name) {
+ SmallString<512> path;
+ sys::fs::real_path(libPath(BaseDir, name + "/lib" + name), path);
+ if (path.empty())
+ EnvReady = false;
+ libs[name] = {path.str().str(), {platformSymbolName("say" + name)}};
+ }
+
void SetUp() override {
if (!EnvReady)
GTEST_SKIP() << "Skipping test: environment setup failed.";
ASSERT_NE(GlobalEnv, nullptr);
BaseDir = GlobalEnv->getBaseDir();
- libs["A"] = {libPath(BaseDir, "A/libA"), {platformSymbolName("sayA")}};
- libs["B"] = {libPath(BaseDir, "B/libB"), {platformSymbolName("sayB")}};
- libs["C"] = {libPath(BaseDir, "C/libC"), {platformSymbolName("sayC")}};
- libs["D"] = {libPath(BaseDir, "D/libD"), {platformSymbolName("sayD")}};
- libs["Z"] = {libPath(BaseDir, "Z/libZ"), {platformSymbolName("sayZ")}};
for (const auto &P : GlobalEnv->getDylibPaths()) {
if (!sys::fs::exists(P))
GTEST_SKIP();
}
+ const std::vector<std::string> libNames = {"A", "B", "C", "D", "Z"};
+ for (const auto &name : libNames)
+ addLib(name);
+
+ if (!EnvReady)
+ GTEST_SKIP() << "Skipping test: environment setup failed.";
}
const std::vector<std::string> &sym(const std::string &key) {
>From ed840882a710614c960e5cbb42d0d8b82514d2a2 Mon Sep 17 00:00:00 2001
From: SahilPatidar <patidarsahil2001 at gmail.com>
Date: Wed, 22 Oct 2025 14:26:20 +0530
Subject: [PATCH 3/3] Update Cmake file
---
llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
index a11b3320f3577..ca8192bb99492 100644
--- a/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
+++ b/llvm/lib/ExecutionEngine/Orc/TargetProcess/CMakeLists.txt
@@ -38,6 +38,7 @@ add_llvm_component_library(LLVMOrcTargetProcess
LINK_COMPONENTS
${intel_jit_profiling}
+ BinaryFormat
Object
OrcShared
Support
More information about the llvm-commits
mailing list