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" 16using namespace llvm; 17using namespace llvm::object; 18 19// Empty out-of-line virtual destructor as the key function. 20RTDyldMemoryManager::~RTDyldMemoryManager() {} 21RuntimeDyldImpl::~RuntimeDyldImpl() {} 22 23namespace llvm { 24 25void 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. 45void 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 56RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { 57 Dyld = 0; 58 MM = mm; 59} 60 61RuntimeDyld::~RuntimeDyld() { 62 delete Dyld; 63} 64 65bool 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 79void *RuntimeDyld::getSymbolAddress(StringRef Name) { 80 return Dyld->getSymbolAddress(Name); 81} 82 83void RuntimeDyld::resolveRelocations() { 84 Dyld->resolveRelocations(); 85} 86 87void RuntimeDyld::reassignSymbolAddress(StringRef Name, uint8_t *Addr) { 88 Dyld->reassignSymbolAddress(Name, Addr); 89} 90 91StringRef RuntimeDyld::getErrorString() { 92 return Dyld->getErrorString(); 93} 94 95} // end namespace llvm 96