Static Value-Flow Analysis
Public Member Functions | Protected Member Functions | Private Member Functions | Private Attributes | List of all members
SVF::SVFIRBuilder Class Reference

#include <SVFIRBuilder.h>

Inheritance diagram for SVF::SVFIRBuilder:

Public Member Functions

 SVFIRBuilder (SVFModule *mod)
 Constructor. More...
 
virtual ~SVFIRBuilder ()
 Destructor. More...
 
virtual SVFIRbuild ()
 Start building SVFIR here. More...
 
SVFIRgetPAG () const
 Return SVFIR. More...
 
void initialiseNodes ()
 Initialize nodes and edges. More...
 
void addEdge (NodeID src, NodeID dst, SVFStmt::PEDGEK kind, APOffset offset=0, Instruction *cs=nullptr)
 
void sanityCheck ()
 Sanity check for SVFIR. More...
 
NodeID getValueNode (const Value *V)
 Get different kinds of node. More...
 
NodeID getObjectNode (const Value *V)
 GetObject - Return the object node (stack/global/heap/function) according to a LLVM Value. More...
 
NodeID getReturnNode (const SVFFunction *func)
 getReturnNode - Return the node representing the unique return value of a function. More...
 
NodeID getVarargNode (const SVFFunction *func)
 getVarargNode - Return the node representing the unique variadic argument of a function. More...
 
virtual void visitAllocaInst (AllocaInst &AI)
 Our visit overrides. More...
 
void visitPHINode (PHINode &I)
 
void visitStoreInst (StoreInst &I)
 
void visitLoadInst (LoadInst &I)
 
void visitGetElementPtrInst (GetElementPtrInst &I)
 
void visitCallInst (CallInst &I)
 
void visitInvokeInst (InvokeInst &II)
 
void visitCallBrInst (CallBrInst &I)
 
void visitCallSite (CallBase *cs)
 
void visitReturnInst (ReturnInst &I)
 
void visitCastInst (CastInst &I)
 
void visitSelectInst (SelectInst &I)
 
void visitExtractValueInst (ExtractValueInst &EVI)
 
void visitBranchInst (BranchInst &I)
 
void visitSwitchInst (SwitchInst &I)
 The following implementation follows ICFGBuilder::processFunBody. More...
 
void visitInsertValueInst (InsertValueInst &I)
 
void visitBinaryOperator (BinaryOperator &I)
 
void visitUnaryOperator (UnaryOperator &I)
 
void visitCmpInst (CmpInst &I)
 
void visitVAArgInst (VAArgInst &)
 
void visitVACopyInst (VACopyInst &)
 
void visitVAEndInst (VAEndInst &)
 
void visitVAStartInst (VAStartInst &)
 
void visitFreezeInst (FreezeInst &I)
 
void visitExtractElementInst (ExtractElementInst &I)
 
void visitInsertElementInst (InsertElementInst &I)
 
void visitShuffleVectorInst (ShuffleVectorInst &I)
 
void visitLandingPadInst (LandingPadInst &I)
 
void visitResumeInst (ResumeInst &)
 Instruction not that often. More...
 
void visitUnreachableInst (UnreachableInst &)
 
void visitFenceInst (FenceInst &I)
 
void visitAtomicCmpXchgInst (AtomicCmpXchgInst &I)
 
void visitAtomicRMWInst (AtomicRMWInst &I)
 
void visitInstruction (Instruction &)
 Provide base case for our instruction visit. More...
 
void updateCallGraph (PTACallGraph *callgraph)
 connect PAG edges based on callgraph More...
 

Protected Member Functions

void visitGlobal (SVFModule *svfModule)
 Handle globals including (global variable and functions) More...
 
void InitialGlobal (const GlobalVariable *gvar, Constant *C, u32_t offset)
 
NodeID getGlobalVarField (const GlobalVariable *gvar, u32_t offset, SVFType *tpy)
 
void processCE (const Value *val)
 Process constant expression. More...
 
u32_t inferFieldIdxFromByteOffset (const llvm::GEPOperator *gepOp, DataLayout *dl, AccessPath &ap, APOffset idx)
 Infer field index from byteoffset. More...
 
bool computeGepOffset (const User *V, AccessPath &ap)
 Compute offset of a gep instruction or gep constant expression. More...
 
const ValuegetBaseValueForExtArg (const Value *V)
 Get the base value of (i8* src and i8* dst) for external argument (e.g. memcpy(i8* dst, i8* src, int size)) More...
 
void handleDirectCall (CallBase *cs, const Function *F)
 Handle direct call. More...
 
void handleIndCall (CallBase *cs)
 Handle indirect call. More...
 
virtual const TypegetBaseTypeAndFlattenedFields (const Value *V, std::vector< AccessPath > &fields, const Value *szValue)
 Handle external call. More...
 
virtual void addComplexConsForExt (Value *D, Value *S, const Value *sz)
 
virtual void handleExtCall (const CallBase *cs, const SVFFunction *svfCallee)
 
void setCurrentLocation (const Value *val, const BasicBlock *bb)
 Set current basic block in order to keep track of control flow information. More...
 
void setCurrentLocation (const SVFValue *val, const SVFBasicBlock *bb)
 
const SVFValuegetCurrentValue () const
 
const SVFBasicBlockgetCurrentBB () const
 
void addGlobalBlackHoleAddrEdge (NodeID node, const ConstantExpr *int2Ptrce)
 Add global black hole Address edge. More...
 
NodeID addNullPtrNode ()
 Add NullPtr PAGNode. More...
 
NodeID getGepValVar (const Value *val, const AccessPath &ap, const SVFType *elementType)
 
void setCurrentBBAndValueForPAGEdge (PAGEdge *edge)
 
void addBlackHoleAddrEdge (NodeID node)
 
AddrStmtaddAddrEdge (NodeID src, NodeID dst)
 Add Address edge. More...
 
AddrStmtaddAddrWithStackArraySz (NodeID src, NodeID dst, llvm::AllocaInst &inst)
 Add Address edge from allocinst with arraysize like "%4 = alloca i8, i64 3". More...
 
AddrStmtaddAddrWithHeapSz (NodeID src, NodeID dst, const CallBase *cs)
 Add Address edge from ext call with args like "%5 = call i8* @malloc(i64 noundef 5)". More...
 
CopyStmtaddCopyEdge (NodeID src, NodeID dst, CopyStmt::CopyKind kind)
 
CopyStmt::CopyKind getCopyKind (const Value *val)
 
void addPhiStmt (NodeID res, NodeID opnd, const ICFGNode *pred)
 Add Copy edge. More...
 
void addSelectStmt (NodeID res, NodeID op1, NodeID op2, NodeID cond)
 Add SelectStmt. More...
 
void addCmpEdge (NodeID op1, NodeID op2, NodeID dst, u32_t predict)
 Add Copy edge. More...
 
void addBinaryOPEdge (NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
 Add Copy edge. More...
 
void addUnaryOPEdge (NodeID src, NodeID dst, u32_t opcode)
 Add Unary edge. More...
 
void addBranchStmt (NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec &succs)
 Add Branch statement. More...
 
void addLoadEdge (NodeID src, NodeID dst)
 Add Load edge. More...
 
void addStoreEdge (NodeID src, NodeID dst)
 Add Store edge. More...
 
void addCallEdge (NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
 Add Call edge. More...
 
void addRetEdge (NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
 Add Return edge. More...
 
void addGepEdge (NodeID src, NodeID dst, const AccessPath &ap, bool constGep)
 Add Gep edge. More...
 
void addNormalGepEdge (NodeID src, NodeID dst, const AccessPath &ap)
 Add Offset(Gep) edge. More...
 
void addVariantGepEdge (NodeID src, NodeID dst, const AccessPath &ap)
 Add Variant(Gep) edge. More...
 
void addThreadForkEdge (NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
 Add Thread fork edge for parameter passing. More...
 
void addThreadJoinEdge (NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
 Add Thread join edge for parameter passing. More...
 
AccessPath getAccessPathFromBaseNode (NodeID nodeId)
 

Private Member Functions

LLVMModuleSetllvmModuleSet ()
 

Private Attributes

SVFIRpag
 
SVFModulesvfModule
 
const SVFBasicBlockcurBB
 Current basic block during SVFIR construction when visiting the module. More...
 
const SVFValuecurVal
 Current Value during SVFIR construction when visiting the module. More...
 

Detailed Description

SVFIR Builder to create SVF variables and statements and PAG

Definition at line 46 of file SVFIRBuilder.h.

Constructor & Destructor Documentation

◆ SVFIRBuilder()

SVF::SVFIRBuilder::SVFIRBuilder ( SVFModule mod)
inline

Constructor.

Definition at line 57 of file SVFIRBuilder.h.

57  : pag(SVFIR::getPAG()), svfModule(mod), curBB(nullptr),curVal(nullptr)
58  {
59  }
SVFModule * svfModule
Definition: SVFIRBuilder.h:51
const SVFBasicBlock * curBB
Current basic block during SVFIR construction when visiting the module.
Definition: SVFIRBuilder.h:52
const SVFValue * curVal
Current Value during SVFIR construction when visiting the module.
Definition: SVFIRBuilder.h:53
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115

◆ ~SVFIRBuilder()

virtual SVF::SVFIRBuilder::~SVFIRBuilder ( )
inlinevirtual

Destructor.

Definition at line 61 of file SVFIRBuilder.h.

62  {
63  }

Member Function Documentation

◆ addAddrEdge()

AddrStmt* SVF::SVFIRBuilder::addAddrEdge ( NodeID  src,
NodeID  dst 
)
inlineprotected

Add Address edge.

Definition at line 292 of file SVFIRBuilder.h.

293  {
294  if(AddrStmt *edge = pag->addAddrStmt(src, dst))
295  {
297  return edge;
298  }
299  return nullptr;
300  }
void setCurrentBBAndValueForPAGEdge(PAGEdge *edge)
AddrStmt * addAddrStmt(NodeID src, NodeID dst)
Add an edge into SVFIR.
Definition: SVFIR.cpp:46

◆ addAddrWithHeapSz()

AddrStmt* SVF::SVFIRBuilder::addAddrWithHeapSz ( NodeID  src,
NodeID  dst,
const CallBase cs 
)
inlineprotected

Add Address edge from ext call with args like "%5 = call i8* @malloc(i64 noundef 5)".

Definition at line 315 of file SVFIRBuilder.h.

316  {
317  // get name of called function
318  AddrStmt* edge = addAddrEdge(src, dst);
319 
320  llvm::Function* calledFunc = cs->getCalledFunction();
321  std::string functionName;
322  if (calledFunc)
323  {
324  functionName = calledFunc->getName().str();
325  }
326  else
327  {
328  SVFUtil::wrnMsg("not support indirect call to add AddrStmt.\n");
329  }
330  if (functionName == "malloc")
331  {
332  if (cs->arg_size() > 0)
333  {
334  const llvm::Value* val = cs->getArgOperand(0);
335  SVFValue* svfval = llvmModuleSet()->getSVFValue(val);
336  edge->addArrSize(svfval);
337  }
338  }
339  // Check if the function called is 'calloc' and process its arguments.
340  // e.g. "%5 = call i8* @calloc(1, 8)", edge should add two SVFValue (1 and 8)
341  else if (functionName == "calloc")
342  {
343  if (cs->arg_size() > 1)
344  {
345  edge->addArrSize(llvmModuleSet()->getSVFValue(cs->getArgOperand(0)));
346  edge->addArrSize(llvmModuleSet()->getSVFValue(cs->getArgOperand(1)));
347  }
348  }
349  else
350  {
351  if (cs->arg_size() > 0)
352  {
353  const llvm::Value* val = cs->getArgOperand(0);
354  SVFValue* svfval = llvmModuleSet()->getSVFValue(val);
355  edge->addArrSize(svfval);
356  }
357  }
358  return edge;
359  }
const char *const string
Definition: cJSON.h:172
SVFValue * getSVFValue(const Value *value)
AddrStmt * addAddrEdge(NodeID src, NodeID dst)
Add Address edge.
Definition: SVFIRBuilder.h:292
LLVMModuleSet * llvmModuleSet()
Definition: SVFIRBuilder.h:509
std::string wrnMsg(const std::string &msg)
Returns warning message by converting a string into yellow string output.
Definition: SVFUtil.cpp:61
llvm::Function Function
Definition: BasicTypes.h:85
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82

◆ addAddrWithStackArraySz()

AddrStmt* SVF::SVFIRBuilder::addAddrWithStackArraySz ( NodeID  src,
NodeID  dst,
llvm::AllocaInst &  inst 
)
inlineprotected

Add Address edge from allocinst with arraysize like "%4 = alloca i8, i64 3".

Definition at line 303 of file SVFIRBuilder.h.

304  {
305  AddrStmt* edge = addAddrEdge(src, dst);
306  if (inst.getArraySize())
307  {
308  SVFValue* arrSz = llvmModuleSet()->getSVFValue(inst.getArraySize());
309  edge->addArrSize(arrSz);
310  }
311  return edge;
312  }

◆ addBinaryOPEdge()

void SVF::SVFIRBuilder::addBinaryOPEdge ( NodeID  op1,
NodeID  op2,
NodeID  dst,
u32_t  opcode 
)
inlineprotected

Add Copy edge.

Definition at line 427 of file SVFIRBuilder.h.

428  {
429  if(BinaryOPStmt *edge = pag->addBinaryOPStmt(op1, op2, dst, opcode))
431  }
BinaryOPStmt * addBinaryOPStmt(NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
Add Copy edge.
Definition: SVFIR.cpp:148

◆ addBlackHoleAddrEdge()

void SVF::SVFIRBuilder::addBlackHoleAddrEdge ( NodeID  node)
inlineprotected

Definition at line 285 of file SVFIRBuilder.h.

286  {
287  if(PAGEdge *edge = pag->addBlackHoleAddrStmt(node))
289  }
SVFStmt * addBlackHoleAddrStmt(NodeID node)
Set a pointer points-to black hole (e.g. int2ptr)
Definition: SVFIR.cpp:277
SVFStmt PAGEdge
Definition: IRGraph.h:43

◆ addBranchStmt()

void SVF::SVFIRBuilder::addBranchStmt ( NodeID  br,
NodeID  cond,
const BranchStmt::SuccAndCondPairVec succs 
)
inlineprotected

Add Branch statement.

Definition at line 439 of file SVFIRBuilder.h.

440  {
441  if(BranchStmt *edge = pag->addBranchStmt(br, cond, succs))
443  }
BranchStmt * addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec &succs)
Add BranchStmt.
Definition: SVFIR.cpp:186

◆ addCallEdge()

void SVF::SVFIRBuilder::addCallEdge ( NodeID  src,
NodeID  dst,
const CallICFGNode cs,
const FunEntryICFGNode entry 
)
inlineprotected

Add Call edge.

Definition at line 463 of file SVFIRBuilder.h.

464  {
465  if (CallPE* edge = pag->addCallPE(src, dst, cs, entry))
467  }
CallPE * addCallPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Call edge.
Definition: SVFIR.cpp:241

◆ addCmpEdge()

void SVF::SVFIRBuilder::addCmpEdge ( NodeID  op1,
NodeID  op2,
NodeID  dst,
u32_t  predict 
)
inlineprotected

Add Copy edge.

Definition at line 421 of file SVFIRBuilder.h.

422  {
423  if(CmpStmt *edge = pag->addCmpStmt(op1, op2, dst, predict))
425  }
CmpStmt * addCmpStmt(NodeID op1, NodeID op2, NodeID dst, u32_t predict)
Add Copy edge.
Definition: SVFIR.cpp:127

◆ addComplexConsForExt()

void SVFIRBuilder::addComplexConsForExt ( Value D,
Value S,
const Value szValue 
)
protectedvirtual

Add the load/store constraints and temp. nodes for the complex constraint *D = *S (where D/S may point to structs).

If sz is 0, we will add edges for all fields.

Definition at line 78 of file SVFIRExtAPI.cpp.

79 {
80  assert(D && S);
81  NodeID vnD= getValueNode(D), vnS= getValueNode(S);
82  if(!vnD || !vnS)
83  return;
84 
85  std::vector<AccessPath> fields;
86 
87  //Get the max possible size of the copy, unless it was provided.
88  std::vector<AccessPath> srcFields;
89  std::vector<AccessPath> dstFields;
90  const Type* stype = getBaseTypeAndFlattenedFields(S, srcFields, szValue);
91  const Type* dtype = getBaseTypeAndFlattenedFields(D, dstFields, szValue);
92  if(srcFields.size() > dstFields.size())
93  fields = dstFields;
94  else
95  fields = srcFields;
96 
98  u32_t sz = fields.size();
99 
100  if (fields.size() == 1 && (LLVMUtil::isConstDataOrAggData(D) || LLVMUtil::isConstDataOrAggData(S)))
101  {
102  NodeID dummy = pag->addDummyValNode();
103  addLoadEdge(vnD,dummy);
104  addStoreEdge(dummy,vnS);
105  return;
106  }
107 
108  //For each field (i), add (Ti = *S + i) and (*D + i = Ti).
109  for (u32_t index = 0; index < sz; index++)
110  {
112  const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(dtype),
113  fields[index].getConstantStructFldIdx());
114  const SVFType* sElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(stype),
115  fields[index].getConstantStructFldIdx());
116  NodeID dField = getGepValVar(D,fields[index],dElementType);
117  NodeID sField = getGepValVar(S,fields[index],sElementType);
118  NodeID dummy = pag->addDummyValNode();
119  addLoadEdge(sField,dummy);
120  addStoreEdge(dummy,dField);
121  }
122 }
unsigned u32_t
Definition: CommandLine.h:18
int index
Definition: cJSON.h:170
SymbolTableInfo * getSymbolInfo() const
Definition: IRGraph.h:114
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
static LLVMModuleSet * getLLVMModuleSet()
Definition: LLVMModule.h:118
void addStoreEdge(NodeID src, NodeID dst)
Add Store edge.
Definition: SVFIRBuilder.h:451
void addLoadEdge(NodeID src, NodeID dst)
Add Load edge.
Definition: SVFIRBuilder.h:445
virtual const Type * getBaseTypeAndFlattenedFields(const Value *V, std::vector< AccessPath > &fields, const Value *szValue)
Handle external call.
Definition: SVFIRExtAPI.cpp:43
NodeID getValueNode(const Value *V)
Get different kinds of node.
Definition: SVFIRBuilder.h:87
NodeID getGepValVar(const Value *val, const AccessPath &ap, const SVFType *elementType)
NodeID addDummyValNode()
Definition: SVFIR.h:474
const SVFType * getFlatternedElemType(const SVFType *baseType, u32_t flatten_idx)
Return the type of a flattened element given a flattened index.
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
Definition: LLVMUtil.h:327
llvm::Type Type
Definition: BasicTypes.h:83
u32_t NodeID
Definition: GeneralType.h:55

◆ addCopyEdge()

CopyStmt* SVF::SVFIRBuilder::addCopyEdge ( NodeID  src,
NodeID  dst,
CopyStmt::CopyKind  kind 
)
inlineprotected

Definition at line 361 of file SVFIRBuilder.h.

362  {
363  if(CopyStmt *edge = pag->addCopyStmt(src, dst, kind))
364  {
366  return edge;
367  }
368  return nullptr;
369  }
CopyStmt * addCopyStmt(NodeID src, NodeID dst, CopyStmt::CopyKind type)
Add Copy edge.
Definition: SVFIR.cpp:64

◆ addEdge()

void SVF::SVFIRBuilder::addEdge ( NodeID  src,
NodeID  dst,
SVFStmt::PEDGEK  kind,
APOffset  offset = 0,
Instruction cs = nullptr 
)

◆ addGepEdge()

void SVF::SVFIRBuilder::addGepEdge ( NodeID  src,
NodeID  dst,
const AccessPath ap,
bool  constGep 
)
inlineprotected

Add Gep edge.

Definition at line 475 of file SVFIRBuilder.h.

476  {
477  if (GepStmt* edge = pag->addGepStmt(src, dst, ap, constGep))
479  }
GepStmt * addGepStmt(NodeID src, NodeID dst, const AccessPath &ap, bool constGep)
Add Gep edge.
Definition: SVFIR.cpp:327

◆ addGlobalBlackHoleAddrEdge()

void SVF::SVFIRBuilder::addGlobalBlackHoleAddrEdge ( NodeID  node,
const ConstantExpr int2Ptrce 
)
inlineprotected

Add global black hole Address edge.

Definition at line 261 of file SVFIRBuilder.h.

262  {
263  const SVFValue* cval = getCurrentValue();
264  const SVFBasicBlock* cbb = getCurrentBB();
265  setCurrentLocation(int2Ptrce,nullptr);
266  addBlackHoleAddrEdge(node);
267  setCurrentLocation(cval,cbb);
268  }
void setCurrentLocation(const Value *val, const BasicBlock *bb)
Set current basic block in order to keep track of control flow information.
Definition: SVFIRBuilder.h:241
const SVFBasicBlock * getCurrentBB() const
Definition: SVFIRBuilder.h:255
void addBlackHoleAddrEdge(NodeID node)
Definition: SVFIRBuilder.h:285
const SVFValue * getCurrentValue() const
Definition: SVFIRBuilder.h:251

◆ addLoadEdge()

void SVF::SVFIRBuilder::addLoadEdge ( NodeID  src,
NodeID  dst 
)
inlineprotected

Add Load edge.

Definition at line 445 of file SVFIRBuilder.h.

446  {
447  if(LoadStmt *edge = pag->addLoadStmt(src, dst))
449  }
LoadStmt * addLoadStmt(NodeID src, NodeID dst)
Add Load edge.
Definition: SVFIR.cpp:204

◆ addNormalGepEdge()

void SVF::SVFIRBuilder::addNormalGepEdge ( NodeID  src,
NodeID  dst,
const AccessPath ap 
)
inlineprotected

Add Offset(Gep) edge.

Definition at line 481 of file SVFIRBuilder.h.

482  {
483  if (GepStmt* edge = pag->addNormalGepStmt(src, dst, ap))
485  }
GepStmt * addNormalGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Offset(Gep) edge.
Definition: SVFIR.cpp:346

◆ addNullPtrNode()

NodeID SVF::SVFIRBuilder::addNullPtrNode ( )
inlineprotected

Add NullPtr PAGNode.

Definition at line 271 of file SVFIRBuilder.h.

272  {
274  ConstantPointerNull* constNull = ConstantPointerNull::get(PointerType::getUnqual(cxt));
275  NodeID nullPtr = pag->addValNode(llvmModuleSet()->getSVFValue(constNull),pag->getNullPtr(), nullptr);
276  setCurrentLocation(constNull, nullptr);
278  return nullPtr;
279  }
NodeID getBlkPtr() const
Definition: IRGraph.h:169
NodeID getNullPtr() const
Definition: IRGraph.h:173
LLVMContext & getContext() const
Definition: LLVMModule.h:349
NodeID addValNode(const SVFValue *val, NodeID i, const SVFBaseNode *gNode)
add node into SVFIR
Definition: SVFIR.h:547
llvm::ConstantPointerNull ConstantPointerNull
Definition: BasicTypes.h:127
llvm::LLVMContext LLVMContext
Definition: BasicTypes.h:70

◆ addPhiStmt()

void SVF::SVFIRBuilder::addPhiStmt ( NodeID  res,
NodeID  opnd,
const ICFGNode pred 
)
inlineprotected

Add Copy edge.

If we already added this phi node, then skip this adding

Definition at line 408 of file SVFIRBuilder.h.

409  {
411  if(PhiStmt *edge = pag->addPhiStmt(res,opnd,pred))
413  }
PhiStmt * addPhiStmt(NodeID res, NodeID opnd, const ICFGNode *pred)
Add phi node information.
Definition: SVFIR.cpp:82

◆ addRetEdge()

void SVF::SVFIRBuilder::addRetEdge ( NodeID  src,
NodeID  dst,
const CallICFGNode cs,
const FunExitICFGNode exit 
)
inlineprotected

Add Return edge.

Definition at line 469 of file SVFIRBuilder.h.

470  {
471  if (RetPE* edge = pag->addRetPE(src, dst, cs, exit))
473  }
RetPE * addRetPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Return edge.
Definition: SVFIR.cpp:259

◆ addSelectStmt()

void SVF::SVFIRBuilder::addSelectStmt ( NodeID  res,
NodeID  op1,
NodeID  op2,
NodeID  cond 
)
inlineprotected

Add SelectStmt.

Definition at line 415 of file SVFIRBuilder.h.

416  {
417  if(SelectStmt *edge = pag->addSelectStmt(res,op1,op2,cond))
419  }
SelectStmt * addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond)
Add SelectStmt.
Definition: SVFIR.cpp:106

◆ addStoreEdge()

void SVF::SVFIRBuilder::addStoreEdge ( NodeID  src,
NodeID  dst 
)
inlineprotected

Add Store edge.

Definition at line 451 of file SVFIRBuilder.h.

452  {
453  ICFGNode* node;
454  if (const SVFInstruction* inst = SVFUtil::dyn_cast<SVFInstruction>(curVal))
455  node = llvmModuleSet()->getICFGNode(
456  SVFUtil::cast<Instruction>(llvmModuleSet()->getLLVMValue(inst)));
457  else
458  node = nullptr;
459  if (StoreStmt* edge = pag->addStoreStmt(src, dst, node))
461  }
ICFGNode * getICFGNode(const Instruction *inst)
Get a basic block ICFGNode.
StoreStmt * addStoreStmt(NodeID src, NodeID dst, const ICFGNode *val)
Add Store edge.
Definition: SVFIR.cpp:223

◆ addThreadForkEdge()

void SVF::SVFIRBuilder::addThreadForkEdge ( NodeID  src,
NodeID  dst,
const CallICFGNode cs,
const FunEntryICFGNode entry 
)
inlineprotected

Add Thread fork edge for parameter passing.

Definition at line 493 of file SVFIRBuilder.h.

494  {
495  if (TDForkPE* edge = pag->addThreadForkPE(src, dst, cs, entry))
497  }
TDForkPE * addThreadForkPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Thread fork edge for parameter passing.
Definition: SVFIR.cpp:288

◆ addThreadJoinEdge()

void SVF::SVFIRBuilder::addThreadJoinEdge ( NodeID  src,
NodeID  dst,
const CallICFGNode cs,
const FunExitICFGNode exit 
)
inlineprotected

Add Thread join edge for parameter passing.

Definition at line 499 of file SVFIRBuilder.h.

500  {
501  if (TDJoinPE* edge = pag->addThreadJoinPE(src, dst, cs, exit))
503  }
TDJoinPE * addThreadJoinPE(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Thread join edge for parameter passing.
Definition: SVFIR.cpp:306

◆ addUnaryOPEdge()

void SVF::SVFIRBuilder::addUnaryOPEdge ( NodeID  src,
NodeID  dst,
u32_t  opcode 
)
inlineprotected

Add Unary edge.

Definition at line 433 of file SVFIRBuilder.h.

434  {
435  if(UnaryOPStmt *edge = pag->addUnaryOPStmt(src, dst, opcode))
437  }
UnaryOPStmt * addUnaryOPStmt(NodeID src, NodeID dst, u32_t opcode)
Add Unary edge.
Definition: SVFIR.cpp:168

◆ addVariantGepEdge()

void SVF::SVFIRBuilder::addVariantGepEdge ( NodeID  src,
NodeID  dst,
const AccessPath ap 
)
inlineprotected

Add Variant(Gep) edge.

Definition at line 487 of file SVFIRBuilder.h.

488  {
489  if (GepStmt* edge = pag->addVariantGepStmt(src, dst, ap))
491  }
GepStmt * addVariantGepStmt(NodeID src, NodeID dst, const AccessPath &ap)
Add Variant(Gep) edge.
Definition: SVFIR.cpp:365

◆ build()

SVFIR * SVFIRBuilder::build ( )
virtual

Start building SVFIR here.

Start building SVFIR here

initial external library information initial SVFIR nodes

initial SVFIR edges: // handle globals

handle functions

collect return node of function fun

Return SVFIR node will not be created for function which can not reach the return instruction due to call to abort(), exit(), etc. In 176.gcc of SPEC 2000, function build_objc_string() from c-lang.c shows an example when fun.doesNotReturn() evaluates to TRUE because of abort().

To be noted, we do not record arguments which are in declared function without body TODO: what about external functions with SVFIR imported by commandline?

Definition at line 54 of file SVFIRBuilder.cpp.

55 {
56  double startTime = SVFStat::getClk(true);
57 
58  DBOUT(DGENERAL, outs() << pasMsg("\t Building SVFIR ...\n"));
59 
60  // Set SVFModule from SVFIRBuilder
62 
63  // Build ICFG
64  pag->setICFG(llvmModuleSet()->getICFG());
65 
66  // Set callgraph
67  pag->setCallGraph(llvmModuleSet()->callgraph);
68 
69  // Set icfgnode in memobj
70  for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())
71  {
72  if(!it.second->getValue())
73  continue;
74  if (const Instruction* inst =
75  SVFUtil::dyn_cast<Instruction>(llvmModuleSet()->getLLVMValue(
76  it.second->getValue())))
77  {
78  if(llvmModuleSet()->hasICFGNode(inst))
79  it.second->gNode = llvmModuleSet()->getICFGNode(inst);
80  }
81  }
82 
83  CHGraph* chg = new CHGraph(pag->getModule());
84  CHGBuilder chgbuilder(chg);
85  chgbuilder.buildCHG();
86  pag->setCHG(chg);
87 
88  // We read SVFIR from a user-defined txt instead of parsing SVFIR from LLVM IR
90  {
92  return fileBuilder.build();
93  }
94 
95  // If the SVFIR has been built before, then we return the unique SVFIR of the program
96  if(pag->getNodeNumAfterPAGBuild() > 1)
97  return pag;
98 
101  initialiseNodes();
106 
108  for (Module& M : llvmModuleSet()->getLLVMModules())
109  {
110  for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
111  {
112  const Function& fun = *F;
113  const SVFFunction* svffun = llvmModuleSet()->getSVFFunction(&fun);
115  if(!fun.isDeclaration())
116  {
122  if (fun.doesNotReturn() == false &&
123  fun.getReturnType()->isVoidTy() == false)
124  {
125  pag->addFunRet(svffun,
126  pag->getGNode(pag->getReturnNode(svffun)));
127  }
128 
131  for (Function::const_arg_iterator I = fun.arg_begin(), E = fun.arg_end();
132  I != E; ++I)
133  {
134  setCurrentLocation(&*I,&fun.getEntryBlock());
135  NodeID argValNodeId = pag->getValueNode(llvmModuleSet()->getSVFValue(&*I));
136  // if this is the function does not have caller (e.g. main)
137  // or a dead function, shall we create a black hole address edge for it?
138  // it is (1) too conservative, and (2) make FormalParmVFGNode defined at blackhole address PAGEdge.
139  // if(SVFUtil::ArgInNoCallerFunction(&*I)) {
140  // if(I->getType()->isPointerTy())
141  // addBlackHoleAddrEdge(argValNodeId);
142  //}
143  pag->addFunArgs(svffun,pag->getGNode(argValNodeId));
144  }
145  }
146  for (Function::const_iterator bit = fun.begin(), ebit = fun.end();
147  bit != ebit; ++bit)
148  {
149  const BasicBlock& bb = *bit;
150  for (BasicBlock::const_iterator it = bb.begin(), eit = bb.end();
151  it != eit; ++it)
152  {
153  const Instruction& inst = *it;
154  setCurrentLocation(&inst,&bb);
155  visit(const_cast<Instruction&>(inst));
156  }
157  }
158  }
159  }
160 
161  sanityCheck();
162 
164 
166 
167  // dump SVFIR
168  if (Options::PAGDotGraph())
169  pag->dump("svfir_initial");
170 
171  // print to command line of the SVFIR graph
172  if (Options::PAGPrint())
173  pag->print();
174 
175  // dump ICFG
176  if (Options::DumpICFG())
177  pag->getICFG()->dump("icfg_initial");
178 
179  if (Options::LoopAnalysis())
180  {
181  LLVMLoopAnalysis loopAnalysis;
182  loopAnalysis.build(pag->getICFG());
183  }
184 
185  // dump SVFIR as JSON
186  if (!Options::DumpJson().empty())
187  {
189  }
190 
191  double endTime = SVFStat::getClk(true);
192  SVFStat::timeOfBuildingSVFIR = (endTime - startTime) / TIMEINTERVAL;
193 
194  return pag;
195 }
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define TIMEINTERVAL
Definition: SVFType.h:512
#define DGENERAL
Definition: SVFType.h:490
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
u32_t getTotalNodeNum() const
Get total number of node/edge.
Definition: GenericGraph.h:680
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition: ICFG.cpp:403
u32_t getNodeNumAfterPAGBuild() const
Definition: IRGraph.h:194
void dump(std::string name)
Dump SVFIR.
Definition: IRGraph.cpp:102
NodeID getValueNode(const SVFValue *V)
Definition: IRGraph.h:137
void setNodeNumAfterPAGBuild(u32_t num)
Definition: IRGraph.h:198
NodeID getReturnNode(const SVFFunction *func) const
GetReturnNode - Return the unique node representing the return value of a function.
Definition: IRGraph.h:152
virtual void build(ICFG *icfg)
Start from here.
SVFFunction * getSVFFunction(const Function *fun) const
Definition: LLVMModule.h:230
static const Option< bool > PAGDotGraph
Definition: Options.h:121
static const Option< std::string > DumpJson
Definition: Options.h:124
static const Option< bool > PAGPrint
Definition: Options.h:127
static const Option< bool > LoopAnalysis
Definition: Options.h:242
static const Option< bool > DumpICFG
Definition: Options.h:123
void sanityCheck()
Sanity check for SVFIR.
void visitGlobal(SVFModule *svfModule)
Handle globals including (global variable and functions)
void initialiseNodes()
Initialize nodes and edges.
static void writeJsonToPath(const SVFIR *svfir, const std::string &path)
void print()
Print SVFIR.
Definition: SVFIR.cpp:554
void setModule(SVFModule *mod)
Set/Get LLVM Module.
Definition: SVFIR.h:157
void addFunRet(const SVFFunction *fun, const SVFVar *ret)
Add function returns.
Definition: SVFIR.h:517
void setICFG(ICFG *i)
Set/Get ICFG.
Definition: SVFIR.h:167
void setCHG(CommonCHGraph *c)
Set/Get CHG.
Definition: SVFIR.h:177
void setCallGraph(PTACallGraph *c)
Set/Get CG.
Definition: SVFIR.h:188
ICFG * getICFG() const
Definition: SVFIR.h:171
void addFunArgs(const SVFFunction *fun, const SVFVar *arg)
Get/set method for function/callsite arguments and returns.
Definition: SVFIR.h:510
SVFModule * getModule()
Definition: SVFIR.h:161
void initialiseCandidatePointers()
Initialize candidate pointers.
Definition: SVFIR.cpp:639
static bool pagReadFromTXT()
Definition: SVFModule.h:98
static std::string pagFileName()
Definition: SVFModule.h:93
static double getClk(bool mark=false)
Definition: SVFStat.cpp:47
static double timeOfBuildingSVFIR
Definition: SVFStat.h:95
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
llvm::BasicBlock BasicBlock
Definition: BasicTypes.h:86
llvm::Instruction Instruction
Definition: BasicTypes.h:87
llvm::Module Module
Definition: BasicTypes.h:84

◆ computeGepOffset()

bool SVFIRBuilder::computeGepOffset ( const User V,
AccessPath ap 
)
protected

Compute offset of a gep instruction or gep constant expression.

Return the object node offset according to GEP insn (V). Given a gep edge p = q + i, if "i" is a constant then we return its offset size otherwise if "i" is a variable determined by runtime, then it is a variant offset Return TRUE if the offset of this GEP insn is a constant.

Definition at line 299 of file SVFIRBuilder.cpp.

300 {
301  assert(V);
302 
303  const llvm::GEPOperator *gepOp = SVFUtil::dyn_cast<const llvm::GEPOperator>(V);
304  DataLayout * dataLayout = getDataLayout(llvmModuleSet()->getMainLLVMModule());
305  llvm::APInt byteOffset(dataLayout->getIndexSizeInBits(gepOp->getPointerAddressSpace()),0,true);
306  if(gepOp && dataLayout && gepOp->accumulateConstantOffset(*dataLayout,byteOffset))
307  {
308  //s32_t bo = byteOffset.getSExtValue();
309  }
310 
311  bool isConst = true;
312 
313  bool prevPtrOperand = false;
314  for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V);
315  gi != ge; ++gi)
316  {
317  const Type* gepTy = *gi;
318  const SVFType* svfGepTy = llvmModuleSet()->getSVFType(gepTy);
319 
320  assert((prevPtrOperand && svfGepTy->isPointerTy()) == false &&
321  "Expect no more than one gep operand to be of a pointer type");
322  if(!prevPtrOperand && svfGepTy->isPointerTy()) prevPtrOperand = true;
323  const Value* offsetVal = gi.getOperand();
324  const SVFValue* offsetSvfVal = llvmModuleSet()->getSVFValue(offsetVal);
325  assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
326  ap.addOffsetVarAndGepTypePair(getPAG()->getGNode(getPAG()->getValueNode(offsetSvfVal)), svfGepTy);
327 
328  //The int value of the current index operand
329  const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(offsetVal);
330 
331  // if Options::ModelConsts() is disabled. We will treat whole array as one,
332  // but we can distinguish different field of an array of struct, e.g. s[1].f1 is different from s[0].f2
333  if(const ArrayType* arrTy = SVFUtil::dyn_cast<ArrayType>(gepTy))
334  {
335  if(!op || (arrTy->getArrayNumElements() <= (u32_t)op->getSExtValue()))
336  continue;
337  APOffset idx = op->getSExtValue();
338  u32_t offset = pag->getSymbolInfo()->getFlattenedElemIdx(llvmModuleSet()->getSVFType(arrTy), idx);
340  }
341  else if (const StructType *ST = SVFUtil::dyn_cast<StructType>(gepTy))
342  {
343  assert(op && "non-const offset accessing a struct");
344  //The actual index
345  APOffset idx = op->getSExtValue();
346  u32_t offset = pag->getSymbolInfo()->getFlattenedElemIdx(llvmModuleSet()->getSVFType(ST), idx);
348  }
349  else if (gepTy->isSingleValueType())
350  {
351  // If it's a non-constant offset access
352  // If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
353  // If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
354  if(!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
355  {
356  isConst = false;
357  }
358 
359  // The actual index
360  //s32_t idx = op->getSExtValue();
361 
362  // For pointer arithmetic we ignore the byte offset
363  // consider using inferFieldIdxFromByteOffset(geopOp,dataLayout,ap,idx)?
364  // ap.setFldIdx(ap.getConstantFieldIdx() + inferFieldIdxFromByteOffset(geopOp,idx));
365  }
366  }
367  return isConst;
368 }
buffer offset
Definition: cJSON.cpp:1113
bool addOffsetVarAndGepTypePair(const SVFVar *var, const SVFType *gepIterType)
Definition: AccessPath.cpp:42
APOffset getConstantStructFldIdx() const
Get methods.
Definition: AccessPath.h:100
void setFldIdx(APOffset idx)
Definition: AccessPath.h:104
SVFIR * getPAG() const
Return SVFIR.
Definition: SVFIRBuilder.h:69
bool isPointerTy() const
Definition: SVFType.h:249
u32_t getFlattenedElemIdx(const SVFType *T, u32_t origId)
Flattened element idx of an array or struct by considering stride.
static DataLayout * getDataLayout(Module *mod)
Definition: LLVMUtil.h:279
llvm::DataLayout DataLayout
Definition: BasicTypes.h:108
llvm::ArrayType ArrayType
Definition: BasicTypes.h:95
llvm::StructType StructType
LLVM types.
Definition: BasicTypes.h:94
s64_t APOffset
Definition: GeneralType.h:60
llvm::GEPOperator GEPOperator
Definition: BasicTypes.h:182
llvm::ConstantInt ConstantInt
Definition: BasicTypes.h:125
bridge_gep_iterator bridge_gep_end(const User *GEP)
bridge_gep_iterator bridge_gep_begin(const User *GEP)

◆ getAccessPathFromBaseNode()

AccessPath SVFIRBuilder::getAccessPathFromBaseNode ( NodeID  nodeId)
protected

Get a base SVFVar given a pointer Return the source node of its connected normal gep edge Otherwise return the node id itself s32_t offset : gep offset

if this node is already a base node

Definition at line 1390 of file SVFIRBuilder.cpp.

1391 {
1392  SVFVar* node = pag->getGNode(nodeId);
1395  if(geps.empty())
1396  return AccessPath(0);
1397 
1398  assert(geps.size()==1 && "one node can only be connected by at most one gep edge!");
1399  SVFVar::iterator it = geps.begin();
1400  const GepStmt* gepEdge = SVFUtil::cast<GepStmt>(*it);
1401  if(gepEdge->isVariantFieldGep())
1402  return AccessPath(0);
1403  else
1404  return gepEdge->getAccessPath();
1405 }
GEdgeSetTy::iterator iterator
Definition: GenericGraph.h:405
bool isVariantFieldGep() const
Gep statement with a variant field index (pointer arithmetic) for struct field access.
const AccessPath & getAccessPath() const
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
SVFStmt::SVFStmtSetTy & getIncomingEdges(SVFStmt::PEDGEK kind)
Get incoming SVFIR statements (edges)
Definition: SVFVariables.h:137

◆ getBaseTypeAndFlattenedFields()

const Type * SVFIRBuilder::getBaseTypeAndFlattenedFields ( const Value V,
std::vector< AccessPath > &  fields,
const Value szValue 
)
protectedvirtual

Handle external call.

Find the base type and the max possible offset of an object pointed to by (V).

use user-specified size for this copy operation if the size is a constaint int

Definition at line 43 of file SVFIRExtAPI.cpp.

44 {
45  assert(V);
46  const Value* value = getBaseValueForExtArg(V);
48  u32_t numOfElems = pag->getSymbolInfo()->getNumOfFlattenElements(LLVMModuleSet::getLLVMModuleSet()->getSVFType(objType));
50  if(szValue && SVFUtil::isa<ConstantInt>(szValue))
51  {
52  numOfElems = (numOfElems > SVFUtil::cast<ConstantInt>(szValue)->getSExtValue()) ? SVFUtil::cast<ConstantInt>(szValue)->getSExtValue() : numOfElems;
53  }
54 
56  for(u32_t ei = 0; ei < numOfElems; ei++)
57  {
58  AccessPath ls(ei);
59  // make a ConstantInt and create char for the content type due to byte-wise copy
60  const ConstantInt* offset = ConstantInt::get(context, llvm::APInt(32, ei));
62  if (!pag->getSymbolInfo()->hasValSym(svfOffset))
63  {
65  builder.collectSym(offset);
66  pag->addValNode(svfOffset, pag->getSymbolInfo()->getValSym(svfOffset), nullptr);
67  }
68  ls.addOffsetVarAndGepTypePair(getPAG()->getGNode(getPAG()->getValueNode(svfOffset)), nullptr);
69  fields.push_back(ls);
70  }
71  return objType;
72 }
ObjTypeInference * getTypeInference()
Definition: LLVMModule.cpp:97
const Type * inferObjType(const Value *var)
get or infer the type of the object pointed by the value
const Value * getBaseValueForExtArg(const Value *V)
Get the base value of (i8* src and i8* dst) for external argument (e.g. memcpy(i8* dst,...
SymID getValSym(const SVFValue *val)
Get different kinds of syms.
u32_t getNumOfFlattenElements(const SVFType *T)
Number of flattened elements of an array or struct.
bool hasValSym(const SVFValue *val)

◆ getBaseValueForExtArg()

const Value * SVFIRBuilder::getBaseValueForExtArg ( const Value V)
protected

Get the base value of (i8* src and i8* dst) for external argument (e.g. memcpy(i8* dst, i8* src, int size))

Definition at line 1163 of file SVFIRBuilder.cpp.

1164 {
1165  const Value* value = stripAllCasts(V);
1166  assert(value && "null ptr?");
1167  if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(value))
1168  {
1169  APOffset totalidx = 0;
1170  for (bridge_gep_iterator gi = bridge_gep_begin(gep), ge = bridge_gep_end(gep); gi != ge; ++gi)
1171  {
1172  if(const ConstantInt* op = SVFUtil::dyn_cast<ConstantInt>(gi.getOperand()))
1173  totalidx += op->getSExtValue();
1174  }
1175  if(totalidx == 0 && !SVFUtil::isa<StructType>(value->getType()))
1176  value = gep->getPointerOperand();
1177  }
1178  return value;
1179 }
const Value * stripAllCasts(const Value *val)
Strip off the all casts.
Definition: LLVMUtil.cpp:251
llvm::GetElementPtrInst GetElementPtrInst
Definition: BasicTypes.h:162

◆ getCopyKind()

CopyStmt::CopyKind SVF::SVFIRBuilder::getCopyKind ( const Value val)
inlineprotected

Definition at line 371 of file SVFIRBuilder.h.

372  {
373  // COPYVAL, ZEXT, SEXT, BITCAST, FPTRUNC, FPTOUI, FPTOSI, UITOFP, SITOFP, INTTOPTR, PTRTOINT
374  if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(val))
375  {
376  switch (inst->getOpcode())
377  {
378  case Instruction::ZExt:
379  return CopyStmt::ZEXT;
380  case Instruction::SExt:
381  return CopyStmt::SEXT;
382  case Instruction::BitCast:
383  return CopyStmt::BITCAST;
384  case Instruction ::Trunc:
385  return CopyStmt::TRUNC;
386  case Instruction::FPTrunc:
387  return CopyStmt::FPTRUNC;
388  case Instruction::FPToUI:
389  return CopyStmt::FPTOUI;
390  case Instruction::FPToSI:
391  return CopyStmt::FPTOSI;
392  case Instruction::UIToFP:
393  return CopyStmt::UITOFP;
394  case Instruction::SIToFP:
395  return CopyStmt::SITOFP;
396  case Instruction::IntToPtr:
397  return CopyStmt::INTTOPTR;
398  case Instruction::PtrToInt:
399  return CopyStmt::PTRTOINT;
400  default:
401  return CopyStmt::COPYVAL;
402  }
403  }
404  assert (false && "Unknown cast inst!");
405  }

◆ getCurrentBB()

const SVFBasicBlock* SVF::SVFIRBuilder::getCurrentBB ( ) const
inlineprotected

Definition at line 255 of file SVFIRBuilder.h.

256  {
257  return curBB;
258  }

◆ getCurrentValue()

const SVFValue* SVF::SVFIRBuilder::getCurrentValue ( ) const
inlineprotected

Definition at line 251 of file SVFIRBuilder.h.

252  {
253  return curVal;
254  }

◆ getGepValVar()

NodeID SVFIRBuilder::getGepValVar ( const Value val,
const AccessPath ap,
const SVFType elementType 
)
protected

Add a temp field value node according to base value and offset this node is after the initial node method, it is out of scope of symInfo table

Definition at line 1254 of file SVFIRBuilder.cpp.

1255 {
1256  NodeID base = getValueNode(val);
1257  NodeID gepval = pag->getGepValVar(curVal, base, ap);
1258  if (gepval==UINT_MAX)
1259  {
1260  assert(((int) UINT_MAX)==-1 && "maximum limit of unsigned int is not -1?");
1261  /*
1262  * getGepValVar can only be called from two places:
1263  * 1. SVFIRBuilder::addComplexConsForExt to handle external calls
1264  * 2. SVFIRBuilder::getGlobalVarField to initialize global variable
1265  * so curVal can only be
1266  * 1. Instruction
1267  * 2. GlobalVariable
1268  */
1269  assert((SVFUtil::isa<SVFInstruction, SVFGlobalValue>(curVal)) && "curVal not an instruction or a globalvariable?");
1270 
1271  // We assume every GepValNode and its GepEdge to the baseNode are unique across the whole program
1272  // We preserve the current BB information to restore it after creating the gepNode
1273  const SVFValue* cval = getCurrentValue();
1274  const SVFBasicBlock* cbb = getCurrentBB();
1275  setCurrentLocation(curVal, nullptr);
1276  LLVMModuleSet* llvmmodule = llvmModuleSet();
1277  NodeID gepNode = pag->addGepValNode(curVal, llvmmodule->getSVFValue(val), ap,
1279  llvmmodule->getSVFType(PointerType::getUnqual(llvmmodule->getContext())));
1280  addGepEdge(base, gepNode, ap, true);
1281  setCurrentLocation(cval, cbb);
1282  return gepNode;
1283  }
1284  else
1285  return gepval;
1286 }
NodeID allocateValueId(void)
Allocate a value ID as determined by the strategy.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
void addGepEdge(NodeID src, NodeID dst, const AccessPath &ap, bool constGep)
Add Gep edge.
Definition: SVFIRBuilder.h:475
NodeID addGepValNode(const SVFValue *curInst, const SVFValue *val, const AccessPath &ap, NodeID i, const SVFType *type)
Add a temp field value node, this method can only invoked by getGepValVar.
Definition: SVFIR.cpp:386
NodeID getGepValVar(const SVFValue *curInst, NodeID base, const AccessPath &ap) const
Due to constraint expression, curInst is used to distinguish different instructions (e....
Definition: SVFIR.cpp:517

◆ getGlobalVarField()

NodeID SVFIRBuilder::getGlobalVarField ( const GlobalVariable gvar,
u32_t  offset,
SVFType tpy 
)
protected

Get the field of the global variable node FIXME:Here we only get the field that actually used in the program We ignore the initialization of global variable field that not used in the program

if we did not find the constant expression in the program, then we need to create a gep node for this field

Definition at line 504 of file SVFIRBuilder.cpp.

505 {
506 
507  // if the global variable do not have any field needs to be initialized
508  if (offset == 0 && gvar->getInitializer()->getType()->isSingleValueType())
509  {
510  return getValueNode(gvar);
511  }
514  else
515  {
516  return getGepValVar(gvar, AccessPath(offset), tpy);
517  }
518 }

◆ getObjectNode()

NodeID SVF::SVFIRBuilder::getObjectNode ( const Value V)
inline

GetObject - Return the object node (stack/global/heap/function) according to a LLVM Value.

Definition at line 98 of file SVFIRBuilder.h.

99  {
100  SVFValue* svfVal = llvmModuleSet()->getSVFValue(V);
101  return pag->getObjectNode(svfVal);
102  }
NodeID getObjectNode(const SVFValue *V)
Definition: IRGraph.h:147

◆ getPAG()

SVFIR* SVF::SVFIRBuilder::getPAG ( ) const
inline

Return SVFIR.

Definition at line 69 of file SVFIRBuilder.h.

70  {
71  return pag;
72  }

◆ getReturnNode()

NodeID SVF::SVFIRBuilder::getReturnNode ( const SVFFunction func)
inline

getReturnNode - Return the node representing the unique return value of a function.

Definition at line 105 of file SVFIRBuilder.h.

106  {
107  return pag->getReturnNode(func);
108  }

◆ getValueNode()

NodeID SVF::SVFIRBuilder::getValueNode ( const Value V)
inline

Get different kinds of node.

Definition at line 87 of file SVFIRBuilder.h.

88  {
89  // first handle gep edge if val if a constant expression
90  processCE(V);
91 
92  // strip off the constant cast and return the value node
93  SVFValue* svfVal = llvmModuleSet()->getSVFValue(V);
94  return pag->getValueNode(svfVal);
95  }
void processCE(const Value *val)
Process constant expression.

◆ getVarargNode()

NodeID SVF::SVFIRBuilder::getVarargNode ( const SVFFunction func)
inline

getVarargNode - Return the node representing the unique variadic argument of a function.

Definition at line 111 of file SVFIRBuilder.h.

112  {
113  return pag->getVarargNode(func);
114  }
NodeID getVarargNode(const SVFFunction *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition: IRGraph.h:157

◆ handleDirectCall()

void SVFIRBuilder::handleDirectCall ( CallBase cs,
const Function F 
)
protected

Handle direct call.

Add the constraints for a direct, non-external call.

FIXME: this assertion should be placed for correct checking except bug program like 188.ammp, 300.twolf

Definition at line 1100 of file SVFIRBuilder.cpp.

1101 {
1102 
1103  assert(F);
1104  CallICFGNode* callICFGNode = llvmModuleSet()->getCallICFGNode(cs);
1105  const SVFFunction* svffun = llvmModuleSet()->getSVFFunction(F);
1106  DBOUT(DPAGBuild,
1107  outs() << "handle direct call " << LLVMUtil::dumpValue(cs) << " callee " << F->getName().str() << "\n");
1108 
1109  //Only handle the ret.val. if it's used as a ptr.
1110  NodeID dstrec = getValueNode(cs);
1111  //Does it actually return a ptr?
1112  if (!cs->getType()->isVoidTy())
1113  {
1114  NodeID srcret = getReturnNode(svffun);
1115  FunExitICFGNode* exitICFGNode = pag->getICFG()->getFunExitICFGNode(svffun);
1116  addRetEdge(srcret, dstrec,callICFGNode, exitICFGNode);
1117  }
1118  //Iterators for the actual and formal parameters
1119  u32_t itA = 0, ieA = cs->arg_size();
1120  Function::const_arg_iterator itF = F->arg_begin(), ieF = F->arg_end();
1121  //Go through the fixed parameters.
1122  DBOUT(DPAGBuild, outs() << " args:");
1123  for (; itF != ieF; ++itA, ++itF)
1124  {
1125  //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
1126  if (itA == ieA)
1127  {
1128  DBOUT(DPAGBuild, outs() << " !! not enough args\n");
1129  break;
1130  }
1131  const Value* AA = cs->getArgOperand(itA), *FA = &*itF; //current actual/formal arg
1132 
1133  DBOUT(DPAGBuild, outs() << "process actual parm " << llvmModuleSet()->getSVFValue(AA)->toString() << " \n");
1134 
1135  NodeID dstFA = getValueNode(FA);
1136  NodeID srcAA = getValueNode(AA);
1137  FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(svffun);
1138  addCallEdge(srcAA, dstFA, callICFGNode, entry);
1139  }
1140  //Any remaining actual args must be varargs.
1141  if (F->isVarArg())
1142  {
1143  NodeID vaF = getVarargNode(svffun);
1144  DBOUT(DPAGBuild, outs() << "\n varargs:");
1145  for (; itA != ieA; ++itA)
1146  {
1147  const Value* AA = cs->getArgOperand(itA);
1148  NodeID vnAA = getValueNode(AA);
1149  FunEntryICFGNode* entry = pag->getICFG()->getFunEntryICFGNode(svffun);
1150  addCallEdge(vnAA,vaF, callICFGNode,entry);
1151  }
1152  }
1153  if(itA != ieA)
1154  {
1157  writeWrnMsg("too many args to non-vararg func.");
1158  writeWrnMsg("(" + callICFGNode->getSourceLoc() + ")");
1159 
1160  }
1161 }
#define DPAGBuild
Definition: SVFType.h:492
const std::string getSourceLoc() const override
Definition: ICFGNode.h:588
FunEntryICFGNode * getFunEntryICFGNode(const SVFFunction *fun)
Add a function entry node.
Definition: ICFG.cpp:234
FunExitICFGNode * getFunExitICFGNode(const SVFFunction *fun)
Add a function exit node.
Definition: ICFG.cpp:241
CallICFGNode * getCallICFGNode(const Instruction *cs)
get a call node
NodeID getVarargNode(const SVFFunction *func)
getVarargNode - Return the node representing the unique variadic argument of a function.
Definition: SVFIRBuilder.h:111
void addRetEdge(NodeID src, NodeID dst, const CallICFGNode *cs, const FunExitICFGNode *exit)
Add Return edge.
Definition: SVFIRBuilder.h:469
void addCallEdge(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Call edge.
Definition: SVFIRBuilder.h:463
NodeID getReturnNode(const SVFFunction *func)
getReturnNode - Return the node representing the unique return value of a function.
Definition: SVFIRBuilder.h:105
std::string dumpValue(const Value *val)
Definition: LLVMUtil.cpp:585
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition: SVFUtil.cpp:66

◆ handleExtCall()

void SVFIRBuilder::handleExtCall ( const CallBase cs,
const SVFFunction svfCallee 
)
protectedvirtual

pthread_create has 1 arg. apr_thread_create has 2 arg.

Connect actual parameter to formal parameter of the start routine

handle indirect calls at pthread create APIs e.g., pthread_create(&t1, nullptr, fp, ...); const Value* fun = ThreadAPI::getThreadAPI()->getForkedFun(inst); if(!SVFUtil::isa<Function>(fun)) pag->addIndirectCallsites(cs,pag->getValueNode(fun));

If forkedFun does not pass to spawnee as function type but as void pointer remember to update inter-procedural callgraph/SVFIR/SVFG etc. when indirect call targets are resolved We don't connect the callgraph here, further investigation is need to handle mod-ref during SVFG construction.

TODO: inter-procedural SVFIR edges for thread joins

Definition at line 124 of file SVFIRExtAPI.cpp.

125 {
127  const SVFCallInst* svfCall = SVFUtil::cast<SVFCallInst>(svfInst);
128  const CallICFGNode *callICFGNode = llvmModuleSet()->getCallICFGNode(cs);
129 
130  if (isHeapAllocExtCallViaRet(callICFGNode))
131  {
132  NodeID val = pag->getValueNode(svfInst);
133  NodeID obj = pag->getObjectNode(svfInst);
134  addAddrWithHeapSz(obj, val, cs);
135  }
136  else if (isHeapAllocExtCallViaArg(callICFGNode))
137  {
138  u32_t arg_pos = getHeapAllocHoldingArgPosition(svfCallee);
139  const SVFValue* arg = svfCall->getArgOperand(arg_pos);
140  if (arg->getType()->isPointerTy())
141  {
142  NodeID vnArg = pag->getValueNode(arg);
143  NodeID dummy = pag->addDummyValNode();
144  NodeID obj = pag->addDummyObjNode(arg->getType());
145  if (vnArg && dummy && obj)
146  {
147  addAddrWithHeapSz(obj, dummy, cs);
148  addStoreEdge(dummy, vnArg);
149  }
150  }
151  else
152  {
153  writeWrnMsg("Arg receiving new object must be pointer type");
154  }
155  }
156  else if (isMemcpyExtFun(svfCallee))
157  {
158  // Side-effects similar to void *memcpy(void *dest, const void * src, size_t n)
159  // which copies n characters from memory area 'src' to memory area 'dest'.
160  if(svfCallee->getName().find("iconv") != std::string::npos)
161  addComplexConsForExt(cs->getArgOperand(3), cs->getArgOperand(1), nullptr);
162  else if(svfCallee->getName().find("bcopy") != std::string::npos)
163  addComplexConsForExt(cs->getArgOperand(1), cs->getArgOperand(0), cs->getArgOperand(2));
164  if(svfCall->arg_size() == 3)
165  addComplexConsForExt(cs->getArgOperand(0), cs->getArgOperand(1), cs->getArgOperand(2));
166  else
167  addComplexConsForExt(cs->getArgOperand(0), cs->getArgOperand(1), nullptr);
168  if(SVFUtil::isa<PointerType>(cs->getType()))
169  addCopyEdge(getValueNode(cs->getArgOperand(0)), getValueNode(cs), CopyStmt::COPYVAL);
170  }
171  else if(isMemsetExtFun(svfCallee))
172  {
173  // Side-effects similar to memset(void *str, int c, size_t n)
174  // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
175  std::vector<AccessPath> dstFields;
176  const Type *dtype = getBaseTypeAndFlattenedFields(cs->getArgOperand(0), dstFields, cs->getArgOperand(2));
177  u32_t sz = dstFields.size();
178  //For each field (i), add store edge *(arg0 + i) = arg1
179  for (u32_t index = 0; index < sz; index++)
180  {
182  const SVFType* dElementType = pag->getSymbolInfo()->getFlatternedElemType(llvmmodule->getSVFType(dtype),
183  dstFields[index].getConstantStructFldIdx());
184  NodeID dField = getGepValVar(cs->getArgOperand(0), dstFields[index], dElementType);
185  addStoreEdge(getValueNode(cs->getArgOperand(1)),dField);
186  }
187  if(SVFUtil::isa<PointerType>(cs->getType()))
188  addCopyEdge(getValueNode(cs->getArgOperand(0)), getValueNode(cs), CopyStmt::COPYVAL);
189  }
190  else if(svfCallee->getName().compare("dlsym") == 0)
191  {
192  /*
193  Side-effects of void* dlsym( void* handle, const char* funName),
194  Locate the function with the name "funName," then add a "copy" edge between the callsite and that function.
195  dlsym() example:
196  int main() {
197  // Open the shared library
198  void* handle = dlopen("./my_shared_library.so", RTLD_LAZY);
199  // Find the function address
200  void (*myFunctionPtr)() = (void (*)())dlsym(handle, "myFunction");
201  // Call the function
202  myFunctionPtr();
203  }
204  */
205  const Value* src = cs->getArgOperand(1);
206  if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
207  src = stripConstantCasts(gep->getPointerOperand());
208 
209  auto getHookFn = [](const Value* src)->const Function*
210  {
211  if (!SVFUtil::isa<GlobalVariable>(src))
212  return nullptr;
213 
214  auto *glob = SVFUtil::cast<GlobalVariable>(src);
215  if (!glob->hasInitializer() || !SVFUtil::isa<ConstantDataArray>(glob->getInitializer()))
216  return nullptr;
217 
218  auto *constarray = SVFUtil::cast<ConstantDataArray>(glob->getInitializer());
219  return LLVMUtil::getProgFunction(constarray->getAsCString().str());
220  };
221 
222  if (const Function *fn = getHookFn(src))
223  {
224  NodeID srcNode = getValueNode(fn);
226  }
227  }
228  else if(svfCallee->getName().find("_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_") != std::string::npos)
229  {
230  // The purpose of this function is to insert a new node into the red-black tree and then rebalance the tree to ensure that the red-black tree properties are maintained.
231  assert(svfCall->arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
232 
233  // We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
234  // Now we calculate the offset from base to vArg3
235  NodeID vnArg3 = pag->getValueNode(svfCall->getArgOperand(3));
236  APOffset offset =
238 
239  // We get all flattened fields of base
240  vector<AccessPath> fields = pag->getTypeLocSetsMap(vnArg3).second;
241 
242  // We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
243  // Note that arg0 is aligned with "offset".
244  for (APOffset i = offset + 1; i <= offset + 3; ++i)
245  {
246  if((u32_t)i >= fields.size())
247  break;
248  const SVFType* elementType = pag->getSymbolInfo()->getFlatternedElemType(pag->getTypeLocSetsMap(vnArg3).first,
249  fields[i].getConstantStructFldIdx());
250  NodeID vnD = getGepValVar(cs->getArgOperand(3), fields[i], elementType);
251  NodeID vnS = pag->getValueNode(svfCall->getArgOperand(1));
252  if(vnD && vnS)
253  addStoreEdge(vnS,vnD);
254  }
255  }
256 
257  if (isThreadForkCall(callICFGNode))
258  {
259  if (const SVFFunction* forkedFun = SVFUtil::dyn_cast<SVFFunction>(getForkedFun(callICFGNode)->getValue()))
260  {
261  forkedFun = forkedFun->getDefFunForMultipleModule();
262  const SVFVar* actualParm = getActualParmAtForkSite(callICFGNode);
265  assert((forkedFun->arg_size() <= 2) && "Size of formal parameter of start routine should be one");
266  if (forkedFun->arg_size() <= 2 && forkedFun->arg_size() >= 1)
267  {
268  const SVFArgument* formalParm = forkedFun->getArg(0);
270  if (actualParm->isPointer() && formalParm->getType()->isPointerTy())
271  {
272  FunEntryICFGNode *entry = pag->getICFG()->getFunEntryICFGNode(forkedFun);
273  addThreadForkEdge(actualParm->getId(), pag->getValueNode(formalParm), callICFGNode, entry);
274  }
275  }
276  }
277  else
278  {
283  }
287  }
288 
290 }
SVFInstruction * getSVFInstruction(const Instruction *inst) const
Definition: LLVMModule.h:244
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
const SVFValue * getArgOperand(u32_t i) const
Definition: SVFValue.h:711
u32_t arg_size() const
Definition: SVFValue.h:703
CopyStmt * addCopyEdge(NodeID src, NodeID dst, CopyStmt::CopyKind kind)
Definition: SVFIRBuilder.h:361
void addThreadForkEdge(NodeID src, NodeID dst, const CallICFGNode *cs, const FunEntryICFGNode *entry)
Add Thread fork edge for parameter passing.
Definition: SVFIRBuilder.h:493
AccessPath getAccessPathFromBaseNode(NodeID nodeId)
AddrStmt * addAddrWithHeapSz(NodeID src, NodeID dst, const CallBase *cs)
Add Address edge from ext call with args like "%5 = call i8* @malloc(i64 noundef 5)".
Definition: SVFIRBuilder.h:315
virtual void addComplexConsForExt(Value *D, Value *S, const Value *sz)
Definition: SVFIRExtAPI.cpp:78
SVFTypeLocSetsPair & getTypeLocSetsMap(NodeID argId)
Given an arg NodeId, get its base SVFType* and all its field location sets.
Definition: SVFIR.h:244
NodeID addDummyObjNode(const SVFType *type)
Definition: SVFIR.h:478
virtual const SVFType * getType() const
Definition: SVFValue.h:256
const std::string & getName() const
Definition: SVFValue.h:243
virtual bool isPointer() const
Whether it is a pointer.
Definition: SVFVariables.h:106
const Function * getProgFunction(const std::string &funName)
Get program entry function from module.
Definition: LLVMUtil.cpp:39
const Value * stripConstantCasts(const Value *val)
Strip off the constant casts.
Definition: LLVMUtil.cpp:220
bool isHeapAllocExtCallViaRet(const Instruction *inst)
Definition: LLVMUtil.cpp:618
bool isHeapAllocExtCallViaArg(const Instruction *inst)
Definition: LLVMUtil.cpp:634
const SVFVar * getActualParmAtForkSite(const CallICFGNode *cs)
Return sole argument of the thread routine.
Definition: SVFUtil.h:435
bool isMemsetExtFun(const SVFFunction *fun)
Definition: SVFUtil.h:288
bool isMemcpyExtFun(const SVFFunction *fun)
Definition: SVFUtil.h:283
u32_t getHeapAllocHoldingArgPosition(const SVFFunction *fun)
Get the position of argument that holds an allocated heap object.
Definition: SVFUtil.h:309
const SVFVar * getForkedFun(const CallICFGNode *inst)
Return thread fork function.
Definition: SVFUtil.h:356
bool isThreadForkCall(const CallICFGNode *inst)
Definition: SVFUtil.h:387

◆ handleIndCall()

void SVFIRBuilder::handleIndCall ( CallBase cs)
protected

Handle indirect call.

Indirect call is resolved on-the-fly during pointer analysis

Definition at line 1184 of file SVFIRBuilder.cpp.

1185 {
1186  const SVFValue* svfcalledval = llvmModuleSet()->getSVFValue(cs->getCalledOperand());
1187 
1188  const CallICFGNode* cbn = llvmModuleSet()->getCallICFGNode(cs);
1189  pag->addIndirectCallsites(cbn,pag->getValueNode(svfcalledval));
1190 }
void addIndirectCallsites(const CallICFGNode *cs, NodeID funPtr)
Add indirect callsites.
Definition: SVFIR.h:536

◆ inferFieldIdxFromByteOffset()

u32_t SVFIRBuilder::inferFieldIdxFromByteOffset ( const llvm::GEPOperator *  gepOp,
DataLayout dl,
AccessPath ap,
APOffset  idx 
)
protected

Infer field index from byteoffset.

Definition at line 288 of file SVFIRBuilder.cpp.

289 {
290  return 0;
291 }

◆ InitialGlobal()

void SVFIRBuilder::InitialGlobal ( const GlobalVariable gvar,
Constant C,
u32_t  offset 
)
protected

src should not point to anything yet

Definition at line 531 of file SVFIRBuilder.cpp.

533 {
534  DBOUT(DPAGBuild, outs() << "global " << llvmModuleSet()->getSVFValue(gvar)->toString() << " constant initializer: " << llvmModuleSet()->getSVFValue(C)->toString() << "\n");
535  if (C->getType()->isSingleValueType())
536  {
537  NodeID src = getValueNode(C);
538  // get the field value if it is available, otherwise we create a dummy field node.
539  setCurrentLocation(gvar, nullptr);
540  NodeID field = getGlobalVarField(gvar, offset, llvmModuleSet()->getSVFType(C->getType()));
541 
542  if (SVFUtil::isa<GlobalVariable, Function>(C))
543  {
544  setCurrentLocation(C, nullptr);
545  addStoreEdge(src, field);
546  }
547  else if (SVFUtil::isa<ConstantExpr>(C))
548  {
549  // add gep edge of C1 itself is a constant expression
550  processCE(C);
551  setCurrentLocation(C, nullptr);
552  addStoreEdge(src, field);
553  }
554  else if (SVFUtil::isa<BlockAddress>(C))
555  {
556  // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
557  // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
558  processCE(C);
559  setCurrentLocation(C, nullptr);
561  }
562  else
563  {
564  setCurrentLocation(C, nullptr);
565  addStoreEdge(src, field);
567  if (C->getType()->isPtrOrPtrVectorTy() && src != pag->getNullPtr())
569  }
570  }
571  else if (SVFUtil::isa<ConstantArray, ConstantStruct>(C))
572  {
574  return;
575  for (u32_t i = 0, e = C->getNumOperands(); i != e; i++)
576  {
577  u32_t off = pag->getSymbolInfo()->getFlattenedElemIdx(llvmModuleSet()->getSVFType(C->getType()), i);
578  InitialGlobal(gvar, SVFUtil::cast<Constant>(C->getOperand(i)), offset + off);
579  }
580  }
581  else if(ConstantData* data = SVFUtil::dyn_cast<ConstantData>(C))
582  {
584  {
585  if(ConstantDataSequential* seq = SVFUtil::dyn_cast<ConstantDataSequential>(data))
586  {
587  for(u32_t i = 0; i < seq->getNumElements(); i++)
588  {
589  u32_t off = pag->getSymbolInfo()->getFlattenedElemIdx(llvmModuleSet()->getSVFType(C->getType()), i);
590  Constant* ct = seq->getElementAsConstant(i);
591  InitialGlobal(gvar, ct, offset + off);
592  }
593  }
594  else
595  {
596  assert((SVFUtil::isa<ConstantAggregateZero, UndefValue>(data)) && "Single value type data should have been handled!");
597  }
598  }
599  }
600  else
601  {
602  //TODO:assert(SVFUtil::isa<ConstantVector>(C),"what else do we have");
603  }
604 }
NodeID getConstantNode() const
Definition: IRGraph.h:165
static const Option< bool > ModelConsts
Definition: Options.h:187
static const Option< bool > VtableInSVFIR
Definition: Options.h:217
void InitialGlobal(const GlobalVariable *gvar, Constant *C, u32_t offset)
NodeID getGlobalVarField(const GlobalVariable *gvar, u32_t offset, SVFType *tpy)
bool isValVtbl(const Value *val)
Definition: CppUtil.cpp:336
llvm::ConstantData ConstantData
Definition: BasicTypes.h:116
llvm::Constant Constant
Definition: BasicTypes.h:124
llvm::ConstantDataSequential ConstantDataSequential
Definition: BasicTypes.h:119

◆ initialiseNodes()

void SVFIRBuilder::initialiseNodes ( )

Initialize nodes and edges.

add address edges for constant nodes.

Definition at line 200 of file SVFIRBuilder.cpp.

201 {
202  DBOUT(DPAGBuild, outs() << "Initialise SVFIR Nodes ...\n");
203 
204  SymbolTableInfo* symTable = pag->getSymbolInfo();
205 
209  addNullPtrNode();
210 
211  for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
212  symTable->valSyms().begin(); iter != symTable->valSyms().end();
213  ++iter)
214  {
215  DBOUT(DPAGBuild, outs() << "add val node " << iter->second << "\n");
216  if(iter->second == symTable->blkPtrSymID() || iter->second == symTable->nullPtrSymID())
217  continue;
218 
219  const SVFBaseNode* gNode = nullptr;
220  if (const Instruction* inst =
221  SVFUtil::dyn_cast<Instruction>(llvmModuleSet()->getLLVMValue(iter->first)))
222  {
223  if (llvmModuleSet()->hasICFGNode(inst))
224  {
225  gNode = llvmModuleSet()->getICFGNode(inst);
226  }
227  }
228  pag->addValNode(iter->first, iter->second, gNode);
229  }
230 
231  for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
232  symTable->objSyms().begin(); iter != symTable->objSyms().end();
233  ++iter)
234  {
235  DBOUT(DPAGBuild, outs() << "add obj node " << iter->second << "\n");
236  if(iter->second == symTable->blackholeSymID() || iter->second == symTable->constantSymID())
237  continue;
238  pag->addObjNode(iter->first, iter->second);
239  }
240 
241  for (SymbolTableInfo::FunToIDMapTy::iterator iter =
242  symTable->retSyms().begin(); iter != symTable->retSyms().end();
243  ++iter)
244  {
245  DBOUT(DPAGBuild, outs() << "add ret node " << iter->second << "\n");
246  pag->addRetNode(iter->first, iter->second);
247  }
248 
249  for (SymbolTableInfo::FunToIDMapTy::iterator iter =
250  symTable->varargSyms().begin();
251  iter != symTable->varargSyms().end(); ++iter)
252  {
253  DBOUT(DPAGBuild, outs() << "add vararg node " << iter->second << "\n");
254  pag->addVarargNode(iter->first, iter->second);
255  }
256 
258  for (SymbolTableInfo::ValueToIDMapTy::iterator iter =
259  symTable->objSyms().begin(); iter != symTable->objSyms().end(); ++iter)
260  {
261  DBOUT(DPAGBuild, outs() << "add address edges for constant node " << iter->second << "\n");
262  const SVFValue* val = iter->first;
263  if (isConstantObjSym(val))
264  {
265  NodeID ptr = pag->getValueNode(val);
266  if(ptr!= pag->getBlkPtr() && ptr!= pag->getNullPtr())
267  {
268  setCurrentLocation(val, nullptr);
269  addAddrEdge(iter->second, ptr);
270  }
271  }
272  }
273 
274  assert(pag->getTotalNodeNum() >= symTable->getTotalSymNum()
275  && "not all node have been initialized!!!");
276 
277 }
NodeID addNullPtrNode()
Add NullPtr PAGNode.
Definition: SVFIRBuilder.h:271
NodeID addObjNode(const SVFValue *val, NodeID i)
Add a memory obj node.
Definition: SVFIR.h:553
NodeID addBlackholePtrNode()
Definition: SVFIR.h:607
NodeID addBlackholeObjNode()
Definition: SVFIR.h:595
NodeID addRetNode(const SVFFunction *val, NodeID i)
Add a unique return node for a procedure.
Definition: SVFIR.h:560
NodeID addVarargNode(const SVFFunction *val, NodeID i)
Add a unique vararg node for a procedure.
Definition: SVFIR.h:566
NodeID addConstantObjNode()
Definition: SVFIR.h:601
SymID blackholeSymID() const
SymID blkPtrSymID() const
u32_t getTotalSymNum() const
Statistics.
ValueToIDMapTy & objSyms()
ValueToIDMapTy & valSyms()
Get different kinds of syms maps.
FunToIDMapTy & retSyms()
SymID constantSymID() const
FunToIDMapTy & varargSyms()
SymID nullPtrSymID() const
bool isConstantObjSym(const SVFValue *val)
Check whether this value points-to a constant object.
Definition: LLVMUtil.cpp:579

◆ llvmModuleSet()

LLVMModuleSet* SVF::SVFIRBuilder::llvmModuleSet ( )
inlineprivate

Definition at line 509 of file SVFIRBuilder.h.

510  {
512  }

◆ processCE()

void SVFIRBuilder::processCE ( const Value val)
protected

Process constant expression.

Handle constant expression, and connect the gep edge

Definition at line 373 of file SVFIRBuilder.cpp.

374 {
375  if (const Constant* ref = SVFUtil::dyn_cast<Constant>(val))
376  {
377  if (const ConstantExpr* gepce = isGepConstantExpr(ref))
378  {
379  DBOUT(DPAGBuild, outs() << "handle gep constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
380  const Constant* opnd = gepce->getOperand(0);
381  // handle recursive constant express case (gep (bitcast (gep X 1)) 1)
382  processCE(opnd);
383  auto &GEPOp = llvm::cast<llvm::GEPOperator>(*gepce);
384  Type *pType = GEPOp.getSourceElementType();
385  AccessPath ap(0, llvmModuleSet()->getSVFType(pType));
386  bool constGep = computeGepOffset(gepce, ap);
387  // must invoke pag methods here, otherwise it will be a dead recursion cycle
388  const SVFValue* cval = getCurrentValue();
389  const SVFBasicBlock* cbb = getCurrentBB();
390  setCurrentLocation(gepce, nullptr);
391  /*
392  * The gep edge created are like constexpr (same edge may appear at multiple callsites)
393  * so bb/inst of this edge may be rewritten several times, we treat it as global here.
394  */
395  addGepEdge(pag->getValueNode(llvmModuleSet()->getSVFValue(opnd)), pag->getValueNode(llvmModuleSet()->getSVFValue(gepce)), ap, constGep);
396  setCurrentLocation(cval, cbb);
397  }
398  else if (const ConstantExpr* castce = isCastConstantExpr(ref))
399  {
400  DBOUT(DPAGBuild, outs() << "handle cast constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
401  const Constant* opnd = castce->getOperand(0);
402  processCE(opnd);
403  const SVFValue* cval = getCurrentValue();
404  const SVFBasicBlock* cbb = getCurrentBB();
405  setCurrentLocation(castce, nullptr);
406  addCopyEdge(pag->getValueNode(llvmModuleSet()->getSVFValue(opnd)), pag->getValueNode(llvmModuleSet()->getSVFValue(castce)), CopyStmt::BITCAST);
407  setCurrentLocation(cval, cbb);
408  }
409  else if (const ConstantExpr* selectce = isSelectConstantExpr(ref))
410  {
411  DBOUT(DPAGBuild, outs() << "handle select constant expression " << llvmModuleSet()->getSVFValue(ref)->toString() << "\n");
412  const Constant* src1 = selectce->getOperand(1);
413  const Constant* src2 = selectce->getOperand(2);
414  processCE(src1);
415  processCE(src2);
416  const SVFValue* cval = getCurrentValue();
417  const SVFBasicBlock* cbb = getCurrentBB();
418  setCurrentLocation(selectce, nullptr);
419  NodeID cond = pag->getValueNode(llvmModuleSet()->getSVFValue(selectce->getOperand(0)));
420  NodeID nsrc1 = pag->getValueNode(llvmModuleSet()->getSVFValue(src1));
421  NodeID nsrc2 = pag->getValueNode(llvmModuleSet()->getSVFValue(src2));
422  NodeID nres = pag->getValueNode(llvmModuleSet()->getSVFValue(selectce));
423  addSelectStmt(nres,nsrc1, nsrc2, cond);
424  setCurrentLocation(cval, cbb);
425  }
426  // if we meet a int2ptr, then it points-to black hole
427  else if (const ConstantExpr* int2Ptrce = isInt2PtrConstantExpr(ref))
428  {
429  const Constant* opnd = int2Ptrce->getOperand(0);
430  processCE(opnd);
431  const SVFBasicBlock* cbb = getCurrentBB();
432  const SVFValue* cval = getCurrentValue();
433  setCurrentLocation(int2Ptrce, nullptr);
434  addCopyEdge(pag->getValueNode(llvmModuleSet()->getSVFValue(opnd)), pag->getValueNode(llvmModuleSet()->getSVFValue(int2Ptrce)), CopyStmt::INTTOPTR);
435  setCurrentLocation(cval, cbb);
436  }
437  else if (const ConstantExpr* ptr2Intce = isPtr2IntConstantExpr(ref))
438  {
439  const Constant* opnd = ptr2Intce->getOperand(0);
440  processCE(opnd);
441  const SVFBasicBlock* cbb = getCurrentBB();
442  const SVFValue* cval = getCurrentValue();
443  setCurrentLocation(ptr2Intce, nullptr);
444  addCopyEdge(pag->getValueNode(llvmModuleSet()->getSVFValue(opnd)), pag->getValueNode(llvmModuleSet()->getSVFValue(ptr2Intce)), CopyStmt::PTRTOINT);
445  setCurrentLocation(cval, cbb);
446  }
447  else if(isTruncConstantExpr(ref) || isCmpConstantExpr(ref))
448  {
449  // we don't handle trunc and cmp instruction for now
450  const SVFValue* cval = getCurrentValue();
451  const SVFBasicBlock* cbb = getCurrentBB();
452  setCurrentLocation(ref, nullptr);
453  NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(ref));
455  setCurrentLocation(cval, cbb);
456  }
457  else if (isBinaryConstantExpr(ref))
458  {
459  // we don't handle binary constant expression like add(x,y) now
460  const SVFValue* cval = getCurrentValue();
461  const SVFBasicBlock* cbb = getCurrentBB();
462  setCurrentLocation(ref, nullptr);
463  NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(ref));
465  setCurrentLocation(cval, cbb);
466  }
467  else if (isUnaryConstantExpr(ref))
468  {
469  // we don't handle unary constant expression like fneg(x) now
470  const SVFValue* cval = getCurrentValue();
471  const SVFBasicBlock* cbb = getCurrentBB();
472  setCurrentLocation(ref, nullptr);
473  NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(ref));
475  setCurrentLocation(cval, cbb);
476  }
477  else if (SVFUtil::isa<ConstantAggregate>(ref))
478  {
479  // we don't handle constant aggregate like constant vectors
480  }
481  else if (SVFUtil::isa<BlockAddress>(ref))
482  {
483  // blockaddress instruction (e.g. i8* blockaddress(@run_vm, %182))
484  // is treated as constant data object for now, see LLVMUtil.h:397, SymbolTableInfo.cpp:674 and SVFIRBuilder.cpp:183-194
485  const SVFValue* cval = getCurrentValue();
486  const SVFBasicBlock* cbb = getCurrentBB();
487  setCurrentLocation(ref, nullptr);
488  NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(ref));
490  setCurrentLocation(cval, cbb);
491  }
492  else
493  {
494  if(SVFUtil::isa<ConstantExpr>(val))
495  assert(false && "we don't handle all other constant expression for now!");
496  }
497  }
498 }
void addSelectStmt(NodeID res, NodeID op1, NodeID op2, NodeID cond)
Add SelectStmt.
Definition: SVFIRBuilder.h:415
bool computeGepOffset(const User *V, AccessPath &ap)
Compute offset of a gep instruction or gep constant expression.
const ConstantExpr * isUnaryConstantExpr(const Value *val)
Definition: LLVMUtil.h:267
const ConstantExpr * isPtr2IntConstantExpr(const Value *val)
Definition: LLVMUtil.h:201
const ConstantExpr * isBinaryConstantExpr(const Value *val)
Definition: LLVMUtil.h:256
const ConstantExpr * isTruncConstantExpr(const Value *val)
Definition: LLVMUtil.h:231
const ConstantExpr * isCmpConstantExpr(const Value *val)
Definition: LLVMUtil.h:245
const ConstantExpr * isGepConstantExpr(const Value *val)
Return corresponding constant expression, otherwise return nullptr.
Definition: LLVMUtil.h:181
const ConstantExpr * isInt2PtrConstantExpr(const Value *val)
Definition: LLVMUtil.h:191
const ConstantExpr * isSelectConstantExpr(const Value *val)
Definition: LLVMUtil.h:221
const ConstantExpr * isCastConstantExpr(const Value *val)
Definition: LLVMUtil.h:211
llvm::ConstantExpr ConstantExpr
Definition: BasicTypes.h:120

◆ sanityCheck()

void SVFIRBuilder::sanityCheck ( )

Sanity check for SVFIR.

Definition at line 1228 of file SVFIRBuilder.cpp.

1229 {
1230  for (SVFIR::iterator nIter = pag->begin(); nIter != pag->end(); ++nIter)
1231  {
1232  (void) pag->getGNode(nIter->first);
1233  //TODO::
1234  // (1) every source(root) node of a pag tree should be object node
1235  // if a node has no incoming edge, but has outgoing edges
1236  // then it has to be an object node.
1237  // (2) make sure every variable should be initialized
1238  // otherwise it causes the a null pointer, the aliasing relation may not be captured
1239  // when loading a pointer value should make sure
1240  // some value has been store into this pointer before
1241  // q = load p, some value should stored into p first like store w p;
1242  // (3) make sure PAGNode should not have a const expr value (pointer should have unique def)
1243  // (4) look closely into addComplexConsForExt, make sure program locations(e.g.,inst bb)
1244  // are set correctly for dummy gepval node
1245  // (5) reduce unnecessary copy edge (const casts) and ensure correctness.
1246  }
1247 }
iterator begin()
Iterators.
Definition: GenericGraph.h:627
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606

◆ setCurrentBBAndValueForPAGEdge()

void SVFIRBuilder::setCurrentBBAndValueForPAGEdge ( PAGEdge edge)
protected

We assume every GepValVar and its GepStmt are unique across whole program

We will have one unique function exit ICFGNode for all returns

Definition at line 1302 of file SVFIRBuilder.cpp.

1303 {
1305  return;
1306 
1307  assert(curVal && "current Val is nullptr?");
1308  edge->setBB(curBB!=nullptr ? curBB : nullptr);
1309  edge->setValue(curVal);
1310  // backmap in valuToEdgeMap
1311  pag->mapValueToEdge(curVal, edge);
1312  ICFGNode* icfgNode = pag->getICFG()->getGlobalICFGNode();
1313  LLVMModuleSet* llvmMS = llvmModuleSet();
1314  if (const SVFInstruction* curInst = SVFUtil::dyn_cast<SVFInstruction>(curVal))
1315  {
1316  const SVFFunction* srcFun = edge->getSrcNode()->getFunction();
1317  const SVFFunction* dstFun = edge->getDstNode()->getFunction();
1318  if(srcFun!=nullptr && !SVFUtil::isa<RetPE>(edge) && !SVFUtil::isa<SVFFunction>(edge->getSrcNode()->getValue()))
1319  {
1320  assert(srcFun==curInst->getFunction() && "SrcNode of the PAGEdge not in the same function?");
1321  }
1322  if(dstFun!=nullptr && !SVFUtil::isa<CallPE>(edge) && !SVFUtil::isa<SVFFunction>(edge->getDstNode()->getValue()))
1323  {
1324  assert(dstFun==curInst->getFunction() && "DstNode of the PAGEdge not in the same function?");
1325  }
1326 
1328  if (!(SVFUtil::isa<GepStmt>(edge) && SVFUtil::isa<GepValVar>(edge->getDstNode())))
1329  assert(curBB && "instruction does not have a basic block??");
1330 
1332  if(curInst->isRetInst())
1333  {
1334  icfgNode = pag->getICFG()->getFunExitICFGNode(curInst->getFunction());
1335  }
1336  else
1337  {
1338  if(SVFUtil::isa<RetPE>(edge))
1339  icfgNode = llvmMS->getRetICFGNode(SVFUtil::cast<Instruction>(llvmMS->getLLVMValue(curInst)));
1340  else
1341  icfgNode = llvmMS->getICFGNode(SVFUtil::cast<Instruction>(llvmMS->getLLVMValue(curInst)));
1342  }
1343  }
1344  else if (const SVFArgument* arg = SVFUtil::dyn_cast<SVFArgument>(curVal))
1345  {
1346  assert(curBB && (curBB->getParent()->getEntryBlock() == curBB));
1347  icfgNode = pag->getICFG()->getFunEntryICFGNode(arg->getParent());
1348  }
1349  else if (SVFUtil::isa<SVFConstant>(curVal) ||
1350  SVFUtil::isa<SVFFunction>(curVal) ||
1351  SVFUtil::isa<SVFMetadataAsValue>(curVal))
1352  {
1353  if (!curBB)
1354  pag->addGlobalPAGEdge(edge);
1355  else
1356  {
1357  icfgNode = const_cast<ICFGNode*>(curBB->front());
1358  }
1359  }
1360  else
1361  {
1362  assert(false && "what else value can we have?");
1363  }
1364 
1365  pag->addToSVFStmtList(icfgNode,edge);
1366  icfgNode->addSVFStmt(edge);
1367  if(const CallPE* callPE = SVFUtil::dyn_cast<CallPE>(edge))
1368  {
1369  CallICFGNode* callNode = const_cast<CallICFGNode*>(callPE->getCallSite());
1370  FunEntryICFGNode* entryNode = const_cast<FunEntryICFGNode*>(callPE->getFunEntryICFGNode());
1371  if(ICFGEdge* edge = pag->getICFG()->hasInterICFGEdge(callNode,entryNode, ICFGEdge::CallCF))
1372  SVFUtil::cast<CallCFGEdge>(edge)->addCallPE(callPE);
1373  }
1374  else if(const RetPE* retPE = SVFUtil::dyn_cast<RetPE>(edge))
1375  {
1376  RetICFGNode* retNode = const_cast<RetICFGNode*>(retPE->getCallSite()->getRetICFGNode());
1377  FunExitICFGNode* exitNode = const_cast<FunExitICFGNode*>(retPE->getFunExitICFGNode());
1378  if(ICFGEdge* edge = pag->getICFG()->hasInterICFGEdge(exitNode, retNode, ICFGEdge::RetCF))
1379  SVFUtil::cast<RetCFGEdge>(edge)->addRetPE(retPE);
1380  }
1381 }
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
NodeType * getDstNode() const
Definition: GenericGraph.h:101
void addSVFStmt(const SVFStmt *edge)
Definition: ICFGNode.h:112
ICFGEdge * hasInterICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Definition: ICFG.cpp:268
GlobalICFGNode * getGlobalICFGNode() const
Definition: ICFG.h:236
void mapValueToEdge(const SVFValue *V, SVFStmt *edge)
Map a value to a set of edges.
Definition: IRGraph.h:89
RetICFGNode * getRetICFGNode(const Instruction *cs)
get a return node
const Value * getLLVMValue(const SVFValue *value) const
Definition: LLVMModule.h:216
const ICFGNode * front() const
Definition: SVFValue.h:594
const SVFFunction * getParent() const
Definition: SVFValue.h:584
const SVFBasicBlock * getEntryBlock() const
Definition: SVFValue.h:409
void addToSVFStmtList(ICFGNode *inst, SVFStmt *edge)
Add a SVFStmt into instruction map.
Definition: SVFIR.h:231
void addGlobalPAGEdge(const SVFStmt *edge)
Add global PAGEdges (not in a procedure)
Definition: SVFIR.h:641
void setBB(const SVFBasicBlock *bb)
void setValue(const SVFValue *val)

◆ setCurrentLocation() [1/2]

void SVF::SVFIRBuilder::setCurrentLocation ( const SVFValue val,
const SVFBasicBlock bb 
)
inlineprotected

Definition at line 246 of file SVFIRBuilder.h.

247  {
248  curBB = bb;
249  curVal = val;
250  }

◆ setCurrentLocation() [2/2]

void SVF::SVFIRBuilder::setCurrentLocation ( const Value val,
const BasicBlock bb 
)
inlineprotected

Set current basic block in order to keep track of control flow information.

Definition at line 241 of file SVFIRBuilder.h.

242  {
243  curBB = (bb == nullptr? nullptr : llvmModuleSet()->getSVFBasicBlock(bb));
244  curVal = (val == nullptr ? nullptr: llvmModuleSet()->getSVFValue(val));
245  }
SVFBasicBlock * getSVFBasicBlock(const BasicBlock *bb) const
Definition: LLVMModule.h:237

◆ updateCallGraph()

void SVFIRBuilder::updateCallGraph ( PTACallGraph callgraph)

connect PAG edges based on callgraph

Definition at line 1192 of file SVFIRBuilder.cpp.

1193 {
1194  PTACallGraph::CallEdgeMap::const_iterator iter = callgraph->getIndCallMap().begin();
1195  PTACallGraph::CallEdgeMap::const_iterator eiter = callgraph->getIndCallMap().end();
1196  for (; iter != eiter; iter++)
1197  {
1198  const CallICFGNode* callBlock = iter->first;
1199  const CallBase* callbase = SVFUtil::cast<CallBase>(llvmModuleSet()->getLLVMValue(callBlock));
1200  assert(callBlock->isIndirectCall() && "this is not an indirect call?");
1201  const PTACallGraph::FunctionSet& functions = iter->second;
1202  for (PTACallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
1203  {
1204  const Function* callee = SVFUtil::cast<Function>(llvmModuleSet()->getLLVMValue(*func_iter));
1205 
1206  if (isExtCall(*func_iter))
1207  {
1208  setCurrentLocation(callee, callee->empty() ? nullptr : &callee->getEntryBlock());
1209  const SVFFunction* svfcallee = llvmModuleSet()->getSVFFunction(callee);
1210  handleExtCall(callbase, svfcallee);
1211  }
1212  else
1213  {
1214  setCurrentLocation(llvmModuleSet()->getSVFValue(llvmModuleSet()->getLLVMValue(callBlock)), callBlock->getBB());
1215  handleDirectCall(const_cast<CallBase*>(callbase), callee);
1216  }
1217  }
1218  }
1219 
1220  // dump SVFIR
1221  if (Options::PAGDotGraph())
1222  pag->dump("svfir_final");
1223 }
bool isIndirectCall() const
Return true if this is an indirect call.
Definition: ICFGNode.h:482
virtual const SVFBasicBlock * getBB() const
Return the basic block of this ICFGNode.
Definition: ICFGNode.h:82
Set< const SVFFunction * > FunctionSet
Definition: PTACallGraph.h:251
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Definition: PTACallGraph.h:304
void handleDirectCall(CallBase *cs, const Function *F)
Handle direct call.
virtual void handleExtCall(const CallBase *cs, const SVFFunction *svfCallee)
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278
llvm::CallBase CallBase
Definition: BasicTypes.h:146

◆ visitAllocaInst()

void SVFIRBuilder::visitAllocaInst ( AllocaInst inst)
virtual

Our visit overrides.

Visit alloca instructions Add edge V (dst) <– O (src), V here is a value node on SVFIR, O is object node on SVFIR

Definition at line 662 of file SVFIRBuilder.cpp.

663 {
664 
665  // AllocaInst should always be a pointer type
666  assert(SVFUtil::isa<PointerType>(inst.getType()));
667 
668  DBOUT(DPAGBuild, outs() << "process alloca " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
669  NodeID dst = getValueNode(&inst);
670 
671  NodeID src = getObjectNode(&inst);
672 
673  addAddrWithStackArraySz(src, dst, inst);
674 
675 }
NodeID getObjectNode(const Value *V)
GetObject - Return the object node (stack/global/heap/function) according to a LLVM Value.
Definition: SVFIRBuilder.h:98
AddrStmt * addAddrWithStackArraySz(NodeID src, NodeID dst, llvm::AllocaInst &inst)
Add Address edge from allocinst with arraysize like "%4 = alloca i8, i64 3".
Definition: SVFIRBuilder.h:303

◆ visitAtomicCmpXchgInst()

void SVF::SVFIRBuilder::visitAtomicCmpXchgInst ( AtomicCmpXchgInst I)
inline

Definition at line 186 of file SVFIRBuilder.h.

187  {
189  }

◆ visitAtomicRMWInst()

void SVF::SVFIRBuilder::visitAtomicRMWInst ( AtomicRMWInst I)
inline

Definition at line 190 of file SVFIRBuilder.h.

191  {
193  }

◆ visitBinaryOperator()

void SVFIRBuilder::visitBinaryOperator ( BinaryOperator inst)

Visit Binary Operator

Definition at line 777 of file SVFIRBuilder.cpp.

778 {
779  NodeID dst = getValueNode(&inst);
780  assert(inst.getNumOperands() == 2 && "not two operands for BinaryOperator?");
781  Value* op1 = inst.getOperand(0);
782  NodeID op1Node = getValueNode(op1);
783  Value* op2 = inst.getOperand(1);
784  NodeID op2Node = getValueNode(op2);
785  u32_t opcode = inst.getOpcode();
786  addBinaryOPEdge(op1Node, op2Node, dst, opcode);
787 }
void addBinaryOPEdge(NodeID op1, NodeID op2, NodeID dst, u32_t opcode)
Add Copy edge.
Definition: SVFIRBuilder.h:427

◆ visitBranchInst()

void SVFIRBuilder::visitBranchInst ( BranchInst inst)

Branch and switch instructions are treated as UnaryOP br cmp label if.then, label if.else

set conditional svf var

Definition at line 955 of file SVFIRBuilder.cpp.

956 {
957  NodeID brinst = getValueNode(&inst);
958  NodeID cond;
959  if (inst.isConditional())
960  cond = getValueNode(inst.getCondition());
961  else
962  cond = pag->getNullPtr();
963 
964  assert(inst.getNumSuccessors() <= 2 && "if/else has more than two branches?");
965 
967  std::vector<const Instruction*> nextInsts;
968  LLVMUtil::getNextInsts(&inst, nextInsts);
969  u32_t branchID = 0;
970  for (const Instruction* succInst : nextInsts)
971  {
972  assert(branchID <= 1 && "if/else has more than two branches?");
973  const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
974  successors.push_back(std::make_pair(icfgNode, 1-branchID));
975  branchID++;
976  }
977  addBranchStmt(brinst, cond, successors);
979  if (inst.isConditional())
980  {
981  for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
982  {
983  if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
984  {
985  intraEdge->setConditionVar(pag->getGNode(cond));
986  }
987  }
988  }
989 }
std::vector< std::pair< const ICFGNode *, s32_t > > SuccAndCondPairVec
void addBranchStmt(NodeID br, NodeID cond, const BranchStmt::SuccAndCondPairVec &succs)
Add Branch statement.
Definition: SVFIRBuilder.h:439
void getNextInsts(const Instruction *curInst, std::vector< const Instruction * > &instList)
Get the next instructions following control flow.
Definition: LLVMUtil.cpp:551

◆ visitCallBrInst()

void SVFIRBuilder::visitCallBrInst ( CallBrInst I)

Definition at line 844 of file SVFIRBuilder.cpp.

845 {
846  visitCallSite(&i);
847 }
void visitCallSite(CallBase *cs)

◆ visitCallInst()

void SVFIRBuilder::visitCallInst ( CallInst I)

Definition at line 834 of file SVFIRBuilder.cpp.

835 {
836  visitCallSite(&i);
837 }

◆ visitCallSite()

void SVFIRBuilder::visitCallSite ( CallBase cs)

Collect callsite arguments and returns

Definition at line 852 of file SVFIRBuilder.cpp.

853 {
854 
855  // skip llvm intrinsics
856  if(isIntrinsicInst(cs))
857  return;
858 
860  outs() << "process callsite " << svfcall->valueOnlyToString() << "\n");
861 
862 
863  CallICFGNode* callBlockNode = llvmModuleSet()->getCallICFGNode(cs);
864  RetICFGNode* retBlockNode = llvmModuleSet()->getRetICFGNode(cs);
865 
866  pag->addCallSite(callBlockNode);
867 
869  for (u32_t i = 0; i < cs->arg_size(); i++)
870  pag->addCallSiteArgs(callBlockNode,pag->getGNode(getValueNode(cs->getArgOperand(i))));
871 
872  if(!cs->getType()->isVoidTy())
873  pag->addCallSiteRets(retBlockNode,pag->getGNode(getValueNode(cs)));
874 
875  if (callBlockNode->isVirtualCall())
876  {
877  const Value* value = cppUtil::getVCallVtblPtr(cs);
878  callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
879  }
880  if (const Function *callee = LLVMUtil::getCallee(cs))
881  {
882  const SVFFunction* svfcallee = llvmModuleSet()->getSVFFunction(callee);
883  if (isExtCall(svfcallee))
884  {
885  handleExtCall(cs, svfcallee);
886  }
887  else
888  {
889  handleDirectCall(cs, callee);
890  }
891  }
892  else
893  {
894  //If the callee was not identified as a function (null F), this is indirect.
895  handleIndCall(cs);
896  }
897 }
bool isVirtualCall() const
Definition: ICFGNode.h:527
void setVtablePtr(SVFVar *v)
Definition: ICFGNode.h:532
void handleIndCall(CallBase *cs)
Handle indirect call.
void addCallSiteArgs(CallICFGNode *callBlockNode, const SVFVar *arg)
Add callsite arguments.
Definition: SVFIR.h:524
void addCallSiteRets(RetICFGNode *retBlockNode, const SVFVar *arg)
Add callsite returns.
Definition: SVFIR.h:530
void addCallSite(const CallICFGNode *call)
Add callsites.
Definition: SVFIR.h:646
bool isIntrinsicInst(const Instruction *inst)
Return true if it is an intrinsic instruction.
Definition: LLVMUtil.cpp:204
const Function * getCallee(const CallBase *cs)
Definition: LLVMUtil.h:63
const Value * getVCallVtblPtr(const CallBase *cs)
Definition: CppUtil.cpp:537

◆ visitCastInst()

void SVFIRBuilder::visitCastInst ( CastInst I)

Definition at line 763 of file SVFIRBuilder.cpp.

764 {
765 
766  DBOUT(DPAGBuild, outs() << "process cast " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
767  NodeID dst = getValueNode(&inst);
768 
769  const Value* opnd = inst.getOperand(0);
770  NodeID src = getValueNode(opnd);
771  addCopyEdge(src, dst, getCopyKind(&inst));
772 }
CopyStmt::CopyKind getCopyKind(const Value *val)
Definition: SVFIRBuilder.h:371

◆ visitCmpInst()

void SVFIRBuilder::visitCmpInst ( CmpInst inst)

Visit compare instruction

Definition at line 805 of file SVFIRBuilder.cpp.

806 {
807  NodeID dst = getValueNode(&inst);
808  assert(inst.getNumOperands() == 2 && "not two operands for compare instruction?");
809  Value* op1 = inst.getOperand(0);
810  NodeID op1Node = getValueNode(op1);
811  Value* op2 = inst.getOperand(1);
812  NodeID op2Node = getValueNode(op2);
813  u32_t predicate = inst.getPredicate();
814  addCmpEdge(op1Node, op2Node, dst, predicate);
815 }
void addCmpEdge(NodeID op1, NodeID op2, NodeID dst, u32_t predict)
Add Copy edge.
Definition: SVFIRBuilder.h:421

◆ visitExtractElementInst()

void SVFIRBuilder::visitExtractElementInst ( ExtractElementInst inst)

The �extractelement� instruction extracts a single scalar element from a vector at a specified index. TODO: for now we just assume the pointer after extraction points to blackhole The first operand of an �extractelement� instruction is a value of vector type. The second operand is an index indicating the position from which to extract the element.

<result> = extractelement <4 x i32> vec, i32 0 ; yields i32

Definition at line 945 of file SVFIRBuilder.cpp.

946 {
947  NodeID dst = getValueNode(&inst);
949 }

◆ visitExtractValueInst()

void SVFIRBuilder::visitExtractValueInst ( ExtractValueInst inst)

visit extract value instructions for structures in registers TODO: for now we just assume the pointer after extraction points to blackhole for example %24 = extractvalue { i32, struct.s_hash* } call34, 0 %24 is a pointer points to first field of a register value call34 however we can not create call34 as an memory object, as it is register value. Is that necessary treat extract value as getelementptr instruction later to get more precise results?

Definition at line 931 of file SVFIRBuilder.cpp.

932 {
933  NodeID dst = getValueNode(&inst);
935 }

◆ visitFenceInst()

void SVF::SVFIRBuilder::visitFenceInst ( FenceInst I)
inline

Definition at line 182 of file SVFIRBuilder.h.

183  {
185  }

◆ visitFreezeInst()

void SVFIRBuilder::visitFreezeInst ( FreezeInst inst)

<result> = freeze ty <val> If <val> is undef or poison, ‘freeze’ returns an arbitrary, but fixed value of type ty Otherwise, this instruction is a no-op and returns the input <val>

<result> = freeze ty <val> If <val> is undef or poison, ‘freeze’ returns an arbitrary, but fixed value of type ty Otherwise, this instruction is a no-op and returns the input <val> For now, we assume <val> is never a poison or undef.

Definition at line 1085 of file SVFIRBuilder.cpp.

1086 {
1087  NodeID dst = getValueNode(&inst);
1088  for (u32_t i = 0; i < inst.getNumOperands(); i++)
1089  {
1090  Value* opnd = inst.getOperand(i);
1091  NodeID src = getValueNode(opnd);
1092  addCopyEdge(src, dst, CopyStmt::COPYVAL);
1093  }
1094 }

◆ visitGetElementPtrInst()

void SVFIRBuilder::visitGetElementPtrInst ( GetElementPtrInst inst)

Visit getelementptr instructions

Definition at line 737 of file SVFIRBuilder.cpp.

738 {
739 
740  NodeID dst = getValueNode(&inst);
741  // GetElementPtrInst should always be a pointer or a vector contains pointers
742  // for now we don't handle vector type here
743  if(SVFUtil::isa<VectorType>(inst.getType()))
744  {
746  return;
747  }
748 
749  assert(SVFUtil::isa<PointerType>(inst.getType()));
750 
751  DBOUT(DPAGBuild, outs() << "process gep " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
752 
753  NodeID src = getValueNode(inst.getPointerOperand());
754 
755  AccessPath ap(0, llvmModuleSet()->getSVFType(inst.getSourceElementType()));
756  bool constGep = computeGepOffset(&inst, ap);
757  addGepEdge(src, dst, ap, constGep);
758 }

◆ visitGlobal()

void SVFIRBuilder::visitGlobal ( SVFModule svfModule)
protected

Handle globals including (global variable and functions)

Visit global variables for building SVFIR

initialize global variable

initialize global functions

Definition at line 609 of file SVFIRBuilder.cpp.

610 {
611 
613  for (Module &M : llvmModuleSet()->getLLVMModules())
614  {
615  for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
616  {
617  GlobalVariable *gvar = &*I;
618  NodeID idx = getValueNode(gvar);
619  NodeID obj = getObjectNode(gvar);
620 
621  setCurrentLocation(gvar, nullptr);
622  addAddrEdge(obj, idx);
623 
624  if (gvar->hasInitializer())
625  {
626  Constant *C = gvar->getInitializer();
627  DBOUT(DPAGBuild, outs() << "add global var node " << llvmModuleSet()->getSVFValue(gvar)->toString() << "\n");
628  InitialGlobal(gvar, C, 0);
629  }
630  }
631 
632 
634  for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
635  {
636  const Function* fun = &*I;
637  NodeID idx = getValueNode(fun);
638  NodeID obj = getObjectNode(fun);
639 
640  DBOUT(DPAGBuild, outs() << "add global function node " << fun->getName().str() << "\n");
641  setCurrentLocation(fun, nullptr);
642  addAddrEdge(obj, idx);
643  }
644 
645  // Handle global aliases (due to linkage of multiple bc files), e.g., @x = internal alias @y. We need to add a copy from y to x.
646  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; I++)
647  {
648  const GlobalAlias* alias = &*I;
649  NodeID dst = pag->getValueNode(llvmModuleSet()->getSVFValue(alias));
650  NodeID src = pag->getValueNode(llvmModuleSet()->getSVFValue(alias->getAliasee()));
651  processCE(alias->getAliasee());
652  setCurrentLocation(alias, nullptr);
653  addCopyEdge(src, dst, CopyStmt::COPYVAL);
654  }
655  }
656 }
llvm::GlobalVariable GlobalVariable
Definition: BasicTypes.h:130
llvm::GlobalAlias GlobalAlias
Definition: BasicTypes.h:128

◆ visitInsertElementInst()

void SVF::SVFIRBuilder::visitInsertElementInst ( InsertElementInst I)
inline

Definition at line 162 of file SVFIRBuilder.h.

163  {
165  }

◆ visitInsertValueInst()

void SVF::SVFIRBuilder::visitInsertValueInst ( InsertValueInst I)
inline

Definition at line 136 of file SVFIRBuilder.h.

137  {
139  }

◆ visitInstruction()

void SVF::SVFIRBuilder::visitInstruction ( Instruction )
inline

Provide base case for our instruction visit.

Definition at line 196 of file SVFIRBuilder.h.

197  {
198  // If a new instruction is added to LLVM that we don't handle.
199  // TODO: ignore here:
200  }

◆ visitInvokeInst()

void SVFIRBuilder::visitInvokeInst ( InvokeInst II)

Definition at line 839 of file SVFIRBuilder.cpp.

840 {
841  visitCallSite(&i);
842 }

◆ visitLandingPadInst()

void SVF::SVFIRBuilder::visitLandingPadInst ( LandingPadInst I)
inline

Definition at line 170 of file SVFIRBuilder.h.

171  {
173  }

◆ visitLoadInst()

void SVFIRBuilder::visitLoadInst ( LoadInst I)

Definition at line 705 of file SVFIRBuilder.cpp.

706 {
707  DBOUT(DPAGBuild, outs() << "process load " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
708 
709  NodeID dst = getValueNode(&inst);
710 
711  NodeID src = getValueNode(inst.getPointerOperand());
712 
713  addLoadEdge(src, dst);
714 }

◆ visitPHINode()

void SVFIRBuilder::visitPHINode ( PHINode inst)

Visit phi instructions

Definition at line 680 of file SVFIRBuilder.cpp.

681 {
682 
683  DBOUT(DPAGBuild, outs() << "process phi " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
684 
685  NodeID dst = getValueNode(&inst);
686 
687  for (u32_t i = 0; i < inst.getNumIncomingValues(); ++i)
688  {
689  const Value* val = inst.getIncomingValue(i);
690  const Instruction* incomingInst = SVFUtil::dyn_cast<Instruction>(val);
691  bool matched = (incomingInst == nullptr ||
692  incomingInst->getFunction() == inst.getFunction());
693  (void) matched; // Suppress warning of unused variable under release build
694  assert(matched && "incomingInst's Function incorrect");
695  const Instruction* predInst = &inst.getIncomingBlock(i)->back();
696  const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(predInst);
697  NodeID src = getValueNode(val);
698  addPhiStmt(dst,src,icfgNode);
699  }
700 }
void addPhiStmt(NodeID res, NodeID opnd, const ICFGNode *pred)
Add Copy edge.
Definition: SVFIRBuilder.h:408

◆ visitResumeInst()

void SVF::SVFIRBuilder::visitResumeInst ( ResumeInst )
inline

Instruction not that often.

Definition at line 176 of file SVFIRBuilder.h.

177  {
178  }

◆ visitReturnInst()

void SVFIRBuilder::visitReturnInst ( ReturnInst inst)

Visit return instructions of a function

Definition at line 902 of file SVFIRBuilder.cpp.

903 {
904 
905  // ReturnInst itself should always not be a pointer type
906  assert(!SVFUtil::isa<PointerType>(inst.getType()));
907 
908  DBOUT(DPAGBuild, outs() << "process return " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
909 
910  if(Value* src = inst.getReturnValue())
911  {
912  const SVFFunction *F = llvmModuleSet()->getSVFFunction(inst.getParent()->getParent());
913 
914  NodeID rnF = getReturnNode(F);
915  NodeID vnS = getValueNode(src);
916  const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(&inst);
917  //vnS may be null if src is a null ptr
918  addPhiStmt(rnF,vnS,icfgNode);
919  }
920 }

◆ visitSelectInst()

void SVFIRBuilder::visitSelectInst ( SelectInst inst)

Visit select instructions

Two operands have same incoming basic block, both are the current BB

Definition at line 821 of file SVFIRBuilder.cpp.

822 {
823 
824  DBOUT(DPAGBuild, outs() << "process select " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
825 
826  NodeID dst = getValueNode(&inst);
827  NodeID src1 = getValueNode(inst.getTrueValue());
828  NodeID src2 = getValueNode(inst.getFalseValue());
829  NodeID cond = getValueNode(inst.getCondition());
831  addSelectStmt(dst,src1,src2, cond);
832 }

◆ visitShuffleVectorInst()

void SVF::SVFIRBuilder::visitShuffleVectorInst ( ShuffleVectorInst I)
inline

Definition at line 166 of file SVFIRBuilder.h.

167  {
169  }

◆ visitStoreInst()

void SVFIRBuilder::visitStoreInst ( StoreInst inst)

Visit store instructions

Definition at line 719 of file SVFIRBuilder.cpp.

720 {
721  // StoreInst itself should always not be a pointer type
722  assert(!SVFUtil::isa<PointerType>(inst.getType()));
723 
724  DBOUT(DPAGBuild, outs() << "process store " << llvmModuleSet()->getSVFValue(&inst)->toString() << " \n");
725 
726  NodeID dst = getValueNode(inst.getPointerOperand());
727 
728  NodeID src = getValueNode(inst.getValueOperand());
729 
730  addStoreEdge(src, dst);
731 
732 }

◆ visitSwitchInst()

void SVFIRBuilder::visitSwitchInst ( SwitchInst inst)

The following implementation follows ICFGBuilder::processFunBody.

See more: https://github.com/SVF-tools/SVF/pull/1191

Given the code:

switch (a) { case 0: printf("0\n"); break; case 1: case 2: case 3: printf("a >=1 && a <= 3\n"); break; case 4: case 6: case 7: printf("a >= 4 && a <=7\n"); break; default: printf("a < 0 || a > 7"); break; }

Generate the IR:

switch i32 %0, label sw.default [ i32 0, label sw.bb i32 1, label sw.bb1 i32 2, label sw.bb1 i32 3, label sw.bb1 i32 4, label sw.bb3 i32 6, label sw.bb3 i32 7, label sw.bb3 ]

We can get every case basic block and related case value: [ {sw.default, -1}, {sw.bb, 0}, {sw.bb1, 1}, {sw.bb1, 2}, {sw.bb1, 3}, {sw.bb3, 4}, {sw.bb3, 6}, {sw.bb3, 7}, ] Note: default case value is nullptr For larger number, we preserve case value just -1 now see more: https://github.com/SVF-tools/SVF/pull/992

branch condition value

default case is set to -1;

set conditional svf var

Definition at line 1037 of file SVFIRBuilder.cpp.

1038 {
1039  NodeID brinst = getValueNode(&inst);
1040  NodeID cond = getValueNode(inst.getCondition());
1041 
1042  BranchStmt::SuccAndCondPairVec successors;
1043  std::vector<const Instruction*> nextInsts;
1044  LLVMUtil::getNextInsts(&inst, nextInsts);
1045  for (const Instruction* succInst : nextInsts)
1046  {
1048  const ConstantInt* condVal = inst.findCaseDest(const_cast<BasicBlock*>(succInst->getParent()));
1050  s64_t val = -1;
1051  if (condVal && condVal->getBitWidth() <= 64)
1052  val = condVal->getSExtValue();
1053  const ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(succInst);
1054  successors.push_back(std::make_pair(icfgNode, val));
1055  }
1056  addBranchStmt(brinst, cond, successors);
1058  for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1059  {
1060  if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1061  {
1062  intraEdge->setConditionVar(pag->getGNode(cond));
1063  }
1064  }
1065 }
signed long long s64_t
Definition: GeneralType.h:49

◆ visitUnaryOperator()

void SVFIRBuilder::visitUnaryOperator ( UnaryOperator inst)

Visit Unary Operator

Definition at line 792 of file SVFIRBuilder.cpp.

793 {
794  NodeID dst = getValueNode(&inst);
795  assert(inst.getNumOperands() == 1 && "not one operand for Unary instruction?");
796  Value* opnd = inst.getOperand(0);
797  NodeID src = getValueNode(opnd);
798  u32_t opcode = inst.getOpcode();
799  addUnaryOPEdge(src, dst, opcode);
800 }
void addUnaryOPEdge(NodeID src, NodeID dst, u32_t opcode)
Add Unary edge.
Definition: SVFIRBuilder.h:433

◆ visitUnreachableInst()

void SVF::SVFIRBuilder::visitUnreachableInst ( UnreachableInst )
inline

Definition at line 179 of file SVFIRBuilder.h.

180  {
181  }

◆ visitVAArgInst()

void SVFIRBuilder::visitVAArgInst ( VAArgInst inst)

TODO: var arguments need to be handled. https://llvm.org/docs/LangRef.html#id1911

ap = alloca struct.va_list ap2 = bitcast struct.va_list* ap to i8* ; Read a single integer argument from ap2 tmp = va_arg i8* ap2, i32 (VAArgInst) TODO: for now, create a copy edge from ap2 to tmp, we assume here tmp should point to the n-th argument of the var_args

Definition at line 1073 of file SVFIRBuilder.cpp.

1074 {
1075  NodeID dst = getValueNode(&inst);
1076  Value* opnd = inst.getPointerOperand();
1077  NodeID src = getValueNode(opnd);
1078  addCopyEdge(src, dst, CopyStmt::COPYVAL);
1079 }

◆ visitVACopyInst()

void SVF::SVFIRBuilder::visitVACopyInst ( VACopyInst )
inline

Definition at line 151 of file SVFIRBuilder.h.

151 {}

◆ visitVAEndInst()

void SVF::SVFIRBuilder::visitVAEndInst ( VAEndInst )
inline

Definition at line 152 of file SVFIRBuilder.h.

152 {}

◆ visitVAStartInst()

void SVF::SVFIRBuilder::visitVAStartInst ( VAStartInst )
inline

Definition at line 153 of file SVFIRBuilder.h.

153 {}

Member Data Documentation

◆ curBB

const SVFBasicBlock* SVF::SVFIRBuilder::curBB
private

Current basic block during SVFIR construction when visiting the module.

Definition at line 52 of file SVFIRBuilder.h.

◆ curVal

const SVFValue* SVF::SVFIRBuilder::curVal
private

Current Value during SVFIR construction when visiting the module.

Definition at line 53 of file SVFIRBuilder.h.

◆ pag

SVFIR* SVF::SVFIRBuilder::pag
private

Definition at line 50 of file SVFIRBuilder.h.

◆ svfModule

SVFModule* SVF::SVFIRBuilder::svfModule
private

Definition at line 51 of file SVFIRBuilder.h.


The documentation for this class was generated from the following files: