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