• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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