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