Also pass -gcc-tool-args when building a shared object.
[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   GCCArgs.insert(GCCArgs.end(), gccArgs.begin(), gccArgs.end());
349
350   // Assuming LLC worked, compile the result with GCC and run it.
351   return gcc->ExecuteProgram(OutputAsmFile.toString(), Args, GCC::AsmFile,
352                              InputFile, OutputFile, GCCArgs,
353                              Timeout, MemoryLimit);
354 }
355
356 /// createLLC - Try to find the LLC executable
357 ///
358 LLC *AbstractInterpreter::createLLC(const std::string &ProgramPath,
359                                     std::string &Message,
360                                     const std::vector<std::string> *Args,
361                                     const std::vector<std::string> *GCCArgs) {
362   std::string LLCPath = FindExecutable("llc", ProgramPath).toString();
363   if (LLCPath.empty()) {
364     Message = "Cannot find `llc' in executable directory or PATH!\n";
365     return 0;
366   }
367
368   Message = "Found llc: " + LLCPath + "\n";
369   GCC *gcc = GCC::create(ProgramPath, Message, GCCArgs);
370   if (!gcc) {
371     std::cerr << Message << "\n";
372     exit(1);
373   }
374   return new LLC(LLCPath, gcc, Args, GCCArgs);
375 }
376
377 //===---------------------------------------------------------------------===//
378 // JIT Implementation of AbstractIntepreter interface
379 //
380 namespace {
381   class JIT : public AbstractInterpreter {
382     std::string LLIPath;          // The path to the LLI executable
383     std::vector<std::string> ToolArgs; // Args to pass to LLI
384   public:
385     JIT(const std::string &Path, const std::vector<std::string> *Args)
386       : LLIPath(Path) {
387       ToolArgs.clear ();
388       if (Args) { ToolArgs = *Args; }
389     }
390
391     virtual int ExecuteProgram(const std::string &Bitcode,
392                                const std::vector<std::string> &Args,
393                                const std::string &InputFile,
394                                const std::string &OutputFile,
395                                const std::vector<std::string> &GCCArgs =
396                                  std::vector<std::string>(),
397                                const std::vector<std::string> &SharedLibs =
398                                  std::vector<std::string>(), 
399                                unsigned Timeout =0,
400                                unsigned MemoryLimit =0);
401   };
402 }
403
404 int JIT::ExecuteProgram(const std::string &Bitcode,
405                         const std::vector<std::string> &Args,
406                         const std::string &InputFile,
407                         const std::string &OutputFile,
408                         const std::vector<std::string> &GCCArgs,
409                         const std::vector<std::string> &SharedLibs,
410                         unsigned Timeout,
411                         unsigned MemoryLimit) {
412   if (!GCCArgs.empty())
413     throw ToolExecutionError("JIT does not support GCC Arguments.");
414   // Construct a vector of parameters, incorporating those from the command-line
415   std::vector<const char*> JITArgs;
416   JITArgs.push_back(LLIPath.c_str());
417   JITArgs.push_back("-force-interpreter=false");
418
419   // Add any extra LLI args.
420   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
421     JITArgs.push_back(ToolArgs[i].c_str());
422
423   for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
424     JITArgs.push_back("-load");
425     JITArgs.push_back(SharedLibs[i].c_str());
426   }
427   JITArgs.push_back(Bitcode.c_str());
428   // Add optional parameters to the running program from Argv
429   for (unsigned i=0, e = Args.size(); i != e; ++i)
430     JITArgs.push_back(Args[i].c_str());
431   JITArgs.push_back(0);
432
433   std::cout << "<jit>" << std::flush;
434   DEBUG(std::cerr << "\nAbout to run:\t";
435         for (unsigned i=0, e = JITArgs.size()-1; i != e; ++i)
436           std::cerr << " " << JITArgs[i];
437         std::cerr << "\n";
438         );
439   DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
440   return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
441       sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
442       Timeout, MemoryLimit);
443 }
444
445 /// createJIT - Try to find the LLI executable
446 ///
447 AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath,
448                    std::string &Message, const std::vector<std::string> *Args) {
449   std::string LLIPath = FindExecutable("lli", ProgPath).toString();
450   if (!LLIPath.empty()) {
451     Message = "Found lli: " + LLIPath + "\n";
452     return new JIT(LLIPath, Args);
453   }
454
455   Message = "Cannot find `lli' in executable directory or PATH!\n";
456   return 0;
457 }
458
459 GCC::FileType CBE::OutputCode(const std::string &Bitcode,
460                               sys::Path &OutputCFile) {
461   sys::Path uniqueFile(Bitcode+".cbe.c");
462   std::string ErrMsg;
463   if (uniqueFile.makeUnique(true, &ErrMsg)) {
464     std::cerr << "Error making unique filename: " << ErrMsg << "\n";
465     exit(1);
466   }
467   OutputCFile = uniqueFile;
468   std::vector<const char *> LLCArgs;
469   LLCArgs.push_back (LLCPath.c_str());
470
471   // Add any extra LLC args.
472   for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
473     LLCArgs.push_back(ToolArgs[i].c_str());
474
475   LLCArgs.push_back ("-o");
476   LLCArgs.push_back (OutputCFile.c_str());   // Output to the C file
477   LLCArgs.push_back ("-march=c");            // Output C language
478   LLCArgs.push_back ("-f");                  // Overwrite as necessary...
479   LLCArgs.push_back (Bitcode.c_str());      // This is the input bitcode
480   LLCArgs.push_back (0);
481
482   std::cout << "<cbe>" << std::flush;
483   DEBUG(std::cerr << "\nAbout to run:\t";
484         for (unsigned i=0, e = LLCArgs.size()-1; i != e; ++i)
485           std::cerr << " " << LLCArgs[i];
486         std::cerr << "\n";
487         );
488   if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
489                             sys::Path()))
490     ProcessFailure(LLCPath, &LLCArgs[0]);
491   return GCC::CFile;
492 }
493
494 void CBE::compileProgram(const std::string &Bitcode) {
495   sys::Path OutputCFile;
496   OutputCode(Bitcode, OutputCFile);
497   OutputCFile.eraseFromDisk();
498 }
499
500 int CBE::ExecuteProgram(const std::string &Bitcode,
501                         const std::vector<std::string> &Args,
502                         const std::string &InputFile,
503                         const std::string &OutputFile,
504                         const std::vector<std::string> &ArgsForGCC,
505                         const std::vector<std::string> &SharedLibs,
506                         unsigned Timeout,
507                         unsigned MemoryLimit) {
508   sys::Path OutputCFile;
509   OutputCode(Bitcode, OutputCFile);
510
511   FileRemover CFileRemove(OutputCFile);
512
513   std::vector<std::string> GCCArgs(ArgsForGCC);
514   GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end());
515
516   return gcc->ExecuteProgram(OutputCFile.toString(), Args, GCC::CFile,
517                              InputFile, OutputFile, GCCArgs,
518                              Timeout, MemoryLimit);
519 }
520
521 /// createCBE - Try to find the 'llc' executable
522 ///
523 CBE *AbstractInterpreter::createCBE(const std::string &ProgramPath,
524                                     std::string &Message,
525                                     const std::vector<std::string> *Args,
526                                     const std::vector<std::string> *GCCArgs) {
527   sys::Path LLCPath = FindExecutable("llc", ProgramPath);
528   if (LLCPath.isEmpty()) {
529     Message =
530       "Cannot find `llc' in executable directory or PATH!\n";
531     return 0;
532   }
533
534   Message = "Found llc: " + LLCPath.toString() + "\n";
535   GCC *gcc = GCC::create(ProgramPath, Message, GCCArgs);
536   if (!gcc) {
537     std::cerr << Message << "\n";
538     exit(1);
539   }
540   return new CBE(LLCPath, gcc, Args);
541 }
542
543 //===---------------------------------------------------------------------===//
544 // GCC abstraction
545 //
546 int GCC::ExecuteProgram(const std::string &ProgramFile,
547                         const std::vector<std::string> &Args,
548                         FileType fileType,
549                         const std::string &InputFile,
550                         const std::string &OutputFile,
551                         const std::vector<std::string> &ArgsForGCC,
552                         unsigned Timeout,
553                         unsigned MemoryLimit) {
554   std::vector<const char*> GCCArgs;
555
556   GCCArgs.push_back(GCCPath.c_str());
557
558   for (std::vector<std::string>::const_iterator
559          I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
560     GCCArgs.push_back(I->c_str());
561
562   // Specify -x explicitly in case the extension is wonky
563   GCCArgs.push_back("-x");
564   if (fileType == CFile) {
565     GCCArgs.push_back("c");
566     GCCArgs.push_back("-fno-strict-aliasing");
567   } else {
568     GCCArgs.push_back("assembler");
569 #ifdef __APPLE__
570     GCCArgs.push_back("-force_cpusubtype_ALL");
571 #endif
572   }
573   GCCArgs.push_back(ProgramFile.c_str());  // Specify the input filename...
574   GCCArgs.push_back("-x");
575   GCCArgs.push_back("none");
576   GCCArgs.push_back("-o");
577   sys::Path OutputBinary (ProgramFile+".gcc.exe");
578   std::string ErrMsg;
579   if (OutputBinary.makeUnique(true, &ErrMsg)) {
580     std::cerr << "Error making unique filename: " << ErrMsg << "\n";
581     exit(1);
582   }
583   GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
584
585   // Add any arguments intended for GCC. We locate them here because this is
586   // most likely -L and -l options that need to come before other libraries but
587   // after the source. Other options won't be sensitive to placement on the
588   // command line, so this should be safe.
589   for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
590     GCCArgs.push_back(ArgsForGCC[i].c_str());
591
592   GCCArgs.push_back("-lm");                // Hard-code the math library...
593   GCCArgs.push_back("-O2");                // Optimize the program a bit...
594 #if defined (HAVE_LINK_R)
595   GCCArgs.push_back("-Wl,-R.");            // Search this dir for .so files
596 #endif
597 #ifdef __sparc__
598   GCCArgs.push_back("-mcpu=v9");
599 #endif
600   GCCArgs.push_back(0);                    // NULL terminator
601
602   std::cout << "<gcc>" << std::flush;
603   DEBUG(std::cerr << "\nAbout to run:\t";
604         for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
605           std::cerr << " " << GCCArgs[i];
606         std::cerr << "\n";
607         );
608   if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
609         sys::Path())) {
610     ProcessFailure(GCCPath, &GCCArgs[0]);
611     exit(1);
612   }
613
614   std::vector<const char*> ProgramArgs;
615
616   if (RemoteClientPath.isEmpty())
617     ProgramArgs.push_back(OutputBinary.c_str());
618   else {
619     ProgramArgs.push_back(RemoteClientPath.c_str());
620     ProgramArgs.push_back(RemoteHost.c_str());
621     ProgramArgs.push_back("-l");
622     ProgramArgs.push_back(RemoteUser.c_str());
623     if (!RemoteExtra.empty()) {
624       ProgramArgs.push_back(RemoteExtra.c_str());
625     }
626
627     char* env_pwd = getenv("PWD");
628     std::string Exec = "cd ";
629     Exec += env_pwd;
630     Exec += "; ./";
631     Exec += OutputBinary.c_str();
632     ProgramArgs.push_back(Exec.c_str());
633   }
634
635   // Add optional parameters to the running program from Argv
636   for (unsigned i=0, e = Args.size(); i != e; ++i)
637     ProgramArgs.push_back(Args[i].c_str());
638   ProgramArgs.push_back(0);                // NULL terminator
639
640   // Now that we have a binary, run it!
641   std::cout << "<program>" << std::flush;
642   DEBUG(std::cerr << "\nAbout to run:\t";
643         for (unsigned i=0, e = ProgramArgs.size()-1; i != e; ++i)
644           std::cerr << " " << ProgramArgs[i];
645         std::cerr << "\n";
646         );
647
648   FileRemover OutputBinaryRemover(OutputBinary);
649
650   if (RemoteClientPath.isEmpty())
651     return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
652         sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
653         Timeout, MemoryLimit);
654   else
655     return RunProgramWithTimeout(sys::Path(RemoteClientPath), &ProgramArgs[0],
656         sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
657         Timeout, MemoryLimit);
658 }
659
660 int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
661                           std::string &OutputFile,
662                           const std::vector<std::string> &ArgsForGCC) {
663   sys::Path uniqueFilename(InputFile+LTDL_SHLIB_EXT);
664   std::string ErrMsg;
665   if (uniqueFilename.makeUnique(true, &ErrMsg)) {
666     std::cerr << "Error making unique filename: " << ErrMsg << "\n";
667     exit(1);
668   }
669   OutputFile = uniqueFilename.toString();
670
671   std::vector<const char*> GCCArgs;
672   
673   GCCArgs.push_back(GCCPath.c_str());
674
675   for (std::vector<std::string>::const_iterator
676          I = gccArgs.begin(), E = gccArgs.end(); I != E; ++I)
677     GCCArgs.push_back(I->c_str());
678
679   // Compile the C/asm file into a shared object
680   GCCArgs.push_back("-x");
681   GCCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
682   GCCArgs.push_back("-fno-strict-aliasing");
683   GCCArgs.push_back(InputFile.c_str());   // Specify the input filename.
684   GCCArgs.push_back("-x");
685   GCCArgs.push_back("none");
686 #if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
687   GCCArgs.push_back("-G");       // Compile a shared library, `-G' for Sparc
688 #elif defined(__APPLE__)
689   // link all source files into a single module in data segment, rather than
690   // generating blocks. dynamic_lookup requires that you set 
691   // MACOSX_DEPLOYMENT_TARGET=10.3 in your env.  FIXME: it would be better for
692   // bugpoint to just pass that in the environment of GCC.
693   GCCArgs.push_back("-single_module");
694   GCCArgs.push_back("-dynamiclib");   // `-dynamiclib' for MacOS X/PowerPC
695   GCCArgs.push_back("-undefined");
696   GCCArgs.push_back("dynamic_lookup");
697 #else
698   GCCArgs.push_back("-shared");  // `-shared' for Linux/X86, maybe others
699 #endif
700
701 #if defined(__ia64__) || defined(__alpha__) || defined(__amd64__)
702   GCCArgs.push_back("-fPIC");   // Requires shared objs to contain PIC
703 #endif
704 #ifdef __sparc__
705   GCCArgs.push_back("-mcpu=v9");
706 #endif
707   GCCArgs.push_back("-o");
708   GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
709   GCCArgs.push_back("-O2");              // Optimize the program a bit.
710
711   
712   
713   // Add any arguments intended for GCC. We locate them here because this is
714   // most likely -L and -l options that need to come before other libraries but
715   // after the source. Other options won't be sensitive to placement on the
716   // command line, so this should be safe.
717   for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
718     GCCArgs.push_back(ArgsForGCC[i].c_str());
719   GCCArgs.push_back(0);                    // NULL terminator
720
721   
722
723   std::cout << "<gcc>" << std::flush;
724   DEBUG(std::cerr << "\nAbout to run:\t";
725         for (unsigned i=0, e = GCCArgs.size()-1; i != e; ++i)
726           std::cerr << " " << GCCArgs[i];
727         std::cerr << "\n";
728         );
729   if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], sys::Path(), sys::Path(),
730                             sys::Path())) {
731     ProcessFailure(GCCPath, &GCCArgs[0]);
732     return 1;
733   }
734   return 0;
735 }
736
737 /// create - Try to find the `gcc' executable
738 ///
739 GCC *GCC::create(const std::string &ProgramPath, std::string &Message,
740                  const std::vector<std::string> *Args) {
741   sys::Path GCCPath = FindExecutable("gcc", ProgramPath);
742   if (GCCPath.isEmpty()) {
743     Message = "Cannot find `gcc' in executable directory or PATH!\n";
744     return 0;
745   }
746
747   sys::Path RemoteClientPath;
748   if (!RemoteClient.empty())
749     RemoteClientPath = FindExecutable(RemoteClient.c_str(), ProgramPath);
750
751   Message = "Found gcc: " + GCCPath.toString() + "\n";
752   return new GCC(GCCPath, RemoteClientPath, Args);
753 }