Home | History | Annotate | Download | only in bugpoint
      1 //===-- ToolRunner.cpp ----------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the interfaces described in the ToolRunner.h file.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #define DEBUG_TYPE "toolrunner"
     15 #include "ToolRunner.h"
     16 #include "llvm/Config/config.h"   // for HAVE_LINK_R
     17 #include "llvm/Support/CommandLine.h"
     18 #include "llvm/Support/Debug.h"
     19 #include "llvm/Support/FileSystem.h"
     20 #include "llvm/Support/FileUtilities.h"
     21 #include "llvm/Support/Program.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 #include <fstream>
     24 #include <sstream>
     25 using namespace llvm;
     26 
     27 namespace llvm {
     28   cl::opt<bool>
     29   SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files"));
     30 }
     31 
     32 namespace {
     33   cl::opt<std::string>
     34   RemoteClient("remote-client",
     35                cl::desc("Remote execution client (rsh/ssh)"));
     36 
     37   cl::opt<std::string>
     38   RemoteHost("remote-host",
     39              cl::desc("Remote execution (rsh/ssh) host"));
     40 
     41   cl::opt<std::string>
     42   RemotePort("remote-port",
     43              cl::desc("Remote execution (rsh/ssh) port"));
     44 
     45   cl::opt<std::string>
     46   RemoteUser("remote-user",
     47              cl::desc("Remote execution (rsh/ssh) user id"));
     48 
     49   cl::opt<std::string>
     50   RemoteExtra("remote-extra-options",
     51           cl::desc("Remote execution (rsh/ssh) extra options"));
     52 }
     53 
     54 /// RunProgramWithTimeout - This function provides an alternate interface
     55 /// to the sys::Program::ExecuteAndWait interface.
     56 /// @see sys::Program::ExecuteAndWait
     57 static int RunProgramWithTimeout(StringRef ProgramPath,
     58                                  const char **Args,
     59                                  StringRef StdInFile,
     60                                  StringRef StdOutFile,
     61                                  StringRef StdErrFile,
     62                                  unsigned NumSeconds = 0,
     63                                  unsigned MemoryLimit = 0,
     64                                  std::string *ErrMsg = 0) {
     65   const StringRef *Redirects[3] = { &StdInFile, &StdOutFile, &StdErrFile };
     66 
     67 #if 0 // For debug purposes
     68   {
     69     errs() << "RUN:";
     70     for (unsigned i = 0; Args[i]; ++i)
     71       errs() << " " << Args[i];
     72     errs() << "\n";
     73   }
     74 #endif
     75 
     76   return sys::ExecuteAndWait(ProgramPath, Args, 0, Redirects,
     77                              NumSeconds, MemoryLimit, ErrMsg);
     78 }
     79 
     80 /// RunProgramRemotelyWithTimeout - This function runs the given program
     81 /// remotely using the given remote client and the sys::Program::ExecuteAndWait.
     82 /// Returns the remote program exit code or reports a remote client error if it
     83 /// fails. Remote client is required to return 255 if it failed or program exit
     84 /// code otherwise.
     85 /// @see sys::Program::ExecuteAndWait
     86 static int RunProgramRemotelyWithTimeout(StringRef RemoteClientPath,
     87                                          const char **Args,
     88                                          StringRef StdInFile,
     89                                          StringRef StdOutFile,
     90                                          StringRef StdErrFile,
     91                                          unsigned NumSeconds = 0,
     92                                          unsigned MemoryLimit = 0) {
     93   const StringRef *Redirects[3] = { &StdInFile, &StdOutFile, &StdErrFile };
     94 
     95 #if 0 // For debug purposes
     96   {
     97     errs() << "RUN:";
     98     for (unsigned i = 0; Args[i]; ++i)
     99       errs() << " " << Args[i];
    100     errs() << "\n";
    101   }
    102 #endif
    103 
    104   // Run the program remotely with the remote client
    105   int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, 0,
    106                                        Redirects, NumSeconds, MemoryLimit);
    107 
    108   // Has the remote client fail?
    109   if (255 == ReturnCode) {
    110     std::ostringstream OS;
    111     OS << "\nError running remote client:\n ";
    112     for (const char **Arg = Args; *Arg; ++Arg)
    113       OS << " " << *Arg;
    114     OS << "\n";
    115 
    116     // The error message is in the output file, let's print it out from there.
    117     std::string StdOutFileName = StdOutFile.str();
    118     std::ifstream ErrorFile(StdOutFileName.c_str());
    119     if (ErrorFile) {
    120       std::copy(std::istreambuf_iterator<char>(ErrorFile),
    121                 std::istreambuf_iterator<char>(),
    122                 std::ostreambuf_iterator<char>(OS));
    123       ErrorFile.close();
    124     }
    125 
    126     errs() << OS.str();
    127   }
    128 
    129   return ReturnCode;
    130 }
    131 
    132 static std::string ProcessFailure(StringRef ProgPath, const char** Args,
    133                                   unsigned Timeout = 0,
    134                                   unsigned MemoryLimit = 0) {
    135   std::ostringstream OS;
    136   OS << "\nError running tool:\n ";
    137   for (const char **Arg = Args; *Arg; ++Arg)
    138     OS << " " << *Arg;
    139   OS << "\n";
    140 
    141   // Rerun the compiler, capturing any error messages to print them.
    142   SmallString<128> ErrorFilename;
    143   int ErrorFD;
    144   error_code EC = sys::fs::createTemporaryFile(
    145       "bugpoint.program_error_messages", "", ErrorFD, ErrorFilename);
    146   if (EC) {
    147     errs() << "Error making unique filename: " << EC.message() << "\n";
    148     exit(1);
    149   }
    150   RunProgramWithTimeout(ProgPath, Args, "", ErrorFilename.str(),
    151                         ErrorFilename.str(), Timeout, MemoryLimit);
    152   // FIXME: check return code ?
    153 
    154   // Print out the error messages generated by GCC if possible...
    155   std::ifstream ErrorFile(ErrorFilename.c_str());
    156   if (ErrorFile) {
    157     std::copy(std::istreambuf_iterator<char>(ErrorFile),
    158               std::istreambuf_iterator<char>(),
    159               std::ostreambuf_iterator<char>(OS));
    160     ErrorFile.close();
    161   }
    162 
    163   sys::fs::remove(ErrorFilename.c_str());
    164   return OS.str();
    165 }
    166 
    167 //===---------------------------------------------------------------------===//
    168 // LLI Implementation of AbstractIntepreter interface
    169 //
    170 namespace {
    171   class LLI : public AbstractInterpreter {
    172     std::string LLIPath;          // The path to the LLI executable
    173     std::vector<std::string> ToolArgs; // Args to pass to LLI
    174   public:
    175     LLI(const std::string &Path, const std::vector<std::string> *Args)
    176       : LLIPath(Path) {
    177       ToolArgs.clear ();
    178       if (Args) { ToolArgs = *Args; }
    179     }
    180 
    181     virtual int ExecuteProgram(const std::string &Bitcode,
    182                                const std::vector<std::string> &Args,
    183                                const std::string &InputFile,
    184                                const std::string &OutputFile,
    185                                std::string *Error,
    186                                const std::vector<std::string> &GCCArgs,
    187                                const std::vector<std::string> &SharedLibs =
    188                                std::vector<std::string>(),
    189                                unsigned Timeout = 0,
    190                                unsigned MemoryLimit = 0);
    191   };
    192 }
    193 
    194 int LLI::ExecuteProgram(const std::string &Bitcode,
    195                         const std::vector<std::string> &Args,
    196                         const std::string &InputFile,
    197                         const std::string &OutputFile,
    198                         std::string *Error,
    199                         const std::vector<std::string> &GCCArgs,
    200                         const std::vector<std::string> &SharedLibs,
    201                         unsigned Timeout,
    202                         unsigned MemoryLimit) {
    203   std::vector<const char*> LLIArgs;
    204   LLIArgs.push_back(LLIPath.c_str());
    205   LLIArgs.push_back("-force-interpreter=true");
    206 
    207   for (std::vector<std::string>::const_iterator i = SharedLibs.begin(),
    208          e = SharedLibs.end(); i != e; ++i) {
    209     LLIArgs.push_back("-load");
    210     LLIArgs.push_back((*i).c_str());
    211   }
    212 
    213   // Add any extra LLI args.
    214   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
    215     LLIArgs.push_back(ToolArgs[i].c_str());
    216 
    217   LLIArgs.push_back(Bitcode.c_str());
    218   // Add optional parameters to the running program from Argv
    219   for (unsigned i=0, e = Args.size(); i != e; ++i)
    220     LLIArgs.push_back(Args[i].c_str());
    221   LLIArgs.push_back(0);
    222 
    223   outs() << "<lli>"; outs().flush();
    224   DEBUG(errs() << "\nAbout to run:\t";
    225         for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
    226           errs() << " " << LLIArgs[i];
    227         errs() << "\n";
    228         );
    229   return RunProgramWithTimeout(LLIPath, &LLIArgs[0],
    230       InputFile, OutputFile, OutputFile,
    231       Timeout, MemoryLimit, Error);
    232 }
    233 
    234 void AbstractInterpreter::anchor() { }
    235 
    236 #if defined(LLVM_ON_UNIX)
    237 const char EXESuffix[] = "";
    238 #elif defined (LLVM_ON_WIN32)
    239 const char EXESuffix[] = "exe";
    240 #endif
    241 
    242 /// Prepend the path to the program being executed
    243 /// to \p ExeName, given the value of argv[0] and the address of main()
    244 /// itself. This allows us to find another LLVM tool if it is built in the same
    245 /// directory. An empty string is returned on error; note that this function
    246 /// just mainpulates the path and doesn't check for executability.
    247 /// @brief Find a named executable.
    248 static std::string PrependMainExecutablePath(const std::string &ExeName,
    249                                              const char *Argv0,
    250                                              void *MainAddr) {
    251   // Check the directory that the calling program is in.  We can do
    252   // this if ProgramPath contains at least one / character, indicating that it
    253   // is a relative path to the executable itself.
    254   std::string Main = sys::fs::getMainExecutable(Argv0, MainAddr);
    255   StringRef Result = sys::path::parent_path(Main);
    256 
    257   if (!Result.empty()) {
    258     SmallString<128> Storage = Result;
    259     sys::path::append(Storage, ExeName);
    260     sys::path::replace_extension(Storage, EXESuffix);
    261     return Storage.str();
    262   }
    263 
    264   return Result.str();
    265 }
    266 
    267 // LLI create method - Try to find the LLI executable
    268 AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
    269                                                     std::string &Message,
    270                                      const std::vector<std::string> *ToolArgs) {
    271   std::string LLIPath =
    272       PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t) & createLLI);
    273   if (!LLIPath.empty()) {
    274     Message = "Found lli: " + LLIPath + "\n";
    275     return new LLI(LLIPath, ToolArgs);
    276   }
    277 
    278   Message = "Cannot find `lli' in executable directory!\n";
    279   return 0;
    280 }
    281 
    282 //===---------------------------------------------------------------------===//
    283 // Custom compiler command implementation of AbstractIntepreter interface
    284 //
    285 // Allows using a custom command for compiling the bitcode, thus allows, for
    286 // example, to compile a bitcode fragment without linking or executing, then
    287 // using a custom wrapper script to check for compiler errors.
    288 namespace {
    289   class CustomCompiler : public AbstractInterpreter {
    290     std::string CompilerCommand;
    291     std::vector<std::string> CompilerArgs;
    292   public:
    293     CustomCompiler(
    294       const std::string &CompilerCmd, std::vector<std::string> CompArgs) :
    295       CompilerCommand(CompilerCmd), CompilerArgs(CompArgs) {}
    296 
    297     virtual void compileProgram(const std::string &Bitcode,
    298                                 std::string *Error,
    299                                 unsigned Timeout = 0,
    300                                 unsigned MemoryLimit = 0);
    301 
    302     virtual int ExecuteProgram(const std::string &Bitcode,
    303                                const std::vector<std::string> &Args,
    304                                const std::string &InputFile,
    305                                const std::string &OutputFile,
    306                                std::string *Error,
    307                                const std::vector<std::string> &GCCArgs =
    308                                std::vector<std::string>(),
    309                                const std::vector<std::string> &SharedLibs =
    310                                std::vector<std::string>(),
    311                                unsigned Timeout = 0,
    312                                unsigned MemoryLimit = 0) {
    313       *Error = "Execution not supported with -compile-custom";
    314       return -1;
    315     }
    316   };
    317 }
    318 
    319 void CustomCompiler::compileProgram(const std::string &Bitcode,
    320                                     std::string *Error,
    321                                     unsigned Timeout,
    322                                     unsigned MemoryLimit) {
    323 
    324   std::vector<const char*> ProgramArgs;
    325   ProgramArgs.push_back(CompilerCommand.c_str());
    326 
    327   for (std::size_t i = 0; i < CompilerArgs.size(); ++i)
    328     ProgramArgs.push_back(CompilerArgs.at(i).c_str());
    329   ProgramArgs.push_back(Bitcode.c_str());
    330   ProgramArgs.push_back(0);
    331 
    332   // Add optional parameters to the running program from Argv
    333   for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
    334     ProgramArgs.push_back(CompilerArgs[i].c_str());
    335 
    336   if (RunProgramWithTimeout(CompilerCommand, &ProgramArgs[0],
    337                              "", "", "",
    338                              Timeout, MemoryLimit, Error))
    339     *Error = ProcessFailure(CompilerCommand, &ProgramArgs[0],
    340                            Timeout, MemoryLimit);
    341 }
    342 
    343 //===---------------------------------------------------------------------===//
    344 // Custom execution command implementation of AbstractIntepreter interface
    345 //
    346 // Allows using a custom command for executing the bitcode, thus allows,
    347 // for example, to invoke a cross compiler for code generation followed by
    348 // a simulator that executes the generated binary.
    349 namespace {
    350   class CustomExecutor : public AbstractInterpreter {
    351     std::string ExecutionCommand;
    352     std::vector<std::string> ExecutorArgs;
    353   public:
    354     CustomExecutor(
    355       const std::string &ExecutionCmd, std::vector<std::string> ExecArgs) :
    356       ExecutionCommand(ExecutionCmd), ExecutorArgs(ExecArgs) {}
    357 
    358     virtual int ExecuteProgram(const std::string &Bitcode,
    359                                const std::vector<std::string> &Args,
    360                                const std::string &InputFile,
    361                                const std::string &OutputFile,
    362                                std::string *Error,
    363                                const std::vector<std::string> &GCCArgs,
    364                                const std::vector<std::string> &SharedLibs =
    365                                  std::vector<std::string>(),
    366                                unsigned Timeout = 0,
    367                                unsigned MemoryLimit = 0);
    368   };
    369 }
    370 
    371 int CustomExecutor::ExecuteProgram(const std::string &Bitcode,
    372                         const std::vector<std::string> &Args,
    373                         const std::string &InputFile,
    374                         const std::string &OutputFile,
    375                         std::string *Error,
    376                         const std::vector<std::string> &GCCArgs,
    377                         const std::vector<std::string> &SharedLibs,
    378                         unsigned Timeout,
    379                         unsigned MemoryLimit) {
    380 
    381   std::vector<const char*> ProgramArgs;
    382   ProgramArgs.push_back(ExecutionCommand.c_str());
    383 
    384   for (std::size_t i = 0; i < ExecutorArgs.size(); ++i)
    385     ProgramArgs.push_back(ExecutorArgs.at(i).c_str());
    386   ProgramArgs.push_back(Bitcode.c_str());
    387   ProgramArgs.push_back(0);
    388 
    389   // Add optional parameters to the running program from Argv
    390   for (unsigned i = 0, e = Args.size(); i != e; ++i)
    391     ProgramArgs.push_back(Args[i].c_str());
    392 
    393   return RunProgramWithTimeout(
    394     ExecutionCommand,
    395     &ProgramArgs[0], InputFile, OutputFile,
    396     OutputFile, Timeout, MemoryLimit, Error);
    397 }
    398 
    399 // Tokenize the CommandLine to the command and the args to allow
    400 // defining a full command line as the command instead of just the
    401 // executed program. We cannot just pass the whole string after the command
    402 // as a single argument because then program sees only a single
    403 // command line argument (with spaces in it: "foo bar" instead
    404 // of "foo" and "bar").
    405 //
    406 // code borrowed from:
    407 // http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
    408 static void lexCommand(std::string &Message, const std::string &CommandLine,
    409                        std::string &CmdPath, std::vector<std::string> Args) {
    410 
    411   std::string Command = "";
    412   std::string delimiters = " ";
    413 
    414   std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
    415   std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
    416 
    417   while (std::string::npos != pos || std::string::npos != lastPos) {
    418     std::string token = CommandLine.substr(lastPos, pos - lastPos);
    419     if (Command == "")
    420        Command = token;
    421     else
    422        Args.push_back(token);
    423     // Skip delimiters.  Note the "not_of"
    424     lastPos = CommandLine.find_first_not_of(delimiters, pos);
    425     // Find next "non-delimiter"
    426     pos = CommandLine.find_first_of(delimiters, lastPos);
    427   }
    428 
    429   CmdPath = sys::FindProgramByName(Command);
    430   if (CmdPath.empty()) {
    431     Message =
    432       std::string("Cannot find '") + Command +
    433       "' in PATH!\n";
    434     return;
    435   }
    436 
    437   Message = "Found command in: " + CmdPath + "\n";
    438 }
    439 
    440 // Custom execution environment create method, takes the execution command
    441 // as arguments
    442 AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
    443                     std::string &Message,
    444                     const std::string &CompileCommandLine) {
    445 
    446   std::string CmdPath;
    447   std::vector<std::string> Args;
    448   lexCommand(Message, CompileCommandLine, CmdPath, Args);
    449   if (CmdPath.empty())
    450     return 0;
    451 
    452   return new CustomCompiler(CmdPath, Args);
    453 }
    454 
    455 // Custom execution environment create method, takes the execution command
    456 // as arguments
    457 AbstractInterpreter *AbstractInterpreter::createCustomExecutor(
    458                     std::string &Message,
    459                     const std::string &ExecCommandLine) {
    460 
    461 
    462   std::string CmdPath;
    463   std::vector<std::string> Args;
    464   lexCommand(Message, ExecCommandLine, CmdPath, Args);
    465   if (CmdPath.empty())
    466     return 0;
    467 
    468   return new CustomExecutor(CmdPath, Args);
    469 }
    470 
    471 //===----------------------------------------------------------------------===//
    472 // LLC Implementation of AbstractIntepreter interface
    473 //
    474 GCC::FileType LLC::OutputCode(const std::string &Bitcode,
    475                               std::string &OutputAsmFile, std::string &Error,
    476                               unsigned Timeout, unsigned MemoryLimit) {
    477   const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
    478 
    479   SmallString<128> UniqueFile;
    480   error_code EC =
    481       sys::fs::createUniqueFile(Bitcode + "-%%%%%%%" + Suffix, UniqueFile);
    482   if (EC) {
    483     errs() << "Error making unique filename: " << EC.message() << "\n";
    484     exit(1);
    485   }
    486   OutputAsmFile = UniqueFile.str();
    487   std::vector<const char *> LLCArgs;
    488   LLCArgs.push_back(LLCPath.c_str());
    489 
    490   // Add any extra LLC args.
    491   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
    492     LLCArgs.push_back(ToolArgs[i].c_str());
    493 
    494   LLCArgs.push_back("-o");
    495   LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file
    496   LLCArgs.push_back(Bitcode.c_str());      // This is the input bitcode
    497 
    498   if (UseIntegratedAssembler)
    499     LLCArgs.push_back("-filetype=obj");
    500 
    501   LLCArgs.push_back (0);
    502 
    503   outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
    504   outs().flush();
    505   DEBUG(errs() << "\nAbout to run:\t";
    506         for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
    507           errs() << " " << LLCArgs[i];
    508         errs() << "\n";
    509         );
    510   if (RunProgramWithTimeout(LLCPath, &LLCArgs[0],
    511                             "", "", "",
    512                             Timeout, MemoryLimit))
    513     Error = ProcessFailure(LLCPath, &LLCArgs[0],
    514                            Timeout, MemoryLimit);
    515   return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
    516 }
    517 
    518 void LLC::compileProgram(const std::string &Bitcode, std::string *Error,
    519                          unsigned Timeout, unsigned MemoryLimit) {
    520   std::string OutputAsmFile;
    521   OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit);
    522   sys::fs::remove(OutputAsmFile);
    523 }
    524 
    525 int LLC::ExecuteProgram(const std::string &Bitcode,
    526                         const std::vector<std::string> &Args,
    527                         const std::string &InputFile,
    528                         const std::string &OutputFile,
    529                         std::string *Error,
    530                         const std::vector<std::string> &ArgsForGCC,
    531                         const std::vector<std::string> &SharedLibs,
    532                         unsigned Timeout,
    533                         unsigned MemoryLimit) {
    534 
    535   std::string OutputAsmFile;
    536   GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout,
    537                                       MemoryLimit);
    538   FileRemover OutFileRemover(OutputAsmFile, !SaveTemps);
    539 
    540   std::vector<std::string> GCCArgs(ArgsForGCC);
    541   GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
    542 
    543   // Assuming LLC worked, compile the result with GCC and run it.
    544   return gcc->ExecuteProgram(OutputAsmFile, Args, FileKind,
    545                              InputFile, OutputFile, Error, GCCArgs,
    546                              Timeout, MemoryLimit);
    547 }
    548 
    549 /// createLLC - Try to find the LLC executable
    550 ///
    551 LLC *AbstractInterpreter::createLLC(const char *Argv0,
    552                                     std::string &Message,
    553                                     const std::string &GCCBinary,
    554                                     const std::vector<std::string> *Args,
    555                                     const std::vector<std::string> *GCCArgs,
    556                                     bool UseIntegratedAssembler) {
    557   std::string LLCPath =
    558       PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t) & createLLC);
    559   if (LLCPath.empty()) {
    560     Message = "Cannot find `llc' in executable directory!\n";
    561     return 0;
    562   }
    563 
    564   GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
    565   if (!gcc) {
    566     errs() << Message << "\n";
    567     exit(1);
    568   }
    569   Message = "Found llc: " + LLCPath + "\n";
    570   return new LLC(LLCPath, gcc, Args, UseIntegratedAssembler);
    571 }
    572 
    573 //===---------------------------------------------------------------------===//
    574 // JIT Implementation of AbstractIntepreter interface
    575 //
    576 namespace {
    577   class JIT : public AbstractInterpreter {
    578     std::string LLIPath;          // The path to the LLI executable
    579     std::vector<std::string> ToolArgs; // Args to pass to LLI
    580   public:
    581     JIT(const std::string &Path, const std::vector<std::string> *Args)
    582       : LLIPath(Path) {
    583       ToolArgs.clear ();
    584       if (Args) { ToolArgs = *Args; }
    585     }
    586 
    587     virtual int ExecuteProgram(const std::string &Bitcode,
    588                                const std::vector<std::string> &Args,
    589                                const std::string &InputFile,
    590                                const std::string &OutputFile,
    591                                std::string *Error,
    592                                const std::vector<std::string> &GCCArgs =
    593                                  std::vector<std::string>(),
    594                                const std::vector<std::string> &SharedLibs =
    595                                  std::vector<std::string>(),
    596                                unsigned Timeout = 0,
    597                                unsigned MemoryLimit = 0);
    598   };
    599 }
    600 
    601 int JIT::ExecuteProgram(const std::string &Bitcode,
    602                         const std::vector<std::string> &Args,
    603                         const std::string &InputFile,
    604                         const std::string &OutputFile,
    605                         std::string *Error,
    606                         const std::vector<std::string> &GCCArgs,
    607                         const std::vector<std::string> &SharedLibs,
    608                         unsigned Timeout,
    609                         unsigned MemoryLimit) {
    610   // Construct a vector of parameters, incorporating those from the command-line
    611   std::vector<const char*> JITArgs;
    612   JITArgs.push_back(LLIPath.c_str());
    613   JITArgs.push_back("-force-interpreter=false");
    614 
    615   // Add any extra LLI args.
    616   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
    617     JITArgs.push_back(ToolArgs[i].c_str());
    618 
    619   for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
    620     JITArgs.push_back("-load");
    621     JITArgs.push_back(SharedLibs[i].c_str());
    622   }
    623   JITArgs.push_back(Bitcode.c_str());
    624   // Add optional parameters to the running program from Argv
    625   for (unsigned i=0, e = Args.size(); i != e; ++i)
    626     JITArgs.push_back(Args[i].c_str());
    627   JITArgs.push_back(0);
    628 
    629   outs() << "<jit>"; outs().flush();
    630   DEBUG(errs() << "\nAbout to run:\t";
    631         for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
    632           errs() << " " << JITArgs[i];
    633         errs() << "\n";
    634         );
    635   DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
    636   return RunProgramWithTimeout(LLIPath, &JITArgs[0],
    637       InputFile, OutputFile, OutputFile,
    638       Timeout, MemoryLimit, Error);
    639 }
    640 
    641 /// createJIT - Try to find the LLI executable
    642 ///
    643 AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
    644                    std::string &Message, const std::vector<std::string> *Args) {
    645   std::string LLIPath =
    646       PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t) & createJIT);
    647   if (!LLIPath.empty()) {
    648     Message = "Found lli: " + LLIPath + "\n";
    649     return new JIT(LLIPath, Args);
    650   }
    651 
    652   Message = "Cannot find `lli' in executable directory!\n";
    653   return 0;
    654 }
    655 
    656 //===---------------------------------------------------------------------===//
    657 // GCC abstraction
    658 //
    659 
    660 static bool IsARMArchitecture(std::vector<const char*> Args) {
    661   for (std::vector<const char*>::const_iterator
    662          I = Args.begin(), E = Args.end(); I != E; ++I) {
    663     if (StringRef(*I).equals_lower("-arch")) {
    664       ++I;
    665       if (I != E && StringRef(*I).substr(0, strlen("arm")).equals_lower("arm"))
    666         return true;
    667     }
    668   }
    669 
    670   return false;
    671 }
    672 
    673 int GCC::ExecuteProgram(const std::string &ProgramFile,
    674                         const std::vector<std::string> &Args,
    675                         FileType fileType,
    676                         const std::string &InputFile,
    677                         const std::string &OutputFile,
    678                         std::string *Error,
    679                         const std::vector<std::string> &ArgsForGCC,
    680                         unsigned Timeout,
    681                         unsigned MemoryLimit) {
    682   std::vector<const char*> GCCArgs;
    683 
    684   GCCArgs.push_back(GCCPath.c_str());
    685 
    686   if (TargetTriple.getArch() == Triple::x86)
    687     GCCArgs.push_back("-m32");
    688 
    689   for (std::vector<std::string>::const_iterator
    690          I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
    691     GCCArgs.push_back(I->c_str());
    692 
    693   // Specify -x explicitly in case the extension is wonky
    694   if (fileType != ObjectFile) {
    695     GCCArgs.push_back("-x");
    696     if (fileType == CFile) {
    697       GCCArgs.push_back("c");
    698       GCCArgs.push_back("-fno-strict-aliasing");
    699     } else {
    700       GCCArgs.push_back("assembler");
    701 
    702       // For ARM architectures we don't want this flag. bugpoint isn't
    703       // explicitly told what architecture it is working on, so we get
    704       // it from gcc flags
    705       if (TargetTriple.isOSDarwin() && !IsARMArchitecture(GCCArgs))
    706         GCCArgs.push_back("-force_cpusubtype_ALL");
    707     }
    708   }
    709 
    710   GCCArgs.push_back(ProgramFile.c_str());  // Specify the input filename.
    711 
    712   GCCArgs.push_back("-x");
    713   GCCArgs.push_back("none");
    714   GCCArgs.push_back("-o");
    715 
    716   SmallString<128> OutputBinary;
    717   error_code EC =
    718       sys::fs::createUniqueFile(ProgramFile + "-%%%%%%%.gcc.exe", OutputBinary);
    719   if (EC) {
    720     errs() << "Error making unique filename: " << EC.message() << "\n";
    721     exit(1);
    722   }
    723   GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
    724 
    725   // Add any arguments intended for GCC. We locate them here because this is
    726   // most likely -L and -l options that need to come before other libraries but
    727   // after the source. Other options won't be sensitive to placement on the
    728   // command line, so this should be safe.
    729   for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
    730     GCCArgs.push_back(ArgsForGCC[i].c_str());
    731 
    732   GCCArgs.push_back("-lm");                // Hard-code the math library...
    733   GCCArgs.push_back("-O2");                // Optimize the program a bit...
    734 #if defined (HAVE_LINK_R)
    735   GCCArgs.push_back("-Wl,-R.");            // Search this dir for .so files
    736 #endif
    737   if (TargetTriple.getArch() == Triple::sparc)
    738     GCCArgs.push_back("-mcpu=v9");
    739   GCCArgs.push_back(0);                    // NULL terminator
    740 
    741   outs() << "<gcc>"; outs().flush();
    742   DEBUG(errs() << "\nAbout to run:\t";
    743         for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
    744           errs() << " " << GCCArgs[i];
    745         errs() << "\n";
    746         );
    747   if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], "", "", "")) {
    748     *Error = ProcessFailure(GCCPath, &GCCArgs[0]);
    749     return -1;
    750   }
    751 
    752   std::vector<const char*> ProgramArgs;
    753 
    754   // Declared here so that the destructor only runs after
    755   // ProgramArgs is used.
    756   std::string Exec;
    757 
    758   if (RemoteClientPath.empty())
    759     ProgramArgs.push_back(OutputBinary.c_str());
    760   else {
    761     ProgramArgs.push_back(RemoteClientPath.c_str());
    762     ProgramArgs.push_back(RemoteHost.c_str());
    763     if (!RemoteUser.empty()) {
    764       ProgramArgs.push_back("-l");
    765       ProgramArgs.push_back(RemoteUser.c_str());
    766     }
    767     if (!RemotePort.empty()) {
    768       ProgramArgs.push_back("-p");
    769       ProgramArgs.push_back(RemotePort.c_str());
    770     }
    771     if (!RemoteExtra.empty()) {
    772       ProgramArgs.push_back(RemoteExtra.c_str());
    773     }
    774 
    775     // Full path to the binary. We need to cd to the exec directory because
    776     // there is a dylib there that the exec expects to find in the CWD
    777     char* env_pwd = getenv("PWD");
    778     Exec = "cd ";
    779     Exec += env_pwd;
    780     Exec += "; ./";
    781     Exec += OutputBinary.c_str();
    782     ProgramArgs.push_back(Exec.c_str());
    783   }
    784 
    785   // Add optional parameters to the running program from Argv
    786   for (unsigned i = 0, e = Args.size(); i != e; ++i)
    787     ProgramArgs.push_back(Args[i].c_str());
    788   ProgramArgs.push_back(0);                // NULL terminator
    789 
    790   // Now that we have a binary, run it!
    791   outs() << "<program>"; outs().flush();
    792   DEBUG(errs() << "\nAbout to run:\t";
    793         for (unsigned i = 0, e = ProgramArgs.size()-1; i != e; ++i)
    794           errs() << " " << ProgramArgs[i];
    795         errs() << "\n";
    796         );
    797 
    798   FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps);
    799 
    800   if (RemoteClientPath.empty()) {
    801     DEBUG(errs() << "<run locally>");
    802     int ExitCode = RunProgramWithTimeout(OutputBinary.str(), &ProgramArgs[0],
    803                                          InputFile, OutputFile, OutputFile,
    804                                          Timeout, MemoryLimit, Error);
    805     // Treat a signal (usually SIGSEGV) or timeout as part of the program output
    806     // so that crash-causing miscompilation is handled seamlessly.
    807     if (ExitCode < -1) {
    808       std::ofstream outFile(OutputFile.c_str(), std::ios_base::app);
    809       outFile << *Error << '\n';
    810       outFile.close();
    811       Error->clear();
    812     }
    813     return ExitCode;
    814   } else {
    815     outs() << "<run remotely>"; outs().flush();
    816     return RunProgramRemotelyWithTimeout(RemoteClientPath,
    817         &ProgramArgs[0], InputFile, OutputFile,
    818         OutputFile, Timeout, MemoryLimit);
    819   }
    820 }
    821 
    822 int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
    823                           std::string &OutputFile,
    824                           const std::vector<std::string> &ArgsForGCC,
    825                           std::string &Error) {
    826   SmallString<128> UniqueFilename;
    827   error_code EC = sys::fs::createUniqueFile(
    828       InputFile + "-%%%%%%%" + LTDL_SHLIB_EXT, UniqueFilename);
    829   if (EC) {
    830     errs() << "Error making unique filename: " << EC.message() << "\n";
    831     exit(1);
    832   }
    833   OutputFile = UniqueFilename.str();
    834 
    835   std::vector<const char*> GCCArgs;
    836 
    837   GCCArgs.push_back(GCCPath.c_str());
    838 
    839   if (TargetTriple.getArch() == Triple::x86)
    840     GCCArgs.push_back("-m32");
    841 
    842   for (std::vector<std::string>::const_iterator
    843          I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
    844     GCCArgs.push_back(I->c_str());
    845 
    846   // Compile the C/asm file into a shared object
    847   if (fileType != ObjectFile) {
    848     GCCArgs.push_back("-x");
    849     GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
    850   }
    851   GCCArgs.push_back("-fno-strict-aliasing");
    852   GCCArgs.push_back(InputFile.c_str());   // Specify the input filename.
    853   GCCArgs.push_back("-x");
    854   GCCArgs.push_back("none");
    855   if (TargetTriple.getArch() == Triple::sparc)
    856     GCCArgs.push_back("-G");       // Compile a shared library, `-G' for Sparc
    857   else if (TargetTriple.isOSDarwin()) {
    858     // link all source files into a single module in data segment, rather than
    859     // generating blocks. dynamic_lookup requires that you set
    860     // MACOSX_DEPLOYMENT_TARGET=10.3 in your env.  FIXME: it would be better for
    861     // bugpoint to just pass that in the environment of GCC.
    862     GCCArgs.push_back("-single_module");
    863     GCCArgs.push_back("-dynamiclib");   // `-dynamiclib' for MacOS X/PowerPC
    864     GCCArgs.push_back("-undefined");
    865     GCCArgs.push_back("dynamic_lookup");
    866   } else
    867     GCCArgs.push_back("-shared");  // `-shared' for Linux/X86, maybe others
    868 
    869   if (TargetTriple.getArch() == Triple::x86_64)
    870     GCCArgs.push_back("-fPIC");   // Requires shared objs to contain PIC
    871 
    872   if (TargetTriple.getArch() == Triple::sparc)
    873     GCCArgs.push_back("-mcpu=v9");
    874 
    875   GCCArgs.push_back("-o");
    876   GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
    877   GCCArgs.push_back("-O2");              // Optimize the program a bit.
    878 
    879 
    880 
    881   // Add any arguments intended for GCC. We locate them here because this is
    882   // most likely -L and -l options that need to come before other libraries but
    883   // after the source. Other options won't be sensitive to placement on the
    884   // command line, so this should be safe.
    885   for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
    886     GCCArgs.push_back(ArgsForGCC[i].c_str());
    887   GCCArgs.push_back(0);                    // NULL terminator
    888 
    889 
    890 
    891   outs() << "<gcc>"; outs().flush();
    892   DEBUG(errs() << "\nAbout to run:\t";
    893         for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
    894           errs() << " " << GCCArgs[i];
    895         errs() << "\n";
    896         );
    897   if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], "", "", "")) {
    898     Error = ProcessFailure(GCCPath, &GCCArgs[0]);
    899     return 1;
    900   }
    901   return 0;
    902 }
    903 
    904 /// create - Try to find the `gcc' executable
    905 ///
    906 GCC *GCC::create(std::string &Message,
    907                  const std::string &GCCBinary,
    908                  const std::vector<std::string> *Args) {
    909   std::string GCCPath = sys::FindProgramByName(GCCBinary);
    910   if (GCCPath.empty()) {
    911     Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
    912     return 0;
    913   }
    914 
    915   std::string RemoteClientPath;
    916   if (!RemoteClient.empty())
    917     RemoteClientPath = sys::FindProgramByName(RemoteClient);
    918 
    919   Message = "Found gcc: " + GCCPath + "\n";
    920   return new GCC(GCCPath, RemoteClientPath, Args);
    921 }
    922