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/iterator_range.h"
170b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITSymbol.h"
180b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/Core.h"
195ffd83dbSDimitry Andric #include "llvm/ExecutionEngine/Orc/Mangling.h"
20bdd1243dSDimitry Andric #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
21e8d8bef9SDimitry Andric #include "llvm/ExecutionEngine/Orc/Shared/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 <utility>
280b57cec5SDimitry Andric #include <vector>
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric namespace llvm {
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric class ConstantArray;
330b57cec5SDimitry Andric class GlobalVariable;
340b57cec5SDimitry Andric class Function;
350b57cec5SDimitry Andric class Module;
360b57cec5SDimitry Andric class Value;
370b57cec5SDimitry Andric 
3806c3fb27SDimitry Andric namespace object {
3906c3fb27SDimitry Andric class MachOUniversalBinary;
4006c3fb27SDimitry Andric }
4106c3fb27SDimitry Andric 
420b57cec5SDimitry Andric namespace orc {
430b57cec5SDimitry Andric 
448bcb0991SDimitry Andric class ObjectLayer;
458bcb0991SDimitry Andric 
460b57cec5SDimitry Andric /// This iterator provides a convenient way to iterate over the elements
470b57cec5SDimitry Andric ///        of an llvm.global_ctors/llvm.global_dtors instance.
480b57cec5SDimitry Andric ///
490b57cec5SDimitry Andric ///   The easiest way to get hold of instances of this class is to use the
500b57cec5SDimitry Andric /// getConstructors/getDestructors functions.
510b57cec5SDimitry Andric class CtorDtorIterator {
520b57cec5SDimitry Andric public:
530b57cec5SDimitry Andric   /// Accessor for an element of the global_ctors/global_dtors array.
540b57cec5SDimitry Andric   ///
550b57cec5SDimitry Andric   ///   This class provides a read-only view of the element with any casts on
560b57cec5SDimitry Andric   /// the function stripped away.
570b57cec5SDimitry Andric   struct Element {
ElementElement580b57cec5SDimitry Andric     Element(unsigned Priority, Function *Func, Value *Data)
590b57cec5SDimitry Andric       : Priority(Priority), Func(Func), Data(Data) {}
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric     unsigned Priority;
620b57cec5SDimitry Andric     Function *Func;
630b57cec5SDimitry Andric     Value *Data;
640b57cec5SDimitry Andric   };
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   /// Construct an iterator instance. If End is true then this iterator
670b57cec5SDimitry Andric   ///        acts as the end of the range, otherwise it is the beginning.
680b57cec5SDimitry Andric   CtorDtorIterator(const GlobalVariable *GV, bool End);
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   /// Test iterators for equality.
710b57cec5SDimitry Andric   bool operator==(const CtorDtorIterator &Other) const;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   /// Test iterators for inequality.
740b57cec5SDimitry Andric   bool operator!=(const CtorDtorIterator &Other) const;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   /// Pre-increment iterator.
770b57cec5SDimitry Andric   CtorDtorIterator& operator++();
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   /// Post-increment iterator.
800b57cec5SDimitry Andric   CtorDtorIterator operator++(int);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   /// Dereference iterator. The resulting value provides a read-only view
830b57cec5SDimitry Andric   ///        of this element of the global_ctors/global_dtors list.
840b57cec5SDimitry Andric   Element operator*() const;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric private:
870b57cec5SDimitry Andric   const ConstantArray *InitList;
880b57cec5SDimitry Andric   unsigned I;
890b57cec5SDimitry Andric };
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric /// Create an iterator range over the entries of the llvm.global_ctors
920b57cec5SDimitry Andric ///        array.
930b57cec5SDimitry Andric iterator_range<CtorDtorIterator> getConstructors(const Module &M);
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric /// Create an iterator range over the entries of the llvm.global_ctors
960b57cec5SDimitry Andric ///        array.
970b57cec5SDimitry Andric iterator_range<CtorDtorIterator> getDestructors(const Module &M);
980b57cec5SDimitry Andric 
995ffd83dbSDimitry Andric /// This iterator provides a convenient way to iterate over GlobalValues that
1005ffd83dbSDimitry Andric /// have initialization effects.
1015ffd83dbSDimitry Andric class StaticInitGVIterator {
1025ffd83dbSDimitry Andric public:
1035ffd83dbSDimitry Andric   StaticInitGVIterator() = default;
1045ffd83dbSDimitry Andric 
StaticInitGVIterator(Module & M)1055ffd83dbSDimitry Andric   StaticInitGVIterator(Module &M)
1065ffd83dbSDimitry Andric       : I(M.global_values().begin()), E(M.global_values().end()),
1075ffd83dbSDimitry Andric         ObjFmt(Triple(M.getTargetTriple()).getObjectFormat()) {
1085ffd83dbSDimitry Andric     if (I != E) {
1095ffd83dbSDimitry Andric       if (!isStaticInitGlobal(*I))
1105ffd83dbSDimitry Andric         moveToNextStaticInitGlobal();
1115ffd83dbSDimitry Andric     } else
1125ffd83dbSDimitry Andric       I = E = Module::global_value_iterator();
1135ffd83dbSDimitry Andric   }
1145ffd83dbSDimitry Andric 
1155ffd83dbSDimitry Andric   bool operator==(const StaticInitGVIterator &O) const { return I == O.I; }
1165ffd83dbSDimitry Andric   bool operator!=(const StaticInitGVIterator &O) const { return I != O.I; }
1175ffd83dbSDimitry Andric 
1185ffd83dbSDimitry Andric   StaticInitGVIterator &operator++() {
1195ffd83dbSDimitry Andric     assert(I != E && "Increment past end of range");
1205ffd83dbSDimitry Andric     moveToNextStaticInitGlobal();
1215ffd83dbSDimitry Andric     return *this;
1225ffd83dbSDimitry Andric   }
1235ffd83dbSDimitry Andric 
1245ffd83dbSDimitry Andric   GlobalValue &operator*() { return *I; }
1255ffd83dbSDimitry Andric 
1265ffd83dbSDimitry Andric private:
1275ffd83dbSDimitry Andric   bool isStaticInitGlobal(GlobalValue &GV);
moveToNextStaticInitGlobal()1285ffd83dbSDimitry Andric   void moveToNextStaticInitGlobal() {
1295ffd83dbSDimitry Andric     ++I;
1305ffd83dbSDimitry Andric     while (I != E && !isStaticInitGlobal(*I))
1315ffd83dbSDimitry Andric       ++I;
1325ffd83dbSDimitry Andric     if (I == E)
1335ffd83dbSDimitry Andric       I = E = Module::global_value_iterator();
1345ffd83dbSDimitry Andric   }
1355ffd83dbSDimitry Andric 
1365ffd83dbSDimitry Andric   Module::global_value_iterator I, E;
1375ffd83dbSDimitry Andric   Triple::ObjectFormatType ObjFmt;
1385ffd83dbSDimitry Andric };
1395ffd83dbSDimitry Andric 
1405ffd83dbSDimitry Andric /// Create an iterator range over the GlobalValues that contribute to static
1415ffd83dbSDimitry Andric /// initialization.
getStaticInitGVs(Module & M)1425ffd83dbSDimitry Andric inline iterator_range<StaticInitGVIterator> getStaticInitGVs(Module &M) {
1435ffd83dbSDimitry Andric   return make_range(StaticInitGVIterator(M), StaticInitGVIterator());
1445ffd83dbSDimitry Andric }
1455ffd83dbSDimitry Andric 
1460b57cec5SDimitry Andric class CtorDtorRunner {
1470b57cec5SDimitry Andric public:
CtorDtorRunner(JITDylib & JD)1480b57cec5SDimitry Andric   CtorDtorRunner(JITDylib &JD) : JD(JD) {}
1490b57cec5SDimitry Andric   void add(iterator_range<CtorDtorIterator> CtorDtors);
1500b57cec5SDimitry Andric   Error run();
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric private:
1530b57cec5SDimitry Andric   using CtorDtorList = std::vector<SymbolStringPtr>;
1540b57cec5SDimitry Andric   using CtorDtorPriorityMap = std::map<unsigned, CtorDtorList>;
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   JITDylib &JD;
1570b57cec5SDimitry Andric   CtorDtorPriorityMap CtorDtorsByPriority;
1580b57cec5SDimitry Andric };
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric /// Support class for static dtor execution. For hosted (in-process) JITs
1610b57cec5SDimitry Andric ///        only!
1620b57cec5SDimitry Andric ///
1630b57cec5SDimitry Andric ///   If a __cxa_atexit function isn't found C++ programs that use static
1640b57cec5SDimitry Andric /// destructors will fail to link. However, we don't want to use the host
1650b57cec5SDimitry Andric /// process's __cxa_atexit, because it will schedule JIT'd destructors to run
1660b57cec5SDimitry Andric /// after the JIT has been torn down, which is no good. This class makes it easy
1670b57cec5SDimitry Andric /// to override __cxa_atexit (and the related __dso_handle).
1680b57cec5SDimitry Andric ///
1690b57cec5SDimitry Andric ///   To use, clients should manually call searchOverrides from their symbol
1700b57cec5SDimitry Andric /// resolver. This should generally be done after attempting symbol resolution
1710b57cec5SDimitry Andric /// inside the JIT, but before searching the host process's symbol table. When
1720b57cec5SDimitry Andric /// the client determines that destructors should be run (generally at JIT
1730b57cec5SDimitry Andric /// teardown or after a return from main), the runDestructors method should be
1740b57cec5SDimitry Andric /// called.
1750b57cec5SDimitry Andric class LocalCXXRuntimeOverridesBase {
1760b57cec5SDimitry Andric public:
1770b57cec5SDimitry Andric   /// Run any destructors recorded by the overriden __cxa_atexit function
1780b57cec5SDimitry Andric   /// (CXAAtExitOverride).
1790b57cec5SDimitry Andric   void runDestructors();
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric protected:
1820b57cec5SDimitry Andric   using DestructorPtr = void (*)(void *);
1830b57cec5SDimitry Andric   using CXXDestructorDataPair = std::pair<DestructorPtr, void *>;
1840b57cec5SDimitry Andric   using CXXDestructorDataPairList = std::vector<CXXDestructorDataPair>;
1850b57cec5SDimitry Andric   CXXDestructorDataPairList DSOHandleOverride;
1860b57cec5SDimitry Andric   static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg,
1870b57cec5SDimitry Andric                                void *DSOHandle);
1880b57cec5SDimitry Andric };
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric class LocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase {
1910b57cec5SDimitry Andric public:
1920b57cec5SDimitry Andric   Error enable(JITDylib &JD, MangleAndInterner &Mangler);
1930b57cec5SDimitry Andric };
1940b57cec5SDimitry Andric 
1955ffd83dbSDimitry Andric /// An interface for Itanium __cxa_atexit interposer implementations.
1965ffd83dbSDimitry Andric class ItaniumCXAAtExitSupport {
1975ffd83dbSDimitry Andric public:
1985ffd83dbSDimitry Andric   struct AtExitRecord {
1995ffd83dbSDimitry Andric     void (*F)(void *);
2005ffd83dbSDimitry Andric     void *Ctx;
2015ffd83dbSDimitry Andric   };
2025ffd83dbSDimitry Andric 
2035ffd83dbSDimitry Andric   void registerAtExit(void (*F)(void *), void *Ctx, void *DSOHandle);
2045ffd83dbSDimitry Andric   void runAtExits(void *DSOHandle);
2055ffd83dbSDimitry Andric 
2065ffd83dbSDimitry Andric private:
2075ffd83dbSDimitry Andric   std::mutex AtExitsMutex;
2085ffd83dbSDimitry Andric   DenseMap<void *, std::vector<AtExitRecord>> AtExitRecords;
2095ffd83dbSDimitry Andric };
2105ffd83dbSDimitry Andric 
2110b57cec5SDimitry Andric /// A utility class to expose symbols found via dlsym to the JIT.
2120b57cec5SDimitry Andric ///
2130b57cec5SDimitry Andric /// If an instance of this class is attached to a JITDylib as a fallback
2140b57cec5SDimitry Andric /// definition generator, then any symbol found in the given DynamicLibrary that
2150b57cec5SDimitry Andric /// passes the 'Allow' predicate will be added to the JITDylib.
216e8d8bef9SDimitry Andric class DynamicLibrarySearchGenerator : public DefinitionGenerator {
2170b57cec5SDimitry Andric public:
218480093f4SDimitry Andric   using SymbolPredicate = std::function<bool(const SymbolStringPtr &)>;
2191db9f3b2SDimitry Andric   using AddAbsoluteSymbolsFn = unique_function<Error(JITDylib &, SymbolMap)>;
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   /// Create a DynamicLibrarySearchGenerator that searches for symbols in the
2220b57cec5SDimitry Andric   /// given sys::DynamicLibrary.
2230b57cec5SDimitry Andric   ///
2240b57cec5SDimitry Andric   /// If the Allow predicate is given then only symbols matching the predicate
2250b57cec5SDimitry Andric   /// will be searched for. If the predicate is not given then all symbols will
2260b57cec5SDimitry Andric   /// be searched for.
2271db9f3b2SDimitry Andric   ///
2281db9f3b2SDimitry Andric   /// If \p AddAbsoluteSymbols is provided, it is used to add the symbols to the
2291db9f3b2SDimitry Andric   /// \c JITDylib; otherwise it uses JD.define(absoluteSymbols(...)).
2301db9f3b2SDimitry Andric   DynamicLibrarySearchGenerator(
2311db9f3b2SDimitry Andric       sys::DynamicLibrary Dylib, char GlobalPrefix,
2321db9f3b2SDimitry Andric       SymbolPredicate Allow = SymbolPredicate(),
2331db9f3b2SDimitry Andric       AddAbsoluteSymbolsFn AddAbsoluteSymbols = nullptr);
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric   /// Permanently loads the library at the given path and, on success, returns
2360b57cec5SDimitry Andric   /// a DynamicLibrarySearchGenerator that will search it for symbol definitions
2370b57cec5SDimitry Andric   /// in the library. On failure returns the reason the library failed to load.
2388bcb0991SDimitry Andric   static Expected<std::unique_ptr<DynamicLibrarySearchGenerator>>
2390b57cec5SDimitry Andric   Load(const char *FileName, char GlobalPrefix,
2401db9f3b2SDimitry Andric        SymbolPredicate Allow = SymbolPredicate(),
2411db9f3b2SDimitry Andric        AddAbsoluteSymbolsFn AddAbsoluteSymbols = nullptr);
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   /// Creates a DynamicLibrarySearchGenerator that searches for symbols in
2440b57cec5SDimitry Andric   /// the current process.
2458bcb0991SDimitry Andric   static Expected<std::unique_ptr<DynamicLibrarySearchGenerator>>
2460b57cec5SDimitry Andric   GetForCurrentProcess(char GlobalPrefix,
2471db9f3b2SDimitry Andric                        SymbolPredicate Allow = SymbolPredicate(),
2481db9f3b2SDimitry Andric                        AddAbsoluteSymbolsFn AddAbsoluteSymbols = nullptr) {
2491db9f3b2SDimitry Andric     return Load(nullptr, GlobalPrefix, std::move(Allow),
2501db9f3b2SDimitry Andric                 std::move(AddAbsoluteSymbols));
2510b57cec5SDimitry Andric   }
2520b57cec5SDimitry Andric 
253e8d8bef9SDimitry Andric   Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
254480093f4SDimitry Andric                       JITDylibLookupFlags JDLookupFlags,
255480093f4SDimitry Andric                       const SymbolLookupSet &Symbols) override;
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric private:
2580b57cec5SDimitry Andric   sys::DynamicLibrary Dylib;
2590b57cec5SDimitry Andric   SymbolPredicate Allow;
2601db9f3b2SDimitry Andric   AddAbsoluteSymbolsFn AddAbsoluteSymbols;
2610b57cec5SDimitry Andric   char GlobalPrefix;
2620b57cec5SDimitry Andric };
2630b57cec5SDimitry Andric 
2648bcb0991SDimitry Andric /// A utility class to expose symbols from a static library.
2658bcb0991SDimitry Andric ///
2668bcb0991SDimitry Andric /// If an instance of this class is attached to a JITDylib as a fallback
2678bcb0991SDimitry Andric /// definition generator, then any symbol found in the archive will result in
2688bcb0991SDimitry Andric /// the containing object being added to the JITDylib.
269e8d8bef9SDimitry Andric class StaticLibraryDefinitionGenerator : public DefinitionGenerator {
2708bcb0991SDimitry Andric public:
2710eae32dcSDimitry Andric   // Interface builder function for objects loaded from this archive.
2720eae32dcSDimitry Andric   using GetObjectFileInterface =
2730eae32dcSDimitry Andric       unique_function<Expected<MaterializationUnit::Interface>(
2740eae32dcSDimitry Andric           ExecutionSession &ES, MemoryBufferRef ObjBuffer)>;
2750eae32dcSDimitry Andric 
2768bcb0991SDimitry Andric   /// Try to create a StaticLibraryDefinitionGenerator from the given path.
2778bcb0991SDimitry Andric   ///
2788bcb0991SDimitry Andric   /// This call will succeed if the file at the given path is a static library
27906c3fb27SDimitry Andric   /// or a MachO universal binary containing a static library that is compatible
28006c3fb27SDimitry Andric   /// with the ExecutionSession's triple. Otherwise it will return an error.
2818bcb0991SDimitry Andric   static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
2820eae32dcSDimitry Andric   Load(ObjectLayer &L, const char *FileName,
2830eae32dcSDimitry Andric        GetObjectFileInterface GetObjFileInterface = GetObjectFileInterface());
2848bcb0991SDimitry Andric 
28506c3fb27SDimitry Andric   /// Try to create a StaticLibrarySearchGenerator from the given memory buffer
28606c3fb27SDimitry Andric   /// and Archive object.
2875ffd83dbSDimitry Andric   static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
28806c3fb27SDimitry Andric   Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
28906c3fb27SDimitry Andric          std::unique_ptr<object::Archive> Archive,
2900eae32dcSDimitry Andric          GetObjectFileInterface GetObjFileInterface = GetObjectFileInterface());
2915ffd83dbSDimitry Andric 
2928bcb0991SDimitry Andric   /// Try to create a StaticLibrarySearchGenerator from the given memory buffer.
293480093f4SDimitry Andric   /// This call will succeed if the buffer contains a valid archive, otherwise
2948bcb0991SDimitry Andric   /// it will return an error.
29506c3fb27SDimitry Andric   ///
29606c3fb27SDimitry Andric   /// This call will succeed if the buffer contains a valid static library or a
29706c3fb27SDimitry Andric   /// MachO universal binary containing a static library that is compatible
29806c3fb27SDimitry Andric   /// with the ExecutionSession's triple. Otherwise it will return an error.
2998bcb0991SDimitry Andric   static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
3000eae32dcSDimitry Andric   Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> ArchiveBuffer,
3010eae32dcSDimitry Andric          GetObjectFileInterface GetObjFileInterface = GetObjectFileInterface());
3028bcb0991SDimitry Andric 
303bdd1243dSDimitry Andric   /// Returns a list of filenames of dynamic libraries that this archive has
304bdd1243dSDimitry Andric   /// imported. This class does not load these libraries by itself. User is
305bdd1243dSDimitry Andric   /// responsible for making sure these libraries are avaliable to the JITDylib.
getImportedDynamicLibraries()306bdd1243dSDimitry Andric   const std::set<std::string> &getImportedDynamicLibraries() const {
307bdd1243dSDimitry Andric     return ImportedDynamicLibraries;
308bdd1243dSDimitry Andric   }
309bdd1243dSDimitry Andric 
310e8d8bef9SDimitry Andric   Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
311480093f4SDimitry Andric                       JITDylibLookupFlags JDLookupFlags,
312480093f4SDimitry Andric                       const SymbolLookupSet &Symbols) override;
3138bcb0991SDimitry Andric 
3148bcb0991SDimitry Andric private:
3158bcb0991SDimitry Andric   StaticLibraryDefinitionGenerator(ObjectLayer &L,
3168bcb0991SDimitry Andric                                    std::unique_ptr<MemoryBuffer> ArchiveBuffer,
31706c3fb27SDimitry Andric                                    std::unique_ptr<object::Archive> Archive,
3180eae32dcSDimitry Andric                                    GetObjectFileInterface GetObjFileInterface,
3198bcb0991SDimitry Andric                                    Error &Err);
320bdd1243dSDimitry Andric   Error buildObjectFilesMap();
321bdd1243dSDimitry Andric 
32206c3fb27SDimitry Andric   static Expected<std::pair<size_t, size_t>>
32306c3fb27SDimitry Andric   getSliceRangeForArch(object::MachOUniversalBinary &UB, const Triple &TT);
32406c3fb27SDimitry Andric 
3258bcb0991SDimitry Andric   ObjectLayer &L;
3260eae32dcSDimitry Andric   GetObjectFileInterface GetObjFileInterface;
327bdd1243dSDimitry Andric   std::set<std::string> ImportedDynamicLibraries;
3288bcb0991SDimitry Andric   std::unique_ptr<MemoryBuffer> ArchiveBuffer;
329480093f4SDimitry Andric   std::unique_ptr<object::Archive> Archive;
330bdd1243dSDimitry Andric   DenseMap<SymbolStringPtr, MemoryBufferRef> ObjectFilesMap;
331bdd1243dSDimitry Andric };
332bdd1243dSDimitry Andric 
333bdd1243dSDimitry Andric /// A utility class to create COFF dllimport GOT symbols (__imp_*) and PLT
334bdd1243dSDimitry Andric /// stubs.
335bdd1243dSDimitry Andric ///
336bdd1243dSDimitry Andric /// If an instance of this class is attached to a JITDylib as a fallback
337bdd1243dSDimitry Andric /// definition generator, PLT stubs and dllimport __imp_ symbols will be
338bdd1243dSDimitry Andric /// generated for external symbols found outside the given jitdylib. Currently
339bdd1243dSDimitry Andric /// only supports x86_64 architecture.
340bdd1243dSDimitry Andric class DLLImportDefinitionGenerator : public DefinitionGenerator {
341bdd1243dSDimitry Andric public:
342bdd1243dSDimitry Andric   /// Creates a DLLImportDefinitionGenerator instance.
343bdd1243dSDimitry Andric   static std::unique_ptr<DLLImportDefinitionGenerator>
344bdd1243dSDimitry Andric   Create(ExecutionSession &ES, ObjectLinkingLayer &L);
345bdd1243dSDimitry Andric 
346bdd1243dSDimitry Andric   Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
347bdd1243dSDimitry Andric                       JITDylibLookupFlags JDLookupFlags,
348bdd1243dSDimitry Andric                       const SymbolLookupSet &Symbols) override;
349bdd1243dSDimitry Andric 
350bdd1243dSDimitry Andric private:
DLLImportDefinitionGenerator(ExecutionSession & ES,ObjectLinkingLayer & L)351bdd1243dSDimitry Andric   DLLImportDefinitionGenerator(ExecutionSession &ES, ObjectLinkingLayer &L)
352bdd1243dSDimitry Andric       : ES(ES), L(L) {}
353bdd1243dSDimitry Andric 
354bdd1243dSDimitry Andric   static Expected<unsigned> getTargetPointerSize(const Triple &TT);
3555f757f3fSDimitry Andric   static Expected<llvm::endianness> getTargetEndianness(const Triple &TT);
356bdd1243dSDimitry Andric   Expected<std::unique_ptr<jitlink::LinkGraph>>
357bdd1243dSDimitry Andric   createStubsGraph(const SymbolMap &Resolved);
358bdd1243dSDimitry Andric 
getImpPrefix()359bdd1243dSDimitry Andric   static StringRef getImpPrefix() { return "__imp_"; }
360bdd1243dSDimitry Andric 
getSectionName()361bdd1243dSDimitry Andric   static StringRef getSectionName() { return "$__DLLIMPORT_STUBS"; }
362bdd1243dSDimitry Andric 
363bdd1243dSDimitry Andric   ExecutionSession &ES;
364bdd1243dSDimitry Andric   ObjectLinkingLayer &L;
3658bcb0991SDimitry Andric };
3668bcb0991SDimitry Andric 
3670b57cec5SDimitry Andric } // end namespace orc
3680b57cec5SDimitry Andric } // end namespace llvm
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric #endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
371