diff options
Diffstat (limited to 'lib/Module/Checks.cpp')
-rw-r--r-- | lib/Module/Checks.cpp | 68 |
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; +} |