blob: 2896c2d556c55ee9d3dc3d17b1f84fe822641ab8 [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 Bendersky76463fd2012-01-22 07:05:02 +000016#include "RuntimeDyldELF.h"
17#include "RuntimeDyldMachO.h"
Eli Benderskya66a1852012-01-16 08:56:09 +000018#include "llvm/Support/Path.h"
Eli Bendersky76463fd2012-01-22 07:05:02 +000019
Jim Grosbach6e563312011-03-21 22:15:52 +000020using namespace llvm;
21using namespace llvm::object;
22
Chandler Carruth53c5e7b2011-04-05 23:54:31 +000023// Empty out-of-line virtual destructor as the key function.
24RTDyldMemoryManager::~RTDyldMemoryManager() {}
Danil Malyshevcf852dc2011-07-13 07:57:58 +000025RuntimeDyldImpl::~RuntimeDyldImpl() {}
Chandler Carruth53c5e7b2011-04-05 23:54:31 +000026
Jim Grosbach6e563312011-03-21 22:15:52 +000027namespace llvm {
Jim Grosbach6e563312011-03-21 22:15:52 +000028
Bill Wendling288967d2012-03-29 23:23:59 +000029void 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));
Jim Grosbach61425c02012-01-16 22:26:39 +000044
Bill Wendling288967d2012-03-29 23:23:59 +000045 // 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}
Jim Grosbachc41ab782011-04-06 01:11:05 +000050
Jim Grosbachf8c1c842011-04-12 21:20:41 +000051// Resolve the relocations for all symbols we currently know about.
52void RuntimeDyldImpl::resolveRelocations() {
Jim Grosbach61425c02012-01-16 22:26:39 +000053 // 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) {
Bill Wendling288967d2012-03-29 23:23:59 +000056 reassignSectionAddress(i, SectionLoadAddress[i]);
Jim Grosbach61425c02012-01-16 22:26:39 +000057 }
Jim Grosbachf8c1c842011-04-12 21:20:41 +000058}
59
Jim Grosbach020f4e82012-01-16 23:50:55 +000060void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress,
61 uint64_t TargetAddress) {
Bill Wendling288967d2012-03-29 23:23:59 +000062 assert(SectionLocalMemToID.count(LocalAddress) &&
63 "Attempting to remap address of unknown section!");
64 unsigned SectionID = SectionLocalMemToID[LocalAddress];
65 reassignSectionAddress(SectionID, TargetAddress);
Jim Grosbach020f4e82012-01-16 23:50:55 +000066}
67
Jim Grosbach6e563312011-03-21 22:15:52 +000068//===----------------------------------------------------------------------===//
69// RuntimeDyld class implementation
Danil Malyshevcf852dc2011-07-13 07:57:58 +000070RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
71 Dyld = 0;
72 MM = mm;
Jim Grosbach6e563312011-03-21 22:15:52 +000073}
74
75RuntimeDyld::~RuntimeDyld() {
76 delete Dyld;
77}
78
79bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
Danil Malyshevcf852dc2011-07-13 07:57:58 +000080 if (!Dyld) {
Eli Benderskya66a1852012-01-16 08:56:09 +000081 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 }
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000109 } else {
Eli Benderskya66a1852012-01-16 08:56:09 +0000110 if (!Dyld->isCompatibleFormat(InputBuffer))
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000111 report_fatal_error("Incompatible object format!");
112 }
113
Jim Grosbach6e563312011-03-21 22:15:52 +0000114 return Dyld->loadObject(InputBuffer);
115}
116
Jim Grosbachb0271052011-04-08 17:31:24 +0000117void *RuntimeDyld::getSymbolAddress(StringRef Name) {
Jim Grosbach6e563312011-03-21 22:15:52 +0000118 return Dyld->getSymbolAddress(Name);
119}
120
Jim Grosbachf8c1c842011-04-12 21:20:41 +0000121void RuntimeDyld::resolveRelocations() {
122 Dyld->resolveRelocations();
123}
124
Jim Grosbach61425c02012-01-16 22:26:39 +0000125void RuntimeDyld::reassignSectionAddress(unsigned SectionID,
126 uint64_t Addr) {
127 Dyld->reassignSectionAddress(SectionID, Addr);
Jim Grosbachf8c1c842011-04-12 21:20:41 +0000128}
129
Jim Grosbach020f4e82012-01-16 23:50:55 +0000130void RuntimeDyld::mapSectionAddress(void *LocalAddress,
131 uint64_t TargetAddress) {
132 Dyld->mapSectionAddress(LocalAddress, TargetAddress);
133}
134
Jim Grosbach91dde152011-03-22 18:22:27 +0000135StringRef RuntimeDyld::getErrorString() {
Jim Grosbachb3eecaf2011-03-22 18:19:42 +0000136 return Dyld->getErrorString();
137}
138
Jim Grosbach6e563312011-03-21 22:15:52 +0000139} // end namespace llvm