10b57cec5SDimitry Andric //===- ExecutionUtils.h - Utilities for executing code in Orc ---*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Contains utilities for executing code in Orc. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H 140b57cec5SDimitry Andric #define LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 170b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h" 180b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITSymbol.h" 190b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/Core.h" 205ffd83dbSDimitry Andric #include "llvm/ExecutionEngine/Orc/Mangling.h" 210b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/OrcError.h" 220b57cec5SDimitry Andric #include "llvm/ExecutionEngine/RuntimeDyld.h" 238bcb0991SDimitry Andric #include "llvm/Object/Archive.h" 240b57cec5SDimitry Andric #include "llvm/Support/DynamicLibrary.h" 250b57cec5SDimitry Andric #include <algorithm> 260b57cec5SDimitry Andric #include <cstdint> 270b57cec5SDimitry Andric #include <string> 280b57cec5SDimitry Andric #include <utility> 290b57cec5SDimitry Andric #include <vector> 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric namespace llvm { 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric class ConstantArray; 340b57cec5SDimitry Andric class GlobalVariable; 350b57cec5SDimitry Andric class Function; 360b57cec5SDimitry Andric class Module; 370b57cec5SDimitry Andric class TargetMachine; 380b57cec5SDimitry Andric class Value; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric namespace orc { 410b57cec5SDimitry Andric 428bcb0991SDimitry Andric class ObjectLayer; 438bcb0991SDimitry Andric 44480093f4SDimitry Andric /// Run a main function, returning the result. 45480093f4SDimitry Andric /// 46480093f4SDimitry Andric /// If the optional ProgramName argument is given then it will be inserted 47480093f4SDimitry Andric /// before the strings in Args as the first argument to the called function. 48480093f4SDimitry Andric /// 49480093f4SDimitry Andric /// It is legal to have an empty argument list and no program name, however 50480093f4SDimitry Andric /// many main functions will expect a name argument at least, and will fail 51480093f4SDimitry Andric /// if none is provided. 52480093f4SDimitry Andric int runAsMain(int (*Main)(int, char *[]), ArrayRef<std::string> Args, 53480093f4SDimitry Andric Optional<StringRef> ProgramName = None); 54480093f4SDimitry Andric 550b57cec5SDimitry Andric /// This iterator provides a convenient way to iterate over the elements 560b57cec5SDimitry Andric /// of an llvm.global_ctors/llvm.global_dtors instance. 570b57cec5SDimitry Andric /// 580b57cec5SDimitry Andric /// The easiest way to get hold of instances of this class is to use the 590b57cec5SDimitry Andric /// getConstructors/getDestructors functions. 600b57cec5SDimitry Andric class CtorDtorIterator { 610b57cec5SDimitry Andric public: 620b57cec5SDimitry Andric /// Accessor for an element of the global_ctors/global_dtors array. 630b57cec5SDimitry Andric /// 640b57cec5SDimitry Andric /// This class provides a read-only view of the element with any casts on 650b57cec5SDimitry Andric /// the function stripped away. 660b57cec5SDimitry Andric struct Element { 670b57cec5SDimitry Andric Element(unsigned Priority, Function *Func, Value *Data) 680b57cec5SDimitry Andric : Priority(Priority), Func(Func), Data(Data) {} 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric unsigned Priority; 710b57cec5SDimitry Andric Function *Func; 720b57cec5SDimitry Andric Value *Data; 730b57cec5SDimitry Andric }; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric /// Construct an iterator instance. If End is true then this iterator 760b57cec5SDimitry Andric /// acts as the end of the range, otherwise it is the beginning. 770b57cec5SDimitry Andric CtorDtorIterator(const GlobalVariable *GV, bool End); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric /// Test iterators for equality. 800b57cec5SDimitry Andric bool operator==(const CtorDtorIterator &Other) const; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric /// Test iterators for inequality. 830b57cec5SDimitry Andric bool operator!=(const CtorDtorIterator &Other) const; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric /// Pre-increment iterator. 860b57cec5SDimitry Andric CtorDtorIterator& operator++(); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric /// Post-increment iterator. 890b57cec5SDimitry Andric CtorDtorIterator operator++(int); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// Dereference iterator. The resulting value provides a read-only view 920b57cec5SDimitry Andric /// of this element of the global_ctors/global_dtors list. 930b57cec5SDimitry Andric Element operator*() const; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric private: 960b57cec5SDimitry Andric const ConstantArray *InitList; 970b57cec5SDimitry Andric unsigned I; 980b57cec5SDimitry Andric }; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// Create an iterator range over the entries of the llvm.global_ctors 1010b57cec5SDimitry Andric /// array. 1020b57cec5SDimitry Andric iterator_range<CtorDtorIterator> getConstructors(const Module &M); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric /// Create an iterator range over the entries of the llvm.global_ctors 1050b57cec5SDimitry Andric /// array. 1060b57cec5SDimitry Andric iterator_range<CtorDtorIterator> getDestructors(const Module &M); 1070b57cec5SDimitry Andric 1085ffd83dbSDimitry Andric /// This iterator provides a convenient way to iterate over GlobalValues that 1095ffd83dbSDimitry Andric /// have initialization effects. 1105ffd83dbSDimitry Andric class StaticInitGVIterator { 1115ffd83dbSDimitry Andric public: 1125ffd83dbSDimitry Andric StaticInitGVIterator() = default; 1135ffd83dbSDimitry Andric 1145ffd83dbSDimitry Andric StaticInitGVIterator(Module &M) 1155ffd83dbSDimitry Andric : I(M.global_values().begin()), E(M.global_values().end()), 1165ffd83dbSDimitry Andric ObjFmt(Triple(M.getTargetTriple()).getObjectFormat()) { 1175ffd83dbSDimitry Andric if (I != E) { 1185ffd83dbSDimitry Andric if (!isStaticInitGlobal(*I)) 1195ffd83dbSDimitry Andric moveToNextStaticInitGlobal(); 1205ffd83dbSDimitry Andric } else 1215ffd83dbSDimitry Andric I = E = Module::global_value_iterator(); 1225ffd83dbSDimitry Andric } 1235ffd83dbSDimitry Andric 1245ffd83dbSDimitry Andric bool operator==(const StaticInitGVIterator &O) const { return I == O.I; } 1255ffd83dbSDimitry Andric bool operator!=(const StaticInitGVIterator &O) const { return I != O.I; } 1265ffd83dbSDimitry Andric 1275ffd83dbSDimitry Andric StaticInitGVIterator &operator++() { 1285ffd83dbSDimitry Andric assert(I != E && "Increment past end of range"); 1295ffd83dbSDimitry Andric moveToNextStaticInitGlobal(); 1305ffd83dbSDimitry Andric return *this; 1315ffd83dbSDimitry Andric } 1325ffd83dbSDimitry Andric 1335ffd83dbSDimitry Andric GlobalValue &operator*() { return *I; } 1345ffd83dbSDimitry Andric 1355ffd83dbSDimitry Andric private: 1365ffd83dbSDimitry Andric bool isStaticInitGlobal(GlobalValue &GV); 1375ffd83dbSDimitry Andric void moveToNextStaticInitGlobal() { 1385ffd83dbSDimitry Andric ++I; 1395ffd83dbSDimitry Andric while (I != E && !isStaticInitGlobal(*I)) 1405ffd83dbSDimitry Andric ++I; 1415ffd83dbSDimitry Andric if (I == E) 1425ffd83dbSDimitry Andric I = E = Module::global_value_iterator(); 1435ffd83dbSDimitry Andric } 1445ffd83dbSDimitry Andric 1455ffd83dbSDimitry Andric Module::global_value_iterator I, E; 1465ffd83dbSDimitry Andric Triple::ObjectFormatType ObjFmt; 1475ffd83dbSDimitry Andric }; 1485ffd83dbSDimitry Andric 1495ffd83dbSDimitry Andric /// Create an iterator range over the GlobalValues that contribute to static 1505ffd83dbSDimitry Andric /// initialization. 1515ffd83dbSDimitry Andric inline iterator_range<StaticInitGVIterator> getStaticInitGVs(Module &M) { 1525ffd83dbSDimitry Andric return make_range(StaticInitGVIterator(M), StaticInitGVIterator()); 1535ffd83dbSDimitry Andric } 1545ffd83dbSDimitry Andric 1550b57cec5SDimitry Andric /// Convenience class for recording constructor/destructor names for 1560b57cec5SDimitry Andric /// later execution. 1570b57cec5SDimitry Andric template <typename JITLayerT> 1580b57cec5SDimitry Andric class LegacyCtorDtorRunner { 1590b57cec5SDimitry Andric public: 1600b57cec5SDimitry Andric /// Construct a CtorDtorRunner for the given range using the given 1610b57cec5SDimitry Andric /// name mangling function. 1620b57cec5SDimitry Andric LLVM_ATTRIBUTE_DEPRECATED( 1630b57cec5SDimitry Andric LegacyCtorDtorRunner(std::vector<std::string> CtorDtorNames, 1640b57cec5SDimitry Andric VModuleKey K), 1650b57cec5SDimitry Andric "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. " 1660b57cec5SDimitry Andric "Please use the ORCv2 CtorDtorRunner utility instead"); 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric LegacyCtorDtorRunner(ORCv1DeprecationAcknowledgement, 1690b57cec5SDimitry Andric std::vector<std::string> CtorDtorNames, VModuleKey K) 1700b57cec5SDimitry Andric : CtorDtorNames(std::move(CtorDtorNames)), K(K) {} 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric /// Run the recorded constructors/destructors through the given JIT 1730b57cec5SDimitry Andric /// layer. 1740b57cec5SDimitry Andric Error runViaLayer(JITLayerT &JITLayer) const { 1750b57cec5SDimitry Andric using CtorDtorTy = void (*)(); 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric for (const auto &CtorDtorName : CtorDtorNames) { 1780b57cec5SDimitry Andric if (auto CtorDtorSym = JITLayer.findSymbolIn(K, CtorDtorName, false)) { 1790b57cec5SDimitry Andric if (auto AddrOrErr = CtorDtorSym.getAddress()) { 1800b57cec5SDimitry Andric CtorDtorTy CtorDtor = 1810b57cec5SDimitry Andric reinterpret_cast<CtorDtorTy>(static_cast<uintptr_t>(*AddrOrErr)); 1820b57cec5SDimitry Andric CtorDtor(); 1830b57cec5SDimitry Andric } else 1840b57cec5SDimitry Andric return AddrOrErr.takeError(); 1850b57cec5SDimitry Andric } else { 1860b57cec5SDimitry Andric if (auto Err = CtorDtorSym.takeError()) 1870b57cec5SDimitry Andric return Err; 1880b57cec5SDimitry Andric else 1890b57cec5SDimitry Andric return make_error<JITSymbolNotFound>(CtorDtorName); 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric return Error::success(); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric private: 1960b57cec5SDimitry Andric std::vector<std::string> CtorDtorNames; 1970b57cec5SDimitry Andric orc::VModuleKey K; 1980b57cec5SDimitry Andric }; 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric template <typename JITLayerT> 2010b57cec5SDimitry Andric LegacyCtorDtorRunner<JITLayerT>::LegacyCtorDtorRunner( 2020b57cec5SDimitry Andric std::vector<std::string> CtorDtorNames, VModuleKey K) 2030b57cec5SDimitry Andric : CtorDtorNames(std::move(CtorDtorNames)), K(K) {} 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric class CtorDtorRunner { 2060b57cec5SDimitry Andric public: 2070b57cec5SDimitry Andric CtorDtorRunner(JITDylib &JD) : JD(JD) {} 2080b57cec5SDimitry Andric void add(iterator_range<CtorDtorIterator> CtorDtors); 2090b57cec5SDimitry Andric Error run(); 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric private: 2120b57cec5SDimitry Andric using CtorDtorList = std::vector<SymbolStringPtr>; 2130b57cec5SDimitry Andric using CtorDtorPriorityMap = std::map<unsigned, CtorDtorList>; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric JITDylib &JD; 2160b57cec5SDimitry Andric CtorDtorPriorityMap CtorDtorsByPriority; 2170b57cec5SDimitry Andric }; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric /// Support class for static dtor execution. For hosted (in-process) JITs 2200b57cec5SDimitry Andric /// only! 2210b57cec5SDimitry Andric /// 2220b57cec5SDimitry Andric /// If a __cxa_atexit function isn't found C++ programs that use static 2230b57cec5SDimitry Andric /// destructors will fail to link. However, we don't want to use the host 2240b57cec5SDimitry Andric /// process's __cxa_atexit, because it will schedule JIT'd destructors to run 2250b57cec5SDimitry Andric /// after the JIT has been torn down, which is no good. This class makes it easy 2260b57cec5SDimitry Andric /// to override __cxa_atexit (and the related __dso_handle). 2270b57cec5SDimitry Andric /// 2280b57cec5SDimitry Andric /// To use, clients should manually call searchOverrides from their symbol 2290b57cec5SDimitry Andric /// resolver. This should generally be done after attempting symbol resolution 2300b57cec5SDimitry Andric /// inside the JIT, but before searching the host process's symbol table. When 2310b57cec5SDimitry Andric /// the client determines that destructors should be run (generally at JIT 2320b57cec5SDimitry Andric /// teardown or after a return from main), the runDestructors method should be 2330b57cec5SDimitry Andric /// called. 2340b57cec5SDimitry Andric class LocalCXXRuntimeOverridesBase { 2350b57cec5SDimitry Andric public: 2360b57cec5SDimitry Andric /// Run any destructors recorded by the overriden __cxa_atexit function 2370b57cec5SDimitry Andric /// (CXAAtExitOverride). 2380b57cec5SDimitry Andric void runDestructors(); 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric protected: 2410b57cec5SDimitry Andric template <typename PtrTy> JITTargetAddress toTargetAddress(PtrTy *P) { 2420b57cec5SDimitry Andric return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(P)); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric using DestructorPtr = void (*)(void *); 2460b57cec5SDimitry Andric using CXXDestructorDataPair = std::pair<DestructorPtr, void *>; 2470b57cec5SDimitry Andric using CXXDestructorDataPairList = std::vector<CXXDestructorDataPair>; 2480b57cec5SDimitry Andric CXXDestructorDataPairList DSOHandleOverride; 2490b57cec5SDimitry Andric static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg, 2500b57cec5SDimitry Andric void *DSOHandle); 2510b57cec5SDimitry Andric }; 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric class LegacyLocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase { 2540b57cec5SDimitry Andric public: 2550b57cec5SDimitry Andric /// Create a runtime-overrides class. 2560b57cec5SDimitry Andric template <typename MangleFtorT> 2570b57cec5SDimitry Andric LLVM_ATTRIBUTE_DEPRECATED( 2580b57cec5SDimitry Andric LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle), 2590b57cec5SDimitry Andric "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. " 2600b57cec5SDimitry Andric "Please use the ORCv2 LocalCXXRuntimeOverrides utility instead"); 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric template <typename MangleFtorT> 2630b57cec5SDimitry Andric LegacyLocalCXXRuntimeOverrides(ORCv1DeprecationAcknowledgement, 2640b57cec5SDimitry Andric const MangleFtorT &Mangle) { 2650b57cec5SDimitry Andric addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride)); 2660b57cec5SDimitry Andric addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride)); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric /// Search overrided symbols. 2700b57cec5SDimitry Andric JITEvaluatedSymbol searchOverrides(const std::string &Name) { 2710b57cec5SDimitry Andric auto I = CXXRuntimeOverrides.find(Name); 2720b57cec5SDimitry Andric if (I != CXXRuntimeOverrides.end()) 2730b57cec5SDimitry Andric return JITEvaluatedSymbol(I->second, JITSymbolFlags::Exported); 2740b57cec5SDimitry Andric return nullptr; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric private: 2780b57cec5SDimitry Andric void addOverride(const std::string &Name, JITTargetAddress Addr) { 2790b57cec5SDimitry Andric CXXRuntimeOverrides.insert(std::make_pair(Name, Addr)); 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric StringMap<JITTargetAddress> CXXRuntimeOverrides; 2830b57cec5SDimitry Andric }; 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric template <typename MangleFtorT> 2860b57cec5SDimitry Andric LegacyLocalCXXRuntimeOverrides::LegacyLocalCXXRuntimeOverrides( 2870b57cec5SDimitry Andric const MangleFtorT &Mangle) { 2880b57cec5SDimitry Andric addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride)); 2890b57cec5SDimitry Andric addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride)); 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric class LocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase { 2930b57cec5SDimitry Andric public: 2940b57cec5SDimitry Andric Error enable(JITDylib &JD, MangleAndInterner &Mangler); 2950b57cec5SDimitry Andric }; 2960b57cec5SDimitry Andric 2975ffd83dbSDimitry Andric /// An interface for Itanium __cxa_atexit interposer implementations. 2985ffd83dbSDimitry Andric class ItaniumCXAAtExitSupport { 2995ffd83dbSDimitry Andric public: 3005ffd83dbSDimitry Andric struct AtExitRecord { 3015ffd83dbSDimitry Andric void (*F)(void *); 3025ffd83dbSDimitry Andric void *Ctx; 3035ffd83dbSDimitry Andric }; 3045ffd83dbSDimitry Andric 3055ffd83dbSDimitry Andric void registerAtExit(void (*F)(void *), void *Ctx, void *DSOHandle); 3065ffd83dbSDimitry Andric void runAtExits(void *DSOHandle); 3075ffd83dbSDimitry Andric 3085ffd83dbSDimitry Andric private: 3095ffd83dbSDimitry Andric std::mutex AtExitsMutex; 3105ffd83dbSDimitry Andric DenseMap<void *, std::vector<AtExitRecord>> AtExitRecords; 3115ffd83dbSDimitry Andric }; 3125ffd83dbSDimitry Andric 3130b57cec5SDimitry Andric /// A utility class to expose symbols found via dlsym to the JIT. 3140b57cec5SDimitry Andric /// 3150b57cec5SDimitry Andric /// If an instance of this class is attached to a JITDylib as a fallback 3160b57cec5SDimitry Andric /// definition generator, then any symbol found in the given DynamicLibrary that 3170b57cec5SDimitry Andric /// passes the 'Allow' predicate will be added to the JITDylib. 3188bcb0991SDimitry Andric class DynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator { 3190b57cec5SDimitry Andric public: 320480093f4SDimitry Andric using SymbolPredicate = std::function<bool(const SymbolStringPtr &)>; 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric /// Create a DynamicLibrarySearchGenerator that searches for symbols in the 3230b57cec5SDimitry Andric /// given sys::DynamicLibrary. 3240b57cec5SDimitry Andric /// 3250b57cec5SDimitry Andric /// If the Allow predicate is given then only symbols matching the predicate 3260b57cec5SDimitry Andric /// will be searched for. If the predicate is not given then all symbols will 3270b57cec5SDimitry Andric /// be searched for. 3280b57cec5SDimitry Andric DynamicLibrarySearchGenerator(sys::DynamicLibrary Dylib, char GlobalPrefix, 3290b57cec5SDimitry Andric SymbolPredicate Allow = SymbolPredicate()); 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric /// Permanently loads the library at the given path and, on success, returns 3320b57cec5SDimitry Andric /// a DynamicLibrarySearchGenerator that will search it for symbol definitions 3330b57cec5SDimitry Andric /// in the library. On failure returns the reason the library failed to load. 3348bcb0991SDimitry Andric static Expected<std::unique_ptr<DynamicLibrarySearchGenerator>> 3350b57cec5SDimitry Andric Load(const char *FileName, char GlobalPrefix, 3360b57cec5SDimitry Andric SymbolPredicate Allow = SymbolPredicate()); 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric /// Creates a DynamicLibrarySearchGenerator that searches for symbols in 3390b57cec5SDimitry Andric /// the current process. 3408bcb0991SDimitry Andric static Expected<std::unique_ptr<DynamicLibrarySearchGenerator>> 3410b57cec5SDimitry Andric GetForCurrentProcess(char GlobalPrefix, 3420b57cec5SDimitry Andric SymbolPredicate Allow = SymbolPredicate()) { 3430b57cec5SDimitry Andric return Load(nullptr, GlobalPrefix, std::move(Allow)); 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 346480093f4SDimitry Andric Error tryToGenerate(LookupKind K, JITDylib &JD, 347480093f4SDimitry Andric JITDylibLookupFlags JDLookupFlags, 348480093f4SDimitry Andric const SymbolLookupSet &Symbols) override; 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric private: 3510b57cec5SDimitry Andric sys::DynamicLibrary Dylib; 3520b57cec5SDimitry Andric SymbolPredicate Allow; 3530b57cec5SDimitry Andric char GlobalPrefix; 3540b57cec5SDimitry Andric }; 3550b57cec5SDimitry Andric 3568bcb0991SDimitry Andric /// A utility class to expose symbols from a static library. 3578bcb0991SDimitry Andric /// 3588bcb0991SDimitry Andric /// If an instance of this class is attached to a JITDylib as a fallback 3598bcb0991SDimitry Andric /// definition generator, then any symbol found in the archive will result in 3608bcb0991SDimitry Andric /// the containing object being added to the JITDylib. 3618bcb0991SDimitry Andric class StaticLibraryDefinitionGenerator : public JITDylib::DefinitionGenerator { 3628bcb0991SDimitry Andric public: 3638bcb0991SDimitry Andric /// Try to create a StaticLibraryDefinitionGenerator from the given path. 3648bcb0991SDimitry Andric /// 3658bcb0991SDimitry Andric /// This call will succeed if the file at the given path is a static library 3668bcb0991SDimitry Andric /// is a valid archive, otherwise it will return an error. 3678bcb0991SDimitry Andric static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 3688bcb0991SDimitry Andric Load(ObjectLayer &L, const char *FileName); 3698bcb0991SDimitry Andric 3705ffd83dbSDimitry Andric /// Try to create a StaticLibraryDefinitionGenerator from the given path. 3715ffd83dbSDimitry Andric /// 3725ffd83dbSDimitry Andric /// This call will succeed if the file at the given path is a static library 3735ffd83dbSDimitry Andric /// or a MachO universal binary containing a static library that is compatible 3745ffd83dbSDimitry Andric /// with the given triple. Otherwise it will return an error. 3755ffd83dbSDimitry Andric static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 3765ffd83dbSDimitry Andric Load(ObjectLayer &L, const char *FileName, const Triple &TT); 3775ffd83dbSDimitry Andric 3788bcb0991SDimitry Andric /// Try to create a StaticLibrarySearchGenerator from the given memory buffer. 379480093f4SDimitry Andric /// This call will succeed if the buffer contains a valid archive, otherwise 3808bcb0991SDimitry Andric /// it will return an error. 3818bcb0991SDimitry Andric static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> 3828bcb0991SDimitry Andric Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer); 3838bcb0991SDimitry Andric 384480093f4SDimitry Andric Error tryToGenerate(LookupKind K, JITDylib &JD, 385480093f4SDimitry Andric JITDylibLookupFlags JDLookupFlags, 386480093f4SDimitry Andric const SymbolLookupSet &Symbols) override; 3878bcb0991SDimitry Andric 3888bcb0991SDimitry Andric private: 3898bcb0991SDimitry Andric StaticLibraryDefinitionGenerator(ObjectLayer &L, 3908bcb0991SDimitry Andric std::unique_ptr<MemoryBuffer> ArchiveBuffer, 3918bcb0991SDimitry Andric Error &Err); 3928bcb0991SDimitry Andric 3938bcb0991SDimitry Andric ObjectLayer &L; 3948bcb0991SDimitry Andric std::unique_ptr<MemoryBuffer> ArchiveBuffer; 395480093f4SDimitry Andric std::unique_ptr<object::Archive> Archive; 3968bcb0991SDimitry Andric }; 3978bcb0991SDimitry Andric 3980b57cec5SDimitry Andric } // end namespace orc 3990b57cec5SDimitry Andric } // end namespace llvm 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric #endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H 402