• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This is a testing tool for use with the MC-JIT LLVM components.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/ADT/StringMap.h"
14 #include "llvm/DebugInfo/DIContext.h"
15 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
16 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
17 #include "llvm/ExecutionEngine/RuntimeDyld.h"
18 #include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
22 #include "llvm/MC/MCInstPrinter.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCRegisterInfo.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCTargetOptions.h"
27 #include "llvm/Object/SymbolSize.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/DynamicLibrary.h"
30 #include "llvm/Support/InitLLVM.h"
31 #include "llvm/Support/MSVCErrorWorkarounds.h"
32 #include "llvm/Support/Memory.h"
33 #include "llvm/Support/MemoryBuffer.h"
34 #include "llvm/Support/Path.h"
35 #include "llvm/Support/TargetRegistry.h"
36 #include "llvm/Support/TargetSelect.h"
37 #include "llvm/Support/Timer.h"
38 #include "llvm/Support/raw_ostream.h"
39 
40 #include <future>
41 #include <list>
42 
43 using namespace llvm;
44 using namespace llvm::object;
45 
46 static cl::list<std::string>
47 InputFileList(cl::Positional, cl::ZeroOrMore,
48               cl::desc("<input files>"));
49 
50 enum ActionType {
51   AC_Execute,
52   AC_PrintObjectLineInfo,
53   AC_PrintLineInfo,
54   AC_PrintDebugLineInfo,
55   AC_Verify
56 };
57 
58 static cl::opt<ActionType>
59 Action(cl::desc("Action to perform:"),
60        cl::init(AC_Execute),
61        cl::values(clEnumValN(AC_Execute, "execute",
62                              "Load, link, and execute the inputs."),
63                   clEnumValN(AC_PrintLineInfo, "printline",
64                              "Load, link, and print line information for each function."),
65                   clEnumValN(AC_PrintDebugLineInfo, "printdebugline",
66                              "Load, link, and print line information for each function using the debug object"),
67                   clEnumValN(AC_PrintObjectLineInfo, "printobjline",
68                              "Like -printlineinfo but does not load the object first"),
69                   clEnumValN(AC_Verify, "verify",
70                              "Load, link and verify the resulting memory image.")));
71 
72 static cl::opt<std::string>
73 EntryPoint("entry",
74            cl::desc("Function to call as entry point."),
75            cl::init("_main"));
76 
77 static cl::list<std::string>
78 Dylibs("dylib",
79        cl::desc("Add library."),
80        cl::ZeroOrMore);
81 
82 static cl::list<std::string> InputArgv("args", cl::Positional,
83                                        cl::desc("<program arguments>..."),
84                                        cl::ZeroOrMore, cl::PositionalEatsArgs);
85 
86 static cl::opt<std::string>
87 TripleName("triple", cl::desc("Target triple for disassembler"));
88 
89 static cl::opt<std::string>
90 MCPU("mcpu",
91      cl::desc("Target a specific cpu type (-mcpu=help for details)"),
92      cl::value_desc("cpu-name"),
93      cl::init(""));
94 
95 static cl::list<std::string>
96 CheckFiles("check",
97            cl::desc("File containing RuntimeDyld verifier checks."),
98            cl::ZeroOrMore);
99 
100 static cl::opt<uint64_t>
101     PreallocMemory("preallocate",
102                    cl::desc("Allocate memory upfront rather than on-demand"),
103                    cl::init(0));
104 
105 static cl::opt<uint64_t> TargetAddrStart(
106     "target-addr-start",
107     cl::desc("For -verify only: start of phony target address "
108              "range."),
109     cl::init(4096), // Start at "page 1" - no allocating at "null".
110     cl::Hidden);
111 
112 static cl::opt<uint64_t> TargetAddrEnd(
113     "target-addr-end",
114     cl::desc("For -verify only: end of phony target address range."),
115     cl::init(~0ULL), cl::Hidden);
116 
117 static cl::opt<uint64_t> TargetSectionSep(
118     "target-section-sep",
119     cl::desc("For -verify only: Separation between sections in "
120              "phony target address space."),
121     cl::init(0), cl::Hidden);
122 
123 static cl::list<std::string>
124 SpecificSectionMappings("map-section",
125                         cl::desc("For -verify only: Map a section to a "
126                                  "specific address."),
127                         cl::ZeroOrMore,
128                         cl::Hidden);
129 
130 static cl::list<std::string>
131 DummySymbolMappings("dummy-extern",
132                     cl::desc("For -verify only: Inject a symbol into the extern "
133                              "symbol table."),
134                     cl::ZeroOrMore,
135                     cl::Hidden);
136 
137 static cl::opt<bool>
138 PrintAllocationRequests("print-alloc-requests",
139                         cl::desc("Print allocation requests made to the memory "
140                                  "manager by RuntimeDyld"),
141                         cl::Hidden);
142 
143 static cl::opt<bool> ShowTimes("show-times",
144                                cl::desc("Show times for llvm-rtdyld phases"),
145                                cl::init(false));
146 
147 ExitOnError ExitOnErr;
148 
149 struct RTDyldTimers {
150   TimerGroup RTDyldTG{"llvm-rtdyld timers", "timers for llvm-rtdyld phases"};
151   Timer LoadObjectsTimer{"load", "time to load/add object files", RTDyldTG};
152   Timer LinkTimer{"link", "time to link object files", RTDyldTG};
153   Timer RunTimer{"run", "time to execute jitlink'd code", RTDyldTG};
154 };
155 
156 std::unique_ptr<RTDyldTimers> Timers;
157 
158 /* *** */
159 
160 using SectionIDMap = StringMap<unsigned>;
161 using FileToSectionIDMap = StringMap<SectionIDMap>;
162 
dumpFileToSectionIDMap(const FileToSectionIDMap & FileToSecIDMap)163 void dumpFileToSectionIDMap(const FileToSectionIDMap &FileToSecIDMap) {
164   for (const auto &KV : FileToSecIDMap) {
165     llvm::dbgs() << "In " << KV.first() << "\n";
166     for (auto &KV2 : KV.second)
167       llvm::dbgs() << "  \"" << KV2.first() << "\" -> " << KV2.second << "\n";
168   }
169 }
170 
getSectionId(const FileToSectionIDMap & FileToSecIDMap,StringRef FileName,StringRef SectionName)171 Expected<unsigned> getSectionId(const FileToSectionIDMap &FileToSecIDMap,
172                                 StringRef FileName, StringRef SectionName) {
173   auto I = FileToSecIDMap.find(FileName);
174   if (I == FileToSecIDMap.end())
175     return make_error<StringError>("No file named " + FileName,
176                                    inconvertibleErrorCode());
177   auto &SectionIDs = I->second;
178   auto J = SectionIDs.find(SectionName);
179   if (J == SectionIDs.end())
180     return make_error<StringError>("No section named \"" + SectionName +
181                                    "\" in file " + FileName,
182                                    inconvertibleErrorCode());
183   return J->second;
184 }
185 
186 // A trivial memory manager that doesn't do anything fancy, just uses the
187 // support library allocation routines directly.
188 class TrivialMemoryManager : public RTDyldMemoryManager {
189 public:
190   struct SectionInfo {
SectionInfoTrivialMemoryManager::SectionInfo191     SectionInfo(StringRef Name, sys::MemoryBlock MB, unsigned SectionID)
192         : Name(std::string(Name)), MB(std::move(MB)), SectionID(SectionID) {}
193     std::string Name;
194     sys::MemoryBlock MB;
195     unsigned SectionID = ~0U;
196   };
197 
198   SmallVector<SectionInfo, 16> FunctionMemory;
199   SmallVector<SectionInfo, 16> DataMemory;
200 
201   uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
202                                unsigned SectionID,
203                                StringRef SectionName) override;
204   uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
205                                unsigned SectionID, StringRef SectionName,
206                                bool IsReadOnly) override;
207 
208   /// If non null, records subsequent Name -> SectionID mappings.
setSectionIDsMap(SectionIDMap * SecIDMap)209   void setSectionIDsMap(SectionIDMap *SecIDMap) {
210     this->SecIDMap = SecIDMap;
211   }
212 
getPointerToNamedFunction(const std::string & Name,bool AbortOnFailure=true)213   void *getPointerToNamedFunction(const std::string &Name,
214                                   bool AbortOnFailure = true) override {
215     return nullptr;
216   }
217 
finalizeMemory(std::string * ErrMsg)218   bool finalizeMemory(std::string *ErrMsg) override { return false; }
219 
addDummySymbol(const std::string & Name,uint64_t Addr)220   void addDummySymbol(const std::string &Name, uint64_t Addr) {
221     DummyExterns[Name] = Addr;
222   }
223 
findSymbol(const std::string & Name)224   JITSymbol findSymbol(const std::string &Name) override {
225     auto I = DummyExterns.find(Name);
226 
227     if (I != DummyExterns.end())
228       return JITSymbol(I->second, JITSymbolFlags::Exported);
229 
230     if (auto Sym = RTDyldMemoryManager::findSymbol(Name))
231       return Sym;
232     else if (auto Err = Sym.takeError())
233       ExitOnErr(std::move(Err));
234     else
235       ExitOnErr(make_error<StringError>("Could not find definition for \"" +
236                                             Name + "\"",
237                                         inconvertibleErrorCode()));
238     llvm_unreachable("Should have returned or exited by now");
239   }
240 
registerEHFrames(uint8_t * Addr,uint64_t LoadAddr,size_t Size)241   void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
242                         size_t Size) override {}
deregisterEHFrames()243   void deregisterEHFrames() override {}
244 
preallocateSlab(uint64_t Size)245   void preallocateSlab(uint64_t Size) {
246     std::error_code EC;
247     sys::MemoryBlock MB =
248       sys::Memory::allocateMappedMemory(Size, nullptr,
249                                         sys::Memory::MF_READ |
250                                         sys::Memory::MF_WRITE,
251                                         EC);
252     if (!MB.base())
253       report_fatal_error("Can't allocate enough memory: " + EC.message());
254 
255     PreallocSlab = MB;
256     UsePreallocation = true;
257     SlabSize = Size;
258   }
259 
allocateFromSlab(uintptr_t Size,unsigned Alignment,bool isCode,StringRef SectionName,unsigned SectionID)260   uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode,
261                             StringRef SectionName, unsigned SectionID) {
262     Size = alignTo(Size, Alignment);
263     if (CurrentSlabOffset + Size > SlabSize)
264       report_fatal_error("Can't allocate enough memory. Tune --preallocate");
265 
266     uintptr_t OldSlabOffset = CurrentSlabOffset;
267     sys::MemoryBlock MB((void *)OldSlabOffset, Size);
268     if (isCode)
269       FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID));
270     else
271       DataMemory.push_back(SectionInfo(SectionName, MB, SectionID));
272     CurrentSlabOffset += Size;
273     return (uint8_t*)OldSlabOffset;
274   }
275 
276 private:
277   std::map<std::string, uint64_t> DummyExterns;
278   sys::MemoryBlock PreallocSlab;
279   bool UsePreallocation = false;
280   uintptr_t SlabSize = 0;
281   uintptr_t CurrentSlabOffset = 0;
282   SectionIDMap *SecIDMap = nullptr;
283 };
284 
allocateCodeSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName)285 uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
286                                                    unsigned Alignment,
287                                                    unsigned SectionID,
288                                                    StringRef SectionName) {
289   if (PrintAllocationRequests)
290     outs() << "allocateCodeSection(Size = " << Size << ", Alignment = "
291            << Alignment << ", SectionName = " << SectionName << ")\n";
292 
293   if (SecIDMap)
294     (*SecIDMap)[SectionName] = SectionID;
295 
296   if (UsePreallocation)
297     return allocateFromSlab(Size, Alignment, true /* isCode */,
298                             SectionName, SectionID);
299 
300   std::error_code EC;
301   sys::MemoryBlock MB =
302     sys::Memory::allocateMappedMemory(Size, nullptr,
303                                       sys::Memory::MF_READ |
304                                       sys::Memory::MF_WRITE,
305                                       EC);
306   if (!MB.base())
307     report_fatal_error("MemoryManager allocation failed: " + EC.message());
308   FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID));
309   return (uint8_t*)MB.base();
310 }
311 
allocateDataSection(uintptr_t Size,unsigned Alignment,unsigned SectionID,StringRef SectionName,bool IsReadOnly)312 uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
313                                                    unsigned Alignment,
314                                                    unsigned SectionID,
315                                                    StringRef SectionName,
316                                                    bool IsReadOnly) {
317   if (PrintAllocationRequests)
318     outs() << "allocateDataSection(Size = " << Size << ", Alignment = "
319            << Alignment << ", SectionName = " << SectionName << ")\n";
320 
321   if (SecIDMap)
322     (*SecIDMap)[SectionName] = SectionID;
323 
324   if (UsePreallocation)
325     return allocateFromSlab(Size, Alignment, false /* isCode */, SectionName,
326                             SectionID);
327 
328   std::error_code EC;
329   sys::MemoryBlock MB =
330     sys::Memory::allocateMappedMemory(Size, nullptr,
331                                       sys::Memory::MF_READ |
332                                       sys::Memory::MF_WRITE,
333                                       EC);
334   if (!MB.base())
335     report_fatal_error("MemoryManager allocation failed: " + EC.message());
336   DataMemory.push_back(SectionInfo(SectionName, MB, SectionID));
337   return (uint8_t*)MB.base();
338 }
339 
340 static const char *ProgramName;
341 
ErrorAndExit(const Twine & Msg)342 static void ErrorAndExit(const Twine &Msg) {
343   errs() << ProgramName << ": error: " << Msg << "\n";
344   exit(1);
345 }
346 
loadDylibs()347 static void loadDylibs() {
348   for (const std::string &Dylib : Dylibs) {
349     if (!sys::fs::is_regular_file(Dylib))
350       report_fatal_error("Dylib not found: '" + Dylib + "'.");
351     std::string ErrMsg;
352     if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg))
353       report_fatal_error("Error loading '" + Dylib + "': " + ErrMsg);
354   }
355 }
356 
357 /* *** */
358 
printLineInfoForInput(bool LoadObjects,bool UseDebugObj)359 static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
360   assert(LoadObjects || !UseDebugObj);
361 
362   // Load any dylibs requested on the command line.
363   loadDylibs();
364 
365   // If we don't have any input files, read from stdin.
366   if (!InputFileList.size())
367     InputFileList.push_back("-");
368   for (auto &File : InputFileList) {
369     // Instantiate a dynamic linker.
370     TrivialMemoryManager MemMgr;
371     RuntimeDyld Dyld(MemMgr, MemMgr);
372 
373     // Load the input memory buffer.
374 
375     ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
376         MemoryBuffer::getFileOrSTDIN(File);
377     if (std::error_code EC = InputBuffer.getError())
378       ErrorAndExit("unable to read input: '" + EC.message() + "'");
379 
380     Expected<std::unique_ptr<ObjectFile>> MaybeObj(
381       ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
382 
383     if (!MaybeObj) {
384       std::string Buf;
385       raw_string_ostream OS(Buf);
386       logAllUnhandledErrors(MaybeObj.takeError(), OS);
387       OS.flush();
388       ErrorAndExit("unable to create object file: '" + Buf + "'");
389     }
390 
391     ObjectFile &Obj = **MaybeObj;
392 
393     OwningBinary<ObjectFile> DebugObj;
394     std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr;
395     ObjectFile *SymbolObj = &Obj;
396     if (LoadObjects) {
397       // Load the object file
398       LoadedObjInfo =
399         Dyld.loadObject(Obj);
400 
401       if (Dyld.hasError())
402         ErrorAndExit(Dyld.getErrorString());
403 
404       // Resolve all the relocations we can.
405       Dyld.resolveRelocations();
406 
407       if (UseDebugObj) {
408         DebugObj = LoadedObjInfo->getObjectForDebug(Obj);
409         SymbolObj = DebugObj.getBinary();
410         LoadedObjInfo.reset();
411       }
412     }
413 
414     std::unique_ptr<DIContext> Context =
415         DWARFContext::create(*SymbolObj, LoadedObjInfo.get());
416 
417     std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
418         object::computeSymbolSizes(*SymbolObj);
419 
420     // Use symbol info to iterate functions in the object.
421     for (const auto &P : SymAddr) {
422       object::SymbolRef Sym = P.first;
423       Expected<SymbolRef::Type> TypeOrErr = Sym.getType();
424       if (!TypeOrErr) {
425         // TODO: Actually report errors helpfully.
426         consumeError(TypeOrErr.takeError());
427         continue;
428       }
429       SymbolRef::Type Type = *TypeOrErr;
430       if (Type == object::SymbolRef::ST_Function) {
431         Expected<StringRef> Name = Sym.getName();
432         if (!Name) {
433           // TODO: Actually report errors helpfully.
434           consumeError(Name.takeError());
435           continue;
436         }
437         Expected<uint64_t> AddrOrErr = Sym.getAddress();
438         if (!AddrOrErr) {
439           // TODO: Actually report errors helpfully.
440           consumeError(AddrOrErr.takeError());
441           continue;
442         }
443         uint64_t Addr = *AddrOrErr;
444 
445         object::SectionedAddress Address;
446 
447         uint64_t Size = P.second;
448         // If we're not using the debug object, compute the address of the
449         // symbol in memory (rather than that in the unrelocated object file)
450         // and use that to query the DWARFContext.
451         if (!UseDebugObj && LoadObjects) {
452           auto SecOrErr = Sym.getSection();
453           if (!SecOrErr) {
454             // TODO: Actually report errors helpfully.
455             consumeError(SecOrErr.takeError());
456             continue;
457           }
458           object::section_iterator Sec = *SecOrErr;
459           Address.SectionIndex = Sec->getIndex();
460           uint64_t SectionLoadAddress =
461             LoadedObjInfo->getSectionLoadAddress(*Sec);
462           if (SectionLoadAddress != 0)
463             Addr += SectionLoadAddress - Sec->getAddress();
464         } else if (auto SecOrErr = Sym.getSection())
465           Address.SectionIndex = SecOrErr.get()->getIndex();
466 
467         outs() << "Function: " << *Name << ", Size = " << Size
468                << ", Addr = " << Addr << "\n";
469 
470         Address.Address = Addr;
471         DILineInfoTable Lines =
472             Context->getLineInfoForAddressRange(Address, Size);
473         for (auto &D : Lines) {
474           outs() << "  Line info @ " << D.first - Addr << ": "
475                  << D.second.FileName << ", line:" << D.second.Line << "\n";
476         }
477       }
478     }
479   }
480 
481   return 0;
482 }
483 
doPreallocation(TrivialMemoryManager & MemMgr)484 static void doPreallocation(TrivialMemoryManager &MemMgr) {
485   // Allocate a slab of memory upfront, if required. This is used if
486   // we want to test small code models.
487   if (static_cast<intptr_t>(PreallocMemory) < 0)
488     report_fatal_error("Pre-allocated bytes of memory must be a positive integer.");
489 
490   // FIXME: Limit the amount of memory that can be preallocated?
491   if (PreallocMemory != 0)
492     MemMgr.preallocateSlab(PreallocMemory);
493 }
494 
executeInput()495 static int executeInput() {
496   // Load any dylibs requested on the command line.
497   loadDylibs();
498 
499   // Instantiate a dynamic linker.
500   TrivialMemoryManager MemMgr;
501   doPreallocation(MemMgr);
502   RuntimeDyld Dyld(MemMgr, MemMgr);
503 
504   // If we don't have any input files, read from stdin.
505   if (!InputFileList.size())
506     InputFileList.push_back("-");
507   {
508     TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
509     for (auto &File : InputFileList) {
510       // Load the input memory buffer.
511       ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
512           MemoryBuffer::getFileOrSTDIN(File);
513       if (std::error_code EC = InputBuffer.getError())
514         ErrorAndExit("unable to read input: '" + EC.message() + "'");
515       Expected<std::unique_ptr<ObjectFile>> MaybeObj(
516           ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
517 
518       if (!MaybeObj) {
519         std::string Buf;
520         raw_string_ostream OS(Buf);
521         logAllUnhandledErrors(MaybeObj.takeError(), OS);
522         OS.flush();
523         ErrorAndExit("unable to create object file: '" + Buf + "'");
524       }
525 
526       ObjectFile &Obj = **MaybeObj;
527 
528       // Load the object file
529       Dyld.loadObject(Obj);
530       if (Dyld.hasError()) {
531         ErrorAndExit(Dyld.getErrorString());
532       }
533     }
534   }
535 
536   {
537     TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);
538     // Resove all the relocations we can.
539     // FIXME: Error out if there are unresolved relocations.
540     Dyld.resolveRelocations();
541   }
542 
543   // Get the address of the entry point (_main by default).
544   void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint);
545   if (!MainAddress)
546     ErrorAndExit("no definition for '" + EntryPoint + "'");
547 
548   // Invalidate the instruction cache for each loaded function.
549   for (auto &FM : MemMgr.FunctionMemory) {
550 
551     auto &FM_MB = FM.MB;
552 
553     // Make sure the memory is executable.
554     // setExecutable will call InvalidateInstructionCache.
555     if (auto EC = sys::Memory::protectMappedMemory(FM_MB,
556                                                    sys::Memory::MF_READ |
557                                                    sys::Memory::MF_EXEC))
558       ErrorAndExit("unable to mark function executable: '" + EC.message() +
559                    "'");
560   }
561 
562   // Dispatch to _main().
563   errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n";
564 
565   int (*Main)(int, const char**) =
566     (int(*)(int,const char**)) uintptr_t(MainAddress);
567   std::vector<const char *> Argv;
568   // Use the name of the first input object module as argv[0] for the target.
569   Argv.push_back(InputFileList[0].data());
570   for (auto &Arg : InputArgv)
571     Argv.push_back(Arg.data());
572   Argv.push_back(nullptr);
573   int Result = 0;
574   {
575     TimeRegion TR(Timers ? &Timers->RunTimer : nullptr);
576     Result = Main(Argv.size() - 1, Argv.data());
577   }
578 
579   return Result;
580 }
581 
checkAllExpressions(RuntimeDyldChecker & Checker)582 static int checkAllExpressions(RuntimeDyldChecker &Checker) {
583   for (const auto& CheckerFileName : CheckFiles) {
584     ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf =
585         MemoryBuffer::getFileOrSTDIN(CheckerFileName);
586     if (std::error_code EC = CheckerFileBuf.getError())
587       ErrorAndExit("unable to read input '" + CheckerFileName + "': " +
588                    EC.message());
589 
590     if (!Checker.checkAllRulesInBuffer("# rtdyld-check:",
591                                        CheckerFileBuf.get().get()))
592       ErrorAndExit("some checks in '" + CheckerFileName + "' failed");
593   }
594   return 0;
595 }
596 
applySpecificSectionMappings(RuntimeDyld & Dyld,const FileToSectionIDMap & FileToSecIDMap)597 void applySpecificSectionMappings(RuntimeDyld &Dyld,
598                                   const FileToSectionIDMap &FileToSecIDMap) {
599 
600   for (StringRef Mapping : SpecificSectionMappings) {
601     size_t EqualsIdx = Mapping.find_first_of("=");
602     std::string SectionIDStr = std::string(Mapping.substr(0, EqualsIdx));
603     size_t ComaIdx = Mapping.find_first_of(",");
604 
605     if (ComaIdx == StringRef::npos)
606       report_fatal_error("Invalid section specification '" + Mapping +
607                          "'. Should be '<file name>,<section name>=<addr>'");
608 
609     std::string FileName = SectionIDStr.substr(0, ComaIdx);
610     std::string SectionName = SectionIDStr.substr(ComaIdx + 1);
611     unsigned SectionID =
612       ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName));
613 
614     auto* OldAddr = Dyld.getSectionContent(SectionID).data();
615     std::string NewAddrStr = std::string(Mapping.substr(EqualsIdx + 1));
616     uint64_t NewAddr;
617 
618     if (StringRef(NewAddrStr).getAsInteger(0, NewAddr))
619       report_fatal_error("Invalid section address in mapping '" + Mapping +
620                          "'.");
621 
622     Dyld.mapSectionAddress(OldAddr, NewAddr);
623   }
624 }
625 
626 // Scatter sections in all directions!
627 // Remaps section addresses for -verify mode. The following command line options
628 // can be used to customize the layout of the memory within the phony target's
629 // address space:
630 // -target-addr-start <s> -- Specify where the phony target address range starts.
631 // -target-addr-end   <e> -- Specify where the phony target address range ends.
632 // -target-section-sep <d> -- Specify how big a gap should be left between the
633 //                            end of one section and the start of the next.
634 //                            Defaults to zero. Set to something big
635 //                            (e.g. 1 << 32) to stress-test stubs, GOTs, etc.
636 //
remapSectionsAndSymbols(const llvm::Triple & TargetTriple,RuntimeDyld & Dyld,TrivialMemoryManager & MemMgr)637 static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
638                                     RuntimeDyld &Dyld,
639                                     TrivialMemoryManager &MemMgr) {
640 
641   // Set up a work list (section addr/size pairs).
642   typedef std::list<const TrivialMemoryManager::SectionInfo*> WorklistT;
643   WorklistT Worklist;
644 
645   for (const auto& CodeSection : MemMgr.FunctionMemory)
646     Worklist.push_back(&CodeSection);
647   for (const auto& DataSection : MemMgr.DataMemory)
648     Worklist.push_back(&DataSection);
649 
650   // Keep an "already allocated" mapping of section target addresses to sizes.
651   // Sections whose address mappings aren't specified on the command line will
652   // allocated around the explicitly mapped sections while maintaining the
653   // minimum separation.
654   std::map<uint64_t, uint64_t> AlreadyAllocated;
655 
656   // Move the previously applied mappings (whether explicitly specified on the
657   // command line, or implicitly set by RuntimeDyld) into the already-allocated
658   // map.
659   for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end();
660        I != E;) {
661     WorklistT::iterator Tmp = I;
662     ++I;
663 
664     auto LoadAddr = Dyld.getSectionLoadAddress((*Tmp)->SectionID);
665 
666     if (LoadAddr != static_cast<uint64_t>(
667           reinterpret_cast<uintptr_t>((*Tmp)->MB.base()))) {
668       // A section will have a LoadAddr of 0 if it wasn't loaded for whatever
669       // reason (e.g. zero byte COFF sections). Don't include those sections in
670       // the allocation map.
671       if (LoadAddr != 0)
672         AlreadyAllocated[LoadAddr] = (*Tmp)->MB.allocatedSize();
673       Worklist.erase(Tmp);
674     }
675   }
676 
677   // If the -target-addr-end option wasn't explicitly passed, then set it to a
678   // sensible default based on the target triple.
679   if (TargetAddrEnd.getNumOccurrences() == 0) {
680     if (TargetTriple.isArch16Bit())
681       TargetAddrEnd = (1ULL << 16) - 1;
682     else if (TargetTriple.isArch32Bit())
683       TargetAddrEnd = (1ULL << 32) - 1;
684     // TargetAddrEnd already has a sensible default for 64-bit systems, so
685     // there's nothing to do in the 64-bit case.
686   }
687 
688   // Process any elements remaining in the worklist.
689   while (!Worklist.empty()) {
690     auto *CurEntry = Worklist.front();
691     Worklist.pop_front();
692 
693     uint64_t NextSectionAddr = TargetAddrStart;
694 
695     for (const auto &Alloc : AlreadyAllocated)
696       if (NextSectionAddr + CurEntry->MB.allocatedSize() + TargetSectionSep <=
697           Alloc.first)
698         break;
699       else
700         NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep;
701 
702     Dyld.mapSectionAddress(CurEntry->MB.base(), NextSectionAddr);
703     AlreadyAllocated[NextSectionAddr] = CurEntry->MB.allocatedSize();
704   }
705 
706   // Add dummy symbols to the memory manager.
707   for (const auto &Mapping : DummySymbolMappings) {
708     size_t EqualsIdx = Mapping.find_first_of('=');
709 
710     if (EqualsIdx == StringRef::npos)
711       report_fatal_error("Invalid dummy symbol specification '" + Mapping +
712                          "'. Should be '<symbol name>=<addr>'");
713 
714     std::string Symbol = Mapping.substr(0, EqualsIdx);
715     std::string AddrStr = Mapping.substr(EqualsIdx + 1);
716 
717     uint64_t Addr;
718     if (StringRef(AddrStr).getAsInteger(0, Addr))
719       report_fatal_error("Invalid symbol mapping '" + Mapping + "'.");
720 
721     MemMgr.addDummySymbol(Symbol, Addr);
722   }
723 }
724 
725 // Load and link the objects specified on the command line, but do not execute
726 // anything. Instead, attach a RuntimeDyldChecker instance and call it to
727 // verify the correctness of the linked memory.
linkAndVerify()728 static int linkAndVerify() {
729 
730   // Check for missing triple.
731   if (TripleName == "")
732     ErrorAndExit("-triple required when running in -verify mode.");
733 
734   // Look up the target and build the disassembler.
735   Triple TheTriple(Triple::normalize(TripleName));
736   std::string ErrorStr;
737   const Target *TheTarget =
738     TargetRegistry::lookupTarget("", TheTriple, ErrorStr);
739   if (!TheTarget)
740     ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr);
741 
742   TripleName = TheTriple.getTriple();
743 
744   std::unique_ptr<MCSubtargetInfo> STI(
745     TheTarget->createMCSubtargetInfo(TripleName, MCPU, ""));
746   if (!STI)
747     ErrorAndExit("Unable to create subtarget info!");
748 
749   std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
750   if (!MRI)
751     ErrorAndExit("Unable to create target register info!");
752 
753   MCTargetOptions MCOptions;
754   std::unique_ptr<MCAsmInfo> MAI(
755       TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
756   if (!MAI)
757     ErrorAndExit("Unable to create target asm info!");
758 
759   MCContext Ctx(MAI.get(), MRI.get(), nullptr);
760 
761   std::unique_ptr<MCDisassembler> Disassembler(
762     TheTarget->createMCDisassembler(*STI, Ctx));
763   if (!Disassembler)
764     ErrorAndExit("Unable to create disassembler!");
765 
766   std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
767   if (!MII)
768     ErrorAndExit("Unable to create target instruction info!");
769 
770   std::unique_ptr<MCInstPrinter> InstPrinter(
771       TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI));
772 
773   // Load any dylibs requested on the command line.
774   loadDylibs();
775 
776   // Instantiate a dynamic linker.
777   TrivialMemoryManager MemMgr;
778   doPreallocation(MemMgr);
779 
780   struct StubID {
781     unsigned SectionID;
782     uint32_t Offset;
783   };
784   using StubInfos = StringMap<StubID>;
785   using StubContainers = StringMap<StubInfos>;
786 
787   StubContainers StubMap;
788   RuntimeDyld Dyld(MemMgr, MemMgr);
789   Dyld.setProcessAllSections(true);
790 
791   Dyld.setNotifyStubEmitted([&StubMap](StringRef FilePath,
792                                        StringRef SectionName,
793                                        StringRef SymbolName, unsigned SectionID,
794                                        uint32_t StubOffset) {
795     std::string ContainerName =
796         (sys::path::filename(FilePath) + "/" + SectionName).str();
797     StubMap[ContainerName][SymbolName] = {SectionID, StubOffset};
798   });
799 
800   auto GetSymbolInfo =
801       [&Dyld, &MemMgr](
802           StringRef Symbol) -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
803     RuntimeDyldChecker::MemoryRegionInfo SymInfo;
804 
805     // First get the target address.
806     if (auto InternalSymbol = Dyld.getSymbol(Symbol))
807       SymInfo.setTargetAddress(InternalSymbol.getAddress());
808     else {
809       // Symbol not found in RuntimeDyld. Fall back to external lookup.
810 #ifdef _MSC_VER
811       using ExpectedLookupResult =
812           MSVCPExpected<JITSymbolResolver::LookupResult>;
813 #else
814       using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>;
815 #endif
816 
817       auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>();
818       auto ResultF = ResultP->get_future();
819 
820       MemMgr.lookup(JITSymbolResolver::LookupSet({Symbol}),
821                     [=](Expected<JITSymbolResolver::LookupResult> Result) {
822                       ResultP->set_value(std::move(Result));
823                     });
824 
825       auto Result = ResultF.get();
826       if (!Result)
827         return Result.takeError();
828 
829       auto I = Result->find(Symbol);
830       assert(I != Result->end() &&
831              "Expected symbol address if no error occurred");
832       SymInfo.setTargetAddress(I->second.getAddress());
833     }
834 
835     // Now find the symbol content if possible (otherwise leave content as a
836     // default-constructed StringRef).
837     if (auto *SymAddr = Dyld.getSymbolLocalAddress(Symbol)) {
838       unsigned SectionID = Dyld.getSymbolSectionID(Symbol);
839       if (SectionID != ~0U) {
840         char *CSymAddr = static_cast<char *>(SymAddr);
841         StringRef SecContent = Dyld.getSectionContent(SectionID);
842         uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data());
843         SymInfo.setContent(StringRef(CSymAddr, SymSize));
844       }
845     }
846     return SymInfo;
847   };
848 
849   auto IsSymbolValid = [&Dyld, GetSymbolInfo](StringRef Symbol) {
850     if (Dyld.getSymbol(Symbol))
851       return true;
852     auto SymInfo = GetSymbolInfo(Symbol);
853     if (!SymInfo) {
854       logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
855       return false;
856     }
857     return SymInfo->getTargetAddress() != 0;
858   };
859 
860   FileToSectionIDMap FileToSecIDMap;
861 
862   auto GetSectionInfo = [&Dyld, &FileToSecIDMap](StringRef FileName,
863                                                  StringRef SectionName)
864       -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
865     auto SectionID = getSectionId(FileToSecIDMap, FileName, SectionName);
866     if (!SectionID)
867       return SectionID.takeError();
868     RuntimeDyldChecker::MemoryRegionInfo SecInfo;
869     SecInfo.setTargetAddress(Dyld.getSectionLoadAddress(*SectionID));
870     SecInfo.setContent(Dyld.getSectionContent(*SectionID));
871     return SecInfo;
872   };
873 
874   auto GetStubInfo = [&Dyld, &StubMap](StringRef StubContainer,
875                                        StringRef SymbolName)
876       -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
877     if (!StubMap.count(StubContainer))
878       return make_error<StringError>("Stub container not found: " +
879                                          StubContainer,
880                                      inconvertibleErrorCode());
881     if (!StubMap[StubContainer].count(SymbolName))
882       return make_error<StringError>("Symbol name " + SymbolName +
883                                          " in stub container " + StubContainer,
884                                      inconvertibleErrorCode());
885     auto &SI = StubMap[StubContainer][SymbolName];
886     RuntimeDyldChecker::MemoryRegionInfo StubMemInfo;
887     StubMemInfo.setTargetAddress(Dyld.getSectionLoadAddress(SI.SectionID) +
888                                  SI.Offset);
889     StubMemInfo.setContent(
890         Dyld.getSectionContent(SI.SectionID).substr(SI.Offset));
891     return StubMemInfo;
892   };
893 
894   // We will initialize this below once we have the first object file and can
895   // know the endianness.
896   std::unique_ptr<RuntimeDyldChecker> Checker;
897 
898   // If we don't have any input files, read from stdin.
899   if (!InputFileList.size())
900     InputFileList.push_back("-");
901   for (auto &InputFile : InputFileList) {
902     // Load the input memory buffer.
903     ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
904         MemoryBuffer::getFileOrSTDIN(InputFile);
905 
906     if (std::error_code EC = InputBuffer.getError())
907       ErrorAndExit("unable to read input: '" + EC.message() + "'");
908 
909     Expected<std::unique_ptr<ObjectFile>> MaybeObj(
910       ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
911 
912     if (!MaybeObj) {
913       std::string Buf;
914       raw_string_ostream OS(Buf);
915       logAllUnhandledErrors(MaybeObj.takeError(), OS);
916       OS.flush();
917       ErrorAndExit("unable to create object file: '" + Buf + "'");
918     }
919 
920     ObjectFile &Obj = **MaybeObj;
921 
922     if (!Checker)
923       Checker = std::make_unique<RuntimeDyldChecker>(
924           IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo,
925           GetStubInfo, Obj.isLittleEndian() ? support::little : support::big,
926           Disassembler.get(), InstPrinter.get(), dbgs());
927 
928     auto FileName = sys::path::filename(InputFile);
929     MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]);
930 
931     // Load the object file
932     Dyld.loadObject(Obj);
933     if (Dyld.hasError()) {
934       ErrorAndExit(Dyld.getErrorString());
935     }
936   }
937 
938   // Re-map the section addresses into the phony target address space and add
939   // dummy symbols.
940   applySpecificSectionMappings(Dyld, FileToSecIDMap);
941   remapSectionsAndSymbols(TheTriple, Dyld, MemMgr);
942 
943   // Resolve all the relocations we can.
944   Dyld.resolveRelocations();
945 
946   // Register EH frames.
947   Dyld.registerEHFrames();
948 
949   int ErrorCode = checkAllExpressions(*Checker);
950   if (Dyld.hasError())
951     ErrorAndExit("RTDyld reported an error applying relocations:\n  " +
952                  Dyld.getErrorString());
953 
954   return ErrorCode;
955 }
956 
main(int argc,char ** argv)957 int main(int argc, char **argv) {
958   InitLLVM X(argc, argv);
959   ProgramName = argv[0];
960 
961   llvm::InitializeAllTargetInfos();
962   llvm::InitializeAllTargetMCs();
963   llvm::InitializeAllDisassemblers();
964 
965   cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n");
966 
967   ExitOnErr.setBanner(std::string(argv[0]) + ": ");
968 
969   Timers = ShowTimes ? std::make_unique<RTDyldTimers>() : nullptr;
970 
971   int Result;
972   switch (Action) {
973   case AC_Execute:
974     Result = executeInput();
975     break;
976   case AC_PrintDebugLineInfo:
977     Result =
978         printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ true);
979     break;
980   case AC_PrintLineInfo:
981     Result =
982         printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ false);
983     break;
984   case AC_PrintObjectLineInfo:
985     Result =
986         printLineInfoForInput(/* LoadObjects */ false, /* UseDebugObj */ false);
987     break;
988   case AC_Verify:
989     Result = linkAndVerify();
990     break;
991   }
992   return Result;
993 }
994