File: | lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp |
Location: | line 413, column 3 |
Description: | Undefined or garbage value returned to caller |
1 | //===-- RuntimeDyld.cpp - 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/ExecutionEngine/RuntimeDyld.h" | |||
15 | #include "JITRegistrar.h" | |||
16 | #include "ObjectImageCommon.h" | |||
17 | #include "RuntimeDyldCheckerImpl.h" | |||
18 | #include "RuntimeDyldELF.h" | |||
19 | #include "RuntimeDyldImpl.h" | |||
20 | #include "RuntimeDyldMachO.h" | |||
21 | #include "llvm/Object/ELF.h" | |||
22 | #include "llvm/Support/MathExtras.h" | |||
23 | #include "llvm/Support/MutexGuard.h" | |||
24 | ||||
25 | using namespace llvm; | |||
26 | using namespace llvm::object; | |||
27 | ||||
28 | #define DEBUG_TYPE"dyld" "dyld" | |||
29 | ||||
30 | // Empty out-of-line virtual destructor as the key function. | |||
31 | RuntimeDyldImpl::~RuntimeDyldImpl() {} | |||
32 | ||||
33 | // Pin the JITRegistrar's and ObjectImage*'s vtables to this file. | |||
34 | void JITRegistrar::anchor() {} | |||
35 | void ObjectImage::anchor() {} | |||
36 | void ObjectImageCommon::anchor() {} | |||
37 | ||||
38 | namespace llvm { | |||
39 | ||||
40 | void RuntimeDyldImpl::registerEHFrames() {} | |||
41 | ||||
42 | void RuntimeDyldImpl::deregisterEHFrames() {} | |||
43 | ||||
44 | #ifndef NDEBUG | |||
45 | static void dumpSectionMemory(const SectionEntry &S, StringRef State) { | |||
46 | dbgs() << "----- Contents of section " << S.Name << " " << State << " -----"; | |||
47 | ||||
48 | const unsigned ColsPerRow = 16; | |||
49 | ||||
50 | uint8_t *DataAddr = S.Address; | |||
51 | uint64_t LoadAddr = S.LoadAddress; | |||
52 | ||||
53 | unsigned StartPadding = LoadAddr & 7; | |||
54 | unsigned BytesRemaining = S.Size; | |||
55 | ||||
56 | if (StartPadding) { | |||
57 | dbgs() << "\n" << format("0x%08x", LoadAddr & ~(ColsPerRow - 1)) << ":"; | |||
58 | while (StartPadding--) | |||
59 | dbgs() << " "; | |||
60 | } | |||
61 | ||||
62 | while (BytesRemaining > 0) { | |||
63 | if ((LoadAddr & (ColsPerRow - 1)) == 0) | |||
64 | dbgs() << "\n" << format("0x%016" PRIx64"l" "x", LoadAddr) << ":"; | |||
65 | ||||
66 | dbgs() << " " << format("%02x", *DataAddr); | |||
67 | ||||
68 | ++DataAddr; | |||
69 | ++LoadAddr; | |||
70 | --BytesRemaining; | |||
71 | } | |||
72 | ||||
73 | dbgs() << "\n"; | |||
74 | } | |||
75 | #endif | |||
76 | ||||
77 | // Resolve the relocations for all symbols we currently know about. | |||
78 | void RuntimeDyldImpl::resolveRelocations() { | |||
79 | MutexGuard locked(lock); | |||
80 | ||||
81 | // First, resolve relocations associated with external symbols. | |||
82 | resolveExternalSymbols(); | |||
83 | ||||
84 | // Just iterate over the sections we have and resolve all the relocations | |||
85 | // in them. Gross overkill, but it gets the job done. | |||
86 | for (int i = 0, e = Sections.size(); i != e; ++i) { | |||
87 | // The Section here (Sections[i]) refers to the section in which the | |||
88 | // symbol for the relocation is located. The SectionID in the relocation | |||
89 | // entry provides the section to which the relocation will be applied. | |||
90 | uint64_t Addr = Sections[i].LoadAddress; | |||
91 | DEBUG(dbgs() << "Resolving relocations Section #" << i << "\t"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Resolving relocations Section #" << i << "\t" << format("0x%x", Addr) << "\n"; } } while (0) | |||
92 | << format("0x%x", Addr) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Resolving relocations Section #" << i << "\t" << format("0x%x", Addr) << "\n"; } } while (0); | |||
93 | DEBUG(dumpSectionMemory(Sections[i], "before relocations"))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dumpSectionMemory(Sections[i], "before relocations" ); } } while (0); | |||
94 | resolveRelocationList(Relocations[i], Addr); | |||
95 | DEBUG(dumpSectionMemory(Sections[i], "after relocations"))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dumpSectionMemory(Sections[i], "after relocations" ); } } while (0); | |||
96 | Relocations.erase(i); | |||
97 | } | |||
98 | } | |||
99 | ||||
100 | void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress, | |||
101 | uint64_t TargetAddress) { | |||
102 | MutexGuard locked(lock); | |||
103 | for (unsigned i = 0, e = Sections.size(); i != e; ++i) { | |||
104 | if (Sections[i].Address == LocalAddress) { | |||
105 | reassignSectionAddress(i, TargetAddress); | |||
106 | return; | |||
107 | } | |||
108 | } | |||
109 | llvm_unreachable("Attempting to remap address of unknown section!")::llvm::llvm_unreachable_internal("Attempting to remap address of unknown section!" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn216889/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp" , 109); | |||
110 | } | |||
111 | ||||
112 | static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) { | |||
113 | uint64_t Address; | |||
114 | if (std::error_code EC = Sym.getAddress(Address)) | |||
115 | return EC; | |||
116 | ||||
117 | if (Address == UnknownAddressOrSize) { | |||
118 | Result = UnknownAddressOrSize; | |||
119 | return object_error::success; | |||
120 | } | |||
121 | ||||
122 | const ObjectFile *Obj = Sym.getObject(); | |||
123 | section_iterator SecI(Obj->section_begin()); | |||
124 | if (std::error_code EC = Sym.getSection(SecI)) | |||
125 | return EC; | |||
126 | ||||
127 | if (SecI == Obj->section_end()) { | |||
128 | Result = UnknownAddressOrSize; | |||
129 | return object_error::success; | |||
130 | } | |||
131 | ||||
132 | uint64_t SectionAddress; | |||
133 | if (std::error_code EC = SecI->getAddress(SectionAddress)) | |||
134 | return EC; | |||
135 | ||||
136 | Result = Address - SectionAddress; | |||
137 | return object_error::success; | |||
138 | } | |||
139 | ||||
140 | ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) { | |||
141 | MutexGuard locked(lock); | |||
142 | ||||
143 | std::unique_ptr<ObjectImage> Obj(InputObject); | |||
144 | if (!Obj) | |||
145 | return nullptr; | |||
146 | ||||
147 | // Save information about our target | |||
148 | Arch = (Triple::ArchType)Obj->getArch(); | |||
149 | IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian(); | |||
150 | ||||
151 | // Compute the memory size required to load all sections to be loaded | |||
152 | // and pass this information to the memory manager | |||
153 | if (MemMgr->needsToReserveAllocationSpace()) { | |||
154 | uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0; | |||
155 | computeTotalAllocSize(*Obj, CodeSize, DataSizeRO, DataSizeRW); | |||
156 | MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW); | |||
157 | } | |||
158 | ||||
159 | // Symbols found in this object | |||
160 | StringMap<SymbolLoc> LocalSymbols; | |||
161 | // Used sections from the object file | |||
162 | ObjSectionToIDMap LocalSections; | |||
163 | ||||
164 | // Common symbols requiring allocation, with their sizes and alignments | |||
165 | CommonSymbolMap CommonSymbols; | |||
166 | // Maximum required total memory to allocate all common symbols | |||
167 | uint64_t CommonSize = 0; | |||
168 | ||||
169 | // Parse symbols | |||
170 | DEBUG(dbgs() << "Parse symbols:\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Parse symbols:\n"; } } while (0); | |||
171 | for (symbol_iterator I = Obj->begin_symbols(), E = Obj->end_symbols(); I != E; | |||
172 | ++I) { | |||
173 | object::SymbolRef::Type SymType; | |||
174 | StringRef Name; | |||
175 | Check(I->getType(SymType)); | |||
176 | Check(I->getName(Name)); | |||
177 | ||||
178 | uint32_t Flags = I->getFlags(); | |||
179 | ||||
180 | bool IsCommon = Flags & SymbolRef::SF_Common; | |||
181 | if (IsCommon) { | |||
182 | // Add the common symbols to a list. We'll allocate them all below. | |||
183 | if (!GlobalSymbolTable.count(Name)) { | |||
184 | uint32_t Align; | |||
185 | Check(I->getAlignment(Align)); | |||
186 | uint64_t Size = 0; | |||
187 | Check(I->getSize(Size)); | |||
188 | CommonSize += Size + Align; | |||
189 | CommonSymbols[*I] = CommonSymbolInfo(Size, Align); | |||
190 | } | |||
191 | } else { | |||
192 | if (SymType == object::SymbolRef::ST_Function || | |||
193 | SymType == object::SymbolRef::ST_Data || | |||
194 | SymType == object::SymbolRef::ST_Unknown) { | |||
195 | uint64_t SectOffset; | |||
196 | StringRef SectionData; | |||
197 | bool IsCode; | |||
198 | section_iterator SI = Obj->end_sections(); | |||
199 | Check(getOffset(*I, SectOffset)); | |||
200 | Check(I->getSection(SI)); | |||
201 | if (SI == Obj->end_sections()) | |||
202 | continue; | |||
203 | Check(SI->getContents(SectionData)); | |||
204 | Check(SI->isText(IsCode)); | |||
205 | unsigned SectionID = | |||
206 | findOrEmitSection(*Obj, *SI, IsCode, LocalSections); | |||
207 | LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset); | |||
208 | DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "\tOffset: " << format("%p" , (uintptr_t)SectOffset) << " flags: " << Flags << " SID: " << SectionID; } } while (0) | |||
209 | << " flags: " << Flags << " SID: " << SectionID)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "\tOffset: " << format("%p" , (uintptr_t)SectOffset) << " flags: " << Flags << " SID: " << SectionID; } } while (0); | |||
210 | GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset); | |||
211 | } | |||
212 | } | |||
213 | DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "\tType: " << SymType << " Name: " << Name << "\n"; } } while (0); | |||
214 | } | |||
215 | ||||
216 | // Allocate common symbols | |||
217 | if (CommonSize != 0) | |||
218 | emitCommonSymbols(*Obj, CommonSymbols, CommonSize, GlobalSymbolTable); | |||
219 | ||||
220 | // Parse and process relocations | |||
221 | DEBUG(dbgs() << "Parse relocations:\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Parse relocations:\n"; } } while (0); | |||
222 | for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections(); | |||
223 | SI != SE; ++SI) { | |||
224 | unsigned SectionID = 0; | |||
225 | StubMap Stubs; | |||
226 | section_iterator RelocatedSection = SI->getRelocatedSection(); | |||
227 | ||||
228 | relocation_iterator I = SI->relocation_begin(); | |||
229 | relocation_iterator E = SI->relocation_end(); | |||
230 | ||||
231 | if (I == E && !ProcessAllSections) | |||
232 | continue; | |||
233 | ||||
234 | bool IsCode = false; | |||
235 | Check(RelocatedSection->isText(IsCode)); | |||
236 | SectionID = | |||
237 | findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections); | |||
238 | DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "\tSectionID: " << SectionID << "\n"; } } while (0); | |||
239 | ||||
240 | for (; I != E;) | |||
241 | I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols, | |||
242 | Stubs); | |||
243 | ||||
244 | // If there is an attached checker, notify it about the stubs for this | |||
245 | // section so that they can be verified. | |||
246 | if (Checker) | |||
247 | Checker->registerStubMap(Obj->getImageName(), SectionID, Stubs); | |||
248 | } | |||
249 | ||||
250 | // Give the subclasses a chance to tie-up any loose ends. | |||
251 | finalizeLoad(*Obj, LocalSections); | |||
252 | ||||
253 | return Obj.release(); | |||
254 | } | |||
255 | ||||
256 | // A helper method for computeTotalAllocSize. | |||
257 | // Computes the memory size required to allocate sections with the given sizes, | |||
258 | // assuming that all sections are allocated with the given alignment | |||
259 | static uint64_t | |||
260 | computeAllocationSizeForSections(std::vector<uint64_t> &SectionSizes, | |||
261 | uint64_t Alignment) { | |||
262 | uint64_t TotalSize = 0; | |||
263 | for (size_t Idx = 0, Cnt = SectionSizes.size(); Idx < Cnt; Idx++) { | |||
264 | uint64_t AlignedSize = | |||
265 | (SectionSizes[Idx] + Alignment - 1) / Alignment * Alignment; | |||
266 | TotalSize += AlignedSize; | |||
267 | } | |||
268 | return TotalSize; | |||
269 | } | |||
270 | ||||
271 | // Compute an upper bound of the memory size that is required to load all | |||
272 | // sections | |||
273 | void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj, | |||
274 | uint64_t &CodeSize, | |||
275 | uint64_t &DataSizeRO, | |||
276 | uint64_t &DataSizeRW) { | |||
277 | // Compute the size of all sections required for execution | |||
278 | std::vector<uint64_t> CodeSectionSizes; | |||
279 | std::vector<uint64_t> ROSectionSizes; | |||
280 | std::vector<uint64_t> RWSectionSizes; | |||
281 | uint64_t MaxAlignment = sizeof(void *); | |||
282 | ||||
283 | // Collect sizes of all sections to be loaded; | |||
284 | // also determine the max alignment of all sections | |||
285 | for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections(); | |||
286 | SI != SE; ++SI) { | |||
287 | const SectionRef &Section = *SI; | |||
288 | ||||
289 | bool IsRequired; | |||
290 | Check(Section.isRequiredForExecution(IsRequired)); | |||
291 | ||||
292 | // Consider only the sections that are required to be loaded for execution | |||
293 | if (IsRequired) { | |||
294 | uint64_t DataSize = 0; | |||
295 | uint64_t Alignment64 = 0; | |||
296 | bool IsCode = false; | |||
297 | bool IsReadOnly = false; | |||
298 | StringRef Name; | |||
299 | Check(Section.getSize(DataSize)); | |||
300 | Check(Section.getAlignment(Alignment64)); | |||
301 | Check(Section.isText(IsCode)); | |||
302 | Check(Section.isReadOnlyData(IsReadOnly)); | |||
303 | Check(Section.getName(Name)); | |||
304 | unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; | |||
305 | ||||
306 | uint64_t StubBufSize = computeSectionStubBufSize(Obj, Section); | |||
307 | uint64_t SectionSize = DataSize + StubBufSize; | |||
308 | ||||
309 | // The .eh_frame section (at least on Linux) needs an extra four bytes | |||
310 | // padded | |||
311 | // with zeroes added at the end. For MachO objects, this section has a | |||
312 | // slightly different name, so this won't have any effect for MachO | |||
313 | // objects. | |||
314 | if (Name == ".eh_frame") | |||
315 | SectionSize += 4; | |||
316 | ||||
317 | if (SectionSize > 0) { | |||
318 | // save the total size of the section | |||
319 | if (IsCode) { | |||
320 | CodeSectionSizes.push_back(SectionSize); | |||
321 | } else if (IsReadOnly) { | |||
322 | ROSectionSizes.push_back(SectionSize); | |||
323 | } else { | |||
324 | RWSectionSizes.push_back(SectionSize); | |||
325 | } | |||
326 | // update the max alignment | |||
327 | if (Alignment > MaxAlignment) { | |||
328 | MaxAlignment = Alignment; | |||
329 | } | |||
330 | } | |||
331 | } | |||
332 | } | |||
333 | ||||
334 | // Compute the size of all common symbols | |||
335 | uint64_t CommonSize = 0; | |||
336 | for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E; | |||
337 | ++I) { | |||
338 | uint32_t Flags = I->getFlags(); | |||
339 | if (Flags & SymbolRef::SF_Common) { | |||
340 | // Add the common symbols to a list. We'll allocate them all below. | |||
341 | uint64_t Size = 0; | |||
342 | Check(I->getSize(Size)); | |||
343 | CommonSize += Size; | |||
344 | } | |||
345 | } | |||
346 | if (CommonSize != 0) { | |||
347 | RWSectionSizes.push_back(CommonSize); | |||
348 | } | |||
349 | ||||
350 | // Compute the required allocation space for each different type of sections | |||
351 | // (code, read-only data, read-write data) assuming that all sections are | |||
352 | // allocated with the max alignment. Note that we cannot compute with the | |||
353 | // individual alignments of the sections, because then the required size | |||
354 | // depends on the order, in which the sections are allocated. | |||
355 | CodeSize = computeAllocationSizeForSections(CodeSectionSizes, MaxAlignment); | |||
356 | DataSizeRO = computeAllocationSizeForSections(ROSectionSizes, MaxAlignment); | |||
357 | DataSizeRW = computeAllocationSizeForSections(RWSectionSizes, MaxAlignment); | |||
358 | } | |||
359 | ||||
360 | // compute stub buffer size for the given section | |||
361 | unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj, | |||
362 | const SectionRef &Section) { | |||
363 | unsigned StubSize = getMaxStubSize(); | |||
364 | if (StubSize == 0) { | |||
365 | return 0; | |||
366 | } | |||
367 | // FIXME: this is an inefficient way to handle this. We should computed the | |||
368 | // necessary section allocation size in loadObject by walking all the sections | |||
369 | // once. | |||
370 | unsigned StubBufSize = 0; | |||
371 | for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections(); | |||
372 | SI != SE; ++SI) { | |||
373 | section_iterator RelSecI = SI->getRelocatedSection(); | |||
374 | if (!(RelSecI == Section)) | |||
375 | continue; | |||
376 | ||||
377 | for (const RelocationRef &Reloc : SI->relocations()) { | |||
378 | (void)Reloc; | |||
379 | StubBufSize += StubSize; | |||
380 | } | |||
381 | } | |||
382 | ||||
383 | // Get section data size and alignment | |||
384 | uint64_t Alignment64; | |||
385 | uint64_t DataSize; | |||
386 | Check(Section.getSize(DataSize)); | |||
387 | Check(Section.getAlignment(Alignment64)); | |||
388 | ||||
389 | // Add stubbuf size alignment | |||
390 | unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; | |||
391 | unsigned StubAlignment = getStubAlignment(); | |||
392 | unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment); | |||
393 | if (StubAlignment > EndAlignment) | |||
394 | StubBufSize += StubAlignment - EndAlignment; | |||
395 | return StubBufSize; | |||
396 | } | |||
397 | ||||
398 | uint64_t RuntimeDyldImpl::readBytesUnaligned(uint8_t *Src, | |||
399 | unsigned Size) const { | |||
400 | uint64_t Result = 0; | |||
401 | uint8_t *Dst = reinterpret_cast<uint8_t*>(&Result); | |||
402 | ||||
403 | if (IsTargetLittleEndian == sys::IsLittleEndianHost) { | |||
| ||||
404 | if (!sys::IsLittleEndianHost) | |||
405 | Dst += sizeof(Result) - Size; | |||
406 | memcpy(Dst, Src, Size); | |||
407 | } else { | |||
408 | Dst += Size - 1; | |||
409 | for (unsigned i = 0; i < Size; ++i) | |||
410 | *Dst-- = *Src++; | |||
411 | } | |||
412 | ||||
413 | return Result; | |||
| ||||
414 | } | |||
415 | ||||
416 | void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst, | |||
417 | unsigned Size) const { | |||
418 | uint8_t *Src = reinterpret_cast<uint8_t*>(&Value); | |||
419 | if (IsTargetLittleEndian == sys::IsLittleEndianHost) { | |||
420 | if (!sys::IsLittleEndianHost) | |||
421 | Src += sizeof(Value) - Size; | |||
422 | memcpy(Dst, Src, Size); | |||
423 | } else { | |||
424 | Src += Size - 1; | |||
425 | for (unsigned i = 0; i < Size; ++i) | |||
426 | *Dst++ = *Src--; | |||
427 | } | |||
428 | } | |||
429 | ||||
430 | void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, | |||
431 | const CommonSymbolMap &CommonSymbols, | |||
432 | uint64_t TotalSize, | |||
433 | SymbolTableMap &SymbolTable) { | |||
434 | // Allocate memory for the section | |||
435 | unsigned SectionID = Sections.size(); | |||
436 | uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void *), | |||
437 | SectionID, StringRef(), false); | |||
438 | if (!Addr) | |||
439 | report_fatal_error("Unable to allocate memory for common symbols!"); | |||
440 | uint64_t Offset = 0; | |||
441 | Sections.push_back(SectionEntry("<common symbols>", Addr, TotalSize, 0)); | |||
442 | memset(Addr, 0, TotalSize); | |||
443 | ||||
444 | DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: " << format("%p", Addr) << " DataSize: " << TotalSize << "\n"; } } while (0) | |||
445 | << format("%p", Addr) << " DataSize: " << TotalSize << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: " << format("%p", Addr) << " DataSize: " << TotalSize << "\n"; } } while (0); | |||
446 | ||||
447 | // Assign the address of each symbol | |||
448 | for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(), | |||
449 | itEnd = CommonSymbols.end(); it != itEnd; ++it) { | |||
450 | uint64_t Size = it->second.first; | |||
451 | uint64_t Align = it->second.second; | |||
452 | StringRef Name; | |||
453 | it->first.getName(Name); | |||
454 | if (Align) { | |||
455 | // This symbol has an alignment requirement. | |||
456 | uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align); | |||
457 | Addr += AlignOffset; | |||
458 | Offset += AlignOffset; | |||
459 | DEBUG(dbgs() << "Allocating common symbol " << Name << " address "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Allocating common symbol " << Name << " address " << format("%p\n", Addr); } } while (0) | |||
460 | << format("%p\n", Addr))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Allocating common symbol " << Name << " address " << format("%p\n", Addr); } } while (0); | |||
461 | } | |||
462 | Obj.updateSymbolAddress(it->first, (uint64_t)Addr); | |||
463 | SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset); | |||
464 | Offset += Size; | |||
465 | Addr += Size; | |||
466 | } | |||
467 | } | |||
468 | ||||
469 | unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, | |||
470 | const SectionRef &Section, bool IsCode) { | |||
471 | ||||
472 | StringRef data; | |||
473 | uint64_t Alignment64; | |||
474 | Check(Section.getContents(data)); | |||
475 | Check(Section.getAlignment(Alignment64)); | |||
476 | ||||
477 | unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; | |||
478 | bool IsRequired; | |||
479 | bool IsVirtual; | |||
480 | bool IsZeroInit; | |||
481 | bool IsReadOnly; | |||
482 | uint64_t DataSize; | |||
483 | unsigned PaddingSize = 0; | |||
484 | unsigned StubBufSize = 0; | |||
485 | StringRef Name; | |||
486 | Check(Section.isRequiredForExecution(IsRequired)); | |||
487 | Check(Section.isVirtual(IsVirtual)); | |||
488 | Check(Section.isZeroInit(IsZeroInit)); | |||
489 | Check(Section.isReadOnlyData(IsReadOnly)); | |||
490 | Check(Section.getSize(DataSize)); | |||
491 | Check(Section.getName(Name)); | |||
492 | ||||
493 | StubBufSize = computeSectionStubBufSize(Obj, Section); | |||
494 | ||||
495 | // The .eh_frame section (at least on Linux) needs an extra four bytes padded | |||
496 | // with zeroes added at the end. For MachO objects, this section has a | |||
497 | // slightly different name, so this won't have any effect for MachO objects. | |||
498 | if (Name == ".eh_frame") | |||
499 | PaddingSize = 4; | |||
500 | ||||
501 | uintptr_t Allocate; | |||
502 | unsigned SectionID = Sections.size(); | |||
503 | uint8_t *Addr; | |||
504 | const char *pData = nullptr; | |||
505 | ||||
506 | // Some sections, such as debug info, don't need to be loaded for execution. | |||
507 | // Leave those where they are. | |||
508 | if (IsRequired) { | |||
509 | Allocate = DataSize + PaddingSize + StubBufSize; | |||
510 | Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID, | |||
511 | Name) | |||
512 | : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, | |||
513 | Name, IsReadOnly); | |||
514 | if (!Addr) | |||
515 | report_fatal_error("Unable to allocate section memory!"); | |||
516 | ||||
517 | // Virtual sections have no data in the object image, so leave pData = 0 | |||
518 | if (!IsVirtual) | |||
519 | pData = data.data(); | |||
520 | ||||
521 | // Zero-initialize or copy the data from the image | |||
522 | if (IsZeroInit || IsVirtual) | |||
523 | memset(Addr, 0, DataSize); | |||
524 | else | |||
525 | memcpy(Addr, pData, DataSize); | |||
526 | ||||
527 | // Fill in any extra bytes we allocated for padding | |||
528 | if (PaddingSize != 0) { | |||
529 | memset(Addr + DataSize, 0, PaddingSize); | |||
530 | // Update the DataSize variable so that the stub offset is set correctly. | |||
531 | DataSize += PaddingSize; | |||
532 | } | |||
533 | ||||
534 | DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Namedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0) | |||
535 | << " obj addr: " << format("%p", pData)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0) | |||
536 | << " new addr: " << format("%p", Addr)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0) | |||
537 | << " DataSize: " << DataSize << " StubBufSize: " << StubBufSizedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0) | |||
538 | << " Allocate: " << Allocate << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", pData) << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0); | |||
539 | Obj.updateSectionAddress(Section, (uint64_t)Addr); | |||
540 | } else { | |||
541 | // Even if we didn't load the section, we need to record an entry for it | |||
542 | // to handle later processing (and by 'handle' I mean don't do anything | |||
543 | // with these sections). | |||
544 | Allocate = 0; | |||
545 | Addr = nullptr; | |||
546 | DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Namedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", data.data()) << " new addr: 0" << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0) | |||
547 | << " obj addr: " << format("%p", data.data()) << " new addr: 0"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", data.data()) << " new addr: 0" << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0) | |||
548 | << " DataSize: " << DataSize << " StubBufSize: " << StubBufSizedo { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", data.data()) << " new addr: 0" << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0) | |||
549 | << " Allocate: " << Allocate << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name << " obj addr: " << format("%p", data.data()) << " new addr: 0" << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"; } } while (0); | |||
550 | } | |||
551 | ||||
552 | Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData)); | |||
553 | return SectionID; | |||
554 | } | |||
555 | ||||
556 | unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj, | |||
557 | const SectionRef &Section, | |||
558 | bool IsCode, | |||
559 | ObjSectionToIDMap &LocalSections) { | |||
560 | ||||
561 | unsigned SectionID = 0; | |||
562 | ObjSectionToIDMap::iterator i = LocalSections.find(Section); | |||
563 | if (i != LocalSections.end()) | |||
564 | SectionID = i->second; | |||
565 | else { | |||
566 | SectionID = emitSection(Obj, Section, IsCode); | |||
567 | LocalSections[Section] = SectionID; | |||
568 | } | |||
569 | return SectionID; | |||
570 | } | |||
571 | ||||
572 | void RuntimeDyldImpl::addRelocationForSection(const RelocationEntry &RE, | |||
573 | unsigned SectionID) { | |||
574 | Relocations[SectionID].push_back(RE); | |||
575 | } | |||
576 | ||||
577 | void RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE, | |||
578 | StringRef SymbolName) { | |||
579 | // Relocation by symbol. If the symbol is found in the global symbol table, | |||
580 | // create an appropriate section relocation. Otherwise, add it to | |||
581 | // ExternalSymbolRelocations. | |||
582 | SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(SymbolName); | |||
583 | if (Loc == GlobalSymbolTable.end()) { | |||
584 | ExternalSymbolRelocations[SymbolName].push_back(RE); | |||
585 | } else { | |||
586 | // Copy the RE since we want to modify its addend. | |||
587 | RelocationEntry RECopy = RE; | |||
588 | RECopy.Addend += Loc->second.second; | |||
589 | Relocations[Loc->second.first].push_back(RECopy); | |||
590 | } | |||
591 | } | |||
592 | ||||
593 | uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr, | |||
594 | unsigned AbiVariant) { | |||
595 | if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) { | |||
596 | // This stub has to be able to access the full address space, | |||
597 | // since symbol lookup won't necessarily find a handy, in-range, | |||
598 | // PLT stub for functions which could be anywhere. | |||
599 | uint32_t *StubAddr = (uint32_t *)Addr; | |||
600 | ||||
601 | // Stub can use ip0 (== x16) to calculate address | |||
602 | *StubAddr = 0xd2e00010; // movz ip0, #:abs_g3:<addr> | |||
603 | StubAddr++; | |||
604 | *StubAddr = 0xf2c00010; // movk ip0, #:abs_g2_nc:<addr> | |||
605 | StubAddr++; | |||
606 | *StubAddr = 0xf2a00010; // movk ip0, #:abs_g1_nc:<addr> | |||
607 | StubAddr++; | |||
608 | *StubAddr = 0xf2800010; // movk ip0, #:abs_g0_nc:<addr> | |||
609 | StubAddr++; | |||
610 | *StubAddr = 0xd61f0200; // br ip0 | |||
611 | ||||
612 | return Addr; | |||
613 | } else if (Arch == Triple::arm || Arch == Triple::armeb) { | |||
614 | // TODO: There is only ARM far stub now. We should add the Thumb stub, | |||
615 | // and stubs for branches Thumb - ARM and ARM - Thumb. | |||
616 | uint32_t *StubAddr = (uint32_t *)Addr; | |||
617 | *StubAddr = 0xe51ff004; // ldr pc,<label> | |||
618 | return (uint8_t *)++StubAddr; | |||
619 | } else if (Arch == Triple::mipsel || Arch == Triple::mips) { | |||
620 | uint32_t *StubAddr = (uint32_t *)Addr; | |||
621 | // 0: 3c190000 lui t9,%hi(addr). | |||
622 | // 4: 27390000 addiu t9,t9,%lo(addr). | |||
623 | // 8: 03200008 jr t9. | |||
624 | // c: 00000000 nop. | |||
625 | const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000; | |||
626 | const unsigned JrT9Instr = 0x03200008, NopInstr = 0x0; | |||
627 | ||||
628 | *StubAddr = LuiT9Instr; | |||
629 | StubAddr++; | |||
630 | *StubAddr = AdduiT9Instr; | |||
631 | StubAddr++; | |||
632 | *StubAddr = JrT9Instr; | |||
633 | StubAddr++; | |||
634 | *StubAddr = NopInstr; | |||
635 | return Addr; | |||
636 | } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) { | |||
637 | // Depending on which version of the ELF ABI is in use, we need to | |||
638 | // generate one of two variants of the stub. They both start with | |||
639 | // the same sequence to load the target address into r12. | |||
640 | writeInt32BE(Addr, 0x3D800000); // lis r12, highest(addr) | |||
641 | writeInt32BE(Addr+4, 0x618C0000); // ori r12, higher(addr) | |||
642 | writeInt32BE(Addr+8, 0x798C07C6); // sldi r12, r12, 32 | |||
643 | writeInt32BE(Addr+12, 0x658C0000); // oris r12, r12, h(addr) | |||
644 | writeInt32BE(Addr+16, 0x618C0000); // ori r12, r12, l(addr) | |||
645 | if (AbiVariant == 2) { | |||
646 | // PowerPC64 stub ELFv2 ABI: The address points to the function itself. | |||
647 | // The address is already in r12 as required by the ABI. Branch to it. | |||
648 | writeInt32BE(Addr+20, 0xF8410018); // std r2, 24(r1) | |||
649 | writeInt32BE(Addr+24, 0x7D8903A6); // mtctr r12 | |||
650 | writeInt32BE(Addr+28, 0x4E800420); // bctr | |||
651 | } else { | |||
652 | // PowerPC64 stub ELFv1 ABI: The address points to a function descriptor. | |||
653 | // Load the function address on r11 and sets it to control register. Also | |||
654 | // loads the function TOC in r2 and environment pointer to r11. | |||
655 | writeInt32BE(Addr+20, 0xF8410028); // std r2, 40(r1) | |||
656 | writeInt32BE(Addr+24, 0xE96C0000); // ld r11, 0(r12) | |||
657 | writeInt32BE(Addr+28, 0xE84C0008); // ld r2, 0(r12) | |||
658 | writeInt32BE(Addr+32, 0x7D6903A6); // mtctr r11 | |||
659 | writeInt32BE(Addr+36, 0xE96C0010); // ld r11, 16(r2) | |||
660 | writeInt32BE(Addr+40, 0x4E800420); // bctr | |||
661 | } | |||
662 | return Addr; | |||
663 | } else if (Arch == Triple::systemz) { | |||
664 | writeInt16BE(Addr, 0xC418); // lgrl %r1,.+8 | |||
665 | writeInt16BE(Addr+2, 0x0000); | |||
666 | writeInt16BE(Addr+4, 0x0004); | |||
667 | writeInt16BE(Addr+6, 0x07F1); // brc 15,%r1 | |||
668 | // 8-byte address stored at Addr + 8 | |||
669 | return Addr; | |||
670 | } else if (Arch == Triple::x86_64) { | |||
671 | *Addr = 0xFF; // jmp | |||
672 | *(Addr+1) = 0x25; // rip | |||
673 | // 32-bit PC-relative address of the GOT entry will be stored at Addr+2 | |||
674 | } else if (Arch == Triple::x86) { | |||
675 | *Addr = 0xE9; // 32-bit pc-relative jump. | |||
676 | } | |||
677 | return Addr; | |||
678 | } | |||
679 | ||||
680 | // Assign an address to a symbol name and resolve all the relocations | |||
681 | // associated with it. | |||
682 | void RuntimeDyldImpl::reassignSectionAddress(unsigned SectionID, | |||
683 | uint64_t Addr) { | |||
684 | // The address to use for relocation resolution is not | |||
685 | // the address of the local section buffer. We must be doing | |||
686 | // a remote execution environment of some sort. Relocations can't | |||
687 | // be applied until all the sections have been moved. The client must | |||
688 | // trigger this with a call to MCJIT::finalize() or | |||
689 | // RuntimeDyld::resolveRelocations(). | |||
690 | // | |||
691 | // Addr is a uint64_t because we can't assume the pointer width | |||
692 | // of the target is the same as that of the host. Just use a generic | |||
693 | // "big enough" type. | |||
694 | Sections[SectionID].LoadAddress = Addr; | |||
695 | } | |||
696 | ||||
697 | void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs, | |||
698 | uint64_t Value) { | |||
699 | for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { | |||
700 | const RelocationEntry &RE = Relocs[i]; | |||
701 | // Ignore relocations for sections that were not loaded | |||
702 | if (Sections[RE.SectionID].Address == nullptr) | |||
703 | continue; | |||
704 | resolveRelocation(RE, Value); | |||
705 | } | |||
706 | } | |||
707 | ||||
708 | void RuntimeDyldImpl::resolveExternalSymbols() { | |||
709 | while (!ExternalSymbolRelocations.empty()) { | |||
710 | StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin(); | |||
711 | ||||
712 | StringRef Name = i->first(); | |||
713 | if (Name.size() == 0) { | |||
714 | // This is an absolute symbol, use an address of zero. | |||
715 | DEBUG(dbgs() << "Resolving absolute relocations."do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Resolving absolute relocations." << "\n"; } } while (0) | |||
716 | << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Resolving absolute relocations." << "\n"; } } while (0); | |||
717 | RelocationList &Relocs = i->second; | |||
718 | resolveRelocationList(Relocs, 0); | |||
719 | } else { | |||
720 | uint64_t Addr = 0; | |||
721 | SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name); | |||
722 | if (Loc == GlobalSymbolTable.end()) { | |||
723 | // This is an external symbol, try to get its address from | |||
724 | // MemoryManager. | |||
725 | Addr = MemMgr->getSymbolAddress(Name.data()); | |||
726 | // The call to getSymbolAddress may have caused additional modules to | |||
727 | // be loaded, which may have added new entries to the | |||
728 | // ExternalSymbolRelocations map. Consquently, we need to update our | |||
729 | // iterator. This is also why retrieval of the relocation list | |||
730 | // associated with this symbol is deferred until below this point. | |||
731 | // New entries may have been added to the relocation list. | |||
732 | i = ExternalSymbolRelocations.find(Name); | |||
733 | } else { | |||
734 | // We found the symbol in our global table. It was probably in a | |||
735 | // Module that we loaded previously. | |||
736 | SymbolLoc SymLoc = Loc->second; | |||
737 | Addr = getSectionLoadAddress(SymLoc.first) + SymLoc.second; | |||
738 | } | |||
739 | ||||
740 | // FIXME: Implement error handling that doesn't kill the host program! | |||
741 | if (!Addr) | |||
742 | report_fatal_error("Program used external function '" + Name + | |||
743 | "' which could not be resolved!"); | |||
744 | ||||
745 | updateGOTEntries(Name, Addr); | |||
746 | DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Resolving relocations Name: " << Name << "\t" << format("0x%lx", Addr) << "\n" ; } } while (0) | |||
747 | << format("0x%lx", Addr) << "\n")do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("dyld")) { dbgs() << "Resolving relocations Name: " << Name << "\t" << format("0x%lx", Addr) << "\n" ; } } while (0); | |||
748 | // This list may have been updated when we called getSymbolAddress, so | |||
749 | // don't change this code to get the list earlier. | |||
750 | RelocationList &Relocs = i->second; | |||
751 | resolveRelocationList(Relocs, Addr); | |||
752 | } | |||
753 | ||||
754 | ExternalSymbolRelocations.erase(i); | |||
755 | } | |||
756 | } | |||
757 | ||||
758 | //===----------------------------------------------------------------------===// | |||
759 | // RuntimeDyld class implementation | |||
760 | RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { | |||
761 | // FIXME: There's a potential issue lurking here if a single instance of | |||
762 | // RuntimeDyld is used to load multiple objects. The current implementation | |||
763 | // associates a single memory manager with a RuntimeDyld instance. Even | |||
764 | // though the public class spawns a new 'impl' instance for each load, | |||
765 | // they share a single memory manager. This can become a problem when page | |||
766 | // permissions are applied. | |||
767 | Dyld = nullptr; | |||
768 | MM = mm; | |||
769 | ProcessAllSections = false; | |||
770 | Checker = nullptr; | |||
771 | } | |||
772 | ||||
773 | RuntimeDyld::~RuntimeDyld() { delete Dyld; } | |||
774 | ||||
775 | static std::unique_ptr<RuntimeDyldELF> | |||
776 | createRuntimeDyldELF(RTDyldMemoryManager *MM, bool ProcessAllSections, | |||
777 | RuntimeDyldCheckerImpl *Checker) { | |||
778 | std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM)); | |||
779 | Dyld->setProcessAllSections(ProcessAllSections); | |||
780 | Dyld->setRuntimeDyldChecker(Checker); | |||
781 | return Dyld; | |||
782 | } | |||
783 | ||||
784 | static std::unique_ptr<RuntimeDyldMachO> | |||
785 | createRuntimeDyldMachO(Triple::ArchType Arch, RTDyldMemoryManager *MM, | |||
786 | bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) { | |||
787 | std::unique_ptr<RuntimeDyldMachO> Dyld(RuntimeDyldMachO::create(Arch, MM)); | |||
788 | Dyld->setProcessAllSections(ProcessAllSections); | |||
789 | Dyld->setRuntimeDyldChecker(Checker); | |||
790 | return Dyld; | |||
791 | } | |||
792 | ||||
793 | ObjectImage *RuntimeDyld::loadObject(std::unique_ptr<ObjectFile> InputObject) { | |||
794 | std::unique_ptr<ObjectImage> InputImage; | |||
795 | ||||
796 | ObjectFile &Obj = *InputObject; | |||
797 | ||||
798 | if (InputObject->isELF()) { | |||
799 | InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(std::move(InputObject))); | |||
800 | if (!Dyld) | |||
801 | Dyld = createRuntimeDyldELF(MM, ProcessAllSections, Checker).release(); | |||
802 | } else if (InputObject->isMachO()) { | |||
803 | InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject))); | |||
804 | if (!Dyld) | |||
805 | Dyld = createRuntimeDyldMachO( | |||
806 | static_cast<Triple::ArchType>(InputImage->getArch()), | |||
807 | MM, ProcessAllSections, Checker).release(); | |||
808 | } else | |||
809 | report_fatal_error("Incompatible object format!"); | |||
810 | ||||
811 | if (!Dyld->isCompatibleFile(&Obj)) | |||
812 | report_fatal_error("Incompatible object format!"); | |||
813 | ||||
814 | Dyld->loadObject(InputImage.get()); | |||
815 | return InputImage.release(); | |||
816 | } | |||
817 | ||||
818 | ObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) { | |||
819 | std::unique_ptr<ObjectImage> InputImage; | |||
820 | sys::fs::file_magic Type = sys::fs::identify_magic(InputBuffer->getBuffer()); | |||
821 | ||||
822 | switch (Type) { | |||
823 | case sys::fs::file_magic::elf_relocatable: | |||
824 | case sys::fs::file_magic::elf_executable: | |||
825 | case sys::fs::file_magic::elf_shared_object: | |||
826 | case sys::fs::file_magic::elf_core: | |||
827 | InputImage.reset(RuntimeDyldELF::createObjectImage(InputBuffer)); | |||
828 | if (!Dyld) | |||
829 | Dyld = createRuntimeDyldELF(MM, ProcessAllSections, Checker).release(); | |||
830 | break; | |||
831 | case sys::fs::file_magic::macho_object: | |||
832 | case sys::fs::file_magic::macho_executable: | |||
833 | case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: | |||
834 | case sys::fs::file_magic::macho_core: | |||
835 | case sys::fs::file_magic::macho_preload_executable: | |||
836 | case sys::fs::file_magic::macho_dynamically_linked_shared_lib: | |||
837 | case sys::fs::file_magic::macho_dynamic_linker: | |||
838 | case sys::fs::file_magic::macho_bundle: | |||
839 | case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: | |||
840 | case sys::fs::file_magic::macho_dsym_companion: | |||
841 | InputImage.reset(RuntimeDyldMachO::createObjectImage(InputBuffer)); | |||
842 | if (!Dyld) | |||
843 | Dyld = createRuntimeDyldMachO( | |||
844 | static_cast<Triple::ArchType>(InputImage->getArch()), | |||
845 | MM, ProcessAllSections, Checker).release(); | |||
846 | break; | |||
847 | case sys::fs::file_magic::unknown: | |||
848 | case sys::fs::file_magic::bitcode: | |||
849 | case sys::fs::file_magic::archive: | |||
850 | case sys::fs::file_magic::coff_object: | |||
851 | case sys::fs::file_magic::coff_import_library: | |||
852 | case sys::fs::file_magic::pecoff_executable: | |||
853 | case sys::fs::file_magic::macho_universal_binary: | |||
854 | case sys::fs::file_magic::windows_resource: | |||
855 | report_fatal_error("Incompatible object format!"); | |||
856 | } | |||
857 | ||||
858 | if (!Dyld->isCompatibleFormat(InputBuffer)) | |||
859 | report_fatal_error("Incompatible object format!"); | |||
860 | ||||
861 | Dyld->loadObject(InputImage.get()); | |||
862 | return InputImage.release(); | |||
863 | } | |||
864 | ||||
865 | void *RuntimeDyld::getSymbolAddress(StringRef Name) { | |||
866 | if (!Dyld) | |||
867 | return nullptr; | |||
868 | return Dyld->getSymbolAddress(Name); | |||
869 | } | |||
870 | ||||
871 | uint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) { | |||
872 | if (!Dyld) | |||
873 | return 0; | |||
874 | return Dyld->getSymbolLoadAddress(Name); | |||
875 | } | |||
876 | ||||
877 | void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); } | |||
878 | ||||
879 | void RuntimeDyld::reassignSectionAddress(unsigned SectionID, uint64_t Addr) { | |||
880 | Dyld->reassignSectionAddress(SectionID, Addr); | |||
881 | } | |||
882 | ||||
883 | void RuntimeDyld::mapSectionAddress(const void *LocalAddress, | |||
884 | uint64_t TargetAddress) { | |||
885 | Dyld->mapSectionAddress(LocalAddress, TargetAddress); | |||
886 | } | |||
887 | ||||
888 | bool RuntimeDyld::hasError() { return Dyld->hasError(); } | |||
889 | ||||
890 | StringRef RuntimeDyld::getErrorString() { return Dyld->getErrorString(); } | |||
891 | ||||
892 | void RuntimeDyld::registerEHFrames() { | |||
893 | if (Dyld) | |||
894 | Dyld->registerEHFrames(); | |||
895 | } | |||
896 | ||||
897 | void RuntimeDyld::deregisterEHFrames() { | |||
898 | if (Dyld) | |||
899 | Dyld->deregisterEHFrames(); | |||
900 | } | |||
901 | ||||
902 | } // end namespace llvm |