about summary refs log tree commit diff homepage
path: root/lib/Module
diff options
context:
space:
mode:
authorDan Liew <daniel.liew@imperial.ac.uk>2015-10-17 15:27:05 +0100
committerDan Liew <daniel.liew@imperial.ac.uk>2015-10-17 15:27:05 +0100
commit20bf195f8a4da5e2e17c59b01b11da8917ee4a8c (patch)
tree3dad6a75ba8687d792c19bb3daada8feceb0822f /lib/Module
parent6b0082b01e60ea2361da401694ea5aa7f7a6e966 (diff)
downloadklee-20bf195f8a4da5e2e17c59b01b11da8917ee4a8c.tar.gz
Implemented SV-COMP 2016 runtime functions which can be activated with
the --svcomp-runtime flag. This is accompanied with a set of tests
to check all the functions are callable.

Due to the fact that the SV-COMP benchmark suite contains a mixture
of i386 and x86_64 benchmarks it is necessary to compile the runtime
functions twice, once for i386 and once for x86_64 and then link the
right version in at runtime. An example function that is problematic
is ``__VERIFIER_nondet_long()`` which is a different size on i386
and x86_64.
Diffstat (limited to 'lib/Module')
-rw-r--r--lib/Module/KModule.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/Module/KModule.cpp b/lib/Module/KModule.cpp
index 1334b58c..e22b3d24 100644
--- a/lib/Module/KModule.cpp
+++ b/lib/Module/KModule.cpp
@@ -97,7 +97,11 @@ namespace {
                                    "execute switch internally"),
                         clEnumValEnd),
              cl::init(eSwitchTypeInternal));
-  
+
+  cl::opt<bool>
+  SVCOMPRuntime("svcomp-runtime",
+               cl::desc("Add SV-COMP runtime functions"),
+               cl::init(false));
   cl::opt<bool>
   DebugPrintEscapingFunctions("debug-print-escaping-functions", 
                               cl::desc("Print functions whose address is taken."));
@@ -349,6 +353,37 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts,
     );
   module = linkWithLibrary(module, LibPath.str());
 
+  // Add SV-COMP runtime if requested
+  if (SVCOMPRuntime) {
+    LibPath = opts.LibraryDir;
+    SmallString<24> runtimeFileName;
+    llvm::StringRef targetName = module->getTargetTriple();
+    // Different versions of the runtime are required based on target
+    // because the size of some types differ. For example
+    // __VERIFIER_nondet_long() return type is i32 on i386 but i64 on x86_64
+    if (targetName.startswith("x86_64")) {
+        runtimeFileName = "kleeSVCOMPRuntime64";
+    } else if (targetName.startswith("i386")) {
+        runtimeFileName = "kleeSVCOMPRuntime32";
+    } else {
+        klee_error("Cannot determine which SV-COMP runtime to use from target %s",
+                   targetName.data());
+    }
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3,3)
+    runtimeFileName += ".bc";
+#else
+    runtimeFileName += ".bca";
+#endif
+    llvm::sys::path::append(LibPath, runtimeFileName.str());
+    module = linkWithLibrary(module, LibPath.str());
+
+    // Add all error reporting functions as internal functions so we report
+    // failures at the correct location
+    addInternalFunction("__VERIFIER_error");
+    addInternalFunction("__VERIFIER_assert");
+    addInternalFunction("__VERIFIER_assume");
+  }
+
   // Add internal functions which are not used to check if instructions
   // have been already visited
   if (opts.CheckDivZero)