// getArchive - Get the archive file name from the command line void getArchive() { if(RestOfArgs.size() > 0) { ArchiveName = RestOfArgs[0]; RestOfArgs.erase(RestOfArgs.begin()); } else throw "An archive name must be specified."; }
// getRelPos - Extract the member filename from the command line for // the [relpos] argument associated with a, b, and i modifiers void getRelPos() { if(RestOfArgs.size() > 0) { RelPos = RestOfArgs[0]; RestOfArgs.erase(RestOfArgs.begin()); } else throw "Expected [relpos] for a, b, or i modifier"; }
// getCount - Extract the [count] argument associated with the N modifier // from the command line and check its value. void getCount() { if(RestOfArgs.size() == 0) show_help("Expected [count] value with N modifier"); Count = atoi(RestOfArgs[0].c_str()); RestOfArgs.erase(RestOfArgs.begin()); // Non-positive counts are not allowed if (Count < 1) show_help("Invalid [count] value (not a positive integer)"); }
// getCount - Extract the [count] argument associated with the N modifier // from the command line and check its value. void getCount() { if(RestOfArgs.size() > 0) { Count = atoi(RestOfArgs[0].c_str()); RestOfArgs.erase(RestOfArgs.begin()); } else throw "Expected [count] value with N modifier"; // Non-positive counts are not allowed if (Count < 1) throw "Invalid [count] value (not a positive integer)"; }
/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM /// bytecode file for the program. static void EmitShellScript(char **argv) { if (Verbose) cout << "Emitting Shell Script\n"; #if defined(_WIN32) || defined(__CYGWIN__) // Windows doesn't support #!/bin/sh style shell scripts in .exe files. To // support windows systems, we copy the llvm-stub.exe executable from the // build tree to the destination file. std::string ErrMsg; sys::Path llvmstub = FindExecutable("llvm-stub.exe", argv[0]); if (llvmstub.isEmpty()) PrintAndExit("Could not find llvm-stub.exe executable!"); if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg)) PrintAndExit(ErrMsg); return; #endif // Output the script to start the program... std::ofstream Out2(OutputFilename.c_str()); if (!Out2.good()) PrintAndExit("error opening '" + OutputFilename + "' for writing!"); Out2 << "#!/bin/sh\n"; // Allow user to setenv LLVMINTERP if lli is not in their PATH. Out2 << "lli=${LLVMINTERP-lli}\n"; Out2 << "exec $lli \\\n"; // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib. LibPaths.push_back("/lib"); LibPaths.push_back("/usr/lib"); LibPaths.push_back("/usr/X11R6/lib"); // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a // shared object at all! See RH 8: plain text. std::vector<std::string>::iterator libc = std::find(Libraries.begin(), Libraries.end(), "c"); if (libc != Libraries.end()) Libraries.erase(libc); // List all the shared object (native) libraries this executable will need // on the command line, so that we don't have to do this manually! for (std::vector<std::string>::iterator i = Libraries.begin(), e = Libraries.end(); i != e; ++i) { sys::Path FullLibraryPath = sys::Path::FindLibrary(*i); if (!FullLibraryPath.isEmpty() && FullLibraryPath.isDynamicLibrary()) Out2 << " -load=" << FullLibraryPath.toString() << " \\\n"; } Out2 << " $0.bc ${1+\"$@\"}\n"; Out2.close(); }
// Get the archive file name from the command line static void getArchive() { if(RestOfArgs.size() == 0) show_help("An archive name must be specified"); ArchiveName = RestOfArgs[0]; RestOfArgs.erase(RestOfArgs.begin()); }
static void getOptions() { if(RestOfArgs.size() == 0) show_help("Expected options"); Options = RestOfArgs[0]; RestOfArgs.erase(RestOfArgs.begin()); }
// Extract the member filename from the command line for the [relpos] argument // associated with a, b, and i modifiers static void getRelPos() { if(RestOfArgs.size() == 0) show_help("Expected [relpos] for a, b, or i modifier"); RelPos = RestOfArgs[0]; RestOfArgs.erase(RestOfArgs.begin()); }
int main(int argc, char **argv, char **envp) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. try { // Initial global variable above for convenience printing of program name. progname = sys::Path(argv[0]).getBasename(); // Parse the command line options cl::ParseCommandLineOptions(argc, argv, " llvm linker\n"); sys::PrintStackTraceOnErrorSignal(); // Construct a Linker (now that Verbose is set) Linker TheLinker(progname, OutputFilename, Verbose); // Keep track of the native link items (versus the bytecode items) Linker::ItemList NativeLinkItems; // Add library paths to the linker TheLinker.addPaths(LibPaths); TheLinker.addSystemPaths(); // Remove any consecutive duplicates of the same library... Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), Libraries.end()); if (LinkAsLibrary) { std::vector<sys::Path> Files; for (unsigned i = 0; i < InputFilenames.size(); ++i ) Files.push_back(sys::Path(InputFilenames[i])); if (TheLinker.LinkInFiles(Files)) return 1; // Error already printed // The libraries aren't linked in but are noted as "dependent" in the // module. for (cl::list<std::string>::const_iterator I = Libraries.begin(), E = Libraries.end(); I != E ; ++I) { TheLinker.getModule()->addLibrary(*I); } } else { // Build a list of the items from our command line Linker::ItemList Items; BuildLinkItems(Items, InputFilenames, Libraries); // Link all the items together if (TheLinker.LinkInItems(Items, NativeLinkItems) ) return 1; // Error already printed } std::auto_ptr<Module> Composite(TheLinker.releaseModule()); // Optimize the module Optimize(Composite.get()); // Generate the bytecode for the optimized module. std::string RealBytecodeOutput = OutputFilename; if (!LinkAsLibrary) RealBytecodeOutput += ".bc"; GenerateBytecode(Composite.get(), RealBytecodeOutput); // If we are not linking a library, generate either a native executable // or a JIT shell script, depending upon what the user wants. if (!LinkAsLibrary) { // If the user wants to run a post-link optimization, run it now. if (!PostLinkOpts.empty()) { std::vector<std::string> opts = PostLinkOpts; for (std::vector<std::string>::iterator I = opts.begin(), E = opts.end(); I != E; ++I) { sys::Path prog(*I); if (!prog.canExecute()) { prog = sys::Program::FindProgramByName(*I); if (prog.isEmpty()) PrintAndExit(std::string("Optimization program '") + *I + "' is not found or not executable."); } // Get the program arguments sys::Path tmp_output("opt_result"); std::string ErrMsg; if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg)) PrintAndExit(ErrMsg); const char* args[4]; args[0] = I->c_str(); args[1] = RealBytecodeOutput.c_str(); args[2] = tmp_output.c_str(); args[3] = 0; if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) { if (tmp_output.isBytecodeFile() || tmp_output.isBitcodeFile()) { sys::Path target(RealBytecodeOutput); target.eraseFromDisk(); if (tmp_output.renamePathOnDisk(target, &ErrMsg)) PrintAndExit(ErrMsg, 2); } else PrintAndExit("Post-link optimization output is not bytecode"); } else { PrintAndExit(ErrMsg); } } } // If the user wants to generate a native executable, compile it from the // bytecode file. // // Otherwise, create a script that will run the bytecode through the JIT. if (Native) { // Name of the Assembly Language output file sys::Path AssemblyFile ( OutputFilename); AssemblyFile.appendSuffix("s"); // Mark the output files for removal if we get an interrupt. sys::RemoveFileOnSignal(AssemblyFile); sys::RemoveFileOnSignal(sys::Path(OutputFilename)); // Determine the locations of the llc and gcc programs. sys::Path llc = FindExecutable("llc", argv[0]); if (llc.isEmpty()) PrintAndExit("Failed to find llc"); sys::Path gcc = FindExecutable("gcc", argv[0]); if (gcc.isEmpty()) PrintAndExit("Failed to find gcc"); // Generate an assembly language file for the bytecode. std::string ErrMsg; if (0 != GenerateAssembly(AssemblyFile.toString(), RealBytecodeOutput, llc, ErrMsg)) PrintAndExit(ErrMsg); if (0 != GenerateNative(OutputFilename, AssemblyFile.toString(), NativeLinkItems, gcc, envp, ErrMsg)) PrintAndExit(ErrMsg); // Remove the assembly language file. AssemblyFile.eraseFromDisk(); } else if (NativeCBE) { sys::Path CFile (OutputFilename); CFile.appendSuffix("cbe.c"); // Mark the output files for removal if we get an interrupt. sys::RemoveFileOnSignal(CFile); sys::RemoveFileOnSignal(sys::Path(OutputFilename)); // Determine the locations of the llc and gcc programs. sys::Path llc = FindExecutable("llc", argv[0]); if (llc.isEmpty()) PrintAndExit("Failed to find llc"); sys::Path gcc = FindExecutable("gcc", argv[0]); if (gcc.isEmpty()) PrintAndExit("Failed to find gcc"); // Generate an assembly language file for the bytecode. std::string ErrMsg; if (0 != GenerateCFile( CFile.toString(), RealBytecodeOutput, llc, ErrMsg)) PrintAndExit(ErrMsg); if (0 != GenerateNative(OutputFilename, CFile.toString(), NativeLinkItems, gcc, envp, ErrMsg)) PrintAndExit(ErrMsg); // Remove the assembly language file. CFile.eraseFromDisk(); } else { EmitShellScript(argv); } // Make the script executable... std::string ErrMsg; if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg); // Make the bytecode file readable and directly executable in LLEE as well if (sys::Path(RealBytecodeOutput).makeExecutableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg); if (sys::Path(RealBytecodeOutput).makeReadableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg); } } catch (const std::string& msg) { PrintAndExit(msg,2); } catch (...) { PrintAndExit("Unexpected unknown exception occurred.", 2); } // Graceful exit return 0; }
int main(int argc, char **argv, char **envp) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeTarget(Registry); // Initial global variable above for convenience printing of program name. progname = sys::path::stem(argv[0]); // Parse the command line options cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); #if defined(_WIN32) || defined(__CYGWIN__) if (!LinkAsLibrary) { // Default to "a.exe" instead of "a.out". if (OutputFilename.getNumOccurrences() == 0) OutputFilename = "a.exe"; // If there is no suffix add an "exe" one. if (sys::path::extension(OutputFilename).empty()) OutputFilename.append(".exe"); } #endif // Generate the bitcode for the optimized module. // If -b wasn't specified, use the name specified // with -o to construct BitcodeOutputFilename. if (BitcodeOutputFilename.empty()) { BitcodeOutputFilename = OutputFilename; if (!LinkAsLibrary) BitcodeOutputFilename += ".bc"; } // Arrange for the bitcode output file to be deleted on any errors. BitcodeOutputRemover.setFile(BitcodeOutputFilename); sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename)); // Arrange for the output file to be deleted on any errors. if (!LinkAsLibrary) { OutputRemover.setFile(OutputFilename); sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } // Construct a Linker (now that Verbose is set) Linker TheLinker(progname, OutputFilename, Context, Verbose); // Keep track of the native link items (versus the bitcode items) Linker::ItemList NativeLinkItems; // Add library paths to the linker TheLinker.addPaths(LibPaths); TheLinker.addSystemPaths(); // Remove any consecutive duplicates of the same library... Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), Libraries.end()); if (LinkAsLibrary) { std::vector<sys::Path> Files; for (unsigned i = 0; i < InputFilenames.size(); ++i ) Files.push_back(sys::Path(InputFilenames[i])); if (TheLinker.LinkInFiles(Files)) return 1; // Error already printed // The libraries aren't linked in but are noted as "dependent" in the // module. for (cl::list<std::string>::const_iterator I = Libraries.begin(), E = Libraries.end(); I != E ; ++I) { TheLinker.getModule()->addLibrary(*I); } } else { // Build a list of the items from our command line Linker::ItemList Items; BuildLinkItems(Items, InputFilenames, Libraries); // Link all the items together if (TheLinker.LinkInItems(Items, NativeLinkItems) ) return 1; // Error already printed } std::auto_ptr<Module> Composite(TheLinker.releaseModule()); // Optimize the module Optimize(Composite.get()); // Generate the bitcode output. GenerateBitcode(Composite.get(), BitcodeOutputFilename); // If we are not linking a library, generate either a native executable // or a JIT shell script, depending upon what the user wants. if (!LinkAsLibrary) { // If the user wants to run a post-link optimization, run it now. if (!PostLinkOpts.empty()) { std::vector<std::string> opts = PostLinkOpts; for (std::vector<std::string>::iterator I = opts.begin(), E = opts.end(); I != E; ++I) { sys::Path prog(*I); if (!prog.canExecute()) { prog = sys::Program::FindProgramByName(*I); if (prog.isEmpty()) PrintAndExit(std::string("Optimization program '") + *I + "' is not found or not executable.", Composite.get()); } // Get the program arguments sys::Path tmp_output("opt_result"); std::string ErrMsg; if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); const char* args[4]; args[0] = I->c_str(); args[1] = BitcodeOutputFilename.c_str(); args[2] = tmp_output.c_str(); args[3] = 0; if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) { if (tmp_output.isBitcodeFile()) { sys::Path target(BitcodeOutputFilename); target.eraseFromDisk(); if (tmp_output.renamePathOnDisk(target, &ErrMsg)) PrintAndExit(ErrMsg, Composite.get(), 2); } else PrintAndExit("Post-link optimization output is not bitcode", Composite.get()); } else { PrintAndExit(ErrMsg, Composite.get()); } } } // If the user wants to generate a native executable, compile it from the // bitcode file. // // Otherwise, create a script that will run the bitcode through the JIT. if (Native) { // Name of the Assembly Language output file sys::Path AssemblyFile ( OutputFilename); AssemblyFile.appendSuffix("s"); // Mark the output files for removal. FileRemover AssemblyFileRemover(AssemblyFile.str()); sys::RemoveFileOnSignal(AssemblyFile); // Determine the locations of the llc and gcc programs. sys::Path llc = PrependMainExecutablePath("llc", argv[0], (void *)(intptr_t)&Optimize); if (llc.isEmpty()) PrintAndExit("Failed to find llc", Composite.get()); sys::Path gcc = sys::Program::FindProgramByName("gcc"); if (gcc.isEmpty()) PrintAndExit("Failed to find gcc", Composite.get()); // Generate an assembly language file for the bitcode. std::string ErrMsg; if (0 != GenerateAssembly(AssemblyFile.str(), BitcodeOutputFilename, llc, ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); if (0 != GenerateNative(OutputFilename, AssemblyFile.str(), NativeLinkItems, gcc, envp, ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); } else if (NativeCBE) { sys::Path CFile (OutputFilename); CFile.appendSuffix("cbe.c"); // Mark the output files for removal. FileRemover CFileRemover(CFile.str()); sys::RemoveFileOnSignal(CFile); // Determine the locations of the llc and gcc programs. sys::Path llc = PrependMainExecutablePath("llc", argv[0], (void *)(intptr_t)&Optimize); if (llc.isEmpty()) PrintAndExit("Failed to find llc", Composite.get()); sys::Path gcc = sys::Program::FindProgramByName("gcc"); if (gcc.isEmpty()) PrintAndExit("Failed to find gcc", Composite.get()); // Generate an assembly language file for the bitcode. std::string ErrMsg; if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); if (GenerateNative(OutputFilename, CFile.str(), NativeLinkItems, gcc, envp, ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); } else { EmitShellScript(argv, Composite.get()); } // Make the script executable... std::string ErrMsg; if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); // Make the bitcode file readable and directly executable in LLEE as well if (sys::Path(BitcodeOutputFilename).makeExecutableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); if (sys::Path(BitcodeOutputFilename).makeReadableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); } // Operations which may fail are now complete. BitcodeOutputRemover.releaseFile(); if (!LinkAsLibrary) OutputRemover.releaseFile(); // Graceful exit return 0; }
/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM /// bitcode file for the program. static void EmitShellScript(char **argv, Module *M) { if (Verbose) errs() << "Emitting Shell Script\n"; #if defined(_WIN32) // Windows doesn't support #!/bin/sh style shell scripts in .exe files. To // support windows systems, we copy the llvm-stub.exe executable from the // build tree to the destination file. std::string ErrMsg; sys::Path llvmstub = PrependMainExecutablePath("llvm-stub", argv[0], (void *)(intptr_t)&Optimize); if (llvmstub.isEmpty()) PrintAndExit("Could not find llvm-stub.exe executable!", M); if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg)) PrintAndExit(ErrMsg, M); return; #endif // Output the script to start the program... std::string ErrorInfo; tool_output_file Out2(OutputFilename.c_str(), ErrorInfo); if (!ErrorInfo.empty()) PrintAndExit(ErrorInfo, M); Out2.os() << "#!/bin/sh\n"; // Allow user to setenv LLVMINTERP if lli is not in their PATH. Out2.os() << "lli=${LLVMINTERP-lli}\n"; Out2.os() << "exec $lli \\\n"; // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib. LibPaths.push_back("/lib"); LibPaths.push_back("/usr/lib"); LibPaths.push_back("/usr/X11R6/lib"); // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a // shared object at all! See RH 8: plain text. std::vector<std::string>::iterator libc = std::find(Libraries.begin(), Libraries.end(), "c"); if (libc != Libraries.end()) Libraries.erase(libc); // List all the shared object (native) libraries this executable will need // on the command line, so that we don't have to do this manually! for (std::vector<std::string>::iterator i = Libraries.begin(), e = Libraries.end(); i != e; ++i) { // try explicit -L arguments first: sys::Path FullLibraryPath; for (cl::list<std::string>::const_iterator P = LibPaths.begin(), E = LibPaths.end(); P != E; ++P) { FullLibraryPath = *P; FullLibraryPath.appendComponent("lib" + *i); FullLibraryPath.appendSuffix(sys::Path::GetDLLSuffix()); if (!FullLibraryPath.isEmpty()) { if (!FullLibraryPath.isDynamicLibrary()) { // Not a native shared library; mark as invalid FullLibraryPath = sys::Path(); } else break; } } if (FullLibraryPath.isEmpty()) FullLibraryPath = sys::Path::FindLibrary(*i); if (!FullLibraryPath.isEmpty()) Out2.os() << " -load=" << FullLibraryPath.str() << " \\\n"; } Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; Out2.keep(); }