ExecutionDriver.cpp revision 200c748a8643cd127271f4d6849da1e147d4442f
16bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//===- ExecutionDriver.cpp - Allow execution of LLVM program --------------===// 26bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 36bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 46bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 56bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 66bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 76bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 86bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 96bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 106bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// This file contains code used to execute the program utilizing one of the 116bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// various ways of running LLVM bitcode. 126bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis// 136bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 146bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 156bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include "BugDriver.h" 166bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include "ToolRunner.h" 176bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include "llvm/Support/CommandLine.h" 186bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include "llvm/Support/Debug.h" 1940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose#include "llvm/Support/FileUtilities.h" 205ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks#include "llvm/Support/SystemUtils.h" 216bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include "llvm/Support/raw_ostream.h" 226bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis#include <fstream> 236bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 2440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Roseusing namespace llvm; 25964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose 26964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rosenamespace { 27964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose // OutputType - Allow the user to specify the way code should be run, to test 28964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose // for miscompilation. 29964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose // 30964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose enum OutputType { 31964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, LLC_Safe, CompileCustom, Custom 32964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose }; 3340d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose 3440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose cl::opt<double> 3540d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose AbsTolerance("abs-tolerance", cl::desc("Absolute error tolerated"), 3640d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose cl::init(0.0)); 3740d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose cl::opt<double> 3840d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose RelTolerance("rel-tolerance", cl::desc("Relative error tolerated"), 3940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose cl::init(0.0)); 40964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose 41964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose cl::opt<OutputType> 42964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose InterpreterSel(cl::desc("Specify the \"test\" i.e. suspect back-end:"), 43964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose cl::values(clEnumValN(AutoPick, "auto", "Use best guess"), 44964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose clEnumValN(RunLLI, "run-int", 45964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose "Execute with the interpreter"), 46964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose clEnumValN(RunJIT, "run-jit", "Execute with JIT"), 47964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose clEnumValN(RunLLC, "run-llc", "Compile with LLC"), 48964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose clEnumValN(RunLLCIA, "run-llc-ia", 4940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose "Compile with LLC with integrated assembler"), 5040d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"), 5140d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose clEnumValN(CompileCustom, "compile-custom", 5240d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose "Use -compile-command to define a command to " 5340d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose "compile the bitcode. Useful to avoid linking."), 5440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose clEnumValN(Custom, "run-custom", 5540d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose "Use -exec-command to define a command to execute " 56964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose "the bitcode. Useful for cross-compilation."), 57964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose clEnumValEnd), 58964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose cl::init(AutoPick)); 59964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose 60964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose cl::opt<OutputType> 61964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"), 62964490c0a8bd3398dc85d224a167ca9c35a36c85Jordan Rose cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"), 6340d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"), 6440d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose clEnumValN(Custom, "safe-run-custom", 6540d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose "Use -exec-command to define a command to execute " 6640d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose "the bitcode. Useful for cross-compilation."), 6740d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose clEnumValEnd), 6840d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose cl::init(AutoPick)); 6940d8551890bc8454c4e0a28c9072c9c1d1dd588aJordan Rose 706bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::opt<std::string> 716bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis SafeInterpreterPath("safe-path", 7257300760964904cc022a175643342f29f46b7e6bAnna Zaks cl::desc("Specify the path to the \"safe\" backend program"), 736bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::init("")); 7457300760964904cc022a175643342f29f46b7e6bAnna Zaks 7557300760964904cc022a175643342f29f46b7e6bAnna Zaks cl::opt<bool> 7657300760964904cc022a175643342f29f46b7e6bAnna Zaks AppendProgramExitCode("append-exit-code", 7757300760964904cc022a175643342f29f46b7e6bAnna Zaks cl::desc("Append the exit code to the output so it gets diff'd too"), 7857300760964904cc022a175643342f29f46b7e6bAnna Zaks cl::init(false)); 793f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks 803152b3cb5b6a2f797d0972c81a5eb3fd69c0d620Anna Zaks cl::opt<std::string> 81063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks InputFile("input", cl::init("/dev/null"), 826bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::desc("Filename to pipe in as stdin (default: /dev/null)")); 83514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek 84514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek cl::list<std::string> 85514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek AdditionalSOs("additional-so", 86514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek cl::desc("Additional shared objects to load " 878ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks "into executing programs")); 8818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek 8918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek cl::list<std::string> 90514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek AdditionalLinkerArgs("Xlinker", 91514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek cl::desc("Additional arguments to pass to the linker")); 928ff5c41f2bde7ebbe568b4c15e59f14b8befae66Anna Zaks 9318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek cl::opt<std::string> 9457300760964904cc022a175643342f29f46b7e6bAnna Zaks CustomCompileCommand("compile-command", cl::init("llc"), 953f5e8d87dbf449d8b39fe96068415428594d370eAnna Zaks cl::desc("Command to compile the bitcode (use with -compile-custom) " 96514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek "(default: llc)")); 97514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek 98777d706547ebc751d998134774d9d5388fff8e02Anna Zaks cl::opt<std::string> 99777d706547ebc751d998134774d9d5388fff8e02Anna Zaks CustomExecCommand("exec-command", cl::init("simulate"), 100777d706547ebc751d998134774d9d5388fff8e02Anna Zaks cl::desc("Command to execute the bitcode (use with -run-custom) " 1016bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis "(default: simulate)")); 1026bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis} 1036bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1046bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidisnamespace llvm { 1056bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis // Anything specified after the --args option are taken as arguments to the 1066bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis // program being debugged. 1076bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::list<std::string> 1086bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis InputArgv("args", cl::Positional, cl::desc("<program arguments>..."), 1096bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::ZeroOrMore, cl::PositionalEatsArgs); 1106bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1116bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::opt<std::string> 1126bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis OutputPrefix("output-prefix", cl::init("bugpoint"), 1137b73e0832b20af1f43601a3d19e76d02d9f4dce5Ted Kremenek cl::desc("Prefix to use for outputs (default: 'bugpoint')")); 114a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks} 115a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks 116a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaksnamespace { 11739ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks cl::list<std::string> 1180a6e09f67c719c318856be19d57e19972101f62cJordan Rose ToolArgv("tool-args", cl::Positional, cl::desc("<tool arguments>..."), 1196bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::ZeroOrMore, cl::PositionalEatsArgs); 12057300760964904cc022a175643342f29f46b7e6bAnna Zaks 12157300760964904cc022a175643342f29f46b7e6bAnna Zaks cl::list<std::string> 12257300760964904cc022a175643342f29f46b7e6bAnna Zaks SafeToolArgv("safe-tool-args", cl::Positional, 12357300760964904cc022a175643342f29f46b7e6bAnna Zaks cl::desc("<safe-tool arguments>..."), 1245d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks cl::ZeroOrMore, cl::PositionalEatsArgs); 1255d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks 12666c486f275531df6362b3511fc3af6563561801bTed Kremenek cl::opt<std::string> 12766c486f275531df6362b3511fc3af6563561801bTed Kremenek GCCBinary("gcc", cl::init("gcc"), 128ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks cl::desc("The gcc binary to use. (default 'gcc')")); 1295d0ea6d62e076c776ddad028c4eb615783be1323Anna Zaks 1306bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::list<std::string> 1316bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis GCCToolArgv("gcc-tool-args", cl::Positional, 1326bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis cl::desc("<gcc-tool arguments>..."), 133461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks cl::ZeroOrMore, cl::PositionalEatsArgs); 1344e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie} 1354e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie 136461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks//===----------------------------------------------------------------------===// 137461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks// BugDriver method implementation 138eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks// 13939ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks 14039ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks/// initializeExecutionEnvironment - This method is used to set up the 14139ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks/// environment for executing LLVM programs. 142955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaks/// 143955cd444f445bcdbade1cdd3926254c8ee7890d8Anna Zaksbool BugDriver::initializeExecutionEnvironment() { 144c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks outs() << "Initializing execution environment: "; 145c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks 146fadcd5d5bbe1bfc1c6b8d819cc2242f780a49fecAnna Zaks // Create an instance of the AbstractInterpreter interface as specified on 147fadcd5d5bbe1bfc1c6b8d819cc2242f780a49fecAnna Zaks // the command line 148fadcd5d5bbe1bfc1c6b8d819cc2242f780a49fecAnna Zaks SafeInterpreter = 0; 1496bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis std::string Message; 1506bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 1516bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis switch (InterpreterSel) { 1526bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis case AutoPick: 1536bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis if (!Interpreter) { 1546bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis InterpreterSel = RunJIT; 1556bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, 1566bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis &ToolArgv); 1576bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 1586bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis if (!Interpreter) { 1596bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis InterpreterSel = RunLLC; 1606bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, 1613f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks GCCBinary, &ToolArgv, 1623f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks &GCCToolArgv); 1633f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks } 1643f10e32b15e54f507aed90cb72d73c7acaa500bbAnna Zaks if (!Interpreter) { 165eeea7c44a6986752fedee1ef1bcef855db373872Anna Zaks InterpreterSel = RunLLI; 16617a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose Interpreter = AbstractInterpreter::createLLI(getToolName(), Message, 16717a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose &ToolArgv); 16817a38e2636a8b1ce473fc6504c4b16cb09db29f4Jordy Rose } 1696a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks if (!Interpreter) { 1706a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks InterpreterSel = AutoPick; 1716a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks Message = "Sorry, I can't automatically select an interpreter!\n"; 1726a93bd526c5136ee5a26871e829cf5a8548a1c6aAnna Zaks } 173063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks break; 174063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks case RunLLI: 175063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks Interpreter = AbstractInterpreter::createLLI(getToolName(), Message, 176063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks &ToolArgv); 1773d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks break; 1783d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks case RunLLC: 1793d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks case RunLLCIA: 1803d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks case LLC_Safe: 1813d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, 1823d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks GCCBinary, &ToolArgv, 1833d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks &GCCToolArgv, 1847a95de68c093991047ed8d339479ccad51b88663David Blaikie InterpreterSel == RunLLCIA); 1853d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks break; 1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case RunJIT: 1873d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, 1883d7c44e01d568e5d5c0fac9c6ccb3f080157ba19Anna Zaks &ToolArgv); 189c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks break; 190c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks case CompileCustom: 191c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks Interpreter = 192c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand); 193c7ecc43c33a21b82c49664910b19fcc1f555aa51Anna Zaks break; 1940bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks case Custom: 1950bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks Interpreter = 1960bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); 197fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose break; 198fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose } 1990bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks if (!Interpreter) 2000bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks errs() << Message; 2010bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks else // Display informational messages on stdout instead of stderr 2020bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks outs() << Message; 2036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::string Path = SafeInterpreterPath; 2056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (Path.empty()) 206063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks Path = getToolName(); 207063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks std::vector<std::string> SafeToolArgs = SafeToolArgv; 2080bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks switch (SafeInterpreterSel) { 2098ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks case AutoPick: 2100bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks // In "llc-safe" mode, default to using LLC as the "safe" backend. 2110bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks if (!SafeInterpreter && 2120bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks InterpreterSel == LLC_Safe) { 2130bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks SafeInterpreterSel = RunLLC; 2140bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks SafeToolArgs.push_back("--relocation-model=pic"); 2158bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, 216fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose GCCBinary, 2176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines &SafeToolArgs, 218fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose &GCCToolArgv); 2196bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 2206bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis 221fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose if (!SafeInterpreter && 2228ba721428af297e540fb40b176eeeea0ee010c1fAnna Zaks InterpreterSel != RunLLC && 2236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines InterpreterSel != RunJIT) { 2246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SafeInterpreterSel = RunLLC; 2256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SafeToolArgs.push_back("--relocation-model=pic"); 226fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, 2276bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis GCCBinary, 2286bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis &SafeToolArgs, 229063e0887ad65d666d23ee3178436ad6507abbd1bAnna Zaks &GCCToolArgv); 230785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose } 23157300760964904cc022a175643342f29f46b7e6bAnna Zaks if (!SafeInterpreter) { 232785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose SafeInterpreterSel = AutoPick; 2336bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis Message = "Sorry, I can't automatically select a safe interpreter!\n"; 2346bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis } 235b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks break; 236b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks case RunLLC: 237b805c8ff133ef0c62df032fa711d6b13c5afd7f4Anna Zaks case RunLLCIA: 2380e12ebfd3ef9ad5d894466c6e4910ac5e6041034Anna Zaks SafeToolArgs.push_back("--relocation-model=pic"); 2399b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, 2409b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks GCCBinary, &SafeToolArgs, 2415ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks &GCCToolArgv, 2425ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks SafeInterpreterSel == RunLLCIA); 2435ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks break; 2445ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks case Custom: 2455ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks SafeInterpreter = 2465ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); 2476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 2485ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks default: 2495ac1df3e15f91ed663826faec7efe2462c18d98cAnna Zaks Message = "Sorry, this back-end is not supported by bugpoint as the " 2509b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks "\"safe\" backend right now!\n"; 2519b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks break; 2529b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks } 2539b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); } 2549b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks 2559b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks gcc = GCC::create(Message, GCCBinary, &GCCToolArgv); 2562f3017f9cbd3774f690c979410bfec38423d03afJordan Rose if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); } 2572f3017f9cbd3774f690c979410bfec38423d03afJordan Rose 2582f3017f9cbd3774f690c979410bfec38423d03afJordan Rose // If there was an error creating the selected interpreter, quit with error. 2592f3017f9cbd3774f690c979410bfec38423d03afJordan Rose return Interpreter == 0; 2602f3017f9cbd3774f690c979410bfec38423d03afJordan Rose} 2612f3017f9cbd3774f690c979410bfec38423d03afJordan Rose 2622f3017f9cbd3774f690c979410bfec38423d03afJordan Rose/// compileProgram - Try to compile the specified module, returning false and 2632f3017f9cbd3774f690c979410bfec38423d03afJordan Rose/// setting Error if an error occurs. This is used for code generation 2642f3017f9cbd3774f690c979410bfec38423d03afJordan Rose/// crash testing. 2652f3017f9cbd3774f690c979410bfec38423d03afJordan Rose/// 2662f3017f9cbd3774f690c979410bfec38423d03afJordan Rosevoid BugDriver::compileProgram(Module *M, std::string *Error) const { 2672f3017f9cbd3774f690c979410bfec38423d03afJordan Rose // Emit the program to a bitcode file... 2680e12ebfd3ef9ad5d894466c6e4910ac5e6041034Anna Zaks SmallString<128> BitcodeFile; 269461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks int BitcodeFD; 270461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks error_code EC = sys::fs::createUniqueFile( 271461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks OutputPrefix + "-test-program-%%%%%%%.bc", BitcodeFD, BitcodeFile); 272461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks if (EC) { 273461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks errs() << ToolName << ": Error making unique filename: " << EC.message() 274461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks << "\n"; 275461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks exit(1); 276461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks } 277461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks if (writeProgramToFile(BitcodeFile.str(), BitcodeFD, M)) { 278461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks errs() << ToolName << ": Error emitting bitcode to file '" << BitcodeFile 279461af1e502c9bd88330bbf17d449a7593fc0d624Anna Zaks << "'!\n"; 2806bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis exit(1); 2818bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek } 28239ac1876f6f9a1a8e0070f0df61036c7ba05202bAnna Zaks 2836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Remove the temporary bitcode file when we are done. 2846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps); 285c8bb3befcad8cd8fc9556bc265289b07dc3c94c8Anna Zaks 286df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks // Actually compile the program! 287df95d146c13cf02e106b32b01d147577d6d6b5a1Anna Zaks Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); 28857300760964904cc022a175643342f29f46b7e6bAnna Zaks} 289fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose 290fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose 291fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose/// executeProgram - This method runs "Program", capturing the output of the 292fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose/// program to a file, returning the filename of the file. A recommended 293fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose/// filename may be optionally specified. 294fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose/// 295fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rosestd::string BugDriver::executeProgram(const Module *Program, 296fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose std::string OutputFile, 297fa06f0464a04bb7fce1fcfb3780d151bb029e00cJordan Rose std::string BitcodeFile, 2986bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis const std::string &SharedObj, 2996bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis AbstractInterpreter *AI, 3006bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis std::string *Error) const { 3016bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis if (AI == 0) AI = Interpreter; 3026bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis assert(AI && "Interpreter should have been created already!"); 3036bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis bool CreatedBitcode = false; 3046bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis std::string ErrMsg; 3056bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis if (BitcodeFile.empty()) { 3066bcb48dc67e417e0ecce803f28d13bbea2ee0243Argyrios Kyrtzidis // Emit the program to a bitcode file... 307 SmallString<128> UniqueFilename; 308 int UniqueFD; 309 error_code EC = sys::fs::createUniqueFile( 310 OutputPrefix + "-test-program-%%%%%%%.bc", UniqueFD, UniqueFilename); 311 if (EC) { 312 errs() << ToolName << ": Error making unique filename: " 313 << EC.message() << "!\n"; 314 exit(1); 315 } 316 BitcodeFile = UniqueFilename.str(); 317 318 if (writeProgramToFile(BitcodeFile, UniqueFD, Program)) { 319 errs() << ToolName << ": Error emitting bitcode to file '" 320 << BitcodeFile << "'!\n"; 321 exit(1); 322 } 323 CreatedBitcode = true; 324 } 325 326 // Remove the temporary bitcode file when we are done. 327 std::string BitcodePath(BitcodeFile); 328 FileRemover BitcodeFileRemover(BitcodePath, 329 CreatedBitcode && !SaveTemps); 330 331 if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output-%%%%%%%"; 332 333 // Check to see if this is a valid output filename... 334 SmallString<128> UniqueFile; 335 error_code EC = sys::fs::createUniqueFile(OutputFile, UniqueFile); 336 if (EC) { 337 errs() << ToolName << ": Error making unique filename: " 338 << EC.message() << "\n"; 339 exit(1); 340 } 341 OutputFile = UniqueFile.str(); 342 343 // Figure out which shared objects to run, if any. 344 std::vector<std::string> SharedObjs(AdditionalSOs); 345 if (!SharedObj.empty()) 346 SharedObjs.push_back(SharedObj); 347 348 int RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, OutputFile, 349 Error, AdditionalLinkerArgs, SharedObjs, 350 Timeout, MemoryLimit); 351 if (!Error->empty()) 352 return OutputFile; 353 354 if (RetVal == -1) { 355 errs() << "<timeout>"; 356 static bool FirstTimeout = true; 357 if (FirstTimeout) { 358 outs() << "\n" 359 "*** Program execution timed out! This mechanism is designed to handle\n" 360 " programs stuck in infinite loops gracefully. The -timeout option\n" 361 " can be used to change the timeout threshold or disable it completely\n" 362 " (with -timeout=0). This message is only displayed once.\n"; 363 FirstTimeout = false; 364 } 365 } 366 367 if (AppendProgramExitCode) { 368 std::ofstream outFile(OutputFile.c_str(), std::ios_base::app); 369 outFile << "exit " << RetVal << '\n'; 370 outFile.close(); 371 } 372 373 // Return the filename we captured the output to. 374 return OutputFile; 375} 376 377/// executeProgramSafely - Used to create reference output with the "safe" 378/// backend, if reference output is not provided. 379/// 380std::string BugDriver::executeProgramSafely(const Module *Program, 381 std::string OutputFile, 382 std::string *Error) const { 383 return executeProgram(Program, OutputFile, "", "", SafeInterpreter, Error); 384} 385 386std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, 387 std::string &Error) { 388 assert(Interpreter && "Interpreter should have been created already!"); 389 std::string OutputFile; 390 391 // Using the known-good backend. 392 GCC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, 393 Error); 394 if (!Error.empty()) 395 return ""; 396 397 std::string SharedObjectFile; 398 bool Failure = gcc->MakeSharedObject(OutputFile, FT, SharedObjectFile, 399 AdditionalLinkerArgs, Error); 400 if (!Error.empty()) 401 return ""; 402 if (Failure) 403 exit(1); 404 405 // Remove the intermediate C file 406 sys::fs::remove(OutputFile); 407 408 return "./" + SharedObjectFile; 409} 410 411/// createReferenceFile - calls compileProgram and then records the output 412/// into ReferenceOutputFile. Returns true if reference file created, false 413/// otherwise. Note: initializeExecutionEnvironment should be called BEFORE 414/// this function. 415/// 416bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) { 417 std::string Error; 418 compileProgram(Program, &Error); 419 if (!Error.empty()) 420 return false; 421 422 ReferenceOutputFile = executeProgramSafely(Program, Filename, &Error); 423 if (!Error.empty()) { 424 errs() << Error; 425 if (Interpreter != SafeInterpreter) { 426 errs() << "*** There is a bug running the \"safe\" backend. Either" 427 << " debug it (for example with the -run-jit bugpoint option," 428 << " if JIT is being used as the \"safe\" backend), or fix the" 429 << " error some other way.\n"; 430 } 431 return false; 432 } 433 outs() << "\nReference output is: " << ReferenceOutputFile << "\n\n"; 434 return true; 435} 436 437/// diffProgram - This method executes the specified module and diffs the 438/// output against the file specified by ReferenceOutputFile. If the output 439/// is different, 1 is returned. If there is a problem with the code 440/// generator (e.g., llc crashes), this will set ErrMsg. 441/// 442bool BugDriver::diffProgram(const Module *Program, 443 const std::string &BitcodeFile, 444 const std::string &SharedObject, 445 bool RemoveBitcode, 446 std::string *ErrMsg) const { 447 // Execute the program, generating an output file... 448 std::string Output( 449 executeProgram(Program, "", BitcodeFile, SharedObject, 0, ErrMsg)); 450 if (!ErrMsg->empty()) 451 return false; 452 453 std::string Error; 454 bool FilesDifferent = false; 455 if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, 456 Output, 457 AbsTolerance, RelTolerance, &Error)) { 458 if (Diff == 2) { 459 errs() << "While diffing output: " << Error << '\n'; 460 exit(1); 461 } 462 FilesDifferent = true; 463 } 464 else { 465 // Remove the generated output if there are no differences. 466 sys::fs::remove(Output); 467 } 468 469 // Remove the bitcode file if we are supposed to. 470 if (RemoveBitcode) 471 sys::fs::remove(BitcodeFile); 472 return FilesDifferent; 473} 474 475bool BugDriver::isExecutingJIT() { 476 return InterpreterSel == RunJIT; 477} 478 479