1//===-- llvm-rtdyld.cpp - MCJIT Testing Tool ------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This is a testing tool for use with the MC-JIT LLVM components.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/ADT/StringMap.h"
15#include "llvm/DebugInfo/DIContext.h"
16#include "llvm/ExecutionEngine/ObjectBuffer.h"
17#include "llvm/ExecutionEngine/ObjectImage.h"
18#include "llvm/ExecutionEngine/RuntimeDyld.h"
19#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
20#include "llvm/MC/MCAsmInfo.h"
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCDisassembler.h"
23#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/MC/MCInstPrinter.h"
25#include "llvm/MC/MCRegisterInfo.h"
26#include "llvm/Object/MachO.h"
27#include "llvm/Support/CommandLine.h"
28#include "llvm/Support/DynamicLibrary.h"
29#include "llvm/Support/ManagedStatic.h"
30#include "llvm/Support/Memory.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include "llvm/Support/PrettyStackTrace.h"
33#include "llvm/Support/raw_ostream.h"
34#include "llvm/Support/Signals.h"
35#include "llvm/Support/TargetRegistry.h"
36#include "llvm/Support/TargetSelect.h"
37#include <system_error>
38
39using namespace llvm;
40using namespace llvm::object;
41
42static cl::list<std::string>
43InputFileList(cl::Positional, cl::ZeroOrMore,
44              cl::desc("<input file>"));
45
46enum ActionType {
47  AC_Execute,
48  AC_PrintLineInfo,
49  AC_Verify
50};
51
52static cl::opt<ActionType>
53Action(cl::desc("Action to perform:"),
54       cl::init(AC_Execute),
55       cl::values(clEnumValN(AC_Execute, "execute",
56                             "Load, link, and execute the inputs."),
57                  clEnumValN(AC_PrintLineInfo, "printline",
58                             "Load, link, and print line information for each function."),
59                  clEnumValN(AC_Verify, "verify",
60                             "Load, link and verify the resulting memory image."),
61                  clEnumValEnd));
62
63static cl::opt<std::string>
64EntryPoint("entry",
65           cl::desc("Function to call as entry point."),
66           cl::init("_main"));
67
68static cl::list<std::string>
69Dylibs("dylib",
70       cl::desc("Add library."),
71       cl::ZeroOrMore);
72
73static cl::opt<std::string>
74TripleName("triple", cl::desc("Target triple for disassembler"));
75
76static cl::list<std::string>
77CheckFiles("check",
78           cl::desc("File containing RuntimeDyld verifier checks."),
79           cl::ZeroOrMore);
80
81/* *** */
82
83// A trivial memory manager that doesn't do anything fancy, just uses the
84// support library allocation routines directly.
85class TrivialMemoryManager : public RTDyldMemoryManager {
86public:
87  SmallVector<sys::MemoryBlock, 16> FunctionMemory;
88  SmallVector<sys::MemoryBlock, 16> DataMemory;
89
90  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
91                               unsigned SectionID,
92                               StringRef SectionName) override;
93  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
94                               unsigned SectionID, StringRef SectionName,
95                               bool IsReadOnly) override;
96
97  void *getPointerToNamedFunction(const std::string &Name,
98                                  bool AbortOnFailure = true) override {
99    return nullptr;
100  }
101
102  bool finalizeMemory(std::string *ErrMsg) override { return false; }
103
104  // Invalidate instruction cache for sections with execute permissions.
105  // Some platforms with separate data cache and instruction cache require
106  // explicit cache flush, otherwise JIT code manipulations (like resolved
107  // relocations) will get to the data cache but not to the instruction cache.
108  virtual void invalidateInstructionCache();
109};
110
111uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
112                                                   unsigned Alignment,
113                                                   unsigned SectionID,
114                                                   StringRef SectionName) {
115  sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, nullptr);
116  FunctionMemory.push_back(MB);
117  return (uint8_t*)MB.base();
118}
119
120uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
121                                                   unsigned Alignment,
122                                                   unsigned SectionID,
123                                                   StringRef SectionName,
124                                                   bool IsReadOnly) {
125  sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, nullptr);
126  DataMemory.push_back(MB);
127  return (uint8_t*)MB.base();
128}
129
130void TrivialMemoryManager::invalidateInstructionCache() {
131  for (int i = 0, e = FunctionMemory.size(); i != e; ++i)
132    sys::Memory::InvalidateInstructionCache(FunctionMemory[i].base(),
133                                            FunctionMemory[i].size());
134
135  for (int i = 0, e = DataMemory.size(); i != e; ++i)
136    sys::Memory::InvalidateInstructionCache(DataMemory[i].base(),
137                                            DataMemory[i].size());
138}
139
140static const char *ProgramName;
141
142static void Message(const char *Type, const Twine &Msg) {
143  errs() << ProgramName << ": " << Type << ": " << Msg << "\n";
144}
145
146static int Error(const Twine &Msg) {
147  Message("error", Msg);
148  return 1;
149}
150
151static void loadDylibs() {
152  for (const std::string &Dylib : Dylibs) {
153    if (sys::fs::is_regular_file(Dylib)) {
154      std::string ErrMsg;
155      if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg))
156        llvm::errs() << "Error loading '" << Dylib << "': "
157                     << ErrMsg << "\n";
158    } else
159      llvm::errs() << "Dylib not found: '" << Dylib << "'.\n";
160  }
161}
162
163/* *** */
164
165static int printLineInfoForInput() {
166  // Load any dylibs requested on the command line.
167  loadDylibs();
168
169  // If we don't have any input files, read from stdin.
170  if (!InputFileList.size())
171    InputFileList.push_back("-");
172  for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
173    // Instantiate a dynamic linker.
174    TrivialMemoryManager MemMgr;
175    RuntimeDyld Dyld(&MemMgr);
176
177    // Load the input memory buffer.
178
179    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
180        MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
181    if (std::error_code EC = InputBuffer.getError())
182      return Error("unable to read input: '" + EC.message() + "'");
183
184    std::unique_ptr<ObjectImage> LoadedObject;
185    // Load the object file
186    LoadedObject.reset(
187        Dyld.loadObject(new ObjectBuffer(InputBuffer.get().release())));
188    if (!LoadedObject) {
189      return Error(Dyld.getErrorString());
190    }
191
192    // Resolve all the relocations we can.
193    Dyld.resolveRelocations();
194
195    std::unique_ptr<DIContext> Context(
196        DIContext::getDWARFContext(LoadedObject->getObjectFile()));
197
198    // Use symbol info to iterate functions in the object.
199    for (object::symbol_iterator I = LoadedObject->begin_symbols(),
200                                 E = LoadedObject->end_symbols();
201         I != E; ++I) {
202      object::SymbolRef::Type SymType;
203      if (I->getType(SymType)) continue;
204      if (SymType == object::SymbolRef::ST_Function) {
205        StringRef  Name;
206        uint64_t   Addr;
207        uint64_t   Size;
208        if (I->getName(Name)) continue;
209        if (I->getAddress(Addr)) continue;
210        if (I->getSize(Size)) continue;
211
212        outs() << "Function: " << Name << ", Size = " << Size << "\n";
213
214        DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size);
215        DILineInfoTable::iterator  Begin = Lines.begin();
216        DILineInfoTable::iterator  End = Lines.end();
217        for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
218          outs() << "  Line info @ " << It->first - Addr << ": "
219                 << It->second.FileName << ", line:" << It->second.Line << "\n";
220        }
221      }
222    }
223  }
224
225  return 0;
226}
227
228static int executeInput() {
229  // Load any dylibs requested on the command line.
230  loadDylibs();
231
232  // Instantiate a dynamic linker.
233  TrivialMemoryManager MemMgr;
234  RuntimeDyld Dyld(&MemMgr);
235
236  // If we don't have any input files, read from stdin.
237  if (!InputFileList.size())
238    InputFileList.push_back("-");
239  for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
240    // Load the input memory buffer.
241    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
242        MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
243    if (std::error_code EC = InputBuffer.getError())
244      return Error("unable to read input: '" + EC.message() + "'");
245    std::unique_ptr<ObjectImage> LoadedObject;
246    // Load the object file
247    LoadedObject.reset(
248        Dyld.loadObject(new ObjectBuffer(InputBuffer.get().release())));
249    if (!LoadedObject) {
250      return Error(Dyld.getErrorString());
251    }
252  }
253
254  // Resolve all the relocations we can.
255  Dyld.resolveRelocations();
256  // Clear instruction cache before code will be executed.
257  MemMgr.invalidateInstructionCache();
258
259  // FIXME: Error out if there are unresolved relocations.
260
261  // Get the address of the entry point (_main by default).
262  void *MainAddress = Dyld.getSymbolAddress(EntryPoint);
263  if (!MainAddress)
264    return Error("no definition for '" + EntryPoint + "'");
265
266  // Invalidate the instruction cache for each loaded function.
267  for (unsigned i = 0, e = MemMgr.FunctionMemory.size(); i != e; ++i) {
268    sys::MemoryBlock &Data = MemMgr.FunctionMemory[i];
269    // Make sure the memory is executable.
270    std::string ErrorStr;
271    sys::Memory::InvalidateInstructionCache(Data.base(), Data.size());
272    if (!sys::Memory::setExecutable(Data, &ErrorStr))
273      return Error("unable to mark function executable: '" + ErrorStr + "'");
274  }
275
276  // Dispatch to _main().
277  errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n";
278
279  int (*Main)(int, const char**) =
280    (int(*)(int,const char**)) uintptr_t(MainAddress);
281  const char **Argv = new const char*[2];
282  // Use the name of the first input object module as argv[0] for the target.
283  Argv[0] = InputFileList[0].c_str();
284  Argv[1] = nullptr;
285  return Main(1, Argv);
286}
287
288static int checkAllExpressions(RuntimeDyldChecker &Checker) {
289  for (const auto& CheckerFileName : CheckFiles) {
290    ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf =
291        MemoryBuffer::getFileOrSTDIN(CheckerFileName);
292    if (std::error_code EC = CheckerFileBuf.getError())
293      return Error("unable to read input '" + CheckerFileName + "': " +
294                   EC.message());
295
296    if (!Checker.checkAllRulesInBuffer("# rtdyld-check:",
297                                       CheckerFileBuf.get().get()))
298      return Error("some checks in '" + CheckerFileName + "' failed");
299  }
300  return 0;
301}
302
303static int linkAndVerify() {
304
305  // Check for missing triple.
306  if (TripleName == "") {
307    llvm::errs() << "Error: -triple required when running in -verify mode.\n";
308    return 1;
309  }
310
311  // Look up the target and build the disassembler.
312  Triple TheTriple(Triple::normalize(TripleName));
313  std::string ErrorStr;
314  const Target *TheTarget =
315    TargetRegistry::lookupTarget("", TheTriple, ErrorStr);
316  if (!TheTarget) {
317    llvm::errs() << "Error accessing target '" << TripleName << "': "
318                 << ErrorStr << "\n";
319    return 1;
320  }
321  TripleName = TheTriple.getTriple();
322
323  std::unique_ptr<MCSubtargetInfo> STI(
324    TheTarget->createMCSubtargetInfo(TripleName, "", ""));
325  assert(STI && "Unable to create subtarget info!");
326
327  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
328  assert(MRI && "Unable to create target register info!");
329
330  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName));
331  assert(MAI && "Unable to create target asm info!");
332
333  MCContext Ctx(MAI.get(), MRI.get(), nullptr);
334
335  std::unique_ptr<MCDisassembler> Disassembler(
336    TheTarget->createMCDisassembler(*STI, Ctx));
337  assert(Disassembler && "Unable to create disassembler!");
338
339  std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
340
341  std::unique_ptr<MCInstPrinter> InstPrinter(
342    TheTarget->createMCInstPrinter(0, *MAI, *MII, *MRI, *STI));
343
344  // Load any dylibs requested on the command line.
345  loadDylibs();
346
347  // Instantiate a dynamic linker.
348  TrivialMemoryManager MemMgr;
349  RuntimeDyld Dyld(&MemMgr);
350
351  // If we don't have any input files, read from stdin.
352  if (!InputFileList.size())
353    InputFileList.push_back("-");
354  for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
355    // Load the input memory buffer.
356    ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer =
357        MemoryBuffer::getFileOrSTDIN(InputFileList[i]);
358    if (std::error_code EC = InputBuffer.getError())
359      return Error("unable to read input: '" + EC.message() + "'");
360
361    std::unique_ptr<ObjectImage> LoadedObject;
362    // Load the object file
363    LoadedObject.reset(
364        Dyld.loadObject(new ObjectBuffer(InputBuffer.get().release())));
365    if (!LoadedObject) {
366      return Error(Dyld.getErrorString());
367    }
368  }
369
370  // Resolve all the relocations we can.
371  Dyld.resolveRelocations();
372
373  RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(),
374                             llvm::dbgs());
375  return checkAllExpressions(Checker);
376}
377
378int main(int argc, char **argv) {
379  sys::PrintStackTraceOnErrorSignal();
380  PrettyStackTraceProgram X(argc, argv);
381
382  ProgramName = argv[0];
383  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
384
385  llvm::InitializeAllTargetInfos();
386  llvm::InitializeAllTargetMCs();
387  llvm::InitializeAllDisassemblers();
388
389  cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n");
390
391  switch (Action) {
392  case AC_Execute:
393    return executeInput();
394  case AC_PrintLineInfo:
395    return printLineInfoForInput();
396  case AC_Verify:
397    return linkAndVerify();
398  }
399}
400