blob: 51f6ef0a872180bd8bdfb2dc974527003b5e2e60 [file] [log] [blame]
Jim Grosbache0934be2012-01-16 23:50: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"
Eli Benderskya66a1852012-01-16 08:56:09 +000016#include "llvm/Support/Path.h"
Jim Grosbach6e563312011-03-21 22:15:52 +000017using namespace llvm;
18using namespace llvm::object;
19
Chandler Carruth53c5e7b2011-04-05 23:54:31 +000020// Empty out-of-line virtual destructor as the key function.
21RTDyldMemoryManager::~RTDyldMemoryManager() {}
Danil Malyshevcf852dc2011-07-13 07:57:58 +000022RuntimeDyldImpl::~RuntimeDyldImpl() {}
Chandler Carruth53c5e7b2011-04-05 23:54:31 +000023
Jim Grosbach6e563312011-03-21 22:15:52 +000024namespace llvm {
Jim Grosbach6e563312011-03-21 22:15:52 +000025
Jim Grosbachc41ab782011-04-06 01:11:05 +000026void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress,
Jim Grosbach01ccab42011-04-06 22:13:52 +000027 uint8_t *EndAddress) {
Jim Grosbach61425c02012-01-16 22:26:39 +000028 // FIXME: DEPRECATED in favor of by-section allocation.
Jim Grosbachc41ab782011-04-06 01:11:05 +000029 // Allocate memory for the function via the memory manager.
30 uintptr_t Size = EndAddress - StartAddress + 1;
Jim Grosbachffa62502011-05-13 20:12:14 +000031 uintptr_t AllocSize = Size;
32 uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize);
Jim Grosbachc41ab782011-04-06 01:11:05 +000033 assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) &&
34 "Memory manager failed to allocate enough memory!");
35 // Copy the function payload into the memory block.
Jim Grosbachffa62502011-05-13 20:12:14 +000036 memcpy(Mem, StartAddress, Size);
Jim Grosbachc41ab782011-04-06 01:11:05 +000037 MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size);
38 // Remember where we put it.
Jim Grosbach61425c02012-01-16 22:26:39 +000039 unsigned SectionID = Sections.size();
40 Sections.push_back(sys::MemoryBlock(Mem, Size));
41
Jim Grosbachf8c1c842011-04-12 21:20:41 +000042 // Default the assigned address for this symbol to wherever this
43 // allocated it.
Jim Grosbache0934be2012-01-16 23:50:58 +000044 SymbolTable[Name] = SymbolLoc(SectionID, 0);
Jim Grosbachffa62502011-05-13 20:12:14 +000045 DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n");
Jim Grosbachc41ab782011-04-06 01:11:05 +000046}
47
Jim Grosbachf8c1c842011-04-12 21:20:41 +000048// Resolve the relocations for all symbols we currently know about.
49void RuntimeDyldImpl::resolveRelocations() {
Jim Grosbach61425c02012-01-16 22:26:39 +000050 // 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]);
54 }
Jim Grosbachf8c1c842011-04-12 21:20:41 +000055}
56
Jim Grosbach020f4e82012-01-16 23:50:55 +000057void 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);
63}
64
Jim Grosbach6e563312011-03-21 22:15:52 +000065//===----------------------------------------------------------------------===//
66// RuntimeDyld class implementation
Danil Malyshevcf852dc2011-07-13 07:57:58 +000067RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
68 Dyld = 0;
69 MM = mm;
Jim Grosbach6e563312011-03-21 22:15:52 +000070}
71
72RuntimeDyld::~RuntimeDyld() {
73 delete Dyld;
74}
75
76bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
Danil Malyshevcf852dc2011-07-13 07:57:58 +000077 if (!Dyld) {
Eli Benderskya66a1852012-01-16 08:56:09 +000078 sys::LLVMFileType type = sys::IdentifyFileType(
79 InputBuffer->getBufferStart(),
80 static_cast<unsigned>(InputBuffer->getBufferSize()));
81 switch (type) {
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);
87 break;
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);
99 break;
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!");
105 }
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000106 } else {
Eli Benderskya66a1852012-01-16 08:56:09 +0000107 if (!Dyld->isCompatibleFormat(InputBuffer))
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000108 report_fatal_error("Incompatible object format!");
109 }
110
Jim Grosbach6e563312011-03-21 22:15:52 +0000111 return Dyld->loadObject(InputBuffer);
112}
113
Jim Grosbachb0271052011-04-08 17:31:24 +0000114void *RuntimeDyld::getSymbolAddress(StringRef Name) {
Jim Grosbach6e563312011-03-21 22:15:52 +0000115 return Dyld->getSymbolAddress(Name);
116}
117
Jim Grosbachf8c1c842011-04-12 21:20:41 +0000118void RuntimeDyld::resolveRelocations() {
119 Dyld->resolveRelocations();
120}
121
Jim Grosbach61425c02012-01-16 22:26:39 +0000122void RuntimeDyld::reassignSectionAddress(unsigned SectionID,
123 uint64_t Addr) {
124 Dyld->reassignSectionAddress(SectionID, Addr);
Jim Grosbachf8c1c842011-04-12 21:20:41 +0000125}
126
Jim Grosbach020f4e82012-01-16 23:50:55 +0000127void RuntimeDyld::mapSectionAddress(void *LocalAddress,
128 uint64_t TargetAddress) {
129 Dyld->mapSectionAddress(LocalAddress, TargetAddress);
130}
131
Jim Grosbach91dde152011-03-22 18:22:27 +0000132StringRef RuntimeDyld::getErrorString() {
Jim Grosbachb3eecaf2011-03-22 18:19:42 +0000133 return Dyld->getErrorString();
134}
135
Jim Grosbach6e563312011-03-21 22:15:52 +0000136} // end namespace llvm