svf-tools 1.0.644 → 1.0.646

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.644",
3
+ "version": "1.0.646",
4
4
  "description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -38,173 +38,7 @@ using namespace std;
38
38
 
39
39
  namespace SVF
40
40
  {
41
-
42
41
  typedef GrammarBase::Symbol Label;
43
- /*!
44
- * Adjacency-list graph representation
45
- */
46
- class CFLData
47
- {
48
- public:
49
- typedef std::map<const Label, NodeBS> TypeMap; // Label with SparseBitVector of NodeID
50
- typedef std::unordered_map<NodeID, TypeMap> DataMap; // Each Node has a TypeMap
51
- typedef typename DataMap::iterator iterator; // iterator for each node
52
- typedef typename DataMap::const_iterator const_iterator; // const iterator
53
-
54
- protected:
55
- DataMap succMap; // succ map for nodes contains Label: Edgeset
56
- DataMap predMap; // pred map for nodes contains Label: edgeset
57
- const NodeBS emptyData; // ??
58
- NodeBS diff; // ??
59
-
60
- // union/add data
61
- //@{
62
- inline bool addPred(const NodeID key, const NodeID src, const Label ty)
63
- {
64
- return predMap[key][ty].test_and_set(src);
65
- };
66
-
67
- inline bool addSucc(const NodeID key, const NodeID dst, const Label ty)
68
- {
69
- return succMap[key][ty].test_and_set(dst);
70
- };
71
-
72
- inline bool addPreds(const NodeID key, const NodeBS& data, const Label ty)
73
- {
74
- if (data.empty())
75
- return false;
76
- return predMap[key][ty] |= data; // union of sparsebitvector (add to LHS)
77
- }
78
-
79
- inline bool addSuccs(const NodeID key, const NodeBS& data, const Label ty)
80
- {
81
- if (data.empty())
82
- return false;
83
- return succMap[key][ty] |= data; // // union of sparsebitvector (add to LHS)
84
- }
85
- //@}
86
-
87
- public:
88
- // Constructor
89
- CFLData()
90
- {}
91
-
92
- // Destructor
93
- virtual ~CFLData()
94
- {}
95
-
96
- virtual void clear()
97
- {
98
- succMap.clear();
99
- predMap.clear();
100
- }
101
-
102
- inline const_iterator begin() const
103
- {
104
- return succMap.begin();
105
- }
106
-
107
- inline const_iterator end() const
108
- {
109
- return succMap.end();
110
- }
111
-
112
- inline iterator begin()
113
- {
114
- return succMap.begin();
115
- }
116
-
117
- inline iterator end()
118
- {
119
- return succMap.end();
120
- }
121
-
122
- inline DataMap& getSuccMap()
123
- {
124
- return succMap;
125
- }
126
-
127
- inline DataMap& getPredMap()
128
- {
129
- return predMap;
130
- }
131
-
132
- inline TypeMap& getSuccMap(const NodeID key)
133
- {
134
- return succMap[key];
135
- }
136
-
137
- inline TypeMap& getPredMap(const NodeID key)
138
- {
139
- return predMap[key];
140
- }
141
-
142
- inline NodeBS& getSuccs(const NodeID key, const Label ty)
143
- {
144
- return succMap[key][ty];
145
- }
146
-
147
- inline NodeBS& getPreds(const NodeID key, const Label ty)
148
- {
149
- return predMap[key][ty];
150
- }
151
-
152
- // Alias data operations
153
- //@{
154
- inline bool addEdge(const NodeID src, const NodeID dst, const Label ty)
155
- {
156
- addSucc(src, dst, ty);
157
- return addPred(dst, src, ty);
158
- }
159
-
160
- /// add edges and return the set of added edges (dst) for src
161
- inline NodeBS addEdges(const NodeID src, const NodeBS& dstData, const Label ty)
162
- {
163
- NodeBS newDsts;
164
- if (addSuccs(src, dstData, ty))
165
- {
166
- for (const NodeID datum: dstData)
167
- if (addPred(datum, src, ty))
168
- newDsts.set(datum);
169
- }
170
- return newDsts;
171
- }
172
-
173
- /// add edges and return the set of added edges (src) for dst
174
- inline NodeBS addEdges(const NodeBS& srcData, const NodeID dst, const Label ty)
175
- {
176
- NodeBS newSrcs;
177
- if (addPreds(dst, srcData, ty))
178
- {
179
- for (const NodeID datum: srcData)
180
- if (addSucc(datum, dst, ty))
181
- newSrcs.set(datum);
182
- }
183
- return newSrcs;
184
- }
185
-
186
- /// find src -> find src[ty] -> find dst in set
187
- inline bool hasEdge(const NodeID src, const NodeID dst, const Label ty)
188
- {
189
- const_iterator iter1 = succMap.find(src);
190
- if (iter1 == succMap.end())
191
- return false;
192
-
193
- auto iter2 = iter1->second.find(ty);
194
- if (iter2 == iter1->second.end())
195
- return false;
196
-
197
- return iter2->second.test(dst);
198
- }
199
-
200
- /* This is a dataset version, to be modified to a cflData version */
201
- inline void clearEdges(const NodeID key)
202
- {
203
- succMap[key].clear();
204
- predMap[key].clear();
205
- }
206
- //@}
207
- };
208
42
 
209
43
  /*!
210
44
  * Hybrid graph representation for transitive relations
@@ -388,51 +222,172 @@ protected:
388
222
  class POCRSolver : public CFLSolver
389
223
  {
390
224
  public:
391
- POCRSolver(CFLGraph* _graph, CFLGrammar* _grammar) : CFLSolver(_graph, _grammar), cflData(NULL)
225
+ typedef std::map<const Label, NodeBS> TypeMap; // Label with SparseBitVector of NodeID
226
+ typedef std::unordered_map<NodeID, TypeMap> DataMap; // Each Node has a TypeMap
227
+ typedef typename DataMap::iterator iterator; // iterator for each node
228
+ typedef typename DataMap::const_iterator const_iterator;
229
+
230
+ protected:
231
+ DataMap succMap; // succ map for nodes contains Label: Edgeset
232
+ DataMap predMap; // pred map for nodes contains Label: edgeset
233
+ const NodeBS emptyData; // ??
234
+ NodeBS diff;
235
+ // union/add data
236
+ //@{
237
+ inline bool addPred(const NodeID key, const NodeID src, const Label ty)
392
238
  {
393
- if (!cflData)
394
- {
395
- cflData = new CFLData();
396
- // Build CFL Data
397
- buildCFLData();
398
- }
239
+ return predMap[key][ty].test_and_set(src);
240
+ };
241
+
242
+ inline bool addSucc(const NodeID key, const NodeID dst, const Label ty)
243
+ {
244
+ return succMap[key][ty].test_and_set(dst);
245
+ };
246
+
247
+ inline bool addPreds(const NodeID key, const NodeBS& data, const Label ty)
248
+ {
249
+ if (data.empty())
250
+ return false;
251
+ return predMap[key][ty] |= data; // union of sparsebitvector (add to LHS)
399
252
  }
400
- /// Destructor
401
- virtual ~POCRSolver()
253
+
254
+ inline bool addSuccs(const NodeID key, const NodeBS& data, const Label ty)
402
255
  {
403
- delete cflData;
256
+ if (data.empty())
257
+ return false;
258
+ return succMap[key][ty] |= data; // // union of sparsebitvector (add to LHS)
404
259
  }
260
+ //@}
261
+ public:
405
262
 
406
- /// Process CFLEdge
407
- virtual void processCFLEdge(const CFLEdge* Y_edge);
263
+ virtual void clear()
264
+ {
265
+ succMap.clear();
266
+ predMap.clear();
267
+ }
408
268
 
409
- /// Init CFLData
410
- virtual void buildCFLData();
269
+ inline const_iterator begin() const
270
+ {
271
+ return succMap.begin();
272
+ }
411
273
 
412
- virtual bool addEdge(const CFLNode* src, const CFLNode* dst, const Label ty)
274
+ inline const_iterator end() const
413
275
  {
414
- return cflData->addEdge(src->getId(), dst->getId(), ty);
276
+ return succMap.end();
415
277
  }
416
278
 
417
- virtual bool addEdge(const NodeID srcId, const NodeID dstId, const Label ty)
279
+ inline iterator begin()
418
280
  {
419
- return cflData->addEdge(srcId, dstId, ty);
281
+ return succMap.begin();
420
282
  }
421
283
 
422
- virtual void initialize();
284
+ inline iterator end()
285
+ {
286
+ return succMap.end();
287
+ }
288
+
289
+ inline DataMap& getSuccMap()
290
+ {
291
+ return succMap;
292
+ }
293
+
294
+ inline DataMap& getPredMap()
295
+ {
296
+ return predMap;
297
+ }
298
+
299
+ inline TypeMap& getSuccMap(const NodeID key)
300
+ {
301
+ return succMap[key];
302
+ }
303
+
304
+ inline TypeMap& getPredMap(const NodeID key)
305
+ {
306
+ return predMap[key];
307
+ }
423
308
 
424
- virtual NodeBS addEdges(const NodeID srcId, const NodeBS& dstData, const Label ty)
309
+ inline NodeBS& getSuccs(const NodeID key, const Label ty)
425
310
  {
426
- return cflData->addEdges(srcId, dstData, ty);
311
+ return succMap[key][ty];
427
312
  }
428
313
 
314
+ inline NodeBS& getPreds(const NodeID key, const Label ty)
315
+ {
316
+ return predMap[key][ty];
317
+ }
429
318
 
430
- virtual NodeBS addEdges(const NodeBS& srcData, const NodeID dstId, const Label ty)
319
+ // Alias data operations
320
+ //@{
321
+ inline bool addEdge(const NodeID src, const NodeID dst, const Label ty)
431
322
  {
432
- return cflData->addEdges(srcData, dstId, ty);
323
+ addSucc(src, dst, ty);
324
+ return addPred(dst, src, ty);
433
325
  }
434
- private:
435
- CFLData* cflData;
326
+
327
+ /// add edges and return the set of added edges (dst) for src
328
+ inline NodeBS addEdges(const NodeID src, const NodeBS& dstData, const Label ty)
329
+ {
330
+ NodeBS newDsts;
331
+ if (addSuccs(src, dstData, ty))
332
+ {
333
+ for (const NodeID datum: dstData)
334
+ if (addPred(datum, src, ty))
335
+ newDsts.set(datum);
336
+ }
337
+ return newDsts;
338
+ }
339
+
340
+ /// add edges and return the set of added edges (src) for dst
341
+ inline NodeBS addEdges(const NodeBS& srcData, const NodeID dst, const Label ty)
342
+ {
343
+ NodeBS newSrcs;
344
+ if (addPreds(dst, srcData, ty))
345
+ {
346
+ for (const NodeID datum: srcData)
347
+ if (addSucc(datum, dst, ty))
348
+ newSrcs.set(datum);
349
+ }
350
+ return newSrcs;
351
+ }
352
+
353
+ /// find src -> find src[ty] -> find dst in set
354
+ inline bool hasEdge(const NodeID src, const NodeID dst, const Label ty)
355
+ {
356
+ const_iterator iter1 = succMap.find(src);
357
+ if (iter1 == succMap.end())
358
+ return false;
359
+
360
+ auto iter2 = iter1->second.find(ty);
361
+ if (iter2 == iter1->second.end())
362
+ return false;
363
+
364
+ return iter2->second.test(dst);
365
+ }
366
+
367
+ /* This is a dataset version, to be modified to a cflData version */
368
+ inline void clearEdges(const NodeID key)
369
+ {
370
+ succMap[key].clear();
371
+ predMap[key].clear();
372
+ }
373
+ //@}
374
+
375
+ POCRSolver(CFLGraph* _graph, CFLGrammar* _grammar) : CFLSolver(_graph, _grammar)
376
+ {
377
+ buildCFLData();
378
+ }
379
+ /// Destructor
380
+ virtual ~POCRSolver()
381
+ {
382
+ }
383
+
384
+ /// Process CFLEdge
385
+ virtual void processCFLEdge(const CFLEdge* Y_edge);
386
+
387
+ /// Init CFLData
388
+ virtual void buildCFLData();
389
+
390
+ virtual void initialize();
436
391
  };
437
392
  }
438
393
 
@@ -0,0 +1,246 @@
1
+ //===- CFBasicBlockG.h ----------------------------------------------------------------//
2
+ //
3
+ // SVF: Static Value-Flow Analysis
4
+ //
5
+ // Copyright (C) <2013-2018> <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 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 General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+
23
+ /*
24
+ * CFBasicBlockG.h
25
+ *
26
+ * Created on: 24 Dec. 2022
27
+ * Author: Xiao, Jiawei
28
+ */
29
+
30
+ #ifndef SVF_CFBASICBLOCKG_H
31
+ #define SVF_CFBASICBLOCKG_H
32
+ #include "Util/SVFUtil.h"
33
+ #include "Graphs/ICFGNode.h"
34
+ #include "Graphs/GenericGraph.h"
35
+
36
+ namespace SVF
37
+ {
38
+ class CFBasicBlockNode;
39
+ class SVFIR;
40
+
41
+ typedef GenericEdge<CFBasicBlockNode> GenericCFBasicBlockEdgeTy;
42
+
43
+ class CFBasicBlockEdge : public GenericCFBasicBlockEdgeTy
44
+ {
45
+ public:
46
+ CFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst) : GenericCFBasicBlockEdgeTy(src, dst, 0) {}
47
+
48
+
49
+ friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockEdge &edge)
50
+ {
51
+ o << edge.toString();
52
+ return o;
53
+ }
54
+
55
+ virtual const std::string toString() const
56
+ {
57
+ return std::to_string(getSrcID()) + " --> " + std::to_string(getDstID());
58
+ }
59
+ };
60
+
61
+ typedef GenericNode<CFBasicBlockNode, CFBasicBlockEdge> GenericCFBasicBlockNodeTy;
62
+
63
+ class CFBasicBlockNode : public GenericCFBasicBlockNodeTy
64
+ {
65
+ private:
66
+ const SVFBasicBlock *_svfBasicBlock; /// Every CFBasicBlockNode holds a SVFBasicBlock
67
+ std::vector<const ICFGNode *> _icfgNodes; /// Every CBFGNode holds a vector of ICFGNodes
68
+
69
+ public:
70
+ CFBasicBlockNode(u32_t id, const SVFBasicBlock *svfBasicBlock);
71
+
72
+ friend std::ostream &operator<<(std::ostream &o, const CFBasicBlockNode &node)
73
+ {
74
+ o << node.toString();
75
+ return o;
76
+ }
77
+
78
+ virtual const std::string toString() const;
79
+
80
+ inline std::string getName() const;
81
+
82
+ inline const SVFBasicBlock *getSVFBasicBlock() const;
83
+
84
+ inline const SVFFunction *getFunction() const;
85
+
86
+ inline std::vector<const ICFGNode *>::const_iterator begin() const
87
+ {
88
+ return _icfgNodes.cbegin();
89
+ }
90
+
91
+ inline std::vector<const ICFGNode *>::const_iterator end() const
92
+ {
93
+ return _icfgNodes.cend();
94
+ }
95
+ };
96
+
97
+ typedef GenericGraph<CFBasicBlockNode, CFBasicBlockEdge> GenericCFBasicBlockGTy;
98
+
99
+ class CFBasicBlockGraph : public GenericCFBasicBlockGTy
100
+ {
101
+ friend class CFBasicBlockGBuilder;
102
+
103
+ public:
104
+ typedef Map<const SVFBasicBlock *, CFBasicBlockNode *> SVFBasicBlockToCFBasicBlockNodeMap;
105
+
106
+ private:
107
+ SVFBasicBlockToCFBasicBlockNodeMap _bbToNode;
108
+ const SVFFunction *_svfFunction;
109
+ u32_t _totalCFBasicBlockNode{0};
110
+ u32_t _totalCFBasicBlockEdge{0};
111
+
112
+ public:
113
+
114
+ CFBasicBlockGraph(const SVFFunction *svfFunction) : _svfFunction(svfFunction)
115
+ {
116
+
117
+ }
118
+
119
+ ~CFBasicBlockGraph() override = default;
120
+
121
+ /// Dump graph into dot file
122
+ void dump(const std::string &filename)
123
+ {
124
+ GraphPrinter::WriteGraphToFile(SVFUtil::outs(), filename, this);
125
+ }
126
+
127
+ inline CFBasicBlockNode *getCFBasicBlockNode(u32_t id) const;
128
+
129
+ inline CFBasicBlockNode *getCFBasicBlockNode(const SVFBasicBlock *bb) const;
130
+
131
+ inline bool hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst);
132
+
133
+ CFBasicBlockEdge* getCFBasicBlockEdge(const CFBasicBlockNode *src, const CFBasicBlockNode *dst);
134
+
135
+ CFBasicBlockEdge* getCFBasicBlockEdge(const SVFBasicBlock *src, const SVFBasicBlock *dst);
136
+
137
+ private:
138
+
139
+ /// Add a CFBasicBlockNode
140
+ inline const CFBasicBlockNode* getOrAddCFBasicBlockNode(const SVFBasicBlock *bb);
141
+
142
+ inline const CFBasicBlockEdge *getOrAddCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst);
143
+
144
+ };
145
+
146
+ class CFBasicBlockGBuilder
147
+ {
148
+
149
+ private:
150
+ CFBasicBlockGraph* _CFBasicBlockG;
151
+
152
+ public:
153
+ CFBasicBlockGBuilder(const SVFFunction *func) : _CFBasicBlockG(new CFBasicBlockGraph(func)) {}
154
+
155
+ void build();
156
+
157
+ inline CFBasicBlockGraph* getCFBasicBlockGraph()
158
+ {
159
+ return _CFBasicBlockG;
160
+ }
161
+ };
162
+ }
163
+
164
+
165
+ namespace SVF
166
+ {
167
+ /* !
168
+ * GenericGraphTraits specializations for generic graph algorithms.
169
+ * Provide graph traits for traversing from a constraint node using standard graph ICFGTraversals.
170
+ */
171
+ template<>
172
+ struct GenericGraphTraits<SVF::CFBasicBlockNode *>
173
+ : public GenericGraphTraits<SVF::GenericNode<SVF::CFBasicBlockNode, SVF::CFBasicBlockEdge> *>
174
+ {
175
+ };
176
+
177
+ /// Inverse GenericGraphTraits specializations for call graph node, it is used for inverse ICFGTraversal.
178
+ template<>
179
+ struct GenericGraphTraits<Inverse< SVF::CFBasicBlockNode *> > : public GenericGraphTraits<
180
+ Inverse<SVF::GenericNode<SVF::CFBasicBlockNode, SVF::CFBasicBlockEdge> *> >
181
+ {
182
+ };
183
+
184
+ template<>
185
+ struct GenericGraphTraits<SVF::CFBasicBlockGraph *>
186
+ : public GenericGraphTraits<SVF::GenericGraph<SVF::CFBasicBlockNode, SVF::CFBasicBlockEdge> *>
187
+ {
188
+ typedef SVF::CFBasicBlockNode *NodeRef;
189
+ };
190
+
191
+ template<>
192
+ struct DOTGraphTraits<SVF::CFBasicBlockGraph *> : public DOTGraphTraits<SVF::SVFIR *>
193
+ {
194
+
195
+ typedef SVF::CFBasicBlockNode NodeType;
196
+
197
+ DOTGraphTraits(bool isSimple = false) :
198
+ DOTGraphTraits<SVF::SVFIR *>(isSimple)
199
+ {
200
+ }
201
+
202
+ /// Return name of the graph
203
+ static std::string getGraphName(SVF::CFBasicBlockGraph *)
204
+ {
205
+ return "CFBasicBlockGraph";
206
+ }
207
+
208
+ std::string getNodeLabel(NodeType *node, SVF::CFBasicBlockGraph *graph)
209
+ {
210
+ return getSimpleNodeLabel(node, graph);
211
+ }
212
+
213
+ /// Return the label of an ICFG node
214
+ static std::string getSimpleNodeLabel(NodeType *node, SVF::CFBasicBlockGraph *)
215
+ {
216
+ std::string str;
217
+ std::stringstream rawstr(str);
218
+ rawstr << "NodeID: " << node->getId() << "\n";
219
+ rawstr << node->toString();
220
+
221
+ return rawstr.str();
222
+ }
223
+
224
+ static std::string getNodeAttributes(NodeType *node, SVF::CFBasicBlockGraph *)
225
+ {
226
+ std::string str;
227
+ std::stringstream rawstr(str);
228
+ rawstr << "color=black";
229
+ return rawstr.str();
230
+ }
231
+
232
+ template<class EdgeIter>
233
+ static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::CFBasicBlockGraph *)
234
+ {
235
+ return "style=solid";
236
+ }
237
+
238
+ template<class EdgeIter>
239
+ static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
240
+ {
241
+ return "";
242
+ }
243
+ };
244
+
245
+ } // End namespace SVF
246
+ #endif //SVF_CFBASICBLOCKG_H
@@ -30,7 +30,7 @@
30
30
  #ifndef GENERICGRAPH_H_
31
31
  #define GENERICGRAPH_H_
32
32
 
33
- #include "SVFIR/SVFValue.h"
33
+ #include "SVFIR/SVFType.h"
34
34
  #include "Util/iterator.h"
35
35
  #include "Graphs/GraphTraits.h"
36
36
 
@@ -36,6 +36,7 @@
36
36
  #include "Util/NodeIDAllocator.h"
37
37
  #include "Util/SVFUtil.h"
38
38
  #include "Graphs/ICFG.h"
39
+ #include "Graphs/CFBasicBlockG.h"
39
40
 
40
41
  namespace SVF
41
42
  {
@@ -163,8 +163,8 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge)
163
163
  for(const Production& prod : grammar->getProdsFromFirstRHS(Y))
164
164
  {
165
165
  Symbol X = grammar->getLHSSymbol(prod);
166
- NodeBS diffDsts = addEdges(i->getId(), cflData->getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)], X);
167
- numOfChecks += cflData->getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count();
166
+ NodeBS diffDsts = addEdges(i->getId(), getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)], X);
167
+ numOfChecks += getSuccMap(j->getId())[grammar->getSecondRHSSymbol(prod)].count();
168
168
  for (NodeID diffDst: diffDsts)
169
169
  {
170
170
  const CFLEdge* newEdge = graph->addCFLEdge(i, graph->getGNode(diffDst), X);
@@ -179,8 +179,8 @@ void POCRSolver::processCFLEdge(const CFLEdge* Y_edge)
179
179
  for(const Production& prod : grammar->getProdsFromSecondRHS(Y))
180
180
  {
181
181
  Symbol X = grammar->getLHSSymbol(prod);
182
- NodeBS diffSrcs = addEdges(cflData->getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X);
183
- numOfChecks += cflData->getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count();
182
+ NodeBS diffSrcs = addEdges(getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)], j->getId(), X);
183
+ numOfChecks += getPredMap(i->getId())[grammar->getFirstRHSSymbol(prod)].count();
184
184
  for (NodeID diffSrc: diffSrcs)
185
185
  {
186
186
  const CFLEdge* newEdge = graph->addCFLEdge(graph->getGNode(diffSrc), j, X);
@@ -203,16 +203,15 @@ void POCRSolver::initialize()
203
203
  /// add X(i,i) if not exist to E and to worklist
204
204
  for(const Production& prod : grammar->getEpsilonProds())
205
205
  {
206
- for(auto IDMap : cflData->getSuccMap())
206
+ for(auto IDMap : getSuccMap())
207
207
  {
208
208
  Symbol X = grammar->getLHSSymbol(prod);
209
- if (cflData->addEdge(IDMap.first, IDMap.first, X))
209
+ if (addEdge(IDMap.first, IDMap.first, X))
210
210
  {
211
211
  CFLNode* i = graph->getGNode(IDMap.first);
212
212
  const CFLEdge* newEdge = graph->addCFLEdge(i, i, X);
213
213
  pushIntoWorklist(newEdge);
214
214
  }
215
-
216
215
  }
217
216
  }
218
217
  }
@@ -0,0 +1,159 @@
1
+ //===- CFBasicBlockG.cpp ----------------------------------------------------------------//
2
+ //
3
+ // SVF: Static Value-Flow Analysis
4
+ //
5
+ // Copyright (C) <2013-2018> <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 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 General Public License for more details.
17
+
18
+ // You should have received a copy of the GNU General Public License
19
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+ //
21
+ //===----------------------------------------------------------------------===//
22
+
23
+ /*
24
+ * CFBasicBlockG.cpp
25
+ *
26
+ * Created on: 24 Dec. 2022
27
+ * Author: Xiao, Jiawei
28
+ */
29
+
30
+ #include "Graphs/CFBasicBlockG.h"
31
+ #include "SVFIR/SVFIR.h"
32
+
33
+ namespace SVF
34
+ {
35
+ CFBasicBlockNode::CFBasicBlockNode(u32_t id, const SVFBasicBlock *svfBasicBlock) : GenericCFBasicBlockNodeTy(id, 0),
36
+ _svfBasicBlock(svfBasicBlock)
37
+ {
38
+ for (auto it = svfBasicBlock->begin(); it != svfBasicBlock->end(); ++it)
39
+ {
40
+ const SVFInstruction *ins = *it;
41
+ ICFGNode *icfgNode = PAG::getPAG()->getICFG()->getICFGNode(ins);
42
+ _icfgNodes.push_back(icfgNode);
43
+ }
44
+ }
45
+
46
+ const std::string CFBasicBlockNode::toString() const
47
+ {
48
+ std::string rawStr;
49
+ std::stringstream stringstream(rawStr);
50
+ stringstream << "Block Name: " << _svfBasicBlock->getName() << "\n";
51
+ for (const auto &icfgNode: _icfgNodes)
52
+ {
53
+ stringstream << icfgNode->toString() << "\n";
54
+ }
55
+ return stringstream.str();
56
+ }
57
+
58
+ std::string CFBasicBlockNode::getName() const
59
+ {
60
+ return _svfBasicBlock->getName();
61
+ }
62
+
63
+ const SVFBasicBlock* CFBasicBlockNode::getSVFBasicBlock() const
64
+ {
65
+ return _svfBasicBlock;
66
+ }
67
+
68
+ const SVFFunction* CFBasicBlockNode::getFunction() const
69
+ {
70
+ return _svfBasicBlock->getFunction();
71
+ }
72
+
73
+ bool CFBasicBlockGraph::hasCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst)
74
+ {
75
+ CFBasicBlockEdge edge(src, dst);
76
+ CFBasicBlockEdge *outEdge = src->hasOutgoingEdge(&edge);
77
+ CFBasicBlockEdge *inEdge = dst->hasIncomingEdge(&edge);
78
+ if (outEdge && inEdge)
79
+ {
80
+ assert(outEdge == inEdge && "edges not match");
81
+ return true;
82
+ }
83
+ else
84
+ return false;
85
+ }
86
+
87
+ CFBasicBlockNode* CFBasicBlockGraph::getCFBasicBlockNode(u32_t id) const
88
+ {
89
+ if (!hasGNode(id)) return nullptr;
90
+ return getGNode(id);
91
+ }
92
+
93
+ CFBasicBlockNode* CFBasicBlockGraph::getCFBasicBlockNode(const SVFBasicBlock *bb) const
94
+ {
95
+ auto it = _bbToNode.find(bb);
96
+ if (it == _bbToNode.end()) return nullptr;
97
+ return it->second;
98
+ }
99
+
100
+ CFBasicBlockEdge* CFBasicBlockGraph::getCFBasicBlockEdge(const SVFBasicBlock *src, const SVFBasicBlock *dst)
101
+ {
102
+ return getCFBasicBlockEdge(getCFBasicBlockNode(src), getCFBasicBlockNode(dst));
103
+ }
104
+
105
+ CFBasicBlockEdge* CFBasicBlockGraph::getCFBasicBlockEdge(const CFBasicBlockNode *src, const CFBasicBlockNode *dst)
106
+ {
107
+ CFBasicBlockEdge *edge = nullptr;
108
+ size_t counter = 0;
109
+ for (auto iter = src->OutEdgeBegin();
110
+ iter != src->OutEdgeEnd(); ++iter)
111
+ {
112
+ if ((*iter)->getDstID() == dst->getId())
113
+ {
114
+ counter++;
115
+ edge = (*iter);
116
+ }
117
+ }
118
+ assert(counter <= 1 && "there's more than one edge between two nodes");
119
+ return edge;
120
+ }
121
+
122
+ const CFBasicBlockNode* CFBasicBlockGraph::getOrAddCFBasicBlockNode(const SVFBasicBlock *bb)
123
+ {
124
+ auto it = _bbToNode.find(bb);
125
+ if (it != _bbToNode.end()) return it->second;
126
+ CFBasicBlockNode *node = new CFBasicBlockNode(_totalCFBasicBlockNode++, bb);
127
+ _bbToNode[bb] = node;
128
+ addGNode(node->getId(), node);
129
+ return node;
130
+ }
131
+
132
+ const CFBasicBlockEdge* CFBasicBlockGraph::getOrAddCFBasicBlockEdge(CFBasicBlockNode *src, CFBasicBlockNode *dst)
133
+ {
134
+ if (const CFBasicBlockEdge *edge = getCFBasicBlockEdge(src, dst)) return edge;
135
+ CFBasicBlockEdge *edge = new CFBasicBlockEdge(src, dst);
136
+ bool added1 = edge->getDstNode()->addIncomingEdge(edge);
137
+ bool added2 = edge->getSrcNode()->addOutgoingEdge(edge);
138
+ assert(added1 && added2 && "edge not added??");
139
+ _totalCFBasicBlockEdge++;
140
+ return edge;
141
+ }
142
+
143
+ void CFBasicBlockGBuilder::build()
144
+ {
145
+ for (const auto &bb: *_CFBasicBlockG->_svfFunction)
146
+ {
147
+ _CFBasicBlockG->getOrAddCFBasicBlockNode(bb);
148
+ }
149
+ for (const auto &bb: *_CFBasicBlockG->_svfFunction)
150
+ {
151
+ for (const auto &succ: bb->getSuccessors())
152
+ {
153
+ _CFBasicBlockG->getOrAddCFBasicBlockEdge(_CFBasicBlockG->getCFBasicBlockNode(bb),
154
+ _CFBasicBlockG->getCFBasicBlockNode(succ));
155
+ }
156
+ }
157
+ }
158
+ }
159
+