1 //===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Interface for the runtime dynamic linker facilities of the MC-JIT. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 15 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 16 17 #include "JITSymbolFlags.h" 18 #include "llvm/ADT/STLExtras.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/Object/ObjectFile.h" 21 #include "llvm/Support/Memory.h" 22 #include "llvm/DebugInfo/DIContext.h" 23 #include <map> 24 #include <memory> 25 26 namespace llvm { 27 28 namespace object { 29 class ObjectFile; 30 template <typename T> class OwningBinary; 31 } 32 33 class RuntimeDyldImpl; 34 class RuntimeDyldCheckerImpl; 35 36 class RuntimeDyld { 37 friend class RuntimeDyldCheckerImpl; 38 39 RuntimeDyld(const RuntimeDyld &) = delete; 40 void operator=(const RuntimeDyld &) = delete; 41 42 protected: 43 // Change the address associated with a section when resolving relocations. 44 // Any relocations already associated with the symbol will be re-resolved. 45 void reassignSectionAddress(unsigned SectionID, uint64_t Addr); 46 public: 47 48 /// \brief Information about a named symbol. 49 class SymbolInfo : public JITSymbolBase { 50 public: SymbolInfo(std::nullptr_t)51 SymbolInfo(std::nullptr_t) : JITSymbolBase(JITSymbolFlags::None), Address(0) {} SymbolInfo(uint64_t Address,JITSymbolFlags Flags)52 SymbolInfo(uint64_t Address, JITSymbolFlags Flags) 53 : JITSymbolBase(Flags), Address(Address) {} 54 explicit operator bool() const { return Address != 0; } getAddress()55 uint64_t getAddress() const { return Address; } 56 private: 57 uint64_t Address; 58 }; 59 60 /// \brief Information about the loaded object. 61 class LoadedObjectInfo : public llvm::LoadedObjectInfo { 62 friend class RuntimeDyldImpl; 63 public: 64 typedef std::map<object::SectionRef, unsigned> ObjSectionToIDMap; 65 LoadedObjectInfo(RuntimeDyldImpl & RTDyld,ObjSectionToIDMap ObjSecToIDMap)66 LoadedObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap) 67 : RTDyld(RTDyld), ObjSecToIDMap(ObjSecToIDMap) { } 68 69 virtual object::OwningBinary<object::ObjectFile> 70 getObjectForDebug(const object::ObjectFile &Obj) const = 0; 71 72 uint64_t 73 getSectionLoadAddress(const object::SectionRef &Sec) const override; 74 75 protected: 76 virtual void anchor(); 77 78 RuntimeDyldImpl &RTDyld; 79 ObjSectionToIDMap ObjSecToIDMap; 80 }; 81 82 template <typename Derived> struct LoadedObjectInfoHelper : LoadedObjectInfo { 83 protected: 84 LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default; 85 LoadedObjectInfoHelper() = default; 86 87 public: LoadedObjectInfoHelperLoadedObjectInfoHelper88 LoadedObjectInfoHelper(RuntimeDyldImpl &RTDyld, 89 LoadedObjectInfo::ObjSectionToIDMap ObjSecToIDMap) 90 : LoadedObjectInfo(RTDyld, std::move(ObjSecToIDMap)) {} cloneLoadedObjectInfoHelper91 std::unique_ptr<llvm::LoadedObjectInfo> clone() const override { 92 return llvm::make_unique<Derived>(static_cast<const Derived &>(*this)); 93 } 94 }; 95 96 /// \brief Memory Management. 97 class MemoryManager { 98 public: ~MemoryManager()99 virtual ~MemoryManager() {} 100 101 /// Allocate a memory block of (at least) the given size suitable for 102 /// executable code. The SectionID is a unique identifier assigned by the 103 /// RuntimeDyld instance, and optionally recorded by the memory manager to 104 /// access a loaded section. 105 virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 106 unsigned SectionID, 107 StringRef SectionName) = 0; 108 109 /// Allocate a memory block of (at least) the given size suitable for data. 110 /// The SectionID is a unique identifier assigned by the JIT engine, and 111 /// optionally recorded by the memory manager to access a loaded section. 112 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 113 unsigned SectionID, 114 StringRef SectionName, 115 bool IsReadOnly) = 0; 116 117 /// Inform the memory manager about the total amount of memory required to 118 /// allocate all sections to be loaded: 119 /// \p CodeSize - the total size of all code sections 120 /// \p DataSizeRO - the total size of all read-only data sections 121 /// \p DataSizeRW - the total size of all read-write data sections 122 /// 123 /// Note that by default the callback is disabled. To enable it 124 /// redefine the method needsToReserveAllocationSpace to return true. reserveAllocationSpace(uintptr_t CodeSize,uintptr_t DataSizeRO,uintptr_t DataSizeRW)125 virtual void reserveAllocationSpace(uintptr_t CodeSize, 126 uintptr_t DataSizeRO, 127 uintptr_t DataSizeRW) {} 128 129 /// Override to return true to enable the reserveAllocationSpace callback. needsToReserveAllocationSpace()130 virtual bool needsToReserveAllocationSpace() { return false; } 131 132 /// Register the EH frames with the runtime so that c++ exceptions work. 133 /// 134 /// \p Addr parameter provides the local address of the EH frame section 135 /// data, while \p LoadAddr provides the address of the data in the target 136 /// address space. If the section has not been remapped (which will usually 137 /// be the case for local execution) these two values will be the same. 138 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 139 size_t Size) = 0; 140 virtual void deregisterEHFrames(uint8_t *addr, uint64_t LoadAddr, 141 size_t Size) = 0; 142 143 /// This method is called when object loading is complete and section page 144 /// permissions can be applied. It is up to the memory manager implementation 145 /// to decide whether or not to act on this method. The memory manager will 146 /// typically allocate all sections as read-write and then apply specific 147 /// permissions when this method is called. Code sections cannot be executed 148 /// until this function has been called. In addition, any cache coherency 149 /// operations needed to reliably use the memory are also performed. 150 /// 151 /// Returns true if an error occurred, false otherwise. 152 virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0; 153 154 private: 155 virtual void anchor(); 156 }; 157 158 /// \brief Symbol resolution. 159 class SymbolResolver { 160 public: ~SymbolResolver()161 virtual ~SymbolResolver() {} 162 163 /// This method returns the address of the specified function or variable. 164 /// It is used to resolve symbols during module linking. 165 /// 166 /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will 167 /// skip all relocations for that symbol, and the client will be responsible 168 /// for handling them manually. 169 virtual SymbolInfo findSymbol(const std::string &Name) = 0; 170 171 /// This method returns the address of the specified symbol if it exists 172 /// within the logical dynamic library represented by this 173 /// RTDyldMemoryManager. Unlike getSymbolAddress, queries through this 174 /// interface should return addresses for hidden symbols. 175 /// 176 /// This is of particular importance for the Orc JIT APIs, which support lazy 177 /// compilation by breaking up modules: Each of those broken out modules 178 /// must be able to resolve hidden symbols provided by the others. Clients 179 /// writing memory managers for MCJIT can usually ignore this method. 180 /// 181 /// This method will be queried by RuntimeDyld when checking for previous 182 /// definitions of common symbols. It will *not* be queried by default when 183 /// resolving external symbols (this minimises the link-time overhead for 184 /// MCJIT clients who don't care about Orc features). If you are writing a 185 /// RTDyldMemoryManager for Orc and want "external" symbol resolution to 186 /// search the logical dylib, you should override your getSymbolAddress 187 /// method call this method directly. 188 virtual SymbolInfo findSymbolInLogicalDylib(const std::string &Name) = 0; 189 private: 190 virtual void anchor(); 191 }; 192 193 /// \brief Construct a RuntimeDyld instance. 194 RuntimeDyld(MemoryManager &MemMgr, SymbolResolver &Resolver); 195 ~RuntimeDyld(); 196 197 /// Add the referenced object file to the list of objects to be loaded and 198 /// relocated. 199 std::unique_ptr<LoadedObjectInfo> loadObject(const object::ObjectFile &O); 200 201 /// Get the address of our local copy of the symbol. This may or may not 202 /// be the address used for relocation (clients can copy the data around 203 /// and resolve relocatons based on where they put it). 204 void *getSymbolLocalAddress(StringRef Name) const; 205 206 /// Get the target address and flags for the named symbol. 207 /// This address is the one used for relocation. 208 SymbolInfo getSymbol(StringRef Name) const; 209 210 /// Resolve the relocations for all symbols we currently know about. 211 void resolveRelocations(); 212 213 /// Map a section to its target address space value. 214 /// Map the address of a JIT section as returned from the memory manager 215 /// to the address in the target process as the running code will see it. 216 /// This is the address which will be used for relocation resolution. 217 void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); 218 219 /// Register any EH frame sections that have been loaded but not previously 220 /// registered with the memory manager. Note, RuntimeDyld is responsible 221 /// for identifying the EH frame and calling the memory manager with the 222 /// EH frame section data. However, the memory manager itself will handle 223 /// the actual target-specific EH frame registration. 224 void registerEHFrames(); 225 226 void deregisterEHFrames(); 227 228 bool hasError(); 229 StringRef getErrorString(); 230 231 /// By default, only sections that are "required for execution" are passed to 232 /// the RTDyldMemoryManager, and other sections are discarded. Passing 'true' 233 /// to this method will cause RuntimeDyld to pass all sections to its 234 /// memory manager regardless of whether they are "required to execute" in the 235 /// usual sense. This is useful for inspecting metadata sections that may not 236 /// contain relocations, E.g. Debug info, stackmaps. 237 /// 238 /// Must be called before the first object file is loaded. setProcessAllSections(bool ProcessAllSections)239 void setProcessAllSections(bool ProcessAllSections) { 240 assert(!Dyld && "setProcessAllSections must be called before loadObject."); 241 this->ProcessAllSections = ProcessAllSections; 242 } 243 244 private: 245 // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public 246 // interface. 247 std::unique_ptr<RuntimeDyldImpl> Dyld; 248 MemoryManager &MemMgr; 249 SymbolResolver &Resolver; 250 bool ProcessAllSections; 251 RuntimeDyldCheckerImpl *Checker; 252 }; 253 254 } // end namespace llvm 255 256 #endif // LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 257