1193323Sed//===-- ToolRunner.cpp ----------------------------------------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file implements the interfaces described in the ToolRunner.h file.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#define DEBUG_TYPE "toolrunner"
15193323Sed#include "ToolRunner.h"
16249423Sdim#include "llvm/Config/config.h"   // for HAVE_LINK_R
17193323Sed#include "llvm/Support/CommandLine.h"
18193323Sed#include "llvm/Support/Debug.h"
19193323Sed#include "llvm/Support/FileUtilities.h"
20249423Sdim#include "llvm/Support/Program.h"
21198090Srdivacky#include "llvm/Support/raw_ostream.h"
22193323Sed#include <fstream>
23193323Sed#include <sstream>
24193323Sedusing namespace llvm;
25193323Sed
26198090Srdivackynamespace llvm {
27198090Srdivacky  cl::opt<bool>
28198090Srdivacky  SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files"));
29198090Srdivacky}
30198090Srdivacky
31193323Sednamespace {
32193323Sed  cl::opt<std::string>
33193323Sed  RemoteClient("remote-client",
34193323Sed               cl::desc("Remote execution client (rsh/ssh)"));
35193323Sed
36193323Sed  cl::opt<std::string>
37193323Sed  RemoteHost("remote-host",
38193323Sed             cl::desc("Remote execution (rsh/ssh) host"));
39193323Sed
40193323Sed  cl::opt<std::string>
41198090Srdivacky  RemotePort("remote-port",
42198090Srdivacky             cl::desc("Remote execution (rsh/ssh) port"));
43198090Srdivacky
44198090Srdivacky  cl::opt<std::string>
45193323Sed  RemoteUser("remote-user",
46193323Sed             cl::desc("Remote execution (rsh/ssh) user id"));
47193323Sed
48193323Sed  cl::opt<std::string>
49193323Sed  RemoteExtra("remote-extra-options",
50193323Sed          cl::desc("Remote execution (rsh/ssh) extra options"));
51193323Sed}
52193323Sed
53198090Srdivacky/// RunProgramWithTimeout - This function provides an alternate interface
54198090Srdivacky/// to the sys::Program::ExecuteAndWait interface.
55207618Srdivacky/// @see sys::Program::ExecuteAndWait
56193323Sedstatic int RunProgramWithTimeout(const sys::Path &ProgramPath,
57193323Sed                                 const char **Args,
58193323Sed                                 const sys::Path &StdInFile,
59193323Sed                                 const sys::Path &StdOutFile,
60193323Sed                                 const sys::Path &StdErrFile,
61193323Sed                                 unsigned NumSeconds = 0,
62218885Sdim                                 unsigned MemoryLimit = 0,
63218885Sdim                                 std::string *ErrMsg = 0) {
64193323Sed  const sys::Path* redirects[3];
65193323Sed  redirects[0] = &StdInFile;
66193323Sed  redirects[1] = &StdOutFile;
67193323Sed  redirects[2] = &StdErrFile;
68198090Srdivacky
69198090Srdivacky#if 0 // For debug purposes
70198090Srdivacky  {
71198090Srdivacky    errs() << "RUN:";
72193323Sed    for (unsigned i = 0; Args[i]; ++i)
73198090Srdivacky      errs() << " " << Args[i];
74198090Srdivacky    errs() << "\n";
75193323Sed  }
76198090Srdivacky#endif
77193323Sed
78193323Sed  return
79193323Sed    sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
80218885Sdim                                 NumSeconds, MemoryLimit, ErrMsg);
81193323Sed}
82193323Sed
83198090Srdivacky/// RunProgramRemotelyWithTimeout - This function runs the given program
84198090Srdivacky/// remotely using the given remote client and the sys::Program::ExecuteAndWait.
85198090Srdivacky/// Returns the remote program exit code or reports a remote client error if it
86198090Srdivacky/// fails. Remote client is required to return 255 if it failed or program exit
87198090Srdivacky/// code otherwise.
88207618Srdivacky/// @see sys::Program::ExecuteAndWait
89198090Srdivackystatic int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath,
90198090Srdivacky                                         const char **Args,
91198090Srdivacky                                         const sys::Path &StdInFile,
92198090Srdivacky                                         const sys::Path &StdOutFile,
93198090Srdivacky                                         const sys::Path &StdErrFile,
94198090Srdivacky                                         unsigned NumSeconds = 0,
95198090Srdivacky                                         unsigned MemoryLimit = 0) {
96198090Srdivacky  const sys::Path* redirects[3];
97198090Srdivacky  redirects[0] = &StdInFile;
98198090Srdivacky  redirects[1] = &StdOutFile;
99198090Srdivacky  redirects[2] = &StdErrFile;
100193323Sed
101198090Srdivacky#if 0 // For debug purposes
102198090Srdivacky  {
103198090Srdivacky    errs() << "RUN:";
104198090Srdivacky    for (unsigned i = 0; Args[i]; ++i)
105198090Srdivacky      errs() << " " << Args[i];
106198090Srdivacky    errs() << "\n";
107198090Srdivacky  }
108198090Srdivacky#endif
109193323Sed
110198090Srdivacky  // Run the program remotely with the remote client
111198090Srdivacky  int ReturnCode = sys::Program::ExecuteAndWait(RemoteClientPath, Args,
112198090Srdivacky                                 0, redirects, NumSeconds, MemoryLimit);
113198090Srdivacky
114198090Srdivacky  // Has the remote client fail?
115198090Srdivacky  if (255 == ReturnCode) {
116198090Srdivacky    std::ostringstream OS;
117198090Srdivacky    OS << "\nError running remote client:\n ";
118198090Srdivacky    for (const char **Arg = Args; *Arg; ++Arg)
119198090Srdivacky      OS << " " << *Arg;
120198090Srdivacky    OS << "\n";
121198090Srdivacky
122198090Srdivacky    // The error message is in the output file, let's print it out from there.
123198090Srdivacky    std::ifstream ErrorFile(StdOutFile.c_str());
124198090Srdivacky    if (ErrorFile) {
125198090Srdivacky      std::copy(std::istreambuf_iterator<char>(ErrorFile),
126198090Srdivacky                std::istreambuf_iterator<char>(),
127198090Srdivacky                std::ostreambuf_iterator<char>(OS));
128198090Srdivacky      ErrorFile.close();
129198090Srdivacky    }
130198090Srdivacky
131236386Sdim    errs() << OS.str();
132198090Srdivacky  }
133198090Srdivacky
134198090Srdivacky  return ReturnCode;
135198090Srdivacky}
136198090Srdivacky
137208599Srdivackystatic std::string ProcessFailure(sys::Path ProgPath, const char** Args,
138208599Srdivacky                                  unsigned Timeout = 0,
139208599Srdivacky                                  unsigned MemoryLimit = 0) {
140193323Sed  std::ostringstream OS;
141193323Sed  OS << "\nError running tool:\n ";
142193323Sed  for (const char **Arg = Args; *Arg; ++Arg)
143193323Sed    OS << " " << *Arg;
144193323Sed  OS << "\n";
145218885Sdim
146193323Sed  // Rerun the compiler, capturing any error messages to print them.
147193323Sed  sys::Path ErrorFilename("bugpoint.program_error_messages");
148193323Sed  std::string ErrMsg;
149193323Sed  if (ErrorFilename.makeUnique(true, &ErrMsg)) {
150198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
151193323Sed    exit(1);
152193323Sed  }
153193323Sed  RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
154208599Srdivacky                        ErrorFilename, Timeout, MemoryLimit);
155208599Srdivacky  // FIXME: check return code ?
156193323Sed
157193323Sed  // Print out the error messages generated by GCC if possible...
158193323Sed  std::ifstream ErrorFile(ErrorFilename.c_str());
159193323Sed  if (ErrorFile) {
160193323Sed    std::copy(std::istreambuf_iterator<char>(ErrorFile),
161193323Sed              std::istreambuf_iterator<char>(),
162193323Sed              std::ostreambuf_iterator<char>(OS));
163193323Sed    ErrorFile.close();
164193323Sed  }
165193323Sed
166193323Sed  ErrorFilename.eraseFromDisk();
167207618Srdivacky  return OS.str();
168193323Sed}
169193323Sed
170193323Sed//===---------------------------------------------------------------------===//
171193323Sed// LLI Implementation of AbstractIntepreter interface
172193323Sed//
173193323Sednamespace {
174193323Sed  class LLI : public AbstractInterpreter {
175193323Sed    std::string LLIPath;          // The path to the LLI executable
176193323Sed    std::vector<std::string> ToolArgs; // Args to pass to LLI
177193323Sed  public:
178193323Sed    LLI(const std::string &Path, const std::vector<std::string> *Args)
179193323Sed      : LLIPath(Path) {
180193323Sed      ToolArgs.clear ();
181193323Sed      if (Args) { ToolArgs = *Args; }
182193323Sed    }
183193323Sed
184193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
185193323Sed                               const std::vector<std::string> &Args,
186193323Sed                               const std::string &InputFile,
187193323Sed                               const std::string &OutputFile,
188207618Srdivacky                               std::string *Error,
189193323Sed                               const std::vector<std::string> &GCCArgs,
190193323Sed                               const std::vector<std::string> &SharedLibs =
191193323Sed                               std::vector<std::string>(),
192193323Sed                               unsigned Timeout = 0,
193193323Sed                               unsigned MemoryLimit = 0);
194193323Sed  };
195193323Sed}
196193323Sed
197193323Sedint LLI::ExecuteProgram(const std::string &Bitcode,
198193323Sed                        const std::vector<std::string> &Args,
199193323Sed                        const std::string &InputFile,
200193323Sed                        const std::string &OutputFile,
201207618Srdivacky                        std::string *Error,
202193323Sed                        const std::vector<std::string> &GCCArgs,
203193323Sed                        const std::vector<std::string> &SharedLibs,
204193323Sed                        unsigned Timeout,
205193323Sed                        unsigned MemoryLimit) {
206193323Sed  std::vector<const char*> LLIArgs;
207193323Sed  LLIArgs.push_back(LLIPath.c_str());
208193323Sed  LLIArgs.push_back("-force-interpreter=true");
209193323Sed
210218885Sdim  for (std::vector<std::string>::const_iterator i = SharedLibs.begin(),
211218885Sdim         e = SharedLibs.end(); i != e; ++i) {
212199481Srdivacky    LLIArgs.push_back("-load");
213199481Srdivacky    LLIArgs.push_back((*i).c_str());
214199481Srdivacky  }
215199481Srdivacky
216193323Sed  // Add any extra LLI args.
217193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
218193323Sed    LLIArgs.push_back(ToolArgs[i].c_str());
219193323Sed
220193323Sed  LLIArgs.push_back(Bitcode.c_str());
221193323Sed  // Add optional parameters to the running program from Argv
222193323Sed  for (unsigned i=0, e = Args.size(); i != e; ++i)
223193323Sed    LLIArgs.push_back(Args[i].c_str());
224193323Sed  LLIArgs.push_back(0);
225193323Sed
226198090Srdivacky  outs() << "<lli>"; outs().flush();
227198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
228193323Sed        for (unsigned i=0, e = LLIArgs.size()-1; i != e; ++i)
229198090Srdivacky          errs() << " " << LLIArgs[i];
230198090Srdivacky        errs() << "\n";
231193323Sed        );
232193323Sed  return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
233193323Sed      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
234218885Sdim      Timeout, MemoryLimit, Error);
235193323Sed}
236193323Sed
237234353Sdimvoid AbstractInterpreter::anchor() { }
238234353Sdim
239193323Sed// LLI create method - Try to find the LLI executable
240198090SrdivackyAbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
241193323Sed                                                    std::string &Message,
242193323Sed                                     const std::vector<std::string> *ToolArgs) {
243198090Srdivacky  std::string LLIPath =
244218885Sdim    PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI).str();
245193323Sed  if (!LLIPath.empty()) {
246193323Sed    Message = "Found lli: " + LLIPath + "\n";
247193323Sed    return new LLI(LLIPath, ToolArgs);
248193323Sed  }
249193323Sed
250218885Sdim  Message = "Cannot find `lli' in executable directory!\n";
251193323Sed  return 0;
252193323Sed}
253193323Sed
254193323Sed//===---------------------------------------------------------------------===//
255218885Sdim// Custom compiler command implementation of AbstractIntepreter interface
256218885Sdim//
257218885Sdim// Allows using a custom command for compiling the bitcode, thus allows, for
258218885Sdim// example, to compile a bitcode fragment without linking or executing, then
259218885Sdim// using a custom wrapper script to check for compiler errors.
260218885Sdimnamespace {
261218885Sdim  class CustomCompiler : public AbstractInterpreter {
262218885Sdim    std::string CompilerCommand;
263218885Sdim    std::vector<std::string> CompilerArgs;
264218885Sdim  public:
265218885Sdim    CustomCompiler(
266218885Sdim      const std::string &CompilerCmd, std::vector<std::string> CompArgs) :
267218885Sdim      CompilerCommand(CompilerCmd), CompilerArgs(CompArgs) {}
268218885Sdim
269218885Sdim    virtual void compileProgram(const std::string &Bitcode,
270218885Sdim                                std::string *Error,
271218885Sdim                                unsigned Timeout = 0,
272218885Sdim                                unsigned MemoryLimit = 0);
273218885Sdim
274218885Sdim    virtual int ExecuteProgram(const std::string &Bitcode,
275218885Sdim                               const std::vector<std::string> &Args,
276218885Sdim                               const std::string &InputFile,
277218885Sdim                               const std::string &OutputFile,
278218885Sdim                               std::string *Error,
279218885Sdim                               const std::vector<std::string> &GCCArgs =
280218885Sdim                               std::vector<std::string>(),
281218885Sdim                               const std::vector<std::string> &SharedLibs =
282218885Sdim                               std::vector<std::string>(),
283218885Sdim                               unsigned Timeout = 0,
284218885Sdim                               unsigned MemoryLimit = 0) {
285218885Sdim      *Error = "Execution not supported with -compile-custom";
286218885Sdim      return -1;
287218885Sdim    }
288218885Sdim  };
289218885Sdim}
290218885Sdim
291218885Sdimvoid CustomCompiler::compileProgram(const std::string &Bitcode,
292218885Sdim                                    std::string *Error,
293218885Sdim                                    unsigned Timeout,
294218885Sdim                                    unsigned MemoryLimit) {
295218885Sdim
296218885Sdim  std::vector<const char*> ProgramArgs;
297218885Sdim  ProgramArgs.push_back(CompilerCommand.c_str());
298218885Sdim
299218885Sdim  for (std::size_t i = 0; i < CompilerArgs.size(); ++i)
300218885Sdim    ProgramArgs.push_back(CompilerArgs.at(i).c_str());
301218885Sdim  ProgramArgs.push_back(Bitcode.c_str());
302218885Sdim  ProgramArgs.push_back(0);
303218885Sdim
304218885Sdim  // Add optional parameters to the running program from Argv
305218885Sdim  for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
306218885Sdim    ProgramArgs.push_back(CompilerArgs[i].c_str());
307218885Sdim
308218885Sdim  if (RunProgramWithTimeout( sys::Path(CompilerCommand), &ProgramArgs[0],
309218885Sdim                             sys::Path(), sys::Path(), sys::Path(),
310218885Sdim                             Timeout, MemoryLimit, Error))
311218885Sdim    *Error = ProcessFailure(sys::Path(CompilerCommand), &ProgramArgs[0],
312218885Sdim                           Timeout, MemoryLimit);
313218885Sdim}
314218885Sdim
315218885Sdim//===---------------------------------------------------------------------===//
316193323Sed// Custom execution command implementation of AbstractIntepreter interface
317193323Sed//
318193323Sed// Allows using a custom command for executing the bitcode, thus allows,
319218885Sdim// for example, to invoke a cross compiler for code generation followed by
320193323Sed// a simulator that executes the generated binary.
321193323Sednamespace {
322193323Sed  class CustomExecutor : public AbstractInterpreter {
323193323Sed    std::string ExecutionCommand;
324193323Sed    std::vector<std::string> ExecutorArgs;
325193323Sed  public:
326193323Sed    CustomExecutor(
327193323Sed      const std::string &ExecutionCmd, std::vector<std::string> ExecArgs) :
328193323Sed      ExecutionCommand(ExecutionCmd), ExecutorArgs(ExecArgs) {}
329193323Sed
330193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
331193323Sed                               const std::vector<std::string> &Args,
332193323Sed                               const std::string &InputFile,
333193323Sed                               const std::string &OutputFile,
334207618Srdivacky                               std::string *Error,
335193323Sed                               const std::vector<std::string> &GCCArgs,
336193323Sed                               const std::vector<std::string> &SharedLibs =
337207618Srdivacky                                 std::vector<std::string>(),
338193323Sed                               unsigned Timeout = 0,
339193323Sed                               unsigned MemoryLimit = 0);
340193323Sed  };
341193323Sed}
342193323Sed
343193323Sedint CustomExecutor::ExecuteProgram(const std::string &Bitcode,
344193323Sed                        const std::vector<std::string> &Args,
345193323Sed                        const std::string &InputFile,
346193323Sed                        const std::string &OutputFile,
347207618Srdivacky                        std::string *Error,
348193323Sed                        const std::vector<std::string> &GCCArgs,
349193323Sed                        const std::vector<std::string> &SharedLibs,
350193323Sed                        unsigned Timeout,
351193323Sed                        unsigned MemoryLimit) {
352193323Sed
353193323Sed  std::vector<const char*> ProgramArgs;
354193323Sed  ProgramArgs.push_back(ExecutionCommand.c_str());
355193323Sed
356193323Sed  for (std::size_t i = 0; i < ExecutorArgs.size(); ++i)
357193323Sed    ProgramArgs.push_back(ExecutorArgs.at(i).c_str());
358193323Sed  ProgramArgs.push_back(Bitcode.c_str());
359193323Sed  ProgramArgs.push_back(0);
360193323Sed
361193323Sed  // Add optional parameters to the running program from Argv
362207618Srdivacky  for (unsigned i = 0, e = Args.size(); i != e; ++i)
363193323Sed    ProgramArgs.push_back(Args[i].c_str());
364193323Sed
365193323Sed  return RunProgramWithTimeout(
366193323Sed    sys::Path(ExecutionCommand),
367218885Sdim    &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
368218885Sdim    sys::Path(OutputFile), Timeout, MemoryLimit, Error);
369193323Sed}
370193323Sed
371218885Sdim// Tokenize the CommandLine to the command and the args to allow
372218885Sdim// defining a full command line as the command instead of just the
373218885Sdim// executed program. We cannot just pass the whole string after the command
374218885Sdim// as a single argument because then program sees only a single
375218885Sdim// command line argument (with spaces in it: "foo bar" instead
376218885Sdim// of "foo" and "bar").
377218885Sdim//
378218885Sdim// code borrowed from:
379218885Sdim// http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
380218885Sdimstatic void lexCommand(std::string &Message, const std::string &CommandLine,
381218885Sdim                       std::string &CmdPath, std::vector<std::string> Args) {
382193323Sed
383193323Sed  std::string Command = "";
384193323Sed  std::string delimiters = " ";
385193323Sed
386218885Sdim  std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
387218885Sdim  std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
388193323Sed
389193323Sed  while (std::string::npos != pos || std::string::npos != lastPos) {
390218885Sdim    std::string token = CommandLine.substr(lastPos, pos - lastPos);
391193323Sed    if (Command == "")
392193323Sed       Command = token;
393193323Sed    else
394193323Sed       Args.push_back(token);
395193323Sed    // Skip delimiters.  Note the "not_of"
396218885Sdim    lastPos = CommandLine.find_first_not_of(delimiters, pos);
397193323Sed    // Find next "non-delimiter"
398218885Sdim    pos = CommandLine.find_first_of(delimiters, lastPos);
399193323Sed  }
400193323Sed
401218885Sdim  CmdPath = sys::Program::FindProgramByName(Command).str();
402193323Sed  if (CmdPath.empty()) {
403218885Sdim    Message =
404218885Sdim      std::string("Cannot find '") + Command +
405218885Sdim      "' in PATH!\n";
406218885Sdim    return;
407193323Sed  }
408193323Sed
409193323Sed  Message = "Found command in: " + CmdPath + "\n";
410218885Sdim}
411193323Sed
412218885Sdim// Custom execution environment create method, takes the execution command
413218885Sdim// as arguments
414218885SdimAbstractInterpreter *AbstractInterpreter::createCustomCompiler(
415218885Sdim                    std::string &Message,
416218885Sdim                    const std::string &CompileCommandLine) {
417218885Sdim
418218885Sdim  std::string CmdPath;
419218885Sdim  std::vector<std::string> Args;
420218885Sdim  lexCommand(Message, CompileCommandLine, CmdPath, Args);
421218885Sdim  if (CmdPath.empty())
422218885Sdim    return 0;
423218885Sdim
424218885Sdim  return new CustomCompiler(CmdPath, Args);
425218885Sdim}
426218885Sdim
427218885Sdim// Custom execution environment create method, takes the execution command
428218885Sdim// as arguments
429218885SdimAbstractInterpreter *AbstractInterpreter::createCustomExecutor(
430218885Sdim                    std::string &Message,
431218885Sdim                    const std::string &ExecCommandLine) {
432218885Sdim
433218885Sdim
434218885Sdim  std::string CmdPath;
435218885Sdim  std::vector<std::string> Args;
436218885Sdim  lexCommand(Message, ExecCommandLine, CmdPath, Args);
437218885Sdim  if (CmdPath.empty())
438218885Sdim    return 0;
439218885Sdim
440193323Sed  return new CustomExecutor(CmdPath, Args);
441193323Sed}
442193323Sed
443193323Sed//===----------------------------------------------------------------------===//
444193323Sed// LLC Implementation of AbstractIntepreter interface
445193323Sed//
446218885SdimGCC::FileType LLC::OutputCode(const std::string &Bitcode,
447208599Srdivacky                              sys::Path &OutputAsmFile, std::string &Error,
448208599Srdivacky                              unsigned Timeout, unsigned MemoryLimit) {
449205218Srdivacky  const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
450205218Srdivacky  sys::Path uniqueFile(Bitcode + Suffix);
451193323Sed  std::string ErrMsg;
452193323Sed  if (uniqueFile.makeUnique(true, &ErrMsg)) {
453198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
454193323Sed    exit(1);
455193323Sed  }
456193323Sed  OutputAsmFile = uniqueFile;
457193323Sed  std::vector<const char *> LLCArgs;
458205218Srdivacky  LLCArgs.push_back(LLCPath.c_str());
459193323Sed
460193323Sed  // Add any extra LLC args.
461193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
462193323Sed    LLCArgs.push_back(ToolArgs[i].c_str());
463193323Sed
464205218Srdivacky  LLCArgs.push_back("-o");
465205218Srdivacky  LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file
466205218Srdivacky  LLCArgs.push_back(Bitcode.c_str());      // This is the input bitcode
467218885Sdim
468205218Srdivacky  if (UseIntegratedAssembler)
469205218Srdivacky    LLCArgs.push_back("-filetype=obj");
470218885Sdim
471193323Sed  LLCArgs.push_back (0);
472193323Sed
473205218Srdivacky  outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
474205218Srdivacky  outs().flush();
475198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
476207618Srdivacky        for (unsigned i = 0, e = LLCArgs.size()-1; i != e; ++i)
477198090Srdivacky          errs() << " " << LLCArgs[i];
478198090Srdivacky        errs() << "\n";
479193323Sed        );
480193323Sed  if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
481208599Srdivacky                            sys::Path(), sys::Path(), sys::Path(),
482208599Srdivacky                            Timeout, MemoryLimit))
483208599Srdivacky    Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0],
484208599Srdivacky                           Timeout, MemoryLimit);
485218885Sdim  return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
486193323Sed}
487193323Sed
488208599Srdivackyvoid LLC::compileProgram(const std::string &Bitcode, std::string *Error,
489208599Srdivacky                         unsigned Timeout, unsigned MemoryLimit) {
490193323Sed  sys::Path OutputAsmFile;
491208599Srdivacky  OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit);
492193323Sed  OutputAsmFile.eraseFromDisk();
493193323Sed}
494193323Sed
495193323Sedint LLC::ExecuteProgram(const std::string &Bitcode,
496193323Sed                        const std::vector<std::string> &Args,
497193323Sed                        const std::string &InputFile,
498193323Sed                        const std::string &OutputFile,
499207618Srdivacky                        std::string *Error,
500193323Sed                        const std::vector<std::string> &ArgsForGCC,
501193323Sed                        const std::vector<std::string> &SharedLibs,
502193323Sed                        unsigned Timeout,
503193323Sed                        unsigned MemoryLimit) {
504193323Sed
505193323Sed  sys::Path OutputAsmFile;
506208599Srdivacky  GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout,
507208599Srdivacky                                      MemoryLimit);
508221337Sdim  FileRemover OutFileRemover(OutputAsmFile.str(), !SaveTemps);
509193323Sed
510193323Sed  std::vector<std::string> GCCArgs(ArgsForGCC);
511193323Sed  GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
512193323Sed
513193323Sed  // Assuming LLC worked, compile the result with GCC and run it.
514205218Srdivacky  return gcc->ExecuteProgram(OutputAsmFile.str(), Args, FileKind,
515207618Srdivacky                             InputFile, OutputFile, Error, GCCArgs,
516193323Sed                             Timeout, MemoryLimit);
517193323Sed}
518193323Sed
519193323Sed/// createLLC - Try to find the LLC executable
520193323Sed///
521198090SrdivackyLLC *AbstractInterpreter::createLLC(const char *Argv0,
522193323Sed                                    std::string &Message,
523208599Srdivacky                                    const std::string &GCCBinary,
524193323Sed                                    const std::vector<std::string> *Args,
525205218Srdivacky                                    const std::vector<std::string> *GCCArgs,
526205218Srdivacky                                    bool UseIntegratedAssembler) {
527198090Srdivacky  std::string LLCPath =
528218885Sdim    PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC).str();
529193323Sed  if (LLCPath.empty()) {
530218885Sdim    Message = "Cannot find `llc' in executable directory!\n";
531193323Sed    return 0;
532193323Sed  }
533193323Sed
534208599Srdivacky  GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
535193323Sed  if (!gcc) {
536198090Srdivacky    errs() << Message << "\n";
537193323Sed    exit(1);
538193323Sed  }
539249423Sdim  Message = "Found llc: " + LLCPath + "\n";
540208599Srdivacky  return new LLC(LLCPath, gcc, Args, UseIntegratedAssembler);
541193323Sed}
542193323Sed
543193323Sed//===---------------------------------------------------------------------===//
544193323Sed// JIT Implementation of AbstractIntepreter interface
545193323Sed//
546193323Sednamespace {
547193323Sed  class JIT : public AbstractInterpreter {
548193323Sed    std::string LLIPath;          // The path to the LLI executable
549193323Sed    std::vector<std::string> ToolArgs; // Args to pass to LLI
550193323Sed  public:
551193323Sed    JIT(const std::string &Path, const std::vector<std::string> *Args)
552193323Sed      : LLIPath(Path) {
553193323Sed      ToolArgs.clear ();
554193323Sed      if (Args) { ToolArgs = *Args; }
555193323Sed    }
556193323Sed
557193323Sed    virtual int ExecuteProgram(const std::string &Bitcode,
558193323Sed                               const std::vector<std::string> &Args,
559193323Sed                               const std::string &InputFile,
560193323Sed                               const std::string &OutputFile,
561207618Srdivacky                               std::string *Error,
562193323Sed                               const std::vector<std::string> &GCCArgs =
563193323Sed                                 std::vector<std::string>(),
564193323Sed                               const std::vector<std::string> &SharedLibs =
565218885Sdim                                 std::vector<std::string>(),
566207618Srdivacky                               unsigned Timeout = 0,
567207618Srdivacky                               unsigned MemoryLimit = 0);
568193323Sed  };
569193323Sed}
570193323Sed
571193323Sedint JIT::ExecuteProgram(const std::string &Bitcode,
572193323Sed                        const std::vector<std::string> &Args,
573193323Sed                        const std::string &InputFile,
574193323Sed                        const std::string &OutputFile,
575207618Srdivacky                        std::string *Error,
576193323Sed                        const std::vector<std::string> &GCCArgs,
577193323Sed                        const std::vector<std::string> &SharedLibs,
578193323Sed                        unsigned Timeout,
579193323Sed                        unsigned MemoryLimit) {
580193323Sed  // Construct a vector of parameters, incorporating those from the command-line
581193323Sed  std::vector<const char*> JITArgs;
582193323Sed  JITArgs.push_back(LLIPath.c_str());
583193323Sed  JITArgs.push_back("-force-interpreter=false");
584193323Sed
585193323Sed  // Add any extra LLI args.
586193323Sed  for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
587193323Sed    JITArgs.push_back(ToolArgs[i].c_str());
588193323Sed
589193323Sed  for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
590193323Sed    JITArgs.push_back("-load");
591193323Sed    JITArgs.push_back(SharedLibs[i].c_str());
592193323Sed  }
593193323Sed  JITArgs.push_back(Bitcode.c_str());
594193323Sed  // Add optional parameters to the running program from Argv
595193323Sed  for (unsigned i=0, e = Args.size(); i != e; ++i)
596193323Sed    JITArgs.push_back(Args[i].c_str());
597193323Sed  JITArgs.push_back(0);
598193323Sed
599198090Srdivacky  outs() << "<jit>"; outs().flush();
600198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
601193323Sed        for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
602198090Srdivacky          errs() << " " << JITArgs[i];
603198090Srdivacky        errs() << "\n";
604193323Sed        );
605198090Srdivacky  DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
606193323Sed  return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
607193323Sed      sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
608218885Sdim      Timeout, MemoryLimit, Error);
609193323Sed}
610193323Sed
611193323Sed/// createJIT - Try to find the LLI executable
612193323Sed///
613198090SrdivackyAbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
614193323Sed                   std::string &Message, const std::vector<std::string> *Args) {
615198090Srdivacky  std::string LLIPath =
616218885Sdim    PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT).str();
617193323Sed  if (!LLIPath.empty()) {
618193323Sed    Message = "Found lli: " + LLIPath + "\n";
619193323Sed    return new JIT(LLIPath, Args);
620193323Sed  }
621193323Sed
622218885Sdim  Message = "Cannot find `lli' in executable directory!\n";
623193323Sed  return 0;
624193323Sed}
625193323Sed
626193323Sed//===---------------------------------------------------------------------===//
627193323Sed// GCC abstraction
628193323Sed//
629198090Srdivacky
630212793Sdimstatic bool IsARMArchitecture(std::vector<const char*> Args) {
631212793Sdim  for (std::vector<const char*>::const_iterator
632198090Srdivacky         I = Args.begin(), E = Args.end(); I != E; ++I) {
633208599Srdivacky    if (StringRef(*I).equals_lower("-arch")) {
634198090Srdivacky      ++I;
635208599Srdivacky      if (I != E && StringRef(*I).substr(0, strlen("arm")).equals_lower("arm"))
636198090Srdivacky        return true;
637198090Srdivacky    }
638198090Srdivacky  }
639198090Srdivacky
640198090Srdivacky  return false;
641198090Srdivacky}
642198090Srdivacky
643193323Sedint GCC::ExecuteProgram(const std::string &ProgramFile,
644193323Sed                        const std::vector<std::string> &Args,
645193323Sed                        FileType fileType,
646193323Sed                        const std::string &InputFile,
647193323Sed                        const std::string &OutputFile,
648207618Srdivacky                        std::string *Error,
649193323Sed                        const std::vector<std::string> &ArgsForGCC,
650193323Sed                        unsigned Timeout,
651193323Sed                        unsigned MemoryLimit) {
652193323Sed  std::vector<const char*> GCCArgs;
653193323Sed
654193323Sed  GCCArgs.push_back(GCCPath.c_str());
655193323Sed
656205218Srdivacky  if (TargetTriple.getArch() == Triple::x86)
657205218Srdivacky    GCCArgs.push_back("-m32");
658205218Srdivacky
659193323Sed  for (std::vector<std::string>::const_iterator
660193323Sed         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
661193323Sed    GCCArgs.push_back(I->c_str());
662193323Sed
663193323Sed  // Specify -x explicitly in case the extension is wonky
664205218Srdivacky  if (fileType != ObjectFile) {
665205218Srdivacky    GCCArgs.push_back("-x");
666205218Srdivacky    if (fileType == CFile) {
667205218Srdivacky      GCCArgs.push_back("c");
668205218Srdivacky      GCCArgs.push_back("-fno-strict-aliasing");
669205218Srdivacky    } else {
670205218Srdivacky      GCCArgs.push_back("assembler");
671198090Srdivacky
672205218Srdivacky      // For ARM architectures we don't want this flag. bugpoint isn't
673205218Srdivacky      // explicitly told what architecture it is working on, so we get
674205218Srdivacky      // it from gcc flags
675221337Sdim      if (TargetTriple.isOSDarwin() && !IsARMArchitecture(GCCArgs))
676205218Srdivacky        GCCArgs.push_back("-force_cpusubtype_ALL");
677205218Srdivacky    }
678193323Sed  }
679218885Sdim
680205218Srdivacky  GCCArgs.push_back(ProgramFile.c_str());  // Specify the input filename.
681218885Sdim
682193323Sed  GCCArgs.push_back("-x");
683193323Sed  GCCArgs.push_back("none");
684193323Sed  GCCArgs.push_back("-o");
685193323Sed  sys::Path OutputBinary (ProgramFile+".gcc.exe");
686193323Sed  std::string ErrMsg;
687193323Sed  if (OutputBinary.makeUnique(true, &ErrMsg)) {
688198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
689193323Sed    exit(1);
690193323Sed  }
691193323Sed  GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
692193323Sed
693193323Sed  // Add any arguments intended for GCC. We locate them here because this is
694193323Sed  // most likely -L and -l options that need to come before other libraries but
695193323Sed  // after the source. Other options won't be sensitive to placement on the
696193323Sed  // command line, so this should be safe.
697193323Sed  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
698193323Sed    GCCArgs.push_back(ArgsForGCC[i].c_str());
699193323Sed
700193323Sed  GCCArgs.push_back("-lm");                // Hard-code the math library...
701193323Sed  GCCArgs.push_back("-O2");                // Optimize the program a bit...
702193323Sed#if defined (HAVE_LINK_R)
703193323Sed  GCCArgs.push_back("-Wl,-R.");            // Search this dir for .so files
704193323Sed#endif
705198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
706198090Srdivacky    GCCArgs.push_back("-mcpu=v9");
707193323Sed  GCCArgs.push_back(0);                    // NULL terminator
708193323Sed
709198090Srdivacky  outs() << "<gcc>"; outs().flush();
710198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
711207618Srdivacky        for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
712198090Srdivacky          errs() << " " << GCCArgs[i];
713198090Srdivacky        errs() << "\n";
714193323Sed        );
715193323Sed  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
716193323Sed        sys::Path())) {
717207618Srdivacky    *Error = ProcessFailure(GCCPath, &GCCArgs[0]);
718207618Srdivacky    return -1;
719193323Sed  }
720193323Sed
721193323Sed  std::vector<const char*> ProgramArgs;
722193323Sed
723212793Sdim  // Declared here so that the destructor only runs after
724212793Sdim  // ProgramArgs is used.
725212793Sdim  std::string Exec;
726212793Sdim
727193323Sed  if (RemoteClientPath.isEmpty())
728193323Sed    ProgramArgs.push_back(OutputBinary.c_str());
729193323Sed  else {
730193323Sed    ProgramArgs.push_back(RemoteClientPath.c_str());
731193323Sed    ProgramArgs.push_back(RemoteHost.c_str());
732198090Srdivacky    if (!RemoteUser.empty()) {
733198090Srdivacky      ProgramArgs.push_back("-l");
734198090Srdivacky      ProgramArgs.push_back(RemoteUser.c_str());
735198090Srdivacky    }
736198090Srdivacky    if (!RemotePort.empty()) {
737198090Srdivacky      ProgramArgs.push_back("-p");
738198090Srdivacky      ProgramArgs.push_back(RemotePort.c_str());
739198090Srdivacky    }
740193323Sed    if (!RemoteExtra.empty()) {
741193323Sed      ProgramArgs.push_back(RemoteExtra.c_str());
742193323Sed    }
743193323Sed
744198090Srdivacky    // Full path to the binary. We need to cd to the exec directory because
745198090Srdivacky    // there is a dylib there that the exec expects to find in the CWD
746193323Sed    char* env_pwd = getenv("PWD");
747212793Sdim    Exec = "cd ";
748193323Sed    Exec += env_pwd;
749193323Sed    Exec += "; ./";
750193323Sed    Exec += OutputBinary.c_str();
751193323Sed    ProgramArgs.push_back(Exec.c_str());
752193323Sed  }
753193323Sed
754193323Sed  // Add optional parameters to the running program from Argv
755207618Srdivacky  for (unsigned i = 0, e = Args.size(); i != e; ++i)
756193323Sed    ProgramArgs.push_back(Args[i].c_str());
757193323Sed  ProgramArgs.push_back(0);                // NULL terminator
758193323Sed
759193323Sed  // Now that we have a binary, run it!
760198090Srdivacky  outs() << "<program>"; outs().flush();
761198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
762207618Srdivacky        for (unsigned i = 0, e = ProgramArgs.size()-1; i != e; ++i)
763198090Srdivacky          errs() << " " << ProgramArgs[i];
764198090Srdivacky        errs() << "\n";
765193323Sed        );
766193323Sed
767221337Sdim  FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps);
768193323Sed
769198090Srdivacky  if (RemoteClientPath.isEmpty()) {
770207618Srdivacky    DEBUG(errs() << "<run locally>");
771223013Sdim    int ExitCode = RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
772193323Sed        sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
773218885Sdim        Timeout, MemoryLimit, Error);
774223013Sdim    // Treat a signal (usually SIGSEGV) or timeout as part of the program output
775223013Sdim    // so that crash-causing miscompilation is handled seamlessly.
776223013Sdim    if (ExitCode < -1) {
777223013Sdim      std::ofstream outFile(OutputFile.c_str(), std::ios_base::app);
778223013Sdim      outFile << *Error << '\n';
779223013Sdim      outFile.close();
780223013Sdim      Error->clear();
781223013Sdim    }
782223013Sdim    return ExitCode;
783198090Srdivacky  } else {
784198090Srdivacky    outs() << "<run remotely>"; outs().flush();
785198090Srdivacky    return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath),
786198090Srdivacky        &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
787198090Srdivacky        sys::Path(OutputFile), Timeout, MemoryLimit);
788198090Srdivacky  }
789193323Sed}
790193323Sed
791193323Sedint GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
792193323Sed                          std::string &OutputFile,
793207618Srdivacky                          const std::vector<std::string> &ArgsForGCC,
794207618Srdivacky                          std::string &Error) {
795193323Sed  sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
796193323Sed  std::string ErrMsg;
797193323Sed  if (uniqueFilename.makeUnique(true, &ErrMsg)) {
798198090Srdivacky    errs() << "Error making unique filename: " << ErrMsg << "\n";
799193323Sed    exit(1);
800193323Sed  }
801198090Srdivacky  OutputFile = uniqueFilename.str();
802193323Sed
803193323Sed  std::vector<const char*> GCCArgs;
804218885Sdim
805193323Sed  GCCArgs.push_back(GCCPath.c_str());
806193323Sed
807205218Srdivacky  if (TargetTriple.getArch() == Triple::x86)
808205218Srdivacky    GCCArgs.push_back("-m32");
809205218Srdivacky
810193323Sed  for (std::vector<std::string>::const_iterator
811193323Sed         I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
812193323Sed    GCCArgs.push_back(I->c_str());
813193323Sed
814193323Sed  // Compile the C/asm file into a shared object
815205218Srdivacky  if (fileType != ObjectFile) {
816205218Srdivacky    GCCArgs.push_back("-x");
817205218Srdivacky    GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
818205218Srdivacky  }
819193323Sed  GCCArgs.push_back("-fno-strict-aliasing");
820193323Sed  GCCArgs.push_back(InputFile.c_str());   // Specify the input filename.
821193323Sed  GCCArgs.push_back("-x");
822193323Sed  GCCArgs.push_back("none");
823198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
824198090Srdivacky    GCCArgs.push_back("-G");       // Compile a shared library, `-G' for Sparc
825221337Sdim  else if (TargetTriple.isOSDarwin()) {
826198090Srdivacky    // link all source files into a single module in data segment, rather than
827218885Sdim    // generating blocks. dynamic_lookup requires that you set
828198090Srdivacky    // MACOSX_DEPLOYMENT_TARGET=10.3 in your env.  FIXME: it would be better for
829198090Srdivacky    // bugpoint to just pass that in the environment of GCC.
830198090Srdivacky    GCCArgs.push_back("-single_module");
831198090Srdivacky    GCCArgs.push_back("-dynamiclib");   // `-dynamiclib' for MacOS X/PowerPC
832198090Srdivacky    GCCArgs.push_back("-undefined");
833198090Srdivacky    GCCArgs.push_back("dynamic_lookup");
834198090Srdivacky  } else
835198090Srdivacky    GCCArgs.push_back("-shared");  // `-shared' for Linux/X86, maybe others
836193323Sed
837234353Sdim  if (TargetTriple.getArch() == Triple::x86_64)
838198090Srdivacky    GCCArgs.push_back("-fPIC");   // Requires shared objs to contain PIC
839198090Srdivacky
840198090Srdivacky  if (TargetTriple.getArch() == Triple::sparc)
841198090Srdivacky    GCCArgs.push_back("-mcpu=v9");
842198090Srdivacky
843193323Sed  GCCArgs.push_back("-o");
844193323Sed  GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
845193323Sed  GCCArgs.push_back("-O2");              // Optimize the program a bit.
846193323Sed
847218885Sdim
848218885Sdim
849193323Sed  // Add any arguments intended for GCC. We locate them here because this is
850193323Sed  // most likely -L and -l options that need to come before other libraries but
851193323Sed  // after the source. Other options won't be sensitive to placement on the
852193323Sed  // command line, so this should be safe.
853193323Sed  for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
854193323Sed    GCCArgs.push_back(ArgsForGCC[i].c_str());
855193323Sed  GCCArgs.push_back(0);                    // NULL terminator
856193323Sed
857193323Sed
858218885Sdim
859198090Srdivacky  outs() << "<gcc>"; outs().flush();
860198090Srdivacky  DEBUG(errs() << "\nAbout to run:\t";
861207618Srdivacky        for (unsigned i = 0, e = GCCArgs.size()-1; i != e; ++i)
862198090Srdivacky          errs() << " " << GCCArgs[i];
863198090Srdivacky        errs() << "\n";
864193323Sed        );
865193323Sed  if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
866193323Sed                            sys::Path())) {
867207618Srdivacky    Error = ProcessFailure(GCCPath, &GCCArgs[0]);
868193323Sed    return 1;
869193323Sed  }
870193323Sed  return 0;
871193323Sed}
872193323Sed
873193323Sed/// create - Try to find the `gcc' executable
874193323Sed///
875198090SrdivackyGCC *GCC::create(std::string &Message,
876208599Srdivacky                 const std::string &GCCBinary,
877193323Sed                 const std::vector<std::string> *Args) {
878208599Srdivacky  sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary);
879193323Sed  if (GCCPath.isEmpty()) {
880218885Sdim    Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
881193323Sed    return 0;
882193323Sed  }
883193323Sed
884193323Sed  sys::Path RemoteClientPath;
885193323Sed  if (!RemoteClient.empty())
886198090Srdivacky    RemoteClientPath = sys::Program::FindProgramByName(RemoteClient);
887193323Sed
888198090Srdivacky  Message = "Found gcc: " + GCCPath.str() + "\n";
889193323Sed  return new GCC(GCCPath, RemoteClientPath, Args);
890193323Sed}
891