20#include "klee/Support/Debug.h"
27#include "llvm/Bitcode/BitcodeReader.h"
28#include "llvm/IR/Constants.h"
29#include "llvm/IR/IRBuilder.h"
30#include "llvm/IR/InstrTypes.h"
31#include "llvm/IR/Instruction.h"
32#include "llvm/IR/Instructions.h"
33#include "llvm/IR/LLVMContext.h"
34#include "llvm/IR/Type.h"
35#include "llvm/Support/CommandLine.h"
36#include "llvm/Support/Errno.h"
37#include "llvm/Support/FileSystem.h"
38#include "llvm/Support/Host.h"
39#include "llvm/Support/ManagedStatic.h"
40#include "llvm/Support/MemoryBuffer.h"
41#include "llvm/Support/Path.h"
42#include "llvm/Support/raw_ostream.h"
44#include "llvm/Support/TargetSelect.h"
45#include "llvm/Support/Signals.h"
67 InputFile(cl::desc(
"<input bytecode>"), cl::Positional, cl::init(
"-"));
70 InputArgv(cl::ConsumeAfter,
71 cl::desc(
"<program arguments>..."));
76 cl::OptionCategory TestCaseCat(
"Test case options",
77 "These options select the files to generate for each test case.");
80 WriteNone(
"write-no-tests",
82 cl::desc(
"Do not generate any test files (default=false)"),
83 cl::cat(TestCaseCat));
86 WriteCVCs(
"write-cvcs",
87 cl::desc(
"Write .cvc files for each test case (default=false)"),
88 cl::cat(TestCaseCat));
91 WriteKQueries(
"write-kqueries",
92 cl::desc(
"Write .kquery files for each test case (default=false)"),
93 cl::cat(TestCaseCat));
96 WriteSMT2s(
"write-smt2s",
97 cl::desc(
"Write .smt2 (SMT-LIBv2) files for each test case (default=false)"),
98 cl::cat(TestCaseCat));
101 WriteCov(
"write-cov",
102 cl::desc(
"Write coverage information for each test case (default=false)"),
103 cl::cat(TestCaseCat));
106 WriteTestInfo(
"write-test-info",
107 cl::desc(
"Write additional test case information (default=false)"),
108 cl::cat(TestCaseCat));
111 WritePaths(
"write-paths",
112 cl::desc(
"Write .path files for each test case (default=false)"),
113 cl::cat(TestCaseCat));
116 WriteSymPaths(
"write-sym-paths",
117 cl::desc(
"Write .sym.path files for each test case (default=false)"),
118 cl::cat(TestCaseCat));
123 cl::OptionCategory StartCat(
"Startup options",
124 "These options affect how execution is started.");
127 EntryPoint(
"entry-point",
128 cl::desc(
"Function in which to start execution (default=main)"),
133 RunInDir(
"run-in-dir",
134 cl::desc(
"Change to the given directory before starting execution (default=location of tested file)."),
138 OutputDir(
"output-dir",
139 cl::desc(
"Directory in which to write results (default=klee-out-<N>)"),
145 cl::desc(
"Parse environment from the given file (in \"env\" format)"),
149 OptimizeModule(
"optimize",
150 cl::desc(
"Optimize the code before execution (default=false)."),
155 WarnAllExternals(
"warn-all-external-symbols",
156 cl::desc(
"Issue a warning on startup for all external symbols (default=false)."),
162 cl::OptionCategory LinkCat(
"Linking options",
163 "These options control the libraries being linked.");
165 enum class LibcType { FreestandingLibc, KleeLibc, UcLibc };
167 cl::opt<LibcType> Libc(
168 "libc", cl::desc(
"Choose libc version (none by default)."),
171 LibcType::FreestandingLibc,
"none",
172 "Don't link in a libc (only provide freestanding environment)"),
173 clEnumValN(LibcType::KleeLibc,
"klee",
"Link in KLEE's libc"),
174 clEnumValN(LibcType::UcLibc,
"uclibc",
175 "Link in uclibc (adapted for KLEE)")),
176 cl::init(LibcType::FreestandingLibc), cl::cat(LinkCat));
178 cl::list<std::string>
179 LinkLibraries(
"link-llvm-lib",
180 cl::desc(
"Link the given bitcode library before execution, "
181 "e.g. .bca, .bc, .a. Can be used multiple times."),
182 cl::value_desc(
"bitcode library file"), cl::cat(LinkCat));
185 WithPOSIXRuntime(
"posix-runtime",
186 cl::desc(
"Link with POSIX runtime. Options that can be passed as arguments to the programs are: --sym-arg <max-len> --sym-args <min-argvs> <max-argvs> <max-len> + file model options (default=false)."),
190 cl::opt<std::string> RuntimeBuild(
192 cl::desc(
"Link with versions of the runtime library that were built with "
193 "the provided configuration (default=" RUNTIME_CONFIGURATION
195 cl::init(RUNTIME_CONFIGURATION), cl::cat(LinkCat));
199 cl::OptionCategory ChecksCat(
"Checks options",
200 "These options control some of the checks being done by KLEE.");
203 CheckDivZero(
"check-div-zero",
204 cl::desc(
"Inject checks for division-by-zero (default=true)"),
209 CheckOvershift(
"check-overshift",
210 cl::desc(
"Inject checks for overshift (default=true)"),
217 OptExitOnError(
"exit-on-error",
218 cl::desc(
"Exit KLEE if an error in the tested application has been found (default=false)"),
225 cl::OptionCategory ReplayCat(
"Replaying options",
226 "These options impact replaying of test cases.");
229 ReplayKeepSymbolic(
"replay-keep-symbolic",
230 cl::desc(
"Replay the test cases only by asserting "
231 "the bytes, not necessarily making them concrete."),
234 cl::list<std::string>
235 ReplayKTestFile(
"replay-ktest-file",
236 cl::desc(
"Specify a ktest file to use for replay"),
237 cl::value_desc(
"ktest file"),
240 cl::list<std::string>
241 ReplayKTestDir(
"replay-ktest-dir",
242 cl::desc(
"Specify a directory to replay ktest files from"),
243 cl::value_desc(
"output directory"),
247 ReplayPathFile(
"replay-path",
248 cl::desc(
"Specify a path file to replay"),
249 cl::value_desc(
"path file"),
254 cl::list<std::string>
255 SeedOutFile(
"seed-file",
256 cl::desc(
".ktest file to be used as seed"),
259 cl::list<std::string>
260 SeedOutDir(
"seed-dir",
261 cl::desc(
"Directory with .ktest files to be used as seeds"),
265 MakeConcreteSymbolic(
"make-concrete-symbolic",
266 cl::desc(
"Probabilistic rate at which to make concrete reads symbolic, "
267 "i.e. approximately 1 in n concrete reads will be made symbolic (0=off, 1=all). "
268 "Used for testing (default=0)"),
273 MaxTests(
"max-tests",
274 cl::desc(
"Stop execution after generating the given number of tests. Extra tests corresponding to partially explored paths will also be dumped. Set to 0 to disable (default=0)"),
280 cl::desc(
"Use a watchdog process to enforce --max-time."),
286 cl::desc(
"Link the llvm libc++ library into the bitcode (default=false)"),
292extern cl::opt<std::string>
MaxTime;
331 const char *errorMessage,
332 const char *errorSuffix);
335 std::unique_ptr<llvm::raw_fd_ostream>
openOutputFile(
const std::string &filename);
337 std::unique_ptr<llvm::raw_fd_ostream>
openTestFile(
const std::string &
suffix,
unsigned id);
341 std::vector<bool> &buffer);
344 std::vector<std::string> &results);
350 : m_interpreter(0), m_pathWriter(0), m_symPathWriter(0),
351 m_outputDirectory(), m_numTotalTests(0), m_numGeneratedTests(0),
352 m_pathsCompleted(0), m_pathsExplored(0), m_argc(argc), m_argv(argv) {
355 bool dir_given = OutputDir !=
"";
356 SmallString<128> directory(dir_given ? OutputDir : InputFile);
358 if (!dir_given) sys::path::remove_filename(directory);
359 if (
auto ec = sys::fs::make_absolute(directory)) {
360 klee_error(
"unable to determine absolute path: %s", ec.message().c_str());
365 if (mkdir(directory.c_str(), 0775) < 0)
366 klee_error(
"cannot create \"%s\": %s", directory.c_str(), strerror(errno));
372 for (; i <= INT_MAX; ++i) {
373 SmallString<128> d(directory);
374 llvm::sys::path::append(d,
"klee-out-");
375 raw_svector_ostream ds(d);
380 if (mkdir(d.c_str(), 0775) == 0) {
383 SmallString<128> klee_last(directory);
384 llvm::sys::path::append(klee_last,
"klee-last");
386 if (((unlink(klee_last.c_str()) < 0) && (errno != ENOENT)) ||
389 klee_warning(
"cannot create klee-last symlink: %s", strerror(errno));
400 klee_error(
"cannot create output directory: index out of range");
408 klee_error(
"cannot open file \"%s\": %s", file_path.c_str(), strerror(errno));
413 klee_error(
"cannot open file \"%s\": %s", file_path.c_str(), strerror(errno));
444 sys::path::append(path,filename);
448std::unique_ptr<llvm::raw_fd_ostream>
454 klee_warning(
"error opening file \"%s\". KLEE may have run out of file "
455 "descriptors: try to increase the maximum number of open file "
456 "descriptors by using ulimit (%s).",
457 path.c_str(), Error.c_str());
464 std::stringstream filename;
465 filename <<
"test" << std::setfill(
'0') << std::setw(6) <<
id <<
'.' <<
suffix;
466 return filename.str();
469std::unique_ptr<llvm::raw_fd_ostream>
477 const char *errorMessage,
478 const char *errorSuffix) {
480 std::vector< std::pair<std::string, std::vector<unsigned char> > > out;
484 klee_warning(
"unable to get symbolic solution, losing test case");
501 o->
name =
const_cast<char*
>(out[i].first.c_str());
505 std::copy(out[i].second.begin(), out[i].second.end(), o->
bytes);
509 klee_warning(
"unable to write output test case, losing it");
526 std::vector<unsigned char> concreteBranches;
531 for (
const auto &branch : concreteBranches) {
532 *f << branch <<
'\n';
537 if (errorMessage || WriteKQueries) {
538 std::string constraints;
548 std::string constraints;
556 std::string constraints;
564 std::vector<unsigned char> symbolicBranches;
569 for (
const auto &branch : symbolicBranches) {
570 *f << branch <<
'\n';
576 std::map<const std::string*, std::set<unsigned> > cov;
580 for (
const auto &entry : cov) {
581 for (
const auto &
line : entry.second) {
582 *f << *entry.first <<
':' <<
line <<
'\n';
595 *f <<
"Time to generate test case: " << elapsed_time <<
'\n';
599 if (errorMessage && OptExitOnError) {
601 klee_error(
"EXITING ON ERROR:\n%s\n", errorMessage);
607 std::vector<bool> &buffer) {
608 std::ifstream f(name.c_str(), std::ios::in | std::ios::binary);
611 assert(0 &&
"unable to open path file");
616 buffer.push_back(!!value);
622 std::vector<std::string> &results) {
624 llvm::sys::fs::directory_iterator i(directoryPath, ec), e;
625 for (; i != e && !ec; i.increment(ec)) {
627 if (f.size() >= 6 && f.substr(f.size()-6,f.size()) ==
".ktest") {
628 results.push_back(f);
633 llvm::errs() <<
"ERROR: unable to read output directory: " << directoryPath
634 <<
": " << ec.message() <<
"\n";
641 const char *env = getenv(
"KLEE_RUNTIME_LIBRARY_PATH");
643 return std::string(env);
648 SmallString<128> toolRoot(
649 llvm::sys::fs::getMainExecutable(argv0, MainExecAddr)
653 llvm::sys::path::remove_filename(toolRoot);
655 SmallString<128> libDir;
657 if (strlen( KLEE_INSTALL_BIN_DIR ) != 0 &&
658 strlen( KLEE_INSTALL_RUNTIME_DIR ) != 0 &&
659 toolRoot.str().endswith( KLEE_INSTALL_BIN_DIR ))
661 KLEE_DEBUG_WITH_TYPE(
"klee_runtime", llvm::dbgs() <<
662 "Using installed KLEE library runtime: ");
663 libDir = toolRoot.str().substr(0,
664 toolRoot.str().size() - strlen( KLEE_INSTALL_BIN_DIR ));
665 llvm::sys::path::append(libDir, KLEE_INSTALL_RUNTIME_DIR);
669 KLEE_DEBUG_WITH_TYPE(
"klee_runtime", llvm::dbgs() <<
670 "Using build directory KLEE library runtime :");
672 llvm::sys::path::append(libDir,
"runtime/lib");
675 KLEE_DEBUG_WITH_TYPE(
"klee_runtime", llvm::dbgs() <<
676 libDir.c_str() <<
"\n");
677 return libDir.c_str();
683static std::string
strip(std::string &in) {
684 unsigned len = in.size();
685 unsigned lead = 0, trail = len;
686 while (lead<len && isspace(in[lead]))
688 while (trail>lead && isspace(in[trail-1]))
690 return in.substr(lead, trail-lead);
696 cl::ParseCommandLineOptions(argc, argv,
" klee\n");
701 llvm::StringRef libCPrefix) {
704 Function *mainFn =
nullptr;
705 for (
auto &module : loadedModules) {
706 mainFn = module->getFunction(EntryPoint);
712 klee_error(
"Entry function '%s' not found in module.", EntryPoint.c_str());
713 mainFn->setName(
"__klee_posix_wrapped_main");
719 if (!libCPrefix.empty() && !mainFn->getParent()->getFunction(EntryPoint))
720 llvm::Function::Create(mainFn->getFunctionType(),
721 llvm::Function::ExternalLinkage, EntryPoint,
722 mainFn->getParent());
724 llvm::Function *wrapper =
nullptr;
725 for (
auto &module : loadedModules) {
726 wrapper = module->getFunction(
"__klee_posix_wrapper");
730 assert(wrapper &&
"klee_posix_wrapper not found");
734 wrapper->setName(libCPrefix + EntryPoint);
744 "_ZTVN10__cxxabiv117__class_type_infoE",
745 "_ZTVN10__cxxabiv120__si_class_type_infoE",
746 "_ZTVN10__cxxabiv121__vmi_class_type_infoE",
761 "klee_check_memory_access",
762 "klee_define_fixed_object",
768 "klee_get_value_i32",
769 "klee_get_value_i64",
772 "klee_make_symbolic",
777 "klee_posix_prefer_cex",
786#ifdef SUPPORT_KLEE_EH_CXX
787 "_klee_eh_Unwind_RaiseException_impl",
788 "klee_eh_typeid_for",
803 "__ubsan_handle_add_overflow",
804 "__ubsan_handle_sub_overflow",
805 "__ubsan_handle_mul_overflow",
806 "__ubsan_handle_divrem_overflow",
861 "__ctype_get_mb_cur_max",
889#define NELEMS(array) (sizeof(array)/sizeof(array[0]))
891 std::map<std::string, bool> externals;
900 case LibcType::KleeLibc:
903 case LibcType::UcLibc:
907 case LibcType::FreestandingLibc:
911 if (WithPOSIXRuntime)
912 dontCare.insert(
"syscall");
914 for (Module::const_iterator fnIt = m->begin(), fn_ie = m->end();
915 fnIt != fn_ie; ++fnIt) {
916 if (fnIt->isDeclaration() && !fnIt->use_empty())
917 externals.insert(std::make_pair(fnIt->getName(),
false));
918 for (Function::const_iterator bbIt = fnIt->begin(), bb_ie = fnIt->end();
919 bbIt != bb_ie; ++bbIt) {
920 for (BasicBlock::const_iterator it = bbIt->begin(), ie = bbIt->end();
922 if (
const CallInst *ci = dyn_cast<CallInst>(it)) {
923#if LLVM_VERSION_CODE >= LLVM_VERSION(8, 0)
924 if (isa<InlineAsm>(ci->getCalledOperand())) {
926 if (isa<InlineAsm>(ci->getCalledValue())) {
929 "function \"%s\" has inline asm",
930 fnIt->getName().data());
937 for (Module::const_global_iterator
938 it = m->global_begin(), ie = m->global_end();
940 if (it->isDeclaration() && !it->use_empty())
941 externals.insert(std::make_pair(it->getName(),
true));
944 for (Module::const_alias_iterator
945 it = m->alias_begin(), ie = m->alias_end();
947 std::map<std::string, bool>::iterator it2 =
948 externals.find(it->getName().str());
949 if (it2!=externals.end())
950 externals.erase(it2);
953 std::map<std::string, bool> foundUnsafe;
954 for (std::map<std::string, bool>::iterator
955 it = externals.begin(), ie = externals.end();
957 const std::string &
ext = it->first;
958 if (!modelled.count(
ext) && (WarnAllExternals ||
959 !dontCare.count(
ext))) {
960 if (
ext.compare(0, 5,
"llvm.") != 0) {
961 if (unsafe.count(
ext)) {
962 foundUnsafe.insert(*it);
965 it->second ?
"variable" :
"function",
972 for (std::map<std::string, bool>::iterator
973 it = foundUnsafe.begin(), ie = foundUnsafe.end();
975 const std::string &
ext = it->first;
977 it->second ?
"variable" :
"function",
999 llvm::errs() <<
"KLEE: ctrl-c detected, requesting interpreter to halt.\n";
1003 llvm::errs() <<
"KLEE: ctrl-c detected, exiting.\n";
1020 snprintf(buffer,
sizeof(buffer),
1021 "gdb --batch --eval-command=\"p halt_execution()\" "
1022 "--eval-command=detach --pid=%d &> /dev/null",
1025 if (system(buffer)==-1)
1029#ifndef SUPPORT_KLEE_UCLIBC
1032 std::vector<std::unique_ptr<llvm::Module>> &modules) {
1033 klee_error(
"invalid libc, no uclibc support!\n");
1036static void replaceOrRenameFunction(llvm::Module *module,
1037 const char *old_name,
const char *new_name)
1039 Function *new_function, *old_function;
1040 new_function = module->getFunction(new_name);
1041 old_function = module->getFunction(old_name);
1044 old_function->replaceAllUsesWith(new_function);
1045 old_function->eraseFromParent();
1047 old_function->setName(new_name);
1048 assert(old_function->getName() == new_name);
1054createLibCWrapper(std::vector<std::unique_ptr<llvm::Module>> &modules,
1055 llvm::StringRef intendedFunction,
1056 llvm::StringRef libcMainFunction) {
1067 auto &ctx = modules[0]->getContext();
1068 Function *userMainFn = modules[0]->getFunction(intendedFunction);
1069 assert(userMainFn &&
"unable to get user main");
1071 userMainFn->setName(
"__user_" + intendedFunction);
1074 llvm::Function *libcMainFn =
nullptr;
1075 for (
auto &module : modules) {
1076 if ((libcMainFn = module->getFunction(libcMainFunction)))
1080 klee_error(
"Could not add %s wrapper", libcMainFunction.str().c_str());
1082 auto inModuleReference = libcMainFn->getParent()->getOrInsertFunction(
1083 userMainFn->getName(), userMainFn->getFunctionType());
1085 const auto ft = libcMainFn->getFunctionType();
1087 if (ft->getNumParams() != 7)
1088 klee_error(
"Imported %s wrapper does not have the correct "
1089 "number of arguments",
1090 libcMainFunction.str().c_str());
1092 std::vector<Type *> fArgs;
1093 fArgs.push_back(ft->getParamType(1));
1094 fArgs.push_back(ft->getParamType(2));
1096 Function::Create(FunctionType::get(Type::getInt32Ty(ctx), fArgs,
false),
1097 GlobalVariable::ExternalLinkage, intendedFunction,
1098 libcMainFn->getParent());
1099 BasicBlock *bb = BasicBlock::Create(ctx,
"entry", stub);
1100 llvm::IRBuilder<> Builder(bb);
1102 std::vector<llvm::Value*> args;
1103 args.push_back(llvm::ConstantExpr::getBitCast(
1105 cast<llvm::Constant>(inModuleReference.getCallee()),
1109 ft->getParamType(0)));
1110 args.push_back(&*(stub->arg_begin()));
1111 auto arg_it = stub->arg_begin();
1112 args.push_back(&*(++arg_it));
1113 args.push_back(Constant::getNullValue(ft->getParamType(3)));
1114 args.push_back(Constant::getNullValue(ft->getParamType(4)));
1115 args.push_back(Constant::getNullValue(ft->getParamType(5)));
1116 args.push_back(Constant::getNullValue(ft->getParamType(6)));
1117 Builder.CreateCall(libcMainFn, args);
1118 Builder.CreateUnreachable();
1123 std::vector<std::unique_ptr<llvm::Module>> &modules) {
1124 LLVMContext &ctx = modules[0]->getContext();
1126 size_t newModules = modules.size();
1129 SmallString<128> uclibcBCA(libDir);
1130 std::string errorMsg;
1131 llvm::sys::path::append(uclibcBCA, KLEE_UCLIBC_BCA_NAME);
1133 klee_error(
"Cannot find klee-uclibc '%s': %s", uclibcBCA.c_str(),
1136 for (
auto i = newModules, j = modules.size(); i < j; ++i) {
1137 replaceOrRenameFunction(modules[i].get(),
"__libc_open",
"open");
1138 replaceOrRenameFunction(modules[i].get(),
"__libc_fcntl",
"fcntl");
1141 createLibCWrapper(modules, EntryPoint,
"__uClibc_main");
1142 klee_message(
"NOTE: Using klee-uclibc : %s", uclibcBCA.c_str());
1145 SmallString<128> FortifyPath(libDir);
1146 llvm::sys::path::append(FortifyPath,
1147 "libkleeRuntimeFortify" + opt_suffix +
".bca");
1148 if (!
klee::loadFile(FortifyPath.c_str(), ctx, modules, errorMsg))
1149 klee_error(
"error loading the fortify library '%s': %s",
1150 FortifyPath.c_str(), errorMsg.c_str());
1154int main(
int argc,
char **argv,
char **envp) {
1155 atexit(llvm_shutdown);
1157#if LLVM_VERSION_CODE >= LLVM_VERSION(13, 0)
1158 KCommandLine::HideOptions(llvm::cl::getGeneralCategory());
1160 KCommandLine::HideOptions(llvm::cl::GeneralCategory);
1163 llvm::InitializeNativeTarget();
1166 sys::PrintStackTraceOnErrorSignal(argv[0]);
1170 klee_error(
"--watchdog used without --max-time");
1189 int status, res = waitpid(pid, &status, WNOHANG);
1192 if (errno==ECHILD) {
1197 }
else if (errno!=EINTR) {
1198 perror(
"watchdog waitpid");
1201 }
else if (res==pid && WIFEXITED(status)) {
1202 return WEXITSTATUS(status);
1206 if (time > nextStep) {
1211 "KLEE: WATCHDOG: time expired, attempting halt via INT\n");
1213 }
else if (level==2) {
1215 "KLEE: WATCHDOG: time expired, attempting halt via gdb\n");
1219 "KLEE: WATCHDOG: kill(9)ing child (I tried to be nice)\n");
1239 std::string errorMsg;
1241 std::vector<std::unique_ptr<llvm::Module>> loadedModules;
1243 klee_error(
"error loading program '%s': %s", InputFile.c_str(),
1250 loadedModules,
"" , errorMsg));
1252 klee_error(
"error loading program '%s': %s", InputFile.c_str(),
1256 llvm::Module *mainModule = M.get();
1258 const std::string &module_triple = mainModule->getTargetTriple();
1259 std::string host_triple = llvm::sys::getDefaultTargetTriple();
1261 if (module_triple != host_triple)
1262 klee_warning(
"Module and host target triples do not match: '%s' != '%s'\n"
1263 "This may cause unexpected crashes or assertion violations.",
1264 module_triple.c_str(), host_triple.c_str());
1267 std::string opt_suffix =
"64";
1268 if (module_triple.find(
"i686") != std::string::npos ||
1269 module_triple.find(
"i586") != std::string::npos ||
1270 module_triple.find(
"i486") != std::string::npos ||
1271 module_triple.find(
"i386") != std::string::npos)
1275 opt_suffix +=
"_" + RuntimeBuild.getValue();
1278 loadedModules.emplace_back(std::move(M));
1286 if (WithPOSIXRuntime) {
1288 llvm::sys::path::append(Path,
"libkleeRuntimePOSIX" + opt_suffix +
".bca");
1289 klee_message(
"NOTE: Using POSIX model: %s", Path.c_str());
1290 if (!
klee::loadFile(Path.c_str(), mainModule->getContext(), loadedModules,
1292 klee_error(
"error loading POSIX support '%s': %s", Path.c_str(),
1295 std::string libcPrefix = (Libc == LibcType::UcLibc ?
"__user_" :
"");
1300#ifndef SUPPORT_KLEE_LIBCXX
1301 klee_error(
"KLEE was not compiled with libc++ support");
1304 llvm::sys::path::append(LibcxxBC, KLEE_LIBCXX_BC_NAME);
1305 if (!
klee::loadFile(LibcxxBC.c_str(), mainModule->getContext(), loadedModules,
1307 klee_error(
"error loading libc++ '%s': %s", LibcxxBC.c_str(),
1309 klee_message(
"NOTE: Using libc++ : %s", LibcxxBC.c_str());
1310#ifdef SUPPORT_KLEE_EH_CXX
1312 llvm::sys::path::append(EhCxxPath,
"libkleeeh-cxx" + opt_suffix +
".bca");
1314 loadedModules, errorMsg))
1315 klee_error(
"error loading libklee-eh-cxx '%s': %s", EhCxxPath.c_str(),
1317 klee_message(
"NOTE: Enabled runtime support for C++ exceptions");
1319 klee_message(
"NOTE: KLEE was not compiled with support for C++ exceptions");
1325 case LibcType::KleeLibc: {
1328 llvm::sys::path::append(Path,
1329 "libkleeRuntimeKLEELibc" + opt_suffix +
".bca");
1330 if (!
klee::loadFile(Path.c_str(), mainModule->getContext(), loadedModules,
1332 klee_error(
"error loading klee libc '%s': %s", Path.c_str(),
1336 case LibcType::FreestandingLibc: {
1338 llvm::sys::path::append(Path,
1339 "libkleeRuntimeFreestanding" + opt_suffix +
".bca");
1340 if (!
klee::loadFile(Path.c_str(), mainModule->getContext(), loadedModules,
1342 klee_error(
"error loading freestanding support '%s': %s", Path.c_str(),
1346 case LibcType::UcLibc:
1351 for (
const auto &library : LinkLibraries) {
1352 if (!
klee::loadFile(library, mainModule->getContext(), loadedModules,
1354 klee_error(
"error loading bitcode library '%s': %s", library.c_str(),
1362 if (Environ !=
"") {
1363 std::vector<std::string> items;
1364 std::ifstream f(Environ.c_str());
1366 klee_error(
"unable to open --environ file: %s", Environ.c_str());
1369 std::getline(f,
line);
1372 items.push_back(
line);
1375 pEnvp =
new char *[items.size()+1];
1377 for (; i != items.size(); ++i)
1378 pEnvp[i] = strdup(items[i].c_str());
1384 pArgc = InputArgv.size() + 1;
1385 pArgv =
new char *[pArgc];
1386 for (
unsigned i=0; i<InputArgv.size()+1; i++) {
1387 std::string &arg = (i==0 ? InputFile : InputArgv[i-1]);
1388 unsigned size = arg.size() + 1;
1389 char *pArg =
new char[size];
1391 std::copy(arg.begin(), arg.end(), pArg);
1397 std::vector<bool> replayPath;
1399 if (ReplayPathFile !=
"") {
1408 assert(interpreter);
1411 for (
int i=0; i<argc; i++) {
1412 handler->
getInfoStream() << argv[i] << (i+1<argc ?
" ":
"\n");
1419 auto finalModule = interpreter->
setModule(loadedModules, Opts);
1420 Function *mainFn = finalModule->getFunction(EntryPoint);
1422 klee_error(
"Entry function '%s' not found in module.", EntryPoint.c_str());
1427 if (ReplayPathFile !=
"") {
1432 auto startTime = std::time(
nullptr);
1434 std::stringstream startInfo;
1437 << std::put_time(std::localtime(&startTime),
"%Y-%m-%d %H:%M:%S") <<
'\n';
1442 if (!ReplayKTestDir.empty() || !ReplayKTestFile.empty()) {
1443 assert(SeedOutFile.empty());
1444 assert(SeedOutDir.empty());
1446 std::vector<std::string> kTestFiles = ReplayKTestFile;
1447 for (std::vector<std::string>::iterator
1448 it = ReplayKTestDir.begin(), ie = ReplayKTestDir.end();
1451 std::vector<KTest*> kTests;
1452 for (std::vector<std::string>::iterator
1453 it = kTestFiles.begin(), ie = kTestFiles.end();
1457 kTests.push_back(out);
1463 if (RunInDir !=
"") {
1464 int res = chdir(RunInDir.c_str());
1466 klee_error(
"Unable to change directory to: %s - %s", RunInDir.c_str(),
1467 sys::StrError(errno).c_str());
1472 for (std::vector<KTest*>::iterator
1473 it = kTests.begin(), ie = kTests.end();
1477 llvm::errs() <<
"KLEE: replaying: " << *it <<
" (" <<
kTest_numBytes(out)
1479 <<
" (" << ++i <<
"/" << kTestFiles.size() <<
")\n";
1485 while (!kTests.empty()) {
1490 std::vector<KTest *> seeds;
1491 for (std::vector<std::string>::iterator
1492 it = SeedOutFile.begin(), ie = SeedOutFile.end();
1496 klee_error(
"unable to open: %s\n", (*it).c_str());
1498 seeds.push_back(out);
1500 for (std::vector<std::string>::iterator
1501 it = SeedOutDir.begin(), ie = SeedOutDir.end();
1503 std::vector<std::string> kTestFiles;
1505 for (std::vector<std::string>::iterator
1506 it2 = kTestFiles.begin(), ie = kTestFiles.end();
1510 klee_error(
"unable to open: %s\n", (*it2).c_str());
1512 seeds.push_back(out);
1514 if (kTestFiles.empty()) {
1515 klee_error(
"seeds directory is empty: %s\n", (*it).c_str());
1519 if (!seeds.empty()) {
1523 if (RunInDir !=
"") {
1524 int res = chdir(RunInDir.c_str());
1526 klee_error(
"Unable to change directory to: %s - %s", RunInDir.c_str(),
1527 sys::StrError(errno).c_str());
1532 while (!seeds.empty()) {
1538 auto endTime = std::time(
nullptr);
1543 std::stringstream endInfo;
1544 endInfo <<
"Finished: "
1545 << std::put_time(std::localtime(&endTime),
"%Y-%m-%d %H:%M:%S") <<
'\n'
1547 << std::setfill(
'0') << std::setw(2) << h
1549 << std::setfill(
'0') << std::setw(2) << +m
1551 << std::setfill(
'0') << std::setw(2) << +s
1558 for (
unsigned i=0; i<InputArgv.size()+1; i++)
1580 <<
"KLEE: done: explored paths = " << 1 +
forks <<
"\n";
1586 <<
"KLEE: done: avg. constructs per query = "
1589 <<
"KLEE: done: total queries = " <<
queries <<
"\n"
1590 <<
"KLEE: done: valid queries = " <<
queriesValid <<
"\n"
1594 std::stringstream stats;
1596 <<
"KLEE: done: total instructions = " <<
instructions <<
'\n'
1599 <<
"KLEE: done: partially completed paths = "
1605 bool useColors = llvm::errs().is_displayed();
1607 llvm::errs().changeColor(llvm::raw_ostream::GREEN,
1611 llvm::errs() << stats.str();
1614 llvm::errs().resetColor();
void kTest_free(KTest *bo)
int kTest_toFile(KTest *bo, const char *path)
KTest * kTest_fromFile(const char *path)
unsigned kTest_numBytes(KTest *bo)
#define LLVM_VERSION_CODE
#define LLVM_VERSION(major, minor)
std::unique_ptr< llvm::raw_ostream > m_infoFile
unsigned getNumPathsCompleted()
unsigned m_numGeneratedTests
SmallString< 128 > m_outputDirectory
static void getKTestFilesInDir(std::string directoryPath, std::vector< std::string > &results)
Interpreter * m_interpreter
void incPathsExplored(std::uint32_t num=1)
std::string getTestFilename(const std::string &suffix, unsigned id)
std::unique_ptr< llvm::raw_fd_ostream > openTestFile(const std::string &suffix, unsigned id)
unsigned getNumPathsExplored()
llvm::raw_ostream & getInfoStream() const
unsigned getNumTestCases()
Returns the number of test cases successfully generated so far.
TreeStreamWriter * m_pathWriter
TreeStreamWriter * m_symPathWriter
void processTestCase(const ExecutionState &state, const char *errorMessage, const char *errorSuffix)
std::unique_ptr< llvm::raw_fd_ostream > openOutputFile(const std::string &filename)
void setInterpreter(Interpreter *i)
unsigned m_pathsCompleted
static std::string getRunTimeLibraryPath(const char *argv0)
static void loadPathFile(std::string name, std::vector< bool > &buffer)
std::string getOutputFilename(const std::string &filename)
KleeHandler(int argc, char **argv)
ExecutionState representing a path under exploration.
virtual void setReplayKTest(const struct KTest *out)=0
virtual void setSymbolicPathWriter(TreeStreamWriter *tsw)=0
virtual void prepareForEarlyExit()=0
virtual void getCoveredLines(const ExecutionState &state, std::map< const std::string *, std::set< unsigned > > &res)=0
virtual void runFunctionAsMain(llvm::Function *f, int argc, char **argv, char **envp)=0
virtual llvm::Module * setModule(std::vector< std::unique_ptr< llvm::Module > > &modules, const ModuleOptions &opts)=0
virtual void setHaltExecution(bool value)=0
virtual unsigned getPathStreamID(const ExecutionState &state)=0
virtual void setReplayPath(const std::vector< bool > *path)=0
virtual void setInhibitForking(bool value)=0
virtual void setPathWriter(TreeStreamWriter *tsw)=0
virtual void getConstraintLog(const ExecutionState &state, std::string &res, LogType logFormat=STP)=0
virtual unsigned getSymbolicPathStreamID(const ExecutionState &state)=0
virtual bool getSymbolicSolution(const ExecutionState &state, std::vector< std::pair< std::string, std::vector< unsigned char > > > &res)=0
virtual void useSeeds(const std::vector< struct KTest * > *seeds)=0
Statistic * getStatisticByName(const std::string &name) const
void readStream(TreeStreamID id, std::vector< unsigned char > &out)
int main(int argc, char **argv)
void klee_warning(char *name)
void klee_warning_once(char *name)
void externalsAndGlobalsCheck(const llvm::Module *m)
static const char * dontCareKlee[]
static const char * modelledExternals[]
static void interrupt_handle()
static void interrupt_handle_watchdog()
static const char * dontCareExternals[]
static const char * unsafeExternals[]
static const char * dontCareUclibc[]
static void halt_via_gdb(int pid)
static std::string strip(std::string &in)
static void preparePOSIX(std::vector< std::unique_ptr< llvm::Module > > &loadedModules, llvm::StringRef libCPrefix)
static void linkWithUclibc(StringRef libDir, std::string opt_suffix, std::vector< std::unique_ptr< llvm::Module > > &modules)
static void parseArguments(int argc, char **argv)
static Interpreter * theInterpreter
int const char const char * suffix
uint64_t ext(uint64_t l, unsigned outWidth, unsigned inWidth)
Statistic queryConstructs
Statistic queryCounterexamples
Statistic forks
The number of process forks.
Point getWallTime()
Returns point in time using a monotonic steady clock.
std::string getClockInfo()
Returns information about clock.
Span seconds(std::uint64_t)
std::unique_ptr< llvm::raw_fd_ostream > klee_open_output_file(const std::string &path, std::string &error)
void klee_message(const char *msg,...) __attribute__((format(printf
std::unique_ptr< llvm::Module > linkModules(std::vector< std::unique_ptr< llvm::Module > > &modules, llvm::StringRef entryFunction, std::string &errorMsg)
bool loadFile(const std::string &libraryName, llvm::LLVMContext &context, std::vector< std::unique_ptr< llvm::Module > > &modules, std::string &errorMsg)
cl::opt< std::string > MaxTime
void klee_error(const char *msg,...) __attribute__((format(printf
llvm::cl::OptionCategory SeedingCat
llvm::cl::OptionCategory TerminationCat
void printVersion(llvm::raw_ostream &OS)
llvm::cl::OptionCategory DebugCat
StatisticManager * theStatisticManager
unsigned MakeConcreteSymbolic
std::tuple< std::uint32_t, std::uint8_t, std::uint8_t > toHMS() const