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

#include <SaberSVFGBuilder.h>

Inheritance diagram for SVF::SaberSVFGBuilder:
SVF::SVFGBuilder SVF::CFLSVFGBuilder

Public Types

typedef Set< const SVFGNode * > SVFGNodeSet
 
typedef Map< NodeID, PointsToNodeToPTSSMap
 
typedef FIFOWorkList< NodeIDWorkList
 
- Public Types inherited from SVF::SVFGBuilder
typedef PointerAnalysis::CallSiteSet CallSiteSet
 
typedef PointerAnalysis::CallEdgeMap CallEdgeMap
 
typedef PointerAnalysis::FunctionSet FunctionSet
 
typedef SVFG::SVFGEdgeSetTy SVFGEdgeSet
 

Public Member Functions

 SaberSVFGBuilder ()
 Constructor. More...
 
virtual ~SaberSVFGBuilder ()
 Destructor. More...
 
bool isGlobalSVFGNode (const SVFGNode *node) const
 
void addActualParmVFGNode (const PAGNode *pagNode, const CallICFGNode *cs)
 Add ActualParmVFGNode. More...
 
void setSaberCondAllocator (SaberCondAllocator *allocator)
 
- Public Member Functions inherited from SVF::SVFGBuilder
 SVFGBuilder (bool _SVFGWithIndCall=false)
 Constructor. More...
 
virtual ~SVFGBuilder ()=default
 Destructor. More...
 
SVFGbuildPTROnlySVFG (BVDataPTAImpl *pta)
 
SVFGbuildFullSVFG (BVDataPTAImpl *pta)
 
SVFGgetSVFG () const
 Get SVFG instance. More...
 
void markValidVFEdge (SVFGEdgeSet &edges)
 Mark feasible VF edge by removing it from set vfEdgesAtIndCallSite. More...
 
bool isSpuriousVFEdgeAtIndCallSite (const SVFGEdge *edge)
 Return true if this is an VF Edge pre-connected by Andersen's analysis. More...
 
virtual std::unique_ptr< MemSSAbuildMSSA (BVDataPTAImpl *pta, bool ptrOnlyMSSA)
 Build Memory SSA. More...
 

Protected Member Functions

virtual void buildSVFG ()
 Re-write create SVFG method. More...
 
bool isStrongUpdate (const SVFGNode *node, NodeID &singleton, BVDataPTAImpl *pta)
 Return TRUE if this is a strong update STORE statement. More...
 
void rmDerefDirSVFGEdges (BVDataPTAImpl *pta)
 
virtual void rmIncomingEdgeForSUStore (BVDataPTAImpl *pta)
 
virtual void AddExtActualParmSVFGNodes (PTACallGraph *callgraph)
 Add actual parameter SVFGNode for 1st argument of a deallocation like external function. More...
 
void collectGlobals (BVDataPTAImpl *pta)
 
bool accessGlobal (BVDataPTAImpl *pta, const PAGNode *pagNode)
 Whether points-to of a PAGNode points-to global variable. More...
 
PointsToCollectPtsChain (BVDataPTAImpl *pta, NodeID id, NodeToPTSSMap &cachedPtsMap)
 Collect objects along points-to chains. More...
 
- Protected Member Functions inherited from SVF::SVFGBuilder
SVFGbuild (BVDataPTAImpl *pta, VFG::VFGK kind)
 Create a DDA SVFG. By default actualOut and FormalIN are removed, unless withAOFI is set true. More...
 
virtual void releaseMemory ()
 Release global SVFG. More...
 

Protected Attributes

PointsTo globs
 
SVFGNodeSet globSVFGNodes
 Store all global SVFG nodes. More...
 
SaberCondAllocatorsaberCondAllocator
 
- Protected Attributes inherited from SVF::SVFGBuilder
SVFGEdgeSet vfEdgesAtIndCallSite
 SVFG Edges connected at indirect call/ret sites. More...
 
std::unique_ptr< SVFGsvfg
 
bool SVFGWithIndCall
 SVFG with precomputed indirect call edges. More...
 

Detailed Description

Definition at line 43 of file SaberSVFGBuilder.h.

Member Typedef Documentation

◆ NodeToPTSSMap

Definition at line 48 of file SaberSVFGBuilder.h.

◆ SVFGNodeSet

Definition at line 47 of file SaberSVFGBuilder.h.

◆ WorkList

Definition at line 49 of file SaberSVFGBuilder.h.

Constructor & Destructor Documentation

◆ SaberSVFGBuilder()

SVF::SaberSVFGBuilder::SaberSVFGBuilder ( )
inline

Constructor.

Definition at line 52 of file SaberSVFGBuilder.h.

52 : SVFGBuilder(true) {}
SVFGBuilder(bool _SVFGWithIndCall=false)
Constructor.
Definition: SVFGBuilder.h:52

◆ ~SaberSVFGBuilder()

virtual SVF::SaberSVFGBuilder::~SaberSVFGBuilder ( )
inlinevirtual

Destructor.

Definition at line 55 of file SaberSVFGBuilder.h.

55 {}

Member Function Documentation

◆ accessGlobal()

bool SaberSVFGBuilder::accessGlobal ( BVDataPTAImpl pta,
const PAGNode pagNode 
)
protected

Whether points-to of a PAGNode points-to global variable.

Decide whether the node and its points-to contains a global objects

Definition at line 170 of file SaberSVFGBuilder.cpp.

171 {
172 
173  NodeID id = pagNode->getId();
174  PointsTo pts = pta->getPts(id);
175  pts.set(id);
176 
177  return pts.intersects(globs);
178 }
const PointsTo & getPts(NodeID id) override
void set(u32_t n)
Inserts n in the set.
Definition: PointsTo.cpp:157
bool intersects(const PointsTo &rhs) const
Returns true if this set and rhs share any elements.
Definition: PointsTo.cpp:189
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
u32_t NodeID
Definition: GeneralType.h:55

◆ addActualParmVFGNode()

void SVF::SaberSVFGBuilder::addActualParmVFGNode ( const PAGNode pagNode,
const CallICFGNode cs 
)
inline

Add ActualParmVFGNode.

Definition at line 63 of file SaberSVFGBuilder.h.

64  {
65  svfg->addActualParmVFGNode(pagNode, cs);
66  }
std::unique_ptr< SVFG > svfg
Definition: SVFGBuilder.h:91

◆ AddExtActualParmSVFGNodes()

void SaberSVFGBuilder::AddExtActualParmSVFGNodes ( PTACallGraph callgraph)
protectedvirtual

Add actual parameter SVFGNode for 1st argument of a deallocation like external function.

Add actual parameter SVFGNode for 1st argument of a deallocation like external function In order to path sensitive leak detection

Definition at line 294 of file SaberSVFGBuilder.cpp.

295 {
296  SVFIR* pag = SVFIR::getPAG();
297  for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(),
298  eit = pag->getCallSiteArgsMap().end(); it!=eit; ++it)
299  {
301  callgraph->getCallees(it->first, callees);
302  for (PTACallGraph::FunctionSet::const_iterator cit = callees.begin(),
303  ecit = callees.end(); cit != ecit; cit++)
304  {
305 
306  const SVFFunction* fun = *cit;
307  if (SaberCheckerAPI::getCheckerAPI()->isMemDealloc(fun)
308  || SaberCheckerAPI::getCheckerAPI()->isFClose(fun))
309  {
310  SVFIR::SVFVarList& arglist = it->second;
311  for(SVFIR::SVFVarList::const_iterator ait = arglist.begin(), aeit = arglist.end(); ait!=aeit; ++ait)
312  {
313  const PAGNode *pagNode = *ait;
314  if (pagNode->isPointer())
315  {
316  addActualParmVFGNode(pagNode, it->first);
317  svfg->addIntraDirectVFEdge(svfg->getDefSVFGNode(pagNode)->getId(), svfg->getActualParmVFGNode(pagNode, it->first)->getId());
318  }
319  }
320  }
321  }
322  }
323 }
void getCallees(const CallICFGNode *cs, FunctionSet &callees)
Get all callees for a callsite.
Definition: PTACallGraph.h:408
Set< const SVFFunction * > FunctionSet
Definition: PTACallGraph.h:251
CSToArgsListMap & getCallSiteArgsMap()
Get callsite argument list.
Definition: SVFIR.h:287
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
std::vector< const SVFVar * > SVFVarList
Definition: SVFIR.h:59
virtual bool isPointer() const
Whether it is a pointer.
Definition: SVFVariables.h:106
static SaberCheckerAPI * getCheckerAPI()
Return a static reference.
void addActualParmVFGNode(const PAGNode *pagNode, const CallICFGNode *cs)
Add ActualParmVFGNode.

◆ buildSVFG()

void SaberSVFGBuilder::buildSVFG ( )
protectedvirtual

Re-write create SVFG method.

Reimplemented from SVF::SVFGBuilder.

Reimplemented in SVF::CFLSVFGBuilder.

Definition at line 41 of file SaberSVFGBuilder.cpp.

42 {
43 
44  MemSSA* mssa = svfg->getMSSA();
45  svfg->buildSVFG();
46  BVDataPTAImpl* pta = mssa->getPTA();
47  DBOUT(DGENERAL, outs() << pasMsg("\tCollect Global Variables\n"));
48 
49  collectGlobals(pta);
50 
51  DBOUT(DGENERAL, outs() << pasMsg("\tRemove Dereference Direct SVFG Edge\n"));
52 
54 
55  assert(saberCondAllocator && "saber condition allocator not set yet!");
57 
58  DBOUT(DGENERAL, outs() << pasMsg("\tAdd Sink SVFG Nodes\n"));
59 
61 
62  if(pta->printStat())
63  svfg->performStat();
64 }
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DGENERAL
Definition: SVFType.h:490
BVDataPTAImpl * getPTA() const
Return PTA.
Definition: MemSSA.h:308
bool printStat()
Whether print statistics.
PTACallGraph * getCallGraph() const
Return call graph.
void collectGlobals(BVDataPTAImpl *pta)
virtual void AddExtActualParmSVFGNodes(PTACallGraph *callgraph)
Add actual parameter SVFGNode for 1st argument of a deallocation like external function.
SaberCondAllocator * saberCondAllocator
void rmDerefDirSVFGEdges(BVDataPTAImpl *pta)
virtual void rmIncomingEdgeForSUStore(BVDataPTAImpl *pta)
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

◆ collectGlobals()

void SaberSVFGBuilder::collectGlobals ( BVDataPTAImpl pta)
protected

Collect memory pointed global pointers, note that this collection is recursively performed, for example gp-->obj-->obj' obj and obj' are both considered global memory

Recursively collect global memory objects

Definition at line 70 of file SaberSVFGBuilder.cpp.

71 {
72  SVFIR* pag = svfg->getPAG();
73  NodeVector worklist;
74  for(SVFIR::iterator it = pag->begin(), eit = pag->end(); it!=eit; it++)
75  {
76  PAGNode* pagNode = it->second;
77  if (SVFUtil::isa<DummyValVar, DummyObjVar>(pagNode))
78  continue;
79 
80  if(GepObjVar* gepobj = SVFUtil::dyn_cast<GepObjVar>(pagNode))
81  {
82  if(SVFUtil::isa<DummyObjVar>(pag->getGNode(gepobj->getBaseNode())))
83  continue;
84  }
85  if(const SVFValue* val = pagNode->getValue())
86  {
87  if(SVFUtil::isa<SVFGlobalValue>(val))
88  worklist.push_back(it->first);
89  }
90  }
91 
92  NodeToPTSSMap cachedPtsMap;
93  while(!worklist.empty())
94  {
95  NodeID id = worklist.back();
96  worklist.pop_back();
97  globs.set(id);
98  const PointsTo& pts = pta->getPts(id);
99  for(PointsTo::iterator it = pts.begin(), eit = pts.end(); it!=eit; ++it)
100  {
101  globs |= CollectPtsChain(pta,*it,cachedPtsMap);
102  }
103  }
104 }
iterator begin()
Iterators.
Definition: GenericGraph.h:627
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
IDToNodeMapTy::iterator iterator
Node Iterators.
Definition: GenericGraph.h:606
const_iterator end() const
Definition: PointsTo.h:132
const_iterator begin() const
Definition: PointsTo.h:128
const SVFValue * getValue() const
Get/has methods of the components.
Definition: SVFVariables.h:83
PointsTo & CollectPtsChain(BVDataPTAImpl *pta, NodeID id, NodeToPTSSMap &cachedPtsMap)
Collect objects along points-to chains.
Map< NodeID, PointsTo > NodeToPTSSMap
std::vector< NodeID > NodeVector
Definition: GeneralType.h:116

◆ CollectPtsChain()

PointsTo & SaberSVFGBuilder::CollectPtsChain ( BVDataPTAImpl pta,
NodeID  id,
NodeToPTSSMap cachedPtsMap 
)
protected

Collect objects along points-to chains.

Definition at line 122 of file SaberSVFGBuilder.cpp.

123 {
124  SVFIR* pag = svfg->getPAG();
125 
126  NodeID baseId = pag->getBaseObjVar(id);
127  NodeToPTSSMap::iterator it = cachedPtsMap.find(baseId);
128  if(it!=cachedPtsMap.end())
129  {
130  return it->second;
131  }
132  else
133  {
134  PointsTo& pts = cachedPtsMap[baseId];
135  // base object
137  {
138  if(pta->isFIObjNode(baseId) && pag->getGNode(baseId)->hasValue())
139  {
140  ValVar* valVar = SVFUtil::dyn_cast<ValVar>(pag->getGNode(baseId));
141  if(valVar && valVar->getGNode() && SVFUtil::isExtCall(SVFUtil::cast<ICFGNode>(valVar->getGNode())))
142  {
143  return pts;
144  }
145  }
146  }
147 
148  pts |= pag->getFieldsAfterCollapse(baseId);
149 
150  WorkList worklist;
151  for(PointsTo::iterator it = pts.begin(), eit = pts.end(); it!=eit; ++it)
152  worklist.push(*it);
153 
154  while(!worklist.empty())
155  {
156  NodeID nodeId = worklist.pop();
157  const PointsTo& tmp = pta->getPts(nodeId);
158  for(PointsTo::iterator it = tmp.begin(), eit = tmp.end(); it!=eit; ++it)
159  {
160  pts |= CollectPtsChain(pta,*it,cachedPtsMap);
161  }
162  }
163  return pts;
164  }
165 }
bool push(const Data &data)
Definition: WorkList.h:165
static const Option< bool > CollectExtRetGlobals
Definition: Options.h:202
bool isFIObjNode(NodeID id) const
NodeBS getFieldsAfterCollapse(NodeID id)
Definition: SVFIR.cpp:499
NodeID getBaseObjVar(NodeID id) const
Base and Offset methods for Value and Object node.
Definition: SVFIR.h:455
bool hasValue() const
Definition: SVFVariables.h:101
FIFOWorkList< NodeID > WorkList
const SVFBaseNode * getGNode() const
Definition: SVFVariables.h:311
bool isExtCall(const SVFFunction *fun)
Definition: SVFUtil.h:278

◆ isGlobalSVFGNode()

bool SVF::SaberSVFGBuilder::isGlobalSVFGNode ( const SVFGNode node) const
inline

Definition at line 57 of file SaberSVFGBuilder.h.

58  {
59  return globSVFGNodes.find(node)!=globSVFGNodes.end();
60  }
SVFGNodeSet globSVFGNodes
Store all global SVFG nodes.

◆ isStrongUpdate()

bool SaberSVFGBuilder::isStrongUpdate ( const SVFGNode node,
NodeID singleton,
BVDataPTAImpl pta 
)
protected

Return TRUE if this is a strong update STORE statement.

Return TRUE if this is a strong update STORE statement.

Find the unique element in cpts

Definition at line 224 of file SaberSVFGBuilder.cpp.

225 {
226  bool isSU = false;
227  if (const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
228  {
229  const PointsTo& dstCPSet = pta->getPts(store->getPAGDstNodeID());
230  if (dstCPSet.count() == 1)
231  {
233  PointsTo::iterator it = dstCPSet.begin();
234  singleton = *it;
235 
236  // Strong update can be made if this points-to target is not heap, array or field-insensitive.
237  if (!pta->isHeapMemObj(singleton) && !pta->isArrayMemObj(singleton)
238  && SVFIR::getPAG()->getBaseObj(singleton)->isFieldInsensitive() == false
239  && !pta->isLocalVarInRecursiveFun(singleton))
240  {
241  isSU = true;
242  }
243  }
244  }
245  return isSU;
246 }
bool isFieldInsensitive() const
Return true if its field limit is 0.
bool isLocalVarInRecursiveFun(NodeID id) const
Whether a local variable is in function recursions.
bool isArrayMemObj(NodeID id) const
bool isHeapMemObj(NodeID id) const
Whether this object is heap or array.
u32_t count() const
Returns number of elements.
Definition: PointsTo.cpp:111
const MemObj * getBaseObj(NodeID id) const
Definition: SVFIR.h:459

◆ rmDerefDirSVFGEdges()

void SaberSVFGBuilder::rmDerefDirSVFGEdges ( BVDataPTAImpl pta)
protected

Remove direct value-flow edge to a dereference point for Saber source-sink memory error detection for example, given two statements: p = alloc; q = *p, the direct SVFG edge between them is deleted Because those edges only stand for values used at the dereference points but they can not pass the value to other definitions

for store, connect the RHS/LHS pointer to its def

Definition at line 180 of file SaberSVFGBuilder.cpp.

181 {
182 
183  for(SVFG::iterator it = svfg->begin(), eit = svfg->end(); it!=eit; ++it)
184  {
185  const SVFGNode* node = it->second;
186 
187  if(const StmtSVFGNode* stmtNode = SVFUtil::dyn_cast<StmtSVFGNode>(node))
188  {
190  if(SVFUtil::isa<StoreSVFGNode>(stmtNode))
191  {
192  const SVFGNode* def = svfg->getDefSVFGNode(stmtNode->getPAGDstNode());
193  if(SVFGEdge* edge = svfg->getIntraVFGEdge(def,stmtNode,SVFGEdge::IntraDirectVF))
194  svfg->removeSVFGEdge(edge);
195  else
196  assert((svfg->getKind()==VFG::FULLSVFG_OPT || svfg->getKind()==VFG::PTRONLYSVFG_OPT) && "Edge not found!");
197 
198  if(accessGlobal(pta,stmtNode->getPAGDstNode()))
199  {
200  globSVFGNodes.insert(stmtNode);
201  }
202  }
203  else if(SVFUtil::isa<LoadSVFGNode>(stmtNode))
204  {
205  const SVFGNode* def = svfg->getDefSVFGNode(stmtNode->getPAGSrcNode());
206  if(SVFGEdge* edge = svfg->getIntraVFGEdge(def,stmtNode,SVFGEdge::IntraDirectVF))
207  svfg->removeSVFGEdge(edge);
208  else
209  assert((svfg->getKind()==VFG::FULLSVFG_OPT || svfg->getKind()==VFG::PTRONLYSVFG_OPT) && "Edge not found!");
210 
211  if(accessGlobal(pta,stmtNode->getPAGSrcNode()))
212  {
213  globSVFGNodes.insert(stmtNode);
214  }
215  }
216 
217  }
218  }
219 }
bool accessGlobal(BVDataPTAImpl *pta, const PAGNode *pagNode)
Whether points-to of a PAGNode points-to global variable.
@ IntraDirectVF
Definition: VFGEdge.h:53
VFGNodeIDToNodeMapTy::iterator iterator
Definition: VFG.h:80
@ PTRONLYSVFG_OPT
Definition: VFG.h:57
@ FULLSVFG_OPT
Definition: VFG.h:57

◆ rmIncomingEdgeForSUStore()

void SaberSVFGBuilder::rmIncomingEdgeForSUStore ( BVDataPTAImpl pta)
protectedvirtual

Remove Incoming Edge for strong-update (SU) store instruction Because the SU node does not receive indirect value

Remove Incoming Edge for strong-update (SU) store instruction Because the SU node does not receive indirect value

e.g., L1: *p = O; (singleton) L2: *p = _; (SU here) We should remove the indirect value flow L1 -> L2 Because the points-to set of O from L1 does not pass to that after L2

Reimplemented in SVF::CFLSVFGBuilder.

Definition at line 258 of file SaberSVFGBuilder.cpp.

259 {
260 
261  for(SVFG::iterator it = svfg->begin(), eit = svfg->end(); it!=eit; ++it)
262  {
263  const SVFGNode* node = it->second;
264 
265  if(const StoreSVFGNode* stmtNode = SVFUtil::dyn_cast<StoreSVFGNode>(node))
266  {
267  if(SVFUtil::isa<StoreStmt>(stmtNode->getPAGEdge()))
268  {
269  NodeID singleton;
270  if(isStrongUpdate(node, singleton, pta))
271  {
272  Set<SVFGEdge*> toRemove;
273  for (SVFGNode::const_iterator it2 = node->InEdgeBegin(), eit2 = node->InEdgeEnd(); it2 != eit2; ++it2)
274  {
275  if ((*it2)->isIndirectVFGEdge())
276  {
277  toRemove.insert(*it2);
278  }
279  }
280  for (SVFGEdge* edge: toRemove)
281  {
282  if (isa<StoreSVFGNode>(edge->getSrcNode()))
283  saberCondAllocator->getRemovedSUVFEdges()[edge->getSrcNode()].insert(edge->getDstNode());
284  svfg->removeSVFGEdge(edge);
285  }
286  }
287  }
288  }
289  }
290 }
iterator InEdgeBegin()
Definition: GenericGraph.h:462
iterator InEdgeEnd()
Definition: GenericGraph.h:466
SVFGNodeToSVFGNodeSetMap & getRemovedSUVFEdges()
bool isStrongUpdate(const SVFGNode *node, NodeID &singleton, BVDataPTAImpl *pta)
Return TRUE if this is a strong update STORE statement.
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
Definition: VFGNode.h:55
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96

◆ setSaberCondAllocator()

void SVF::SaberSVFGBuilder::setSaberCondAllocator ( SaberCondAllocator allocator)
inline

Definition at line 68 of file SaberSVFGBuilder.h.

69  {
70  saberCondAllocator = allocator;
71  }

Member Data Documentation

◆ globs

PointsTo SVF::SaberSVFGBuilder::globs
protected

Definition at line 105 of file SaberSVFGBuilder.h.

◆ globSVFGNodes

SVFGNodeSet SVF::SaberSVFGBuilder::globSVFGNodes
protected

Store all global SVFG nodes.

Definition at line 107 of file SaberSVFGBuilder.h.

◆ saberCondAllocator

SaberCondAllocator* SVF::SaberSVFGBuilder::saberCondAllocator
protected

Definition at line 109 of file SaberSVFGBuilder.h.


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