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