File: RuntimeDyld.cpp

package info (click to toggle)
llvm-3.0 3.0-10
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 75,412 kB
  • sloc: cpp: 468,043; asm: 109,345; ansic: 13,782; sh: 12,935; ml: 4,716; python: 4,351; perl: 2,096; makefile: 1,905; pascal: 1,578; exp: 389; xml: 283; lisp: 187; csh: 117
file content (95 lines) | stat: -rw-r--r-- 3,070 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//===-- RuntimeDyld.cpp - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implementation of the MC-JIT runtime dynamic linker.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "dyld"
#include "RuntimeDyldImpl.h"
using namespace llvm;
using namespace llvm::object;

// Empty out-of-line virtual destructor as the key function.
RTDyldMemoryManager::~RTDyldMemoryManager() {}
RuntimeDyldImpl::~RuntimeDyldImpl() {}

namespace llvm {

void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress,
                                      uint8_t *EndAddress) {
  // Allocate memory for the function via the memory manager.
  uintptr_t Size = EndAddress - StartAddress + 1;
  uintptr_t AllocSize = Size;
  uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize);
  assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) &&
         "Memory manager failed to allocate enough memory!");
  // Copy the function payload into the memory block.
  memcpy(Mem, StartAddress, Size);
  MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size);
  // Remember where we put it.
  Functions[Name] = sys::MemoryBlock(Mem, Size);
  // Default the assigned address for this symbol to wherever this
  // allocated it.
  SymbolTable[Name] = Mem;
  DEBUG(dbgs() << "    allocated to [" << Mem << ", " << Mem + Size << "]\n");
}

// Resolve the relocations for all symbols we currently know about.
void RuntimeDyldImpl::resolveRelocations() {
  // Just iterate over the symbols in our symbol table and assign their
  // addresses.
  StringMap<uint8_t*>::iterator i = SymbolTable.begin();
  StringMap<uint8_t*>::iterator e = SymbolTable.end();
  for (;i != e; ++i)
    reassignSymbolAddress(i->getKey(), i->getValue());
}

//===----------------------------------------------------------------------===//
// RuntimeDyld class implementation
RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
  Dyld = 0;
  MM = mm;
}

RuntimeDyld::~RuntimeDyld() {
  delete Dyld;
}

bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
  if (!Dyld) {
    if (RuntimeDyldMachO::isKnownFormat(InputBuffer))
      Dyld = new RuntimeDyldMachO(MM);
    else
      report_fatal_error("Unknown object format!");
  } else {
    if(!Dyld->isCompatibleFormat(InputBuffer))
      report_fatal_error("Incompatible object format!");
  }

  return Dyld->loadObject(InputBuffer);
}

void *RuntimeDyld::getSymbolAddress(StringRef Name) {
  return Dyld->getSymbolAddress(Name);
}

void RuntimeDyld::resolveRelocations() {
  Dyld->resolveRelocations();
}

void RuntimeDyld::reassignSymbolAddress(StringRef Name, uint8_t *Addr) {
  Dyld->reassignSymbolAddress(Name, Addr);
}

StringRef RuntimeDyld::getErrorString() {
  return Dyld->getErrorString();
}

} // end namespace llvm