1221337Sdim//===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===//
2221337Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6221337Sdim//
7221337Sdim//===----------------------------------------------------------------------===//
8221337Sdim//
9221337Sdim// This is a testing tool for use with the MC-JIT LLVM components.
10221337Sdim//
11221337Sdim//===----------------------------------------------------------------------===//
12221337Sdim
13221337Sdim#include "llvm/ADT/StringMap.h"
14249423Sdim#include "llvm/DebugInfo/DIContext.h"
15288943Sdim#include "llvm/DebugInfo/DWARF/DWARFContext.h"
16288943Sdim#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
17221337Sdim#include "llvm/ExecutionEngine/RuntimeDyld.h"
18276479Sdim#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
19276479Sdim#include "llvm/MC/MCAsmInfo.h"
20276479Sdim#include "llvm/MC/MCContext.h"
21309124Sdim#include "llvm/MC/MCDisassembler/MCDisassembler.h"
22280031Sdim#include "llvm/MC/MCInstPrinter.h"
23276479Sdim#include "llvm/MC/MCInstrInfo.h"
24276479Sdim#include "llvm/MC/MCRegisterInfo.h"
25288943Sdim#include "llvm/MC/MCSubtargetInfo.h"
26360784Sdim#include "llvm/MC/MCTargetOptions.h"
27288943Sdim#include "llvm/Object/SymbolSize.h"
28221337Sdim#include "llvm/Support/CommandLine.h"
29276479Sdim#include "llvm/Support/DynamicLibrary.h"
30341825Sdim#include "llvm/Support/InitLLVM.h"
31360784Sdim#include "llvm/Support/MSVCErrorWorkarounds.h"
32221337Sdim#include "llvm/Support/Memory.h"
33221337Sdim#include "llvm/Support/MemoryBuffer.h"
34353358Sdim#include "llvm/Support/Path.h"
35276479Sdim#include "llvm/Support/TargetRegistry.h"
36276479Sdim#include "llvm/Support/TargetSelect.h"
37360784Sdim#include "llvm/Support/Timer.h"
38280031Sdim#include "llvm/Support/raw_ostream.h"
39353358Sdim
40353358Sdim#include <future>
41280031Sdim#include <list>
42276479Sdim
43221337Sdimusing namespace llvm;
44221337Sdimusing namespace llvm::object;
45221337Sdim
46221337Sdimstatic cl::list<std::string>
47221337SdimInputFileList(cl::Positional, cl::ZeroOrMore,
48341825Sdim              cl::desc("<input files>"));
49221337Sdim
50221337Sdimenum ActionType {
51249423Sdim  AC_Execute,
52288943Sdim  AC_PrintObjectLineInfo,
53276479Sdim  AC_PrintLineInfo,
54288943Sdim  AC_PrintDebugLineInfo,
55276479Sdim  AC_Verify
56221337Sdim};
57221337Sdim
58221337Sdimstatic cl::opt<ActionType>
59221337SdimAction(cl::desc("Action to perform:"),
60221337Sdim       cl::init(AC_Execute),
61221337Sdim       cl::values(clEnumValN(AC_Execute, "execute",
62221337Sdim                             "Load, link, and execute the inputs."),
63249423Sdim                  clEnumValN(AC_PrintLineInfo, "printline",
64249423Sdim                             "Load, link, and print line information for each function."),
65288943Sdim                  clEnumValN(AC_PrintDebugLineInfo, "printdebugline",
66288943Sdim                             "Load, link, and print line information for each function using the debug object"),
67288943Sdim                  clEnumValN(AC_PrintObjectLineInfo, "printobjline",
68288943Sdim                             "Like -printlineinfo but does not load the object first"),
69276479Sdim                  clEnumValN(AC_Verify, "verify",
70314564Sdim                             "Load, link and verify the resulting memory image.")));
71221337Sdim
72221337Sdimstatic cl::opt<std::string>
73221337SdimEntryPoint("entry",
74221337Sdim           cl::desc("Function to call as entry point."),
75221337Sdim           cl::init("_main"));
76221337Sdim
77276479Sdimstatic cl::list<std::string>
78276479SdimDylibs("dylib",
79276479Sdim       cl::desc("Add library."),
80276479Sdim       cl::ZeroOrMore);
81276479Sdim
82353358Sdimstatic cl::list<std::string> InputArgv("args", cl::Positional,
83353358Sdim                                       cl::desc("<program arguments>..."),
84353358Sdim                                       cl::ZeroOrMore, cl::PositionalEatsArgs);
85353358Sdim
86276479Sdimstatic cl::opt<std::string>
87276479SdimTripleName("triple", cl::desc("Target triple for disassembler"));
88276479Sdim
89288943Sdimstatic cl::opt<std::string>
90288943SdimMCPU("mcpu",
91288943Sdim     cl::desc("Target a specific cpu type (-mcpu=help for details)"),
92288943Sdim     cl::value_desc("cpu-name"),
93288943Sdim     cl::init(""));
94288943Sdim
95276479Sdimstatic cl::list<std::string>
96276479SdimCheckFiles("check",
97276479Sdim           cl::desc("File containing RuntimeDyld verifier checks."),
98276479Sdim           cl::ZeroOrMore);
99276479Sdim
100353358Sdimstatic cl::opt<uint64_t>
101353358Sdim    PreallocMemory("preallocate",
102353358Sdim                   cl::desc("Allocate memory upfront rather than on-demand"),
103353358Sdim                   cl::init(0));
104296417Sdim
105353358Sdimstatic cl::opt<uint64_t> TargetAddrStart(
106353358Sdim    "target-addr-start",
107353358Sdim    cl::desc("For -verify only: start of phony target address "
108353358Sdim             "range."),
109353358Sdim    cl::init(4096), // Start at "page 1" - no allocating at "null".
110353358Sdim    cl::Hidden);
111280031Sdim
112353358Sdimstatic cl::opt<uint64_t> TargetAddrEnd(
113353358Sdim    "target-addr-end",
114353358Sdim    cl::desc("For -verify only: end of phony target address range."),
115353358Sdim    cl::init(~0ULL), cl::Hidden);
116280031Sdim
117353358Sdimstatic cl::opt<uint64_t> TargetSectionSep(
118353358Sdim    "target-section-sep",
119353358Sdim    cl::desc("For -verify only: Separation between sections in "
120353358Sdim             "phony target address space."),
121353358Sdim    cl::init(0), cl::Hidden);
122280031Sdim
123280031Sdimstatic cl::list<std::string>
124280031SdimSpecificSectionMappings("map-section",
125288943Sdim                        cl::desc("For -verify only: Map a section to a "
126288943Sdim                                 "specific address."),
127288943Sdim                        cl::ZeroOrMore,
128288943Sdim                        cl::Hidden);
129280031Sdim
130288943Sdimstatic cl::list<std::string>
131288943SdimDummySymbolMappings("dummy-extern",
132288943Sdim                    cl::desc("For -verify only: Inject a symbol into the extern "
133288943Sdim                             "symbol table."),
134288943Sdim                    cl::ZeroOrMore,
135288943Sdim                    cl::Hidden);
136288943Sdim
137296417Sdimstatic cl::opt<bool>
138296417SdimPrintAllocationRequests("print-alloc-requests",
139296417Sdim                        cl::desc("Print allocation requests made to the memory "
140296417Sdim                                 "manager by RuntimeDyld"),
141296417Sdim                        cl::Hidden);
142296417Sdim
143360784Sdimstatic cl::opt<bool> ShowTimes("show-times",
144360784Sdim                               cl::desc("Show times for llvm-rtdyld phases"),
145360784Sdim                               cl::init(false));
146360784Sdim
147353358SdimExitOnError ExitOnErr;
148353358Sdim
149360784Sdimstruct RTDyldTimers {
150360784Sdim  TimerGroup RTDyldTG{"llvm-rtdyld timers", "timers for llvm-rtdyld phases"};
151360784Sdim  Timer LoadObjectsTimer{"load", "time to load/add object files", RTDyldTG};
152360784Sdim  Timer LinkTimer{"link", "time to link object files", RTDyldTG};
153360784Sdim  Timer RunTimer{"run", "time to execute jitlink'd code", RTDyldTG};
154360784Sdim};
155360784Sdim
156360784Sdimstd::unique_ptr<RTDyldTimers> Timers;
157360784Sdim
158221337Sdim/* *** */
159221337Sdim
160353358Sdimusing SectionIDMap = StringMap<unsigned>;
161353358Sdimusing FileToSectionIDMap = StringMap<SectionIDMap>;
162353358Sdim
163353358Sdimvoid dumpFileToSectionIDMap(const FileToSectionIDMap &FileToSecIDMap) {
164353358Sdim  for (const auto &KV : FileToSecIDMap) {
165353358Sdim    llvm::dbgs() << "In " << KV.first() << "\n";
166353358Sdim    for (auto &KV2 : KV.second)
167353358Sdim      llvm::dbgs() << "  \"" << KV2.first() << "\" -> " << KV2.second << "\n";
168353358Sdim  }
169353358Sdim}
170353358Sdim
171353358SdimExpected<unsigned> getSectionId(const FileToSectionIDMap &FileToSecIDMap,
172353358Sdim                                StringRef FileName, StringRef SectionName) {
173353358Sdim  auto I = FileToSecIDMap.find(FileName);
174353358Sdim  if (I == FileToSecIDMap.end())
175353358Sdim    return make_error<StringError>("No file named " + FileName,
176353358Sdim                                   inconvertibleErrorCode());
177353358Sdim  auto &SectionIDs = I->second;
178353358Sdim  auto J = SectionIDs.find(SectionName);
179353358Sdim  if (J == SectionIDs.end())
180353358Sdim    return make_error<StringError>("No section named \"" + SectionName +
181353358Sdim                                   "\" in file " + FileName,
182353358Sdim                                   inconvertibleErrorCode());
183353358Sdim  return J->second;
184353358Sdim}
185353358Sdim
186221337Sdim// A trivial memory manager that doesn't do anything fancy, just uses the
187221337Sdim// support library allocation routines directly.
188221337Sdimclass TrivialMemoryManager : public RTDyldMemoryManager {
189221337Sdimpublic:
190353358Sdim  struct SectionInfo {
191353358Sdim    SectionInfo(StringRef Name, sys::MemoryBlock MB, unsigned SectionID)
192353358Sdim      : Name(Name), MB(std::move(MB)), SectionID(SectionID) {}
193353358Sdim    std::string Name;
194353358Sdim    sys::MemoryBlock MB;
195353358Sdim    unsigned SectionID = ~0U;
196353358Sdim  };
197221337Sdim
198353358Sdim  SmallVector<SectionInfo, 16> FunctionMemory;
199353358Sdim  SmallVector<SectionInfo, 16> DataMemory;
200353358Sdim
201234353Sdim  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
202276479Sdim                               unsigned SectionID,
203276479Sdim                               StringRef SectionName) override;
204234353Sdim  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
205261991Sdim                               unsigned SectionID, StringRef SectionName,
206276479Sdim                               bool IsReadOnly) override;
207234353Sdim
208353358Sdim  /// If non null, records subsequent Name -> SectionID mappings.
209353358Sdim  void setSectionIDsMap(SectionIDMap *SecIDMap) {
210353358Sdim    this->SecIDMap = SecIDMap;
211353358Sdim  }
212353358Sdim
213276479Sdim  void *getPointerToNamedFunction(const std::string &Name,
214276479Sdim                                  bool AbortOnFailure = true) override {
215276479Sdim    return nullptr;
216234353Sdim  }
217234353Sdim
218276479Sdim  bool finalizeMemory(std::string *ErrMsg) override { return false; }
219249423Sdim
220288943Sdim  void addDummySymbol(const std::string &Name, uint64_t Addr) {
221288943Sdim    DummyExterns[Name] = Addr;
222288943Sdim  }
223288943Sdim
224314564Sdim  JITSymbol findSymbol(const std::string &Name) override {
225288943Sdim    auto I = DummyExterns.find(Name);
226288943Sdim
227288943Sdim    if (I != DummyExterns.end())
228314564Sdim      return JITSymbol(I->second, JITSymbolFlags::Exported);
229288943Sdim
230353358Sdim    if (auto Sym = RTDyldMemoryManager::findSymbol(Name))
231353358Sdim      return Sym;
232353358Sdim    else if (auto Err = Sym.takeError())
233353358Sdim      ExitOnErr(std::move(Err));
234353358Sdim    else
235353358Sdim      ExitOnErr(make_error<StringError>("Could not find definition for \"" +
236353358Sdim                                            Name + "\"",
237353358Sdim                                        inconvertibleErrorCode()));
238353358Sdim    llvm_unreachable("Should have returned or exited by now");
239288943Sdim  }
240288943Sdim
241288943Sdim  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
242288943Sdim                        size_t Size) override {}
243321369Sdim  void deregisterEHFrames() override {}
244296417Sdim
245296417Sdim  void preallocateSlab(uint64_t Size) {
246327952Sdim    std::error_code EC;
247327952Sdim    sys::MemoryBlock MB =
248327952Sdim      sys::Memory::allocateMappedMemory(Size, nullptr,
249327952Sdim                                        sys::Memory::MF_READ |
250327952Sdim                                        sys::Memory::MF_WRITE,
251327952Sdim                                        EC);
252296417Sdim    if (!MB.base())
253327952Sdim      report_fatal_error("Can't allocate enough memory: " + EC.message());
254296417Sdim
255296417Sdim    PreallocSlab = MB;
256296417Sdim    UsePreallocation = true;
257296417Sdim    SlabSize = Size;
258296417Sdim  }
259296417Sdim
260353358Sdim  uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode,
261353358Sdim                            StringRef SectionName, unsigned SectionID) {
262309124Sdim    Size = alignTo(Size, Alignment);
263296417Sdim    if (CurrentSlabOffset + Size > SlabSize)
264296417Sdim      report_fatal_error("Can't allocate enough memory. Tune --preallocate");
265296417Sdim
266296417Sdim    uintptr_t OldSlabOffset = CurrentSlabOffset;
267296417Sdim    sys::MemoryBlock MB((void *)OldSlabOffset, Size);
268296417Sdim    if (isCode)
269353358Sdim      FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID));
270296417Sdim    else
271353358Sdim      DataMemory.push_back(SectionInfo(SectionName, MB, SectionID));
272296417Sdim    CurrentSlabOffset += Size;
273296417Sdim    return (uint8_t*)OldSlabOffset;
274296417Sdim  }
275296417Sdim
276288943Sdimprivate:
277288943Sdim  std::map<std::string, uint64_t> DummyExterns;
278296417Sdim  sys::MemoryBlock PreallocSlab;
279296417Sdim  bool UsePreallocation = false;
280296417Sdim  uintptr_t SlabSize = 0;
281296417Sdim  uintptr_t CurrentSlabOffset = 0;
282353358Sdim  SectionIDMap *SecIDMap = nullptr;
283221337Sdim};
284221337Sdim
285234353Sdimuint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
286234353Sdim                                                   unsigned Alignment,
287261991Sdim                                                   unsigned SectionID,
288261991Sdim                                                   StringRef SectionName) {
289296417Sdim  if (PrintAllocationRequests)
290296417Sdim    outs() << "allocateCodeSection(Size = " << Size << ", Alignment = "
291296417Sdim           << Alignment << ", SectionName = " << SectionName << ")\n";
292296417Sdim
293353358Sdim  if (SecIDMap)
294353358Sdim    (*SecIDMap)[SectionName] = SectionID;
295353358Sdim
296296417Sdim  if (UsePreallocation)
297353358Sdim    return allocateFromSlab(Size, Alignment, true /* isCode */,
298353358Sdim                            SectionName, SectionID);
299296417Sdim
300327952Sdim  std::error_code EC;
301327952Sdim  sys::MemoryBlock MB =
302327952Sdim    sys::Memory::allocateMappedMemory(Size, nullptr,
303327952Sdim                                      sys::Memory::MF_READ |
304327952Sdim                                      sys::Memory::MF_WRITE,
305327952Sdim                                      EC);
306296417Sdim  if (!MB.base())
307327952Sdim    report_fatal_error("MemoryManager allocation failed: " + EC.message());
308353358Sdim  FunctionMemory.push_back(SectionInfo(SectionName, MB, SectionID));
309239462Sdim  return (uint8_t*)MB.base();
310221337Sdim}
311221337Sdim
312234353Sdimuint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
313234353Sdim                                                   unsigned Alignment,
314249423Sdim                                                   unsigned SectionID,
315261991Sdim                                                   StringRef SectionName,
316249423Sdim                                                   bool IsReadOnly) {
317296417Sdim  if (PrintAllocationRequests)
318296417Sdim    outs() << "allocateDataSection(Size = " << Size << ", Alignment = "
319296417Sdim           << Alignment << ", SectionName = " << SectionName << ")\n";
320296417Sdim
321353358Sdim  if (SecIDMap)
322353358Sdim    (*SecIDMap)[SectionName] = SectionID;
323353358Sdim
324296417Sdim  if (UsePreallocation)
325353358Sdim    return allocateFromSlab(Size, Alignment, false /* isCode */, SectionName,
326353358Sdim                            SectionID);
327296417Sdim
328327952Sdim  std::error_code EC;
329327952Sdim  sys::MemoryBlock MB =
330327952Sdim    sys::Memory::allocateMappedMemory(Size, nullptr,
331327952Sdim                                      sys::Memory::MF_READ |
332327952Sdim                                      sys::Memory::MF_WRITE,
333327952Sdim                                      EC);
334296417Sdim  if (!MB.base())
335327952Sdim    report_fatal_error("MemoryManager allocation failed: " + EC.message());
336353358Sdim  DataMemory.push_back(SectionInfo(SectionName, MB, SectionID));
337239462Sdim  return (uint8_t*)MB.base();
338221337Sdim}
339221337Sdim
340221337Sdimstatic const char *ProgramName;
341221337Sdim
342309124Sdimstatic void ErrorAndExit(const Twine &Msg) {
343296417Sdim  errs() << ProgramName << ": error: " << Msg << "\n";
344309124Sdim  exit(1);
345221337Sdim}
346221337Sdim
347276479Sdimstatic void loadDylibs() {
348276479Sdim  for (const std::string &Dylib : Dylibs) {
349296417Sdim    if (!sys::fs::is_regular_file(Dylib))
350296417Sdim      report_fatal_error("Dylib not found: '" + Dylib + "'.");
351296417Sdim    std::string ErrMsg;
352296417Sdim    if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg))
353296417Sdim      report_fatal_error("Error loading '" + Dylib + "': " + ErrMsg);
354276479Sdim  }
355276479Sdim}
356276479Sdim
357221337Sdim/* *** */
358221337Sdim
359288943Sdimstatic int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
360288943Sdim  assert(LoadObjects || !UseDebugObj);
361288943Sdim
362276479Sdim  // Load any dylibs requested on the command line.
363276479Sdim  loadDylibs();
364276479Sdim
365249423Sdim  // If we don't have any input files, read from stdin.
366249423Sdim  if (!InputFileList.size())
367249423Sdim    InputFileList.push_back("-");
368296417Sdim  for (auto &File : InputFileList) {
369249423Sdim    // Instantiate a dynamic linker.
370261991Sdim    TrivialMemoryManager MemMgr;
371288943Sdim    RuntimeDyld Dyld(MemMgr, MemMgr);
372249423Sdim
373249423Sdim    // Load the input memory buffer.
374249423Sdim
375276479Sdim    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
376296417Sdim        MemoryBuffer::getFileOrSTDIN(File);
377276479Sdim    if (std::error_code EC = InputBuffer.getError())
378309124Sdim      ErrorAndExit("unable to read input: '" + EC.message() + "'");
379276479Sdim
380309124Sdim    Expected<std::unique_ptr<ObjectFile>> MaybeObj(
381280031Sdim      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
382280031Sdim
383309124Sdim    if (!MaybeObj) {
384309124Sdim      std::string Buf;
385309124Sdim      raw_string_ostream OS(Buf);
386344779Sdim      logAllUnhandledErrors(MaybeObj.takeError(), OS);
387309124Sdim      OS.flush();
388309124Sdim      ErrorAndExit("unable to create object file: '" + Buf + "'");
389309124Sdim    }
390280031Sdim
391280031Sdim    ObjectFile &Obj = **MaybeObj;
392280031Sdim
393288943Sdim    OwningBinary<ObjectFile> DebugObj;
394288943Sdim    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr;
395288943Sdim    ObjectFile *SymbolObj = &Obj;
396288943Sdim    if (LoadObjects) {
397288943Sdim      // Load the object file
398288943Sdim      LoadedObjInfo =
399288943Sdim        Dyld.loadObject(Obj);
400280031Sdim
401288943Sdim      if (Dyld.hasError())
402309124Sdim        ErrorAndExit(Dyld.getErrorString());
403249423Sdim
404288943Sdim      // Resolve all the relocations we can.
405288943Sdim      Dyld.resolveRelocations();
406249423Sdim
407288943Sdim      if (UseDebugObj) {
408288943Sdim        DebugObj = LoadedObjInfo->getObjectForDebug(Obj);
409288943Sdim        SymbolObj = DebugObj.getBinary();
410296417Sdim        LoadedObjInfo.reset();
411288943Sdim      }
412288943Sdim    }
413280031Sdim
414327952Sdim    std::unique_ptr<DIContext> Context =
415327952Sdim        DWARFContext::create(*SymbolObj, LoadedObjInfo.get());
416249423Sdim
417288943Sdim    std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
418288943Sdim        object::computeSymbolSizes(*SymbolObj);
419288943Sdim
420249423Sdim    // Use symbol info to iterate functions in the object.
421288943Sdim    for (const auto &P : SymAddr) {
422288943Sdim      object::SymbolRef Sym = P.first;
423309124Sdim      Expected<SymbolRef::Type> TypeOrErr = Sym.getType();
424309124Sdim      if (!TypeOrErr) {
425309124Sdim        // TODO: Actually report errors helpfully.
426309124Sdim        consumeError(TypeOrErr.takeError());
427309124Sdim        continue;
428309124Sdim      }
429309124Sdim      SymbolRef::Type Type = *TypeOrErr;
430309124Sdim      if (Type == object::SymbolRef::ST_Function) {
431309124Sdim        Expected<StringRef> Name = Sym.getName();
432309124Sdim        if (!Name) {
433309124Sdim          // TODO: Actually report errors helpfully.
434309124Sdim          consumeError(Name.takeError());
435288943Sdim          continue;
436309124Sdim        }
437309124Sdim        Expected<uint64_t> AddrOrErr = Sym.getAddress();
438309124Sdim        if (!AddrOrErr) {
439309124Sdim          // TODO: Actually report errors helpfully.
440309124Sdim          consumeError(AddrOrErr.takeError());
441288943Sdim          continue;
442309124Sdim        }
443288943Sdim        uint64_t Addr = *AddrOrErr;
444249423Sdim
445353358Sdim        object::SectionedAddress Address;
446353358Sdim
447288943Sdim        uint64_t Size = P.second;
448288943Sdim        // If we're not using the debug object, compute the address of the
449288943Sdim        // symbol in memory (rather than that in the unrelocated object file)
450288943Sdim        // and use that to query the DWARFContext.
451288943Sdim        if (!UseDebugObj && LoadObjects) {
452309124Sdim          auto SecOrErr = Sym.getSection();
453309124Sdim          if (!SecOrErr) {
454309124Sdim            // TODO: Actually report errors helpfully.
455309124Sdim            consumeError(SecOrErr.takeError());
456309124Sdim            continue;
457309124Sdim          }
458309124Sdim          object::section_iterator Sec = *SecOrErr;
459353358Sdim          Address.SectionIndex = Sec->getIndex();
460288943Sdim          uint64_t SectionLoadAddress =
461296417Sdim            LoadedObjInfo->getSectionLoadAddress(*Sec);
462288943Sdim          if (SectionLoadAddress != 0)
463288943Sdim            Addr += SectionLoadAddress - Sec->getAddress();
464353358Sdim        } else if (auto SecOrErr = Sym.getSection())
465353358Sdim          Address.SectionIndex = SecOrErr.get()->getIndex();
466249423Sdim
467288943Sdim        outs() << "Function: " << *Name << ", Size = " << Size
468288943Sdim               << ", Addr = " << Addr << "\n";
469288943Sdim
470353358Sdim        Address.Address = Addr;
471353358Sdim        DILineInfoTable Lines =
472353358Sdim            Context->getLineInfoForAddressRange(Address, Size);
473296417Sdim        for (auto &D : Lines) {
474296417Sdim          outs() << "  Line info @ " << D.first - Addr << ": "
475296417Sdim                 << D.second.FileName << ", line:" << D.second.Line << "\n";
476249423Sdim        }
477249423Sdim      }
478249423Sdim    }
479249423Sdim  }
480249423Sdim
481249423Sdim  return 0;
482249423Sdim}
483249423Sdim
484296417Sdimstatic void doPreallocation(TrivialMemoryManager &MemMgr) {
485296417Sdim  // Allocate a slab of memory upfront, if required. This is used if
486296417Sdim  // we want to test small code models.
487296417Sdim  if (static_cast<intptr_t>(PreallocMemory) < 0)
488296417Sdim    report_fatal_error("Pre-allocated bytes of memory must be a positive integer.");
489296417Sdim
490296417Sdim  // FIXME: Limit the amount of memory that can be preallocated?
491296417Sdim  if (PreallocMemory != 0)
492296417Sdim    MemMgr.preallocateSlab(PreallocMemory);
493296417Sdim}
494296417Sdim
495221337Sdimstatic int executeInput() {
496276479Sdim  // Load any dylibs requested on the command line.
497276479Sdim  loadDylibs();
498276479Sdim
499221337Sdim  // Instantiate a dynamic linker.
500261991Sdim  TrivialMemoryManager MemMgr;
501296417Sdim  doPreallocation(MemMgr);
502288943Sdim  RuntimeDyld Dyld(MemMgr, MemMgr);
503221337Sdim
504221337Sdim  // If we don't have any input files, read from stdin.
505221337Sdim  if (!InputFileList.size())
506221337Sdim    InputFileList.push_back("-");
507360784Sdim  {
508360784Sdim    TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
509360784Sdim    for (auto &File : InputFileList) {
510360784Sdim      // Load the input memory buffer.
511360784Sdim      ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
512360784Sdim          MemoryBuffer::getFileOrSTDIN(File);
513360784Sdim      if (std::error_code EC = InputBuffer.getError())
514360784Sdim        ErrorAndExit("unable to read input: '" + EC.message() + "'");
515360784Sdim      Expected<std::unique_ptr<ObjectFile>> MaybeObj(
516360784Sdim          ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
517280031Sdim
518360784Sdim      if (!MaybeObj) {
519360784Sdim        std::string Buf;
520360784Sdim        raw_string_ostream OS(Buf);
521360784Sdim        logAllUnhandledErrors(MaybeObj.takeError(), OS);
522360784Sdim        OS.flush();
523360784Sdim        ErrorAndExit("unable to create object file: '" + Buf + "'");
524360784Sdim      }
525280031Sdim
526360784Sdim      ObjectFile &Obj = **MaybeObj;
527280031Sdim
528360784Sdim      // Load the object file
529360784Sdim      Dyld.loadObject(Obj);
530360784Sdim      if (Dyld.hasError()) {
531360784Sdim        ErrorAndExit(Dyld.getErrorString());
532360784Sdim      }
533221337Sdim    }
534221337Sdim  }
535221337Sdim
536360784Sdim  {
537360784Sdim    TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);
538360784Sdim    // Resove all the relocations we can.
539360784Sdim    // FIXME: Error out if there are unresolved relocations.
540360784Sdim    Dyld.resolveRelocations();
541360784Sdim  }
542221337Sdim
543221337Sdim  // Get the address of the entry point (_main by default).
544288943Sdim  void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint);
545276479Sdim  if (!MainAddress)
546309124Sdim    ErrorAndExit("no definition for '" + EntryPoint + "'");
547221337Sdim
548221337Sdim  // Invalidate the instruction cache for each loaded function.
549296417Sdim  for (auto &FM : MemMgr.FunctionMemory) {
550296417Sdim
551353358Sdim    auto &FM_MB = FM.MB;
552353358Sdim
553221337Sdim    // Make sure the memory is executable.
554296417Sdim    // setExecutable will call InvalidateInstructionCache.
555353358Sdim    if (auto EC = sys::Memory::protectMappedMemory(FM_MB,
556327952Sdim                                                   sys::Memory::MF_READ |
557327952Sdim                                                   sys::Memory::MF_EXEC))
558327952Sdim      ErrorAndExit("unable to mark function executable: '" + EC.message() +
559327952Sdim                   "'");
560221337Sdim  }
561221337Sdim
562221337Sdim  // Dispatch to _main().
563221337Sdim  errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n";
564221337Sdim
565221337Sdim  int (*Main)(int, const char**) =
566221337Sdim    (int(*)(int,const char**)) uintptr_t(MainAddress);
567353358Sdim  std::vector<const char *> Argv;
568221337Sdim  // Use the name of the first input object module as argv[0] for the target.
569353358Sdim  Argv.push_back(InputFileList[0].data());
570353358Sdim  for (auto &Arg : InputArgv)
571353358Sdim    Argv.push_back(Arg.data());
572353358Sdim  Argv.push_back(nullptr);
573360784Sdim  int Result = 0;
574360784Sdim  {
575360784Sdim    TimeRegion TR(Timers ? &Timers->RunTimer : nullptr);
576360784Sdim    Result = Main(Argv.size() - 1, Argv.data());
577360784Sdim  }
578360784Sdim
579360784Sdim  return Result;
580221337Sdim}
581221337Sdim
582276479Sdimstatic int checkAllExpressions(RuntimeDyldChecker &Checker) {
583276479Sdim  for (const auto& CheckerFileName : CheckFiles) {
584276479Sdim    ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf =
585276479Sdim        MemoryBuffer::getFileOrSTDIN(CheckerFileName);
586276479Sdim    if (std::error_code EC = CheckerFileBuf.getError())
587309124Sdim      ErrorAndExit("unable to read input '" + CheckerFileName + "': " +
588276479Sdim                   EC.message());
589276479Sdim
590276479Sdim    if (!Checker.checkAllRulesInBuffer("# rtdyld-check:",
591276479Sdim                                       CheckerFileBuf.get().get()))
592309124Sdim      ErrorAndExit("some checks in '" + CheckerFileName + "' failed");
593276479Sdim  }
594276479Sdim  return 0;
595276479Sdim}
596276479Sdim
597353358Sdimvoid applySpecificSectionMappings(RuntimeDyld &Dyld,
598353358Sdim                                  const FileToSectionIDMap &FileToSecIDMap) {
599280031Sdim
600280031Sdim  for (StringRef Mapping : SpecificSectionMappings) {
601280031Sdim    size_t EqualsIdx = Mapping.find_first_of("=");
602288943Sdim    std::string SectionIDStr = Mapping.substr(0, EqualsIdx);
603280031Sdim    size_t ComaIdx = Mapping.find_first_of(",");
604280031Sdim
605296417Sdim    if (ComaIdx == StringRef::npos)
606296417Sdim      report_fatal_error("Invalid section specification '" + Mapping +
607296417Sdim                         "'. Should be '<file name>,<section name>=<addr>'");
608280031Sdim
609288943Sdim    std::string FileName = SectionIDStr.substr(0, ComaIdx);
610288943Sdim    std::string SectionName = SectionIDStr.substr(ComaIdx + 1);
611353358Sdim    unsigned SectionID =
612353358Sdim      ExitOnErr(getSectionId(FileToSecIDMap, FileName, SectionName));
613280031Sdim
614353358Sdim    auto* OldAddr = Dyld.getSectionContent(SectionID).data();
615288943Sdim    std::string NewAddrStr = Mapping.substr(EqualsIdx + 1);
616280031Sdim    uint64_t NewAddr;
617280031Sdim
618296417Sdim    if (StringRef(NewAddrStr).getAsInteger(0, NewAddr))
619296417Sdim      report_fatal_error("Invalid section address in mapping '" + Mapping +
620296417Sdim                         "'.");
621280031Sdim
622353358Sdim    Dyld.mapSectionAddress(OldAddr, NewAddr);
623280031Sdim  }
624280031Sdim}
625280031Sdim
626280031Sdim// Scatter sections in all directions!
627280031Sdim// Remaps section addresses for -verify mode. The following command line options
628280031Sdim// can be used to customize the layout of the memory within the phony target's
629280031Sdim// address space:
630314564Sdim// -target-addr-start <s> -- Specify where the phony target address range starts.
631280031Sdim// -target-addr-end   <e> -- Specify where the phony target address range ends.
632280031Sdim// -target-section-sep <d> -- Specify how big a gap should be left between the
633280031Sdim//                            end of one section and the start of the next.
634280031Sdim//                            Defaults to zero. Set to something big
635280031Sdim//                            (e.g. 1 << 32) to stress-test stubs, GOTs, etc.
636280031Sdim//
637288943Sdimstatic void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
638353358Sdim                                    RuntimeDyld &Dyld,
639353358Sdim                                    TrivialMemoryManager &MemMgr) {
640280031Sdim
641280031Sdim  // Set up a work list (section addr/size pairs).
642353358Sdim  typedef std::list<const TrivialMemoryManager::SectionInfo*> WorklistT;
643280031Sdim  WorklistT Worklist;
644280031Sdim
645280031Sdim  for (const auto& CodeSection : MemMgr.FunctionMemory)
646353358Sdim    Worklist.push_back(&CodeSection);
647280031Sdim  for (const auto& DataSection : MemMgr.DataMemory)
648353358Sdim    Worklist.push_back(&DataSection);
649280031Sdim
650280031Sdim  // Keep an "already allocated" mapping of section target addresses to sizes.
651280031Sdim  // Sections whose address mappings aren't specified on the command line will
652280031Sdim  // allocated around the explicitly mapped sections while maintaining the
653280031Sdim  // minimum separation.
654280031Sdim  std::map<uint64_t, uint64_t> AlreadyAllocated;
655280031Sdim
656321369Sdim  // Move the previously applied mappings (whether explicitly specified on the
657321369Sdim  // command line, or implicitly set by RuntimeDyld) into the already-allocated
658321369Sdim  // map.
659280031Sdim  for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end();
660280031Sdim       I != E;) {
661280031Sdim    WorklistT::iterator Tmp = I;
662280031Sdim    ++I;
663280031Sdim
664353358Sdim    auto LoadAddr = Dyld.getSectionLoadAddress((*Tmp)->SectionID);
665353358Sdim
666353358Sdim    if (LoadAddr != static_cast<uint64_t>(
667353358Sdim          reinterpret_cast<uintptr_t>((*Tmp)->MB.base()))) {
668344779Sdim      // A section will have a LoadAddr of 0 if it wasn't loaded for whatever
669344779Sdim      // reason (e.g. zero byte COFF sections). Don't include those sections in
670344779Sdim      // the allocation map.
671353358Sdim      if (LoadAddr != 0)
672353358Sdim        AlreadyAllocated[LoadAddr] = (*Tmp)->MB.allocatedSize();
673280031Sdim      Worklist.erase(Tmp);
674280031Sdim    }
675280031Sdim  }
676280031Sdim
677280031Sdim  // If the -target-addr-end option wasn't explicitly passed, then set it to a
678280031Sdim  // sensible default based on the target triple.
679280031Sdim  if (TargetAddrEnd.getNumOccurrences() == 0) {
680280031Sdim    if (TargetTriple.isArch16Bit())
681280031Sdim      TargetAddrEnd = (1ULL << 16) - 1;
682280031Sdim    else if (TargetTriple.isArch32Bit())
683280031Sdim      TargetAddrEnd = (1ULL << 32) - 1;
684280031Sdim    // TargetAddrEnd already has a sensible default for 64-bit systems, so
685280031Sdim    // there's nothing to do in the 64-bit case.
686280031Sdim  }
687280031Sdim
688280031Sdim  // Process any elements remaining in the worklist.
689280031Sdim  while (!Worklist.empty()) {
690353358Sdim    auto *CurEntry = Worklist.front();
691280031Sdim    Worklist.pop_front();
692280031Sdim
693280031Sdim    uint64_t NextSectionAddr = TargetAddrStart;
694280031Sdim
695280031Sdim    for (const auto &Alloc : AlreadyAllocated)
696353358Sdim      if (NextSectionAddr + CurEntry->MB.allocatedSize() + TargetSectionSep <=
697353358Sdim          Alloc.first)
698280031Sdim        break;
699280031Sdim      else
700280031Sdim        NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep;
701280031Sdim
702353358Sdim    Dyld.mapSectionAddress(CurEntry->MB.base(), NextSectionAddr);
703353358Sdim    AlreadyAllocated[NextSectionAddr] = CurEntry->MB.allocatedSize();
704280031Sdim  }
705280031Sdim
706288943Sdim  // Add dummy symbols to the memory manager.
707288943Sdim  for (const auto &Mapping : DummySymbolMappings) {
708314564Sdim    size_t EqualsIdx = Mapping.find_first_of('=');
709288943Sdim
710296417Sdim    if (EqualsIdx == StringRef::npos)
711296417Sdim      report_fatal_error("Invalid dummy symbol specification '" + Mapping +
712296417Sdim                         "'. Should be '<symbol name>=<addr>'");
713288943Sdim
714288943Sdim    std::string Symbol = Mapping.substr(0, EqualsIdx);
715288943Sdim    std::string AddrStr = Mapping.substr(EqualsIdx + 1);
716288943Sdim
717288943Sdim    uint64_t Addr;
718296417Sdim    if (StringRef(AddrStr).getAsInteger(0, Addr))
719296417Sdim      report_fatal_error("Invalid symbol mapping '" + Mapping + "'.");
720288943Sdim
721288943Sdim    MemMgr.addDummySymbol(Symbol, Addr);
722288943Sdim  }
723280031Sdim}
724280031Sdim
725280031Sdim// Load and link the objects specified on the command line, but do not execute
726280031Sdim// anything. Instead, attach a RuntimeDyldChecker instance and call it to
727280031Sdim// verify the correctness of the linked memory.
728276479Sdimstatic int linkAndVerify() {
729276479Sdim
730276479Sdim  // Check for missing triple.
731296417Sdim  if (TripleName == "")
732309124Sdim    ErrorAndExit("-triple required when running in -verify mode.");
733276479Sdim
734276479Sdim  // Look up the target and build the disassembler.
735276479Sdim  Triple TheTriple(Triple::normalize(TripleName));
736276479Sdim  std::string ErrorStr;
737276479Sdim  const Target *TheTarget =
738276479Sdim    TargetRegistry::lookupTarget("", TheTriple, ErrorStr);
739296417Sdim  if (!TheTarget)
740309124Sdim    ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr);
741296417Sdim
742276479Sdim  TripleName = TheTriple.getTriple();
743276479Sdim
744276479Sdim  std::unique_ptr<MCSubtargetInfo> STI(
745288943Sdim    TheTarget->createMCSubtargetInfo(TripleName, MCPU, ""));
746296417Sdim  if (!STI)
747309124Sdim    ErrorAndExit("Unable to create subtarget info!");
748276479Sdim
749276479Sdim  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
750296417Sdim  if (!MRI)
751309124Sdim    ErrorAndExit("Unable to create target register info!");
752276479Sdim
753360784Sdim  MCTargetOptions MCOptions;
754360784Sdim  std::unique_ptr<MCAsmInfo> MAI(
755360784Sdim      TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
756296417Sdim  if (!MAI)
757309124Sdim    ErrorAndExit("Unable to create target asm info!");
758276479Sdim
759276479Sdim  MCContext Ctx(MAI.get(), MRI.get(), nullptr);
760276479Sdim
761276479Sdim  std::unique_ptr<MCDisassembler> Disassembler(
762276479Sdim    TheTarget->createMCDisassembler(*STI, Ctx));
763296417Sdim  if (!Disassembler)
764309124Sdim    ErrorAndExit("Unable to create disassembler!");
765276479Sdim
766276479Sdim  std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
767276479Sdim
768276479Sdim  std::unique_ptr<MCInstPrinter> InstPrinter(
769288943Sdim      TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI));
770276479Sdim
771276479Sdim  // Load any dylibs requested on the command line.
772276479Sdim  loadDylibs();
773276479Sdim
774276479Sdim  // Instantiate a dynamic linker.
775276479Sdim  TrivialMemoryManager MemMgr;
776296417Sdim  doPreallocation(MemMgr);
777353358Sdim
778353358Sdim  struct StubID {
779353358Sdim    unsigned SectionID;
780353358Sdim    uint32_t Offset;
781353358Sdim  };
782353358Sdim  using StubInfos = StringMap<StubID>;
783353358Sdim  using StubContainers = StringMap<StubInfos>;
784353358Sdim
785353358Sdim  StubContainers StubMap;
786288943Sdim  RuntimeDyld Dyld(MemMgr, MemMgr);
787280031Sdim  Dyld.setProcessAllSections(true);
788276479Sdim
789353358Sdim  Dyld.setNotifyStubEmitted([&StubMap](StringRef FilePath,
790353358Sdim                                       StringRef SectionName,
791353358Sdim                                       StringRef SymbolName, unsigned SectionID,
792353358Sdim                                       uint32_t StubOffset) {
793353358Sdim    std::string ContainerName =
794353358Sdim        (sys::path::filename(FilePath) + "/" + SectionName).str();
795353358Sdim    StubMap[ContainerName][SymbolName] = {SectionID, StubOffset};
796353358Sdim  });
797353358Sdim
798353358Sdim  auto GetSymbolInfo =
799353358Sdim      [&Dyld, &MemMgr](
800353358Sdim          StringRef Symbol) -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
801353358Sdim    RuntimeDyldChecker::MemoryRegionInfo SymInfo;
802353358Sdim
803353358Sdim    // First get the target address.
804353358Sdim    if (auto InternalSymbol = Dyld.getSymbol(Symbol))
805353358Sdim      SymInfo.setTargetAddress(InternalSymbol.getAddress());
806353358Sdim    else {
807353358Sdim      // Symbol not found in RuntimeDyld. Fall back to external lookup.
808353358Sdim#ifdef _MSC_VER
809353358Sdim      using ExpectedLookupResult =
810353358Sdim          MSVCPExpected<JITSymbolResolver::LookupResult>;
811353358Sdim#else
812353358Sdim      using ExpectedLookupResult = Expected<JITSymbolResolver::LookupResult>;
813353358Sdim#endif
814353358Sdim
815353358Sdim      auto ResultP = std::make_shared<std::promise<ExpectedLookupResult>>();
816353358Sdim      auto ResultF = ResultP->get_future();
817353358Sdim
818353358Sdim      MemMgr.lookup(JITSymbolResolver::LookupSet({Symbol}),
819353358Sdim                    [=](Expected<JITSymbolResolver::LookupResult> Result) {
820353358Sdim                      ResultP->set_value(std::move(Result));
821353358Sdim                    });
822353358Sdim
823353358Sdim      auto Result = ResultF.get();
824353358Sdim      if (!Result)
825353358Sdim        return Result.takeError();
826353358Sdim
827353358Sdim      auto I = Result->find(Symbol);
828353358Sdim      assert(I != Result->end() &&
829353358Sdim             "Expected symbol address if no error occurred");
830353358Sdim      SymInfo.setTargetAddress(I->second.getAddress());
831353358Sdim    }
832353358Sdim
833353358Sdim    // Now find the symbol content if possible (otherwise leave content as a
834353358Sdim    // default-constructed StringRef).
835353358Sdim    if (auto *SymAddr = Dyld.getSymbolLocalAddress(Symbol)) {
836353358Sdim      unsigned SectionID = Dyld.getSymbolSectionID(Symbol);
837353358Sdim      if (SectionID != ~0U) {
838353358Sdim        char *CSymAddr = static_cast<char *>(SymAddr);
839353358Sdim        StringRef SecContent = Dyld.getSectionContent(SectionID);
840353358Sdim        uint64_t SymSize = SecContent.size() - (CSymAddr - SecContent.data());
841353358Sdim        SymInfo.setContent(StringRef(CSymAddr, SymSize));
842353358Sdim      }
843353358Sdim    }
844353358Sdim    return SymInfo;
845353358Sdim  };
846353358Sdim
847353358Sdim  auto IsSymbolValid = [&Dyld, GetSymbolInfo](StringRef Symbol) {
848353358Sdim    if (Dyld.getSymbol(Symbol))
849353358Sdim      return true;
850353358Sdim    auto SymInfo = GetSymbolInfo(Symbol);
851353358Sdim    if (!SymInfo) {
852353358Sdim      logAllUnhandledErrors(SymInfo.takeError(), errs(), "RTDyldChecker: ");
853353358Sdim      return false;
854353358Sdim    }
855353358Sdim    return SymInfo->getTargetAddress() != 0;
856353358Sdim  };
857353358Sdim
858353358Sdim  FileToSectionIDMap FileToSecIDMap;
859353358Sdim
860353358Sdim  auto GetSectionInfo = [&Dyld, &FileToSecIDMap](StringRef FileName,
861353358Sdim                                                 StringRef SectionName)
862353358Sdim      -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
863353358Sdim    auto SectionID = getSectionId(FileToSecIDMap, FileName, SectionName);
864353358Sdim    if (!SectionID)
865353358Sdim      return SectionID.takeError();
866353358Sdim    RuntimeDyldChecker::MemoryRegionInfo SecInfo;
867353358Sdim    SecInfo.setTargetAddress(Dyld.getSectionLoadAddress(*SectionID));
868353358Sdim    SecInfo.setContent(Dyld.getSectionContent(*SectionID));
869353358Sdim    return SecInfo;
870353358Sdim  };
871353358Sdim
872353358Sdim  auto GetStubInfo = [&Dyld, &StubMap](StringRef StubContainer,
873353358Sdim                                       StringRef SymbolName)
874353358Sdim      -> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
875353358Sdim    if (!StubMap.count(StubContainer))
876353358Sdim      return make_error<StringError>("Stub container not found: " +
877353358Sdim                                         StubContainer,
878353358Sdim                                     inconvertibleErrorCode());
879353358Sdim    if (!StubMap[StubContainer].count(SymbolName))
880353358Sdim      return make_error<StringError>("Symbol name " + SymbolName +
881353358Sdim                                         " in stub container " + StubContainer,
882353358Sdim                                     inconvertibleErrorCode());
883353358Sdim    auto &SI = StubMap[StubContainer][SymbolName];
884353358Sdim    RuntimeDyldChecker::MemoryRegionInfo StubMemInfo;
885353358Sdim    StubMemInfo.setTargetAddress(Dyld.getSectionLoadAddress(SI.SectionID) +
886353358Sdim                                 SI.Offset);
887353358Sdim    StubMemInfo.setContent(
888353358Sdim        Dyld.getSectionContent(SI.SectionID).substr(SI.Offset));
889353358Sdim    return StubMemInfo;
890353358Sdim  };
891353358Sdim
892353358Sdim  // We will initialize this below once we have the first object file and can
893353358Sdim  // know the endianness.
894353358Sdim  std::unique_ptr<RuntimeDyldChecker> Checker;
895353358Sdim
896276479Sdim  // If we don't have any input files, read from stdin.
897276479Sdim  if (!InputFileList.size())
898276479Sdim    InputFileList.push_back("-");
899353358Sdim  for (auto &InputFile : InputFileList) {
900276479Sdim    // Load the input memory buffer.
901276479Sdim    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
902353358Sdim        MemoryBuffer::getFileOrSTDIN(InputFile);
903280031Sdim
904276479Sdim    if (std::error_code EC = InputBuffer.getError())
905309124Sdim      ErrorAndExit("unable to read input: '" + EC.message() + "'");
906276479Sdim
907309124Sdim    Expected<std::unique_ptr<ObjectFile>> MaybeObj(
908280031Sdim      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
909280031Sdim
910309124Sdim    if (!MaybeObj) {
911309124Sdim      std::string Buf;
912309124Sdim      raw_string_ostream OS(Buf);
913344779Sdim      logAllUnhandledErrors(MaybeObj.takeError(), OS);
914309124Sdim      OS.flush();
915309124Sdim      ErrorAndExit("unable to create object file: '" + Buf + "'");
916309124Sdim    }
917280031Sdim
918280031Sdim    ObjectFile &Obj = **MaybeObj;
919280031Sdim
920353358Sdim    if (!Checker)
921360784Sdim      Checker = std::make_unique<RuntimeDyldChecker>(
922353358Sdim          IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo,
923353358Sdim          GetStubInfo, Obj.isLittleEndian() ? support::little : support::big,
924353358Sdim          Disassembler.get(), InstPrinter.get(), dbgs());
925353358Sdim
926353358Sdim    auto FileName = sys::path::filename(InputFile);
927353358Sdim    MemMgr.setSectionIDsMap(&FileToSecIDMap[FileName]);
928353358Sdim
929276479Sdim    // Load the object file
930280031Sdim    Dyld.loadObject(Obj);
931280031Sdim    if (Dyld.hasError()) {
932309124Sdim      ErrorAndExit(Dyld.getErrorString());
933276479Sdim    }
934276479Sdim  }
935276479Sdim
936288943Sdim  // Re-map the section addresses into the phony target address space and add
937288943Sdim  // dummy symbols.
938353358Sdim  applySpecificSectionMappings(Dyld, FileToSecIDMap);
939353358Sdim  remapSectionsAndSymbols(TheTriple, Dyld, MemMgr);
940280031Sdim
941276479Sdim  // Resolve all the relocations we can.
942276479Sdim  Dyld.resolveRelocations();
943276479Sdim
944280031Sdim  // Register EH frames.
945280031Sdim  Dyld.registerEHFrames();
946280031Sdim
947353358Sdim  int ErrorCode = checkAllExpressions(*Checker);
948296417Sdim  if (Dyld.hasError())
949309124Sdim    ErrorAndExit("RTDyld reported an error applying relocations:\n  " +
950296417Sdim                 Dyld.getErrorString());
951280031Sdim
952280031Sdim  return ErrorCode;
953276479Sdim}
954276479Sdim
955221337Sdimint main(int argc, char **argv) {
956341825Sdim  InitLLVM X(argc, argv);
957221337Sdim  ProgramName = argv[0];
958221337Sdim
959276479Sdim  llvm::InitializeAllTargetInfos();
960276479Sdim  llvm::InitializeAllTargetMCs();
961276479Sdim  llvm::InitializeAllDisassemblers();
962276479Sdim
963221337Sdim  cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n");
964221337Sdim
965353358Sdim  ExitOnErr.setBanner(std::string(argv[0]) + ": ");
966353358Sdim
967360784Sdim  Timers = ShowTimes ? std::make_unique<RTDyldTimers>() : nullptr;
968360784Sdim
969360784Sdim  int Result;
970221337Sdim  switch (Action) {
971221337Sdim  case AC_Execute:
972360784Sdim    Result = executeInput();
973360784Sdim    break;
974288943Sdim  case AC_PrintDebugLineInfo:
975360784Sdim    Result =
976360784Sdim        printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ true);
977360784Sdim    break;
978249423Sdim  case AC_PrintLineInfo:
979360784Sdim    Result =
980360784Sdim        printLineInfoForInput(/* LoadObjects */ true, /* UseDebugObj */ false);
981360784Sdim    break;
982288943Sdim  case AC_PrintObjectLineInfo:
983360784Sdim    Result =
984360784Sdim        printLineInfoForInput(/* LoadObjects */ false, /* UseDebugObj */ false);
985360784Sdim    break;
986276479Sdim  case AC_Verify:
987360784Sdim    Result = linkAndVerify();
988360784Sdim    break;
989221337Sdim  }
990360784Sdim  return Result;
991221337Sdim}
992