1 //===-- RuntimeDyld.cpp - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Implementation of the MC-JIT runtime dynamic linker.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "dyld"
15 #include "RuntimeDyldImpl.h"
17 using namespace llvm::object;
19 // Empty out-of-line virtual destructor as the key function.
20 RTDyldMemoryManager::~RTDyldMemoryManager() {}
21 RuntimeDyldImpl::~RuntimeDyldImpl() {}
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
40 SymbolTable[Name] = Mem;
41 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n");
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
48 StringMap<uint8_t*>::iterator i = SymbolTable.begin();
49 StringMap<uint8_t*>::iterator e = SymbolTable.end();
51 reassignSymbolAddress(i->getKey(), i->getValue());
54 //===----------------------------------------------------------------------===//
55 // RuntimeDyld class implementation
56 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
61 RuntimeDyld::~RuntimeDyld() {
65 bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
67 if (RuntimeDyldMachO::isKnownFormat(InputBuffer))
68 Dyld = new RuntimeDyldMachO(MM);
70 report_fatal_error("Unknown object format!");
72 if(!Dyld->isCompatibleFormat(InputBuffer))
73 report_fatal_error("Incompatible object format!");
76 return Dyld->loadObject(InputBuffer);
79 void *RuntimeDyld::getSymbolAddress(StringRef Name) {
80 return Dyld->getSymbolAddress(Name);
83 void RuntimeDyld::resolveRelocations() {
84 Dyld->resolveRelocations();
87 void RuntimeDyld::reassignSymbolAddress(StringRef Name, uint8_t *Addr) {
88 Dyld->reassignSymbolAddress(Name, Addr);
91 StringRef RuntimeDyld::getErrorString() {
92 return Dyld->getErrorString();
95 } // end namespace llvm