diff options
Diffstat (limited to 'tools/llvm-ld/llvm-ld.cpp')
-rw-r--r-- | tools/llvm-ld/llvm-ld.cpp | 103 |
1 files changed, 56 insertions, 47 deletions
diff --git a/tools/llvm-ld/llvm-ld.cpp b/tools/llvm-ld/llvm-ld.cpp index 2b9d255..ef3c250 100644 --- a/tools/llvm-ld/llvm-ld.cpp +++ b/tools/llvm-ld/llvm-ld.cpp @@ -12,7 +12,7 @@ // Additionally, this program outputs a shell script that is used to invoke LLI // to execute the program. In this manner, the generated executable (a.out for // example), is directly executable, whereas the bitcode file actually lives in -// the a.out.bc file generated by this program. Also, Force is on by default. +// the a.out.bc file generated by this program. // // Note that if someone (or a script) deletes the executable program generated, // the .bc file will be left around. Considering that this is a temporary hack, @@ -29,21 +29,24 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/Streams.h" #include "llvm/Support/SystemUtils.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/System/Signals.h" #include "llvm/Config/config.h" -#include <fstream> #include <memory> #include <cstring> using namespace llvm; +// Rightly this should go in a header file but it just seems such a waste. +namespace llvm { +extern void Optimize(Module*); +} + // Input/Output Options static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore, cl::desc("<input bitcode files>")); @@ -52,6 +55,10 @@ static cl::opt<std::string> OutputFilename("o", cl::init("a.out"), cl::desc("Override output filename"), cl::value_desc("filename")); +static cl::opt<std::string> BitcodeOutputFilename("b", cl::init(""), + cl::desc("Override bitcode output filename"), + cl::value_desc("filename")); + static cl::opt<bool> Verbose("v", cl::desc("Print information about actions taken")); @@ -124,7 +131,7 @@ static std::string progname; /// Message - The message to print to standard error. /// static void PrintAndExit(const std::string &Message, int errcode = 1) { - cerr << progname << ": " << Message << "\n"; + errs() << progname << ": " << Message << "\n"; llvm_shutdown(); exit(errcode); } @@ -133,8 +140,8 @@ static void PrintCommand(const std::vector<const char*> &args) { std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); for (; I != E; ++I) if (*I) - cout << "'" << *I << "'" << " "; - cout << "\n" << std::flush; + outs() << "'" << *I << "'" << " "; + outs() << "\n"; outs().flush(); } /// CopyEnv - This function takes an array of environment variables and makes a @@ -219,14 +226,14 @@ static void RemoveEnv(const char * name, char ** const envp) { void GenerateBitcode(Module* M, const std::string& FileName) { if (Verbose) - cout << "Generating Bitcode To " << FileName << '\n'; + outs() << "Generating Bitcode To " << FileName << '\n'; // Create the output file. - std::ios::openmode io_mode = std::ios::out | std::ios::trunc | - std::ios::binary; - std::ofstream Out(FileName.c_str(), io_mode); - if (!Out.good()) - PrintAndExit("error opening '" + FileName + "' for writing!"); + std::string ErrorInfo; + raw_fd_ostream Out(FileName.c_str(), ErrorInfo, + raw_fd_ostream::F_Binary); + if (!ErrorInfo.empty()) + PrintAndExit(ErrorInfo); // Ensure that the bitcode file gets removed from the disk if we get a // terminating signal. @@ -267,7 +274,7 @@ static int GenerateAssembly(const std::string &OutputFilename, args.push_back(0); if (Verbose) { - cout << "Generating Assembly With: \n"; + outs() << "Generating Assembly With: \n"; PrintCommand(args); } @@ -290,7 +297,7 @@ static int GenerateCFile(const std::string &OutputFile, args.push_back(0); if (Verbose) { - cout << "Generating C Source With: \n"; + outs() << "Generating C Source With: \n"; PrintCommand(args); } @@ -387,7 +394,7 @@ static int GenerateNative(const std::string &OutputFilename, Args.push_back(0); if (Verbose) { - cout << "Generating Native Executable With:\n"; + outs() << "Generating Native Executable With:\n"; PrintCommand(Args); } @@ -402,13 +409,14 @@ static int GenerateNative(const std::string &OutputFilename, /// bitcode file for the program. static void EmitShellScript(char **argv) { if (Verbose) - cout << "Emitting Shell Script\n"; + outs() << "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]); + sys::Path llvmstub = FindExecutable("llvm-stub.exe", argv[0], + (void *)(intptr_t)&Optimize); if (llvmstub.isEmpty()) PrintAndExit("Could not find llvm-stub.exe executable!"); @@ -419,9 +427,10 @@ static void EmitShellScript(char **argv) { #endif // Output the script to start the program... - std::ofstream Out2(OutputFilename.c_str()); - if (!Out2.good()) - PrintAndExit("error opening '" + OutputFilename + "' for writing!"); + std::string ErrorInfo; + raw_fd_ostream Out2(OutputFilename.c_str(), ErrorInfo); + if (!ErrorInfo.empty()) + PrintAndExit(ErrorInfo); Out2 << "#!/bin/sh\n"; // Allow user to setenv LLVMINTERP if lli is not in their PATH. @@ -457,9 +466,9 @@ static void EmitShellScript(char **argv) { if (FullLibraryPath.isEmpty()) FullLibraryPath = sys::Path::FindLibrary(*i); if (!FullLibraryPath.isEmpty()) - Out2 << " -load=" << FullLibraryPath.toString() << " \\\n"; + Out2 << " -load=" << FullLibraryPath.str() << " \\\n"; } - Out2 << " $0.bc ${1+\"$@\"}\n"; + Out2 << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; Out2.close(); } @@ -497,17 +506,12 @@ static void BuildLinkItems( } } -// Rightly this should go in a header file but it just seems such a waste. -namespace llvm { -extern void Optimize(Module*); -} - int main(int argc, char **argv, char **envp) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); - LLVMContext Context; + LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. try { // Initial global variable above for convenience printing of program name. @@ -568,16 +572,20 @@ int main(int argc, char **argv, char **envp) { sys::Path ExeFile( OutputFilename ); if (ExeFile.getSuffix() == "") { ExeFile.appendSuffix("exe"); - OutputFilename = ExeFile.toString(); + OutputFilename = ExeFile.str(); } } #endif // Generate the bitcode for the optimized module. - std::string RealBitcodeOutput = OutputFilename; + // If -b wasn't specified, use the name specified + // with -o to construct BitcodeOutputFilename. + if (BitcodeOutputFilename.empty()) { + BitcodeOutputFilename = OutputFilename; + if (!LinkAsLibrary) BitcodeOutputFilename += ".bc"; + } - if (!LinkAsLibrary) RealBitcodeOutput += ".bc"; - GenerateBitcode(Composite.get(), RealBitcodeOutput); + 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. @@ -602,12 +610,12 @@ int main(int argc, char **argv, char **envp) { const char* args[4]; args[0] = I->c_str(); - args[1] = RealBitcodeOutput.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() || tmp_output.isBitcodeFile()) { - sys::Path target(RealBitcodeOutput); + sys::Path target(BitcodeOutputFilename); target.eraseFromDisk(); if (tmp_output.renamePathOnDisk(target, &ErrMsg)) PrintAndExit(ErrMsg, 2); @@ -633,21 +641,22 @@ int main(int argc, char **argv, char **envp) { sys::RemoveFileOnSignal(sys::Path(OutputFilename)); // Determine the locations of the llc and gcc programs. - sys::Path llc = FindExecutable("llc", argv[0]); + sys::Path llc = FindExecutable("llc", argv[0], + (void *)(intptr_t)&Optimize); if (llc.isEmpty()) PrintAndExit("Failed to find llc"); - sys::Path gcc = FindExecutable("gcc", argv[0]); + sys::Path gcc = sys::Program::FindProgramByName("gcc"); if (gcc.isEmpty()) PrintAndExit("Failed to find gcc"); // Generate an assembly language file for the bitcode. std::string ErrMsg; - if (0 != GenerateAssembly(AssemblyFile.toString(), RealBitcodeOutput, + if (0 != GenerateAssembly(AssemblyFile.str(), BitcodeOutputFilename, llc, ErrMsg)) PrintAndExit(ErrMsg); - if (0 != GenerateNative(OutputFilename, AssemblyFile.toString(), + if (0 != GenerateNative(OutputFilename, AssemblyFile.str(), NativeLinkItems, gcc, envp, ErrMsg)) PrintAndExit(ErrMsg); @@ -662,22 +671,22 @@ int main(int argc, char **argv, char **envp) { sys::RemoveFileOnSignal(sys::Path(OutputFilename)); // Determine the locations of the llc and gcc programs. - sys::Path llc = FindExecutable("llc", argv[0]); + sys::Path llc = FindExecutable("llc", argv[0], + (void *)(intptr_t)&Optimize); if (llc.isEmpty()) PrintAndExit("Failed to find llc"); - sys::Path gcc = FindExecutable("gcc", argv[0]); + sys::Path gcc = sys::Program::FindProgramByName("gcc"); if (gcc.isEmpty()) PrintAndExit("Failed to find gcc"); // Generate an assembly language file for the bitcode. std::string ErrMsg; - if (0 != GenerateCFile( - CFile.toString(), RealBitcodeOutput, llc, ErrMsg)) + if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg)) PrintAndExit(ErrMsg); - if (0 != GenerateNative(OutputFilename, CFile.toString(), - NativeLinkItems, gcc, envp, ErrMsg)) + if (GenerateNative(OutputFilename, CFile.str(), + NativeLinkItems, gcc, envp, ErrMsg)) PrintAndExit(ErrMsg); // Remove the assembly language file. @@ -693,10 +702,10 @@ int main(int argc, char **argv, char **envp) { PrintAndExit(ErrMsg); // Make the bitcode file readable and directly executable in LLEE as well - if (sys::Path(RealBitcodeOutput).makeExecutableOnDisk(&ErrMsg)) + if (sys::Path(BitcodeOutputFilename).makeExecutableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg); - if (sys::Path(RealBitcodeOutput).makeReadableOnDisk(&ErrMsg)) + if (sys::Path(BitcodeOutputFilename).makeReadableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg); } } catch (const std::string& msg) { |