blob: 33dd70502798f840efb8bb93ae83b3ea6cb97af2 [file] [log] [blame]
Danil Malyshevcf852dc2011-07-13 07:57:58 +00001//===-- RuntimeDyld.cpp - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
Jim Grosbach6e563312011-03-21 22:15:52 +00002//
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
Jim Grosbach8b54dca2011-03-23 19:52:00 +000014#define DEBUG_TYPE "dyld"
Danil Malyshevcf852dc2011-07-13 07:57:58 +000015#include "RuntimeDyldImpl.h"
Jim Grosbach6e563312011-03-21 22:15:52 +000016using namespace llvm;
17using namespace llvm::object;
18
Chandler Carruth53c5e7b2011-04-05 23:54:31 +000019// Empty out-of-line virtual destructor as the key function.
20RTDyldMemoryManager::~RTDyldMemoryManager() {}
Danil Malyshevcf852dc2011-07-13 07:57:58 +000021RuntimeDyldImpl::~RuntimeDyldImpl() {}
Chandler Carruth53c5e7b2011-04-05 23:54:31 +000022
Jim Grosbach6e563312011-03-21 22:15:52 +000023namespace llvm {
Jim Grosbach6e563312011-03-21 22:15:52 +000024
Jim Grosbachc41ab782011-04-06 01:11:05 +000025void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress,
Jim Grosbach01ccab42011-04-06 22:13:52 +000026 uint8_t *EndAddress) {
Jim Grosbachc41ab782011-04-06 01:11:05 +000027 // Allocate memory for the function via the memory manager.
28 uintptr_t Size = EndAddress - StartAddress + 1;
Jim Grosbachffa62502011-05-13 20:12:14 +000029 uintptr_t AllocSize = Size;
30 uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize);
Jim Grosbachc41ab782011-04-06 01:11:05 +000031 assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) &&
32 "Memory manager failed to allocate enough memory!");
33 // Copy the function payload into the memory block.
Jim Grosbachffa62502011-05-13 20:12:14 +000034 memcpy(Mem, StartAddress, Size);
Jim Grosbachc41ab782011-04-06 01:11:05 +000035 MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size);
36 // Remember where we put it.
37 Functions[Name] = sys::MemoryBlock(Mem, Size);
Jim Grosbachf8c1c842011-04-12 21:20:41 +000038 // Default the assigned address for this symbol to wherever this
39 // allocated it.
40 SymbolTable[Name] = Mem;
Jim Grosbachffa62502011-05-13 20:12:14 +000041 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n");
Jim Grosbachc41ab782011-04-06 01:11:05 +000042}
43
Jim Grosbachf8c1c842011-04-12 21:20:41 +000044// Resolve the relocations for all symbols we currently know about.
45void 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
Jim Grosbach6e563312011-03-21 22:15:52 +000054//===----------------------------------------------------------------------===//
55// RuntimeDyld class implementation
Danil Malyshevcf852dc2011-07-13 07:57:58 +000056RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
57 Dyld = 0;
58 MM = mm;
Jim Grosbach6e563312011-03-21 22:15:52 +000059}
60
61RuntimeDyld::~RuntimeDyld() {
62 delete Dyld;
63}
64
65bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
Danil Malyshevcf852dc2011-07-13 07:57:58 +000066 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
Jim Grosbach6e563312011-03-21 22:15:52 +000076 return Dyld->loadObject(InputBuffer);
77}
78
Jim Grosbachb0271052011-04-08 17:31:24 +000079void *RuntimeDyld::getSymbolAddress(StringRef Name) {
Jim Grosbach6e563312011-03-21 22:15:52 +000080 return Dyld->getSymbolAddress(Name);
81}
82
Jim Grosbachf8c1c842011-04-12 21:20:41 +000083void RuntimeDyld::resolveRelocations() {
84 Dyld->resolveRelocations();
85}
86
87void RuntimeDyld::reassignSymbolAddress(StringRef Name, uint8_t *Addr) {
88 Dyld->reassignSymbolAddress(Name, Addr);
89}
90
Jim Grosbach91dde152011-03-22 18:22:27 +000091StringRef RuntimeDyld::getErrorString() {
Jim Grosbachb3eecaf2011-03-22 18:19:42 +000092 return Dyld->getErrorString();
93}
94
Jim Grosbach6e563312011-03-21 22:15:52 +000095} // end namespace llvm