1 //===-- RuntimeDyldImpl.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 implementations of runtime dynamic linker facilities. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDIMPL_H 15 #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDIMPL_H 16 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/ADT/Triple.h" 21 #include "llvm/ExecutionEngine/RuntimeDyld.h" 22 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" 23 #include "llvm/Object/ObjectFile.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/Format.h" 27 #include "llvm/Support/Host.h" 28 #include "llvm/Support/Mutex.h" 29 #include "llvm/Support/SwapByteOrder.h" 30 #include "llvm/Support/raw_ostream.h" 31 #include <map> 32 #include <system_error> 33 34 using namespace llvm; 35 using namespace llvm::object; 36 37 namespace llvm { 38 39 class Twine; 40 41 /// SectionEntry - represents a section emitted into memory by the dynamic 42 /// linker. 43 class SectionEntry { 44 public: 45 /// Name - section name. 46 StringRef Name; 47 48 /// Address - address in the linker's memory where the section resides. 49 uint8_t *Address; 50 51 /// Size - section size. Doesn't include the stubs. 52 size_t Size; 53 54 /// LoadAddress - the address of the section in the target process's memory. 55 /// Used for situations in which JIT-ed code is being executed in the address 56 /// space of a separate process. If the code executes in the same address 57 /// space where it was JIT-ed, this just equals Address. 58 uint64_t LoadAddress; 59 60 /// StubOffset - used for architectures with stub functions for far 61 /// relocations (like ARM). 62 uintptr_t StubOffset; 63 64 /// ObjAddress - address of the section in the in-memory object file. Used 65 /// for calculating relocations in some object formats (like MachO). 66 uintptr_t ObjAddress; 67 SectionEntry(StringRef name,uint8_t * address,size_t size,uintptr_t objAddress)68 SectionEntry(StringRef name, uint8_t *address, size_t size, 69 uintptr_t objAddress) 70 : Name(name), Address(address), Size(size), 71 LoadAddress(reinterpret_cast<uintptr_t>(address)), StubOffset(size), 72 ObjAddress(objAddress) {} 73 }; 74 75 /// RelocationEntry - used to represent relocations internally in the dynamic 76 /// linker. 77 class RelocationEntry { 78 public: 79 /// SectionID - the section this relocation points to. 80 unsigned SectionID; 81 82 /// Offset - offset into the section. 83 uint64_t Offset; 84 85 /// RelType - relocation type. 86 uint32_t RelType; 87 88 /// Addend - the relocation addend encoded in the instruction itself. Also 89 /// used to make a relocation section relative instead of symbol relative. 90 int64_t Addend; 91 92 struct SectionPair { 93 uint32_t SectionA; 94 uint32_t SectionB; 95 }; 96 97 /// SymOffset - Section offset of the relocation entry's symbol (used for GOT 98 /// lookup). 99 union { 100 uint64_t SymOffset; 101 SectionPair Sections; 102 }; 103 104 /// True if this is a PCRel relocation (MachO specific). 105 bool IsPCRel; 106 107 /// The size of this relocation (MachO specific). 108 unsigned Size; 109 RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend)110 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend) 111 : SectionID(id), Offset(offset), RelType(type), Addend(addend), 112 SymOffset(0), IsPCRel(false), Size(0) {} 113 RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend,uint64_t symoffset)114 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, 115 uint64_t symoffset) 116 : SectionID(id), Offset(offset), RelType(type), Addend(addend), 117 SymOffset(symoffset), IsPCRel(false), Size(0) {} 118 RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend,bool IsPCRel,unsigned Size)119 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, 120 bool IsPCRel, unsigned Size) 121 : SectionID(id), Offset(offset), RelType(type), Addend(addend), 122 SymOffset(0), IsPCRel(IsPCRel), Size(Size) {} 123 RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend,unsigned SectionA,uint64_t SectionAOffset,unsigned SectionB,uint64_t SectionBOffset,bool IsPCRel,unsigned Size)124 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, 125 unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB, 126 uint64_t SectionBOffset, bool IsPCRel, unsigned Size) 127 : SectionID(id), Offset(offset), RelType(type), 128 Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel), 129 Size(Size) { 130 Sections.SectionA = SectionA; 131 Sections.SectionB = SectionB; 132 } 133 }; 134 135 class RelocationValueRef { 136 public: 137 unsigned SectionID; 138 uint64_t Offset; 139 int64_t Addend; 140 const char *SymbolName; RelocationValueRef()141 RelocationValueRef() : SectionID(0), Offset(0), Addend(0), 142 SymbolName(nullptr) {} 143 144 inline bool operator==(const RelocationValueRef &Other) const { 145 return SectionID == Other.SectionID && Offset == Other.Offset && 146 Addend == Other.Addend && SymbolName == Other.SymbolName; 147 } 148 inline bool operator<(const RelocationValueRef &Other) const { 149 if (SectionID != Other.SectionID) 150 return SectionID < Other.SectionID; 151 if (Offset != Other.Offset) 152 return Offset < Other.Offset; 153 if (Addend != Other.Addend) 154 return Addend < Other.Addend; 155 return SymbolName < Other.SymbolName; 156 } 157 }; 158 159 class RuntimeDyldImpl { 160 friend class RuntimeDyld::LoadedObjectInfo; 161 friend class RuntimeDyldCheckerImpl; 162 protected: 163 // The MemoryManager to load objects into. 164 RTDyldMemoryManager *MemMgr; 165 166 // Attached RuntimeDyldChecker instance. Null if no instance attached. 167 RuntimeDyldCheckerImpl *Checker; 168 169 // A list of all sections emitted by the dynamic linker. These sections are 170 // referenced in the code by means of their index in this list - SectionID. 171 typedef SmallVector<SectionEntry, 64> SectionList; 172 SectionList Sections; 173 174 typedef unsigned SID; // Type for SectionIDs 175 #define RTDYLD_INVALID_SECTION_ID ((SID)(-1)) 176 177 // Keep a map of sections from object file to the SectionID which 178 // references it. 179 typedef std::map<SectionRef, unsigned> ObjSectionToIDMap; 180 181 // A global symbol table for symbols from all loaded modules. Maps the 182 // symbol name to a (SectionID, offset in section) pair. 183 typedef std::pair<unsigned, uintptr_t> SymbolLoc; 184 typedef StringMap<SymbolLoc> SymbolTableMap; 185 SymbolTableMap GlobalSymbolTable; 186 187 // Pair representing the size and alignment requirement for a common symbol. 188 typedef std::pair<unsigned, unsigned> CommonSymbolInfo; 189 // Keep a map of common symbols to their info pairs 190 typedef std::map<SymbolRef, CommonSymbolInfo> CommonSymbolMap; 191 192 // For each symbol, keep a list of relocations based on it. Anytime 193 // its address is reassigned (the JIT re-compiled the function, e.g.), 194 // the relocations get re-resolved. 195 // The symbol (or section) the relocation is sourced from is the Key 196 // in the relocation list where it's stored. 197 typedef SmallVector<RelocationEntry, 64> RelocationList; 198 // Relocations to sections already loaded. Indexed by SectionID which is the 199 // source of the address. The target where the address will be written is 200 // SectionID/Offset in the relocation itself. 201 DenseMap<unsigned, RelocationList> Relocations; 202 203 // Relocations to external symbols that are not yet resolved. Symbols are 204 // external when they aren't found in the global symbol table of all loaded 205 // modules. This map is indexed by symbol name. 206 StringMap<RelocationList> ExternalSymbolRelocations; 207 208 209 typedef std::map<RelocationValueRef, uintptr_t> StubMap; 210 211 Triple::ArchType Arch; 212 bool IsTargetLittleEndian; 213 214 // True if all sections should be passed to the memory manager, false if only 215 // sections containing relocations should be. Defaults to 'false'. 216 bool ProcessAllSections; 217 218 // This mutex prevents simultaneously loading objects from two different 219 // threads. This keeps us from having to protect individual data structures 220 // and guarantees that section allocation requests to the memory manager 221 // won't be interleaved between modules. It is also used in mapSectionAddress 222 // and resolveRelocations to protect write access to internal data structures. 223 // 224 // loadObject may be called on the same thread during the handling of of 225 // processRelocations, and that's OK. The handling of the relocation lists 226 // is written in such a way as to work correctly if new elements are added to 227 // the end of the list while the list is being processed. 228 sys::Mutex lock; 229 230 virtual unsigned getMaxStubSize() = 0; 231 virtual unsigned getStubAlignment() = 0; 232 233 bool HasError; 234 std::string ErrorStr; 235 236 // Set the error state and record an error string. Error(const Twine & Msg)237 bool Error(const Twine &Msg) { 238 ErrorStr = Msg.str(); 239 HasError = true; 240 return true; 241 } 242 getSectionLoadAddress(unsigned SectionID)243 uint64_t getSectionLoadAddress(unsigned SectionID) const { 244 return Sections[SectionID].LoadAddress; 245 } 246 getSectionAddress(unsigned SectionID)247 uint8_t *getSectionAddress(unsigned SectionID) const { 248 return (uint8_t *)Sections[SectionID].Address; 249 } 250 writeInt16BE(uint8_t * Addr,uint16_t Value)251 void writeInt16BE(uint8_t *Addr, uint16_t Value) { 252 if (IsTargetLittleEndian) 253 sys::swapByteOrder(Value); 254 *Addr = (Value >> 8) & 0xFF; 255 *(Addr + 1) = Value & 0xFF; 256 } 257 writeInt32BE(uint8_t * Addr,uint32_t Value)258 void writeInt32BE(uint8_t *Addr, uint32_t Value) { 259 if (IsTargetLittleEndian) 260 sys::swapByteOrder(Value); 261 *Addr = (Value >> 24) & 0xFF; 262 *(Addr + 1) = (Value >> 16) & 0xFF; 263 *(Addr + 2) = (Value >> 8) & 0xFF; 264 *(Addr + 3) = Value & 0xFF; 265 } 266 writeInt64BE(uint8_t * Addr,uint64_t Value)267 void writeInt64BE(uint8_t *Addr, uint64_t Value) { 268 if (IsTargetLittleEndian) 269 sys::swapByteOrder(Value); 270 *Addr = (Value >> 56) & 0xFF; 271 *(Addr + 1) = (Value >> 48) & 0xFF; 272 *(Addr + 2) = (Value >> 40) & 0xFF; 273 *(Addr + 3) = (Value >> 32) & 0xFF; 274 *(Addr + 4) = (Value >> 24) & 0xFF; 275 *(Addr + 5) = (Value >> 16) & 0xFF; 276 *(Addr + 6) = (Value >> 8) & 0xFF; 277 *(Addr + 7) = Value & 0xFF; 278 } 279 280 /// Endian-aware read Read the least significant Size bytes from Src. 281 uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const; 282 283 /// Endian-aware write. Write the least significant Size bytes from Value to 284 /// Dst. 285 void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const; 286 287 /// \brief Given the common symbols discovered in the object file, emit a 288 /// new section for them and update the symbol mappings in the object and 289 /// symbol table. 290 void emitCommonSymbols(const ObjectFile &Obj, 291 const CommonSymbolMap &CommonSymbols, 292 uint64_t TotalSize, SymbolTableMap &SymbolTable); 293 294 /// \brief Emits section data from the object file to the MemoryManager. 295 /// \param IsCode if it's true then allocateCodeSection() will be 296 /// used for emits, else allocateDataSection() will be used. 297 /// \return SectionID. 298 unsigned emitSection(const ObjectFile &Obj, const SectionRef &Section, 299 bool IsCode); 300 301 /// \brief Find Section in LocalSections. If the secton is not found - emit 302 /// it and store in LocalSections. 303 /// \param IsCode if it's true then allocateCodeSection() will be 304 /// used for emmits, else allocateDataSection() will be used. 305 /// \return SectionID. 306 unsigned findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, 307 bool IsCode, ObjSectionToIDMap &LocalSections); 308 309 // \brief Add a relocation entry that uses the given section. 310 void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID); 311 312 // \brief Add a relocation entry that uses the given symbol. This symbol may 313 // be found in the global symbol table, or it may be external. 314 void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName); 315 316 /// \brief Emits long jump instruction to Addr. 317 /// \return Pointer to the memory area for emitting target address. 318 uint8_t *createStubFunction(uint8_t *Addr, unsigned AbiVariant = 0); 319 320 /// \brief Resolves relocations from Relocs list with address from Value. 321 void resolveRelocationList(const RelocationList &Relocs, uint64_t Value); 322 323 /// \brief A object file specific relocation resolver 324 /// \param RE The relocation to be resolved 325 /// \param Value Target symbol address to apply the relocation action 326 virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value) = 0; 327 328 /// \brief Parses one or more object file relocations (some object files use 329 /// relocation pairs) and stores it to Relocations or SymbolRelocations 330 /// (this depends on the object file type). 331 /// \return Iterator to the next relocation that needs to be parsed. 332 virtual relocation_iterator 333 processRelocationRef(unsigned SectionID, relocation_iterator RelI, 334 const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, 335 StubMap &Stubs) = 0; 336 337 /// \brief Resolve relocations to external symbols. 338 void resolveExternalSymbols(); 339 340 /// \brief Update GOT entries for external symbols. 341 // The base class does nothing. ELF overrides this. updateGOTEntries(StringRef Name,uint64_t Addr)342 virtual void updateGOTEntries(StringRef Name, uint64_t Addr) {} 343 344 // \brief Compute an upper bound of the memory that is required to load all 345 // sections 346 void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize, 347 uint64_t &DataSizeRO, uint64_t &DataSizeRW); 348 349 // \brief Compute the stub buffer size required for a section 350 unsigned computeSectionStubBufSize(const ObjectFile &Obj, 351 const SectionRef &Section); 352 353 // \brief Implementation of the generic part of the loadObject algorithm. 354 std::pair<unsigned, unsigned> loadObjectImpl(const object::ObjectFile &Obj); 355 356 public: RuntimeDyldImpl(RTDyldMemoryManager * mm)357 RuntimeDyldImpl(RTDyldMemoryManager *mm) 358 : MemMgr(mm), Checker(nullptr), ProcessAllSections(false), HasError(false) { 359 } 360 361 virtual ~RuntimeDyldImpl(); 362 setProcessAllSections(bool ProcessAllSections)363 void setProcessAllSections(bool ProcessAllSections) { 364 this->ProcessAllSections = ProcessAllSections; 365 } 366 setRuntimeDyldChecker(RuntimeDyldCheckerImpl * Checker)367 void setRuntimeDyldChecker(RuntimeDyldCheckerImpl *Checker) { 368 this->Checker = Checker; 369 } 370 371 virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo> 372 loadObject(const object::ObjectFile &Obj) = 0; 373 getSymbolAddress(StringRef Name)374 uint8_t* getSymbolAddress(StringRef Name) const { 375 // FIXME: Just look up as a function for now. Overly simple of course. 376 // Work in progress. 377 SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name); 378 if (pos == GlobalSymbolTable.end()) 379 return nullptr; 380 SymbolLoc Loc = pos->second; 381 return getSectionAddress(Loc.first) + Loc.second; 382 } 383 getSymbolLoadAddress(StringRef Name)384 uint64_t getSymbolLoadAddress(StringRef Name) const { 385 // FIXME: Just look up as a function for now. Overly simple of course. 386 // Work in progress. 387 SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name); 388 if (pos == GlobalSymbolTable.end()) 389 return 0; 390 SymbolLoc Loc = pos->second; 391 return getSectionLoadAddress(Loc.first) + Loc.second; 392 } 393 394 void resolveRelocations(); 395 396 void reassignSectionAddress(unsigned SectionID, uint64_t Addr); 397 398 void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); 399 400 // Is the linker in an error state? hasError()401 bool hasError() { return HasError; } 402 403 // Mark the error condition as handled and continue. clearError()404 void clearError() { HasError = false; } 405 406 // Get the error message. getErrorString()407 StringRef getErrorString() { return ErrorStr; } 408 409 virtual bool isCompatibleFile(const ObjectFile &Obj) const = 0; 410 411 virtual void registerEHFrames(); 412 413 virtual void deregisterEHFrames(); 414 finalizeLoad(const ObjectFile & ObjImg,ObjSectionToIDMap & SectionMap)415 virtual void finalizeLoad(const ObjectFile &ObjImg, 416 ObjSectionToIDMap &SectionMap) {} 417 }; 418 419 } // end namespace llvm 420 421 #endif 422