166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===- llvm-ld.cpp - LLVM 'ld' compatible linker --------------------------===// 266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// The LLVM Compiler Infrastructure 466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This file is distributed under the University of Illinois Open Source 666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// License. See LICENSE.TXT for details. 766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===// 966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 1066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This utility is intended to be compatible with GCC, and follows standard 1166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// system 'ld' conventions. As such, the default output file is ./a.out. 1266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Additionally, this program outputs a shell script that is used to invoke LLI 1366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// to execute the program. In this manner, the generated executable (a.out for 1466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// example), is directly executable, whereas the bitcode file actually lives in 1566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// the a.out.bc file generated by this program. 1666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 1766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Note that if someone (or a script) deletes the executable program generated, 1866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// the .bc file will be left around. Considering that this is a temporary hack, 1966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// I'm not too worried about this. 2066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// 2166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===// 2266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 2366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/LinkAllVMCore.h" 2466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Linker.h" 2566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/LLVMContext.h" 2666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Program.h" 2766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Module.h" 2866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/PassManager.h" 2966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Bitcode/ReaderWriter.h" 3066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Target/TargetData.h" 3166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Target/TargetMachine.h" 3266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/CommandLine.h" 3366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/FileUtilities.h" 3466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/ManagedStatic.h" 3566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/MemoryBuffer.h" 3666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/PrettyStackTrace.h" 3766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/SystemUtils.h" 3866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/ToolOutputFile.h" 3966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Signals.h" 4066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Config/config.h" 4166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include <memory> 4266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include <cstring> 4366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanusing namespace llvm; 4466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 4566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Rightly this should go in a header file but it just seems such a waste. 4666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace llvm { 4766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanextern void Optimize(Module*); 4866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 4966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 5066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Input/Output Options 5166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore, 5266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("<input bitcode files>")); 5366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 5466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<std::string> OutputFilename("o", cl::init("a.out"), 5566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Override output filename"), 5666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::value_desc("filename")); 5766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 5866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<std::string> BitcodeOutputFilename("b", cl::init(""), 5966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Override bitcode output filename"), 6066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::value_desc("filename")); 6166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 6266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool> Verbose("v", 6366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Print information about actions taken")); 6466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 6566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::list<std::string> LibPaths("L", cl::Prefix, 6666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Specify a library search path"), 6766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::value_desc("directory")); 6866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 6966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::list<std::string> FrameworkPaths("F", cl::Prefix, 7066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Specify a framework search path"), 7166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::value_desc("directory")); 7266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 7366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::list<std::string> Libraries("l", cl::Prefix, 7466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Specify libraries to link to"), 7566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::value_desc("library prefix")); 7666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 7766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::list<std::string> Frameworks("framework", 7866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Specify frameworks to link to"), 7966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::value_desc("framework")); 8066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 8166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Options to control the linking, optimization, and code gen processes 8266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool> LinkAsLibrary("link-as-library", 8366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Link the .bc files together as a library, not an executable")); 8466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 8566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::alias Relink("r", cl::aliasopt(LinkAsLibrary), 8666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Alias for -link-as-library")); 8766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 8866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool> Native("native", 8966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Generate a native binary instead of a shell script")); 9066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 9166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool>NativeCBE("native-cbe", 9266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Generate a native binary with the C backend and GCC")); 9366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 9466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::list<std::string> PostLinkOpts("post-link-opts", 9566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::value_desc("path"), 9666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Run one or more optimization programs after linking")); 9766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 9866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::list<std::string> XLinker("Xlinker", cl::value_desc("option"), 9966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Pass options to the system linker")); 10066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 10166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Compatibility options that llvm-ld ignores but are supported for 10266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// compatibility with LD 10366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<std::string> CO3("soname", cl::Hidden, 10466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Compatibility option: ignored")); 10566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 10666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<std::string> CO4("version-script", cl::Hidden, 10766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Compatibility option: ignored")); 10866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 10966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool> CO5("eh-frame-hdr", cl::Hidden, 11066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Compatibility option: ignored")); 11166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 11266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<std::string> CO6("h", cl::Hidden, 11366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Compatibility option: ignored")); 11466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 11566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool> CO7("start-group", cl::Hidden, 11666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Compatibility option: ignored")); 11766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 11866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool> CO8("end-group", cl::Hidden, 11966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Compatibility option: ignored")); 12066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 12166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<std::string> CO9("m", cl::Hidden, 12266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::desc("Compatibility option: ignored")); 12366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 12466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// This is just for convenience so it doesn't have to be passed around 12566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// everywhere. 12666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic std::string progname; 12766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 12866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// FileRemover objects to clean up output files in the event of an error. 12966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic FileRemover OutputRemover; 13066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic FileRemover BitcodeOutputRemover; 13166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 13266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// PrintAndExit - Prints a message to standard error and exits with error code 13366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 13466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Inputs: 13566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Message - The message to print to standard error. 13666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 13766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void PrintAndExit(const std::string &Message, Module *M, int errcode = 1) { 13866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errs() << progname << ": " << Message << "\n"; 13966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman delete M; 14066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman llvm_shutdown(); 14166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman exit(errcode); 14266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 14366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 14466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void PrintCommand(const std::vector<const char*> &args) { 14566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::vector<const char*>::const_iterator I = args.begin(), E = args.end(); 14666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (; I != E; ++I) 14766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (*I) 14866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errs() << "'" << *I << "'" << " "; 14966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errs() << "\n"; 15066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 15166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 15266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// CopyEnv - This function takes an array of environment variables and makes a 15366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// copy of it. This copy can then be manipulated any way the caller likes 15466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// without affecting the process's real environment. 15566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 15666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Inputs: 15766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// envp - An array of C strings containing an environment. 15866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 15966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Return value: 16066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// NULL - An error occurred. 16166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 16266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Otherwise, a pointer to a new array of C strings is returned. Every string 16366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// in the array is a duplicate of the one in the original array (i.e. we do 16466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// not copy the char *'s from one array to another). 16566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 16666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic char ** CopyEnv(char ** const envp) { 16766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Count the number of entries in the old list; 16866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman unsigned entries; // The number of entries in the old environment list 16966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (entries = 0; envp[entries] != NULL; entries++) 17066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman /*empty*/; 17166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 17266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add one more entry for the NULL pointer that ends the list. 17366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ++entries; 17466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 17566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // If there are no entries at all, just return NULL. 17666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (entries == 0) 17766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 17866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 17966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Allocate a new environment list. 18066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman char **newenv = new char* [entries]; 18166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (newenv == NULL) 18266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return NULL; 18366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 18466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Make a copy of the list. Don't forget the NULL that ends the list. 18566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman entries = 0; 18666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman while (envp[entries] != NULL) { 18766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman size_t len = strlen(envp[entries]) + 1; 18866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman newenv[entries] = new char[len]; 18966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman memcpy(newenv[entries], envp[entries], len); 19066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman ++entries; 19166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 19266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman newenv[entries] = NULL; 19366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 19466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return newenv; 19566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 19666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 19766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 19866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// RemoveEnv - Remove the specified environment variable from the environment 19966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// array. 20066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 20166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Inputs: 20266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// name - The name of the variable to remove. It cannot be NULL. 20366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// envp - The array of environment variables. It cannot be NULL. 20466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 20566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Notes: 20666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// This is mainly done because functions to remove items from the environment 20766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// are not available across all platforms. In particular, Solaris does not 20866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// seem to have an unsetenv() function or a setenv() function (or they are 20966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// undocumented if they do exist). 21066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 21166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void RemoveEnv(const char * name, char ** const envp) { 21266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned index=0; envp[index] != NULL; index++) { 21366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Find the first equals sign in the array and make it an EOS character. 21466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman char *p = strchr (envp[index], '='); 21566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (p == NULL) 21666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman continue; 21766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 21866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman *p = '\0'; 21966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 22066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Compare the two strings. If they are equal, zap this string. 22166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Otherwise, restore it. 22266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!strcmp(name, envp[index])) 22366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman *envp[index] = '\0'; 22466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 22566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman *p = '='; 22666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 22766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 22866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 22966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 23066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 23166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// GenerateBitcode - generates a bitcode file from the module provided 23266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid GenerateBitcode(Module* M, const std::string& FileName) { 23366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 23466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Verbose) 23566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errs() << "Generating Bitcode To " << FileName << '\n'; 23666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 23766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Create the output file. 23866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string ErrorInfo; 23966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman tool_output_file Out(FileName.c_str(), ErrorInfo, 24066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman raw_fd_ostream::F_Binary); 24166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!ErrorInfo.empty()) { 24266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrorInfo, M); 24366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 24466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 24566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 24666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Write it out 24766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman WriteBitcodeToFile(M, Out.os()); 24866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Out.keep(); 24966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 25066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 25166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// GenerateAssembly - generates a native assembly language source file from the 25266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// specified bitcode file. 25366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 25466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Inputs: 25566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// InputFilename - The name of the input bitcode file. 25666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// OutputFilename - The name of the file to generate. 25766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// llc - The pathname to use for LLC. 25866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// envp - The environment to use when running LLC. 25966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 26066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Return non-zero value on error. 26166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 26266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic int GenerateAssembly(const std::string &OutputFilename, 26366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const std::string &InputFilename, 26466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const sys::Path &llc, 26566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string &ErrMsg ) { 26666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Run LLC to convert the bitcode file into assembly code. 26766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::vector<const char*> args; 26866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(llc.c_str()); 26966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // We will use GCC to assemble the program so set the assembly syntax to AT&T, 27066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // regardless of what the target in the bitcode file is. 27166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-x86-asm-syntax=att"); 27266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-o"); 27366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(OutputFilename.c_str()); 27466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(InputFilename.c_str()); 27566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(0); 27666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 27766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Verbose) { 27866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errs() << "Generating Assembly With: \n"; 27966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintCommand(args); 28066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 28166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 28266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return sys::Program::ExecuteAndWait(llc, &args[0], 0, 0, 0, 0, &ErrMsg); 28366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 28466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 28566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// GenerateCFile - generates a C source file from the specified bitcode file. 28666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic int GenerateCFile(const std::string &OutputFile, 28766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const std::string &InputFile, 28866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const sys::Path &llc, 28966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string& ErrMsg) { 29066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Run LLC to convert the bitcode file into C. 29166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::vector<const char*> args; 29266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(llc.c_str()); 29366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-march=c"); 29466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-o"); 29566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(OutputFile.c_str()); 29666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(InputFile.c_str()); 29766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(0); 29866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 29966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Verbose) { 30066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errs() << "Generating C Source With: \n"; 30166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintCommand(args); 30266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 30366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 30466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return sys::Program::ExecuteAndWait(llc, &args[0], 0, 0, 0, 0, &ErrMsg); 30566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 30666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 30766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// GenerateNative - generates a native object file from the 30866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// specified bitcode file. 30966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 31066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Inputs: 31166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// InputFilename - The name of the input bitcode file. 31266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// OutputFilename - The name of the file to generate. 31366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// NativeLinkItems - The native libraries, files, code with which to link 31466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// LibPaths - The list of directories in which to find libraries. 31566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// FrameworksPaths - The list of directories in which to find frameworks. 31666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Frameworks - The list of frameworks (dynamic libraries) 31766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// gcc - The pathname to use for GGC. 31866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// envp - A copy of the process's current environment. 31966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 32066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Outputs: 32166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// None. 32266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 32366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Returns non-zero value on error. 32466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// 32566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic int GenerateNative(const std::string &OutputFilename, 32666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const std::string &InputFilename, 32766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const Linker::ItemList &LinkItems, 32866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const sys::Path &gcc, char ** const envp, 32966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string& ErrMsg) { 33066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Remove these environment variables from the environment of the 33166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // programs that we will execute. It appears that GCC sets these 33266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // environment variables so that the programs it uses can configure 33366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // themselves identically. 33466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // 33566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // However, when we invoke GCC below, we want it to use its normal 33666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // configuration. Hence, we must sanitize its environment. 33766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman char ** clean_env = CopyEnv(envp); 33866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (clean_env == NULL) 33966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return 1; 34066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman RemoveEnv("LIBRARY_PATH", clean_env); 34166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman RemoveEnv("COLLECT_GCC_OPTIONS", clean_env); 34266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman RemoveEnv("GCC_EXEC_PREFIX", clean_env); 34366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman RemoveEnv("COMPILER_PATH", clean_env); 34466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman RemoveEnv("COLLECT_GCC", clean_env); 34566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 34666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 34766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Run GCC to assemble and link the program into native code. 34866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // 34966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Note: 35066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // We can't just assemble and link the file with the system assembler 35166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // and linker because we don't know where to put the _start symbol. 35266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // GCC mysteriously knows how to do it. 35366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::vector<std::string> args; 35466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(gcc.c_str()); 35566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-fno-strict-aliasing"); 35666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-O3"); 35766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-o"); 35866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(OutputFilename); 35966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(InputFilename); 36066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 36166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add in the library and framework paths 36266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned index = 0; index < LibPaths.size(); index++) { 36366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-L" + LibPaths[index]); 36466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 36566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned index = 0; index < FrameworkPaths.size(); index++) { 36666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-F" + FrameworkPaths[index]); 36766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 36866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 36966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add the requested options 37066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned index = 0; index < XLinker.size(); index++) 37166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(XLinker[index]); 37266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 37366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add in the libraries to link. 37466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned index = 0; index < LinkItems.size(); index++) 37566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (LinkItems[index].first != "crtend") { 37666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (LinkItems[index].second) 37766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-l" + LinkItems[index].first); 37866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 37966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(LinkItems[index].first); 38066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 38166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 38266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add in frameworks to link. 38366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned index = 0; index < Frameworks.size(); index++) { 38466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back("-framework"); 38566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args.push_back(Frameworks[index]); 38666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 38766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 38866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Now that "args" owns all the std::strings for the arguments, call the c_str 38966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // method to get the underlying string array. We do this game so that the 39066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // std::string array is guaranteed to outlive the const char* array. 39166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::vector<const char *> Args; 39266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned i = 0, e = args.size(); i != e; ++i) 39366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Args.push_back(args[i].c_str()); 39466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Args.push_back(0); 39566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 39666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Verbose) { 39766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errs() << "Generating Native Executable With:\n"; 39866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintCommand(Args); 39966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 40066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 40166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Run the compiler to assembly and link together the program. 40266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman int R = sys::Program::ExecuteAndWait( 40366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman gcc, &Args[0], const_cast<const char **>(clean_env), 0, 0, 0, &ErrMsg); 40466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman delete [] clean_env; 40566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return R; 40666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 40766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 40866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM 40966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// bitcode file for the program. 41066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void EmitShellScript(char **argv, Module *M) { 41166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Verbose) 41266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman errs() << "Emitting Shell Script\n"; 41366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#if defined(_WIN32) 41466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Windows doesn't support #!/bin/sh style shell scripts in .exe files. To 41566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // support windows systems, we copy the llvm-stub.exe executable from the 41666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // build tree to the destination file. 41766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string ErrMsg; 41866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path llvmstub = PrependMainExecutablePath("llvm-stub", argv[0], 41966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman (void *)(intptr_t)&Optimize); 42066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (llvmstub.isEmpty()) 42166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit("Could not find llvm-stub.exe executable!", M); 42266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 42366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg)) 42466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, M); 42566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 42666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return; 42766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#endif 42866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 42966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Output the script to start the program... 43066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string ErrorInfo; 43166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman tool_output_file Out2(OutputFilename.c_str(), ErrorInfo); 43266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!ErrorInfo.empty()) 43366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrorInfo, M); 43466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 43566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Out2.os() << "#!/bin/sh\n"; 43666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Allow user to setenv LLVMINTERP if lli is not in their PATH. 43766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Out2.os() << "lli=${LLVMINTERP-lli}\n"; 43866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Out2.os() << "exec $lli \\\n"; 43966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib. 44066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman LibPaths.push_back("/lib"); 44166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman LibPaths.push_back("/usr/lib"); 44266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman LibPaths.push_back("/usr/X11R6/lib"); 44366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a 44466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // shared object at all! See RH 8: plain text. 44566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::vector<std::string>::iterator libc = 44666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::find(Libraries.begin(), Libraries.end(), "c"); 44766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (libc != Libraries.end()) Libraries.erase(libc); 44866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // List all the shared object (native) libraries this executable will need 44966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // on the command line, so that we don't have to do this manually! 45066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (std::vector<std::string>::iterator i = Libraries.begin(), 45166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman e = Libraries.end(); i != e; ++i) { 45266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // try explicit -L arguments first: 45366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path FullLibraryPath; 45466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (cl::list<std::string>::const_iterator P = LibPaths.begin(), 45566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman E = LibPaths.end(); P != E; ++P) { 45666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman FullLibraryPath = *P; 45766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman FullLibraryPath.appendComponent("lib" + *i); 45866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman FullLibraryPath.appendSuffix(sys::Path::GetDLLSuffix()); 45966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!FullLibraryPath.isEmpty()) { 46066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!FullLibraryPath.isDynamicLibrary()) { 46166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Not a native shared library; mark as invalid 46266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman FullLibraryPath = sys::Path(); 46366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else break; 46466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 46566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 46666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (FullLibraryPath.isEmpty()) 46766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman FullLibraryPath = sys::Path::FindLibrary(*i); 46866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!FullLibraryPath.isEmpty()) 46966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Out2.os() << " -load=" << FullLibraryPath.str() << " \\\n"; 47066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 47166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; 47266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Out2.keep(); 47366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 47466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 47566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// BuildLinkItems -- This function generates a LinkItemList for the LinkItems 47666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// linker function by combining the Files and Libraries in the order they were 47766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// declared on the command line. 47866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void BuildLinkItems( 47966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Linker::ItemList& Items, 48066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const cl::list<std::string>& Files, 48166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const cl::list<std::string>& Libraries) { 48266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 48366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Build the list of linkage items for LinkItems. 48466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 48566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::list<std::string>::const_iterator fileIt = Files.begin(); 48666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::list<std::string>::const_iterator libIt = Libraries.begin(); 48766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 48866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman int libPos = -1, filePos = -1; 48966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman while ( libIt != Libraries.end() || fileIt != Files.end() ) { 49066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (libIt != Libraries.end()) 49166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman libPos = Libraries.getPosition(libIt - Libraries.begin()); 49266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 49366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman libPos = -1; 49466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (fileIt != Files.end()) 49566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman filePos = Files.getPosition(fileIt - Files.begin()); 49666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman else 49766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman filePos = -1; 49866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 49966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (filePos != -1 && (libPos == -1 || filePos < libPos)) { 50066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add a source file 50166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Items.push_back(std::make_pair(*fileIt++, false)); 50266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else if (libPos != -1 && (filePos == -1 || libPos < filePos)) { 50366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add a library 50466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Items.push_back(std::make_pair(*libIt++, true)); 50566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 50666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 50766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 50866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 50966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint main(int argc, char **argv, char **envp) { 51066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Print a stack trace if we signal out. 51166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::PrintStackTraceOnErrorSignal(); 51266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrettyStackTraceProgram X(argc, argv); 51366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 51466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman LLVMContext &Context = getGlobalContext(); 51566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 51666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 51766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Initialize passes 51866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PassRegistry &Registry = *PassRegistry::getPassRegistry(); 51966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman initializeCore(Registry); 52066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman initializeScalarOpts(Registry); 52166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman initializeIPO(Registry); 52266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman initializeAnalysis(Registry); 52366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman initializeIPA(Registry); 52466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman initializeTransformUtils(Registry); 52566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman initializeInstCombine(Registry); 52666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman initializeTarget(Registry); 52766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 52866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Initial global variable above for convenience printing of program name. 52966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman progname = sys::path::stem(argv[0]); 53066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 53166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Parse the command line options 53266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); 53366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 53466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#if defined(_WIN32) || defined(__CYGWIN__) 53566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!LinkAsLibrary) { 53666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Default to "a.exe" instead of "a.out". 53766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (OutputFilename.getNumOccurrences() == 0) 53866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OutputFilename = "a.exe"; 53966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 54066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // If there is no suffix add an "exe" one. 54166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (sys::path::extension(OutputFilename).empty()) 54266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OutputFilename.append(".exe"); 54366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 54466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#endif 54566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 54666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Generate the bitcode for the optimized module. 54766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // If -b wasn't specified, use the name specified 54866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // with -o to construct BitcodeOutputFilename. 54966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (BitcodeOutputFilename.empty()) { 55066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman BitcodeOutputFilename = OutputFilename; 55166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!LinkAsLibrary) BitcodeOutputFilename += ".bc"; 55266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 55366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 55466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Arrange for the bitcode output file to be deleted on any errors. 55566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman BitcodeOutputRemover.setFile(BitcodeOutputFilename); 55666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename)); 55766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 55866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Arrange for the output file to be deleted on any errors. 55966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!LinkAsLibrary) { 56066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OutputRemover.setFile(OutputFilename); 56166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::RemoveFileOnSignal(sys::Path(OutputFilename)); 56266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 56366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 56466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Construct a Linker (now that Verbose is set) 56566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Linker TheLinker(progname, OutputFilename, Context, Verbose); 56666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 56766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Keep track of the native link items (versus the bitcode items) 56866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Linker::ItemList NativeLinkItems; 56966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 57066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Add library paths to the linker 57166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman TheLinker.addPaths(LibPaths); 57266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman TheLinker.addSystemPaths(); 57366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 57466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Remove any consecutive duplicates of the same library... 57566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), 57666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Libraries.end()); 57766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 57866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (LinkAsLibrary) { 57966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::vector<sys::Path> Files; 58066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (unsigned i = 0; i < InputFilenames.size(); ++i ) 58166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Files.push_back(sys::Path(InputFilenames[i])); 58266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (TheLinker.LinkInFiles(Files)) 58366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return 1; // Error already printed 58466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 58566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // The libraries aren't linked in but are noted as "dependent" in the 58666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // module. 58766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (cl::list<std::string>::const_iterator I = Libraries.begin(), 58866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman E = Libraries.end(); I != E ; ++I) { 58966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman TheLinker.getModule()->addLibrary(*I); 59066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 59166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else { 59266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Build a list of the items from our command line 59366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Linker::ItemList Items; 59466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman BuildLinkItems(Items, InputFilenames, Libraries); 59566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 59666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Link all the items together 59766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (TheLinker.LinkInItems(Items, NativeLinkItems) ) 59866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return 1; // Error already printed 59966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 60066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 60166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::auto_ptr<Module> Composite(TheLinker.releaseModule()); 60266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 60366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Optimize the module 60466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Optimize(Composite.get()); 60566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 60666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Generate the bitcode output. 60766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman GenerateBitcode(Composite.get(), BitcodeOutputFilename); 60866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 60966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // If we are not linking a library, generate either a native executable 61066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // or a JIT shell script, depending upon what the user wants. 61166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!LinkAsLibrary) { 61266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // If the user wants to run a post-link optimization, run it now. 61366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!PostLinkOpts.empty()) { 61466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::vector<std::string> opts = PostLinkOpts; 61566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman for (std::vector<std::string>::iterator I = opts.begin(), 61666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman E = opts.end(); I != E; ++I) { 61766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path prog(*I); 61866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!prog.canExecute()) { 61966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman prog = sys::Program::FindProgramByName(*I); 62066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (prog.isEmpty()) 62166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(std::string("Optimization program '") + *I + 62266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman "' is not found or not executable.", Composite.get()); 62366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 62466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Get the program arguments 62566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path tmp_output("opt_result"); 62666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string ErrMsg; 62766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg)) 62866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 62966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 63066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman const char* args[4]; 63166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args[0] = I->c_str(); 63266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args[1] = BitcodeOutputFilename.c_str(); 63366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args[2] = tmp_output.c_str(); 63466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman args[3] = 0; 63566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) { 63666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (tmp_output.isBitcodeFile()) { 63766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path target(BitcodeOutputFilename); 63866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman target.eraseFromDisk(); 63966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (tmp_output.renamePathOnDisk(target, &ErrMsg)) 64066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get(), 2); 64166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else 64266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit("Post-link optimization output is not bitcode", 64366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman Composite.get()); 64466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else { 64566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 64666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 64766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 64866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 64966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 65066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // If the user wants to generate a native executable, compile it from the 65166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // bitcode file. 65266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // 65366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Otherwise, create a script that will run the bitcode through the JIT. 65466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (Native) { 65566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Name of the Assembly Language output file 65666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path AssemblyFile ( OutputFilename); 65766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman AssemblyFile.appendSuffix("s"); 65866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 65966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Mark the output files for removal. 66066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman FileRemover AssemblyFileRemover(AssemblyFile.str()); 66166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::RemoveFileOnSignal(AssemblyFile); 66266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 66366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Determine the locations of the llc and gcc programs. 66466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path llc = PrependMainExecutablePath("llc", argv[0], 66566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman (void *)(intptr_t)&Optimize); 66666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (llc.isEmpty()) 66766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit("Failed to find llc", Composite.get()); 66866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 66966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path gcc = sys::Program::FindProgramByName("gcc"); 67066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (gcc.isEmpty()) 67166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit("Failed to find gcc", Composite.get()); 67266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 67366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Generate an assembly language file for the bitcode. 67466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string ErrMsg; 67566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (0 != GenerateAssembly(AssemblyFile.str(), BitcodeOutputFilename, 67666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman llc, ErrMsg)) 67766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 67866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 67966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (0 != GenerateNative(OutputFilename, AssemblyFile.str(), 68066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NativeLinkItems, gcc, envp, ErrMsg)) 68166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 68266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else if (NativeCBE) { 68366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path CFile (OutputFilename); 68466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman CFile.appendSuffix("cbe.c"); 68566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 68666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Mark the output files for removal. 68766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman FileRemover CFileRemover(CFile.str()); 68866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::RemoveFileOnSignal(CFile); 68966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 69066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Determine the locations of the llc and gcc programs. 69166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path llc = PrependMainExecutablePath("llc", argv[0], 69266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman (void *)(intptr_t)&Optimize); 69366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (llc.isEmpty()) 69466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit("Failed to find llc", Composite.get()); 69566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 69666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman sys::Path gcc = sys::Program::FindProgramByName("gcc"); 69766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (gcc.isEmpty()) 69866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit("Failed to find gcc", Composite.get()); 69966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 70066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Generate an assembly language file for the bitcode. 70166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string ErrMsg; 70266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg)) 70366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 70466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 70566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (GenerateNative(OutputFilename, CFile.str(), 70666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman NativeLinkItems, gcc, envp, ErrMsg)) 70766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 70866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } else { 70966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman EmitShellScript(argv, Composite.get()); 71066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 71166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 71266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Make the script executable... 71366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman std::string ErrMsg; 71466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg)) 71566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 71666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 71766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Make the bitcode file readable and directly executable in LLEE as well 71866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (sys::Path(BitcodeOutputFilename).makeExecutableOnDisk(&ErrMsg)) 71966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 72066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 72166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (sys::Path(BitcodeOutputFilename).makeReadableOnDisk(&ErrMsg)) 72266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman PrintAndExit(ErrMsg, Composite.get()); 72366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman } 72466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 72566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Operations which may fail are now complete. 72666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman BitcodeOutputRemover.releaseFile(); 72766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman if (!LinkAsLibrary) 72866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman OutputRemover.releaseFile(); 72966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman 73066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman // Graceful exit 73166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman return 0; 73266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman} 733