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