Tidy up.
[oota-llvm.git] / lib / ExecutionEngine / RuntimeDyld / RuntimeDyld.cpp
1 //===-- RuntimeDyld.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 // Implementation of the MC-JIT runtime dynamic linker.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/ADT/OwningPtr.h"
15 #include "llvm/ADT/StringMap.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/ExecutionEngine/RuntimeDyld.h"
19 #include "llvm/Object/MachOObject.h"
20 #include "llvm/Support/Memory.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include "llvm/Support/system_error.h"
23 using namespace llvm;
24 using namespace llvm::object;
25
26 namespace llvm {
27 class RuntimeDyldImpl {
28   // Master symbol table. As modules are loaded and external symbols are
29   // resolved, their addresses are stored here.
30   StringMap<void*> SymbolTable;
31
32   // FIXME: Should have multiple data blocks, one for each loaded chunk of
33   //        compiled code.
34   sys::MemoryBlock Data;
35
36   bool HasError;
37   std::string ErrorStr;
38
39   // Set the error state and record an error string.
40   bool Error(const Twine &Msg) {
41     ErrorStr = Msg.str();
42     HasError = true;
43     return true;
44   }
45
46   bool loadSegment32(const MachOObject *Obj,
47                      const MachOObject::LoadCommandInfo *SegmentLCI,
48                      const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
49   bool loadSegment64(const MachOObject *Obj,
50                      const MachOObject::LoadCommandInfo *SegmentLCI,
51                      const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);
52
53 public:
54   RuntimeDyldImpl() : HasError(false) {}
55
56   bool loadObject(MemoryBuffer *InputBuffer);
57
58   void *getSymbolAddress(StringRef Name) {
59     // Use lookup() rather than [] because we don't want to add an entry
60     // if there isn't one already, which the [] operator does.
61     return SymbolTable.lookup(Name);
62   }
63
64   sys::MemoryBlock getMemoryBlock() { return Data; }
65
66   // Is the linker in an error state?
67   bool hasError() { return HasError; }
68
69   // Mark the error condition as handled and continue.
70   void clearError() { HasError = false; }
71
72   // Get the error message.
73   StringRef getErrorString() { return ErrorStr; }
74 };
75
76
77
78 bool RuntimeDyldImpl::
79 loadSegment32(const MachOObject *Obj,
80               const MachOObject::LoadCommandInfo *SegmentLCI,
81               const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) {
82   InMemoryStruct<macho::SegmentLoadCommand> Segment32LC;
83   Obj->ReadSegmentLoadCommand(*SegmentLCI, Segment32LC);
84   if (!Segment32LC)
85     return Error("unable to load segment load command");
86
87   // Map the segment into memory.
88   std::string ErrorStr;
89   Data = sys::Memory::AllocateRWX(Segment32LC->VMSize, 0, &ErrorStr);
90   if (!Data.base())
91     return Error("unable to allocate memory block: '" + ErrorStr + "'");
92   memcpy(Data.base(), Obj->getData(Segment32LC->FileOffset,
93                                    Segment32LC->FileSize).data(),
94          Segment32LC->FileSize);
95   memset((char*)Data.base() + Segment32LC->FileSize, 0,
96          Segment32LC->VMSize - Segment32LC->FileSize);
97
98   // Bind the section indices to address.
99   void **SectionBases = new void*[Segment32LC->NumSections];
100   for (unsigned i = 0; i != Segment32LC->NumSections; ++i) {
101     InMemoryStruct<macho::Section> Sect;
102     Obj->ReadSection(*SegmentLCI, i, Sect);
103     if (!Sect)
104       return Error("unable to load section: '" + Twine(i) + "'");
105
106     // FIXME: We don't support relocations yet.
107     if (Sect->NumRelocationTableEntries != 0)
108       return Error("not yet implemented: relocations!");
109
110     // FIXME: Improve check.
111     if (Sect->Flags != 0x80000400)
112       return Error("unsupported section type!");
113
114     SectionBases[i] = (char*) Data.base() + Sect->Address;
115   }
116
117   // Bind all the symbols to address.
118   for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
119     InMemoryStruct<macho::SymbolTableEntry> STE;
120     Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE);
121     if (!STE)
122       return Error("unable to read symbol: '" + Twine(i) + "'");
123     if (STE->SectionIndex == 0)
124       return Error("unexpected undefined symbol!");
125
126     unsigned Index = STE->SectionIndex - 1;
127     if (Index >= Segment32LC->NumSections)
128       return Error("invalid section index for symbol: '" + Twine() + "'");
129
130     // Get the symbol name.
131     StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
132
133     // Get the section base address.
134     void *SectionBase = SectionBases[Index];
135
136     // Get the symbol address.
137     void *Address = (char*) SectionBase + STE->Value;
138
139     // FIXME: Check the symbol type and flags.
140     if (STE->Type != 0xF)
141       return Error("unexpected symbol type!");
142     if (STE->Flags != 0x0)
143       return Error("unexpected symbol type!");
144
145     SymbolTable[Name] = Address;
146   }
147
148   // We've loaded the section; now mark the functions in it as executable.
149   // FIXME: We really should use the JITMemoryManager for this.
150   sys::Memory::setRangeExecutable(Data.base(), Data.size());
151
152   delete SectionBases;
153   return false;
154 }
155
156
157 bool RuntimeDyldImpl::
158 loadSegment64(const MachOObject *Obj,
159               const MachOObject::LoadCommandInfo *SegmentLCI,
160               const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) {
161   InMemoryStruct<macho::Segment64LoadCommand> Segment64LC;
162   Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC);
163   if (!Segment64LC)
164     return Error("unable to load segment load command");
165
166   // Map the segment into memory.
167   std::string ErrorStr;
168   Data = sys::Memory::AllocateRWX(Segment64LC->VMSize, 0, &ErrorStr);
169   if (!Data.base())
170     return Error("unable to allocate memory block: '" + ErrorStr + "'");
171   memcpy(Data.base(), Obj->getData(Segment64LC->FileOffset,
172                                    Segment64LC->FileSize).data(),
173          Segment64LC->FileSize);
174   memset((char*)Data.base() + Segment64LC->FileSize, 0,
175          Segment64LC->VMSize - Segment64LC->FileSize);
176
177   // Bind the section indices to address.
178   void **SectionBases = new void*[Segment64LC->NumSections];
179   for (unsigned i = 0; i != Segment64LC->NumSections; ++i) {
180     InMemoryStruct<macho::Section64> Sect;
181     Obj->ReadSection64(*SegmentLCI, i, Sect);
182     if (!Sect)
183       return Error("unable to load section: '" + Twine(i) + "'");
184
185     // FIXME: We don't support relocations yet.
186     if (Sect->NumRelocationTableEntries != 0)
187       return Error("not yet implemented: relocations!");
188
189     // FIXME: Improve check.
190     if (Sect->Flags != 0x80000400)
191       return Error("unsupported section type!");
192
193     SectionBases[i] = (char*) Data.base() + Sect->Address;
194   }
195
196   // Bind all the symbols to address.
197   for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
198     InMemoryStruct<macho::Symbol64TableEntry> STE;
199     Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE);
200     if (!STE)
201       return Error("unable to read symbol: '" + Twine(i) + "'");
202     if (STE->SectionIndex == 0)
203       return Error("unexpected undefined symbol!");
204
205     unsigned Index = STE->SectionIndex - 1;
206     if (Index >= Segment64LC->NumSections)
207       return Error("invalid section index for symbol: '" + Twine() + "'");
208
209     // Get the symbol name.
210     StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
211
212     // Get the section base address.
213     void *SectionBase = SectionBases[Index];
214
215     // Get the symbol address.
216     void *Address = (char*) SectionBase + STE->Value;
217
218     // FIXME: Check the symbol type and flags.
219     if (STE->Type != 0xF)
220       return Error("unexpected symbol type!");
221     if (STE->Flags != 0x0)
222       return Error("unexpected symbol type!");
223
224     SymbolTable[Name] = Address;
225   }
226
227   // We've loaded the section; now mark the functions in it as executable.
228   // FIXME: We really should use the JITMemoryManager for this.
229   sys::Memory::setRangeExecutable(Data.base(), Data.size());
230
231   delete SectionBases;
232   return false;
233 }
234
235 bool RuntimeDyldImpl::loadObject(MemoryBuffer *InputBuffer) {
236   // If the linker is in an error state, don't do anything.
237   if (hasError())
238     return true;
239   // Load the Mach-O wrapper object.
240   std::string ErrorStr;
241   OwningPtr<MachOObject> Obj(
242     MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr));
243   if (!Obj)
244     return Error("unable to load object: '" + ErrorStr + "'");
245
246   // Validate that the load commands match what we expect.
247   const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0,
248     *DysymtabLCI = 0;
249   for (unsigned i = 0; i != Obj->getHeader().NumLoadCommands; ++i) {
250     const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i);
251     switch (LCI.Command.Type) {
252     case macho::LCT_Segment:
253     case macho::LCT_Segment64:
254       if (SegmentLCI)
255         return Error("unexpected input object (multiple segments)");
256       SegmentLCI = &LCI;
257       break;
258     case macho::LCT_Symtab:
259       if (SymtabLCI)
260         return Error("unexpected input object (multiple symbol tables)");
261       SymtabLCI = &LCI;
262       break;
263     case macho::LCT_Dysymtab:
264       if (DysymtabLCI)
265         return Error("unexpected input object (multiple symbol tables)");
266       DysymtabLCI = &LCI;
267       break;
268     default:
269       return Error("unexpected input object (unexpected load command");
270     }
271   }
272
273   if (!SymtabLCI)
274     return Error("no symbol table found in object");
275   if (!SegmentLCI)
276     return Error("no symbol table found in object");
277
278   // Read and register the symbol table data.
279   InMemoryStruct<macho::SymtabLoadCommand> SymtabLC;
280   Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
281   if (!SymtabLC)
282     return Error("unable to load symbol table load command");
283   Obj->RegisterStringTable(*SymtabLC);
284
285   // Read the dynamic link-edit information, if present (not present in static
286   // objects).
287   if (DysymtabLCI) {
288     InMemoryStruct<macho::DysymtabLoadCommand> DysymtabLC;
289     Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC);
290     if (!DysymtabLC)
291       return Error("unable to load dynamic link-exit load command");
292
293     // FIXME: We don't support anything interesting yet.
294     if (DysymtabLC->LocalSymbolsIndex != 0)
295       return Error("NOT YET IMPLEMENTED: local symbol entries");
296     if (DysymtabLC->ExternalSymbolsIndex != 0)
297       return Error("NOT YET IMPLEMENTED: non-external symbol entries");
298     if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries)
299       return Error("NOT YET IMPLEMENTED: undefined symbol entries");
300   }
301
302   // Load the segment load command.
303   if (SegmentLCI->Command.Type == macho::LCT_Segment) {
304     if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC))
305       return true;
306   } else {
307     if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC))
308       return true;
309   }
310
311   return false;
312 }
313
314
315 //===----------------------------------------------------------------------===//
316 // RuntimeDyld class implementation
317 RuntimeDyld::RuntimeDyld() {
318   Dyld = new RuntimeDyldImpl;
319 }
320
321 RuntimeDyld::~RuntimeDyld() {
322   delete Dyld;
323 }
324
325 bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
326   return Dyld->loadObject(InputBuffer);
327 }
328
329 void *RuntimeDyld::getSymbolAddress(StringRef Name) {
330   return Dyld->getSymbolAddress(Name);
331 }
332
333 sys::MemoryBlock RuntimeDyld::getMemoryBlock() {
334   return Dyld->getMemoryBlock();
335 }
336
337 StringRef RuntimeDyld::getErrorString() {
338   return Dyld->getErrorString();
339 }
340
341 } // end namespace llvm