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

Protected Member Functions

virtual void buildSVFG ()
 Re-write create SVFG method.
 
bool isStrongUpdate (const SVFGNode *node, NodeID &singleton, BVDataPTAImpl *pta)
 Return TRUE if this is a strong update STORE statement.
 
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.
 
void collectGlobals (BVDataPTAImpl *pta)
 
bool accessGlobal (BVDataPTAImpl *pta, const PAGNode *pagNode)
 Whether points-to of a PAGNode points-to global variable.
 
PointsToCollectPtsChain (BVDataPTAImpl *pta, NodeID id, NodeToPTSSMap &cachedPtsMap)
 Collect objects along points-to chains.
 
- 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.
 
virtual void releaseMemory ()
 Release global SVFG.
 

Protected Attributes

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

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 168 of file SaberSVFGBuilder.cpp.

169{
170
171 NodeID id = pagNode->getId();
172 PointsTo pts = pta->getPts(id);
173 pts.set(id);
174
175 return pts.intersects(globs);
176}
const PointsTo & getPts(NodeID id) override
void set(u32_t n)
Inserts n in the set.
Definition PointsTo.cpp:157
u32_t NodeID
Definition GeneralType.h:55
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74

◆ 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 292 of file SaberSVFGBuilder.cpp.

293{
294 SVFIR* pag = SVFIR::getPAG();
295 for(SVFIR::CSToArgsListMap::iterator it = pag->getCallSiteArgsMap().begin(),
296 eit = pag->getCallSiteArgsMap().end(); it!=eit; ++it)
297 {
299 callgraph->getCallees(it->first, callees);
300 for (PTACallGraph::FunctionSet::const_iterator cit = callees.begin(),
301 ecit = callees.end(); cit != ecit; cit++)
302 {
303
304 const SVFFunction* fun = *cit;
307 {
308 SVFIR::SVFVarList& arglist = it->second;
309 for(SVFIR::SVFVarList::const_iterator ait = arglist.begin(), aeit = arglist.end(); ait!=aeit; ++ait)
310 {
311 const PAGNode *pagNode = *ait;
312 if (pagNode->isPointer())
313 {
315 svfg->addIntraDirectVFEdge(svfg->getDefSVFGNode(pagNode)->getId(), svfg->getActualParmVFGNode(pagNode, it->first)->getId());
316 }
317 }
318 }
319 }
320 }
321}
void getCallees(const CallICFGNode *cs, FunctionSet &callees)
Get all callees for a callsite.
Set< const SVFFunction * > FunctionSet
CSToArgsListMap & getCallSiteArgsMap()
Get callsite argument list.
Definition SVFIR.h:288
std::vector< const SVFVar * > SVFVarList
Definition SVFIR.h:60
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:116
bool isFClose(const SVFFunction *fun) const
Return true if this call is a file close.
bool isMemDealloc(const SVFFunction *fun) const
Return true if this call is a memory deallocation.
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:100
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 ((isa<ObjVar>(pagNode) && isa<GlobalObjVar>(pag->getBaseObject(pagNode->getId()))) ||
87 worklist.push_back(it->first);
88 }
89
91 while(!worklist.empty())
92 {
93 NodeID id = worklist.back();
94 worklist.pop_back();
95 globs.set(id);
96 const PointsTo& pts = pta->getPts(id);
97 for(PointsTo::iterator it = pts.begin(), eit = pts.end(); it!=eit; ++it)
98 {
100 }
101 }
102}
iterator begin()
Iterators.
IDToNodeMapTy::iterator iterator
Node Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:405
const ValVar * getBaseValVar(NodeID id) const
Definition SVFIR.h:415
PointsTo & CollectPtsChain(BVDataPTAImpl *pta, NodeID id, NodeToPTSSMap &cachedPtsMap)
Collect objects along points-to chains.
Map< NodeID, PointsTo > NodeToPTSSMap
std::vector< NodeID > NodeVector

◆ CollectPtsChain()

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

Collect objects along points-to chains.

Definition at line 120 of file SaberSVFGBuilder.cpp.

121{
122 SVFIR* pag = svfg->getPAG();
123
124 NodeID baseId = pag->getBaseObjVar(id);
125 NodeToPTSSMap::iterator it = cachedPtsMap.find(baseId);
126 if(it!=cachedPtsMap.end())
127 {
128 return it->second;
129 }
130 else
131 {
133 // base object
135 {
136 if(pta->isFIObjNode(baseId) && pag->getGNode(baseId)->hasValue())
137 {
138 ValVar* valVar = SVFUtil::dyn_cast<ValVar>(pag->getGNode(baseId));
139 if(valVar && valVar->getICFGNode() && SVFUtil::isExtCall(valVar->getICFGNode()))
140 {
141 return pts;
142 }
143 }
144 }
145
147
148 WorkList worklist;
149 for(PointsTo::iterator it = pts.begin(), eit = pts.end(); it!=eit; ++it)
150 worklist.push(*it);
151
152 while(!worklist.empty())
153 {
154 NodeID nodeId = worklist.pop();
155 const PointsTo& tmp = pta->getPts(nodeId);
156 for(PointsTo::iterator it = tmp.begin(), eit = tmp.end(); it!=eit; ++it)
157 {
159 }
160 }
161 return pts;
162 }
163}
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:511
NodeID getBaseObjVar(NodeID id) const
Base and Offset methods for Value and Object node.
Definition SVFIR.h:477
bool hasValue() const
FIFOWorkList< NodeID > WorkList
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 222 of file SaberSVFGBuilder.cpp.

223{
224 bool isSU = false;
225 if (const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
226 {
227 const PointsTo& dstCPSet = pta->getPts(store->getPAGDstNodeID());
228 if (dstCPSet.count() == 1)
229 {
232 singleton = *it;
233
234 // Strong update can be made if this points-to target is not heap, array or field-insensitive.
235 if (!pta->isHeapMemObj(singleton) && !pta->isArrayMemObj(singleton)
238 {
239 isSU = true;
240 }
241 }
242 }
243 return isSU;
244}
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.
const MemObj * getBaseObj(NodeID id) const
Definition SVFIR.h:481

◆ 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 178 of file SaberSVFGBuilder.cpp.

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

257{
258
259 for(SVFG::iterator it = svfg->begin(), eit = svfg->end(); it!=eit; ++it)
260 {
261 const SVFGNode* node = it->second;
262
263 if(const StoreSVFGNode* stmtNode = SVFUtil::dyn_cast<StoreSVFGNode>(node))
264 {
265 if(SVFUtil::isa<StoreStmt>(stmtNode->getPAGEdge()))
266 {
268 if(isStrongUpdate(node, singleton, pta))
269 {
271 for (SVFGNode::const_iterator it2 = node->InEdgeBegin(), eit2 = node->InEdgeEnd(); it2 != eit2; ++it2)
272 {
273 if ((*it2)->isIndirectVFGEdge())
274 {
275 toRemove.insert(*it2);
276 }
277 }
278 for (SVFGEdge* edge: toRemove)
279 {
280 if (isa<StoreSVFGNode>(edge->getSrcNode()))
281 saberCondAllocator->getRemovedSUVFEdges()[edge->getSrcNode()].insert(edge->getDstNode());
282 svfg->removeSVFGEdge(edge);
283 }
284 }
285 }
286 }
287 }
288}
iterator InEdgeBegin()
iterator InEdgeEnd()
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

◆ 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: