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