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 "llvm/Support/Path.h" 17 using namespace llvm; 18 using namespace llvm::object; 19 20 // Empty out-of-line virtual destructor as the key function. 21 RTDyldMemoryManager::~RTDyldMemoryManager() {} 22 RuntimeDyldImpl::~RuntimeDyldImpl() {} 23 24 namespace llvm { 25 26 void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress, 27 uint8_t *EndAddress) { 28 // Allocate memory for the function via the memory manager. 29 uintptr_t Size = EndAddress - StartAddress + 1; 30 uintptr_t AllocSize = Size; 31 uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize); 32 assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) && 33 "Memory manager failed to allocate enough memory!"); 34 // Copy the function payload into the memory block. 35 memcpy(Mem, StartAddress, Size); 36 MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size); 37 // Remember where we put it. 38 Functions[Name] = sys::MemoryBlock(Mem, Size); 39 // Default the assigned address for this symbol to wherever this 40 // allocated it. 41 SymbolTable[Name] = Mem; 42 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n"); 43 } 44 45 // Resolve the relocations for all symbols we currently know about. 46 void RuntimeDyldImpl::resolveRelocations() { 47 // Just iterate over the symbols in our symbol table and assign their 48 // addresses. 49 StringMap<uint8_t*>::iterator i = SymbolTable.begin(); 50 StringMap<uint8_t*>::iterator e = SymbolTable.end(); 51 for (;i != e; ++i) 52 reassignSymbolAddress(i->getKey(), i->getValue()); 53 } 54 55 //===----------------------------------------------------------------------===// 56 // RuntimeDyld class implementation 57 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { 58 Dyld = 0; 59 MM = mm; 60 } 61 62 RuntimeDyld::~RuntimeDyld() { 63 delete Dyld; 64 } 65 66 bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) { 67 if (!Dyld) { 68 sys::LLVMFileType type = sys::IdentifyFileType( 69 InputBuffer->getBufferStart(), 70 static_cast<unsigned>(InputBuffer->getBufferSize())); 71 switch (type) { 72 case sys::ELF_Relocatable_FileType: 73 case sys::ELF_Executable_FileType: 74 case sys::ELF_SharedObject_FileType: 75 case sys::ELF_Core_FileType: 76 Dyld = new RuntimeDyldELF(MM); 77 break; 78 case sys::Mach_O_Object_FileType: 79 case sys::Mach_O_Executable_FileType: 80 case sys::Mach_O_FixedVirtualMemorySharedLib_FileType: 81 case sys::Mach_O_Core_FileType: 82 case sys::Mach_O_PreloadExecutable_FileType: 83 case sys::Mach_O_DynamicallyLinkedSharedLib_FileType: 84 case sys::Mach_O_DynamicLinker_FileType: 85 case sys::Mach_O_Bundle_FileType: 86 case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: 87 case sys::Mach_O_DSYMCompanion_FileType: 88 Dyld = new RuntimeDyldMachO(MM); 89 break; 90 case sys::Unknown_FileType: 91 case sys::Bitcode_FileType: 92 case sys::Archive_FileType: 93 case sys::COFF_FileType: 94 report_fatal_error("Incompatible object format!"); 95 } 96 } else { 97 if (!Dyld->isCompatibleFormat(InputBuffer)) 98 report_fatal_error("Incompatible object format!"); 99 } 100 101 return Dyld->loadObject(InputBuffer); 102 } 103 104 void *RuntimeDyld::getSymbolAddress(StringRef Name) { 105 return Dyld->getSymbolAddress(Name); 106 } 107 108 void RuntimeDyld::resolveRelocations() { 109 Dyld->resolveRelocations(); 110 } 111 112 void RuntimeDyld::reassignSymbolAddress(StringRef Name, uint8_t *Addr) { 113 Dyld->reassignSymbolAddress(Name, Addr); 114 } 115 116 StringRef RuntimeDyld::getErrorString() { 117 return Dyld->getErrorString(); 118 } 119 120 } // end namespace llvm 121