svf-tools 1.0.1001 → 1.0.1003

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.1001",
3
+ "version": "1.0.1003",
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": {
@@ -189,6 +189,11 @@ public:
189
189
 
190
190
  }
191
191
 
192
+ inline const std::string &getName() const
193
+ {
194
+ return fun->getName();
195
+ }
196
+
192
197
  /// Get function of this call node
193
198
  inline const SVFFunction* getFunction() const
194
199
  {
@@ -254,8 +259,6 @@ public:
254
259
  };
255
260
 
256
261
  private:
257
- CGEK kind;
258
-
259
262
  /// Indirect call map
260
263
  CallEdgeMap indirectCallMap;
261
264
 
@@ -270,6 +273,7 @@ protected:
270
273
 
271
274
  NodeID callGraphNodeNum;
272
275
  u32_t numOfResolvedIndCallEdge;
276
+ CGEK kind;
273
277
 
274
278
  /// Clean up memory
275
279
  void destroy();
@@ -278,7 +282,9 @@ public:
278
282
  /// Constructor
279
283
  CallGraph(CGEK k = NormCallGraph);
280
284
 
281
- /// Add callgraph Node
285
+ /// Copy constructor
286
+ CallGraph(const CallGraph& other);
287
+
282
288
  void addCallGraphNode(const SVFFunction* fun);
283
289
 
284
290
  /// Destructor
@@ -172,7 +172,10 @@ public:
172
172
  typedef Map<const CallICFGNode*, ParForEdgeSet> CallInstToParForEdgesMap;
173
173
 
174
174
  /// Constructor
175
- ThreadCallGraph();
175
+ ThreadCallGraph(const CallGraph& cg);
176
+
177
+ ThreadCallGraph(ThreadCallGraph& cg) = delete;
178
+
176
179
  /// Destructor
177
180
  virtual ~ThreadCallGraph()
178
181
  {
@@ -98,6 +98,7 @@ private:
98
98
  ICFG* icfg; // ICFG
99
99
  CommonCHGraph* chgraph; // class hierarchy graph
100
100
  CallSiteSet callSiteSet; /// all the callsites of a program
101
+ CallGraph* callGraph; /// call graph
101
102
 
102
103
  static std::unique_ptr<SVFIR> pag; ///< Singleton pattern here to enable instance of SVFIR can only be created once.
103
104
 
@@ -182,6 +183,18 @@ public:
182
183
  assert(chgraph && "empty ICFG! Build SVF IR first!");
183
184
  return chgraph;
184
185
  }
186
+
187
+ /// Set/Get CG
188
+ inline void setCallGraph(CallGraph* c)
189
+ {
190
+ callGraph = c;
191
+ }
192
+ inline CallGraph* getCallGraph()
193
+ {
194
+ assert(callGraph && "empty CallGraph! Build SVF IR first!");
195
+ return callGraph;
196
+ }
197
+
185
198
  /// Get/set methods to get SVFStmts based on their kinds and ICFGNodes
186
199
  //@{
187
200
  /// Get edges set according to its kind
@@ -130,23 +130,6 @@ public:
130
130
 
131
131
  /// Iterators
132
132
  ///@{
133
- iterator begin()
134
- {
135
- return FunctionSet.begin();
136
- }
137
- const_iterator begin() const
138
- {
139
- return FunctionSet.begin();
140
- }
141
- iterator end()
142
- {
143
- return FunctionSet.end();
144
- }
145
- const_iterator end() const
146
- {
147
- return FunctionSet.end();
148
- }
149
-
150
133
  global_iterator global_begin()
151
134
  {
152
135
  return GlobalSet.begin();
@@ -38,34 +38,18 @@ namespace SVF
38
38
  {
39
39
 
40
40
  class ICFG;
41
+ class SVFModule;
41
42
 
42
43
  class CallGraphBuilder
43
44
  {
44
-
45
- protected:
46
- CallGraph* callgraph;
47
- ICFG* icfg;
48
45
  public:
49
- CallGraphBuilder(CallGraph* cg, ICFG* i): callgraph(cg),icfg(i)
50
- {
51
- }
52
-
53
- /// Build normal callgraph
54
- CallGraph* buildCallGraph(SVFModule* svfModule);
55
-
56
- };
46
+ CallGraphBuilder()=default;
57
47
 
58
- class ThreadCallGraphBuilder : public CallGraphBuilder
59
- {
60
-
61
- public:
62
- ThreadCallGraphBuilder(ThreadCallGraph* cg, ICFG* i): CallGraphBuilder(cg,i)
63
- {
64
- }
48
+ /// Buidl SVFIR callgraoh
49
+ CallGraph* buildSVFIRCallGraph(SVFModule* svfModule);
65
50
 
66
51
  /// Build thread-aware callgraph
67
- CallGraph* buildThreadCallGraph(SVFModule* svfModule);
68
-
52
+ ThreadCallGraph* buildThreadCallGraph();
69
53
  };
70
54
 
71
55
  } // End namespace SVF
@@ -327,29 +327,11 @@ inline bool isProgEntryFunction(const SVFFunction* fun)
327
327
  return fun && fun->getName() == "main";
328
328
  }
329
329
 
330
- /// Get program entry function from module.
331
- inline const SVFFunction* getProgFunction(SVFModule* svfModule, const std::string& funName)
332
- {
333
- for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
334
- {
335
- const SVFFunction *fun = *it;
336
- if (fun->getName()==funName)
337
- return fun;
338
- }
339
- return nullptr;
340
- }
330
+ /// Get program entry function from function name.
331
+ const SVFFunction* getProgFunction(const std::string& funName);
341
332
 
342
- /// Get program entry function from module.
343
- inline const SVFFunction* getProgEntryFunction(SVFModule* svfModule)
344
- {
345
- for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
346
- {
347
- const SVFFunction *fun = *it;
348
- if (isProgEntryFunction(fun))
349
- return (fun);
350
- }
351
- return nullptr;
352
- }
333
+ /// Get program entry function.
334
+ const SVFFunction* getProgEntryFunction();
353
335
 
354
336
  /// Return true if this is a program exit function call
355
337
  //@{
@@ -112,6 +112,39 @@ CallGraph::CallGraph(CGEK k): kind(k)
112
112
  numOfResolvedIndCallEdge = 0;
113
113
  }
114
114
 
115
+ /// Copy constructor
116
+ CallGraph::CallGraph(const CallGraph& other)
117
+ {
118
+ callGraphNodeNum = other.callGraphNodeNum;
119
+ numOfResolvedIndCallEdge = 0;
120
+ kind = other.kind;
121
+
122
+ /// copy call graph nodes
123
+ for (const auto& item : other)
124
+ {
125
+ const CallGraphNode* cgn = item.second;
126
+ CallGraphNode* callGraphNode = new CallGraphNode(cgn->getId(), cgn->getFunction());
127
+ addGNode(cgn->getId(),callGraphNode);
128
+ funToCallGraphNodeMap[cgn->getFunction()] = callGraphNode;
129
+ }
130
+
131
+ /// copy edges
132
+ for (const auto& item : other.callinstToCallGraphEdgesMap)
133
+ {
134
+ const CallICFGNode* cs = item.first;
135
+ for (const CallGraphEdge* edge : item.second)
136
+ {
137
+ CallGraphNode* src = getCallGraphNode(edge->getSrcID());
138
+ CallGraphNode* dst = getCallGraphNode(edge->getDstID());
139
+ CallGraphEdge* newEdge = new CallGraphEdge(src,dst,CallGraphEdge::CallRetEdge,edge->getCallSiteID());
140
+ newEdge->addDirectCallSite(cs);
141
+ addEdge(newEdge);
142
+ callinstToCallGraphEdgesMap[cs].insert(newEdge);
143
+ }
144
+ }
145
+
146
+ }
147
+
115
148
  /*!
116
149
  * Memory has been cleaned up at GenericGraph
117
150
  */
@@ -124,10 +157,10 @@ void CallGraph::destroy()
124
157
  */
125
158
  void CallGraph::addCallGraphNode(const SVFFunction* fun)
126
159
  {
127
- NodeID id = callGraphNodeNum;
128
- CallGraphNode* callGraphNode = new CallGraphNode(id, fun);
129
- addGNode(id,callGraphNode);
130
- funToCallGraphNodeMap[fun] = callGraphNode;
160
+ NodeID id = callGraphNodeNum;
161
+ CallGraphNode *callGraphNode = new CallGraphNode(id, fun);
162
+ addGNode(id, callGraphNode);
163
+ funToCallGraphNodeMap[callGraphNode->getFunction()] = callGraphNode;
131
164
  callGraphNodeNum++;
132
165
  }
133
166
 
@@ -427,9 +427,7 @@ void SVFG::connectIndirectSVFGEdges()
427
427
  */
428
428
  void SVFG::connectFromGlobalToProgEntry()
429
429
  {
430
- SVFModule* svfModule = mssa->getPTA()->getModule();
431
- const SVFFunction* mainFunc =
432
- SVFUtil::getProgEntryFunction(svfModule);
430
+ const SVFFunction* mainFunc = SVFUtil::getProgEntryFunction();
433
431
  FormalINSVFGNodeSet& formalIns = getFormalINSVFGNodes(mainFunc);
434
432
  if (formalIns.empty())
435
433
  return;
@@ -39,9 +39,10 @@ using namespace SVFUtil;
39
39
  /*!
40
40
  * Constructor
41
41
  */
42
- ThreadCallGraph::ThreadCallGraph() :
43
- CallGraph(ThdCallGraph), tdAPI(ThreadAPI::getThreadAPI())
42
+ ThreadCallGraph::ThreadCallGraph(const CallGraph& cg) :
43
+ CallGraph(cg), tdAPI(ThreadAPI::getThreadAPI())
44
44
  {
45
+ kind = ThdCallGraph;
45
46
  DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Building ThreadCallGraph\n"));
46
47
  }
47
48
 
@@ -173,11 +173,10 @@ SVFIR::SVFStmtList& MRGenerator::getPAGEdgesFromInst(const ICFGNode* node)
173
173
  void MRGenerator::collectModRefForLoadStore()
174
174
  {
175
175
 
176
- SVFModule* svfModule = pta->getModule();
177
- for (SVFModule::const_iterator fi = svfModule->begin(), efi = svfModule->end(); fi != efi;
178
- ++fi)
176
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
177
+ for (const auto& item: *svfirCallGraph)
179
178
  {
180
- const SVFFunction& fun = **fi;
179
+ const SVFFunction& fun = *item.second->getFunction();
181
180
 
182
181
  /// if this function does not have any caller, then we do not care its MSSA
183
182
  if (Options::IgnoreDeadFun() && fun.isUncalledFunction())
@@ -575,10 +575,10 @@ u32_t MemSSA::getBBPhiNum() const
575
575
  void MemSSA::dumpMSSA(OutStream& Out)
576
576
  {
577
577
 
578
- for (SVFModule::iterator fit = pta->getModule()->begin(), efit = pta->getModule()->end();
579
- fit != efit; ++fit)
578
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
579
+ for (const auto& item: *svfirCallGraph)
580
580
  {
581
- const SVFFunction* fun = *fit;
581
+ const SVFFunction* fun = item.second->getFunction();
582
582
  if(Options::MSSAFun()!="" && Options::MSSAFun()!=fun->getName())
583
583
  continue;
584
584
 
@@ -101,12 +101,11 @@ std::unique_ptr<MemSSA> SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM
101
101
 
102
102
  auto mssa = std::make_unique<MemSSA>(pta, ptrOnlyMSSA);
103
103
 
104
- SVFModule* svfModule = mssa->getPTA()->getModule();
105
- for (SVFModule::const_iterator iter = svfModule->begin(), eiter = svfModule->end();
106
- iter != eiter; ++iter)
104
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
105
+ for (const auto& item: *svfirCallGraph)
107
106
  {
108
107
 
109
- const SVFFunction *fun = *iter;
108
+ const SVFFunction *fun = item.second->getFunction();
110
109
  if (isExtCall(fun))
111
110
  continue;
112
111
 
@@ -185,9 +185,10 @@ void TCT::markRelProcs(const SVFFunction* svffun)
185
185
  */
186
186
  void TCT::collectEntryFunInCallGraph()
187
187
  {
188
- for(SVFModule::const_iterator it = getSVFModule()->begin(), eit = getSVFModule()->end(); it!=eit; ++it)
188
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
189
+ for (const auto& item: *svfirCallGraph)
189
190
  {
190
- const SVFFunction* fun = (*it);
191
+ const SVFFunction* fun = item.second->getFunction();
191
192
  if (SVFUtil::isExtCall(fun))
192
193
  continue;
193
194
  CallGraphNode* node = tcg->getCallGraphNode(fun);
@@ -111,15 +111,13 @@ void PointerAnalysis::initialize()
111
111
  /// initialise pta call graph for every pointer analysis instance
112
112
  if(Options::EnableThreadCallGraph())
113
113
  {
114
- ThreadCallGraph* cg = new ThreadCallGraph();
115
- ThreadCallGraphBuilder bd(cg, pag->getICFG());
116
- callgraph = bd.buildThreadCallGraph(pag->getModule());
114
+ CallGraphBuilder bd;
115
+ callgraph = bd.buildThreadCallGraph();
117
116
  }
118
117
  else
119
118
  {
120
- CallGraph* cg = new CallGraph();
121
- CallGraphBuilder bd(cg,pag->getICFG());
122
- callgraph = bd.buildCallGraph(pag->getModule());
119
+ CallGraph* cg = pag->getCallGraph();
120
+ callgraph = new CallGraph(*cg);
123
121
  }
124
122
  callGraphSCCDetection();
125
123
 
@@ -59,8 +59,10 @@ void SaberCondAllocator::allocate(const SVFModule *M)
59
59
  {
60
60
  DBOUT(DGENERAL, outs() << pasMsg("path condition allocation starts\n"));
61
61
 
62
- for (const auto &func: *M)
62
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
63
+ for (const auto& item: *svfirCallGraph)
63
64
  {
65
+ const SVFFunction *func = (item.second)->getFunction();
64
66
  if (!SVFUtil::isExtCall(func))
65
67
  {
66
68
  // Allocate conditions for a program.
@@ -544,6 +544,8 @@ void SVFIR::destroy()
544
544
  chgraph = nullptr;
545
545
  SVFModule::releaseSVFModule();
546
546
  svfModule = nullptr;
547
+ delete callGraph;
548
+ callGraph = nullptr;
547
549
  }
548
550
 
549
551
  /*!
@@ -27,6 +27,7 @@
27
27
  * Author: Xiao Cheng
28
28
  */
29
29
  #include "Util/CDGBuilder.h"
30
+ #include "Graphs/CallGraph.h"
30
31
 
31
32
  using namespace SVF;
32
33
  using namespace SVFUtil;
@@ -122,8 +123,10 @@ s64_t CDGBuilder::getBBSuccessorBranchID(const SVFBasicBlock *BB, const SVFBasic
122
123
  */
123
124
  void CDGBuilder::buildControlDependence(const SVFModule *svfgModule)
124
125
  {
125
- for (const auto &svfFun: *svfgModule)
126
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
127
+ for (const auto& item: *svfirCallGraph)
126
128
  {
129
+ const SVFFunction *svfFun = (item.second)->getFunction();
127
130
  if (SVFUtil::isExtCall(svfFun)) continue;
128
131
  // extract basic block edges to be processed
129
132
  Map<const SVFBasicBlock *, std::vector<const SVFBasicBlock *>> BBS;
@@ -36,18 +36,17 @@
36
36
  using namespace SVF;
37
37
  using namespace SVFUtil;
38
38
 
39
- CallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule)
39
+ CallGraph* CallGraphBuilder::buildSVFIRCallGraph(SVFModule* svfModule)
40
40
  {
41
- /// create nodes
42
- for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F)
41
+ CallGraph* callgraph = new CallGraph();
42
+ for (const SVFFunction* svfFunc: svfModule->getFunctionSet())
43
43
  {
44
- callgraph->addCallGraphNode(*F);
44
+ callgraph->addCallGraphNode(svfFunc);
45
45
  }
46
46
 
47
- /// create edges
48
- for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F)
47
+ for (const auto& item : *callgraph)
49
48
  {
50
- for (const SVFBasicBlock* svfbb : (*F)->getBasicBlockList())
49
+ for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
51
50
  {
52
51
  for (const ICFGNode* inst : svfbb->getICFGNodeList())
53
52
  {
@@ -56,28 +55,24 @@ CallGraph* CallGraphBuilder::buildCallGraph(SVFModule* svfModule)
56
55
  const CallICFGNode* callBlockNode = cast<CallICFGNode>(inst);
57
56
  if(const SVFFunction* callee = callBlockNode->getCalledFunction())
58
57
  {
59
- callgraph->addDirectCallGraphEdge(callBlockNode,*F,callee);
58
+ callgraph->addDirectCallGraphEdge(callBlockNode,(item.second)->getFunction(),callee);
60
59
  }
61
60
  }
62
61
  }
63
62
  }
64
63
  }
65
-
66
64
  return callgraph;
67
65
  }
68
66
 
69
- CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
67
+ ThreadCallGraph* CallGraphBuilder::buildThreadCallGraph()
70
68
  {
71
-
72
- buildCallGraph(svfModule);
73
-
74
- ThreadCallGraph* cg = dyn_cast<ThreadCallGraph>(callgraph);
75
- assert(cg && "not a thread callgraph?");
69
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
70
+ ThreadCallGraph* cg = new ThreadCallGraph(*svfirCallGraph);
76
71
 
77
72
  ThreadAPI* tdAPI = ThreadAPI::getThreadAPI();
78
- for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F)
73
+ for (const auto& item: *svfirCallGraph)
79
74
  {
80
- for (const SVFBasicBlock* svfbb : (*F)->getBasicBlockList())
75
+ for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
81
76
  {
82
77
  for (const ICFGNode* inst : svfbb->getICFGNodeList())
83
78
  {
@@ -100,9 +95,9 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
100
95
  }
101
96
  }
102
97
  // record join sites
103
- for (SVFModule::const_iterator F = svfModule->begin(), E = svfModule->end(); F != E; ++F)
98
+ for (const auto& item: *svfirCallGraph)
104
99
  {
105
- for (const SVFBasicBlock* svfbb : (*F)->getBasicBlockList())
100
+ for (const SVFBasicBlock* svfbb : (item.second)->getFunction()->getBasicBlockList())
106
101
  {
107
102
  for (const ICFGNode* node : svfbb->getICFGNodeList())
108
103
  {
@@ -117,7 +112,3 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
117
112
 
118
113
  return cg;
119
114
  }
120
-
121
-
122
-
123
-
@@ -214,13 +214,12 @@ void SVFStat::performStat()
214
214
 
215
215
  void SVFStat::branchStat()
216
216
  {
217
- SVFModule* module = SVFIR::getPAG()->getModule();
218
217
  u32_t numOfBB_2Succ = 0;
219
218
  u32_t numOfBB_3Succ = 0;
220
- for (SVFModule::const_iterator funIter = module->begin(), funEiter = module->end();
221
- funIter != funEiter; ++funIter)
219
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
220
+ for (const auto& item: *svfirCallGraph)
222
221
  {
223
- const SVFFunction* func = *funIter;
222
+ const SVFFunction* func = item.second->getFunction();
224
223
  for (SVFFunction::const_iterator bbIt = func->begin(), bbEit = func->end();
225
224
  bbIt != bbEit; ++bbIt)
226
225
  {
@@ -396,4 +396,30 @@ bool SVFUtil::isRetInstNode(const ICFGNode* node)
396
396
  bool SVFUtil::isProgExitCall(const CallICFGNode* cs)
397
397
  {
398
398
  return isProgExitFunction(cs->getCalledFunction());
399
+ }
400
+
401
+ /// Get program entry function from module.
402
+ const SVFFunction* SVFUtil::getProgFunction(const std::string& funName)
403
+ {
404
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
405
+ for (const auto& item: *svfirCallGraph)
406
+ {
407
+ const CallGraphNode*fun = item.second;
408
+ if (fun->getName()==funName)
409
+ return fun->getFunction();
410
+ }
411
+ return nullptr;
412
+ }
413
+
414
+ /// Get program entry function from module.
415
+ const SVFFunction* SVFUtil::getProgEntryFunction()
416
+ {
417
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
418
+ for (const auto& item: *svfirCallGraph)
419
+ {
420
+ const CallGraphNode*fun = item.second;
421
+ if (isProgEntryFunction(fun->getFunction()))
422
+ return (fun->getFunction());
423
+ }
424
+ return nullptr;
399
425
  }
@@ -33,6 +33,7 @@
33
33
  #include "Util/ThreadAPI.h"
34
34
  #include "Util/SVFUtil.h"
35
35
  #include "SVFIR/SVFIR.h"
36
+ #include "Graphs/CallGraph.h"
36
37
 
37
38
  #include <iostream> /// std output
38
39
  #include <stdio.h>
@@ -269,9 +270,10 @@ void ThreadAPI::performAPIStat(SVFModule* module)
269
270
 
270
271
  statInit(tdAPIStatMap);
271
272
 
272
- for (SVFModule::const_iterator it = module->begin(), eit = module->end(); it != eit; ++it)
273
+ CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
274
+ for (const auto& item: *svfirCallGraph)
273
275
  {
274
- for (SVFFunction::const_iterator bit = (*it)->begin(), ebit = (*it)->end(); bit != ebit; ++bit)
276
+ for (SVFFunction::const_iterator bit = (item.second)->getFunction()->begin(), ebit = (item.second)->getFunction()->end(); bit != ebit; ++bit)
275
277
  {
276
278
  const SVFBasicBlock* bb = *bit;
277
279
  for (const auto& svfInst: bb->getICFGNodeList())
@@ -58,11 +58,11 @@ private:
58
58
  public:
59
59
  typedef FIFOWorkList<const Instruction*> WorkList;
60
60
 
61
- ICFGBuilder(ICFG* i): icfg(i)
61
+ ICFGBuilder(): icfg(new ICFG())
62
62
  {
63
63
 
64
64
  }
65
- void build();
65
+ ICFG* build();
66
66
 
67
67
  private:
68
68
 
@@ -76,6 +76,7 @@ private:
76
76
  static bool preProcessed;
77
77
  SymbolTableInfo* symInfo;
78
78
  SVFModule* svfModule; ///< Borrowed from singleton SVFModule::svfModule
79
+ ICFG* icfg;
79
80
  std::unique_ptr<LLVMContext> owned_ctx;
80
81
  std::vector<std::unique_ptr<Module>> owned_modules;
81
82
  std::vector<std::reference_wrapper<Module>> modules;
@@ -104,6 +105,7 @@ private:
104
105
  InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode
105
106
  FunToFunEntryNodeMapTy FunToFunEntryNodeMap; ///< map a function to its FunExitICFGNode
106
107
  FunToFunExitNodeMapTy FunToFunExitNodeMap; ///< map a function to its FunEntryICFGNode
108
+ CallGraph* callgraph;
107
109
 
108
110
  /// Constructor
109
111
  LLVMModuleSet();
@@ -362,6 +364,11 @@ public:
362
364
 
363
365
  ObjTypeInference* getTypeInference();
364
366
 
367
+ inline ICFG* getICFG()
368
+ {
369
+ return icfg;
370
+ }
371
+
365
372
  private:
366
373
  /// Create SVFTypes
367
374
  SVFType* addSVFTypeInfo(const Type* t);
@@ -40,7 +40,7 @@ using namespace SVFUtil;
40
40
  /*!
41
41
  * Create ICFG nodes and edges
42
42
  */
43
- void ICFGBuilder::build()
43
+ ICFG* ICFGBuilder::build()
44
44
  {
45
45
  DBOUT(DGENERAL, outs() << pasMsg("\t Building ICFG ...\n"));
46
46
  // Add the unique global ICFGNode at the entry of a program (before the main method).
@@ -78,6 +78,7 @@ void ICFGBuilder::build()
78
78
 
79
79
  }
80
80
  connectGlobalToProgEntry();
81
+ return icfg;
81
82
  }
82
83
 
83
84
  void ICFGBuilder::checkICFGNodesVisited(const Function* fun)
@@ -235,8 +236,6 @@ void ICFGBuilder::processFunExit(const Function* f)
235
236
  */
236
237
  InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
237
238
  {
238
- SVFInstruction* svfInst =
239
- llvmModuleSet()->getSVFInstruction(inst);
240
239
  assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
241
240
  assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
242
241
  assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
@@ -254,8 +253,10 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
254
253
  llvmModuleSet()->getSVFValue(called_llvmval));
255
254
  }
256
255
 
256
+ SVFBasicBlock* bb = llvmModuleSet()->getSVFBasicBlock(inst->getParent());
257
+
257
258
  CallICFGNode* callICFGNode = icfg->addCallICFGNode(
258
- svfInst->getParent(), llvmModuleSet()->getSVFType(inst->getType()),
259
+ bb, llvmModuleSet()->getSVFType(inst->getType()),
259
260
  calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
260
261
  isvcall ? cppUtil::getVCallIdx(cb) : 0,
261
262
  isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
@@ -330,25 +331,22 @@ void ICFGBuilder::connectGlobalToProgEntry()
330
331
  inline ICFGNode* ICFGBuilder::addBlockICFGNode(const Instruction* inst)
331
332
  {
332
333
  ICFGNode* node;
333
- SVFInstruction* svfINst =
334
- llvmModuleSet()->getSVFInstruction(inst);
335
334
  if(LLVMUtil::isNonInstricCallSite(inst))
336
335
  node = addInterBlockICFGNode(inst);
337
336
  else
338
337
  node = addIntraBlockICFGNode(inst);
339
- const_cast<SVFBasicBlock*>(svfINst->getParent())
338
+ const_cast<SVFBasicBlock*>(
339
+ llvmModuleSet()->getSVFBasicBlock(inst->getParent()))
340
340
  ->addICFGNode(node);
341
341
  return node;
342
342
  }
343
343
 
344
344
  IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
345
345
  {
346
- SVFInstruction* svfInst =
347
- llvmModuleSet()->getSVFInstruction(inst);
348
346
  IntraICFGNode* node = llvmModuleSet()->getIntraBlock(inst);
349
347
  assert (node==nullptr && "no IntraICFGNode for this instruction?");
350
348
  IntraICFGNode* sNode = icfg->addIntraICFGNode(
351
- svfInst->getParent(), SVFUtil::isa<ReturnInst>(inst));
349
+ llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
352
350
  instToBlockNodeMap()[inst] = sNode;
353
351
  llvmModuleSet()->setValueAttr(inst, sNode);
354
352
  return sNode;
@@ -40,6 +40,9 @@
40
40
  #include "llvm/Support/FileSystem.h"
41
41
  #include "SVF-LLVM/ObjTypeInference.h"
42
42
  #include "llvm/Transforms/Utils/Cloning.h"
43
+ #include "SVF-LLVM/ICFGBuilder.h"
44
+ #include "Graphs/CallGraph.h"
45
+ #include "Util/CallGraphBuilder.h"
43
46
 
44
47
  using namespace std;
45
48
  using namespace SVF;
@@ -166,6 +169,11 @@ void LLVMModuleSet::build()
166
169
 
167
170
  createSVFDataStructure();
168
171
  initSVFFunction();
172
+ ICFGBuilder icfgbuilder;
173
+ icfg = icfgbuilder.build();
174
+
175
+ CallGraphBuilder callGraphBuilder;
176
+ callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);
169
177
  }
170
178
 
171
179
  void LLVMModuleSet::createSVFDataStructure()
@@ -38,6 +38,7 @@
38
38
  #include "SVFIR/SVFFileSystem.h"
39
39
  #include "SVFIR/SVFModule.h"
40
40
  #include "SVFIR/SVFValue.h"
41
+ #include "Util/CallGraphBuilder.h"
41
42
  #include "Util/Options.h"
42
43
  #include "Util/SVFUtil.h"
43
44
 
@@ -60,10 +61,10 @@ SVFIR* SVFIRBuilder::build()
60
61
  pag->setModule(svfModule);
61
62
 
62
63
  // Build ICFG
63
- ICFG* icfg = new ICFG();
64
- ICFGBuilder icfgbuilder(icfg);
65
- icfgbuilder.build();
66
- pag->setICFG(icfg);
64
+ pag->setICFG(llvmModuleSet()->getICFG());
65
+
66
+ // Set callgraph
67
+ pag->setCallGraph(llvmModuleSet()->callgraph);
67
68
 
68
69
  // Set icfgnode in memobj
69
70
  for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())