]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / lib / ExecutionEngine / RuntimeDyld / RuntimeDyld.cpp
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