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 using namespace llvm; 17 using namespace llvm::object; 18 19 // Empty out-of-line virtual destructor as the key function. 20 RTDyldMemoryManager::~RTDyldMemoryManager() {} 21 RuntimeDyldImpl::~RuntimeDyldImpl() {} 22 23 namespace llvm { 24 25 void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress, 26 uint8_t *EndAddress) { 27 // Allocate memory for the function via the memory manager. 28 uintptr_t Size = EndAddress - StartAddress + 1; 29 uintptr_t AllocSize = Size; 30 uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize); 31 assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) && 32 "Memory manager failed to allocate enough memory!"); 33 // Copy the function payload into the memory block. 34 memcpy(Mem, StartAddress, Size); 35 MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size); 36 // Remember where we put it. 37 Functions[Name] = sys::MemoryBlock(Mem, Size); 38 // Default the assigned address for this symbol to wherever this 39 // allocated it. 40 SymbolTable[Name] = Mem; 41 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n"); 42 } 43 44 // Resolve the relocations for all symbols we currently know about. 45 void RuntimeDyldImpl::resolveRelocations() { 46 // Just iterate over the symbols in our symbol table and assign their 47 // addresses. 48 StringMap<uint8_t*>::iterator i = SymbolTable.begin(); 49 StringMap<uint8_t*>::iterator e = SymbolTable.end(); 50 for (;i != e; ++i) 51 reassignSymbolAddress(i->getKey(), i->getValue()); 52 } 53 54 //===----------------------------------------------------------------------===// 55 // RuntimeDyld class implementation 56 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { 57 Dyld = 0; 58 MM = mm; 59 } 60 61 RuntimeDyld::~RuntimeDyld() { 62 delete Dyld; 63 } 64 65 bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) { 66 if (!Dyld) { 67 if (RuntimeDyldMachO::isKnownFormat(InputBuffer)) 68 Dyld = new RuntimeDyldMachO(MM); 69 else 70 report_fatal_error("Unknown object format!"); 71 } else { 72 if(!Dyld->isCompatibleFormat(InputBuffer)) 73 report_fatal_error("Incompatible object format!"); 74 } 75 76 return Dyld->loadObject(InputBuffer); 77 } 78 79 void *RuntimeDyld::getSymbolAddress(StringRef Name) { 80 return Dyld->getSymbolAddress(Name); 81 } 82 83 void RuntimeDyld::resolveRelocations() { 84 Dyld->resolveRelocations(); 85 } 86 87 void RuntimeDyld::reassignSymbolAddress(StringRef Name, uint8_t *Addr) { 88 Dyld->reassignSymbolAddress(Name, Addr); 89 } 90 91 StringRef RuntimeDyld::getErrorString() { 92 return Dyld->getErrorString(); 93 } 94 95 } // end namespace llvm 96