1 //===-- RuntimeDyld.cpp - 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 // Implementation of the MC-JIT runtime dynamic linker. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "dyld" 15 #include "RuntimeDyldImpl.h" 16 #include "RuntimeDyldELF.h" 17 #include "RuntimeDyldMachO.h" 18 #include "llvm/Support/Path.h" 19 20 using namespace llvm; 21 using namespace llvm::object; 22 23 // Empty out-of-line virtual destructor as the key function. 24 RTDyldMemoryManager::~RTDyldMemoryManager() {} 25 RuntimeDyldImpl::~RuntimeDyldImpl() {} 26 27 namespace llvm { 28 29 void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress, 30 uint8_t *EndAddress) { 31 // FIXME: DEPRECATED in favor of by-section allocation. 32 // Allocate memory for the function via the memory manager. 33 uintptr_t Size = EndAddress - StartAddress + 1; 34 uintptr_t AllocSize = Size; 35 uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize); 36 assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) && 37 "Memory manager failed to allocate enough memory!"); 38 // Copy the function payload into the memory block. 39 memcpy(Mem, StartAddress, Size); 40 MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size); 41 // Remember where we put it. 42 unsigned SectionID = Sections.size(); 43 Sections.push_back(sys::MemoryBlock(Mem, Size)); 44 45 // Default the assigned address for this symbol to wherever this 46 // allocated it. 47 SymbolTable[Name] = SymbolLoc(SectionID, 0); 48 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n"); 49 } 50 51 // Resolve the relocations for all symbols we currently know about. 52 void RuntimeDyldImpl::resolveRelocations() { 53 // Just iterate over the sections we have and resolve all the relocations 54 // in them. Gross overkill, but it gets the job done. 55 for (int i = 0, e = Sections.size(); i != e; ++i) { 56 reassignSectionAddress(i, SectionLoadAddress[i]); 57 } 58 } 59 60 void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress, 61 uint64_t TargetAddress) { 62 assert(SectionLocalMemToID.count(LocalAddress) && 63 "Attempting to remap address of unknown section!"); 64 unsigned SectionID = SectionLocalMemToID[LocalAddress]; 65 reassignSectionAddress(SectionID, TargetAddress); 66 } 67 68 //===----------------------------------------------------------------------===// 69 // RuntimeDyld class implementation 70 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { 71 Dyld = 0; 72 MM = mm; 73 } 74 75 RuntimeDyld::~RuntimeDyld() { 76 delete Dyld; 77 } 78 79 bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) { 80 if (!Dyld) { 81 sys::LLVMFileType type = sys::IdentifyFileType( 82 InputBuffer->getBufferStart(), 83 static_cast<unsigned>(InputBuffer->getBufferSize())); 84 switch (type) { 85 case sys::ELF_Relocatable_FileType: 86 case sys::ELF_Executable_FileType: 87 case sys::ELF_SharedObject_FileType: 88 case sys::ELF_Core_FileType: 89 Dyld = new RuntimeDyldELF(MM); 90 break; 91 case sys::Mach_O_Object_FileType: 92 case sys::Mach_O_Executable_FileType: 93 case sys::Mach_O_FixedVirtualMemorySharedLib_FileType: 94 case sys::Mach_O_Core_FileType: 95 case sys::Mach_O_PreloadExecutable_FileType: 96 case sys::Mach_O_DynamicallyLinkedSharedLib_FileType: 97 case sys::Mach_O_DynamicLinker_FileType: 98 case sys::Mach_O_Bundle_FileType: 99 case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: 100 case sys::Mach_O_DSYMCompanion_FileType: 101 Dyld = new RuntimeDyldMachO(MM); 102 break; 103 case sys::Unknown_FileType: 104 case sys::Bitcode_FileType: 105 case sys::Archive_FileType: 106 case sys::COFF_FileType: 107 report_fatal_error("Incompatible object format!"); 108 } 109 } else { 110 if (!Dyld->isCompatibleFormat(InputBuffer)) 111 report_fatal_error("Incompatible object format!"); 112 } 113 114 return Dyld->loadObject(InputBuffer); 115 } 116 117 void *RuntimeDyld::getSymbolAddress(StringRef Name) { 118 return Dyld->getSymbolAddress(Name); 119 } 120 121 void RuntimeDyld::resolveRelocations() { 122 Dyld->resolveRelocations(); 123 } 124 125 void RuntimeDyld::reassignSectionAddress(unsigned SectionID, 126 uint64_t Addr) { 127 Dyld->reassignSectionAddress(SectionID, Addr); 128 } 129 130 void RuntimeDyld::mapSectionAddress(void *LocalAddress, 131 uint64_t TargetAddress) { 132 Dyld->mapSectionAddress(LocalAddress, TargetAddress); 133 } 134 135 StringRef RuntimeDyld::getErrorString() { 136 return Dyld->getErrorString(); 137 } 138 139 } // end namespace llvm 140