1 //===-- RuntimeDyldImpl.h - 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 // Interface for the implementations of runtime dynamic linker facilities.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_RUNTIME_DYLD_IMPL_H
15 #define LLVM_RUNTIME_DYLD_IMPL_H
17 #include "llvm/ExecutionEngine/RuntimeDyld.h"
18 #include "llvm/Object/MachOObject.h"
19 #include "llvm/ADT/IndexedMap.h"
20 #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"
33 using namespace llvm::object;
36 class RuntimeDyldImpl {
41 // The MemoryManager to load objects into.
42 RTDyldMemoryManager *MemMgr;
44 // 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;
52 // Master symbol table. As modules are loaded and external symbols are
53 // resolved, their addresses are stored here as a SectionID/Offset pair.
54 typedef std::pair<unsigned, uint64_t> SymbolLoc;
55 StringMap<SymbolLoc> SymbolTable;
60 // Set the error state and record an error string.
61 bool Error(const Twine &Msg) {
67 uint8_t *getSectionAddress(unsigned SectionID) {
68 return (uint8_t*)Sections[SectionID].base();
70 void extractFunction(StringRef Name, uint8_t *StartAddress,
74 RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
76 virtual ~RuntimeDyldImpl();
78 virtual bool loadObject(MemoryBuffer *InputBuffer) = 0;
80 void *getSymbolAddress(StringRef Name) {
81 // FIXME: Just look up as a function for now. Overly simple of course.
83 if (SymbolTable.find(Name) == SymbolTable.end())
85 SymbolLoc Loc = SymbolTable.lookup(Name);
86 return getSectionAddress(Loc.first) + Loc.second;
89 virtual void resolveRelocations();
91 virtual void reassignSectionAddress(unsigned SectionID, uint64_t Addr) = 0;
93 // Is the linker in an error state?
94 bool hasError() { return HasError; }
96 // Mark the error condition as handled and continue.
97 void clearError() { HasError = false; }
99 // Get the error message.
100 StringRef getErrorString() { return ErrorStr; }
102 virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0;
105 class 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.
112 // Offset into the target function or section for the relocation.
116 // Addend encoded in the instruction itself, if any.
118 // Has the relocation been recalcuated as an offset within a function?
119 bool IsFunctionRelative;
120 // Has this relocation been resolved previously?
123 RelocationEntry(StringRef t,
127 bool isFunctionRelative)
132 , IsFunctionRelative(isFunctionRelative)
133 , isResolved(false) { }
135 typedef SmallVector<RelocationEntry, 4> RelocationList;
136 StringMap<RelocationList> Relocations;
139 void resolveRelocations();
141 void resolveX86_64Relocation(StringRef Name,
143 const RelocationEntry &RE);
145 void resolveX86Relocation(StringRef Name,
147 const RelocationEntry &RE);
149 void resolveArmRelocation(StringRef Name,
151 const RelocationEntry &RE);
153 void resolveRelocation(StringRef Name,
155 const RelocationEntry &RE);
158 RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
160 bool loadObject(MemoryBuffer *InputBuffer);
162 void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
163 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
165 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
169 class RuntimeDyldMachO : public RuntimeDyldImpl {
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.
174 // The symbol (or section) the relocation is sourced from is the Key
175 // in the relocation list where it's stored.
176 struct RelocationEntry {
177 unsigned SectionID; // Section the relocation is contained in.
178 uint64_t Offset; // Offset into the section for the relocation.
179 uint32_t Data; // Second word of the raw macho relocation entry.
180 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.
184 RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
185 : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
187 typedef SmallVector<RelocationEntry, 4> RelocationList;
188 // 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;
196 bool resolveRelocation(uint8_t *Address, uint64_t Value, bool isPCRel,
197 unsigned Type, unsigned Size, int64_t Addend);
198 bool resolveX86_64Relocation(uintptr_t Address, uintptr_t Value, bool isPCRel,
199 unsigned Type, unsigned Size, int64_t Addend);
200 bool resolveARMRelocation(uintptr_t Address, uintptr_t Value, bool isPCRel,
201 unsigned Type, unsigned Size, int64_t Addend);
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);
209 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);
218 void resolveSymbol(StringRef Name);
221 RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
223 bool loadObject(MemoryBuffer *InputBuffer);
225 void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
227 static bool isKnownFormat(const MemoryBuffer *InputBuffer);
229 bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
230 return isKnownFormat(InputBuffer);
234 } // end namespace llvm