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