1 //===-- RuntimeDyld.cpp - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Implementation of the MC-JIT runtime dynamic linker.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "dyld"
15 #include "RuntimeDyldImpl.h"
16 #include "llvm/Support/Path.h"
18 using namespace llvm::object;
20 // Empty out-of-line virtual destructor as the key function.
21 RTDyldMemoryManager::~RTDyldMemoryManager() {}
22 RuntimeDyldImpl::~RuntimeDyldImpl() {}
26 void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress,
27 uint8_t *EndAddress) {
28 // FIXME: DEPRECATED in favor of by-section allocation.
29 // Allocate memory for the function via the memory manager.
30 uintptr_t Size = EndAddress - StartAddress + 1;
31 uintptr_t AllocSize = Size;
32 uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize);
33 assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) &&
34 "Memory manager failed to allocate enough memory!");
35 // Copy the function payload into the memory block.
36 memcpy(Mem, StartAddress, Size);
37 MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size);
38 // Remember where we put it.
39 unsigned SectionID = Sections.size();
40 Sections.push_back(sys::MemoryBlock(Mem, Size));
42 // Default the assigned address for this symbol to wherever this
44 SymbolTable[Name] = SymbolLoc(SectionID, 0);
45 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n");
48 // Resolve the relocations for all symbols we currently know about.
49 void RuntimeDyldImpl::resolveRelocations() {
50 // Just iterate over the sections we have and resolve all the relocations
51 // in them. Gross overkill, but it gets the job done.
52 for (int i = 0, e = Sections.size(); i != e; ++i) {
53 reassignSectionAddress(i, SectionLoadAddress[i]);
57 void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress,
58 uint64_t TargetAddress) {
59 assert(SectionLocalMemToID.count(LocalAddress) &&
60 "Attempting to remap address of unknown section!");
61 unsigned SectionID = SectionLocalMemToID[LocalAddress];
62 reassignSectionAddress(SectionID, TargetAddress);
65 //===----------------------------------------------------------------------===//
66 // RuntimeDyld class implementation
67 RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
72 RuntimeDyld::~RuntimeDyld() {
76 bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
78 sys::LLVMFileType type = sys::IdentifyFileType(
79 InputBuffer->getBufferStart(),
80 static_cast<unsigned>(InputBuffer->getBufferSize()));
82 case sys::ELF_Relocatable_FileType:
83 case sys::ELF_Executable_FileType:
84 case sys::ELF_SharedObject_FileType:
85 case sys::ELF_Core_FileType:
86 Dyld = new RuntimeDyldELF(MM);
88 case sys::Mach_O_Object_FileType:
89 case sys::Mach_O_Executable_FileType:
90 case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
91 case sys::Mach_O_Core_FileType:
92 case sys::Mach_O_PreloadExecutable_FileType:
93 case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
94 case sys::Mach_O_DynamicLinker_FileType:
95 case sys::Mach_O_Bundle_FileType:
96 case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
97 case sys::Mach_O_DSYMCompanion_FileType:
98 Dyld = new RuntimeDyldMachO(MM);
100 case sys::Unknown_FileType:
101 case sys::Bitcode_FileType:
102 case sys::Archive_FileType:
103 case sys::COFF_FileType:
104 report_fatal_error("Incompatible object format!");
107 if (!Dyld->isCompatibleFormat(InputBuffer))
108 report_fatal_error("Incompatible object format!");
111 return Dyld->loadObject(InputBuffer);
114 void *RuntimeDyld::getSymbolAddress(StringRef Name) {
115 return Dyld->getSymbolAddress(Name);
118 void RuntimeDyld::resolveRelocations() {
119 Dyld->resolveRelocations();
122 void RuntimeDyld::reassignSectionAddress(unsigned SectionID,
124 Dyld->reassignSectionAddress(SectionID, Addr);
127 void RuntimeDyld::mapSectionAddress(void *LocalAddress,
128 uint64_t TargetAddress) {
129 Dyld->mapSectionAddress(LocalAddress, TargetAddress);
132 StringRef RuntimeDyld::getErrorString() {
133 return Dyld->getErrorString();
136 } // end namespace llvm