11cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===//
21cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//
31cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//                     The LLVM Compiler Infrastructure
41cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//
51cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// This file is distributed under the University of Illinois Open Source
61cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// License. See LICENSE.TXT for details.
71cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//
81cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//===----------------------------------------------------------------------===//
91cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//
101cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach// This is a testing tool for use with the MC-JIT LLVM components.
111cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//
121cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach//===----------------------------------------------------------------------===//
131cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
14f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/StringMap.h"
156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/DebugInfo/DIContext.h"
166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/DebugInfo/DWARF/DWARFContext.h"
170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
18f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ExecutionEngine/RuntimeDyld.h"
19c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
20c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCAsmInfo.h"
21c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCContext.h"
22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/MC/MCDisassembler/MCDisassembler.h"
23c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCInstPrinter.h"
24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/MC/MCInstrInfo.h"
25c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/MCRegisterInfo.h"
266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCSubtargetInfo.h"
272173e1839c2d00f7f980450dd537047b7b376e6bRafael Espindola#include "llvm/Object/MachO.h"
28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Object/SymbolSize.h"
291cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach#include "llvm/Support/CommandLine.h"
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/DynamicLibrary.h"
311cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach#include "llvm/Support/ManagedStatic.h"
321cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach#include "llvm/Support/Memory.h"
331cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach#include "llvm/Support/MemoryBuffer.h"
344d6b695c953462c3317e3a7eb57d0534db858ac2Alp Toker#include "llvm/Support/PrettyStackTrace.h"
35c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/Signals.h"
36c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/TargetRegistry.h"
37c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/Support/TargetSelect.h"
38ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/raw_ostream.h"
3937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include <list>
40c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error>
41c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
421cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachusing namespace llvm;
431cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachusing namespace llvm::object;
441cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
454f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbachstatic cl::list<std::string>
464f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim GrosbachInputFileList(cl::Positional, cl::ZeroOrMore,
474f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach              cl::desc("<input file>"));
481cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
491cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachenum ActionType {
50ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor  AC_Execute,
516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  AC_PrintObjectLineInfo,
52c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  AC_PrintLineInfo,
536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  AC_PrintDebugLineInfo,
54c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  AC_Verify
551cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach};
561cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
571cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachstatic cl::opt<ActionType>
581cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim GrosbachAction(cl::desc("Action to perform:"),
591cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach       cl::init(AC_Execute),
601cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach       cl::values(clEnumValN(AC_Execute, "execute",
611cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach                             "Load, link, and execute the inputs."),
62ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor                  clEnumValN(AC_PrintLineInfo, "printline",
63ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor                             "Load, link, and print line information for each function."),
646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                  clEnumValN(AC_PrintDebugLineInfo, "printdebugline",
656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                             "Load, link, and print line information for each function using the debug object"),
666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                  clEnumValN(AC_PrintObjectLineInfo, "printobjline",
676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                             "Like -printlineinfo but does not load the object first"),
68c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                  clEnumValN(AC_Verify, "verify",
69c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                             "Load, link and verify the resulting memory image."),
701cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach                  clEnumValEnd));
711cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
726b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbachstatic cl::opt<std::string>
736b32e7e213ca14d5d898c84053d6f38a4c360763Jim GrosbachEntryPoint("entry",
746b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbach           cl::desc("Function to call as entry point."),
756b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbach           cl::init("_main"));
766b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbach
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::list<std::string>
78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDylibs("dylib",
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       cl::desc("Add library."),
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       cl::ZeroOrMore);
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
82c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic cl::opt<std::string>
83c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesTripleName("triple", cl::desc("Target triple for disassembler"));
84c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<std::string>
86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarMCPU("mcpu",
87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar     cl::desc("Target a specific cpu type (-mcpu=help for details)"),
88f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar     cl::value_desc("cpu-name"),
89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar     cl::init(""));
90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
91c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic cl::list<std::string>
92c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesCheckFiles("check",
93c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines           cl::desc("File containing RuntimeDyld verifier checks."),
94c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines           cl::ZeroOrMore);
95c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<uint64_t>
97f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarPreallocMemory("preallocate",
98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              cl::desc("Allocate memory upfront rather than on-demand"),
99f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              cl::init(0));
100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<uint64_t>
10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTargetAddrStart("target-addr-start",
10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                cl::desc("For -verify only: start of phony target address "
10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         "range."),
10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                cl::init(4096), // Start at "page 1" - no allocating at "null".
10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                cl::Hidden);
10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<uint64_t>
10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTargetAddrEnd("target-addr-end",
11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              cl::desc("For -verify only: end of phony target address range."),
11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              cl::init(~0ULL),
11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              cl::Hidden);
11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<uint64_t>
11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTargetSectionSep("target-section-sep",
11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 cl::desc("For -verify only: Separation between sections in "
11737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          "phony target address space."),
11837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 cl::init(0),
11937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 cl::Hidden);
12037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
12137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::list<std::string>
12237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesSpecificSectionMappings("map-section",
123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        cl::desc("For -verify only: Map a section to a "
124f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                 "specific address."),
125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        cl::ZeroOrMore,
126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        cl::Hidden);
127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::list<std::string>
129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarDummySymbolMappings("dummy-extern",
130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    cl::desc("For -verify only: Inject a symbol into the extern "
131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                             "symbol table."),
132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    cl::ZeroOrMore,
133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    cl::Hidden);
134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<bool>
136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarPrintAllocationRequests("print-alloc-requests",
137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        cl::desc("Print allocation requests made to the memory "
138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                 "manager by RuntimeDyld"),
139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        cl::Hidden);
14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1411cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach/* *** */
1421cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
143fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbach// A trivial memory manager that doesn't do anything fancy, just uses the
144fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbach// support library allocation routines directly.
145fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbachclass TrivialMemoryManager : public RTDyldMemoryManager {
146fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbachpublic:
1477cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach  SmallVector<sys::MemoryBlock, 16> FunctionMemory;
14861425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach  SmallVector<sys::MemoryBlock, 16> DataMemory;
14961425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach
15061425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               unsigned SectionID,
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               StringRef SectionName) override;
15361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
1546eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo                               unsigned SectionID, StringRef SectionName,
15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                               bool IsReadOnly) override;
1567cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void *getPointerToNamedFunction(const std::string &Name,
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  bool AbortOnFailure = true) override {
159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
16030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev  }
16130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool finalizeMemory(std::string *ErrMsg) override { return false; }
16353608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor
164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void addDummySymbol(const std::string &Name, uint64_t Addr) {
165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DummyExterns[Name] = Addr;
166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override {
169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto I = DummyExterns.find(Name);
170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (I != DummyExterns.end())
172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return RuntimeDyld::SymbolInfo(I->second, JITSymbolFlags::Exported);
173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return RTDyldMemoryManager::findSymbol(Name);
175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
1786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                        size_t Size) override {}
1796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
1806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                          size_t Size) override {}
181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void preallocateSlab(uint64_t Size) {
183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string Err;
184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err);
185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!MB.base())
186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error("Can't allocate enough memory: " + Err);
187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    PreallocSlab = MB;
189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    UsePreallocation = true;
190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SlabSize = Size;
191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint8_t *allocateFromSlab(uintptr_t Size, unsigned Alignment, bool isCode) {
194de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Size = alignTo(Size, Alignment);
195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (CurrentSlabOffset + Size > SlabSize)
196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error("Can't allocate enough memory. Tune --preallocate");
197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uintptr_t OldSlabOffset = CurrentSlabOffset;
199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    sys::MemoryBlock MB((void *)OldSlabOffset, Size);
200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (isCode)
201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FunctionMemory.push_back(MB);
202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else
203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      DataMemory.push_back(MB);
204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CurrentSlabOffset += Size;
205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return (uint8_t*)OldSlabOffset;
206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarprivate:
209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::map<std::string, uint64_t> DummyExterns;
210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  sys::MemoryBlock PreallocSlab;
211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool UsePreallocation = false;
212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uintptr_t SlabSize = 0;
213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uintptr_t CurrentSlabOffset = 0;
214fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbach};
215fcbe5b71936b820647dffff0e4f9c60ece3988a5Jim Grosbach
21661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachuint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
21761425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach                                                   unsigned Alignment,
2186eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo                                                   unsigned SectionID,
2196eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo                                                   StringRef SectionName) {
220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (PrintAllocationRequests)
221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << "allocateCodeSection(Size = " << Size << ", Alignment = "
222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar           << Alignment << ", SectionName = " << SectionName << ")\n";
223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (UsePreallocation)
225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return allocateFromSlab(Size, Alignment, true /* isCode */);
226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::string Err;
228f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err);
229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!MB.base())
230f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    report_fatal_error("MemoryManager allocation failed: " + Err);
231068c65b22d50c265b51886062b2b9c1cb696d67dDanil Malyshev  FunctionMemory.push_back(MB);
232068c65b22d50c265b51886062b2b9c1cb696d67dDanil Malyshev  return (uint8_t*)MB.base();
23361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach}
23461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach
23561425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbachuint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
23661425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach                                                   unsigned Alignment,
23753608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor                                                   unsigned SectionID,
2386eb43d295625cd2ff314c59b49d4fd11f3348cadFilip Pizlo                                                   StringRef SectionName,
23953608a34ce3f0969e9fb01eaa983422761011e03Andrew Kaylor                                                   bool IsReadOnly) {
240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (PrintAllocationRequests)
241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    outs() << "allocateDataSection(Size = " << Size << ", Alignment = "
242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar           << Alignment << ", SectionName = " << SectionName << ")\n";
243068c65b22d50c265b51886062b2b9c1cb696d67dDanil Malyshev
244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (UsePreallocation)
245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return allocateFromSlab(Size, Alignment, false /* isCode */);
246068c65b22d50c265b51886062b2b9c1cb696d67dDanil Malyshev
247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::string Err;
248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, &Err);
249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!MB.base())
250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    report_fatal_error("MemoryManager allocation failed: " + Err);
251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DataMemory.push_back(MB);
252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return (uint8_t*)MB.base();
25361425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach}
25461425c0a7f4e3608a85f7bbf254cd052a15b7446Jim Grosbach
2551cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachstatic const char *ProgramName;
2561cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
257de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarstatic void ErrorAndExit(const Twine &Msg) {
258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  errs() << ProgramName << ": error: " << Msg << "\n";
259de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  exit(1);
2601cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach}
2611cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void loadDylibs() {
263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (const std::string &Dylib : Dylibs) {
264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!sys::fs::is_regular_file(Dylib))
265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error("Dylib not found: '" + Dylib + "'.");
266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string ErrMsg;
267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg))
268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error("Error loading '" + Dylib + "': " + ErrMsg);
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
270dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
271dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2721cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach/* *** */
27335fdeb7b373e416ff00c54abef12e786963af725Jim Grosbach
2746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) {
2756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(LoadObjects || !UseDebugObj);
2766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
277dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Load any dylibs requested on the command line.
278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  loadDylibs();
279dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
280ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor  // If we don't have any input files, read from stdin.
281ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor  if (!InputFileList.size())
282ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    InputFileList.push_back("-");
283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &File : InputFileList) {
284ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    // Instantiate a dynamic linker.
285a757e936263d0a95cbacff4fedd4703e5185800cBenjamin Kramer    TrivialMemoryManager MemMgr;
2860c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    RuntimeDyld Dyld(MemMgr, MemMgr);
287ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
288ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    // Load the input memory buffer.
289ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
290c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MemoryBuffer::getFileOrSTDIN(File);
292c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = InputBuffer.getError())
293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("unable to read input: '" + EC.message() + "'");
294c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<std::unique_ptr<ObjectFile>> MaybeObj(
296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
298de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!MaybeObj) {
299de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(MaybeObj.takeError(), OS, "");
302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("unable to create object file: '" + Buf + "'");
304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ObjectFile &Obj = **MaybeObj;
307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    OwningBinary<ObjectFile> DebugObj;
3096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr;
3106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    ObjectFile *SymbolObj = &Obj;
3116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (LoadObjects) {
3126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // Load the object file
3136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      LoadedObjInfo =
3146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Dyld.loadObject(Obj);
315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (Dyld.hasError())
317de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        ErrorAndExit(Dyld.getErrorString());
318ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
3196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // Resolve all the relocations we can.
3206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Dyld.resolveRelocations();
321ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
3226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (UseDebugObj) {
3236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        DebugObj = LoadedObjInfo->getObjectForDebug(Obj);
3246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        SymbolObj = DebugObj.getBinary();
325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        LoadedObjInfo.reset();
3266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      }
3276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::unique_ptr<DIContext> Context(
3306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get()));
3316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        object::computeSymbolSizes(*SymbolObj);
334ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
335ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    // Use symbol info to iterate functions in the object.
336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (const auto &P : SymAddr) {
337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      object::SymbolRef Sym = P.first;
338de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<SymbolRef::Type> TypeOrErr = Sym.getType();
339de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!TypeOrErr) {
340de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        // TODO: Actually report errors helpfully.
341de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        consumeError(TypeOrErr.takeError());
342de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        continue;
343de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
344de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      SymbolRef::Type Type = *TypeOrErr;
345de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (Type == object::SymbolRef::ST_Function) {
346de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Expected<StringRef> Name = Sym.getName();
347de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (!Name) {
348de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          // TODO: Actually report errors helpfully.
349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          consumeError(Name.takeError());
3506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          continue;
351de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        }
352de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Expected<uint64_t> AddrOrErr = Sym.getAddress();
353de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        if (!AddrOrErr) {
354de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          // TODO: Actually report errors helpfully.
355de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          consumeError(AddrOrErr.takeError());
3566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          continue;
357de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        }
358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint64_t Addr = *AddrOrErr;
3596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint64_t Size = P.second;
3616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // If we're not using the debug object, compute the address of the
3626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // symbol in memory (rather than that in the unrelocated object file)
3636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        // and use that to query the DWARFContext.
3646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        if (!UseDebugObj && LoadObjects) {
365de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          auto SecOrErr = Sym.getSection();
366de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          if (!SecOrErr) {
367de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            // TODO: Actually report errors helpfully.
368de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            consumeError(SecOrErr.takeError());
369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            continue;
370de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          }
371de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          object::section_iterator Sec = *SecOrErr;
3726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          StringRef SecName;
3736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          Sec->getName(SecName);
3746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          uint64_t SectionLoadAddress =
375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            LoadedObjInfo->getSectionLoadAddress(*Sec);
3766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          if (SectionLoadAddress != 0)
3776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar            Addr += SectionLoadAddress - Sec->getAddress();
3786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        }
379ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        outs() << "Function: " << *Name << ", Size = " << Size
381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               << ", Addr = " << Addr << "\n";
382ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
383e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor        DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size);
384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        for (auto &D : Lines) {
385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          outs() << "  Line info @ " << D.first - Addr << ": "
386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 << D.second.FileName << ", line:" << D.second.Line << "\n";
387e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor        }
388ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor      }
389ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor    }
390ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor  }
391ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
392ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor  return 0;
393ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor}
394ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor
395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic void doPreallocation(TrivialMemoryManager &MemMgr) {
396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Allocate a slab of memory upfront, if required. This is used if
397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // we want to test small code models.
398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (static_cast<intptr_t>(PreallocMemory) < 0)
399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    report_fatal_error("Pre-allocated bytes of memory must be a positive integer.");
400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // FIXME: Limit the amount of memory that can be preallocated?
402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (PreallocMemory != 0)
403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MemMgr.preallocateSlab(PreallocMemory);
404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
40635fdeb7b373e416ff00c54abef12e786963af725Jim Grosbachstatic int executeInput() {
407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Load any dylibs requested on the command line.
408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  loadDylibs();
409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
4106e56331ed99e5b96de940dfdc53e438eef521a2eJim Grosbach  // Instantiate a dynamic linker.
411a757e936263d0a95cbacff4fedd4703e5185800cBenjamin Kramer  TrivialMemoryManager MemMgr;
412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  doPreallocation(MemMgr);
4130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  RuntimeDyld Dyld(MemMgr, MemMgr);
4140c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
4154f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach  // If we don't have any input files, read from stdin.
4164f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach  if (!InputFileList.size())
4174f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach    InputFileList.push_back("-");
418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &File : InputFileList) {
4194f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach    // Load the input memory buffer.
420c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MemoryBuffer::getFileOrSTDIN(File);
422c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = InputBuffer.getError())
423de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("unable to read input: '" + EC.message() + "'");
424de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<std::unique_ptr<ObjectFile>> MaybeObj(
425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
427de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!MaybeObj) {
428de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
429de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
430de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(MaybeObj.takeError(), OS, "");
431de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
432de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("unable to create object file: '" + Buf + "'");
433de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
435ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ObjectFile &Obj = **MaybeObj;
436ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4373f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor    // Load the object file
438ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Dyld.loadObject(Obj);
439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Dyld.hasError()) {
440de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit(Dyld.getErrorString());
4414f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach    }
442b3eecaf19e81f0cccffdeff940afbfd1a3754af2Jim Grosbach  }
4434f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach
444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Resove all the relocations we can.
4454f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach  // FIXME: Error out if there are unresolved relocations.
446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Dyld.resolveRelocations();
4474f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach
4486b32e7e213ca14d5d898c84053d6f38a4c360763Jim Grosbach  // Get the address of the entry point (_main by default).
4494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint);
450dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!MainAddress)
451de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorAndExit("no definition for '" + EntryPoint + "'");
4521cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
4537cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach  // Invalidate the instruction cache for each loaded function.
454f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &FM : MemMgr.FunctionMemory) {
455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
4567cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach    // Make sure the memory is executable.
457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // setExecutable will call InvalidateInstructionCache.
4587cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach    std::string ErrorStr;
459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!sys::Memory::setExecutable(FM, &ErrorStr))
460de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("unable to mark function executable: '" + ErrorStr + "'");
4617cbf92d1d9945c35d1021458280bb7984f796a01Jim Grosbach  }
4621cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
4631cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  // Dispatch to _main().
4644f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach  errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n";
4651cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
4661cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  int (*Main)(int, const char**) =
4671cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach    (int(*)(int,const char**)) uintptr_t(MainAddress);
4681cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  const char **Argv = new const char*[2];
4694f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach  // Use the name of the first input object module as argv[0] for the target.
4704f9f41f2f9772ecd6a57800fcc8de8ec2734f33cJim Grosbach  Argv[0] = InputFileList[0].c_str();
471dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Argv[1] = nullptr;
4721cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  return Main(1, Argv);
4731cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach}
4741cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
475c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic int checkAllExpressions(RuntimeDyldChecker &Checker) {
476c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  for (const auto& CheckerFileName : CheckFiles) {
477c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf =
478c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        MemoryBuffer::getFileOrSTDIN(CheckerFileName);
479c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = CheckerFileBuf.getError())
480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("unable to read input '" + CheckerFileName + "': " +
481c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                   EC.message());
482c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
483c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (!Checker.checkAllRulesInBuffer("# rtdyld-check:",
484c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                       CheckerFileBuf.get().get()))
485de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("some checks in '" + CheckerFileName + "' failed");
486c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
487c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return 0;
488c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
489c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
4904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic std::map<void *, uint64_t>
49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesapplySpecificSectionMappings(RuntimeDyldChecker &Checker) {
49237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
49337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::map<void*, uint64_t> SpecificMappings;
49437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
49537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (StringRef Mapping : SpecificSectionMappings) {
49637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
49737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    size_t EqualsIdx = Mapping.find_first_of("=");
498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string SectionIDStr = Mapping.substr(0, EqualsIdx);
49937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    size_t ComaIdx = Mapping.find_first_of(",");
50037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ComaIdx == StringRef::npos)
502f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error("Invalid section specification '" + Mapping +
503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                         "'. Should be '<file name>,<section name>=<addr>'");
50437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string FileName = SectionIDStr.substr(0, ComaIdx);
506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string SectionName = SectionIDStr.substr(ComaIdx + 1);
50737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
50837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t OldAddrInt;
50937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    std::string ErrorMsg;
51037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    std::tie(OldAddrInt, ErrorMsg) =
51137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Checker.getSectionAddr(FileName, SectionName, true);
51237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ErrorMsg != "")
514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error(ErrorMsg);
51537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
51637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    void* OldAddr = reinterpret_cast<void*>(static_cast<uintptr_t>(OldAddrInt));
51737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string NewAddrStr = Mapping.substr(EqualsIdx + 1);
51937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t NewAddr;
52037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (StringRef(NewAddrStr).getAsInteger(0, NewAddr))
522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error("Invalid section address in mapping '" + Mapping +
523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                         "'.");
52437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
52537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Checker.getRTDyld().mapSectionAddress(OldAddr, NewAddr);
52637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SpecificMappings[OldAddr] = NewAddr;
52737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
52837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
52937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return SpecificMappings;
53037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
53137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
53237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Scatter sections in all directions!
53337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Remaps section addresses for -verify mode. The following command line options
53437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// can be used to customize the layout of the memory within the phony target's
53537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// address space:
53637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// -target-addr-start <s> -- Specify where the phony target addres range starts.
53737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// -target-addr-end   <e> -- Specify where the phony target address range ends.
53837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// -target-section-sep <d> -- Specify how big a gap should be left between the
53937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//                            end of one section and the start of the next.
54037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//                            Defaults to zero. Set to something big
54137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//                            (e.g. 1 << 32) to stress-test stubs, GOTs, etc.
54237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines//
543f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
544f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                    TrivialMemoryManager &MemMgr,
545f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                    RuntimeDyldChecker &Checker) {
54637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
54737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Set up a work list (section addr/size pairs).
54837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  typedef std::list<std::pair<void*, uint64_t>> WorklistT;
54937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  WorklistT Worklist;
55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
55137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const auto& CodeSection : MemMgr.FunctionMemory)
55237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Worklist.push_back(std::make_pair(CodeSection.base(), CodeSection.size()));
55337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const auto& DataSection : MemMgr.DataMemory)
55437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Worklist.push_back(std::make_pair(DataSection.base(), DataSection.size()));
55537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
55637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Apply any section-specific mappings that were requested on the command
55737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // line.
55837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  typedef std::map<void*, uint64_t> AppliedMappingsT;
55937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker);
56037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
56137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Keep an "already allocated" mapping of section target addresses to sizes.
56237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Sections whose address mappings aren't specified on the command line will
56337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // allocated around the explicitly mapped sections while maintaining the
56437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // minimum separation.
56537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::map<uint64_t, uint64_t> AlreadyAllocated;
56637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
56737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Move the previously applied mappings into the already-allocated map.
56837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end();
56937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines       I != E;) {
57037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    WorklistT::iterator Tmp = I;
57137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ++I;
57237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    AppliedMappingsT::iterator AI = AppliedMappings.find(Tmp->first);
57337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
57437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (AI != AppliedMappings.end()) {
57537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      AlreadyAllocated[AI->second] = Tmp->second;
57637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Worklist.erase(Tmp);
57737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
57837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
57937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
58037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If the -target-addr-end option wasn't explicitly passed, then set it to a
58137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // sensible default based on the target triple.
58237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (TargetAddrEnd.getNumOccurrences() == 0) {
58337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (TargetTriple.isArch16Bit())
58437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      TargetAddrEnd = (1ULL << 16) - 1;
58537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else if (TargetTriple.isArch32Bit())
58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      TargetAddrEnd = (1ULL << 32) - 1;
58737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // TargetAddrEnd already has a sensible default for 64-bit systems, so
58837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // there's nothing to do in the 64-bit case.
58937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
59037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
59137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Process any elements remaining in the worklist.
59237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  while (!Worklist.empty()) {
59337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    std::pair<void*, uint64_t> CurEntry = Worklist.front();
59437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Worklist.pop_front();
59537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
59637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t NextSectionAddr = TargetAddrStart;
59737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
59837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (const auto &Alloc : AlreadyAllocated)
59937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (NextSectionAddr + CurEntry.second + TargetSectionSep <= Alloc.first)
60037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
60137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else
60237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep;
60337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
60437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    AlreadyAllocated[NextSectionAddr] = CurEntry.second;
60537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Checker.getRTDyld().mapSectionAddress(CurEntry.first, NextSectionAddr);
60637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
60737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Add dummy symbols to the memory manager.
609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (const auto &Mapping : DummySymbolMappings) {
610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    size_t EqualsIdx = Mapping.find_first_of("=");
611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
612f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (EqualsIdx == StringRef::npos)
613f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error("Invalid dummy symbol specification '" + Mapping +
614f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                         "'. Should be '<symbol name>=<addr>'");
615f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string Symbol = Mapping.substr(0, EqualsIdx);
617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string AddrStr = Mapping.substr(EqualsIdx + 1);
618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t Addr;
620f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (StringRef(AddrStr).getAsInteger(0, Addr))
621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      report_fatal_error("Invalid symbol mapping '" + Mapping + "'.");
622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
623f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MemMgr.addDummySymbol(Symbol, Addr);
624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
62537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
62637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
62737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// Load and link the objects specified on the command line, but do not execute
62837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// anything. Instead, attach a RuntimeDyldChecker instance and call it to
62937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines// verify the correctness of the linked memory.
630c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesstatic int linkAndVerify() {
631c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
632c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Check for missing triple.
633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (TripleName == "")
634de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorAndExit("-triple required when running in -verify mode.");
635c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
636c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Look up the target and build the disassembler.
637c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Triple TheTriple(Triple::normalize(TripleName));
638c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::string ErrorStr;
639c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  const Target *TheTarget =
640c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    TargetRegistry::lookupTarget("", TheTriple, ErrorStr);
641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!TheTarget)
642de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorAndExit("Error accessing target '" + TripleName + "': " + ErrorStr);
643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
644c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  TripleName = TheTriple.getTriple();
645c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
646c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MCSubtargetInfo> STI(
647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    TheTarget->createMCSubtargetInfo(TripleName, MCPU, ""));
648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!STI)
649de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorAndExit("Unable to create subtarget info!");
650c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
651c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!MRI)
653de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorAndExit("Unable to create target register info!");
654c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
655c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!MAI)
657de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorAndExit("Unable to create target asm info!");
658c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
659c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MCContext Ctx(MAI.get(), MRI.get(), nullptr);
660c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
661c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MCDisassembler> Disassembler(
662c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    TheTarget->createMCDisassembler(*STI, Ctx));
663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!Disassembler)
664de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorAndExit("Unable to create disassembler!");
665c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
666c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
667c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
668c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MCInstPrinter> InstPrinter(
6690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI));
670c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
671c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Load any dylibs requested on the command line.
672c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  loadDylibs();
673c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
674c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Instantiate a dynamic linker.
675c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  TrivialMemoryManager MemMgr;
676f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  doPreallocation(MemMgr);
6770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  RuntimeDyld Dyld(MemMgr, MemMgr);
67837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Dyld.setProcessAllSections(true);
67937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(),
68037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             llvm::dbgs());
681c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
682c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // If we don't have any input files, read from stdin.
683c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!InputFileList.size())
684c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    InputFileList.push_back("-");
685f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &Filename : InputFileList) {
686c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    // Load the input memory buffer.
687c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
688f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MemoryBuffer::getFileOrSTDIN(Filename);
689ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
690c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = InputBuffer.getError())
691de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("unable to read input: '" + EC.message() + "'");
692c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
693de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Expected<std::unique_ptr<ObjectFile>> MaybeObj(
694ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef()));
695ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
696de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!MaybeObj) {
697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      std::string Buf;
698de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      raw_string_ostream OS(Buf);
699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      logAllUnhandledErrors(MaybeObj.takeError(), OS, "");
700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS.flush();
701de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit("unable to create object file: '" + Buf + "'");
702de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
703ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
704ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ObjectFile &Obj = **MaybeObj;
705ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
706c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    // Load the object file
707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Dyld.loadObject(Obj);
708ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Dyld.hasError()) {
709de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      ErrorAndExit(Dyld.getErrorString());
710c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
711c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
712c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Re-map the section addresses into the phony target address space and add
714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // dummy symbols.
715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  remapSectionsAndSymbols(TheTriple, MemMgr, Checker);
71637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
717c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Resolve all the relocations we can.
718c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Dyld.resolveRelocations();
719c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
72037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Register EH frames.
72137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Dyld.registerEHFrames();
72237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
72337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int ErrorCode = checkAllExpressions(Checker);
724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Dyld.hasError())
725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    ErrorAndExit("RTDyld reported an error applying relocations:\n  " +
726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 Dyld.getErrorString());
72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
72837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return ErrorCode;
729c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
730c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
7311cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbachint main(int argc, char **argv) {
732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  sys::PrintStackTraceOnErrorSignal(argv[0]);
7334d6b695c953462c3317e3a7eb57d0534db858ac2Alp Toker  PrettyStackTraceProgram X(argc, argv);
7344d6b695c953462c3317e3a7eb57d0534db858ac2Alp Toker
7351cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  ProgramName = argv[0];
7361cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
7371cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
738c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  llvm::InitializeAllTargetInfos();
739c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  llvm::InitializeAllTargetMCs();
740c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  llvm::InitializeAllDisassemblers();
741c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
7421cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n");
7431cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach
7441cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  switch (Action) {
7451cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  case AC_Execute:
74682c25b4964f91760fb4731cdef114b2ba2a950ccJim Grosbach    return executeInput();
7476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case AC_PrintDebugLineInfo:
7486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */ true);
749ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor  case AC_PrintLineInfo:
7506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return printLineInfoForInput(/* LoadObjects */ true,/* UseDebugObj */false);
7516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case AC_PrintObjectLineInfo:
7526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return printLineInfoForInput(/* LoadObjects */false,/* UseDebugObj */false);
753c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case AC_Verify:
754c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return linkAndVerify();
7551cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach  }
7561cb19a4470533be84eb61e8f5fc40aa9d45f86f9Jim Grosbach}
757