1 //===- ExecutionDriver.cpp - Allow execution of LLVM program --------------===// 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 contains code used to execute the program utilizing one of the 11 // various ways of running LLVM bitcode. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "BugDriver.h" 16 #include "ToolRunner.h" 17 #include "llvm/Support/CommandLine.h" 18 #include "llvm/Support/Debug.h" 19 #include "llvm/Support/FileUtilities.h" 20 #include "llvm/Support/SystemUtils.h" 21 #include "llvm/Support/raw_ostream.h" 22 #include <fstream> 23 24 using namespace llvm; 25 26 namespace { 27 // OutputType - Allow the user to specify the way code should be run, to test 28 // for miscompilation. 29 // 30 enum OutputType { 31 AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe, 32 CompileCustom, Custom 33 }; 34 35 cl::opt<double> 36 AbsTolerance("abs-tolerance", cl::desc("Absolute error tolerated"), 37 cl::init(0.0)); 38 cl::opt<double> 39 RelTolerance("rel-tolerance", cl::desc("Relative error tolerated"), 40 cl::init(0.0)); 41 42 cl::opt<OutputType> 43 InterpreterSel(cl::desc("Specify the \"test\" i.e. suspect back-end:"), 44 cl::values(clEnumValN(AutoPick, "auto", "Use best guess"), 45 clEnumValN(RunLLI, "run-int", 46 "Execute with the interpreter"), 47 clEnumValN(RunJIT, "run-jit", "Execute with JIT"), 48 clEnumValN(RunLLC, "run-llc", "Compile with LLC"), 49 clEnumValN(RunLLCIA, "run-llc-ia", 50 "Compile with LLC with integrated assembler"), 51 clEnumValN(RunCBE, "run-cbe", "Compile with CBE"), 52 clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"), 53 clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"), 54 clEnumValN(CompileCustom, "compile-custom", 55 "Use -compile-command to define a command to " 56 "compile the bitcode. Useful to avoid linking."), 57 clEnumValN(Custom, "run-custom", 58 "Use -exec-command to define a command to execute " 59 "the bitcode. Useful for cross-compilation."), 60 clEnumValEnd), 61 cl::init(AutoPick)); 62 63 cl::opt<OutputType> 64 SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"), 65 cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"), 66 clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"), 67 clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"), 68 clEnumValN(Custom, "safe-run-custom", 69 "Use -exec-command to define a command to execute " 70 "the bitcode. Useful for cross-compilation."), 71 clEnumValEnd), 72 cl::init(AutoPick)); 73 74 cl::opt<std::string> 75 SafeInterpreterPath("safe-path", 76 cl::desc("Specify the path to the \"safe\" backend program"), 77 cl::init("")); 78 79 cl::opt<bool> 80 AppendProgramExitCode("append-exit-code", 81 cl::desc("Append the exit code to the output so it gets diff'd too"), 82 cl::init(false)); 83 84 cl::opt<std::string> 85 InputFile("input", cl::init("/dev/null"), 86 cl::desc("Filename to pipe in as stdin (default: /dev/null)")); 87 88 cl::list<std::string> 89 AdditionalSOs("additional-so", 90 cl::desc("Additional shared objects to load " 91 "into executing programs")); 92 93 cl::list<std::string> 94 AdditionalLinkerArgs("Xlinker", 95 cl::desc("Additional arguments to pass to the linker")); 96 97 cl::opt<std::string> 98 CustomCompileCommand("compile-command", cl::init("llc"), 99 cl::desc("Command to compile the bitcode (use with -compile-custom) " 100 "(default: llc)")); 101 102 cl::opt<std::string> 103 CustomExecCommand("exec-command", cl::init("simulate"), 104 cl::desc("Command to execute the bitcode (use with -run-custom) " 105 "(default: simulate)")); 106 } 107 108 namespace llvm { 109 // Anything specified after the --args option are taken as arguments to the 110 // program being debugged. 111 cl::list<std::string> 112 InputArgv("args", cl::Positional, cl::desc("<program arguments>..."), 113 cl::ZeroOrMore, cl::PositionalEatsArgs); 114 115 cl::opt<std::string> 116 OutputPrefix("output-prefix", cl::init("bugpoint"), 117 cl::desc("Prefix to use for outputs (default: 'bugpoint')")); 118 } 119 120 namespace { 121 cl::list<std::string> 122 ToolArgv("tool-args", cl::Positional, cl::desc("<tool arguments>..."), 123 cl::ZeroOrMore, cl::PositionalEatsArgs); 124 125 cl::list<std::string> 126 SafeToolArgv("safe-tool-args", cl::Positional, 127 cl::desc("<safe-tool arguments>..."), 128 cl::ZeroOrMore, cl::PositionalEatsArgs); 129 130 cl::opt<std::string> 131 GCCBinary("gcc", cl::init("gcc"), 132 cl::desc("The gcc binary to use. (default 'gcc')")); 133 134 cl::list<std::string> 135 GCCToolArgv("gcc-tool-args", cl::Positional, 136 cl::desc("<gcc-tool arguments>..."), 137 cl::ZeroOrMore, cl::PositionalEatsArgs); 138 } 139 140 //===----------------------------------------------------------------------===// 141 // BugDriver method implementation 142 // 143 144 /// initializeExecutionEnvironment - This method is used to set up the 145 /// environment for executing LLVM programs. 146 /// 147 bool BugDriver::initializeExecutionEnvironment() { 148 outs() << "Initializing execution environment: "; 149 150 // Create an instance of the AbstractInterpreter interface as specified on 151 // the command line 152 SafeInterpreter = 0; 153 std::string Message; 154 155 switch (InterpreterSel) { 156 case AutoPick: 157 InterpreterSel = RunCBE; 158 Interpreter = 159 AbstractInterpreter::createCBE(getToolName(), Message, GCCBinary, 160 &ToolArgv, &GCCToolArgv); 161 if (!Interpreter) { 162 InterpreterSel = RunJIT; 163 Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, 164 &ToolArgv); 165 } 166 if (!Interpreter) { 167 InterpreterSel = RunLLC; 168 Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, 169 GCCBinary, &ToolArgv, 170 &GCCToolArgv); 171 } 172 if (!Interpreter) { 173 InterpreterSel = RunLLI; 174 Interpreter = AbstractInterpreter::createLLI(getToolName(), Message, 175 &ToolArgv); 176 } 177 if (!Interpreter) { 178 InterpreterSel = AutoPick; 179 Message = "Sorry, I can't automatically select an interpreter!\n"; 180 } 181 break; 182 case RunLLI: 183 Interpreter = AbstractInterpreter::createLLI(getToolName(), Message, 184 &ToolArgv); 185 break; 186 case RunLLC: 187 case RunLLCIA: 188 case LLC_Safe: 189 Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, 190 GCCBinary, &ToolArgv, 191 &GCCToolArgv, 192 InterpreterSel == RunLLCIA); 193 break; 194 case RunJIT: 195 Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, 196 &ToolArgv); 197 break; 198 case RunCBE: 199 case CBE_bug: 200 Interpreter = AbstractInterpreter::createCBE(getToolName(), Message, 201 GCCBinary, &ToolArgv, 202 &GCCToolArgv); 203 break; 204 case CompileCustom: 205 Interpreter = 206 AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand); 207 break; 208 case Custom: 209 Interpreter = 210 AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); 211 break; 212 } 213 if (!Interpreter) 214 errs() << Message; 215 else // Display informational messages on stdout instead of stderr 216 outs() << Message; 217 218 std::string Path = SafeInterpreterPath; 219 if (Path.empty()) 220 Path = getToolName(); 221 std::vector<std::string> SafeToolArgs = SafeToolArgv; 222 switch (SafeInterpreterSel) { 223 case AutoPick: 224 // In "cbe-bug" mode, default to using LLC as the "safe" backend. 225 if (!SafeInterpreter && 226 InterpreterSel == CBE_bug) { 227 SafeInterpreterSel = RunLLC; 228 SafeToolArgs.push_back("--relocation-model=pic"); 229 SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, 230 GCCBinary, 231 &SafeToolArgs, 232 &GCCToolArgv); 233 } 234 235 // In "llc-safe" mode, default to using LLC as the "safe" backend. 236 if (!SafeInterpreter && 237 InterpreterSel == LLC_Safe) { 238 SafeInterpreterSel = RunLLC; 239 SafeToolArgs.push_back("--relocation-model=pic"); 240 SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, 241 GCCBinary, 242 &SafeToolArgs, 243 &GCCToolArgv); 244 } 245 246 // Pick a backend that's different from the test backend. The JIT and 247 // LLC backends share a lot of code, so prefer to use the CBE as the 248 // safe back-end when testing them. 249 if (!SafeInterpreter && 250 InterpreterSel != RunCBE) { 251 SafeInterpreterSel = RunCBE; 252 SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, 253 GCCBinary, 254 &SafeToolArgs, 255 &GCCToolArgv); 256 } 257 if (!SafeInterpreter && 258 InterpreterSel != RunLLC && 259 InterpreterSel != RunJIT) { 260 SafeInterpreterSel = RunLLC; 261 SafeToolArgs.push_back("--relocation-model=pic"); 262 SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, 263 GCCBinary, 264 &SafeToolArgs, 265 &GCCToolArgv); 266 } 267 if (!SafeInterpreter) { 268 SafeInterpreterSel = AutoPick; 269 Message = "Sorry, I can't automatically select an interpreter!\n"; 270 } 271 break; 272 case RunLLC: 273 case RunLLCIA: 274 SafeToolArgs.push_back("--relocation-model=pic"); 275 SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, 276 GCCBinary, &SafeToolArgs, 277 &GCCToolArgv, 278 SafeInterpreterSel == RunLLCIA); 279 break; 280 case RunCBE: 281 SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, 282 GCCBinary, &SafeToolArgs, 283 &GCCToolArgv); 284 break; 285 case Custom: 286 SafeInterpreter = 287 AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); 288 break; 289 default: 290 Message = "Sorry, this back-end is not supported by bugpoint as the " 291 "\"safe\" backend right now!\n"; 292 break; 293 } 294 if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); } 295 296 gcc = GCC::create(Message, GCCBinary, &GCCToolArgv); 297 if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); } 298 299 // If there was an error creating the selected interpreter, quit with error. 300 return Interpreter == 0; 301 } 302 303 /// compileProgram - Try to compile the specified module, returning false and 304 /// setting Error if an error occurs. This is used for code generation 305 /// crash testing. 306 /// 307 void BugDriver::compileProgram(Module *M, std::string *Error) const { 308 // Emit the program to a bitcode file... 309 sys::Path BitcodeFile (OutputPrefix + "-test-program.bc"); 310 std::string ErrMsg; 311 if (BitcodeFile.makeUnique(true, &ErrMsg)) { 312 errs() << ToolName << ": Error making unique filename: " << ErrMsg 313 << "\n"; 314 exit(1); 315 } 316 if (writeProgramToFile(BitcodeFile.str(), M)) { 317 errs() << ToolName << ": Error emitting bitcode to file '" 318 << BitcodeFile.str() << "'!\n"; 319 exit(1); 320 } 321 322 // Remove the temporary bitcode file when we are done. 323 FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps); 324 325 // Actually compile the program! 326 Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); 327 } 328 329 330 /// executeProgram - This method runs "Program", capturing the output of the 331 /// program to a file, returning the filename of the file. A recommended 332 /// filename may be optionally specified. 333 /// 334 std::string BugDriver::executeProgram(const Module *Program, 335 std::string OutputFile, 336 std::string BitcodeFile, 337 const std::string &SharedObj, 338 AbstractInterpreter *AI, 339 std::string *Error) const { 340 if (AI == 0) AI = Interpreter; 341 assert(AI && "Interpreter should have been created already!"); 342 bool CreatedBitcode = false; 343 std::string ErrMsg; 344 if (BitcodeFile.empty()) { 345 // Emit the program to a bitcode file... 346 sys::Path uniqueFilename(OutputPrefix + "-test-program.bc"); 347 if (uniqueFilename.makeUnique(true, &ErrMsg)) { 348 errs() << ToolName << ": Error making unique filename: " 349 << ErrMsg << "!\n"; 350 exit(1); 351 } 352 BitcodeFile = uniqueFilename.str(); 353 354 if (writeProgramToFile(BitcodeFile, Program)) { 355 errs() << ToolName << ": Error emitting bitcode to file '" 356 << BitcodeFile << "'!\n"; 357 exit(1); 358 } 359 CreatedBitcode = true; 360 } 361 362 // Remove the temporary bitcode file when we are done. 363 sys::Path BitcodePath(BitcodeFile); 364 FileRemover BitcodeFileRemover(BitcodePath.str(), 365 CreatedBitcode && !SaveTemps); 366 367 if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output"; 368 369 // Check to see if this is a valid output filename... 370 sys::Path uniqueFile(OutputFile); 371 if (uniqueFile.makeUnique(true, &ErrMsg)) { 372 errs() << ToolName << ": Error making unique filename: " 373 << ErrMsg << "\n"; 374 exit(1); 375 } 376 OutputFile = uniqueFile.str(); 377 378 // Figure out which shared objects to run, if any. 379 std::vector<std::string> SharedObjs(AdditionalSOs); 380 if (!SharedObj.empty()) 381 SharedObjs.push_back(SharedObj); 382 383 int RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, OutputFile, 384 Error, AdditionalLinkerArgs, SharedObjs, 385 Timeout, MemoryLimit); 386 if (!Error->empty()) 387 return OutputFile; 388 389 if (RetVal == -1) { 390 errs() << "<timeout>"; 391 static bool FirstTimeout = true; 392 if (FirstTimeout) { 393 outs() << "\n" 394 "*** Program execution timed out! This mechanism is designed to handle\n" 395 " programs stuck in infinite loops gracefully. The -timeout option\n" 396 " can be used to change the timeout threshold or disable it completely\n" 397 " (with -timeout=0). This message is only displayed once.\n"; 398 FirstTimeout = false; 399 } 400 } 401 402 if (AppendProgramExitCode) { 403 std::ofstream outFile(OutputFile.c_str(), std::ios_base::app); 404 outFile << "exit " << RetVal << '\n'; 405 outFile.close(); 406 } 407 408 // Return the filename we captured the output to. 409 return OutputFile; 410 } 411 412 /// executeProgramSafely - Used to create reference output with the "safe" 413 /// backend, if reference output is not provided. 414 /// 415 std::string BugDriver::executeProgramSafely(const Module *Program, 416 std::string OutputFile, 417 std::string *Error) const { 418 return executeProgram(Program, OutputFile, "", "", SafeInterpreter, Error); 419 } 420 421 std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, 422 std::string &Error) { 423 assert(Interpreter && "Interpreter should have been created already!"); 424 sys::Path OutputFile; 425 426 // Using the known-good backend. 427 GCC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, 428 Error); 429 if (!Error.empty()) 430 return ""; 431 432 std::string SharedObjectFile; 433 bool Failure = gcc->MakeSharedObject(OutputFile.str(), FT, SharedObjectFile, 434 AdditionalLinkerArgs, Error); 435 if (!Error.empty()) 436 return ""; 437 if (Failure) 438 exit(1); 439 440 // Remove the intermediate C file 441 OutputFile.eraseFromDisk(); 442 443 return "./" + SharedObjectFile; 444 } 445 446 /// createReferenceFile - calls compileProgram and then records the output 447 /// into ReferenceOutputFile. Returns true if reference file created, false 448 /// otherwise. Note: initializeExecutionEnvironment should be called BEFORE 449 /// this function. 450 /// 451 bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) { 452 std::string Error; 453 compileProgram(Program, &Error); 454 if (!Error.empty()) 455 return false; 456 457 ReferenceOutputFile = executeProgramSafely(Program, Filename, &Error); 458 if (!Error.empty()) { 459 errs() << Error; 460 if (Interpreter != SafeInterpreter) { 461 errs() << "*** There is a bug running the \"safe\" backend. Either" 462 << " debug it (for example with the -run-cbe bugpoint option," 463 << " if CBE is being used as the \"safe\" backend), or fix the" 464 << " error some other way.\n"; 465 } 466 return false; 467 } 468 outs() << "\nReference output is: " << ReferenceOutputFile << "\n\n"; 469 return true; 470 } 471 472 /// diffProgram - This method executes the specified module and diffs the 473 /// output against the file specified by ReferenceOutputFile. If the output 474 /// is different, 1 is returned. If there is a problem with the code 475 /// generator (e.g., llc crashes), this will set ErrMsg. 476 /// 477 bool BugDriver::diffProgram(const Module *Program, 478 const std::string &BitcodeFile, 479 const std::string &SharedObject, 480 bool RemoveBitcode, 481 std::string *ErrMsg) const { 482 // Execute the program, generating an output file... 483 sys::Path Output(executeProgram(Program, "", BitcodeFile, SharedObject, 0, 484 ErrMsg)); 485 if (!ErrMsg->empty()) 486 return false; 487 488 std::string Error; 489 bool FilesDifferent = false; 490 if (int Diff = DiffFilesWithTolerance(sys::Path(ReferenceOutputFile), 491 sys::Path(Output.str()), 492 AbsTolerance, RelTolerance, &Error)) { 493 if (Diff == 2) { 494 errs() << "While diffing output: " << Error << '\n'; 495 exit(1); 496 } 497 FilesDifferent = true; 498 } 499 else { 500 // Remove the generated output if there are no differences. 501 Output.eraseFromDisk(); 502 } 503 504 // Remove the bitcode file if we are supposed to. 505 if (RemoveBitcode) 506 sys::Path(BitcodeFile).eraseFromDisk(); 507 return FilesDifferent; 508 } 509 510 bool BugDriver::isExecutingJIT() { 511 return InterpreterSel == RunJIT; 512 } 513 514