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