/3rd_party/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp

https://code.google.com/p/softart/ · C++ · 258 lines · 179 code · 41 blank · 38 comment · 31 complexity · 926ee6f519c1d9f9de358494ae826278 MD5 · raw file

  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. #include "llvm/ADT/OwningPtr.h"
  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/Object/MachO.h"
  20. #include "llvm/Support/CommandLine.h"
  21. #include "llvm/Support/ManagedStatic.h"
  22. #include "llvm/Support/Memory.h"
  23. #include "llvm/Support/MemoryBuffer.h"
  24. #include "llvm/Support/PrettyStackTrace.h"
  25. #include "llvm/Support/Signals.h"
  26. #include "llvm/Support/raw_ostream.h"
  27. #include "llvm/Support/system_error.h"
  28. using namespace llvm;
  29. using namespace llvm::object;
  30. static cl::list<std::string>
  31. InputFileList(cl::Positional, cl::ZeroOrMore,
  32. cl::desc("<input file>"));
  33. enum ActionType {
  34. AC_Execute,
  35. AC_PrintLineInfo
  36. };
  37. static cl::opt<ActionType>
  38. Action(cl::desc("Action to perform:"),
  39. cl::init(AC_Execute),
  40. cl::values(clEnumValN(AC_Execute, "execute",
  41. "Load, link, and execute the inputs."),
  42. clEnumValN(AC_PrintLineInfo, "printline",
  43. "Load, link, and print line information for each function."),
  44. clEnumValEnd));
  45. static cl::opt<std::string>
  46. EntryPoint("entry",
  47. cl::desc("Function to call as entry point."),
  48. cl::init("_main"));
  49. /* *** */
  50. // A trivial memory manager that doesn't do anything fancy, just uses the
  51. // support library allocation routines directly.
  52. class TrivialMemoryManager : public RTDyldMemoryManager {
  53. public:
  54. SmallVector<sys::MemoryBlock, 16> FunctionMemory;
  55. SmallVector<sys::MemoryBlock, 16> DataMemory;
  56. uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
  57. unsigned SectionID, StringRef SectionName);
  58. uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
  59. unsigned SectionID, StringRef SectionName,
  60. bool IsReadOnly);
  61. virtual void *getPointerToNamedFunction(const std::string &Name,
  62. bool AbortOnFailure = true) {
  63. return 0;
  64. }
  65. bool finalizeMemory(std::string *ErrMsg) { return false; }
  66. // Invalidate instruction cache for sections with execute permissions.
  67. // Some platforms with separate data cache and instruction cache require
  68. // explicit cache flush, otherwise JIT code manipulations (like resolved
  69. // relocations) will get to the data cache but not to the instruction cache.
  70. virtual void invalidateInstructionCache();
  71. };
  72. uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
  73. unsigned Alignment,
  74. unsigned SectionID,
  75. StringRef SectionName) {
  76. sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0);
  77. FunctionMemory.push_back(MB);
  78. return (uint8_t*)MB.base();
  79. }
  80. uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
  81. unsigned Alignment,
  82. unsigned SectionID,
  83. StringRef SectionName,
  84. bool IsReadOnly) {
  85. sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0);
  86. DataMemory.push_back(MB);
  87. return (uint8_t*)MB.base();
  88. }
  89. void TrivialMemoryManager::invalidateInstructionCache() {
  90. for (int i = 0, e = FunctionMemory.size(); i != e; ++i)
  91. sys::Memory::InvalidateInstructionCache(FunctionMemory[i].base(),
  92. FunctionMemory[i].size());
  93. for (int i = 0, e = DataMemory.size(); i != e; ++i)
  94. sys::Memory::InvalidateInstructionCache(DataMemory[i].base(),
  95. DataMemory[i].size());
  96. }
  97. static const char *ProgramName;
  98. static void Message(const char *Type, const Twine &Msg) {
  99. errs() << ProgramName << ": " << Type << ": " << Msg << "\n";
  100. }
  101. static int Error(const Twine &Msg) {
  102. Message("error", Msg);
  103. return 1;
  104. }
  105. /* *** */
  106. static int printLineInfoForInput() {
  107. // If we don't have any input files, read from stdin.
  108. if (!InputFileList.size())
  109. InputFileList.push_back("-");
  110. for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
  111. // Instantiate a dynamic linker.
  112. TrivialMemoryManager MemMgr;
  113. RuntimeDyld Dyld(&MemMgr);
  114. // Load the input memory buffer.
  115. OwningPtr<MemoryBuffer> InputBuffer;
  116. OwningPtr<ObjectImage> LoadedObject;
  117. if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
  118. InputBuffer))
  119. return Error("unable to read input: '" + ec.message() + "'");
  120. // Load the object file
  121. LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
  122. if (!LoadedObject) {
  123. return Error(Dyld.getErrorString());
  124. }
  125. // Resolve all the relocations we can.
  126. Dyld.resolveRelocations();
  127. OwningPtr<DIContext> Context(DIContext::getDWARFContext(LoadedObject->getObjectFile()));
  128. // Use symbol info to iterate functions in the object.
  129. error_code ec;
  130. for (object::symbol_iterator I = LoadedObject->begin_symbols(),
  131. E = LoadedObject->end_symbols();
  132. I != E && !ec;
  133. I.increment(ec)) {
  134. object::SymbolRef::Type SymType;
  135. if (I->getType(SymType)) continue;
  136. if (SymType == object::SymbolRef::ST_Function) {
  137. StringRef Name;
  138. uint64_t Addr;
  139. uint64_t Size;
  140. if (I->getName(Name)) continue;
  141. if (I->getAddress(Addr)) continue;
  142. if (I->getSize(Size)) continue;
  143. outs() << "Function: " << Name << ", Size = " << Size << "\n";
  144. DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size);
  145. DILineInfoTable::iterator Begin = Lines.begin();
  146. DILineInfoTable::iterator End = Lines.end();
  147. for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
  148. outs() << " Line info @ " << It->first - Addr << ": "
  149. << It->second.getFileName()
  150. << ", line:" << It->second.getLine() << "\n";
  151. }
  152. }
  153. }
  154. }
  155. return 0;
  156. }
  157. static int executeInput() {
  158. // Instantiate a dynamic linker.
  159. TrivialMemoryManager MemMgr;
  160. RuntimeDyld Dyld(&MemMgr);
  161. // If we don't have any input files, read from stdin.
  162. if (!InputFileList.size())
  163. InputFileList.push_back("-");
  164. for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
  165. // Load the input memory buffer.
  166. OwningPtr<MemoryBuffer> InputBuffer;
  167. OwningPtr<ObjectImage> LoadedObject;
  168. if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
  169. InputBuffer))
  170. return Error("unable to read input: '" + ec.message() + "'");
  171. // Load the object file
  172. LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
  173. if (!LoadedObject) {
  174. return Error(Dyld.getErrorString());
  175. }
  176. }
  177. // Resolve all the relocations we can.
  178. Dyld.resolveRelocations();
  179. // Clear instruction cache before code will be executed.
  180. MemMgr.invalidateInstructionCache();
  181. // FIXME: Error out if there are unresolved relocations.
  182. // Get the address of the entry point (_main by default).
  183. void *MainAddress = Dyld.getSymbolAddress(EntryPoint);
  184. if (MainAddress == 0)
  185. return Error("no definition for '" + EntryPoint + "'");
  186. // Invalidate the instruction cache for each loaded function.
  187. for (unsigned i = 0, e = MemMgr.FunctionMemory.size(); i != e; ++i) {
  188. sys::MemoryBlock &Data = MemMgr.FunctionMemory[i];
  189. // Make sure the memory is executable.
  190. std::string ErrorStr;
  191. sys::Memory::InvalidateInstructionCache(Data.base(), Data.size());
  192. if (!sys::Memory::setExecutable(Data, &ErrorStr))
  193. return Error("unable to mark function executable: '" + ErrorStr + "'");
  194. }
  195. // Dispatch to _main().
  196. errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n";
  197. int (*Main)(int, const char**) =
  198. (int(*)(int,const char**)) uintptr_t(MainAddress);
  199. const char **Argv = new const char*[2];
  200. // Use the name of the first input object module as argv[0] for the target.
  201. Argv[0] = InputFileList[0].c_str();
  202. Argv[1] = 0;
  203. return Main(1, Argv);
  204. }
  205. int main(int argc, char **argv) {
  206. sys::PrintStackTraceOnErrorSignal();
  207. PrettyStackTraceProgram X(argc, argv);
  208. ProgramName = argv[0];
  209. llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
  210. cl::ParseCommandLineOptions(argc, argv, "llvm MC-JIT tool\n");
  211. switch (Action) {
  212. case AC_Execute:
  213. return executeInput();
  214. case AC_PrintLineInfo:
  215. return printLineInfoForInput();
  216. }
  217. }