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