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