| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 1 | //===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===// | 
| John Criswell | 7c0e022 | 2003-10-20 17:47:21 +0000 | [diff] [blame] | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file was developed by the LLVM research group and is distributed under | 
|  | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 9 | // | 
| Chris Lattner | 7efea1d | 2003-12-26 05:07:35 +0000 | [diff] [blame] | 10 | // This utility provides a simple wrapper around the LLVM Execution Engines, | 
|  | 11 | // which allow the direct execution of LLVM programs through a Just-In-Time | 
|  | 12 | // compiler, or through an intepreter if no JIT is available for this platform. | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 13 | // | 
|  | 14 | //===----------------------------------------------------------------------===// | 
|  | 15 |  | 
| Chris Lattner | fd13129 | 2003-09-05 20:08:15 +0000 | [diff] [blame] | 16 | #include "llvm/DerivedTypes.h" | 
|  | 17 | #include "llvm/Module.h" | 
| Misha Brukman | c4fb6fd | 2003-10-14 21:39:53 +0000 | [diff] [blame] | 18 | #include "llvm/ModuleProvider.h" | 
| Chris Lattner | fd13129 | 2003-09-05 20:08:15 +0000 | [diff] [blame] | 19 | #include "llvm/Bytecode/Reader.h" | 
| Brian Gaeke | d1cab3e | 2003-09-05 19:42:34 +0000 | [diff] [blame] | 20 | #include "llvm/ExecutionEngine/ExecutionEngine.h" | 
|  | 21 | #include "llvm/ExecutionEngine/GenericValue.h" | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 22 | #include "llvm/Target/TargetMachineImpls.h" | 
| Brian Gaeke | 70975ee | 2003-09-05 18:42:01 +0000 | [diff] [blame] | 23 | #include "llvm/Target/TargetData.h" | 
| Chris Lattner | fd13129 | 2003-09-05 20:08:15 +0000 | [diff] [blame] | 24 | #include "Support/CommandLine.h" | 
|  | 25 | #include "Support/Debug.h" | 
| Misha Brukman | c4fb6fd | 2003-10-14 21:39:53 +0000 | [diff] [blame] | 26 | #include "Support/SystemUtils.h" | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 27 |  | 
| Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 28 | using namespace llvm; | 
|  | 29 |  | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 30 | namespace { | 
|  | 31 | cl::opt<std::string> | 
|  | 32 | InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-")); | 
| Chris Lattner | 5ff62e9 | 2002-07-22 02:10:13 +0000 | [diff] [blame] | 33 |  | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 34 | cl::list<std::string> | 
|  | 35 | InputArgv(cl::ConsumeAfter, cl::desc("<program arguments>...")); | 
| Chris Lattner | 5ff62e9 | 2002-07-22 02:10:13 +0000 | [diff] [blame] | 36 |  | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 37 | cl::opt<bool> ForceInterpreter("force-interpreter", | 
| Misha Brukman | 3d8a54d | 2003-09-25 18:10:34 +0000 | [diff] [blame] | 38 | cl::desc("Force interpretation: disable JIT"), | 
|  | 39 | cl::init(false)); | 
| Chris Lattner | e69671d | 2003-10-28 22:51:44 +0000 | [diff] [blame] | 40 |  | 
|  | 41 | cl::opt<std::string> | 
|  | 42 | FakeArgv0("fake-argv0", | 
|  | 43 | cl::desc("Override the 'argv[0]' value passed into the executing" | 
|  | 44 | " program"), cl::value_desc("executable")); | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 45 | } | 
| Chris Lattner | 43e3f7c | 2001-10-27 08:43:52 +0000 | [diff] [blame] | 46 |  | 
| Brian Gaeke | 70975ee | 2003-09-05 18:42:01 +0000 | [diff] [blame] | 47 | static void *CreateArgv(ExecutionEngine *EE, | 
| Misha Brukman | 3d8a54d | 2003-09-25 18:10:34 +0000 | [diff] [blame] | 48 | const std::vector<std::string> &InputArgv) { | 
| Chris Lattner | 3ef3dd3 | 2003-12-26 06:36:20 +0000 | [diff] [blame^] | 49 | unsigned PtrSize = EE->getTargetData().getPointerSize(); | 
|  | 50 | char *Result = new char[(InputArgv.size()+1)*PtrSize]; | 
| Brian Gaeke | 70975ee | 2003-09-05 18:42:01 +0000 | [diff] [blame] | 51 |  | 
| Chris Lattner | 3ef3dd3 | 2003-12-26 06:36:20 +0000 | [diff] [blame^] | 52 | DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); | 
|  | 53 | const Type *SBytePtr = PointerType::get(Type::SByteTy); | 
| Brian Gaeke | 70975ee | 2003-09-05 18:42:01 +0000 | [diff] [blame] | 54 |  | 
| Chris Lattner | 3ef3dd3 | 2003-12-26 06:36:20 +0000 | [diff] [blame^] | 55 | for (unsigned i = 0; i != InputArgv.size(); ++i) { | 
|  | 56 | unsigned Size = InputArgv[i].size()+1; | 
|  | 57 | char *Dest = new char[Size]; | 
|  | 58 | DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); | 
| Brian Gaeke | 70975ee | 2003-09-05 18:42:01 +0000 | [diff] [blame] | 59 |  | 
| Chris Lattner | 3ef3dd3 | 2003-12-26 06:36:20 +0000 | [diff] [blame^] | 60 | std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); | 
|  | 61 | Dest[Size-1] = 0; | 
| Brian Gaeke | 70975ee | 2003-09-05 18:42:01 +0000 | [diff] [blame] | 62 |  | 
| Chris Lattner | 3ef3dd3 | 2003-12-26 06:36:20 +0000 | [diff] [blame^] | 63 | // Endian safe: Result[i] = (PointerTy)Dest; | 
|  | 64 | EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i*PtrSize), | 
|  | 65 | SBytePtr); | 
| Brian Gaeke | 70975ee | 2003-09-05 18:42:01 +0000 | [diff] [blame] | 66 | } | 
| Chris Lattner | 3ef3dd3 | 2003-12-26 06:36:20 +0000 | [diff] [blame^] | 67 |  | 
|  | 68 | // Null terminate it | 
|  | 69 | EE->StoreValueToMemory(PTOGV(0), | 
|  | 70 | (GenericValue*)(Result+InputArgv.size()*PtrSize), | 
|  | 71 | SBytePtr); | 
|  | 72 | return Result; | 
| Brian Gaeke | 70975ee | 2003-09-05 18:42:01 +0000 | [diff] [blame] | 73 | } | 
|  | 74 |  | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 75 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 76 | // main Driver function | 
|  | 77 | // | 
| Misha Brukman | c4fb6fd | 2003-10-14 21:39:53 +0000 | [diff] [blame] | 78 | int main(int argc, char **argv, char * const *envp) { | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 79 | cl::ParseCommandLineOptions(argc, argv, | 
| Misha Brukman | 3d8a54d | 2003-09-25 18:10:34 +0000 | [diff] [blame] | 80 | " llvm interpreter & dynamic compiler\n"); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 81 |  | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 82 | // Load the bytecode... | 
| Chris Lattner | d6840ac | 2002-12-24 00:39:16 +0000 | [diff] [blame] | 83 | std::string ErrorMsg; | 
| Misha Brukman | c4fb6fd | 2003-10-14 21:39:53 +0000 | [diff] [blame] | 84 | ModuleProvider *MP = 0; | 
|  | 85 | try { | 
|  | 86 | MP = getBytecodeModuleProvider(InputFile); | 
|  | 87 | } catch (std::string &err) { | 
| Brian Gaeke | 3f6e798 | 2003-12-12 00:47:19 +0000 | [diff] [blame] | 88 | std::cerr << "Error loading program '" << InputFile << "': " << err << "\n"; | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 89 | exit(1); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 90 | } | 
|  | 91 |  | 
| Brian Gaeke | 82d8277 | 2003-09-03 20:34:19 +0000 | [diff] [blame] | 92 | ExecutionEngine *EE = | 
| Brian Gaeke | 2f828c3 | 2003-10-24 20:00:17 +0000 | [diff] [blame] | 93 | ExecutionEngine::create(MP, ForceInterpreter); | 
| Misha Brukman | 3d8a54d | 2003-09-25 18:10:34 +0000 | [diff] [blame] | 94 | assert(EE && "Couldn't create an ExecutionEngine, not even an interpreter?"); | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 95 |  | 
| Chris Lattner | e69671d | 2003-10-28 22:51:44 +0000 | [diff] [blame] | 96 | // If the user specifically requested an argv[0] to pass into the program, do | 
|  | 97 | // it now. | 
|  | 98 | if (!FakeArgv0.empty()) { | 
|  | 99 | InputFile = FakeArgv0; | 
|  | 100 | } else { | 
|  | 101 | // Otherwise, if there is a .bc suffix on the executable strip it off, it | 
|  | 102 | // might confuse the program. | 
|  | 103 | if (InputFile.rfind(".bc") == InputFile.length() - 3) | 
|  | 104 | InputFile.erase(InputFile.length() - 3); | 
| Brian Gaeke | 6ae73dc | 2003-05-23 20:28:07 +0000 | [diff] [blame] | 105 | } | 
| Chris Lattner | e69671d | 2003-10-28 22:51:44 +0000 | [diff] [blame] | 106 |  | 
|  | 107 | // Add the module's name to the start of the vector of arguments to main(). | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 108 | InputArgv.insert(InputArgv.begin(), InputFile); | 
|  | 109 |  | 
| Chris Lattner | efec966 | 2003-12-26 06:14:47 +0000 | [diff] [blame] | 110 | // Call the main function from M as if its signature were: | 
|  | 111 | //   int main (int argc, char **argv, const char **envp) | 
|  | 112 | // using the contents of Args to determine argc & argv, and the contents of | 
|  | 113 | // EnvVars to determine envp. | 
|  | 114 | // | 
|  | 115 | Function *Fn = MP->getModule()->getMainFunction(); | 
|  | 116 | if (!Fn) { | 
|  | 117 | std::cerr << "'main' function not found in module.\n"; | 
|  | 118 | return -1; | 
|  | 119 | } | 
| Chris Lattner | fe11a97 | 2002-12-23 23:59:41 +0000 | [diff] [blame] | 120 |  | 
| Chris Lattner | efec966 | 2003-12-26 06:14:47 +0000 | [diff] [blame] | 121 | std::vector<GenericValue> GVArgs; | 
|  | 122 | GenericValue GVArgc; | 
|  | 123 | GVArgc.IntVal = InputArgv.size(); | 
|  | 124 | GVArgs.push_back(GVArgc); // Arg #0 = argc. | 
|  | 125 | GVArgs.push_back(PTOGV(CreateArgv(EE, InputArgv))); // Arg #1 = argv. | 
|  | 126 | assert(((char **)GVTOP(GVArgs[1]))[0] && "argv[0] was null after CreateArgv"); | 
|  | 127 |  | 
| Chris Lattner | 3ef3dd3 | 2003-12-26 06:36:20 +0000 | [diff] [blame^] | 128 | std::vector<std::string> EnvVars; | 
|  | 129 | for (unsigned i = 0; envp[i]; ++i) | 
|  | 130 | EnvVars.push_back(envp[i]); | 
| Chris Lattner | efec966 | 2003-12-26 06:14:47 +0000 | [diff] [blame] | 131 | GVArgs.push_back(PTOGV(CreateArgv(EE, EnvVars))); // Arg #2 = envp. | 
|  | 132 | GenericValue Result = EE->runFunction(Fn, GVArgs); | 
|  | 133 |  | 
|  | 134 | // If the program didn't explicitly call exit, call exit now, for the program. | 
|  | 135 | // This ensures that any atexit handlers get called correctly. | 
|  | 136 | Function *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy, | 
|  | 137 | Type::IntTy, 0); | 
|  | 138 |  | 
|  | 139 | GVArgs.clear(); | 
|  | 140 | GVArgs.push_back(Result); | 
|  | 141 | EE->runFunction(Exit, GVArgs); | 
|  | 142 |  | 
|  | 143 | std::cerr << "ERROR: exit(" << Result.IntVal << ") returned!\n"; | 
|  | 144 | abort(); | 
| Chris Lattner | 92101ac | 2001-08-23 17:05:04 +0000 | [diff] [blame] | 145 | } |