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/SmallVector.h" 18 #include "llvm/ADT/StringMap.h" 19 #include "llvm/ADT/Triple.h" 20 #include "llvm/ExecutionEngine/RTDyldMemoryManager.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 <map> 31 #include <system_error> 32 #include <unordered_map> 33 34 using namespace llvm; 35 using namespace llvm::object; 36 37 namespace llvm { 38 39 class Twine; 40 41 #define UNIMPLEMENTED_RELOC(RelType) \ 42 case RelType: \ 43 return make_error<RuntimeDyldError>("Unimplemented relocation: " #RelType) 44 45 /// SectionEntry - represents a section emitted into memory by the dynamic 46 /// linker. 47 class SectionEntry { 48 /// Name - section name. 49 std::string Name; 50 51 /// Address - address in the linker's memory where the section resides. 52 uint8_t *Address; 53 54 /// Size - section size. Doesn't include the stubs. 55 size_t Size; 56 57 /// LoadAddress - the address of the section in the target process's memory. 58 /// Used for situations in which JIT-ed code is being executed in the address 59 /// space of a separate process. If the code executes in the same address 60 /// space where it was JIT-ed, this just equals Address. 61 uint64_t LoadAddress; 62 63 /// StubOffset - used for architectures with stub functions for far 64 /// relocations (like ARM). 65 uintptr_t StubOffset; 66 67 /// The total amount of space allocated for this section. This includes the 68 /// section size and the maximum amount of space that the stubs can occupy. 69 size_t AllocationSize; 70 71 /// ObjAddress - address of the section in the in-memory object file. Used 72 /// for calculating relocations in some object formats (like MachO). 73 uintptr_t ObjAddress; 74 75 public: SectionEntry(StringRef name,uint8_t * address,size_t size,size_t allocationSize,uintptr_t objAddress)76 SectionEntry(StringRef name, uint8_t *address, size_t size, 77 size_t allocationSize, uintptr_t objAddress) 78 : Name(name), Address(address), Size(size), 79 LoadAddress(reinterpret_cast<uintptr_t>(address)), StubOffset(size), 80 AllocationSize(allocationSize), ObjAddress(objAddress) { 81 // AllocationSize is used only in asserts, prevent an "unused private field" 82 // warning: 83 (void)AllocationSize; 84 } 85 getName()86 StringRef getName() const { return Name; } 87 getAddress()88 uint8_t *getAddress() const { return Address; } 89 90 /// Return the address of this section with an offset. getAddressWithOffset(unsigned OffsetBytes)91 uint8_t *getAddressWithOffset(unsigned OffsetBytes) const { 92 assert(OffsetBytes <= AllocationSize && "Offset out of bounds!"); 93 return Address + OffsetBytes; 94 } 95 getSize()96 size_t getSize() const { return Size; } 97 getLoadAddress()98 uint64_t getLoadAddress() const { return LoadAddress; } setLoadAddress(uint64_t LA)99 void setLoadAddress(uint64_t LA) { LoadAddress = LA; } 100 101 /// Return the load address of this section with an offset. getLoadAddressWithOffset(unsigned OffsetBytes)102 uint64_t getLoadAddressWithOffset(unsigned OffsetBytes) const { 103 assert(OffsetBytes <= AllocationSize && "Offset out of bounds!"); 104 return LoadAddress + OffsetBytes; 105 } 106 getStubOffset()107 uintptr_t getStubOffset() const { return StubOffset; } 108 advanceStubOffset(unsigned StubSize)109 void advanceStubOffset(unsigned StubSize) { 110 StubOffset += StubSize; 111 assert(StubOffset <= AllocationSize && "Not enough space allocated!"); 112 } 113 getObjAddress()114 uintptr_t getObjAddress() const { return ObjAddress; } 115 }; 116 117 /// RelocationEntry - used to represent relocations internally in the dynamic 118 /// linker. 119 class RelocationEntry { 120 public: 121 /// SectionID - the section this relocation points to. 122 unsigned SectionID; 123 124 /// Offset - offset into the section. 125 uint64_t Offset; 126 127 /// RelType - relocation type. 128 uint32_t RelType; 129 130 /// Addend - the relocation addend encoded in the instruction itself. Also 131 /// used to make a relocation section relative instead of symbol relative. 132 int64_t Addend; 133 134 struct SectionPair { 135 uint32_t SectionA; 136 uint32_t SectionB; 137 }; 138 139 /// SymOffset - Section offset of the relocation entry's symbol (used for GOT 140 /// lookup). 141 union { 142 uint64_t SymOffset; 143 SectionPair Sections; 144 }; 145 146 /// True if this is a PCRel relocation (MachO specific). 147 bool IsPCRel; 148 149 /// The size of this relocation (MachO specific). 150 unsigned Size; 151 152 // ARM (MachO and COFF) specific. 153 bool IsTargetThumbFunc = false; 154 RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend)155 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend) 156 : SectionID(id), Offset(offset), RelType(type), Addend(addend), 157 SymOffset(0), IsPCRel(false), Size(0), IsTargetThumbFunc(false) {} 158 RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend,uint64_t symoffset)159 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, 160 uint64_t symoffset) 161 : SectionID(id), Offset(offset), RelType(type), Addend(addend), 162 SymOffset(symoffset), IsPCRel(false), Size(0), 163 IsTargetThumbFunc(false) {} 164 RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend,bool IsPCRel,unsigned Size)165 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, 166 bool IsPCRel, unsigned Size) 167 : SectionID(id), Offset(offset), RelType(type), Addend(addend), 168 SymOffset(0), IsPCRel(IsPCRel), Size(Size), IsTargetThumbFunc(false) {} 169 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)170 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, 171 unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB, 172 uint64_t SectionBOffset, bool IsPCRel, unsigned Size) 173 : SectionID(id), Offset(offset), RelType(type), 174 Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel), 175 Size(Size), IsTargetThumbFunc(false) { 176 Sections.SectionA = SectionA; 177 Sections.SectionB = SectionB; 178 } 179 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,bool IsTargetThumbFunc)180 RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, 181 unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB, 182 uint64_t SectionBOffset, bool IsPCRel, unsigned Size, 183 bool IsTargetThumbFunc) 184 : SectionID(id), Offset(offset), RelType(type), 185 Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel), 186 Size(Size), IsTargetThumbFunc(IsTargetThumbFunc) { 187 Sections.SectionA = SectionA; 188 Sections.SectionB = SectionB; 189 } 190 }; 191 192 class RelocationValueRef { 193 public: 194 unsigned SectionID; 195 uint64_t Offset; 196 int64_t Addend; 197 const char *SymbolName; 198 bool IsStubThumb = false; RelocationValueRef()199 RelocationValueRef() : SectionID(0), Offset(0), Addend(0), 200 SymbolName(nullptr) {} 201 202 inline bool operator==(const RelocationValueRef &Other) const { 203 return SectionID == Other.SectionID && Offset == Other.Offset && 204 Addend == Other.Addend && SymbolName == Other.SymbolName && 205 IsStubThumb == Other.IsStubThumb; 206 } 207 inline bool operator<(const RelocationValueRef &Other) const { 208 if (SectionID != Other.SectionID) 209 return SectionID < Other.SectionID; 210 if (Offset != Other.Offset) 211 return Offset < Other.Offset; 212 if (Addend != Other.Addend) 213 return Addend < Other.Addend; 214 if (IsStubThumb != Other.IsStubThumb) 215 return IsStubThumb < Other.IsStubThumb; 216 return SymbolName < Other.SymbolName; 217 } 218 }; 219 220 /// Symbol info for RuntimeDyld. 221 class SymbolTableEntry { 222 public: 223 SymbolTableEntry() = default; 224 SymbolTableEntry(unsigned SectionID,uint64_t Offset,JITSymbolFlags Flags)225 SymbolTableEntry(unsigned SectionID, uint64_t Offset, JITSymbolFlags Flags) 226 : Offset(Offset), SectionID(SectionID), Flags(Flags) {} 227 getSectionID()228 unsigned getSectionID() const { return SectionID; } getOffset()229 uint64_t getOffset() const { return Offset; } setOffset(uint64_t NewOffset)230 void setOffset(uint64_t NewOffset) { Offset = NewOffset; } 231 getFlags()232 JITSymbolFlags getFlags() const { return Flags; } 233 234 private: 235 uint64_t Offset = 0; 236 unsigned SectionID = 0; 237 JITSymbolFlags Flags = JITSymbolFlags::None; 238 }; 239 240 typedef StringMap<SymbolTableEntry> RTDyldSymbolTable; 241 242 class RuntimeDyldImpl { 243 friend class RuntimeDyld::LoadedObjectInfo; 244 friend class RuntimeDyldCheckerImpl; 245 protected: 246 static const unsigned AbsoluteSymbolSection = ~0U; 247 248 // The MemoryManager to load objects into. 249 RuntimeDyld::MemoryManager &MemMgr; 250 251 // The symbol resolver to use for external symbols. 252 JITSymbolResolver &Resolver; 253 254 // Attached RuntimeDyldChecker instance. Null if no instance attached. 255 RuntimeDyldCheckerImpl *Checker; 256 257 // A list of all sections emitted by the dynamic linker. These sections are 258 // referenced in the code by means of their index in this list - SectionID. 259 typedef SmallVector<SectionEntry, 64> SectionList; 260 SectionList Sections; 261 262 typedef unsigned SID; // Type for SectionIDs 263 #define RTDYLD_INVALID_SECTION_ID ((RuntimeDyldImpl::SID)(-1)) 264 265 // Keep a map of sections from object file to the SectionID which 266 // references it. 267 typedef std::map<SectionRef, unsigned> ObjSectionToIDMap; 268 269 // A global symbol table for symbols from all loaded modules. 270 RTDyldSymbolTable GlobalSymbolTable; 271 272 // Keep a map of common symbols to their info pairs 273 typedef std::vector<SymbolRef> CommonSymbolList; 274 275 // For each symbol, keep a list of relocations based on it. Anytime 276 // its address is reassigned (the JIT re-compiled the function, e.g.), 277 // the relocations get re-resolved. 278 // The symbol (or section) the relocation is sourced from is the Key 279 // in the relocation list where it's stored. 280 typedef SmallVector<RelocationEntry, 64> RelocationList; 281 // Relocations to sections already loaded. Indexed by SectionID which is the 282 // source of the address. The target where the address will be written is 283 // SectionID/Offset in the relocation itself. 284 std::unordered_map<unsigned, RelocationList> Relocations; 285 286 // Relocations to external symbols that are not yet resolved. Symbols are 287 // external when they aren't found in the global symbol table of all loaded 288 // modules. This map is indexed by symbol name. 289 StringMap<RelocationList> ExternalSymbolRelocations; 290 291 292 typedef std::map<RelocationValueRef, uintptr_t> StubMap; 293 294 Triple::ArchType Arch; 295 bool IsTargetLittleEndian; 296 bool IsMipsO32ABI; 297 bool IsMipsN32ABI; 298 bool IsMipsN64ABI; 299 300 // True if all sections should be passed to the memory manager, false if only 301 // sections containing relocations should be. Defaults to 'false'. 302 bool ProcessAllSections; 303 304 // This mutex prevents simultaneously loading objects from two different 305 // threads. This keeps us from having to protect individual data structures 306 // and guarantees that section allocation requests to the memory manager 307 // won't be interleaved between modules. It is also used in mapSectionAddress 308 // and resolveRelocations to protect write access to internal data structures. 309 // 310 // loadObject may be called on the same thread during the handling of of 311 // processRelocations, and that's OK. The handling of the relocation lists 312 // is written in such a way as to work correctly if new elements are added to 313 // the end of the list while the list is being processed. 314 sys::Mutex lock; 315 316 virtual unsigned getMaxStubSize() = 0; 317 virtual unsigned getStubAlignment() = 0; 318 319 bool HasError; 320 std::string ErrorStr; 321 getSectionLoadAddress(unsigned SectionID)322 uint64_t getSectionLoadAddress(unsigned SectionID) const { 323 return Sections[SectionID].getLoadAddress(); 324 } 325 getSectionAddress(unsigned SectionID)326 uint8_t *getSectionAddress(unsigned SectionID) const { 327 return Sections[SectionID].getAddress(); 328 } 329 writeInt16BE(uint8_t * Addr,uint16_t Value)330 void writeInt16BE(uint8_t *Addr, uint16_t Value) { 331 if (IsTargetLittleEndian) 332 sys::swapByteOrder(Value); 333 *Addr = (Value >> 8) & 0xFF; 334 *(Addr + 1) = Value & 0xFF; 335 } 336 writeInt32BE(uint8_t * Addr,uint32_t Value)337 void writeInt32BE(uint8_t *Addr, uint32_t Value) { 338 if (IsTargetLittleEndian) 339 sys::swapByteOrder(Value); 340 *Addr = (Value >> 24) & 0xFF; 341 *(Addr + 1) = (Value >> 16) & 0xFF; 342 *(Addr + 2) = (Value >> 8) & 0xFF; 343 *(Addr + 3) = Value & 0xFF; 344 } 345 writeInt64BE(uint8_t * Addr,uint64_t Value)346 void writeInt64BE(uint8_t *Addr, uint64_t Value) { 347 if (IsTargetLittleEndian) 348 sys::swapByteOrder(Value); 349 *Addr = (Value >> 56) & 0xFF; 350 *(Addr + 1) = (Value >> 48) & 0xFF; 351 *(Addr + 2) = (Value >> 40) & 0xFF; 352 *(Addr + 3) = (Value >> 32) & 0xFF; 353 *(Addr + 4) = (Value >> 24) & 0xFF; 354 *(Addr + 5) = (Value >> 16) & 0xFF; 355 *(Addr + 6) = (Value >> 8) & 0xFF; 356 *(Addr + 7) = Value & 0xFF; 357 } 358 setMipsABI(const ObjectFile & Obj)359 virtual void setMipsABI(const ObjectFile &Obj) { 360 IsMipsO32ABI = false; 361 IsMipsN32ABI = false; 362 IsMipsN64ABI = false; 363 } 364 365 /// Endian-aware read Read the least significant Size bytes from Src. 366 uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const; 367 368 /// Endian-aware write. Write the least significant Size bytes from Value to 369 /// Dst. 370 void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const; 371 372 /// Generate JITSymbolFlags from a libObject symbol. 373 virtual JITSymbolFlags getJITSymbolFlags(const BasicSymbolRef &Sym); 374 375 /// Modify the given target address based on the given symbol flags. 376 /// This can be used by subclasses to tweak addresses based on symbol flags, 377 /// For example: the MachO/ARM target uses it to set the low bit if the target 378 /// is a thumb symbol. modifyAddressBasedOnFlags(uint64_t Addr,JITSymbolFlags Flags)379 virtual uint64_t modifyAddressBasedOnFlags(uint64_t Addr, 380 JITSymbolFlags Flags) const { 381 return Addr; 382 } 383 384 /// Given the common symbols discovered in the object file, emit a 385 /// new section for them and update the symbol mappings in the object and 386 /// symbol table. 387 Error emitCommonSymbols(const ObjectFile &Obj, 388 CommonSymbolList &CommonSymbols, uint64_t CommonSize, 389 uint32_t CommonAlign); 390 391 /// Emits section data from the object file to the MemoryManager. 392 /// \param IsCode if it's true then allocateCodeSection() will be 393 /// used for emits, else allocateDataSection() will be used. 394 /// \return SectionID. 395 Expected<unsigned> emitSection(const ObjectFile &Obj, 396 const SectionRef &Section, 397 bool IsCode); 398 399 /// Find Section in LocalSections. If the secton is not found - emit 400 /// it and store in LocalSections. 401 /// \param IsCode if it's true then allocateCodeSection() will be 402 /// used for emmits, else allocateDataSection() will be used. 403 /// \return SectionID. 404 Expected<unsigned> findOrEmitSection(const ObjectFile &Obj, 405 const SectionRef &Section, bool IsCode, 406 ObjSectionToIDMap &LocalSections); 407 408 // Add a relocation entry that uses the given section. 409 void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID); 410 411 // Add a relocation entry that uses the given symbol. This symbol may 412 // be found in the global symbol table, or it may be external. 413 void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName); 414 415 /// Emits long jump instruction to Addr. 416 /// \return Pointer to the memory area for emitting target address. 417 uint8_t *createStubFunction(uint8_t *Addr, unsigned AbiVariant = 0); 418 419 /// Resolves relocations from Relocs list with address from Value. 420 void resolveRelocationList(const RelocationList &Relocs, uint64_t Value); 421 422 /// A object file specific relocation resolver 423 /// \param RE The relocation to be resolved 424 /// \param Value Target symbol address to apply the relocation action 425 virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value) = 0; 426 427 /// Parses one or more object file relocations (some object files use 428 /// relocation pairs) and stores it to Relocations or SymbolRelocations 429 /// (this depends on the object file type). 430 /// \return Iterator to the next relocation that needs to be parsed. 431 virtual Expected<relocation_iterator> 432 processRelocationRef(unsigned SectionID, relocation_iterator RelI, 433 const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, 434 StubMap &Stubs) = 0; 435 436 /// Resolve relocations to external symbols. 437 Error resolveExternalSymbols(); 438 439 // Compute an upper bound of the memory that is required to load all 440 // sections 441 Error computeTotalAllocSize(const ObjectFile &Obj, 442 uint64_t &CodeSize, uint32_t &CodeAlign, 443 uint64_t &RODataSize, uint32_t &RODataAlign, 444 uint64_t &RWDataSize, uint32_t &RWDataAlign); 445 446 // Compute GOT size 447 unsigned computeGOTSize(const ObjectFile &Obj); 448 449 // Compute the stub buffer size required for a section 450 unsigned computeSectionStubBufSize(const ObjectFile &Obj, 451 const SectionRef &Section); 452 453 // Implementation of the generic part of the loadObject algorithm. 454 Expected<ObjSectionToIDMap> loadObjectImpl(const object::ObjectFile &Obj); 455 456 // Return size of Global Offset Table (GOT) entry getGOTEntrySize()457 virtual size_t getGOTEntrySize() { return 0; } 458 459 // Return true if the relocation R may require allocating a GOT entry. relocationNeedsGot(const RelocationRef & R)460 virtual bool relocationNeedsGot(const RelocationRef &R) const { 461 return false; 462 } 463 464 // Return true if the relocation R may require allocating a stub. relocationNeedsStub(const RelocationRef & R)465 virtual bool relocationNeedsStub(const RelocationRef &R) const { 466 return true; // Conservative answer 467 } 468 469 public: RuntimeDyldImpl(RuntimeDyld::MemoryManager & MemMgr,JITSymbolResolver & Resolver)470 RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr, 471 JITSymbolResolver &Resolver) 472 : MemMgr(MemMgr), Resolver(Resolver), Checker(nullptr), 473 ProcessAllSections(false), HasError(false) { 474 } 475 476 virtual ~RuntimeDyldImpl(); 477 setProcessAllSections(bool ProcessAllSections)478 void setProcessAllSections(bool ProcessAllSections) { 479 this->ProcessAllSections = ProcessAllSections; 480 } 481 setRuntimeDyldChecker(RuntimeDyldCheckerImpl * Checker)482 void setRuntimeDyldChecker(RuntimeDyldCheckerImpl *Checker) { 483 this->Checker = Checker; 484 } 485 486 virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo> 487 loadObject(const object::ObjectFile &Obj) = 0; 488 getSymbolLocalAddress(StringRef Name)489 uint8_t* getSymbolLocalAddress(StringRef Name) const { 490 // FIXME: Just look up as a function for now. Overly simple of course. 491 // Work in progress. 492 RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name); 493 if (pos == GlobalSymbolTable.end()) 494 return nullptr; 495 const auto &SymInfo = pos->second; 496 // Absolute symbols do not have a local address. 497 if (SymInfo.getSectionID() == AbsoluteSymbolSection) 498 return nullptr; 499 return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset(); 500 } 501 getSymbol(StringRef Name)502 JITEvaluatedSymbol getSymbol(StringRef Name) const { 503 // FIXME: Just look up as a function for now. Overly simple of course. 504 // Work in progress. 505 RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name); 506 if (pos == GlobalSymbolTable.end()) 507 return nullptr; 508 const auto &SymEntry = pos->second; 509 uint64_t SectionAddr = 0; 510 if (SymEntry.getSectionID() != AbsoluteSymbolSection) 511 SectionAddr = getSectionLoadAddress(SymEntry.getSectionID()); 512 uint64_t TargetAddr = SectionAddr + SymEntry.getOffset(); 513 514 // FIXME: Have getSymbol should return the actual address and the client 515 // modify it based on the flags. This will require clients to be 516 // aware of the target architecture, which we should build 517 // infrastructure for. 518 TargetAddr = modifyAddressBasedOnFlags(TargetAddr, SymEntry.getFlags()); 519 return JITEvaluatedSymbol(TargetAddr, SymEntry.getFlags()); 520 } 521 getSymbolTable()522 std::map<StringRef, JITEvaluatedSymbol> getSymbolTable() const { 523 std::map<StringRef, JITEvaluatedSymbol> Result; 524 525 for (auto &KV : GlobalSymbolTable) { 526 auto SectionID = KV.second.getSectionID(); 527 uint64_t SectionAddr = 0; 528 if (SectionID != AbsoluteSymbolSection) 529 SectionAddr = getSectionLoadAddress(SectionID); 530 Result[KV.first()] = 531 JITEvaluatedSymbol(SectionAddr + KV.second.getOffset(), KV.second.getFlags()); 532 } 533 534 return Result; 535 } 536 537 void resolveRelocations(); 538 539 void reassignSectionAddress(unsigned SectionID, uint64_t Addr); 540 541 void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); 542 543 // Is the linker in an error state? hasError()544 bool hasError() { return HasError; } 545 546 // Mark the error condition as handled and continue. clearError()547 void clearError() { HasError = false; } 548 549 // Get the error message. getErrorString()550 StringRef getErrorString() { return ErrorStr; } 551 552 virtual bool isCompatibleFile(const ObjectFile &Obj) const = 0; 553 554 virtual void registerEHFrames(); 555 556 void deregisterEHFrames(); 557 finalizeLoad(const ObjectFile & ObjImg,ObjSectionToIDMap & SectionMap)558 virtual Error finalizeLoad(const ObjectFile &ObjImg, 559 ObjSectionToIDMap &SectionMap) { 560 return Error::success(); 561 } 562 }; 563 564 } // end namespace llvm 565 566 #endif 567