about summary refs log tree commit diff homepage
path: root/lib/Module/Checks.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Module/Checks.cpp')
-rw-r--r--lib/Module/Checks.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/Module/Checks.cpp b/lib/Module/Checks.cpp
new file mode 100644
index 00000000..ca4eeb44
--- /dev/null
+++ b/lib/Module/Checks.cpp
@@ -0,0 +1,68 @@
+//===-- Checks.cpp --------------------------------------------------------===//
+//
+//                     The KLEE Symbolic Virtual Machine
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Passes.h"
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Type.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Target/TargetData.h"
+
+using namespace llvm;
+using namespace klee;
+
+char DivCheckPass::ID;
+
+bool DivCheckPass::runOnModule(Module &M) { 
+  Function *divZeroCheckFunction = 0;
+
+  bool moduleChanged = false;
+  
+  for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) {
+    for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) {
+      for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) {     
+          if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) {
+          // find all [s|u][div|mod] instructions
+          Instruction::BinaryOps opcode = binOp->getOpcode();
+          if (opcode == Instruction::SDiv || opcode == Instruction::UDiv ||
+              opcode == Instruction::SRem || opcode == Instruction::URem) {
+            
+            CastInst *denominator =
+              CastInst::CreateIntegerCast(i->getOperand(1),
+                                          (Type*)Type::Int64Ty,
+                                          false,  /* sign doesn't matter */
+                                          "int_cast_to_i64",
+                                          i);
+            
+            // Lazily bind the function to avoid always importing it.
+            if (!divZeroCheckFunction) {
+              Constant *fc = M.getOrInsertFunction("klee_div_zero_check", 
+                                                   Type::VoidTy, 
+                                                   Type::Int64Ty, NULL);
+              divZeroCheckFunction = cast<Function>(fc);
+            }
+
+	    CallInst::Create(divZeroCheckFunction, denominator, "", &*i);
+            moduleChanged = true;
+          }
+        }
+      }
+    }
+  }
+  return moduleChanged;
+}