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