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.
~RTDyldMemoryManager()20 RTDyldMemoryManager::~RTDyldMemoryManager() {}
~RuntimeDyldImpl()21 RuntimeDyldImpl::~RuntimeDyldImpl() {}
22
23 namespace llvm {
24
extractFunction(StringRef Name,uint8_t * StartAddress,uint8_t * EndAddress)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.
resolveRelocations()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
RuntimeDyld(RTDyldMemoryManager * mm)56 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
57 Dyld = 0;
58 MM = mm;
59 }
60
~RuntimeDyld()61 RuntimeDyld::~RuntimeDyld() {
62 delete Dyld;
63 }
64
loadObject(MemoryBuffer * InputBuffer)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
getSymbolAddress(StringRef Name)79 void *RuntimeDyld::getSymbolAddress(StringRef Name) {
80 return Dyld->getSymbolAddress(Name);
81 }
82
resolveRelocations()83 void RuntimeDyld::resolveRelocations() {
84 Dyld->resolveRelocations();
85 }
86
reassignSymbolAddress(StringRef Name,uint8_t * Addr)87 void RuntimeDyld::reassignSymbolAddress(StringRef Name, uint8_t *Addr) {
88 Dyld->reassignSymbolAddress(Name, Addr);
89 }
90
getErrorString()91 StringRef RuntimeDyld::getErrorString() {
92 return Dyld->getErrorString();
93 }
94
95 } // end namespace llvm
96