166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===-- ToolRunner.cpp ----------------------------------------------------===//
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 file implements the interfaces described in the ToolRunner.h file.
1166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
1266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===//
1366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
1466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#define DEBUG_TYPE "toolrunner"
1566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "ToolRunner.h"
1666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Program.h"
1766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/CommandLine.h"
1866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Debug.h"
1966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/FileUtilities.h"
2066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/raw_ostream.h"
2166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Config/config.h"   // for HAVE_LINK_R
2266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include <fstream>
2366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include <sstream>
2466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanusing namespace llvm;
2566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
2666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace llvm {
2766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  cl::opt<bool>
2866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files"));
2966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
3066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
3166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace {
3266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  cl::opt<std::string>
3366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  RemoteClient("remote-client",
3466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman               cl::desc("Remote execution client (rsh/ssh)"));
3566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
3666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  cl::opt<std::string>
3766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  RemoteHost("remote-host",
3866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman             cl::desc("Remote execution (rsh/ssh) host"));
3966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
4066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  cl::opt<std::string>
4166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  RemotePort("remote-port",
4266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman             cl::desc("Remote execution (rsh/ssh) port"));
4366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
4466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  cl::opt<std::string>
4566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  RemoteUser("remote-user",
4666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman             cl::desc("Remote execution (rsh/ssh) user id"));
4766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
4866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  cl::opt<std::string>
4966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  RemoteExtra("remote-extra-options",
5066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          cl::desc("Remote execution (rsh/ssh) extra options"));
5166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
5266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
5366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// RunProgramWithTimeout - This function provides an alternate interface
5466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// to the sys::Program::ExecuteAndWait interface.
5566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// @see sys::Program::ExecuteAndWait
5666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic int RunProgramWithTimeout(const sys::Path &ProgramPath,
5766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 const char **Args,
5866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 const sys::Path &StdInFile,
5966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 const sys::Path &StdOutFile,
6066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 const sys::Path &StdErrFile,
6166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 unsigned NumSeconds = 0,
6266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 unsigned MemoryLimit = 0,
6366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 std::string *ErrMsg = 0) {
6466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  const sys::Path* redirects[3];
6566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  redirects[0] = &StdInFile;
6666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  redirects[1] = &StdOutFile;
6766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  redirects[2] = &StdErrFile;
6866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
6966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#if 0 // For debug purposes
7066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  {
7166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "RUN:";
7266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    for (unsigned i = 0; Args[i]; ++i)
7366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      errs() << " " << Args[i];
7466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "\n";
7566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
7666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#endif
7766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
7866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return
7966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
8066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 NumSeconds, MemoryLimit, ErrMsg);
8166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
8266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
8366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// RunProgramRemotelyWithTimeout - This function runs the given program
8466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// remotely using the given remote client and the sys::Program::ExecuteAndWait.
8566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// Returns the remote program exit code or reports a remote client error if it
8666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// fails. Remote client is required to return 255 if it failed or program exit
8766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// code otherwise.
8866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// @see sys::Program::ExecuteAndWait
8966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath,
9066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                         const char **Args,
9166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                         const sys::Path &StdInFile,
9266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                         const sys::Path &StdOutFile,
9366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                         const sys::Path &StdErrFile,
9466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                         unsigned NumSeconds = 0,
9566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                         unsigned MemoryLimit = 0) {
9666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  const sys::Path* redirects[3];
9766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  redirects[0] = &StdInFile;
9866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  redirects[1] = &StdOutFile;
9966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  redirects[2] = &StdErrFile;
10066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
10166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#if 0 // For debug purposes
10266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  {
10366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "RUN:";
10466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    for (unsigned i = 0; Args[i]; ++i)
10566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      errs() << " " << Args[i];
10666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "\n";
10766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
10866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#endif
10966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
11066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Run the program remotely with the remote client
11166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  int ReturnCode = sys::Program::ExecuteAndWait(RemoteClientPath, Args,
11266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 0, redirects, NumSeconds, MemoryLimit);
11366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
11466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Has the remote client fail?
11566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (255 == ReturnCode) {
11666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::ostringstream OS;
11766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    OS << "\nError running remote client:\n ";
11866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    for (const char **Arg = Args; *Arg; ++Arg)
11966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      OS << " " << *Arg;
12066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    OS << "\n";
12166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
12266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // The error message is in the output file, let's print it out from there.
12366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::ifstream ErrorFile(StdOutFile.c_str());
12466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (ErrorFile) {
12566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      std::copy(std::istreambuf_iterator<char>(ErrorFile),
12666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                std::istreambuf_iterator<char>(),
12766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                std::ostreambuf_iterator<char>(OS));
12866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ErrorFile.close();
12966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
13066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
13166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << OS;
13266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
13366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
13466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return ReturnCode;
13566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
13666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
13766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic std::string ProcessFailure(sys::Path ProgPath, const char** Args,
13866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                  unsigned Timeout = 0,
13966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                  unsigned MemoryLimit = 0) {
14066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::ostringstream OS;
14166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OS << "\nError running tool:\n ";
14266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (const char **Arg = Args; *Arg; ++Arg)
14366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    OS << " " << *Arg;
14466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OS << "\n";
14566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
14666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Rerun the compiler, capturing any error messages to print them.
14766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path ErrorFilename("bugpoint.program_error_messages");
14866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string ErrMsg;
14966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (ErrorFilename.makeUnique(true, &ErrMsg)) {
15066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "Error making unique filename: " << ErrMsg << "\n";
15166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    exit(1);
15266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
15366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
15466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        ErrorFilename, Timeout, MemoryLimit);
15566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // FIXME: check return code ?
15666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
15766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Print out the error messages generated by GCC if possible...
15866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::ifstream ErrorFile(ErrorFilename.c_str());
15966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (ErrorFile) {
16066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::copy(std::istreambuf_iterator<char>(ErrorFile),
16166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman              std::istreambuf_iterator<char>(),
16266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman              std::ostreambuf_iterator<char>(OS));
16366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ErrorFile.close();
16466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
16566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
16666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ErrorFilename.eraseFromDisk();
16766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return OS.str();
16866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
16966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
17066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===---------------------------------------------------------------------===//
17166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// LLI Implementation of AbstractIntepreter interface
17266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
17366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace {
17466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  class LLI : public AbstractInterpreter {
17566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::string LLIPath;          // The path to the LLI executable
17666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<std::string> ToolArgs; // Args to pass to LLI
17766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  public:
17866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    LLI(const std::string &Path, const std::vector<std::string> *Args)
17966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      : LLIPath(Path) {
18066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ToolArgs.clear ();
18166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (Args) { ToolArgs = *Args; }
18266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
18366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
18466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    virtual int ExecuteProgram(const std::string &Bitcode,
18566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &Args,
18666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::string &InputFile,
18766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::string &OutputFile,
18866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               std::string *Error,
18966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &GCCArgs,
19066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &SharedLibs =
19166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               std::vector<std::string>(),
19266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               unsigned Timeout = 0,
19366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               unsigned MemoryLimit = 0);
19466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  };
19566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
19666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
19766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint LLI::ExecuteProgram(const std::string &Bitcode,
19866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &Args,
19966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &InputFile,
20066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &OutputFile,
20166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        std::string *Error,
20266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &GCCArgs,
20366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &SharedLibs,
20466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned Timeout,
20566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned MemoryLimit) {
20666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char*> LLIArgs;
20766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLIArgs.push_back(LLIPath.c_str());
20866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLIArgs.push_back("-force-interpreter=true");
20966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
21066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (std::vector<std::string>::const_iterator i = SharedLibs.begin(),
21166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman         e = SharedLibs.end(); i != e; ++i) {
21266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    LLIArgs.push_back("-load");
21366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    LLIArgs.push_back((*i).c_str());
21466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
21566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
21666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add any extra LLI args.
21766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
21866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    LLIArgs.push_back(ToolArgs[i].c_str());
21966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
22066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLIArgs.push_back(Bitcode.c_str());
22166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add optional parameters to the running program from Argv
22266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i=0, e = Args.size(); i != e; ++i)
22366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    LLIArgs.push_back(Args[i].c_str());
22466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLIArgs.push_back(0);
22566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
22666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << "<lli>"; outs().flush();
22766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  DEBUG(errs() << "\nAbout to run:\t";
22866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
22966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          errs() << " " << LLIArgs[i];
23066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        errs() << "\n";
23166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        );
23266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
23366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
23466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      Timeout, MemoryLimit, Error);
23566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
23666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
23766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// LLI create method - Try to find the LLI executable
23866b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanAbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
23966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                    std::string &Message,
24066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                     const std::vector<std::string> *ToolArgs) {
24166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string LLIPath =
24266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI).str();
24366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!LLIPath.empty()) {
24466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Message = "Found lli: " + LLIPath + "\n";
24566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return new LLI(LLIPath, ToolArgs);
24666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
24766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
24866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  Message = "Cannot find `lli' in executable directory!\n";
24966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return 0;
25066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
25166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
25266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===---------------------------------------------------------------------===//
25366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Custom compiler command implementation of AbstractIntepreter interface
25466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
25566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Allows using a custom command for compiling the bitcode, thus allows, for
25666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// example, to compile a bitcode fragment without linking or executing, then
25766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// using a custom wrapper script to check for compiler errors.
25866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace {
25966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  class CustomCompiler : public AbstractInterpreter {
26066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::string CompilerCommand;
26166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<std::string> CompilerArgs;
26266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  public:
26366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    CustomCompiler(
26466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      const std::string &CompilerCmd, std::vector<std::string> CompArgs) :
26566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      CompilerCommand(CompilerCmd), CompilerArgs(CompArgs) {}
26666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
26766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    virtual void compileProgram(const std::string &Bitcode,
26866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                std::string *Error,
26966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                unsigned Timeout = 0,
27066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                unsigned MemoryLimit = 0);
27166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
27266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    virtual int ExecuteProgram(const std::string &Bitcode,
27366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &Args,
27466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::string &InputFile,
27566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::string &OutputFile,
27666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               std::string *Error,
27766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &GCCArgs =
27866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               std::vector<std::string>(),
27966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &SharedLibs =
28066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               std::vector<std::string>(),
28166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               unsigned Timeout = 0,
28266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               unsigned MemoryLimit = 0) {
28366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      *Error = "Execution not supported with -compile-custom";
28466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      return -1;
28566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
28666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  };
28766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
28866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
28966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid CustomCompiler::compileProgram(const std::string &Bitcode,
29066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    std::string *Error,
29166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    unsigned Timeout,
29266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    unsigned MemoryLimit) {
29366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
29466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char*> ProgramArgs;
29566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ProgramArgs.push_back(CompilerCommand.c_str());
29666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
29766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (std::size_t i = 0; i < CompilerArgs.size(); ++i)
29866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(CompilerArgs.at(i).c_str());
29966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ProgramArgs.push_back(Bitcode.c_str());
30066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ProgramArgs.push_back(0);
30166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
30266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add optional parameters to the running program from Argv
30366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
30466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(CompilerArgs[i].c_str());
30566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
30666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (RunProgramWithTimeout( sys::Path(CompilerCommand), &ProgramArgs[0],
30766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                             sys::Path(), sys::Path(), sys::Path(),
30866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                             Timeout, MemoryLimit, Error))
30966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    *Error = ProcessFailure(sys::Path(CompilerCommand), &ProgramArgs[0],
31066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                           Timeout, MemoryLimit);
31166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
31266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
31366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===---------------------------------------------------------------------===//
31466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Custom execution command implementation of AbstractIntepreter interface
31566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
31666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Allows using a custom command for executing the bitcode, thus allows,
31766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// for example, to invoke a cross compiler for code generation followed by
31866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// a simulator that executes the generated binary.
31966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace {
32066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  class CustomExecutor : public AbstractInterpreter {
32166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::string ExecutionCommand;
32266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<std::string> ExecutorArgs;
32366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  public:
32466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    CustomExecutor(
32566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      const std::string &ExecutionCmd, std::vector<std::string> ExecArgs) :
32666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ExecutionCommand(ExecutionCmd), ExecutorArgs(ExecArgs) {}
32766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
32866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    virtual int ExecuteProgram(const std::string &Bitcode,
32966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &Args,
33066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::string &InputFile,
33166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::string &OutputFile,
33266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               std::string *Error,
33366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &GCCArgs,
33466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &SharedLibs =
33566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 std::vector<std::string>(),
33666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               unsigned Timeout = 0,
33766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               unsigned MemoryLimit = 0);
33866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  };
33966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
34066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
34166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint CustomExecutor::ExecuteProgram(const std::string &Bitcode,
34266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &Args,
34366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &InputFile,
34466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &OutputFile,
34566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        std::string *Error,
34666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &GCCArgs,
34766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &SharedLibs,
34866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned Timeout,
34966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned MemoryLimit) {
35066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
35166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char*> ProgramArgs;
35266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ProgramArgs.push_back(ExecutionCommand.c_str());
35366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
35466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (std::size_t i = 0; i < ExecutorArgs.size(); ++i)
35566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(ExecutorArgs.at(i).c_str());
35666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ProgramArgs.push_back(Bitcode.c_str());
35766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ProgramArgs.push_back(0);
35866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
35966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add optional parameters to the running program from Argv
36066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = Args.size(); i != e; ++i)
36166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(Args[i].c_str());
36266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
36366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return RunProgramWithTimeout(
36466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    sys::Path(ExecutionCommand),
36566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
36666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    sys::Path(OutputFile), Timeout, MemoryLimit, Error);
36766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
36866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
36966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Tokenize the CommandLine to the command and the args to allow
37066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// defining a full command line as the command instead of just the
37166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// executed program. We cannot just pass the whole string after the command
37266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// as a single argument because then program sees only a single
37366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// command line argument (with spaces in it: "foo bar" instead
37466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// of "foo" and "bar").
37566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
37666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// code borrowed from:
37766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
37866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void lexCommand(std::string &Message, const std::string &CommandLine,
37966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                       std::string &CmdPath, std::vector<std::string> Args) {
38066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
38166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string Command = "";
38266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string delimiters = " ";
38366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
38466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
38566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
38666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
38766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  while (std::string::npos != pos || std::string::npos != lastPos) {
38866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::string token = CommandLine.substr(lastPos, pos - lastPos);
38966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (Command == "")
39066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman       Command = token;
39166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    else
39266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman       Args.push_back(token);
39366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Skip delimiters.  Note the "not_of"
39466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    lastPos = CommandLine.find_first_not_of(delimiters, pos);
39566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Find next "non-delimiter"
39666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    pos = CommandLine.find_first_of(delimiters, lastPos);
39766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
39866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
39966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  CmdPath = sys::Program::FindProgramByName(Command).str();
40066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (CmdPath.empty()) {
40166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Message =
40266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      std::string("Cannot find '") + Command +
40366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      "' in PATH!\n";
40466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return;
40566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
40666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
40766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  Message = "Found command in: " + CmdPath + "\n";
40866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
40966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
41066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Custom execution environment create method, takes the execution command
41166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// as arguments
41266b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanAbstractInterpreter *AbstractInterpreter::createCustomCompiler(
41366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                    std::string &Message,
41466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                    const std::string &CompileCommandLine) {
41566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
41666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string CmdPath;
41766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<std::string> Args;
41866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  lexCommand(Message, CompileCommandLine, CmdPath, Args);
41966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (CmdPath.empty())
42066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return 0;
42166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
42266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return new CustomCompiler(CmdPath, Args);
42366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
42466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
42566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// Custom execution environment create method, takes the execution command
42666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// as arguments
42766b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanAbstractInterpreter *AbstractInterpreter::createCustomExecutor(
42866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                    std::string &Message,
42966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                    const std::string &ExecCommandLine) {
43066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
43166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
43266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string CmdPath;
43366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<std::string> Args;
43466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  lexCommand(Message, ExecCommandLine, CmdPath, Args);
43566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (CmdPath.empty())
43666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return 0;
43766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
43866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return new CustomExecutor(CmdPath, Args);
43966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
44066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
44166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===//
44266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// LLC Implementation of AbstractIntepreter interface
44366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
44466b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanGCC::FileType LLC::OutputCode(const std::string &Bitcode,
44566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                              sys::Path &OutputAsmFile, std::string &Error,
44666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                              unsigned Timeout, unsigned MemoryLimit) {
44766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
44866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path uniqueFile(Bitcode + Suffix);
44966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string ErrMsg;
45066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (uniqueFile.makeUnique(true, &ErrMsg)) {
45166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "Error making unique filename: " << ErrMsg << "\n";
45266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    exit(1);
45366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
45466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OutputAsmFile = uniqueFile;
45566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char *> LLCArgs;
45666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back(LLCPath.c_str());
45766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
45866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add any extra LLC args.
45966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
46066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    LLCArgs.push_back(ToolArgs[i].c_str());
46166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
46266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back("-o");
46366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file
46466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back(Bitcode.c_str());      // This is the input bitcode
46566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
46666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (UseIntegratedAssembler)
46766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    LLCArgs.push_back("-filetype=obj");
46866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
46966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back (0);
47066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
47166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
47266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs().flush();
47366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  DEBUG(errs() << "\nAbout to run:\t";
47466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
47566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          errs() << " " << LLCArgs[i];
47666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        errs() << "\n";
47766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        );
47866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
47966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                            sys::Path(), sys::Path(), sys::Path(),
48066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                            Timeout, MemoryLimit))
48166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0],
48266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                           Timeout, MemoryLimit);
48366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
48466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
48566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
48666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid LLC::compileProgram(const std::string &Bitcode, std::string *Error,
48766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                         unsigned Timeout, unsigned MemoryLimit) {
48866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path OutputAsmFile;
48966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit);
49066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OutputAsmFile.eraseFromDisk();
49166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
49266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
49366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint LLC::ExecuteProgram(const std::string &Bitcode,
49466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &Args,
49566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &InputFile,
49666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &OutputFile,
49766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        std::string *Error,
49866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &ArgsForGCC,
49966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &SharedLibs,
50066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned Timeout,
50166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned MemoryLimit) {
50266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
50366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path OutputAsmFile;
50466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout,
50566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                      MemoryLimit);
50666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  FileRemover OutFileRemover(OutputAsmFile.str(), !SaveTemps);
50766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
50866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<std::string> GCCArgs(ArgsForGCC);
50966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
51066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
51166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Assuming LLC worked, compile the result with GCC and run it.
51266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return gcc->ExecuteProgram(OutputAsmFile.str(), Args, FileKind,
51366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                             InputFile, OutputFile, Error, GCCArgs,
51466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                             Timeout, MemoryLimit);
51566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
51666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
51766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// createLLC - Try to find the LLC executable
51866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman///
51966b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanLLC *AbstractInterpreter::createLLC(const char *Argv0,
52066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    std::string &Message,
52166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    const std::string &GCCBinary,
52266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    const std::vector<std::string> *Args,
52366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    const std::vector<std::string> *GCCArgs,
52466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    bool UseIntegratedAssembler) {
52566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string LLCPath =
52666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC).str();
52766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (LLCPath.empty()) {
52866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Message = "Cannot find `llc' in executable directory!\n";
52966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return 0;
53066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
53166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
53266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  Message = "Found llc: " + LLCPath + "\n";
53366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
53466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!gcc) {
53566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << Message << "\n";
53666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    exit(1);
53766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
53866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return new LLC(LLCPath, gcc, Args, UseIntegratedAssembler);
53966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
54066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
54166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===---------------------------------------------------------------------===//
54266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// JIT Implementation of AbstractIntepreter interface
54366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
54466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumannamespace {
54566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  class JIT : public AbstractInterpreter {
54666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::string LLIPath;          // The path to the LLI executable
54766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<std::string> ToolArgs; // Args to pass to LLI
54866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  public:
54966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    JIT(const std::string &Path, const std::vector<std::string> *Args)
55066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      : LLIPath(Path) {
55166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ToolArgs.clear ();
55266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (Args) { ToolArgs = *Args; }
55366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
55466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
55566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    virtual int ExecuteProgram(const std::string &Bitcode,
55666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &Args,
55766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::string &InputFile,
55866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::string &OutputFile,
55966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               std::string *Error,
56066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &GCCArgs =
56166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 std::vector<std::string>(),
56266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               const std::vector<std::string> &SharedLibs =
56366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                 std::vector<std::string>(),
56466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               unsigned Timeout = 0,
56566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               unsigned MemoryLimit = 0);
56666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  };
56766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
56866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
56966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint JIT::ExecuteProgram(const std::string &Bitcode,
57066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &Args,
57166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &InputFile,
57266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &OutputFile,
57366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        std::string *Error,
57466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &GCCArgs,
57566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &SharedLibs,
57666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned Timeout,
57766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned MemoryLimit) {
57866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Construct a vector of parameters, incorporating those from the command-line
57966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char*> JITArgs;
58066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  JITArgs.push_back(LLIPath.c_str());
58166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  JITArgs.push_back("-force-interpreter=false");
58266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
58366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add any extra LLI args.
58466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
58566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    JITArgs.push_back(ToolArgs[i].c_str());
58666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
58766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
58866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    JITArgs.push_back("-load");
58966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    JITArgs.push_back(SharedLibs[i].c_str());
59066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
59166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  JITArgs.push_back(Bitcode.c_str());
59266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add optional parameters to the running program from Argv
59366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i=0, e = Args.size(); i != e; ++i)
59466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    JITArgs.push_back(Args[i].c_str());
59566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  JITArgs.push_back(0);
59666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
59766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << "<jit>"; outs().flush();
59866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  DEBUG(errs() << "\nAbout to run:\t";
59966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
60066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          errs() << " " << JITArgs[i];
60166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        errs() << "\n";
60266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        );
60366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
60466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
60566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
60666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      Timeout, MemoryLimit, Error);
60766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
60866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
60966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// createJIT - Try to find the LLI executable
61066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman///
61166b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanAbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
61266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                   std::string &Message, const std::vector<std::string> *Args) {
61366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string LLIPath =
61466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT).str();
61566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!LLIPath.empty()) {
61666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Message = "Found lli: " + LLIPath + "\n";
61766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return new JIT(LLIPath, Args);
61866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
61966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
62066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  Message = "Cannot find `lli' in executable directory!\n";
62166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return 0;
62266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
62366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
62466b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanGCC::FileType CBE::OutputCode(const std::string &Bitcode,
62566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                              sys::Path &OutputCFile, std::string &Error,
62666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                              unsigned Timeout, unsigned MemoryLimit) {
62766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path uniqueFile(Bitcode+".cbe.c");
62866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string ErrMsg;
62966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (uniqueFile.makeUnique(true, &ErrMsg)) {
63066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "Error making unique filename: " << ErrMsg << "\n";
63166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    exit(1);
63266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
63366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OutputCFile = uniqueFile;
63466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char *> LLCArgs;
63566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back(LLCPath.c_str());
63666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
63766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add any extra LLC args.
63866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
63966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    LLCArgs.push_back(ToolArgs[i].c_str());
64066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
64166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back("-o");
64266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back(OutputCFile.c_str());   // Output to the C file
64366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back("-march=c");            // Output C language
64466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back(Bitcode.c_str());      // This is the input bitcode
64566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  LLCArgs.push_back(0);
64666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
64766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << "<cbe>"; outs().flush();
64866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  DEBUG(errs() << "\nAbout to run:\t";
64966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
65066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          errs() << " " << LLCArgs[i];
65166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        errs() << "\n";
65266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        );
65366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
65466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                            sys::Path(), Timeout, MemoryLimit))
65566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit);
65666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return GCC::CFile;
65766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
65866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
65966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid CBE::compileProgram(const std::string &Bitcode, std::string *Error,
66066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                         unsigned Timeout, unsigned MemoryLimit) {
66166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path OutputCFile;
66266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
66366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OutputCFile.eraseFromDisk();
66466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
66566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
66666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint CBE::ExecuteProgram(const std::string &Bitcode,
66766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &Args,
66866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &InputFile,
66966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &OutputFile,
67066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        std::string *Error,
67166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &ArgsForGCC,
67266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &SharedLibs,
67366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned Timeout,
67466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned MemoryLimit) {
67566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path OutputCFile;
67666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
67766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
67866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  FileRemover CFileRemove(OutputCFile.str(), !SaveTemps);
67966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
68066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<std::string> GCCArgs(ArgsForGCC);
68166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
68266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
68366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return gcc->ExecuteProgram(OutputCFile.str(), Args, GCC::CFile,
68466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                             InputFile, OutputFile, Error, GCCArgs,
68566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                             Timeout, MemoryLimit);
68666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
68766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
68866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// createCBE - Try to find the 'llc' executable
68966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman///
69066b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanCBE *AbstractInterpreter::createCBE(const char *Argv0,
69166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    std::string &Message,
69266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    const std::string &GCCBinary,
69366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    const std::vector<std::string> *Args,
69466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    const std::vector<std::string> *GCCArgs) {
69566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path LLCPath =
69666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createCBE);
69766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (LLCPath.isEmpty()) {
69866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Message =
69966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      "Cannot find `llc' in executable directory!\n";
70066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return 0;
70166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
70266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
70366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  Message = "Found llc: " + LLCPath.str() + "\n";
70466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
70566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!gcc) {
70666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << Message << "\n";
70766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    exit(1);
70866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
70966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return new CBE(LLCPath, gcc, Args);
71066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
71166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
71266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===---------------------------------------------------------------------===//
71366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// GCC abstraction
71466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
71566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
71666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic bool IsARMArchitecture(std::vector<const char*> Args) {
71766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (std::vector<const char*>::const_iterator
71866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman         I = Args.begin(), E = Args.end(); I != E; ++I) {
71966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (StringRef(*I).equals_lower("-arch")) {
72066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ++I;
72166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (I != E && StringRef(*I).substr(0, strlen("arm")).equals_lower("arm"))
72266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        return true;
72366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
72466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
72566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
72666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return false;
72766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
72866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
72966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint GCC::ExecuteProgram(const std::string &ProgramFile,
73066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &Args,
73166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        FileType fileType,
73266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &InputFile,
73366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::string &OutputFile,
73466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        std::string *Error,
73566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        const std::vector<std::string> &ArgsForGCC,
73666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned Timeout,
73766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        unsigned MemoryLimit) {
73866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char*> GCCArgs;
73966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
74066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back(GCCPath.c_str());
74166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
74266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (TargetTriple.getArch() == Triple::x86)
74366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-m32");
74466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
74566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (std::vector<std::string>::const_iterator
74666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
74766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back(I->c_str());
74866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
74966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Specify -x explicitly in case the extension is wonky
75066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (fileType != ObjectFile) {
75166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-x");
75266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (fileType == CFile) {
75366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      GCCArgs.push_back("c");
75466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      GCCArgs.push_back("-fno-strict-aliasing");
75566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    } else {
75666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      GCCArgs.push_back("assembler");
75766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
75866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      // For ARM architectures we don't want this flag. bugpoint isn't
75966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      // explicitly told what architecture it is working on, so we get
76066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      // it from gcc flags
76166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (TargetTriple.isOSDarwin() && !IsARMArchitecture(GCCArgs))
76266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        GCCArgs.push_back("-force_cpusubtype_ALL");
76366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
76466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
76566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
76666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back(ProgramFile.c_str());  // Specify the input filename.
76766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
76866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-x");
76966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("none");
77066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-o");
77166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path OutputBinary (ProgramFile+".gcc.exe");
77266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string ErrMsg;
77366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (OutputBinary.makeUnique(true, &ErrMsg)) {
77466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "Error making unique filename: " << ErrMsg << "\n";
77566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    exit(1);
77666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
77766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
77866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
77966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add any arguments intended for GCC. We locate them here because this is
78066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // most likely -L and -l options that need to come before other libraries but
78166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // after the source. Other options won't be sensitive to placement on the
78266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // command line, so this should be safe.
78366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
78466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back(ArgsForGCC[i].c_str());
78566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
78666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-lm");                // Hard-code the math library...
78766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-O2");                // Optimize the program a bit...
78866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#if defined (HAVE_LINK_R)
78966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-Wl,-R.");            // Search this dir for .so files
79066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#endif
79166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (TargetTriple.getArch() == Triple::sparc)
79266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-mcpu=v9");
79366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back(0);                    // NULL terminator
79466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
79566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << "<gcc>"; outs().flush();
79666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  DEBUG(errs() << "\nAbout to run:\t";
79766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
79866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          errs() << " " << GCCArgs[i];
79966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        errs() << "\n";
80066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        );
80166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
80266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        sys::Path())) {
80366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    *Error = ProcessFailure(GCCPath, &GCCArgs[0]);
80466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return -1;
80566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
80666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
80766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char*> ProgramArgs;
80866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
80966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Declared here so that the destructor only runs after
81066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // ProgramArgs is used.
81166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string Exec;
81266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
81366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (RemoteClientPath.isEmpty())
81466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(OutputBinary.c_str());
81566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  else {
81666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(RemoteClientPath.c_str());
81766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(RemoteHost.c_str());
81866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (!RemoteUser.empty()) {
81966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ProgramArgs.push_back("-l");
82066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ProgramArgs.push_back(RemoteUser.c_str());
82166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
82266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (!RemotePort.empty()) {
82366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ProgramArgs.push_back("-p");
82466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ProgramArgs.push_back(RemotePort.c_str());
82566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
82666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (!RemoteExtra.empty()) {
82766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      ProgramArgs.push_back(RemoteExtra.c_str());
82866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
82966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
83066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Full path to the binary. We need to cd to the exec directory because
83166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // there is a dylib there that the exec expects to find in the CWD
83266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    char* env_pwd = getenv("PWD");
83366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Exec = "cd ";
83466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Exec += env_pwd;
83566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Exec += "; ./";
83666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Exec += OutputBinary.c_str();
83766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(Exec.c_str());
83866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
83966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
84066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add optional parameters to the running program from Argv
84166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = Args.size(); i != e; ++i)
84266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ProgramArgs.push_back(Args[i].c_str());
84366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ProgramArgs.push_back(0);                // NULL terminator
84466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
84566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Now that we have a binary, run it!
84666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << "<program>"; outs().flush();
84766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  DEBUG(errs() << "\nAbout to run:\t";
84866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        for (unsigned i = 0, e = ProgramArgs.size()-1; i != e; ++i)
84966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          errs() << " " << ProgramArgs[i];
85066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        errs() << "\n";
85166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        );
85266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
85366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps);
85466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
85566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (RemoteClientPath.isEmpty()) {
85666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    DEBUG(errs() << "<run locally>");
85766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    int ExitCode = RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
85866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
85966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        Timeout, MemoryLimit, Error);
86066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Treat a signal (usually SIGSEGV) or timeout as part of the program output
86166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // so that crash-causing miscompilation is handled seamlessly.
86266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (ExitCode < -1) {
86366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      std::ofstream outFile(OutputFile.c_str(), std::ios_base::app);
86466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      outFile << *Error << '\n';
86566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      outFile.close();
86666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      Error->clear();
86766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
86866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return ExitCode;
86966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  } else {
87066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    outs() << "<run remotely>"; outs().flush();
87166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath),
87266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
87366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        sys::Path(OutputFile), Timeout, MemoryLimit);
87466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
87566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
87666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
87766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
87866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                          std::string &OutputFile,
87966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                          const std::vector<std::string> &ArgsForGCC,
88066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                          std::string &Error) {
88166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
88266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string ErrMsg;
88366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (uniqueFilename.makeUnique(true, &ErrMsg)) {
88466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << "Error making unique filename: " << ErrMsg << "\n";
88566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    exit(1);
88666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
88766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OutputFile = uniqueFilename.str();
88866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
88966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::vector<const char*> GCCArgs;
89066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
89166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back(GCCPath.c_str());
89266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
89366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (TargetTriple.getArch() == Triple::x86)
89466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-m32");
89566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
89666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (std::vector<std::string>::const_iterator
89766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
89866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back(I->c_str());
89966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
90066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Compile the C/asm file into a shared object
90166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (fileType != ObjectFile) {
90266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-x");
90366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
90466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
90566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-fno-strict-aliasing");
90666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back(InputFile.c_str());   // Specify the input filename.
90766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-x");
90866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("none");
90966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (TargetTriple.getArch() == Triple::sparc)
91066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-G");       // Compile a shared library, `-G' for Sparc
91166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  else if (TargetTriple.isOSDarwin()) {
91266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // link all source files into a single module in data segment, rather than
91366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // generating blocks. dynamic_lookup requires that you set
91466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // MACOSX_DEPLOYMENT_TARGET=10.3 in your env.  FIXME: it would be better for
91566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // bugpoint to just pass that in the environment of GCC.
91666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-single_module");
91766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-dynamiclib");   // `-dynamiclib' for MacOS X/PowerPC
91866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-undefined");
91966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("dynamic_lookup");
92066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  } else
92166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-shared");  // `-shared' for Linux/X86, maybe others
92266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
92366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if ((TargetTriple.getArch() == Triple::alpha) ||
92466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      (TargetTriple.getArch() == Triple::x86_64))
92566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-fPIC");   // Requires shared objs to contain PIC
92666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
92766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (TargetTriple.getArch() == Triple::sparc)
92866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back("-mcpu=v9");
92966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
93066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-o");
93166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
93266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back("-O2");              // Optimize the program a bit.
93366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
93466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
93566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
93666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Add any arguments intended for GCC. We locate them here because this is
93766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // most likely -L and -l options that need to come before other libraries but
93866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // after the source. Other options won't be sensitive to placement on the
93966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // command line, so this should be safe.
94066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
94166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    GCCArgs.push_back(ArgsForGCC[i].c_str());
94266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  GCCArgs.push_back(0);                    // NULL terminator
94366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
94466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
94566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
94666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << "<gcc>"; outs().flush();
94766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  DEBUG(errs() << "\nAbout to run:\t";
94866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
94966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          errs() << " " << GCCArgs[i];
95066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        errs() << "\n";
95166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        );
95266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
95366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                            sys::Path())) {
95466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Error = ProcessFailure(GCCPath, &GCCArgs[0]);
95566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return 1;
95666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
95766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return 0;
95866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
95966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
96066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// create - Try to find the `gcc' executable
96166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman///
96266b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanGCC *GCC::create(std::string &Message,
96366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                 const std::string &GCCBinary,
96466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                 const std::vector<std::string> *Args) {
96566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary);
96666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (GCCPath.isEmpty()) {
96766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
96866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return 0;
96966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
97066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
97166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::Path RemoteClientPath;
97266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!RemoteClient.empty())
97366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    RemoteClientPath = sys::Program::FindProgramByName(RemoteClient);
97466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
97566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  Message = "Found gcc: " + GCCPath.str() + "\n";
97666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return new GCC(GCCPath, RemoteClientPath, Args);
97766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
978