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