Static Value-Flow Analysis
ConsG.h
Go to the documentation of this file.
1 //===- ConsG.h -- Constraint graph representation-----------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-2017> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * ConstraintGraph.h
25  *
26  * Created on: Oct 14, 2013
27  * Author: Yulei Sui
28  */
29 
30 #ifndef CONSG_H_
31 #define CONSG_H_
32 
33 #include "Graphs/ConsGEdge.h"
34 #include "Graphs/ConsGNode.h"
35 
36 namespace SVF
37 {
38 
44 class ConstraintGraph : public GenericGraph<ConstraintNode,ConstraintEdge>
45 {
46 
47 public:
49  typedef ConstraintEdge::ConstraintEdgeSetTy::iterator ConstraintNodeIter;
53 
54 protected:
60 
65 
66  void buildCG();
67 
68  void destroy();
69 
70  void clearSolitaries(); // remove nodes that are neither pointers nor connected with any edge
71 
73  {
74  return pag->getPTASVFStmtSet(kind);
75  }
76 
78 
79  inline NodeID getValueNode(const SVFValue* value) const
80  {
81  return sccRepNode(pag->getValueNode(value));
82  }
83 
84  inline NodeID getReturnNode(const SVFFunction* value) const
85  {
86  return pag->getReturnNode(value);
87  }
88 
89  inline NodeID getVarargNode(const SVFFunction* value) const
90  {
91  return pag->getVarargNode(value);
92  }
94 
95 public:
98  {
99  buildCG();
100  }
103  {
104  destroy();
105  }
106 
108 
110  {
111  id = sccRepNode(id);
112  return getGNode(id);
113  }
114  inline void addConstraintNode(ConstraintNode* node, NodeID id)
115  {
116  addGNode(id,node);
117  }
118  inline bool hasConstraintNode(NodeID id) const
119  {
120  id = sccRepNode(id);
121  return hasGNode(id);
122  }
124  {
125  removeGNode(node);
126  }
128 
131  {
132  ConstraintEdge edge(src,dst,kind);
133  if(kind == ConstraintEdge::Copy ||
135  return directEdgeSet.find(&edge) != directEdgeSet.end();
136  else if(kind == ConstraintEdge::Addr)
137  return AddrCGEdgeSet.find(&edge) != AddrCGEdgeSet.end();
138  else if(kind == ConstraintEdge::Store)
139  return StoreCGEdgeSet.find(&edge) != StoreCGEdgeSet.end();
140  else if(kind == ConstraintEdge::Load)
141  return LoadCGEdgeSet.find(&edge) != LoadCGEdgeSet.end();
142  else
143  assert(false && "no other kind!");
144  return false;
145  }
146 
149  {
150  ConstraintEdge edge(src,dst,kind);
152  {
153  auto eit = directEdgeSet.find(&edge);
154  return *eit;
155  }
156  else if(kind == ConstraintEdge::Addr)
157  {
158  auto eit = AddrCGEdgeSet.find(&edge);
159  return *eit;
160  }
161  else if(kind == ConstraintEdge::Store)
162  {
163  auto eit = StoreCGEdgeSet.find(&edge);
164  return *eit;
165  }
166  else if(kind == ConstraintEdge::Load)
167  {
168  auto eit = LoadCGEdgeSet.find(&edge);
169  return *eit;
170  }
171  else
172  {
173  assert(false && "no other kind!");
174  return nullptr;
175  }
176  }
177 
179 
192 
194 
197  {
198  return AddrCGEdgeSet;
199  }
202  {
203  return directEdgeSet;
204  }
207  {
208  return LoadCGEdgeSet;
209  }
212  {
213  return StoreCGEdgeSet;
214  }
216 
218 
219  void reTargetDstOfEdge(ConstraintEdge* edge, ConstraintNode* newDstNode);
222  void reTargetSrcOfEdge(ConstraintEdge* edge, ConstraintNode* newSrcNode);
224  void removeAddrEdge(AddrCGEdge* edge);
226  void removeDirectEdge(ConstraintEdge* edge);
228  void removeLoadEdge(LoadCGEdge* edge);
230  void removeStoreEdge(StoreCGEdge* edge);
232 
234 
235  inline NodeID sccRepNode(NodeID id) const
236  {
237  NodeToRepMap::const_iterator it = nodeToRepMap.find(id);
238  if(it==nodeToRepMap.end())
239  return id;
240  else
241  return it->second;
242  }
244  {
245  nodeToSubsMap[id].set(id);
246  return nodeToSubsMap[id];
247  }
248  inline void setRep(NodeID node, NodeID rep)
249  {
250  nodeToRepMap[node] = rep;
251  }
252  inline void setSubs(NodeID node, NodeBS& subs)
253  {
254  nodeToSubsMap[node] |= subs;
255  }
256  inline void resetSubs(NodeID node)
257  {
258  nodeToSubsMap.erase(node);
259  }
260  inline NodeBS& getSubs(NodeID node)
261  {
262  return nodeToSubsMap[node];
263  }
264  inline NodeID getRep(NodeID node)
265  {
266  return nodeToRepMap[node];
267  }
268  inline void resetRep(NodeID node)
269  {
270  nodeToRepMap.erase(node);
271  }
273 
278 
283 
287  {
288  bool gepIn = moveInEdgesToRepNode(node, rep);
289  bool gepOut = moveOutEdgesToRepNode(node, rep);
290  return (gepIn || gepOut);
291  }
292 
294  inline bool isZeroOffsettedGepCGEdge(ConstraintEdge *edge) const
295  {
296  if (NormalGepCGEdge *normalGepCGEdge = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
297  if (0 == normalGepCGEdge->getConstantFieldIdx())
298  return true;
299  return false;
300  }
301 
303 
305  {
306  return pag->getIndirectCallsites();
307  }
309  {
310  return pag->getBlackHoleNode();
311  }
313  {
314  return pag->isBlkObjOrConstantObj(id);
315  }
317  {
318  return pag->getAllFieldsObjVars(id);
319  }
321  {
322  return pag->getBaseObjVar(id);
323  }
324  inline bool isSingleFieldObj(NodeID id) const
325  {
326  const MemObj* mem = pag->getBaseObj(id);
327  return (mem->getMaxFieldOffsetLimit() == 1);
328  }
330  inline NodeID getGepObjVar(NodeID id, const APOffset& apOffset)
331  {
332  NodeID gep = pag->getGepObjVar(id, apOffset);
334  if(sccRepNode(gep)==gep && hasConstraintNode(gep)==false)
335  addConstraintNode(new ConstraintNode(gep),gep);
336  return gep;
337  }
340  {
341  NodeID fi = pag->getFIObjVar(id);
343  assert((hasConstraintNode(fi) || sccRepNode(fi) != fi) && "non-existing fi obj??");
344  return fi;
345  }
347 
349 
350  inline bool isPWCNode(NodeID nodeId)
351  {
352  return getConstraintNode(nodeId)->isPWCNode();
353  }
354  inline void setPWCNode(NodeID nodeId)
355  {
356  getConstraintNode(nodeId)->setPWCNode();
357  }
359 
361 
362  inline bool hasNodesToBeCollapsed() const
363  {
364  return (!nodesToBeCollapsed.empty());
365  }
366  inline void addNodeToBeCollapsed(NodeID id)
367  {
369  }
371  {
372  return nodesToBeCollapsed.pop();
373  }
375 
377  void dump(std::string name);
379  void print();
380 
382  void view();
383 };
384 
385 
386 /* !
387  * GenericGraphTraits specializations for the generic graph algorithms.
388  * Provide graph traits for traversing from a constraint node using standard graph traversals.
389  */
390 template<> struct GenericGraphTraits<SVF::ConstraintNode*> : public GenericGraphTraits<SVF::GenericNode<SVF::ConstraintNode,SVF::ConstraintEdge>* >
391 {
392 };
393 
395 template<>
396 struct GenericGraphTraits<Inverse<SVF::ConstraintNode *> > : public GenericGraphTraits<Inverse<SVF::GenericNode<SVF::ConstraintNode,SVF::ConstraintEdge>* > >
397 {
398 };
399 
400 template<> struct GenericGraphTraits<SVF::ConstraintGraph*> : public GenericGraphTraits<SVF::GenericGraph<SVF::ConstraintNode,SVF::ConstraintEdge>* >
401 {
403 };
404 
405 } // End namespace SVF
406 
407 #endif /* CONSG_H_ */
cJSON * p
Definition: cJSON.cpp:2559
const char *const name
Definition: cJSON.h:264
const char *const string
Definition: cJSON.h:172
GenericNode< ConstraintNode, ConstraintEdge >::GEdgeSetTy ConstraintEdgeSetTy
Constraint edge type.
Definition: ConsGEdge.h:85
NodeID getNextCollapseNode()
Definition: ConsG.h:370
void setPWCNode(NodeID nodeId)
Definition: ConsG.h:354
ConstraintEdge * getEdge(ConstraintNode *src, ConstraintNode *dst, ConstraintEdge::ConstraintEdgeK kind)
Get an edge via its src and dst nodes and kind.
Definition: ConsG.h:148
bool moveInEdgesToRepNode(ConstraintNode *node, ConstraintNode *rep)
Definition: ConsG.cpp:474
NodeID getValueNode(const SVFValue *value) const
Wrappers used internally, not expose to Andersen Pass.
Definition: ConsG.h:79
ConstraintEdge::ConstraintEdgeSetTy StoreCGEdgeSet
Definition: ConsG.h:64
void setSubs(NodeID node, NodeBS &subs)
Definition: ConsG.h:252
ConstraintEdge::ConstraintEdgeSetTy::iterator ConstraintNodeIter
Definition: ConsG.h:49
virtual ~ConstraintGraph()
Destructor.
Definition: ConsG.h:102
void addNodeToBeCollapsed(NodeID id)
Definition: ConsG.h:366
ConstraintEdge::ConstraintEdgeSetTy directEdgeSet
Definition: ConsG.h:62
ConstraintEdge::ConstraintEdgeSetTy LoadCGEdgeSet
Definition: ConsG.h:63
LoadCGEdge * addLoadCGEdge(NodeID src, NodeID dst)
Add Load edge.
Definition: ConsG.cpp:288
ConstraintNode * getConstraintNode(NodeID id) const
Get/add/remove constraint node.
Definition: ConsG.h:109
void view()
View graph from the debugger.
Definition: ConsG.cpp:659
bool isSingleFieldObj(NodeID id) const
Definition: ConsG.h:324
NodeID sccRepNode(NodeID id) const
SCC rep/sub nodes methods.
Definition: ConsG.h:235
const SVFIR::CallSiteToFunPtrMap & getIndirectCallsites() const
Wrappers for invoking SVFIR methods.
Definition: ConsG.h:304
void reTargetDstOfEdge(ConstraintEdge *edge, ConstraintNode *newDstNode)
Used for cycle elimination.
Definition: ConsG.cpp:335
SVFStmt::SVFStmtSetTy & getPAGEdgeSet(SVFStmt::PEDGEK kind)
Definition: ConsG.h:72
OrderedMap< NodeID, ConstraintNode * > ConstraintNodeIDToNodeMapTy
Definition: ConsG.h:48
NodeID getVarargNode(const SVFFunction *value) const
Definition: ConsG.h:89
AddrCGEdge * addAddrCGEdge(NodeID src, NodeID dst)
Add a SVFIR edge into Edge map.
Definition: ConsG.cpp:202
ConstraintEdge::ConstraintEdgeSetTy AddrCGEdgeSet
Definition: ConsG.h:61
void addConstraintNode(ConstraintNode *node, NodeID id)
Definition: ConsG.h:114
bool hasEdge(ConstraintNode *src, ConstraintNode *dst, ConstraintEdge::ConstraintEdgeK kind)
Definition: ConsG.h:130
void resetSubs(NodeID node)
Definition: ConsG.h:256
CopyCGEdge * addCopyCGEdge(NodeID src, NodeID dst)
Add Copy edge.
Definition: ConsG.cpp:222
ConstraintEdge::ConstraintEdgeSetTy & getStoreCGEdges()
Get Store edges.
Definition: ConsG.h:211
StoreCGEdge * addStoreCGEdge(NodeID src, NodeID dst)
Add Store edge.
Definition: ConsG.cpp:309
NodeID getGepObjVar(NodeID id, const APOffset &apOffset)
Get a field of a memory object.
Definition: ConsG.h:330
void clearSolitaries()
Definition: ConsG.cpp:150
VariantGepCGEdge * addVariantGepCGEdge(NodeID src, NodeID dst)
Definition: ConsG.cpp:267
NodeID getBaseObjVar(NodeID id)
Definition: ConsG.h:320
NodeID getFIObjVar(NodeID id)
Get a field-insensitive node of a memory object.
Definition: ConsG.h:339
ConstraintGraph(SVFIR *p)
Constructor.
Definition: ConsG.h:97
NodeID getReturnNode(const SVFFunction *value) const
Definition: ConsG.h:84
bool isPWCNode(NodeID nodeId)
Check/Set PWC (positive weight cycle) flag.
Definition: ConsG.h:350
bool isBlkObjOrConstantObj(NodeID id)
Definition: ConsG.h:312
void removeConstraintNode(ConstraintNode *node)
Definition: ConsG.h:123
void removeDirectEdge(ConstraintEdge *edge)
Remove direct edge from their src and dst edge sets.
Definition: ConsG.cpp:459
void resetRep(NodeID node)
Definition: ConsG.h:268
bool moveOutEdgesToRepNode(ConstraintNode *node, ConstraintNode *rep)
Definition: ConsG.cpp:532
void removeLoadEdge(LoadCGEdge *edge)
Remove load edge from their src and dst edge sets.
Definition: ConsG.cpp:433
bool hasNodesToBeCollapsed() const
Add/get nodes to be collapsed.
Definition: ConsG.h:362
void print()
Print CG into terminal.
Definition: ConsG.cpp:599
void reTargetSrcOfEdge(ConstraintEdge *edge, ConstraintNode *newSrcNode)
Remove edge from old src target, change edge dst id and add modified edge into new src.
Definition: ConsG.cpp:379
bool moveEdgesToRepNode(ConstraintNode *node, ConstraintNode *rep)
Definition: ConsG.h:286
void removeStoreEdge(StoreCGEdge *edge)
Remove store edge from their src and dst edge sets.
Definition: ConsG.cpp:446
bool hasConstraintNode(NodeID id) const
Definition: ConsG.h:118
NormalGepCGEdge * addNormalGepCGEdge(NodeID src, NodeID dst, const AccessPath &ap)
Add Gep edge.
Definition: ConsG.cpp:245
NodeToRepMap nodeToRepMap
Definition: ConsG.h:56
NodeID getBlackHoleNode()
Definition: ConsG.h:308
void setRep(NodeID node, NodeID rep)
Definition: ConsG.h:248
EdgeID edgeIndex
Definition: ConsG.h:59
Map< NodeID, NodeBS > NodeToSubsMap
Definition: ConsG.h:51
void removeAddrEdge(AddrCGEdge *edge)
Remove addr edge from their src and dst edge sets.
Definition: ConsG.cpp:420
NodeID getRep(NodeID node)
Definition: ConsG.h:264
ConstraintEdge::ConstraintEdgeSetTy & getDirectCGEdges()
Get Copy/call/ret/gep edges.
Definition: ConsG.h:201
NodeBS & getSubs(NodeID node)
Definition: ConsG.h:260
ConstraintEdge::ConstraintEdgeSetTy & getAddrCGEdges()
Get SVFIR edge.
Definition: ConsG.h:196
FIFOWorkList< NodeID > WorkList
Definition: ConsG.h:52
NodeBS & sccSubNodes(NodeID id)
Definition: ConsG.h:243
WorkList nodesToBeCollapsed
Definition: ConsG.h:58
bool isZeroOffsettedGepCGEdge(ConstraintEdge *edge) const
Check if a given edge is a NormalGepCGEdge with 0 offset.
Definition: ConsG.h:294
NodeToSubsMap nodeToSubsMap
Definition: ConsG.h:57
void dump(std::string name)
Dump graph into dot file.
Definition: ConsG.cpp:591
ConstraintEdge::ConstraintEdgeSetTy & getLoadCGEdges()
Get Load edges.
Definition: ConsG.h:206
NodeBS & getAllFieldsObjVars(NodeID id)
Definition: ConsG.h:316
Map< NodeID, NodeID > NodeToRepMap
Definition: ConsG.h:50
bool isPWCNode() const
Whether a node involves in PWC, if so, all its points-to elements should become field-insensitive.
Definition: ConsGNode.h:81
bool push(const Data &data)
Definition: WorkList.h:165
bool empty() const
Definition: WorkList.h:146
void addGNode(NodeID id, NodeType *node)
Add a Node.
Definition: GenericGraph.h:646
void removeGNode(NodeType *node)
Delete a node.
Definition: GenericGraph.h:668
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
bool hasGNode(NodeID id) const
Has a node.
Definition: GenericGraph.h:661
NodeID getBlackHoleNode() const
Definition: IRGraph.h:161
NodeID getValueNode(const SVFValue *V)
Definition: IRGraph.h:137
NodeID getVarargNode(const SVFFunction *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition: IRGraph.h:157
NodeID getReturnNode(const SVFFunction *func) const
GetReturnNode - Return the unique node representing the return value of a function.
Definition: IRGraph.h:152
u32_t getMaxFieldOffsetLimit() const
Get max field offset limit.
NodeID getFIObjVar(const MemObj *obj) const
Get a field-insensitive obj SVFIR node according to a mem obj.
Definition: SVFIR.h:415
const CallSiteToFunPtrMap & getIndirectCallsites() const
Add/get indirect callsites.
Definition: SVFIR.h:350
OrderedMap< const CallICFGNode *, NodeID > CallSiteToFunPtrMap
Definition: SVFIR.h:55
SVFStmt::SVFStmtSetTy & getPTASVFStmtSet(SVFStmt::PEDGEK kind)
Get PTA edges set according to its kind.
Definition: SVFIR.h:206
NodeBS & getAllFieldsObjVars(const MemObj *obj)
Get all fields of an object.
Definition: SVFIR.cpp:477
NodeID getBaseObjVar(NodeID id) const
Base and Offset methods for Value and Object node.
Definition: SVFIR.h:455
bool isBlkObjOrConstantObj(NodeID id) const
Definition: SVFIR.h:435
NodeID getGepObjVar(const MemObj *obj, const APOffset &ap)
Get a field SVFIR Object node according to base mem obj and offset.
Definition: SVFIR.cpp:422
const MemObj * getBaseObj(NodeID id) const
Definition: SVFIR.h:459
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
s64_t APOffset
Definition: GeneralType.h:60
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
u32_t EdgeID
Definition: GeneralType.h:56
std::map< Key, Value, Compare, Allocator > OrderedMap
Definition: GeneralType.h:109