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