1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
//===-- 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 "klee/Config/Version.h"
#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/DataLayout.h"
#else
#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/Type.h"
#if LLVM_VERSION_CODE >= LLVM_VERSION(2, 7)
#include "llvm/LLVMContext.h"
#endif
#if LLVM_VERSION_CODE <= LLVM_VERSION(3, 1)
#include "llvm/Target/TargetData.h"
#else
#include "llvm/DataLayout.h"
#endif
#endif
#include "llvm/Pass.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Support/CallSite.h"
#include <iostream>
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::getInt64Ty(getGlobalContext()),
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::getVoidTy(getGlobalContext()),
Type::getInt64Ty(getGlobalContext()),
NULL);
divZeroCheckFunction = cast<Function>(fc);
}
CallInst::Create(divZeroCheckFunction, denominator, "", &*i);
moduleChanged = true;
}
}
}
}
}
return moduleChanged;
}
|