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