ClearBlue
SEGValue.h
1 /*
2  * Developed by Yibo, Jin
3  * Copy Right by Prism Research Group and HKUST.
4  */
5 
6 #ifndef SEGVALUE_H
7 #define SEGVALUE_H
8 
9 #include <llvm/IR/BasicBlock.h>
10 #include <llvm/IR/CallSite.h>
11 #include <llvm/IR/Constants.h>
12 #include <llvm/IR/Function.h>
13 #include <llvm/IR/InstIterator.h>
14 #include <llvm/IR/Instruction.h>
15 #include <llvm/IR/Instructions.h>
16 #include <llvm/IR/Value.h>
17 
18 #include <llvm/Support/Casting.h>
19 #include <llvm/Support/FileSystem.h>
20 #include <llvm/Support/Format.h>
21 #include <llvm/Support/raw_ostream.h>
22 
23 #include <llvm/Analysis/MemoryBuiltins.h>
24 #include <llvm/Target/TargetLibraryInfo.h>
25 
26 #include "Analysis/Bitcode/BitcodeUtils.h"
27 
28 #include <map>
29 #include <set>
30 #include <unordered_map>
31 #include <unordered_set>
32 #include <vector>
33 
34 using namespace llvm;
35 
36 class SEGValue;
37 
38 class SEGValue {
39 
40 public:
41  enum SEGValueKind {
42  value,
43  basicblock,
44  instruction,
45  function,
46  };
47 
48 private:
49  Value *Val;
50 
51  friend class SEGObject;
52  friend class SEGNodeBase;
53  friend class SEGSiteBase;
54 
55 public:
57  SEGValue(Value *val) : Val(val) {}
59  ~SEGValue() {}
60 
61  /* --------- Value --------- */
62 
66  Value *getValue() { return Val; }
67 
71  bool hasName() const { return Val->hasName(); }
72 
76  StringRef getValueName() const { return Val->getName(); }
77 
83  bool isEqualValue(SEGValue *sValue) const {
84  return Val == sValue->getValue();
85  }
86 
90  bool isConstantInt() const {
91  if (!Val) {
92  return false;
93  }
94  if (isa<ConstantInt>(Val)) {
95  return true;
96  }
97  return false;
98  }
99 
105  bool isConstantInt(int constantInt) const {
106  if (!Val) {
107  return false;
108  }
109  if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
110  if (CI->getSExtValue() == constantInt) {
111  return true;
112  }
113  }
114  return false;
115  }
116 
117  /* --------- Type --------- */
118 
122  bool isUndefined() const { return isa<UndefValue>(Val); }
123 
127  bool isPointerType() const { return Val->getType()->isPointerTy(); }
128 
132  bool isConstantPointerNull() const { return isa<ConstantPointerNull>(Val); }
133 
134  /* --------- Instruction --------- */
135 
139  bool isInstruction() const { return isa<Instruction>(Val); }
140 
146  bool isSame(SEGValue *sValue) const { return Val == sValue->getValue(); }
147 
151  bool isPhiInst() const { return isa<PHINode>(Val); }
152 
156  bool isFreeInst(TargetLibraryInfo *TLI) const {
157  if (isInstruction())
158  return isFreeCall(dyn_cast<Instruction>(Val), TLI);
159  return false;
160  }
161 
165  bool isLoadInst() const {
166  assert(isInstruction() && "Not an instruction");
167  return isa<LoadInst>(Val);
168  }
169 
173  bool isDivInst() const {
174  assert(isInstruction() && "Not an instruction");
175  auto *Inst = dyn_cast<Instruction>(Val);
176  return Inst->getOpcode() == Instruction::UDiv ||
177  Inst->getOpcode() == Instruction::SDiv ||
178  Inst->getOpcode() == Instruction::FDiv ||
179  Inst->getOpcode() == Instruction::URem ||
180  Inst->getOpcode() == Instruction::SRem ||
181  Inst->getOpcode() == Instruction::FRem;
182  }
183 
184  bool isConstantString() {
185  if (auto *GV = dyn_cast<GlobalVariable>(Val)) {
186  if (!GV->hasInitializer()) {
187  return false;
188  }
189  Constant *CI = GV->getInitializer();
190  if (isa<ConstantDataArray>(CI) || isa<ConstantDataSequential>(CI) ||
191  isa<ConstantDataVector>(CI)) {
192  return true;
193  }
194  }
195  return false;
196  }
197 
198  StringRef getConstantString() {
199  assert(isConstantString() && "Current SEGValue is not a constant string!");
200  if (auto *GV = dyn_cast<GlobalVariable>(Val)) {
201  Constant *CI = GV->getInitializer();
202  if (auto *CA = dyn_cast<ConstantDataArray>(CI)) {
203  CA->getAsString();
204  } else if (auto *CS = dyn_cast<ConstantDataSequential>(CI)) {
205  CS->getAsString();
206  } else if (auto *CV = dyn_cast<ConstantDataVector>(CI)) {
207  CV->getAsString();
208  } else {
209  return nullptr;
210  }
211  }
212  }
213 
220  SEGValue *getInstOperand(size_t offset) {
221  if (isInstruction()) {
222  auto *Inst = dyn_cast<Instruction>(Val);
223  return new SEGValue(Inst->getOperand(offset));
224  }
225  return nullptr;
226  }
227 
234  bool isDerefPtr(SEGValue *sValue) const {
235  if (isInstruction()) {
236  kvec<Value *> DerefPtrs;
237  getDerefPtrFromInst(*(dyn_cast<Instruction>(Val)), DerefPtrs);
238  if (DerefPtrs.find(sValue->getValue()) != DerefPtrs.end()) {
239  return true;
240  }
241  }
242  return false;
243  }
244 
245  /* --------- CallSite --------- */
246 
250  bool isCallOrInvoke() const {
251  return isa<CallInst>(Val) || isa<InvokeInst>(Val);
252  }
253 
257  size_t getCallSiteArgSize() const {
258  return CallSite(dyn_cast<Instruction>(Val)).arg_size();
259  }
260 
261  /* --------- Function --------- */
262 
266  bool hasCalledFunction() const {
267  assert((isa<CallInst>(Val) || isa<InvokeInst>(Val)) &&
268  "Val is nullptr or neither a CallInst nor InvokeInst");
269  return CallSite(Val).getCalledFunction() != nullptr;
270  }
271 
275  Function *getCalledFunction() const {
276  assert(Val && (isa<CallInst>(Val) || isa<InvokeInst>(Val)) &&
277  "Val is nullptr or neither a CallInst nor InvokeInst");
278  CallSite CS(Val);
279  return CS.getCalledFunction();
280  }
281 
285  size_t getFuncArgSize() const {
286  assert(Val && (isa<CallInst>(Val) || isa<InvokeInst>(Val)) &&
287  "Val is nullptr or neither a CallInst nor InvokeInst");
288  Function *callee = CallSite(Val).getCalledFunction();
289  return callee->arg_size();
290  }
291 
299  bool isFuncNthArgument(SEGValue *sValue, size_t offset) const {
300  Value *Inst = sValue->getValue();
301  assert((isa<CallInst>(Inst) || isa<InvokeInst>(Inst)) &&
302  "Val is nullptr or neither a CallInst nor InvokeInst");
303  CallSite CS(Inst);
304  return Val == CS.getArgument(offset);
305  }
306 
310  StringRef getFuncName() const {
311  assert(Val && (isa<CallInst>(Val) || isa<InvokeInst>(Val)) &&
312  "Val is nullptr or neither a CallInst nor InvokeInst");
313  CallSite CS(Val);
314  Function *Func = CS.getCalledFunction();
315  if (Func != nullptr) {
316  return Func->getName();
317  }
318  return {""};
319  }
320 
321  bool hasFuncName() const {
322  assert(Val && (isa<CallInst>(Val) || isa<InvokeInst>(Val)) &&
323  "Val is nullptr or neither a CallInst nor InvokeInst");
324  CallSite CS(Val);
325  Function *Func = CS.getCalledFunction();
326  return Func && Func->hasName();
327  }
328 };
329 
330 #endif
SEGValue::getValueName
StringRef getValueName() const
Get the name of Value.
Definition: SEGValue.h:76
SEGValue::isFuncNthArgument
bool isFuncNthArgument(SEGValue *sValue, size_t offset) const
Determine whether the Value is one of the arguments of callee function.
Definition: SEGValue.h:299
SEGValue::isCallOrInvoke
bool isCallOrInvoke() const
Determine whether CallSite is a CallInst or a InvokeInst.
Definition: SEGValue.h:250
SEGValue::isDerefPtr
bool isDerefPtr(SEGValue *sValue) const
Determine whether the pointer in a dereference instruction points to the specific Value.
Definition: SEGValue.h:234
SEGValue::isEqualValue
bool isEqualValue(SEGValue *sValue) const
Determine whether Value equals to the other Value.
Definition: SEGValue.h:83
SEGValue::hasCalledFunction
bool hasCalledFunction() const
Determine whether CallSite has a callee function.
Definition: SEGValue.h:266
SEGValue::isLoadInst
bool isLoadInst() const
Determine whether it is a load instruction.
Definition: SEGValue.h:165
SEGValue::getInstOperand
SEGValue * getInstOperand(size_t offset)
Get the target operand of instruction.
Definition: SEGValue.h:220
SEGValue::getFuncArgSize
size_t getFuncArgSize() const
Get the argument size of Function.
Definition: SEGValue.h:285
SEGValue::~SEGValue
~SEGValue()
Destructor.
Definition: SEGValue.h:59
SEGValue::getFuncName
StringRef getFuncName() const
Get the fucntion name.
Definition: SEGValue.h:310
SEGValue::isDivInst
bool isDivInst() const
Determine whether it is an instruction about division.
Definition: SEGValue.h:173
SEGValue::getValue
Value * getValue()
Get Value.
Definition: SEGValue.h:66
SEGValue::isPointerType
bool isPointerType() const
Determine whether the type of Value is pointer.
Definition: SEGValue.h:127
SEGObject
Definition: SymbolicExprGraph.h:87
SEGValue::hasName
bool hasName() const
Determine whether Value has its name.
Definition: SEGValue.h:71
SEGValue::isSame
bool isSame(SEGValue *sValue) const
Determine whether the instruction equals to the other instruction.
Definition: SEGValue.h:146
SEGValue
Definition: SEGValue.h:38
SEGValue::isInstruction
bool isInstruction() const
Determine whether the type of Value is instruction.
Definition: SEGValue.h:139
SEGValue::getCalledFunction
Function * getCalledFunction() const
Get the callee function of CallSite.
Definition: SEGValue.h:275
SEGValue::isConstantPointerNull
bool isConstantPointerNull() const
Determine whether the type of Value is pointer.
Definition: SEGValue.h:132
SEGValue::isConstantInt
bool isConstantInt() const
Determine whether Value is a Constant int.
Definition: SEGValue.h:90
SEGValue::getCallSiteArgSize
size_t getCallSiteArgSize() const
Get the argument size of CallSite.
Definition: SEGValue.h:257
SEGValue::isUndefined
bool isUndefined() const
Determine whether Value is undefined.
Definition: SEGValue.h:122
SEGValue::isConstantInt
bool isConstantInt(int constantInt) const
Determine whether Value is a Constant int.
Definition: SEGValue.h:105
SEGSiteBase
Definition: SymbolicExprGraph.h:776
SEGValue::isPhiInst
bool isPhiInst() const
Determine whether it is a PHI instruction.
Definition: SEGValue.h:151
SEGValue::SEGValue
SEGValue(Value *val)
Constructor.
Definition: SEGValue.h:57
SEGNodeBase
The node base of symbolic expression graph.
Definition: SymbolicExprGraph.h:288
SEGValue::isFreeInst
bool isFreeInst(TargetLibraryInfo *TLI) const
Determine whether it is a free instruction.
Definition: SEGValue.h:156