Split the lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h header to smaller logical...
[oota-llvm.git] / 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 #include "RuntimeDyldELF.h"
17 #include "RuntimeDyldMachO.h"
18 #include "llvm/Support/Path.h"
19
20 using namespace llvm;
21 using namespace llvm::object;
22
23 // Empty out-of-line virtual destructor as the key function.
24 RTDyldMemoryManager::~RTDyldMemoryManager() {}
25 RuntimeDyldImpl::~RuntimeDyldImpl() {}
26
27 namespace llvm {
28
29 void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress,
30                                       uint8_t *EndAddress) {
31   // FIXME: DEPRECATED in favor of by-section allocation.
32   // Allocate memory for the function via the memory manager.
33   uintptr_t Size = EndAddress - StartAddress + 1;
34   uintptr_t AllocSize = Size;
35   uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize);
36   assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) &&
37          "Memory manager failed to allocate enough memory!");
38   // Copy the function payload into the memory block.
39   memcpy(Mem, StartAddress, Size);
40   MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size);
41   // Remember where we put it.
42   unsigned SectionID = Sections.size();
43   Sections.push_back(sys::MemoryBlock(Mem, Size));
44
45   // Default the assigned address for this symbol to wherever this
46   // allocated it.
47   SymbolTable[Name] = SymbolLoc(SectionID, 0);
48   DEBUG(dbgs() << "    allocated to [" << Mem << ", " << Mem + Size << "]\n");
49 }
50
51 // Resolve the relocations for all symbols we currently know about.
52 void RuntimeDyldImpl::resolveRelocations() {
53   // Just iterate over the sections we have and resolve all the relocations
54   // in them. Gross overkill, but it gets the job done.
55   for (int i = 0, e = Sections.size(); i != e; ++i) {
56     reassignSectionAddress(i, SectionLoadAddress[i]);
57   }
58 }
59
60 void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress,
61                                         uint64_t TargetAddress) {
62   assert(SectionLocalMemToID.count(LocalAddress) &&
63          "Attempting to remap address of unknown section!");
64   unsigned SectionID = SectionLocalMemToID[LocalAddress];
65   reassignSectionAddress(SectionID, TargetAddress);
66 }
67
68 //===----------------------------------------------------------------------===//
69 // RuntimeDyld class implementation
70 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
71   Dyld = 0;
72   MM = mm;
73 }
74
75 RuntimeDyld::~RuntimeDyld() {
76   delete Dyld;
77 }
78
79 bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
80   if (!Dyld) {
81     sys::LLVMFileType type = sys::IdentifyFileType(
82             InputBuffer->getBufferStart(),
83             static_cast<unsigned>(InputBuffer->getBufferSize()));
84     switch (type) {
85       case sys::ELF_Relocatable_FileType:
86       case sys::ELF_Executable_FileType:
87       case sys::ELF_SharedObject_FileType:
88       case sys::ELF_Core_FileType:
89         Dyld = new RuntimeDyldELF(MM);
90         break;
91       case sys::Mach_O_Object_FileType:
92       case sys::Mach_O_Executable_FileType:
93       case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
94       case sys::Mach_O_Core_FileType:
95       case sys::Mach_O_PreloadExecutable_FileType:
96       case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
97       case sys::Mach_O_DynamicLinker_FileType:
98       case sys::Mach_O_Bundle_FileType:
99       case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
100       case sys::Mach_O_DSYMCompanion_FileType:
101         Dyld = new RuntimeDyldMachO(MM);
102         break;
103       case sys::Unknown_FileType:
104       case sys::Bitcode_FileType:
105       case sys::Archive_FileType:
106       case sys::COFF_FileType:
107         report_fatal_error("Incompatible object format!");
108     }
109   } else {
110     if (!Dyld->isCompatibleFormat(InputBuffer))
111       report_fatal_error("Incompatible object format!");
112   }
113
114   return Dyld->loadObject(InputBuffer);
115 }
116
117 void *RuntimeDyld::getSymbolAddress(StringRef Name) {
118   return Dyld->getSymbolAddress(Name);
119 }
120
121 void RuntimeDyld::resolveRelocations() {
122   Dyld->resolveRelocations();
123 }
124
125 void RuntimeDyld::reassignSectionAddress(unsigned SectionID,
126                                          uint64_t Addr) {
127   Dyld->reassignSectionAddress(SectionID, Addr);
128 }
129
130 void RuntimeDyld::mapSectionAddress(void *LocalAddress,
131                                     uint64_t TargetAddress) {
132   Dyld->mapSectionAddress(LocalAddress, TargetAddress);
133 }
134
135 StringRef RuntimeDyld::getErrorString() {
136   return Dyld->getErrorString();
137 }
138
139 } // end namespace llvm