Tidy up.
[oota-llvm.git] / lib / ExecutionEngine / RuntimeDyld / RuntimeDyldImpl.h
1 //===-- 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"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/IndexedMap.h"
21 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/ExecutionEngine/ExecutionEngine.h"
25 #include "llvm/Support/Format.h"
26 #include "llvm/Support/Memory.h"
27 #include "llvm/Support/MemoryBuffer.h"
28 #include "llvm/Support/system_error.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32
33 using namespace llvm;
34 using namespace llvm::object;
35
36 namespace llvm {
37 class RuntimeDyldImpl {
38 protected:
39   unsigned CPUType;
40   unsigned CPUSubtype;
41
42   // The MemoryManager to load objects into.
43   RTDyldMemoryManager *MemMgr;
44
45   // For each section, we have a MemoryBlock of it's data.
46   // Indexed by SectionID.
47   SmallVector<sys::MemoryBlock, 32> Sections;
48   // For each section, the address it will be considered to live at for
49   // relocations. The same as the pointer to the above memory block for hosted
50   // JITs. Indexed by SectionID.
51   SmallVector<uint64_t, 32> SectionLoadAddress;
52
53   // Keep a map of starting local address to the SectionID which references it.
54   // Lookup function for when we assign virtual addresses.
55   DenseMap<void *, unsigned> SectionLocalMemToID;
56
57   // Master symbol table. As modules are loaded and external symbols are
58   // resolved, their addresses are stored here as a SectionID/Offset pair.
59   typedef std::pair<unsigned, uint64_t> SymbolLoc;
60   StringMap<SymbolLoc> SymbolTable;
61
62   bool HasError;
63   std::string ErrorStr;
64
65   // Set the error state and record an error string.
66   bool Error(const Twine &Msg) {
67     ErrorStr = Msg.str();
68     HasError = true;
69     return true;
70   }
71
72   uint8_t *getSectionAddress(unsigned SectionID) {
73     return (uint8_t*)Sections[SectionID].base();
74   }
75   void extractFunction(StringRef Name, uint8_t *StartAddress,
76                        uint8_t *EndAddress);
77
78 public:
79   RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {}
80
81   virtual ~RuntimeDyldImpl();
82
83   virtual bool loadObject(MemoryBuffer *InputBuffer) = 0;
84
85   void *getSymbolAddress(StringRef Name) {
86     // FIXME: Just look up as a function for now. Overly simple of course.
87     // Work in progress.
88     if (SymbolTable.find(Name) == SymbolTable.end())
89       return 0;
90     SymbolLoc Loc = SymbolTable.lookup(Name);
91     return getSectionAddress(Loc.first) + Loc.second;
92   }
93
94   virtual void resolveRelocations();
95
96   virtual void reassignSectionAddress(unsigned SectionID, uint64_t Addr) = 0;
97
98   void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress);
99
100   // Is the linker in an error state?
101   bool hasError() { return HasError; }
102
103   // Mark the error condition as handled and continue.
104   void clearError() { HasError = false; }
105
106   // Get the error message.
107   StringRef getErrorString() { return ErrorStr; }
108
109   virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0;
110 };
111
112 class RuntimeDyldELF : public RuntimeDyldImpl {
113     // For each symbol, keep a list of relocations based on it. Anytime
114     // its address is reassigned (the JIT re-compiled the function, e.g.),
115     // the relocations get re-resolved.
116     struct RelocationEntry {
117       // Function or section this relocation is contained in.
118       std::string Target;
119       // Offset into the target function or section for the relocation.
120       uint32_t    Offset;
121       // Relocation type
122       uint32_t    Type;
123       // Addend encoded in the instruction itself, if any.
124       int32_t     Addend;
125       // Has the relocation been recalcuated as an offset within a function?
126       bool        IsFunctionRelative;
127       // Has this relocation been resolved previously?
128       bool        isResolved;
129
130       RelocationEntry(StringRef t,
131                       uint32_t offset,
132                       uint32_t type,
133                       int32_t addend,
134                       bool isFunctionRelative)
135         : Target(t)
136         , Offset(offset)
137         , Type(type)
138         , Addend(addend)
139         , IsFunctionRelative(isFunctionRelative)
140         , isResolved(false) { }
141     };
142     typedef SmallVector<RelocationEntry, 4> RelocationList;
143     StringMap<RelocationList> Relocations;
144     unsigned Arch;
145
146     void resolveRelocations();
147
148     void resolveX86_64Relocation(StringRef Name,
149                                  uint8_t *Addr,
150                                  const RelocationEntry &RE);
151
152     void resolveX86Relocation(StringRef Name,
153                               uint8_t *Addr,
154                               const RelocationEntry &RE);
155
156     void resolveArmRelocation(StringRef Name,
157                               uint8_t *Addr,
158                               const RelocationEntry &RE);
159
160     void resolveRelocation(StringRef Name,
161                            uint8_t *Addr,
162                            const RelocationEntry &RE);
163
164 public:
165   RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
166
167   bool loadObject(MemoryBuffer *InputBuffer);
168
169   void reassignSymbolAddress(StringRef Name, uint8_t *Addr);
170   void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
171
172   bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const;
173 };
174
175
176 class RuntimeDyldMachO : public RuntimeDyldImpl {
177
178   // For each symbol, keep a list of relocations based on it. Anytime
179   // its address is reassigned (the JIT re-compiled the function, e.g.),
180   // the relocations get re-resolved.
181   // The symbol (or section) the relocation is sourced from is the Key
182   // in the relocation list where it's stored.
183   struct RelocationEntry {
184     unsigned    SectionID;  // Section the relocation is contained in.
185     uint64_t    Offset;     // Offset into the section for the relocation.
186     uint32_t    Data;       // Second word of the raw macho relocation entry.
187     int64_t     Addend;     // Addend encoded in the instruction itself, if any,
188                             // plus the offset into the source section for
189                             // the symbol once the relocation is resolvable.
190
191     RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend)
192       : SectionID(id), Offset(offset), Data(data), Addend(addend) {}
193   };
194   typedef SmallVector<RelocationEntry, 4> RelocationList;
195   // Relocations to sections already loaded. Indexed by SectionID which is the
196   // source of the address. The target where the address will be writen is
197   // SectionID/Offset in the relocation itself.
198   IndexedMap<RelocationList> Relocations;
199   // Relocations to symbols that are not yet resolved. Must be external
200   // relocations by definition. Indexed by symbol name.
201   StringMap<RelocationList> UnresolvedRelocations;
202
203   bool resolveRelocation(uint8_t *Address, uint64_t Value, bool isPCRel,
204                          unsigned Type, unsigned Size, int64_t Addend);
205   bool resolveX86_64Relocation(uintptr_t Address, uintptr_t Value, bool isPCRel,
206                                unsigned Type, unsigned Size, int64_t Addend);
207   bool resolveARMRelocation(uintptr_t Address, uintptr_t Value, bool isPCRel,
208                             unsigned Type, unsigned Size, int64_t Addend);
209
210   bool loadSegment32(const MachOObject *Obj,
211                      const MachOObject::LoadCommandInfo *SegmentLCI,
212                      const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
213   bool loadSegment64(const MachOObject *Obj,
214                      const MachOObject::LoadCommandInfo *SegmentLCI,
215                      const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
216   bool processSymbols32(const MachOObject *Obj,
217                       SmallVectorImpl<unsigned> &SectionMap,
218                       SmallVectorImpl<StringRef> &SymbolNames,
219                       const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
220   bool processSymbols64(const MachOObject *Obj,
221                       SmallVectorImpl<unsigned> &SectionMap,
222                       SmallVectorImpl<StringRef> &SymbolNames,
223                       const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
224
225   void resolveSymbol(StringRef Name);
226
227 public:
228   RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
229
230   bool loadObject(MemoryBuffer *InputBuffer);
231
232   void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
233
234   static bool isKnownFormat(const MemoryBuffer *InputBuffer);
235
236   bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const {
237     return isKnownFormat(InputBuffer);
238   }
239 };
240
241 } // end namespace llvm
242
243
244 #endif