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 const 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 const 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(LLVM_ON_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 /// @brief 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 program sees only a single 359 // command line argument (with spaces in it: "foo bar" instead 360 // of "foo" and "bar"). 361 // 362 // code borrowed from: 363 // http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html 364 static void lexCommand(std::string &Message, const std::string &CommandLine, 365 std::string &CmdPath, std::vector<std::string> &Args) { 366 367 std::string Command = ""; 368 std::string delimiters = " "; 369 370 std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0); 371 std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos); 372 373 while (std::string::npos != pos || std::string::npos != lastPos) { 374 std::string token = CommandLine.substr(lastPos, pos - lastPos); 375 if (Command == "") 376 Command = token; 377 else 378 Args.push_back(token); 379 // Skip delimiters. Note the "not_of" 380 lastPos = CommandLine.find_first_not_of(delimiters, pos); 381 // Find next "non-delimiter" 382 pos = CommandLine.find_first_of(delimiters, lastPos); 383 } 384 385 auto Path = sys::findProgramByName(Command); 386 if (!Path) { 387 Message = std::string("Cannot find '") + Command + "' in PATH: " + 388 Path.getError().message() + "\n"; 389 return; 390 } 391 CmdPath = *Path; 392 393 Message = "Found command in: " + CmdPath + "\n"; 394 } 395 396 // Custom execution environment create method, takes the execution command 397 // as arguments 398 AbstractInterpreter *AbstractInterpreter::createCustomCompiler( 399 std::string &Message, const std::string &CompileCommandLine) { 400 401 std::string CmdPath; 402 std::vector<std::string> Args; 403 lexCommand(Message, CompileCommandLine, CmdPath, Args); 404 if (CmdPath.empty()) 405 return nullptr; 406 407 return new CustomCompiler(CmdPath, Args); 408 } 409 410 // Custom execution environment create method, takes the execution command 411 // as arguments 412 AbstractInterpreter * 413 AbstractInterpreter::createCustomExecutor(std::string &Message, 414 const std::string &ExecCommandLine) { 415 416 std::string CmdPath; 417 std::vector<std::string> Args; 418 lexCommand(Message, ExecCommandLine, CmdPath, Args); 419 if (CmdPath.empty()) 420 return nullptr; 421 422 return new CustomExecutor(CmdPath, Args); 423 } 424 425 //===----------------------------------------------------------------------===// 426 // LLC Implementation of AbstractIntepreter interface 427 // 428 Expected<CC::FileType> LLC::OutputCode(const std::string &Bitcode, 429 std::string &OutputAsmFile, 430 unsigned Timeout, unsigned MemoryLimit) { 431 const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s"); 432 433 SmallString<128> UniqueFile; 434 std::error_code EC = 435 sys::fs::createUniqueFile(Bitcode + "-%%%%%%%" + Suffix, UniqueFile); 436 if (EC) { 437 errs() << "Error making unique filename: " << EC.message() << "\n"; 438 exit(1); 439 } 440 OutputAsmFile = UniqueFile.str(); 441 std::vector<const char *> LLCArgs; 442 LLCArgs.push_back(LLCPath.c_str()); 443 444 // Add any extra LLC args. 445 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) 446 LLCArgs.push_back(ToolArgs[i].c_str()); 447 448 LLCArgs.push_back("-o"); 449 LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file 450 LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode 451 452 if (UseIntegratedAssembler) 453 LLCArgs.push_back("-filetype=obj"); 454 455 LLCArgs.push_back(nullptr); 456 457 outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>"); 458 outs().flush(); 459 DEBUG(errs() << "\nAbout to run:\t"; 460 for (unsigned i = 0, e = LLCArgs.size() - 1; i != e; ++i) errs() 461 << " " << LLCArgs[i]; 462 errs() << "\n";); 463 if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], "", "", "", Timeout, 464 MemoryLimit)) 465 return ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit); 466 return UseIntegratedAssembler ? CC::ObjectFile : CC::AsmFile; 467 } 468 469 Error LLC::compileProgram(const std::string &Bitcode, unsigned Timeout, 470 unsigned MemoryLimit) { 471 std::string OutputAsmFile; 472 Expected<CC::FileType> Result = 473 OutputCode(Bitcode, OutputAsmFile, Timeout, MemoryLimit); 474 sys::fs::remove(OutputAsmFile); 475 if (Error E = Result.takeError()) 476 return E; 477 return Error::success(); 478 } 479 480 Expected<int> LLC::ExecuteProgram(const std::string &Bitcode, 481 const std::vector<std::string> &Args, 482 const std::string &InputFile, 483 const std::string &OutputFile, 484 const std::vector<std::string> &ArgsForCC, 485 const std::vector<std::string> &SharedLibs, 486 unsigned Timeout, unsigned MemoryLimit) { 487 488 std::string OutputAsmFile; 489 Expected<CC::FileType> FileKind = 490 OutputCode(Bitcode, OutputAsmFile, Timeout, MemoryLimit); 491 FileRemover OutFileRemover(OutputAsmFile, !SaveTemps); 492 if (Error E = FileKind.takeError()) 493 return std::move(E); 494 495 std::vector<std::string> CCArgs(ArgsForCC); 496 CCArgs.insert(CCArgs.end(), SharedLibs.begin(), SharedLibs.end()); 497 498 // Assuming LLC worked, compile the result with CC and run it. 499 return cc->ExecuteProgram(OutputAsmFile, Args, *FileKind, InputFile, 500 OutputFile, CCArgs, Timeout, MemoryLimit); 501 } 502 503 /// createLLC - Try to find the LLC executable 504 /// 505 LLC *AbstractInterpreter::createLLC(const char *Argv0, std::string &Message, 506 const std::string &CCBinary, 507 const std::vector<std::string> *Args, 508 const std::vector<std::string> *CCArgs, 509 bool UseIntegratedAssembler) { 510 std::string LLCPath = 511 PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC); 512 if (LLCPath.empty()) { 513 Message = "Cannot find `llc' in executable directory!\n"; 514 return nullptr; 515 } 516 517 CC *cc = CC::create(Message, CCBinary, CCArgs); 518 if (!cc) { 519 errs() << Message << "\n"; 520 exit(1); 521 } 522 Message = "Found llc: " + LLCPath + "\n"; 523 return new LLC(LLCPath, cc, Args, UseIntegratedAssembler); 524 } 525 526 //===---------------------------------------------------------------------===// 527 // JIT Implementation of AbstractIntepreter interface 528 // 529 namespace { 530 class JIT : public AbstractInterpreter { 531 std::string LLIPath; // The path to the LLI executable 532 std::vector<std::string> ToolArgs; // Args to pass to LLI 533 public: 534 JIT(const std::string &Path, const std::vector<std::string> *Args) 535 : LLIPath(Path) { 536 ToolArgs.clear(); 537 if (Args) { 538 ToolArgs = *Args; 539 } 540 } 541 542 Expected<int> ExecuteProgram( 543 const std::string &Bitcode, const std::vector<std::string> &Args, 544 const std::string &InputFile, const std::string &OutputFile, 545 const std::vector<std::string> &CCArgs = std::vector<std::string>(), 546 const std::vector<std::string> &SharedLibs = std::vector<std::string>(), 547 unsigned Timeout = 0, unsigned MemoryLimit = 0) override; 548 }; 549 } 550 551 Expected<int> JIT::ExecuteProgram(const std::string &Bitcode, 552 const std::vector<std::string> &Args, 553 const std::string &InputFile, 554 const std::string &OutputFile, 555 const std::vector<std::string> &CCArgs, 556 const std::vector<std::string> &SharedLibs, 557 unsigned Timeout, unsigned MemoryLimit) { 558 // Construct a vector of parameters, incorporating those from the command-line 559 std::vector<const char *> JITArgs; 560 JITArgs.push_back(LLIPath.c_str()); 561 JITArgs.push_back("-force-interpreter=false"); 562 563 // Add any extra LLI args. 564 for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i) 565 JITArgs.push_back(ToolArgs[i].c_str()); 566 567 for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) { 568 JITArgs.push_back("-load"); 569 JITArgs.push_back(SharedLibs[i].c_str()); 570 } 571 JITArgs.push_back(Bitcode.c_str()); 572 // Add optional parameters to the running program from Argv 573 for (unsigned i = 0, e = Args.size(); i != e; ++i) 574 JITArgs.push_back(Args[i].c_str()); 575 JITArgs.push_back(nullptr); 576 577 outs() << "<jit>"; 578 outs().flush(); 579 DEBUG(errs() << "\nAbout to run:\t"; 580 for (unsigned i = 0, e = JITArgs.size() - 1; i != e; ++i) errs() 581 << " " << JITArgs[i]; 582 errs() << "\n";); 583 DEBUG(errs() << "\nSending output to " << OutputFile << "\n"); 584 return RunProgramWithTimeout(LLIPath, &JITArgs[0], InputFile, OutputFile, 585 OutputFile, Timeout, MemoryLimit); 586 } 587 588 /// createJIT - Try to find the LLI executable 589 /// 590 AbstractInterpreter * 591 AbstractInterpreter::createJIT(const char *Argv0, std::string &Message, 592 const std::vector<std::string> *Args) { 593 std::string LLIPath = 594 PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT); 595 if (!LLIPath.empty()) { 596 Message = "Found lli: " + LLIPath + "\n"; 597 return new JIT(LLIPath, Args); 598 } 599 600 Message = "Cannot find `lli' in executable directory!\n"; 601 return nullptr; 602 } 603 604 //===---------------------------------------------------------------------===// 605 // CC abstraction 606 // 607 608 static bool IsARMArchitecture(std::vector<const char *> Args) { 609 for (std::vector<const char *>::const_iterator I = Args.begin(), 610 E = Args.end(); 611 I != E; ++I) { 612 if (StringRef(*I).equals_lower("-arch")) { 613 ++I; 614 if (I != E && StringRef(*I).startswith_lower("arm")) 615 return true; 616 } 617 } 618 619 return false; 620 } 621 622 Expected<int> CC::ExecuteProgram(const std::string &ProgramFile, 623 const std::vector<std::string> &Args, 624 FileType fileType, 625 const std::string &InputFile, 626 const std::string &OutputFile, 627 const std::vector<std::string> &ArgsForCC, 628 unsigned Timeout, unsigned MemoryLimit) { 629 std::vector<const char *> CCArgs; 630 631 CCArgs.push_back(CCPath.c_str()); 632 633 if (TargetTriple.getArch() == Triple::x86) 634 CCArgs.push_back("-m32"); 635 636 for (std::vector<std::string>::const_iterator I = ccArgs.begin(), 637 E = ccArgs.end(); 638 I != E; ++I) 639 CCArgs.push_back(I->c_str()); 640 641 // Specify -x explicitly in case the extension is wonky 642 if (fileType != ObjectFile) { 643 CCArgs.push_back("-x"); 644 if (fileType == CFile) { 645 CCArgs.push_back("c"); 646 CCArgs.push_back("-fno-strict-aliasing"); 647 } else { 648 CCArgs.push_back("assembler"); 649 650 // For ARM architectures we don't want this flag. bugpoint isn't 651 // explicitly told what architecture it is working on, so we get 652 // it from cc flags 653 if (TargetTriple.isOSDarwin() && !IsARMArchitecture(CCArgs)) 654 CCArgs.push_back("-force_cpusubtype_ALL"); 655 } 656 } 657 658 CCArgs.push_back(ProgramFile.c_str()); // Specify the input filename. 659 660 CCArgs.push_back("-x"); 661 CCArgs.push_back("none"); 662 CCArgs.push_back("-o"); 663 664 SmallString<128> OutputBinary; 665 std::error_code EC = 666 sys::fs::createUniqueFile(ProgramFile + "-%%%%%%%.cc.exe", OutputBinary); 667 if (EC) { 668 errs() << "Error making unique filename: " << EC.message() << "\n"; 669 exit(1); 670 } 671 CCArgs.push_back(OutputBinary.c_str()); // Output to the right file... 672 673 // Add any arguments intended for CC. We locate them here because this is 674 // most likely -L and -l options that need to come before other libraries but 675 // after the source. Other options won't be sensitive to placement on the 676 // command line, so this should be safe. 677 for (unsigned i = 0, e = ArgsForCC.size(); i != e; ++i) 678 CCArgs.push_back(ArgsForCC[i].c_str()); 679 680 CCArgs.push_back("-lm"); // Hard-code the math library... 681 CCArgs.push_back("-O2"); // Optimize the program a bit... 682 if (TargetTriple.getArch() == Triple::sparc) 683 CCArgs.push_back("-mcpu=v9"); 684 CCArgs.push_back(nullptr); // NULL terminator 685 686 outs() << "<CC>"; 687 outs().flush(); 688 DEBUG(errs() << "\nAbout to run:\t"; 689 for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs() 690 << " " << CCArgs[i]; 691 errs() << "\n";); 692 if (RunProgramWithTimeout(CCPath, &CCArgs[0], "", "", "")) 693 return ProcessFailure(CCPath, &CCArgs[0]); 694 695 std::vector<const char *> ProgramArgs; 696 697 // Declared here so that the destructor only runs after 698 // ProgramArgs is used. 699 std::string Exec; 700 701 if (RemoteClientPath.empty()) 702 ProgramArgs.push_back(OutputBinary.c_str()); 703 else { 704 ProgramArgs.push_back(RemoteClientPath.c_str()); 705 ProgramArgs.push_back(RemoteHost.c_str()); 706 if (!RemoteUser.empty()) { 707 ProgramArgs.push_back("-l"); 708 ProgramArgs.push_back(RemoteUser.c_str()); 709 } 710 if (!RemotePort.empty()) { 711 ProgramArgs.push_back("-p"); 712 ProgramArgs.push_back(RemotePort.c_str()); 713 } 714 if (!RemoteExtra.empty()) { 715 ProgramArgs.push_back(RemoteExtra.c_str()); 716 } 717 718 // Full path to the binary. We need to cd to the exec directory because 719 // there is a dylib there that the exec expects to find in the CWD 720 char *env_pwd = getenv("PWD"); 721 Exec = "cd "; 722 Exec += env_pwd; 723 Exec += "; ./"; 724 Exec += OutputBinary.c_str(); 725 ProgramArgs.push_back(Exec.c_str()); 726 } 727 728 // Add optional parameters to the running program from Argv 729 for (unsigned i = 0, e = Args.size(); i != e; ++i) 730 ProgramArgs.push_back(Args[i].c_str()); 731 ProgramArgs.push_back(nullptr); // NULL terminator 732 733 // Now that we have a binary, run it! 734 outs() << "<program>"; 735 outs().flush(); 736 DEBUG(errs() << "\nAbout to run:\t"; 737 for (unsigned i = 0, e = ProgramArgs.size() - 1; i != e; ++i) errs() 738 << " " << ProgramArgs[i]; 739 errs() << "\n";); 740 741 FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps); 742 743 if (RemoteClientPath.empty()) { 744 DEBUG(errs() << "<run locally>"); 745 std::string Error; 746 int ExitCode = RunProgramWithTimeout(OutputBinary.str(), &ProgramArgs[0], 747 InputFile, OutputFile, OutputFile, 748 Timeout, MemoryLimit, &Error); 749 // Treat a signal (usually SIGSEGV) or timeout as part of the program output 750 // so that crash-causing miscompilation is handled seamlessly. 751 if (ExitCode < -1) { 752 std::ofstream outFile(OutputFile.c_str(), std::ios_base::app); 753 outFile << Error << '\n'; 754 outFile.close(); 755 } 756 return ExitCode; 757 } else { 758 outs() << "<run remotely>"; 759 outs().flush(); 760 return RunProgramRemotelyWithTimeout(RemoteClientPath, &ProgramArgs[0], 761 InputFile, OutputFile, OutputFile, 762 Timeout, MemoryLimit); 763 } 764 } 765 766 Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType, 767 std::string &OutputFile, 768 const std::vector<std::string> &ArgsForCC) { 769 SmallString<128> UniqueFilename; 770 std::error_code EC = sys::fs::createUniqueFile( 771 InputFile + "-%%%%%%%" + LTDL_SHLIB_EXT, UniqueFilename); 772 if (EC) { 773 errs() << "Error making unique filename: " << EC.message() << "\n"; 774 exit(1); 775 } 776 OutputFile = UniqueFilename.str(); 777 778 std::vector<const char *> CCArgs; 779 780 CCArgs.push_back(CCPath.c_str()); 781 782 if (TargetTriple.getArch() == Triple::x86) 783 CCArgs.push_back("-m32"); 784 785 for (std::vector<std::string>::const_iterator I = ccArgs.begin(), 786 E = ccArgs.end(); 787 I != E; ++I) 788 CCArgs.push_back(I->c_str()); 789 790 // Compile the C/asm file into a shared object 791 if (fileType != ObjectFile) { 792 CCArgs.push_back("-x"); 793 CCArgs.push_back(fileType == AsmFile ? "assembler" : "c"); 794 } 795 CCArgs.push_back("-fno-strict-aliasing"); 796 CCArgs.push_back(InputFile.c_str()); // Specify the input filename. 797 CCArgs.push_back("-x"); 798 CCArgs.push_back("none"); 799 if (TargetTriple.getArch() == Triple::sparc) 800 CCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc 801 else if (TargetTriple.isOSDarwin()) { 802 // link all source files into a single module in data segment, rather than 803 // generating blocks. dynamic_lookup requires that you set 804 // MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for 805 // bugpoint to just pass that in the environment of CC. 806 CCArgs.push_back("-single_module"); 807 CCArgs.push_back("-dynamiclib"); // `-dynamiclib' for MacOS X/PowerPC 808 CCArgs.push_back("-undefined"); 809 CCArgs.push_back("dynamic_lookup"); 810 } else 811 CCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others 812 813 if (TargetTriple.getArch() == Triple::x86_64) 814 CCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC 815 816 if (TargetTriple.getArch() == Triple::sparc) 817 CCArgs.push_back("-mcpu=v9"); 818 819 CCArgs.push_back("-o"); 820 CCArgs.push_back(OutputFile.c_str()); // Output to the right filename. 821 CCArgs.push_back("-O2"); // Optimize the program a bit. 822 823 // Add any arguments intended for CC. We locate them here because this is 824 // most likely -L and -l options that need to come before other libraries but 825 // after the source. Other options won't be sensitive to placement on the 826 // command line, so this should be safe. 827 for (unsigned i = 0, e = ArgsForCC.size(); i != e; ++i) 828 CCArgs.push_back(ArgsForCC[i].c_str()); 829 CCArgs.push_back(nullptr); // NULL terminator 830 831 outs() << "<CC>"; 832 outs().flush(); 833 DEBUG(errs() << "\nAbout to run:\t"; 834 for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs() 835 << " " << CCArgs[i]; 836 errs() << "\n";); 837 if (RunProgramWithTimeout(CCPath, &CCArgs[0], "", "", "")) 838 return ProcessFailure(CCPath, &CCArgs[0]); 839 return Error::success();; 840 } 841 842 /// create - Try to find the CC executable 843 /// 844 CC *CC::create(std::string &Message, const std::string &CCBinary, 845 const std::vector<std::string> *Args) { 846 auto CCPath = sys::findProgramByName(CCBinary); 847 if (!CCPath) { 848 Message = "Cannot find `" + CCBinary + "' in PATH: " + 849 CCPath.getError().message() + "\n"; 850 return nullptr; 851 } 852 853 std::string RemoteClientPath; 854 if (!RemoteClient.empty()) { 855 auto Path = sys::findProgramByName(RemoteClient); 856 if (!Path) { 857 Message = "Cannot find `" + RemoteClient + "' in PATH: " + 858 Path.getError().message() + "\n"; 859 return nullptr; 860 } 861 RemoteClientPath = *Path; 862 } 863 864 Message = "Found CC: " + *CCPath + "\n"; 865 return new CC(*CCPath, RemoteClientPath, Args); 866 } 867