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;
331*0fca6ea1SDimitry Andric BumpPtrAllocator ObjFileNameStorage;
332bdd1243dSDimitry Andric };
333bdd1243dSDimitry Andric
334bdd1243dSDimitry Andric /// A utility class to create COFF dllimport GOT symbols (__imp_*) and PLT
335bdd1243dSDimitry Andric /// stubs.
336bdd1243dSDimitry Andric ///
337bdd1243dSDimitry Andric /// If an instance of this class is attached to a JITDylib as a fallback
338bdd1243dSDimitry Andric /// definition generator, PLT stubs and dllimport __imp_ symbols will be
339bdd1243dSDimitry Andric /// generated for external symbols found outside the given jitdylib. Currently
340bdd1243dSDimitry Andric /// only supports x86_64 architecture.
341bdd1243dSDimitry Andric class DLLImportDefinitionGenerator : public DefinitionGenerator {
342bdd1243dSDimitry Andric public:
343bdd1243dSDimitry Andric /// Creates a DLLImportDefinitionGenerator instance.
344bdd1243dSDimitry Andric static std::unique_ptr<DLLImportDefinitionGenerator>
345bdd1243dSDimitry Andric Create(ExecutionSession &ES, ObjectLinkingLayer &L);
346bdd1243dSDimitry Andric
347bdd1243dSDimitry Andric Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
348bdd1243dSDimitry Andric JITDylibLookupFlags JDLookupFlags,
349bdd1243dSDimitry Andric const SymbolLookupSet &Symbols) override;
350bdd1243dSDimitry Andric
351bdd1243dSDimitry Andric private:
DLLImportDefinitionGenerator(ExecutionSession & ES,ObjectLinkingLayer & L)352bdd1243dSDimitry Andric DLLImportDefinitionGenerator(ExecutionSession &ES, ObjectLinkingLayer &L)
353bdd1243dSDimitry Andric : ES(ES), L(L) {}
354bdd1243dSDimitry Andric
355bdd1243dSDimitry Andric static Expected<unsigned> getTargetPointerSize(const Triple &TT);
356*0fca6ea1SDimitry Andric static Expected<llvm::endianness> getEndianness(const Triple &TT);
357bdd1243dSDimitry Andric Expected<std::unique_ptr<jitlink::LinkGraph>>
358bdd1243dSDimitry Andric createStubsGraph(const SymbolMap &Resolved);
359bdd1243dSDimitry Andric
getImpPrefix()360bdd1243dSDimitry Andric static StringRef getImpPrefix() { return "__imp_"; }
361bdd1243dSDimitry Andric
getSectionName()362bdd1243dSDimitry Andric static StringRef getSectionName() { return "$__DLLIMPORT_STUBS"; }
363bdd1243dSDimitry Andric
364bdd1243dSDimitry Andric ExecutionSession &ES;
365bdd1243dSDimitry Andric ObjectLinkingLayer &L;
3668bcb0991SDimitry Andric };
3678bcb0991SDimitry Andric
3680b57cec5SDimitry Andric } // end namespace orc
3690b57cec5SDimitry Andric } // end namespace llvm
3700b57cec5SDimitry Andric
3710b57cec5SDimitry Andric #endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H
372