10b57cec5SDimitry Andric //===- RuntimeDyld.h - Run-time dynamic linker for MC-JIT -------*- 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 // Interface for the runtime dynamic linker facilities of the MC-JIT. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 140b57cec5SDimitry Andric #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 150b57cec5SDimitry Andric 168bcb0991SDimitry Andric #include "llvm/ADT/FunctionExtras.h" 170b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 190b57cec5SDimitry Andric #include "llvm/DebugInfo/DIContext.h" 200b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITSymbol.h" 210b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h" 220b57cec5SDimitry Andric #include "llvm/Support/Error.h" 230b57cec5SDimitry Andric #include <algorithm> 240b57cec5SDimitry Andric #include <cassert> 250b57cec5SDimitry Andric #include <cstddef> 260b57cec5SDimitry Andric #include <cstdint> 270b57cec5SDimitry Andric #include <map> 280b57cec5SDimitry Andric #include <memory> 290b57cec5SDimitry Andric #include <string> 300b57cec5SDimitry Andric #include <system_error> 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric namespace llvm { 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric namespace object { 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric template <typename T> class OwningBinary; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric } // end namespace object 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric /// Base class for errors originating in RuntimeDyld, e.g. missing relocation 410b57cec5SDimitry Andric /// support. 420b57cec5SDimitry Andric class RuntimeDyldError : public ErrorInfo<RuntimeDyldError> { 430b57cec5SDimitry Andric public: 440b57cec5SDimitry Andric static char ID; 450b57cec5SDimitry Andric RuntimeDyldError(std::string ErrMsg)460b57cec5SDimitry Andric RuntimeDyldError(std::string ErrMsg) : ErrMsg(std::move(ErrMsg)) {} 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric void log(raw_ostream &OS) const override; getErrorMessage()490b57cec5SDimitry Andric const std::string &getErrorMessage() const { return ErrMsg; } 500b57cec5SDimitry Andric std::error_code convertToErrorCode() const override; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric private: 530b57cec5SDimitry Andric std::string ErrMsg; 540b57cec5SDimitry Andric }; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric class RuntimeDyldImpl; 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric class RuntimeDyld { 59fe6060f1SDimitry Andric public: 600b57cec5SDimitry Andric // Change the address associated with a section when resolving relocations. 610b57cec5SDimitry Andric // Any relocations already associated with the symbol will be re-resolved. 620b57cec5SDimitry Andric void reassignSectionAddress(unsigned SectionID, uint64_t Addr); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric using NotifyStubEmittedFunction = std::function<void( 650b57cec5SDimitry Andric StringRef FileName, StringRef SectionName, StringRef SymbolName, 660b57cec5SDimitry Andric unsigned SectionID, uint32_t StubOffset)>; 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric /// Information about the loaded object. 690b57cec5SDimitry Andric class LoadedObjectInfo : public llvm::LoadedObjectInfo { 700b57cec5SDimitry Andric friend class RuntimeDyldImpl; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric public: 730b57cec5SDimitry Andric using ObjSectionToIDMap = std::map<object::SectionRef, unsigned>; 740b57cec5SDimitry Andric LoadedObjectInfo(RuntimeDyldImpl & RTDyld,ObjSectionToIDMap ObjSecToIDMap)750b57cec5SDimitry Andric LoadedObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap) 760b57cec5SDimitry Andric : RTDyld(RTDyld), ObjSecToIDMap(std::move(ObjSecToIDMap)) {} 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric virtual object::OwningBinary<object::ObjectFile> 790b57cec5SDimitry Andric getObjectForDebug(const object::ObjectFile &Obj) const = 0; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric uint64_t 820b57cec5SDimitry Andric getSectionLoadAddress(const object::SectionRef &Sec) const override; 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric protected: 850b57cec5SDimitry Andric virtual void anchor(); 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric RuntimeDyldImpl &RTDyld; 880b57cec5SDimitry Andric ObjSectionToIDMap ObjSecToIDMap; 890b57cec5SDimitry Andric }; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// Memory Management. 920b57cec5SDimitry Andric class MemoryManager { 930b57cec5SDimitry Andric friend class RuntimeDyld; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric public: 960b57cec5SDimitry Andric MemoryManager() = default; 970b57cec5SDimitry Andric virtual ~MemoryManager() = default; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric /// Allocate a memory block of (at least) the given size suitable for 1000b57cec5SDimitry Andric /// executable code. The SectionID is a unique identifier assigned by the 1010b57cec5SDimitry Andric /// RuntimeDyld instance, and optionally recorded by the memory manager to 1020b57cec5SDimitry Andric /// access a loaded section. 1030b57cec5SDimitry Andric virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 1040b57cec5SDimitry Andric unsigned SectionID, 1050b57cec5SDimitry Andric StringRef SectionName) = 0; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// Allocate a memory block of (at least) the given size suitable for data. 1080b57cec5SDimitry Andric /// The SectionID is a unique identifier assigned by the JIT engine, and 1090b57cec5SDimitry Andric /// optionally recorded by the memory manager to access a loaded section. 1100b57cec5SDimitry Andric virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 1110b57cec5SDimitry Andric unsigned SectionID, 1120b57cec5SDimitry Andric StringRef SectionName, 1130b57cec5SDimitry Andric bool IsReadOnly) = 0; 1140b57cec5SDimitry Andric 115349cc55cSDimitry Andric /// An allocated TLS section 116349cc55cSDimitry Andric struct TLSSection { 117349cc55cSDimitry Andric /// The pointer to the initialization image 118349cc55cSDimitry Andric uint8_t *InitializationImage; 119349cc55cSDimitry Andric /// The TLS offset 120349cc55cSDimitry Andric intptr_t Offset; 121349cc55cSDimitry Andric }; 122349cc55cSDimitry Andric 123349cc55cSDimitry Andric /// Allocate a memory block of (at least) the given size to be used for 124349cc55cSDimitry Andric /// thread-local storage (TLS). 125349cc55cSDimitry Andric virtual TLSSection allocateTLSSection(uintptr_t Size, unsigned Alignment, 126349cc55cSDimitry Andric unsigned SectionID, 127349cc55cSDimitry Andric StringRef SectionName); 128349cc55cSDimitry Andric 1290b57cec5SDimitry Andric /// Inform the memory manager about the total amount of memory required to 1300b57cec5SDimitry Andric /// allocate all sections to be loaded: 1310b57cec5SDimitry Andric /// \p CodeSize - the total size of all code sections 1320b57cec5SDimitry Andric /// \p DataSizeRO - the total size of all read-only data sections 1330b57cec5SDimitry Andric /// \p DataSizeRW - the total size of all read-write data sections 1340b57cec5SDimitry Andric /// 1350b57cec5SDimitry Andric /// Note that by default the callback is disabled. To enable it 1360b57cec5SDimitry Andric /// redefine the method needsToReserveAllocationSpace to return true. reserveAllocationSpace(uintptr_t CodeSize,Align CodeAlign,uintptr_t RODataSize,Align RODataAlign,uintptr_t RWDataSize,Align RWDataAlign)137bdd1243dSDimitry Andric virtual void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign, 138bdd1243dSDimitry Andric uintptr_t RODataSize, Align RODataAlign, 1390b57cec5SDimitry Andric uintptr_t RWDataSize, 140bdd1243dSDimitry Andric Align RWDataAlign) {} 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric /// Override to return true to enable the reserveAllocationSpace callback. needsToReserveAllocationSpace()1430b57cec5SDimitry Andric virtual bool needsToReserveAllocationSpace() { return false; } 1440b57cec5SDimitry Andric 145fe6060f1SDimitry Andric /// Override to return false to tell LLVM no stub space will be needed. 146fe6060f1SDimitry Andric /// This requires some guarantees depending on architecuture, but when 147fe6060f1SDimitry Andric /// you know what you are doing it saves allocated space. allowStubAllocation()148fe6060f1SDimitry Andric virtual bool allowStubAllocation() const { return true; } 149fe6060f1SDimitry Andric 1500b57cec5SDimitry Andric /// Register the EH frames with the runtime so that c++ exceptions work. 1510b57cec5SDimitry Andric /// 1520b57cec5SDimitry Andric /// \p Addr parameter provides the local address of the EH frame section 1530b57cec5SDimitry Andric /// data, while \p LoadAddr provides the address of the data in the target 1540b57cec5SDimitry Andric /// address space. If the section has not been remapped (which will usually 1550b57cec5SDimitry Andric /// be the case for local execution) these two values will be the same. 1560b57cec5SDimitry Andric virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 1570b57cec5SDimitry Andric size_t Size) = 0; 1580b57cec5SDimitry Andric virtual void deregisterEHFrames() = 0; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric /// This method is called when object loading is complete and section page 1610b57cec5SDimitry Andric /// permissions can be applied. It is up to the memory manager implementation 1620b57cec5SDimitry Andric /// to decide whether or not to act on this method. The memory manager will 1630b57cec5SDimitry Andric /// typically allocate all sections as read-write and then apply specific 1640b57cec5SDimitry Andric /// permissions when this method is called. Code sections cannot be executed 1650b57cec5SDimitry Andric /// until this function has been called. In addition, any cache coherency 1660b57cec5SDimitry Andric /// operations needed to reliably use the memory are also performed. 1670b57cec5SDimitry Andric /// 1680b57cec5SDimitry Andric /// Returns true if an error occurred, false otherwise. 1690b57cec5SDimitry Andric virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric /// This method is called after an object has been loaded into memory but 1720b57cec5SDimitry Andric /// before relocations are applied to the loaded sections. 1730b57cec5SDimitry Andric /// 1740b57cec5SDimitry Andric /// Memory managers which are preparing code for execution in an external 1750b57cec5SDimitry Andric /// address space can use this call to remap the section addresses for the 1760b57cec5SDimitry Andric /// newly loaded object. 1770b57cec5SDimitry Andric /// 1780b57cec5SDimitry Andric /// For clients that do not need access to an ExecutionEngine instance this 1790b57cec5SDimitry Andric /// method should be preferred to its cousin 1800b57cec5SDimitry Andric /// MCJITMemoryManager::notifyObjectLoaded as this method is compatible with 1810b57cec5SDimitry Andric /// ORC JIT stacks. notifyObjectLoaded(RuntimeDyld & RTDyld,const object::ObjectFile & Obj)1820b57cec5SDimitry Andric virtual void notifyObjectLoaded(RuntimeDyld &RTDyld, 1830b57cec5SDimitry Andric const object::ObjectFile &Obj) {} 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric private: 1860b57cec5SDimitry Andric virtual void anchor(); 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric bool FinalizationLocked = false; 1890b57cec5SDimitry Andric }; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric /// Construct a RuntimeDyld instance. 1920b57cec5SDimitry Andric RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver); 1930b57cec5SDimitry Andric RuntimeDyld(const RuntimeDyld &) = delete; 1940b57cec5SDimitry Andric RuntimeDyld &operator=(const RuntimeDyld &) = delete; 1950b57cec5SDimitry Andric ~RuntimeDyld(); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric /// Add the referenced object file to the list of objects to be loaded and 1980b57cec5SDimitry Andric /// relocated. 1990b57cec5SDimitry Andric std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric /// Get the address of our local copy of the symbol. This may or may not 2020b57cec5SDimitry Andric /// be the address used for relocation (clients can copy the data around 2030b57cec5SDimitry Andric /// and resolve relocatons based on where they put it). 2040b57cec5SDimitry Andric void *getSymbolLocalAddress(StringRef Name) const; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric /// Get the section ID for the section containing the given symbol. 2070b57cec5SDimitry Andric unsigned getSymbolSectionID(StringRef Name) const; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric /// Get the target address and flags for the named symbol. 2100b57cec5SDimitry Andric /// This address is the one used for relocation. 2110b57cec5SDimitry Andric JITEvaluatedSymbol getSymbol(StringRef Name) const; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric /// Returns a copy of the symbol table. This can be used by on-finalized 2140b57cec5SDimitry Andric /// callbacks to extract the symbol table before throwing away the 2150b57cec5SDimitry Andric /// RuntimeDyld instance. Because the map keys (StringRefs) are backed by 2160b57cec5SDimitry Andric /// strings inside the RuntimeDyld instance, the map should be processed 2170b57cec5SDimitry Andric /// before the RuntimeDyld instance is discarded. 2180b57cec5SDimitry Andric std::map<StringRef, JITEvaluatedSymbol> getSymbolTable() const; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric /// Resolve the relocations for all symbols we currently know about. 2210b57cec5SDimitry Andric void resolveRelocations(); 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric /// Map a section to its target address space value. 2240b57cec5SDimitry Andric /// Map the address of a JIT section as returned from the memory manager 2250b57cec5SDimitry Andric /// to the address in the target process as the running code will see it. 2260b57cec5SDimitry Andric /// This is the address which will be used for relocation resolution. 2270b57cec5SDimitry Andric void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric /// Returns the section's working memory. 2300b57cec5SDimitry Andric StringRef getSectionContent(unsigned SectionID) const; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric /// If the section was loaded, return the section's load address, 233bdd1243dSDimitry Andric /// otherwise return std::nullopt. 2340b57cec5SDimitry Andric uint64_t getSectionLoadAddress(unsigned SectionID) const; 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric /// Set the NotifyStubEmitted callback. This is used for debugging 2370b57cec5SDimitry Andric /// purposes. A callback is made for each stub that is generated. setNotifyStubEmitted(NotifyStubEmittedFunction NotifyStubEmitted)2380b57cec5SDimitry Andric void setNotifyStubEmitted(NotifyStubEmittedFunction NotifyStubEmitted) { 2390b57cec5SDimitry Andric this->NotifyStubEmitted = std::move(NotifyStubEmitted); 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric /// Register any EH frame sections that have been loaded but not previously 2430b57cec5SDimitry Andric /// registered with the memory manager. Note, RuntimeDyld is responsible 2440b57cec5SDimitry Andric /// for identifying the EH frame and calling the memory manager with the 2450b57cec5SDimitry Andric /// EH frame section data. However, the memory manager itself will handle 2460b57cec5SDimitry Andric /// the actual target-specific EH frame registration. 2470b57cec5SDimitry Andric void registerEHFrames(); 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric void deregisterEHFrames(); 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric bool hasError(); 2520b57cec5SDimitry Andric StringRef getErrorString(); 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric /// By default, only sections that are "required for execution" are passed to 2550b57cec5SDimitry Andric /// the RTDyldMemoryManager, and other sections are discarded. Passing 'true' 2560b57cec5SDimitry Andric /// to this method will cause RuntimeDyld to pass all sections to its 2570b57cec5SDimitry Andric /// memory manager regardless of whether they are "required to execute" in the 2580b57cec5SDimitry Andric /// usual sense. This is useful for inspecting metadata sections that may not 2590b57cec5SDimitry Andric /// contain relocations, E.g. Debug info, stackmaps. 2600b57cec5SDimitry Andric /// 2610b57cec5SDimitry Andric /// Must be called before the first object file is loaded. setProcessAllSections(bool ProcessAllSections)2620b57cec5SDimitry Andric void setProcessAllSections(bool ProcessAllSections) { 2630b57cec5SDimitry Andric assert(!Dyld && "setProcessAllSections must be called before loadObject."); 2640b57cec5SDimitry Andric this->ProcessAllSections = ProcessAllSections; 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric /// Perform all actions needed to make the code owned by this RuntimeDyld 2680b57cec5SDimitry Andric /// instance executable: 2690b57cec5SDimitry Andric /// 2700b57cec5SDimitry Andric /// 1) Apply relocations. 2710b57cec5SDimitry Andric /// 2) Register EH frames. 2720b57cec5SDimitry Andric /// 3) Update memory permissions*. 2730b57cec5SDimitry Andric /// 2740b57cec5SDimitry Andric /// * Finalization is potentially recursive**, and the 3rd step will only be 2750b57cec5SDimitry Andric /// applied by the outermost call to finalize. This allows different 2760b57cec5SDimitry Andric /// RuntimeDyld instances to share a memory manager without the innermost 2770b57cec5SDimitry Andric /// finalization locking the memory and causing relocation fixup errors in 2780b57cec5SDimitry Andric /// outer instances. 2790b57cec5SDimitry Andric /// 2800b57cec5SDimitry Andric /// ** Recursive finalization occurs when one RuntimeDyld instances needs the 2810b57cec5SDimitry Andric /// address of a symbol owned by some other instance in order to apply 2820b57cec5SDimitry Andric /// relocations. 2830b57cec5SDimitry Andric /// 2840b57cec5SDimitry Andric void finalizeWithMemoryManagerLocking(); 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric private: 2875ffd83dbSDimitry Andric friend void jitLinkForORC( 2885ffd83dbSDimitry Andric object::OwningBinary<object::ObjectFile> O, 2890b57cec5SDimitry Andric RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, 2900b57cec5SDimitry Andric bool ProcessAllSections, 291e8d8bef9SDimitry Andric unique_function<Error(const object::ObjectFile &Obj, LoadedObjectInfo &, 2920b57cec5SDimitry Andric std::map<StringRef, JITEvaluatedSymbol>)> 2930b57cec5SDimitry Andric OnLoaded, 294e8d8bef9SDimitry Andric unique_function<void(object::OwningBinary<object::ObjectFile> O, 295e8d8bef9SDimitry Andric std::unique_ptr<LoadedObjectInfo>, Error)> 2965ffd83dbSDimitry Andric OnEmitted); 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public 2990b57cec5SDimitry Andric // interface. 3000b57cec5SDimitry Andric std::unique_ptr<RuntimeDyldImpl> Dyld; 3010b57cec5SDimitry Andric MemoryManager &MemMgr; 3020b57cec5SDimitry Andric JITSymbolResolver &Resolver; 3030b57cec5SDimitry Andric bool ProcessAllSections; 3040b57cec5SDimitry Andric NotifyStubEmittedFunction NotifyStubEmitted; 3050b57cec5SDimitry Andric }; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric // Asynchronous JIT link for ORC. 3080b57cec5SDimitry Andric // 3090b57cec5SDimitry Andric // Warning: This API is experimental and probably should not be used by anyone 3100b57cec5SDimitry Andric // but ORC's RTDyldObjectLinkingLayer2. Internally it constructs a RuntimeDyld 3110b57cec5SDimitry Andric // instance and uses continuation passing to perform the fix-up and finalize 3120b57cec5SDimitry Andric // steps asynchronously. 3138bcb0991SDimitry Andric void jitLinkForORC( 3145ffd83dbSDimitry Andric object::OwningBinary<object::ObjectFile> O, 3158bcb0991SDimitry Andric RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, 3168bcb0991SDimitry Andric bool ProcessAllSections, 3175ffd83dbSDimitry Andric unique_function<Error(const object::ObjectFile &Obj, 318e8d8bef9SDimitry Andric RuntimeDyld::LoadedObjectInfo &, 3190b57cec5SDimitry Andric std::map<StringRef, JITEvaluatedSymbol>)> 3200b57cec5SDimitry Andric OnLoaded, 321e8d8bef9SDimitry Andric unique_function<void(object::OwningBinary<object::ObjectFile>, 322e8d8bef9SDimitry Andric std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)> 3235ffd83dbSDimitry Andric OnEmitted); 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric } // end namespace llvm 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric #endif // LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 328