Initialize HasError.
[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   delete SectionBases;
149   return false;
150 }
151
152
153 bool RuntimeDyldImpl::
154 loadSegment64(const MachOObject *Obj,
155               const MachOObject::LoadCommandInfo *SegmentLCI,
156               const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) {
157   InMemoryStruct<macho::Segment64LoadCommand> Segment64LC;
158   Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC);
159   if (!Segment64LC)
160     return Error("unable to load segment load command");
161
162   // Map the segment into memory.
163   std::string ErrorStr;
164   Data = sys::Memory::AllocateRWX(Segment64LC->VMSize, 0, &ErrorStr);
165   if (!Data.base())
166     return Error("unable to allocate memory block: '" + ErrorStr + "'");
167   memcpy(Data.base(), Obj->getData(Segment64LC->FileOffset,
168                                    Segment64LC->FileSize).data(),
169          Segment64LC->FileSize);
170   memset((char*)Data.base() + Segment64LC->FileSize, 0,
171          Segment64LC->VMSize - Segment64LC->FileSize);
172
173   // Bind the section indices to address.
174   void **SectionBases = new void*[Segment64LC->NumSections];
175   for (unsigned i = 0; i != Segment64LC->NumSections; ++i) {
176     InMemoryStruct<macho::Section64> Sect;
177     Obj->ReadSection64(*SegmentLCI, i, Sect);
178     if (!Sect)
179       return Error("unable to load section: '" + Twine(i) + "'");
180
181     // FIXME: We don't support relocations yet.
182     if (Sect->NumRelocationTableEntries != 0)
183       return Error("not yet implemented: relocations!");
184
185     // FIXME: Improve check.
186     if (Sect->Flags != 0x80000400)
187       return Error("unsupported section type!");
188
189     SectionBases[i] = (char*) Data.base() + Sect->Address;
190   }
191
192   // Bind all the symbols to address.
193   for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
194     InMemoryStruct<macho::Symbol64TableEntry> STE;
195     Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE);
196     if (!STE)
197       return Error("unable to read symbol: '" + Twine(i) + "'");
198     if (STE->SectionIndex == 0)
199       return Error("unexpected undefined symbol!");
200
201     unsigned Index = STE->SectionIndex - 1;
202     if (Index >= Segment64LC->NumSections)
203       return Error("invalid section index for symbol: '" + Twine() + "'");
204
205     // Get the symbol name.
206     StringRef Name = Obj->getStringAtIndex(STE->StringIndex);
207
208     // Get the section base address.
209     void *SectionBase = SectionBases[Index];
210
211     // Get the symbol address.
212     void *Address = (char*) SectionBase + STE->Value;
213
214     // FIXME: Check the symbol type and flags.
215     if (STE->Type != 0xF)
216       return Error("unexpected symbol type!");
217     if (STE->Flags != 0x0)
218       return Error("unexpected symbol type!");
219
220     SymbolTable[Name] = Address;
221   }
222
223   delete SectionBases;
224   return false;
225 }
226
227
228
229 bool RuntimeDyldImpl::loadObject(MemoryBuffer *InputBuffer) {
230   // If the linker is in an error state, don't do anything.
231   if (hasError())
232     return true;
233   // Load the Mach-O wrapper object.
234   std::string ErrorStr;
235   OwningPtr<MachOObject> Obj(
236     MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr));
237   if (!Obj)
238     return Error("unable to load object: '" + ErrorStr + "'");
239
240   // Validate that the load commands match what we expect.
241   const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0,
242     *DysymtabLCI = 0;
243   for (unsigned i = 0; i != Obj->getHeader().NumLoadCommands; ++i) {
244     const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i);
245     switch (LCI.Command.Type) {
246     case macho::LCT_Segment:
247     case macho::LCT_Segment64:
248       if (SegmentLCI)
249         return Error("unexpected input object (multiple segments)");
250       SegmentLCI = &LCI;
251       break;
252     case macho::LCT_Symtab:
253       if (SymtabLCI)
254         return Error("unexpected input object (multiple symbol tables)");
255       SymtabLCI = &LCI;
256       break;
257     case macho::LCT_Dysymtab:
258       if (DysymtabLCI)
259         return Error("unexpected input object (multiple symbol tables)");
260       DysymtabLCI = &LCI;
261       break;
262     default:
263       return Error("unexpected input object (unexpected load command");
264     }
265   }
266
267   if (!SymtabLCI)
268     return Error("no symbol table found in object");
269   if (!SegmentLCI)
270     return Error("no symbol table found in object");
271
272   // Read and register the symbol table data.
273   InMemoryStruct<macho::SymtabLoadCommand> SymtabLC;
274   Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
275   if (!SymtabLC)
276     return Error("unable to load symbol table load command");
277   Obj->RegisterStringTable(*SymtabLC);
278
279   // Read the dynamic link-edit information, if present (not present in static
280   // objects).
281   if (DysymtabLCI) {
282     InMemoryStruct<macho::DysymtabLoadCommand> DysymtabLC;
283     Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC);
284     if (!DysymtabLC)
285       return Error("unable to load dynamic link-exit load command");
286
287     // FIXME: We don't support anything interesting yet.
288     if (DysymtabLC->LocalSymbolsIndex != 0)
289       return Error("NOT YET IMPLEMENTED: local symbol entries");
290     if (DysymtabLC->ExternalSymbolsIndex != 0)
291       return Error("NOT YET IMPLEMENTED: non-external symbol entries");
292     if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries)
293       return Error("NOT YET IMPLEMENTED: undefined symbol entries");
294   }
295
296   // Load the segment load command.
297   if (SegmentLCI->Command.Type == macho::LCT_Segment) {
298     if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC))
299       return true;
300   } else {
301     if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC))
302       return true;
303   }
304
305   return false;
306 }
307
308
309 //===----------------------------------------------------------------------===//
310 // RuntimeDyld class implementation
311 RuntimeDyld::RuntimeDyld() {
312   Dyld = new RuntimeDyldImpl;
313 }
314
315 RuntimeDyld::~RuntimeDyld() {
316   delete Dyld;
317 }
318
319 bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {
320   return Dyld->loadObject(InputBuffer);
321 }
322
323 void *RuntimeDyld::getSymbolAddress(StringRef Name) {
324   return Dyld->getSymbolAddress(Name);
325 }
326
327 sys::MemoryBlock RuntimeDyld::getMemoryBlock() {
328   return Dyld->getMemoryBlock();
329 }
330
331 } // end namespace llvm