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