about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--NEWS24
-rw-r--r--autoconf/configure.ac2
-rwxr-xr-xconfigure18
-rw-r--r--include/klee/Interpreter.h2
-rw-r--r--lib/Core/Executor.cpp19
-rw-r--r--lib/Core/Executor.h12
-rw-r--r--test/Coverage/ReplayOutDir.c2
-rw-r--r--tools/klee/main.cpp68
8 files changed, 83 insertions, 64 deletions
diff --git a/NEWS b/NEWS
index 8c1699e5..17d62a3a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,27 @@
+KLEE 1.2.0, 31 March 2016
+=========================
+
+* Added native support for Z3 (@delcypher)
+* Made it possible to build KLEE without using STP and only MetaSMT (@delcypher)
+* Added support for tcmalloc, which allows KLEE to better track memory consumption (@MartinNowack)
+* Added support for lowering the ``llvm.objectsize`` intrinsic (@delcypher)
+* Added soname for Runtest dynamic library (@MartinNowack)
+* Added support to load libraries from command line (@omeranson)
+* Added command line flag --silent-klee-assume to suppress errors due to infeasible assumptions (Valentin Wüstholz, @wuestholz)
+* Changed code to print out arrays deterministically (@MartinNowack)
+* Improved klee-clang script (@msoos)
+* Added code to dump queries and assignments (@MartinNowack)
+* Code cleanup and refactorings (@delcypher, @MartinNowack)
+* Improvements to code infrastructure (@delcypher, @domainexpert, @MartinNowack, @mdimjasevic, @msoos)
+* Fixed several memory leaks (@delcypher)
+* Fixed a bug with how non-power of 2 values were written to memory (@kren1)
+* Fixed valueIsOnlyCalled() used by MD2U (@yotann)
+* Fixed SELinux signatures (@lszekeres)
+* Fixed incorrect position of Not in Expr::Kind (@delcypher)
+* Fixed wrong std::vector usage after reserve() call (@pollnossa)
+* Improved documentation (@bananaappletw, @ccadar, @delcypher, @mdimjasevic, @Teemperor, @ward, @wuestholz)
+
+
 KLEE 1.1.0, 13 November 2015
 ============================
 
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index 01c2c809..2be02321 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -1,7 +1,7 @@
 dnl **************************************************************************
 dnl * Initialize
 dnl **************************************************************************
-AC_INIT([[KLEE]],[[1.1.0]],[[klee-dev@imperial.ac.uk]],[[klee-]],[[https://klee.github.io]])
+AC_INIT([[KLEE]],[[1.2.0]],[[klee-dev@imperial.ac.uk]],[[klee-]],[[https://klee.github.io]])
 
 dnl Identify where LLVM source tree is (this is patched by
 dnl AutoRegen.sh)
diff --git a/configure b/configure
index ee5593d2..33893680 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for KLEE 1.1.0.
+# Generated by GNU Autoconf 2.69 for KLEE 1.2.0.
 #
 # Report bugs to <klee-dev@imperial.ac.uk>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='KLEE'
 PACKAGE_TARNAME='klee-'
-PACKAGE_VERSION='1.1.0'
-PACKAGE_STRING='KLEE 1.1.0'
+PACKAGE_VERSION='1.2.0'
+PACKAGE_STRING='KLEE 1.2.0'
 PACKAGE_BUGREPORT='klee-dev@imperial.ac.uk'
 PACKAGE_URL='https://klee.github.io'
 
@@ -1293,7 +1293,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures KLEE 1.1.0 to adapt to many kinds of systems.
+\`configure' configures KLEE 1.2.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1359,7 +1359,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of KLEE 1.1.0:";;
+     short | recursive ) echo "Configuration of KLEE 1.2.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1474,7 +1474,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-KLEE configure 1.1.0
+KLEE configure 1.2.0
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2055,7 +2055,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by KLEE $as_me 1.1.0, which was
+It was created by KLEE $as_me 1.2.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -5934,7 +5934,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by KLEE $as_me 1.1.0, which was
+This file was extended by KLEE $as_me 1.2.0, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -6001,7 +6001,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-KLEE config.status 1.1.0
+KLEE config.status 1.2.0
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/include/klee/Interpreter.h b/include/klee/Interpreter.h
index abd454b1..b40ad0d5 100644
--- a/include/klee/Interpreter.h
+++ b/include/klee/Interpreter.h
@@ -113,7 +113,7 @@ public:
 
   // supply a test case to replay from. this can be used to drive the
   // interpretation down a user specified path. use null to reset.
-  virtual void setReplayOut(const struct KTest *out) = 0;
+  virtual void setReplayKTest(const struct KTest *out) = 0;
 
   // supply a list of branch decisions specifying which direction to
   // take on forks. this can be used to drive the interpretation down
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index dc9edf5f..3b2a860e 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -282,7 +282,7 @@ Executor::Executor(const InterpreterOptions &opts,
     symPathWriter(0),
     specialFunctionHandler(0),
     processTree(0),
-    replayOut(0),
+    replayKTest(0),
     replayPath(0),    
     usingSeeds(0),
     atMemoryLimit(false),
@@ -736,7 +736,7 @@ Executor::fork(ExecutionState &current, ref<Expr> condition, bool isInternal) {
         }
       }
     } else if (res==Solver::Unknown) {
-      assert(!replayOut && "in replay mode, only one branch can be true.");
+      assert(!replayKTest && "in replay mode, only one branch can be true.");
       
       if ((MaxMemoryInhibit && atMemoryLimit) || 
           current.forkDisabled ||
@@ -1926,8 +1926,7 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
       count = Expr::createZExtToPointerWidth(count);
       size = MulExpr::create(size, count);
     }
-    bool isLocal = i->getOpcode()==Instruction::Alloca;
-    executeAlloc(state, size, isLocal, ki);
+    executeAlloc(state, size, true, ki);
     break;
   }
 
@@ -2652,8 +2651,8 @@ std::string Executor::getAddressInfo(ExecutionState &state,
 }
 
 void Executor::terminateState(ExecutionState &state) {
-  if (replayOut && replayPosition!=replayOut->numObjects) {
-    klee_warning_once(replayOut, 
+  if (replayKTest && replayPosition!=replayKTest->numObjects) {
+    klee_warning_once(replayKTest,
                       "replay did not consume all objects in test input.");
   }
 
@@ -2875,7 +2874,7 @@ void Executor::callExternalFunction(ExecutionState &state,
 ref<Expr> Executor::replaceReadWithSymbolic(ExecutionState &state, 
                                             ref<Expr> e) {
   unsigned n = interpreterOpts.MakeConcreteSymbolic;
-  if (!n || replayOut || replayPath)
+  if (!n || replayKTest || replayPath)
     return e;
 
   // right now, we don't replace symbolics (is there any reason to?)
@@ -3221,7 +3220,7 @@ void Executor::executeMakeSymbolic(ExecutionState &state,
                                    const MemoryObject *mo,
                                    const std::string &name) {
   // Create a new object state for the memory object (instead of a copy).
-  if (!replayOut) {
+  if (!replayKTest) {
     // Find a unique name for this array.  First try the original name,
     // or if that fails try adding a unique identifier.
     unsigned id = 0;
@@ -3281,10 +3280,10 @@ void Executor::executeMakeSymbolic(ExecutionState &state,
     }
   } else {
     ObjectState *os = bindObjectInState(state, mo, false);
-    if (replayPosition >= replayOut->numObjects) {
+    if (replayPosition >= replayKTest->numObjects) {
       terminateStateOnError(state, "replay count mismatch", "user.err");
     } else {
-      KTestObject *obj = &replayOut->objects[replayPosition++];
+      KTestObject *obj = &replayKTest->objects[replayPosition++];
       if (obj->numBytes != mo->size) {
         terminateStateOnError(state, "replay size mismatch", "user.err");
       } else {
diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h
index 8bfa278a..1997bad2 100644
--- a/lib/Core/Executor.h
+++ b/lib/Core/Executor.h
@@ -150,10 +150,10 @@ private:
 
   /// When non-null the bindings that will be used for calls to
   /// klee_make_symbolic in order replay.
-  const struct KTest *replayOut;
+  const struct KTest *replayKTest;
   /// When non-null a list of branch decisions to be used for replay.
   const std::vector<bool> *replayPath;
-  /// The index into the current \ref replayOut or \ref replayPath
+  /// The index into the current \ref replayKTest or \ref replayPath
   /// object.
   unsigned replayPosition;
 
@@ -417,16 +417,16 @@ public:
   }
   virtual void setSymbolicPathWriter(TreeStreamWriter *tsw) {
     symPathWriter = tsw;
-  }      
+  }
 
-  virtual void setReplayOut(const struct KTest *out) {
+  virtual void setReplayKTest(const struct KTest *out) {
     assert(!replayPath && "cannot replay both buffer and path");
-    replayOut = out;
+    replayKTest = out;
     replayPosition = 0;
   }
 
   virtual void setReplayPath(const std::vector<bool> *path) {
-    assert(!replayOut && "cannot replay both buffer and path");
+    assert(!replayKTest && "cannot replay both buffer and path");
     replayPath = path;
     replayPosition = 0;
   }
diff --git a/test/Coverage/ReplayOutDir.c b/test/Coverage/ReplayOutDir.c
index ca7e590a..d9bffea0 100644
--- a/test/Coverage/ReplayOutDir.c
+++ b/test/Coverage/ReplayOutDir.c
@@ -1,7 +1,7 @@
 // RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
 // RUN: rm -rf %t1.out %t1.replay
 // RUN: %klee --output-dir=%t1.out %t1.bc
-// RUN: %klee --output-dir=%t1.replay --replay-out-dir=%t1.out %t1.bc
+// RUN: %klee --output-dir=%t1.replay --replay-ktest-dir=%t1.out %t1.bc
 
 int main() {
   int i;
diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp
index 568c70bb..80161caa 100644
--- a/tools/klee/main.cpp
+++ b/tools/klee/main.cpp
@@ -179,14 +179,14 @@ namespace {
                               "the bytes, not necessarily making them concrete."));
 
   cl::list<std::string>
-  ReplayOutFile("replay-out",
-                cl::desc("Specify an out file to replay"),
-                cl::value_desc("out file"));
+      ReplayKTestFile("replay-ktest-file",
+                      cl::desc("Specify a ktest file to use for replay"),
+                      cl::value_desc("ktest file"));
 
   cl::list<std::string>
-  ReplayOutDir("replay-out-dir",
-	       cl::desc("Specify a directory to replay .out files from"),
-	       cl::value_desc("output directory"));
+      ReplayKTestDir("replay-ktest-dir",
+                   cl::desc("Specify a directory to replay ktest files from"),
+                   cl::value_desc("output directory"));
 
   cl::opt<std::string>
   ReplayPathFile("replay-path",
@@ -261,16 +261,12 @@ public:
   std::string getTestFilename(const std::string &suffix, unsigned id);
   llvm::raw_fd_ostream *openTestFile(const std::string &suffix, unsigned id);
 
-  // load a .out file
-  static void loadOutFile(std::string name,
-                          std::vector<unsigned char> &buffer);
-
   // load a .path file
   static void loadPathFile(std::string name,
                            std::vector<bool> &buffer);
 
-  static void getOutFiles(std::string path,
-			  std::vector<std::string> &results);
+  static void getKTestFilesInDir(std::string directoryPath,
+                                 std::vector<std::string> &results);
 
   static std::string getRunTimeLibraryPath(const char *argv0);
 };
@@ -566,14 +562,15 @@ void KleeHandler::loadPathFile(std::string name,
   }
 }
 
-void KleeHandler::getOutFiles(std::string path,
-			      std::vector<std::string> &results) {
+void KleeHandler::getKTestFilesInDir(std::string directoryPath,
+                                     std::vector<std::string> &results) {
 #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
   error_code ec;
 #else
   std::error_code ec;
 #endif
-  for (llvm::sys::fs::directory_iterator i(path,ec),e; i!=e && !ec; i.increment(ec)){
+  for (llvm::sys::fs::directory_iterator i(directoryPath, ec), e; i != e && !ec;
+       i.increment(ec)) {
     std::string f = (*i).path();
     if (f.substr(f.size()-6,f.size()) == ".ktest") {
           results.push_back(f);
@@ -581,8 +578,8 @@ void KleeHandler::getOutFiles(std::string path,
   }
 
   if (ec) {
-    llvm::errs() << "ERROR: unable to read output directory: " << path << ": "
-                 << ec.message() << "\n";
+    llvm::errs() << "ERROR: unable to read output directory: " << directoryPath
+                 << ": " << ec.message() << "\n";
     exit(1);
   }
 }
@@ -1385,11 +1382,10 @@ int main(int argc, char **argv, char **envp) {
     theInterpreter = Interpreter::create(IOpts, handler);
   handler->setInterpreter(interpreter);
 
-  llvm::raw_ostream &infoFile = handler->getInfoStream();
   for (int i=0; i<argc; i++) {
-    infoFile << argv[i] << (i+1<argc ? " ":"\n");
+    handler->getInfoStream() << argv[i] << (i+1<argc ? " ":"\n");
   }
-  infoFile << "PID: " << getpid() << "\n";
+  handler->getInfoStream() << "PID: " << getpid() << "\n";
 
   const Module *finalModule =
     interpreter->setModule(mainModule, Opts);
@@ -1403,21 +1399,21 @@ int main(int argc, char **argv, char **envp) {
   time_t t[2];
   t[0] = time(NULL);
   strftime(buf, sizeof(buf), "Started: %Y-%m-%d %H:%M:%S\n", localtime(&t[0]));
-  infoFile << buf;
-  infoFile.flush();
+  handler->getInfoStream() << buf;
+  handler->getInfoStream().flush();
 
-  if (!ReplayOutDir.empty() || !ReplayOutFile.empty()) {
+  if (!ReplayKTestDir.empty() || !ReplayKTestFile.empty()) {
     assert(SeedOutFile.empty());
     assert(SeedOutDir.empty());
 
-    std::vector<std::string> outFiles = ReplayOutFile;
+    std::vector<std::string> kTestFiles = ReplayKTestFile;
     for (std::vector<std::string>::iterator
-           it = ReplayOutDir.begin(), ie = ReplayOutDir.end();
+           it = ReplayKTestDir.begin(), ie = ReplayKTestDir.end();
          it != ie; ++it)
-      KleeHandler::getOutFiles(*it, outFiles);
+      KleeHandler::getKTestFilesInDir(*it, kTestFiles);
     std::vector<KTest*> kTests;
     for (std::vector<std::string>::iterator
-           it = outFiles.begin(), ie = outFiles.end();
+           it = kTestFiles.begin(), ie = kTestFiles.end();
          it != ie; ++it) {
       KTest *out = kTest_fromFile(it->c_str());
       if (out) {
@@ -1439,15 +1435,15 @@ int main(int argc, char **argv, char **envp) {
            it = kTests.begin(), ie = kTests.end();
          it != ie; ++it) {
       KTest *out = *it;
-      interpreter->setReplayOut(out);
+      interpreter->setReplayKTest(out);
       llvm::errs() << "KLEE: replaying: " << *it << " (" << kTest_numBytes(out)
                    << " bytes)"
-                   << " (" << ++i << "/" << outFiles.size() << ")\n";
+                   << " (" << ++i << "/" << kTestFiles.size() << ")\n";
       // XXX should put envp in .ktest ?
       interpreter->runFunctionAsMain(mainFn, out->numArgs, out->args, pEnvp);
       if (interrupted) break;
     }
-    interpreter->setReplayOut(0);
+    interpreter->setReplayKTest(0);
     while (!kTests.empty()) {
       kTest_free(kTests.back());
       kTests.pop_back();
@@ -1467,10 +1463,10 @@ int main(int argc, char **argv, char **envp) {
     for (std::vector<std::string>::iterator
            it = SeedOutDir.begin(), ie = SeedOutDir.end();
          it != ie; ++it) {
-      std::vector<std::string> outFiles;
-      KleeHandler::getOutFiles(*it, outFiles);
+      std::vector<std::string> kTestFiles;
+      KleeHandler::getKTestFilesInDir(*it, kTestFiles);
       for (std::vector<std::string>::iterator
-             it2 = outFiles.begin(), ie = outFiles.end();
+             it2 = kTestFiles.begin(), ie = kTestFiles.end();
            it2 != ie; ++it2) {
         KTest *out = kTest_fromFile(it2->c_str());
         if (!out) {
@@ -1479,7 +1475,7 @@ int main(int argc, char **argv, char **envp) {
         }
         seeds.push_back(out);
       }
-      if (outFiles.empty()) {
+      if (kTestFiles.empty()) {
         llvm::errs() << "KLEE: seeds directory is empty: " << *it << "\n";
         exit(1);
       }
@@ -1505,11 +1501,11 @@ int main(int argc, char **argv, char **envp) {
 
   t[1] = time(NULL);
   strftime(buf, sizeof(buf), "Finished: %Y-%m-%d %H:%M:%S\n", localtime(&t[1]));
-  infoFile << buf;
+  handler->getInfoStream() << buf;
 
   strcpy(buf, "Elapsed: ");
   strcpy(format_tdiff(buf, t[1] - t[0]), "\n");
-  infoFile << buf;
+  handler->getInfoStream() << buf;
 
   // Free all the args.
   for (unsigned i=0; i<InputArgv.size()+1; i++)