1 //===- RuntimeDyld.h - Run-time dynamic linker for MC-JIT -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Interface for the runtime dynamic linker facilities of the MC-JIT. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 14 #define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 15 16 #include "llvm/ADT/FunctionExtras.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/DebugInfo/DIContext.h" 20 #include "llvm/ExecutionEngine/JITSymbol.h" 21 #include "llvm/Object/ObjectFile.h" 22 #include "llvm/Support/Compiler.h" 23 #include "llvm/Support/Error.h" 24 #include <algorithm> 25 #include <cassert> 26 #include <cstddef> 27 #include <cstdint> 28 #include <map> 29 #include <memory> 30 #include <string> 31 #include <system_error> 32 33 namespace llvm { 34 35 namespace object { 36 37 template <typename T> class OwningBinary; 38 39 } // end namespace object 40 41 /// Base class for errors originating in RuntimeDyld, e.g. missing relocation 42 /// support. 43 class LLVM_ABI RuntimeDyldError : public ErrorInfo<RuntimeDyldError> { 44 public: 45 static char ID; 46 RuntimeDyldError(std::string ErrMsg)47 RuntimeDyldError(std::string ErrMsg) : ErrMsg(std::move(ErrMsg)) {} 48 49 void log(raw_ostream &OS) const override; getErrorMessage()50 const std::string &getErrorMessage() const { return ErrMsg; } 51 std::error_code convertToErrorCode() const override; 52 53 private: 54 std::string ErrMsg; 55 }; 56 57 class RuntimeDyldImpl; 58 59 class RuntimeDyld { 60 public: 61 // Change the address associated with a section when resolving relocations. 62 // Any relocations already associated with the symbol will be re-resolved. 63 LLVM_ABI void reassignSectionAddress(unsigned SectionID, uint64_t Addr); 64 65 using NotifyStubEmittedFunction = std::function<void( 66 StringRef FileName, StringRef SectionName, StringRef SymbolName, 67 unsigned SectionID, uint32_t StubOffset)>; 68 69 /// Information about the loaded object. 70 class LLVM_ABI LoadedObjectInfo : public llvm::LoadedObjectInfo { 71 friend class RuntimeDyldImpl; 72 73 public: 74 using ObjSectionToIDMap = std::map<object::SectionRef, unsigned>; 75 LoadedObjectInfo(RuntimeDyldImpl & RTDyld,ObjSectionToIDMap ObjSecToIDMap)76 LoadedObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap) 77 : RTDyld(RTDyld), ObjSecToIDMap(std::move(ObjSecToIDMap)) {} 78 79 virtual object::OwningBinary<object::ObjectFile> 80 getObjectForDebug(const object::ObjectFile &Obj) const = 0; 81 82 uint64_t 83 getSectionLoadAddress(const object::SectionRef &Sec) const override; 84 85 protected: 86 virtual void anchor(); 87 88 RuntimeDyldImpl &RTDyld; 89 ObjSectionToIDMap ObjSecToIDMap; 90 }; 91 92 /// Memory Management. 93 class LLVM_ABI MemoryManager { 94 friend class RuntimeDyld; 95 96 public: 97 MemoryManager() = default; 98 virtual ~MemoryManager() = default; 99 100 /// Allocate a memory block of (at least) the given size suitable for 101 /// executable code. The SectionID is a unique identifier assigned by the 102 /// RuntimeDyld instance, and optionally recorded by the memory manager to 103 /// access a loaded section. 104 virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 105 unsigned SectionID, 106 StringRef SectionName) = 0; 107 108 /// Allocate a memory block of (at least) the given size suitable for data. 109 /// The SectionID is a unique identifier assigned by the JIT engine, and 110 /// optionally recorded by the memory manager to access a loaded section. 111 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 112 unsigned SectionID, 113 StringRef SectionName, 114 bool IsReadOnly) = 0; 115 116 /// An allocated TLS section 117 struct TLSSection { 118 /// The pointer to the initialization image 119 uint8_t *InitializationImage; 120 /// The TLS offset 121 intptr_t Offset; 122 }; 123 124 /// Allocate a memory block of (at least) the given size to be used for 125 /// thread-local storage (TLS). 126 virtual TLSSection allocateTLSSection(uintptr_t Size, unsigned Alignment, 127 unsigned SectionID, 128 StringRef SectionName); 129 130 /// Inform the memory manager about the total amount of memory required to 131 /// allocate all sections to be loaded: 132 /// \p CodeSize - the total size of all code sections 133 /// \p DataSizeRO - the total size of all read-only data sections 134 /// \p DataSizeRW - the total size of all read-write data sections 135 /// 136 /// Note that by default the callback is disabled. To enable it 137 /// redefine the method needsToReserveAllocationSpace to return true. reserveAllocationSpace(uintptr_t CodeSize,Align CodeAlign,uintptr_t RODataSize,Align RODataAlign,uintptr_t RWDataSize,Align RWDataAlign)138 virtual void reserveAllocationSpace(uintptr_t CodeSize, Align CodeAlign, 139 uintptr_t RODataSize, Align RODataAlign, 140 uintptr_t RWDataSize, 141 Align RWDataAlign) {} 142 143 /// Override to return true to enable the reserveAllocationSpace callback. needsToReserveAllocationSpace()144 virtual bool needsToReserveAllocationSpace() { return false; } 145 146 /// Override to return false to tell LLVM no stub space will be needed. 147 /// This requires some guarantees depending on architecuture, but when 148 /// you know what you are doing it saves allocated space. allowStubAllocation()149 virtual bool allowStubAllocation() const { return true; } 150 151 /// Register the EH frames with the runtime so that c++ exceptions work. 152 /// 153 /// \p Addr parameter provides the local address of the EH frame section 154 /// data, while \p LoadAddr provides the address of the data in the target 155 /// address space. If the section has not been remapped (which will usually 156 /// be the case for local execution) these two values will be the same. 157 virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 158 size_t Size) = 0; 159 virtual void deregisterEHFrames() = 0; 160 161 /// This method is called when object loading is complete and section page 162 /// permissions can be applied. It is up to the memory manager implementation 163 /// to decide whether or not to act on this method. The memory manager will 164 /// typically allocate all sections as read-write and then apply specific 165 /// permissions when this method is called. Code sections cannot be executed 166 /// until this function has been called. In addition, any cache coherency 167 /// operations needed to reliably use the memory are also performed. 168 /// 169 /// Returns true if an error occurred, false otherwise. 170 virtual bool finalizeMemory(std::string *ErrMsg = nullptr) = 0; 171 172 /// This method is called after an object has been loaded into memory but 173 /// before relocations are applied to the loaded sections. 174 /// 175 /// Memory managers which are preparing code for execution in an external 176 /// address space can use this call to remap the section addresses for the 177 /// newly loaded object. 178 /// 179 /// For clients that do not need access to an ExecutionEngine instance this 180 /// method should be preferred to its cousin 181 /// MCJITMemoryManager::notifyObjectLoaded as this method is compatible with 182 /// ORC JIT stacks. notifyObjectLoaded(RuntimeDyld & RTDyld,const object::ObjectFile & Obj)183 virtual void notifyObjectLoaded(RuntimeDyld &RTDyld, 184 const object::ObjectFile &Obj) {} 185 186 private: 187 virtual void anchor(); 188 189 bool FinalizationLocked = false; 190 }; 191 192 /// Construct a RuntimeDyld instance. 193 LLVM_ABI RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver); 194 RuntimeDyld(const RuntimeDyld &) = delete; 195 RuntimeDyld &operator=(const RuntimeDyld &) = delete; 196 LLVM_ABI ~RuntimeDyld(); 197 198 /// Add the referenced object file to the list of objects to be loaded and 199 /// relocated. 200 LLVM_ABI std::unique_ptr<LoadedObjectInfo> 201 loadObject(const object::ObjectFile &O); 202 203 /// Get the address of our local copy of the symbol. This may or may not 204 /// be the address used for relocation (clients can copy the data around 205 /// and resolve relocatons based on where they put it). 206 LLVM_ABI void *getSymbolLocalAddress(StringRef Name) const; 207 208 /// Get the section ID for the section containing the given symbol. 209 LLVM_ABI unsigned getSymbolSectionID(StringRef Name) const; 210 211 /// Get the target address and flags for the named symbol. 212 /// This address is the one used for relocation. 213 LLVM_ABI JITEvaluatedSymbol getSymbol(StringRef Name) const; 214 215 /// Returns a copy of the symbol table. This can be used by on-finalized 216 /// callbacks to extract the symbol table before throwing away the 217 /// RuntimeDyld instance. Because the map keys (StringRefs) are backed by 218 /// strings inside the RuntimeDyld instance, the map should be processed 219 /// before the RuntimeDyld instance is discarded. 220 LLVM_ABI std::map<StringRef, JITEvaluatedSymbol> getSymbolTable() const; 221 222 /// Resolve the relocations for all symbols we currently know about. 223 LLVM_ABI void resolveRelocations(); 224 225 /// Map a section to its target address space value. 226 /// Map the address of a JIT section as returned from the memory manager 227 /// to the address in the target process as the running code will see it. 228 /// This is the address which will be used for relocation resolution. 229 LLVM_ABI void mapSectionAddress(const void *LocalAddress, 230 uint64_t TargetAddress); 231 232 /// Returns the section's working memory. 233 LLVM_ABI StringRef getSectionContent(unsigned SectionID) const; 234 235 /// If the section was loaded, return the section's load address, 236 /// otherwise return std::nullopt. 237 LLVM_ABI uint64_t getSectionLoadAddress(unsigned SectionID) const; 238 239 /// Set the NotifyStubEmitted callback. This is used for debugging 240 /// purposes. A callback is made for each stub that is generated. setNotifyStubEmitted(NotifyStubEmittedFunction NotifyStubEmitted)241 void setNotifyStubEmitted(NotifyStubEmittedFunction NotifyStubEmitted) { 242 this->NotifyStubEmitted = std::move(NotifyStubEmitted); 243 } 244 245 /// Register any EH frame sections that have been loaded but not previously 246 /// registered with the memory manager. Note, RuntimeDyld is responsible 247 /// for identifying the EH frame and calling the memory manager with the 248 /// EH frame section data. However, the memory manager itself will handle 249 /// the actual target-specific EH frame registration. 250 LLVM_ABI void registerEHFrames(); 251 252 LLVM_ABI void deregisterEHFrames(); 253 254 LLVM_ABI bool hasError(); 255 LLVM_ABI StringRef getErrorString(); 256 257 /// By default, only sections that are "required for execution" are passed to 258 /// the RTDyldMemoryManager, and other sections are discarded. Passing 'true' 259 /// to this method will cause RuntimeDyld to pass all sections to its 260 /// memory manager regardless of whether they are "required to execute" in the 261 /// usual sense. This is useful for inspecting metadata sections that may not 262 /// contain relocations, E.g. Debug info, stackmaps. 263 /// 264 /// Must be called before the first object file is loaded. setProcessAllSections(bool ProcessAllSections)265 void setProcessAllSections(bool ProcessAllSections) { 266 assert(!Dyld && "setProcessAllSections must be called before loadObject."); 267 this->ProcessAllSections = ProcessAllSections; 268 } 269 270 /// Perform all actions needed to make the code owned by this RuntimeDyld 271 /// instance executable: 272 /// 273 /// 1) Apply relocations. 274 /// 2) Register EH frames. 275 /// 3) Update memory permissions*. 276 /// 277 /// * Finalization is potentially recursive**, and the 3rd step will only be 278 /// applied by the outermost call to finalize. This allows different 279 /// RuntimeDyld instances to share a memory manager without the innermost 280 /// finalization locking the memory and causing relocation fixup errors in 281 /// outer instances. 282 /// 283 /// ** Recursive finalization occurs when one RuntimeDyld instances needs the 284 /// address of a symbol owned by some other instance in order to apply 285 /// relocations. 286 /// 287 LLVM_ABI void finalizeWithMemoryManagerLocking(); 288 289 private: 290 LLVM_ABI friend void jitLinkForORC( 291 object::OwningBinary<object::ObjectFile> O, 292 RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, 293 bool ProcessAllSections, 294 unique_function<Error(const object::ObjectFile &Obj, LoadedObjectInfo &, 295 std::map<StringRef, JITEvaluatedSymbol>)> 296 OnLoaded, 297 unique_function<void(object::OwningBinary<object::ObjectFile> O, 298 std::unique_ptr<LoadedObjectInfo>, Error)> 299 OnEmitted); 300 301 // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public 302 // interface. 303 std::unique_ptr<RuntimeDyldImpl> Dyld; 304 MemoryManager &MemMgr; 305 JITSymbolResolver &Resolver; 306 bool ProcessAllSections; 307 NotifyStubEmittedFunction NotifyStubEmitted; 308 }; 309 310 // Asynchronous JIT link for ORC. 311 // 312 // Warning: This API is experimental and probably should not be used by anyone 313 // but ORC's RTDyldObjectLinkingLayer2. Internally it constructs a RuntimeDyld 314 // instance and uses continuation passing to perform the fix-up and finalize 315 // steps asynchronously. 316 LLVM_ABI void jitLinkForORC( 317 object::OwningBinary<object::ObjectFile> O, 318 RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, 319 bool ProcessAllSections, 320 unique_function<Error(const object::ObjectFile &Obj, 321 RuntimeDyld::LoadedObjectInfo &, 322 std::map<StringRef, JITEvaluatedSymbol>)> 323 OnLoaded, 324 unique_function<void(object::OwningBinary<object::ObjectFile>, 325 std::unique_ptr<RuntimeDyld::LoadedObjectInfo>, Error)> 326 OnEmitted); 327 328 } // end namespace llvm 329 330 #endif // LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H 331