blob: bbfef768c4cd902352f3a7bfad1e3572e6ed9c81 [file] [log] [blame]
Danil Malyshevcf852dc2011-07-13 07:57:58 +00001//===-- RuntimeDyldImpl.h - 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// Interface for the implementations of runtime dynamic linker facilities.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_RUNTIME_DYLD_IMPL_H
15#define LLVM_RUNTIME_DYLD_IMPL_H
16
17#include "llvm/ExecutionEngine/RuntimeDyld.h"
18#include "llvm/Object/MachOObject.h"
Jim Grosbach61425c02012-01-16 22:26:39 +000019#include "llvm/ADT/IndexedMap.h"
Danil Malyshevcf852dc2011-07-13 07:57:58 +000020#include "llvm/ADT/StringMap.h"
21#include "llvm/ADT/Twine.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ExecutionEngine/ExecutionEngine.h"
24#include "llvm/Support/Format.h"
25#include "llvm/Support/Memory.h"
26#include "llvm/Support/MemoryBuffer.h"
27#include "llvm/Support/system_error.h"
28#include "llvm/Support/raw_ostream.h"
29#include "llvm/Support/Debug.h"
30#include "llvm/Support/ErrorHandling.h"
31
32using namespace llvm;
33using namespace llvm::object;
34
35namespace llvm {
36class RuntimeDyldImpl {
37protected:
38 unsigned CPUType;
39 unsigned CPUSubtype;
40
41 // The MemoryManager to load objects into.
42 RTDyldMemoryManager *MemMgr;
43
Jim Grosbach61425c02012-01-16 22:26:39 +000044 // For each section, we have a MemoryBlock of it's data.
45 // Indexed by SectionID.
46 SmallVector<sys::MemoryBlock, 32> Sections;
47 // For each section, the address it will be considered to live at for
48 // relocations. The same as the pointer the above memory block for hosted
49 // JITs. Indexed by SectionID.
50 SmallVector<uint64_t, 32> SectionLoadAddress;
Danil Malyshevcf852dc2011-07-13 07:57:58 +000051
52 // Master symbol table. As modules are loaded and external symbols are
Jim Grosbach61425c02012-01-16 22:26:39 +000053 // resolved, their addresses are stored here as a SectionID/Offset pair.
54 typedef std::pair<unsigned, uint64_t> SymbolLoc;
55 StringMap<SymbolLoc> SymbolTable;
Danil Malyshevcf852dc2011-07-13 07:57:58 +000056
57 bool HasError;
58 std::string ErrorStr;
59
60 // Set the error state and record an error string.
61 bool Error(const Twine &Msg) {
62 ErrorStr = Msg.str();
63 HasError = true;
64 return true;
65 }
66
Jim Grosbach61425c02012-01-16 22:26:39 +000067 uint8_t *getSectionAddress(unsigned SectionID) {
68 return (uint8_t*)Sections[SectionID].base();
69 }
Danil Malyshevcf852dc2011-07-13 07:57:58 +000070 void extractFunction(StringRef Name, uint8_t *StartAddress,
71 uint8_t *EndAddress);
72
73public:
74 RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
75
76 virtual ~RuntimeDyldImpl();
77
78 virtual bool loadObject(MemoryBuffer *InputBuffer) = 0;
79
80 void *getSymbolAddress(StringRef Name) {
81 // FIXME: Just look up as a function for now. Overly simple of course.
82 // Work in progress.
Jim Grosbach61425c02012-01-16 22:26:39 +000083 if (SymbolTable.find(Name) == SymbolTable.end())
84 return 0;
85 SymbolLoc Loc = SymbolTable.lookup(Name);
86 return getSectionAddress(Loc.first) + Loc.second;
Danil Malyshevcf852dc2011-07-13 07:57:58 +000087 }
88
Jim Grosbach61425c02012-01-16 22:26:39 +000089 virtual void resolveRelocations();
Danil Malyshevcf852dc2011-07-13 07:57:58 +000090
Jim Grosbach61425c02012-01-16 22:26:39 +000091 virtual void reassignSectionAddress(unsigned SectionID, uint64_t Addr) = 0;
Danil Malyshevcf852dc2011-07-13 07:57:58 +000092
93 // Is the linker in an error state?
94 bool hasError() { return HasError; }
95
96 // Mark the error condition as handled and continue.
97 void clearError() { HasError = false; }
98
99 // Get the error message.
100 StringRef getErrorString() { return ErrorStr; }
101
102 virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0;
103};
104
Eli Benderskya66a1852012-01-16 08:56:09 +0000105class RuntimeDyldELF : public RuntimeDyldImpl {
106 // For each symbol, keep a list of relocations based on it. Anytime
107 // its address is reassigned (the JIT re-compiled the function, e.g.),
108 // the relocations get re-resolved.
109 struct RelocationEntry {
110 // Function or section this relocation is contained in.
111 std::string Target;
112 // Offset into the target function or section for the relocation.
113 uint32_t Offset;
114 // Relocation type
115 uint32_t Type;
116 // Addend encoded in the instruction itself, if any.
117 int32_t Addend;
118 // Has the relocation been recalcuated as an offset within a function?
119 bool IsFunctionRelative;
120 // Has this relocation been resolved previously?
121 bool isResolved;
122
123 RelocationEntry(StringRef t,
124 uint32_t offset,
125 uint32_t type,
126 int32_t addend,
127 bool isFunctionRelative)
128 : Target(t)
129 , Offset(offset)
130 , Type(type)
131 , Addend(addend)
132 , IsFunctionRelative(isFunctionRelative)
133 , isResolved(false) { }
134 };
135 typedef SmallVector<RelocationEntry, 4> RelocationList;
136 StringMap<RelocationList> Relocations;
137 unsigned Arch;
138
Jim Grosbach61425c02012-01-16 22:26:39 +0000139 void resolveRelocations();
140
Eli Benderskya66a1852012-01-16 08:56:09 +0000141 void resolveX86_64Relocation(StringRef Name,
142 uint8_t *Addr,
143 const RelocationEntry &RE);
144
145 void resolveX86Relocation(StringRef Name,
146 uint8_t *Addr,
147 const RelocationEntry &RE);
148
149 void resolveArmRelocation(StringRef Name,
150 uint8_t *Addr,
151 const RelocationEntry &RE);
152
153 void resolveRelocation(StringRef Name,
154 uint8_t *Addr,
155 const RelocationEntry &RE);
156
157public:
158 RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
159
160 bool loadObject(MemoryBuffer *InputBuffer);
161
162 void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
Jim Grosbach61425c02012-01-16 22:26:39 +0000163 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
Eli Benderskya66a1852012-01-16 08:56:09 +0000164
165 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
166};
167
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000168
169class RuntimeDyldMachO : public RuntimeDyldImpl {
170
171 // For each symbol, keep a list of relocations based on it. Anytime
172 // its address is reassigned (the JIT re-compiled the function, e.g.),
173 // the relocations get re-resolved.
Jim Grosbach61425c02012-01-16 22:26:39 +0000174 // The symbol (or section) the relocation is sourced from is the Key
175 // in the relocation list where it's stored.
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000176 struct RelocationEntry {
Jim Grosbach61425c02012-01-16 22:26:39 +0000177 unsigned SectionID; // Section the relocation is contained in.
178 uint64_t Offset; // Offset into the section for the relocation.
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000179 uint32_t Data; // Second word of the raw macho relocation entry.
Jim Grosbach61425c02012-01-16 22:26:39 +0000180 int64_t Addend; // Addend encoded in the instruction itself, if any,
181 // plus the offset into the source section for
182 // the symbol once the relocation is resolvable.
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000183
Jim Grosbach61425c02012-01-16 22:26:39 +0000184 RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
185 : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000186 };
187 typedef SmallVector<RelocationEntry, 4> RelocationList;
Jim Grosbach61425c02012-01-16 22:26:39 +0000188 // Relocations to sections already loaded. Indexed by SectionID which is the
189 // source of the address. The target where the address will be writen is
190 // SectionID/Offset in the relocation itself.
191 IndexedMap<RelocationList> Relocations;
192 // Relocations to symbols that are not yet resolved. Must be external
193 // relocations by definition. Indexed by symbol name.
194 StringMap<RelocationList> UnresolvedRelocations;
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000195
Jim Grosbach61425c02012-01-16 22:26:39 +0000196 bool resolveRelocation(uint8_t *Address, uint64_t Value, bool isPCRel,
197 unsigned Type, unsigned Size, int64_t Addend);
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000198 bool resolveX86_64Relocation(uintptr_t Address, uintptr_t Value, bool isPCRel,
Jim Grosbach61425c02012-01-16 22:26:39 +0000199 unsigned Type, unsigned Size, int64_t Addend);
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000200 bool resolveARMRelocation(uintptr_t Address, uintptr_t Value, bool isPCRel,
Jim Grosbach61425c02012-01-16 22:26:39 +0000201 unsigned Type, unsigned Size, int64_t Addend);
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000202
203 bool loadSegment32(const MachOObject *Obj,
204 const MachOObject::LoadCommandInfo *SegmentLCI,
205 const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
206 bool loadSegment64(const MachOObject *Obj,
207 const MachOObject::LoadCommandInfo *SegmentLCI,
208 const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
Jim Grosbach61425c02012-01-16 22:26:39 +0000209 bool processSymbols32(const MachOObject *Obj,
210 SmallVectorImpl<unsigned> &SectionMap,
211 SmallVectorImpl<StringRef> &SymbolNames,
212 const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
213 bool processSymbols64(const MachOObject *Obj,
214 SmallVectorImpl<unsigned> &SectionMap,
215 SmallVectorImpl<StringRef> &SymbolNames,
216 const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
217
218 void resolveSymbol(StringRef Name);
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000219
220public:
221 RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
222
223 bool loadObject(MemoryBuffer *InputBuffer);
224
Jim Grosbach61425c02012-01-16 22:26:39 +0000225 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000226
227 static bool isKnownFormat(const MemoryBuffer *InputBuffer);
228
229 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
230 return isKnownFormat(InputBuffer);
Eric Christophercf1e9672011-07-20 02:44:39 +0000231 }
Danil Malyshevcf852dc2011-07-13 07:57:58 +0000232};
233
234} // end namespace llvm
235
236
237#endif