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