svf-tools 1.0.1002 → 1.0.1004

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.1002",
3
+ "version": "1.0.1004",
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
@@ -143,7 +143,7 @@ protected:
143
143
  /// Add intraprocedural and interprocedural control-flow edges.
144
144
  //@{
145
145
  ICFGEdge* addIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode);
146
- ICFGEdge* addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFValue* condition, s32_t branchCondVal);
146
+ ICFGEdge* addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, s64_t branchCondVal);
147
147
  ICFGEdge* addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode);
148
148
  ICFGEdge* addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode);
149
149
  //@}
@@ -114,6 +114,8 @@ class IntraCFGEdge : public ICFGEdge
114
114
  {
115
115
  friend class SVFIRWriter;
116
116
  friend class SVFIRReader;
117
+ friend class ICFG;
118
+ friend class SVFIRBuilder;
117
119
 
118
120
  public:
119
121
  /// Constructor
@@ -137,7 +139,7 @@ public:
137
139
  }
138
140
  //@}
139
141
 
140
- const SVFValue* getCondition() const
142
+ const SVFVar* getCondition() const
141
143
  {
142
144
  return conditionVar;
143
145
  }
@@ -148,12 +150,6 @@ public:
148
150
  return branchCondVal;
149
151
  }
150
152
 
151
- void setBranchCondition(const SVFValue* c, s64_t bVal)
152
- {
153
- conditionVar = c;
154
- branchCondVal = bVal;
155
- }
156
-
157
153
  virtual const std::string toString() const;
158
154
 
159
155
  private:
@@ -166,8 +162,18 @@ private:
166
162
  /// Inst3: label 1;
167
163
  /// for edge between Inst1 and Inst 2, the first element is %cmp and
168
164
  /// the second element is 0
169
- const SVFValue* conditionVar;
165
+ const SVFVar* conditionVar;
170
166
  s64_t branchCondVal;
167
+
168
+ inline void setConditionVar(const SVFVar* c)
169
+ {
170
+ conditionVar = c;
171
+ }
172
+
173
+ inline void setBranchCondVal(s64_t bVal)
174
+ {
175
+ branchCondVal = bVal;
176
+ }
171
177
  };
172
178
 
173
179
  /*!
@@ -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
  //@{
@@ -452,9 +452,7 @@ bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t suc
452
452
  bool AbstractInterpretation::isBranchFeasible(const IntraCFGEdge* intraEdge,
453
453
  AbstractState& as)
454
454
  {
455
- const SVFValue *cond = intraEdge->getCondition();
456
- NodeID cmpID = svfir->getValueNode(cond);
457
- SVFVar *cmpVar = svfir->getGNode(cmpID);
455
+ const SVFVar *cmpVar = intraEdge->getCondition();
458
456
  if (cmpVar->getInEdges().empty())
459
457
  {
460
458
  return isSwitchBranchFeasible(cmpVar,
@@ -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
 
@@ -341,7 +341,7 @@ ICFGEdge* ICFG::addIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode)
341
341
  /*!
342
342
  * Add conditional intraprocedural edges between two nodes
343
343
  */
344
- ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, const SVFValue* condition, s32_t branchCondVal)
344
+ ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, s64_t branchCondVal)
345
345
  {
346
346
 
347
347
  checkIntraEdgeParents(srcNode, dstNode);
@@ -354,7 +354,7 @@ ICFGEdge* ICFG::addConditionalIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode, co
354
354
  else
355
355
  {
356
356
  IntraCFGEdge* intraEdge = new IntraCFGEdge(srcNode,dstNode);
357
- intraEdge->setBranchCondition(condition,branchCondVal);
357
+ intraEdge->setBranchCondVal(branchCondVal);
358
358
  return (addICFGEdge(intraEdge) ? intraEdge : nullptr);
359
359
  }
360
360
  }
@@ -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())
@@ -105,6 +105,7 @@ private:
105
105
  InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode
106
106
  FunToFunEntryNodeMapTy FunToFunEntryNodeMap; ///< map a function to its FunExitICFGNode
107
107
  FunToFunExitNodeMapTy FunToFunExitNodeMap; ///< map a function to its FunEntryICFGNode
108
+ CallGraph* callgraph;
108
109
 
109
110
  /// Constructor
110
111
  LLVMModuleSet();
@@ -157,7 +157,7 @@ void ICFGBuilder::processFunBody(WorkList& worklist)
157
157
  }
158
158
  InstVec nextInsts;
159
159
  LLVMUtil::getNextInsts(inst, nextInsts);
160
- u32_t branchID = 0;
160
+ s64_t branchID = 0;
161
161
  for (InstVec::const_iterator nit = nextInsts.begin(), enit =
162
162
  nextInsts.end(); nit != enit; ++nit)
163
163
  {
@@ -185,7 +185,7 @@ void ICFGBuilder::processFunBody(WorkList& worklist)
185
185
  {
186
186
  assert(branchID <= 1 && "if/else has more than two branches?");
187
187
  if(br->isConditional())
188
- icfg->addConditionalIntraEdge(srcNode, dstNode, llvmModuleSet()->getSVFValue(br->getCondition()), 1 - branchID);
188
+ icfg->addConditionalIntraEdge(srcNode, dstNode, 1 - branchID);
189
189
  else
190
190
  icfg->addIntraEdge(srcNode, dstNode);
191
191
  }
@@ -197,7 +197,7 @@ void ICFGBuilder::processFunBody(WorkList& worklist)
197
197
  s64_t val = -1;
198
198
  if (condVal && condVal->getBitWidth() <= 64)
199
199
  val = condVal->getSExtValue();
200
- icfg->addConditionalIntraEdge(srcNode, dstNode, llvmModuleSet()->getSVFValue(si->getCondition()),val);
200
+ icfg->addConditionalIntraEdge(srcNode, dstNode,val);
201
201
  }
202
202
  else
203
203
  icfg->addIntraEdge(srcNode, dstNode);
@@ -41,6 +41,8 @@
41
41
  #include "SVF-LLVM/ObjTypeInference.h"
42
42
  #include "llvm/Transforms/Utils/Cloning.h"
43
43
  #include "SVF-LLVM/ICFGBuilder.h"
44
+ #include "Graphs/CallGraph.h"
45
+ #include "Util/CallGraphBuilder.h"
44
46
 
45
47
  using namespace std;
46
48
  using namespace SVF;
@@ -169,6 +171,9 @@ void LLVMModuleSet::build()
169
171
  initSVFFunction();
170
172
  ICFGBuilder icfgbuilder;
171
173
  icfg = icfgbuilder.build();
174
+
175
+ CallGraphBuilder callGraphBuilder;
176
+ callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);
172
177
  }
173
178
 
174
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
 
@@ -62,6 +63,9 @@ SVFIR* SVFIRBuilder::build()
62
63
  // Build ICFG
63
64
  pag->setICFG(llvmModuleSet()->getICFG());
64
65
 
66
+ // Set callgraph
67
+ pag->setCallGraph(llvmModuleSet()->callgraph);
68
+
65
69
  // Set icfgnode in memobj
66
70
  for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())
67
71
  {
@@ -971,6 +975,17 @@ void SVFIRBuilder::visitBranchInst(BranchInst &inst)
971
975
  branchID++;
972
976
  }
973
977
  addBranchStmt(brinst, cond, successors);
978
+ /// set conditional svf var
979
+ if (inst.isConditional())
980
+ {
981
+ for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
982
+ {
983
+ if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
984
+ {
985
+ intraEdge->setConditionVar(pag->getGNode(cond));
986
+ }
987
+ }
988
+ }
974
989
  }
975
990
 
976
991
 
@@ -1039,6 +1054,14 @@ void SVFIRBuilder::visitSwitchInst(SwitchInst &inst)
1039
1054
  successors.push_back(std::make_pair(icfgNode, val));
1040
1055
  }
1041
1056
  addBranchStmt(brinst, cond, successors);
1057
+ /// set conditional svf var
1058
+ for (auto& edge : llvmModuleSet()->getICFGNode(&inst)->getOutEdges())
1059
+ {
1060
+ if (IntraCFGEdge* intraEdge = SVFUtil::dyn_cast<IntraCFGEdge>(edge))
1061
+ {
1062
+ intraEdge->setConditionVar(pag->getGNode(cond));
1063
+ }
1064
+ }
1042
1065
  }
1043
1066
 
1044
1067