Home | History | Annotate | Download | only in RuntimeDyld
      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
     96