svf-tools 1.0.1000 → 1.0.1002

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.1000",
3
+ "version": "1.0.1002",
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": {
@@ -172,6 +172,49 @@ protected:
172
172
  }
173
173
  }
174
174
 
175
+ virtual inline IntraICFGNode* addIntraICFGNode(const SVFBasicBlock* bb, bool isRet)
176
+ {
177
+ IntraICFGNode* intraIcfgNode =
178
+ new IntraICFGNode(totalICFGNode++, bb, isRet);
179
+ addICFGNode(intraIcfgNode);
180
+ return intraIcfgNode;
181
+ }
182
+
183
+ virtual inline CallICFGNode* addCallICFGNode(
184
+ const SVFBasicBlock* bb, const SVFType* ty,
185
+ const SVFFunction* calledFunc, bool isVararg, bool isvcall,
186
+ s32_t vcallIdx, const std::string& funNameOfVcall)
187
+ {
188
+
189
+ CallICFGNode* callICFGNode =
190
+ new CallICFGNode(totalICFGNode++, bb, ty, calledFunc, isVararg,
191
+ isvcall, vcallIdx, funNameOfVcall);
192
+ addICFGNode(callICFGNode);
193
+ return callICFGNode;
194
+ }
195
+
196
+ virtual inline RetICFGNode* addRetICFGNode(CallICFGNode* call)
197
+ {
198
+ RetICFGNode* retICFGNode = new RetICFGNode(totalICFGNode++, call);
199
+ call->setRetICFGNode(retICFGNode);
200
+ addICFGNode(retICFGNode);
201
+ return retICFGNode;
202
+ }
203
+
204
+ virtual inline FunEntryICFGNode* addFunEntryICFGNode(const SVFFunction* svfFunc)
205
+ {
206
+ FunEntryICFGNode* sNode = new FunEntryICFGNode(totalICFGNode++,svfFunc);
207
+ addICFGNode(sNode);
208
+ return FunToFunEntryNodeMap[svfFunc] = sNode;
209
+ }
210
+
211
+ virtual inline FunExitICFGNode* addFunExitICFGNode(const SVFFunction* svfFunc)
212
+ {
213
+ FunExitICFGNode* sNode = new FunExitICFGNode(totalICFGNode++, svfFunc);
214
+ addICFGNode(sNode);
215
+ return FunToFunExitNodeMap[svfFunc] = sNode;
216
+ }
217
+
175
218
  /// Add a ICFG node
176
219
  virtual inline void addICFGNode(ICFGNode* node)
177
220
  {
@@ -428,19 +428,28 @@ public:
428
428
  typedef std::vector<const SVFVar *> ActualParmNodeVec;
429
429
 
430
430
  protected:
431
- const SVFInstruction* cs;
432
431
  const RetICFGNode* ret;
433
- ActualParmNodeVec APNodes;
432
+ ActualParmNodeVec APNodes; /// arguments
433
+ const SVFFunction* calledFunc; /// called function
434
+ bool isvararg; /// is variable argument
435
+ bool isVirCallInst; /// is virtual call inst
436
+ SVFVar* vtabPtr; /// virtual table pointer
437
+ s32_t virtualFunIdx; /// virtual function index of the virtual table(s) at a virtual call
438
+ std::string funNameOfVcall; /// the function name of this virtual call
434
439
 
435
440
  /// Constructor to create empty CallICFGNode (for SVFIRReader/deserialization)
436
- CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock), cs{}, ret{} {}
441
+ CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock), ret{} {}
437
442
 
438
443
  public:
439
- CallICFGNode(NodeID id, const SVFInstruction* c, const SVFType* ty)
440
- : InterICFGNode(id, FunCallBlock), cs(c), ret(nullptr)
444
+ CallICFGNode(NodeID id, const SVFBasicBlock* b, const SVFType* ty,
445
+ const SVFFunction* cf, bool iv, bool ivc, s32_t vfi,
446
+ const std::string& fnv)
447
+ : InterICFGNode(id, FunCallBlock), ret(nullptr), calledFunc(cf),
448
+ isvararg(iv), isVirCallInst(ivc), vtabPtr(nullptr),
449
+ virtualFunIdx(vfi), funNameOfVcall(fnv)
441
450
  {
442
- fun = cs->getFunction();
443
- bb = cs->getParent();
451
+ fun = b->getFunction();
452
+ bb = b;
444
453
  type = ty;
445
454
  }
446
455
 
@@ -472,7 +481,7 @@ public:
472
481
  /// Return true if this is an indirect call
473
482
  inline bool isIndirectCall() const
474
483
  {
475
- return nullptr == SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
484
+ return nullptr == calledFunc;
476
485
  }
477
486
 
478
487
  /// Return the set of actual parameters
@@ -488,54 +497,61 @@ public:
488
497
  }
489
498
  /// Parameter operations
490
499
  //@{
491
- const SVFVar* getArgument(u32_t ArgNo) const
500
+ inline const SVFVar* getArgument(u32_t ArgNo) const
492
501
  {
493
502
  return getActualParms()[ArgNo];
494
503
  }
495
504
 
496
- u32_t arg_size() const
505
+ inline u32_t arg_size() const
497
506
  {
498
507
  return APNodes.size();
499
508
  }
500
- bool arg_empty() const
509
+ inline bool arg_empty() const
501
510
  {
502
511
  return APNodes.empty();
503
512
  }
504
513
 
505
- u32_t getNumArgOperands() const
514
+ inline u32_t getNumArgOperands() const
506
515
  {
507
516
  return arg_size();
508
517
  }
509
- const SVFFunction* getCalledFunction() const
518
+ inline const SVFFunction* getCalledFunction() const
510
519
  {
511
- return SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
520
+ return calledFunc;
512
521
  }
513
- const SVFValue* getCalledValue() const
522
+
523
+ inline bool isVarArg() const
514
524
  {
515
- return SVFUtil::cast<SVFCallInst>(cs)->getCalledOperand();
525
+ return isvararg;
516
526
  }
517
- bool isVarArg() const
527
+ inline bool isVirtualCall() const
518
528
  {
519
- return SVFUtil::cast<SVFCallInst>(cs)->isVarArg();
529
+ return isVirCallInst;
520
530
  }
521
- bool isVirtualCall() const
531
+
532
+ inline void setVtablePtr(SVFVar* v)
522
533
  {
523
- return SVFUtil::isa<SVFVirtualCallInst>(cs);
534
+ vtabPtr = v;
524
535
  }
525
- const SVFValue* getVtablePtr() const
536
+
537
+ inline const SVFVar* getVtablePtr() const
526
538
  {
527
539
  assert(isVirtualCall() && "not a virtual call?");
528
- return SVFUtil::cast<SVFVirtualCallInst>(cs)->getVtablePtr();
540
+ return vtabPtr;
529
541
  }
530
- s32_t getFunIdxInVtable() const
542
+
543
+
544
+ inline s32_t getFunIdxInVtable() const
531
545
  {
532
546
  assert(isVirtualCall() && "not a virtual call?");
533
- return SVFUtil::cast<SVFVirtualCallInst>(cs)->getFunIdxInVtable();
547
+ assert(virtualFunIdx >=0 && "virtual function idx is less than 0? not set yet?");
548
+ return virtualFunIdx;
534
549
  }
535
- const std::string& getFunNameOfVirtualCall() const
550
+
551
+ inline const std::string& getFunNameOfVirtualCall() const
536
552
  {
537
553
  assert(isVirtualCall() && "not a virtual call?");
538
- return SVFUtil::cast<SVFVirtualCallInst>(cs)->getFunNameOfVirtualCall();
554
+ return funNameOfVcall;
539
555
  }
540
556
  //@}
541
557
 
@@ -585,23 +601,22 @@ class RetICFGNode : public InterICFGNode
585
601
  friend class SVFIRReader;
586
602
 
587
603
  private:
588
- const SVFInstruction* cs;
589
604
  const SVFVar *actualRet;
590
605
  const CallICFGNode* callBlockNode;
591
606
 
592
607
  /// Constructor to create empty RetICFGNode (for SVFIRReader/deserialization)
593
608
  RetICFGNode(NodeID id)
594
- : InterICFGNode(id, FunRetBlock), cs{}, actualRet{}, callBlockNode{}
609
+ : InterICFGNode(id, FunRetBlock), actualRet{}, callBlockNode{}
595
610
  {
596
611
  }
597
612
 
598
613
  public:
599
- RetICFGNode(NodeID id, const SVFInstruction* c, CallICFGNode* cb) :
600
- InterICFGNode(id, FunRetBlock), cs(c), actualRet(nullptr), callBlockNode(cb)
614
+ RetICFGNode(NodeID id, CallICFGNode* cb) :
615
+ InterICFGNode(id, FunRetBlock), actualRet(nullptr), callBlockNode(cb)
601
616
  {
602
- fun = cs->getFunction();
603
- bb = cs->getParent();
604
- type = callBlockNode->getType();
617
+ fun = cb->getFun();
618
+ bb = cb->getBB();
619
+ type = cb->getType();
605
620
  }
606
621
 
607
622
  inline const CallICFGNode* getCallICFGNode() const
@@ -44,9 +44,10 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call
44
44
 
45
45
  if (cs->isVirtualCall())
46
46
  {
47
- const SVFValue* vtbl = cs->getVtablePtr();
48
- assert(pag->hasValueNode(vtbl));
49
- NodeID vtblId = pag->getValueNode(vtbl);
47
+ const SVFVar* vtbl = cs->getVtablePtr();
48
+
49
+ assert(vtbl != nullptr);
50
+ NodeID vtblId = vtbl->getId();
50
51
  resolveCPPIndCalls(cs, getCFLPts(vtblId), newEdges);
51
52
  }
52
53
  else
@@ -83,9 +83,9 @@ OrderedNodeSet& FunptrDDAClient::collectCandidateQueries(SVFIR* p)
83
83
  {
84
84
  if (it->first->isVirtualCall())
85
85
  {
86
- const SVFValue* vtblPtr = it->first->getVtablePtr();
87
- assert(pag->hasValueNode(vtblPtr) && "not a vtable pointer?");
88
- NodeID vtblId = pag->getValueNode(vtblPtr);
86
+ const SVFVar* vtblPtr = it->first->getVtablePtr();
87
+ assert(vtblPtr != nullptr && "not a vtable pointer?");
88
+ NodeID vtblId = vtblPtr->getId();
89
89
  addCandidate(vtblId);
90
90
  vtableToCallSiteMap[vtblId] = it->first;
91
91
  }
@@ -497,9 +497,9 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,
497
497
 
498
498
  if (cs->isVirtualCall())
499
499
  {
500
- const SVFValue* vtbl = cs->getVtablePtr();
501
- assert(pag->hasValueNode(vtbl));
502
- NodeID vtblId = pag->getValueNode(vtbl);
500
+ const SVFVar* vtbl = cs->getVtablePtr();
501
+ assert(vtbl != nullptr);
502
+ NodeID vtblId = vtbl->getId();
503
503
  resolveCPPIndCalls(cs, getPts(vtblId), newEdges);
504
504
  }
505
505
  else
@@ -412,7 +412,6 @@ cJSON* SVFIRWriter::contentToJson(const FunExitICFGNode* node)
412
412
  cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
413
413
  {
414
414
  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
415
- JSON_WRITE_FIELD(root, node, cs);
416
415
  JSON_WRITE_FIELD(root, node, ret);
417
416
  JSON_WRITE_FIELD(root, node, APNodes);
418
417
  return root;
@@ -421,7 +420,6 @@ cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
421
420
  cJSON* SVFIRWriter::contentToJson(const RetICFGNode* node)
422
421
  {
423
422
  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
424
- JSON_WRITE_FIELD(root, node, cs);
425
423
  JSON_WRITE_FIELD(root, node, actualRet);
426
424
  JSON_WRITE_FIELD(root, node, callBlockNode);
427
425
  return root;
@@ -2205,7 +2203,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, FunExitICFGNode* node)
2205
2203
  void SVFIRReader::fill(const cJSON*& fieldJson, CallICFGNode* node)
2206
2204
  {
2207
2205
  fill(fieldJson, static_cast<ICFGNode*>(node));
2208
- JSON_READ_FIELD_FWD(fieldJson, node, cs);
2209
2206
  JSON_READ_FIELD_FWD(fieldJson, node, ret);
2210
2207
  JSON_READ_FIELD_FWD(fieldJson, node, APNodes);
2211
2208
  }
@@ -2213,7 +2210,6 @@ void SVFIRReader::fill(const cJSON*& fieldJson, CallICFGNode* node)
2213
2210
  void SVFIRReader::fill(const cJSON*& fieldJson, RetICFGNode* node)
2214
2211
  {
2215
2212
  fill(fieldJson, static_cast<ICFGNode*>(node));
2216
- JSON_READ_FIELD_FWD(fieldJson, node, cs);
2217
2213
  JSON_READ_FIELD_FWD(fieldJson, node, actualRet);
2218
2214
  JSON_READ_FIELD_FWD(fieldJson, node, callBlockNode);
2219
2215
  }
@@ -79,9 +79,9 @@ void TypeAnalysis::callGraphSolveBasedOnCHA(const CallSiteToFunPtrMap& callsites
79
79
  const CallICFGNode* cbn = iter->first;
80
80
  if (cbn->isVirtualCall())
81
81
  {
82
- const SVFValue* vtbl = cbn->getVtablePtr();
82
+ const SVFVar* vtbl = cbn->getVtablePtr();
83
83
  (void)vtbl; // Suppress warning of unused variable under release build
84
- assert(pag->hasValueNode(vtbl));
84
+ assert(vtbl != nullptr);
85
85
  VFunSet vfns;
86
86
  getVFnsFromCHA(cbn, vfns);
87
87
  connectVCallToVFns(cbn, vfns, newEdges);
@@ -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;
@@ -362,6 +363,11 @@ public:
362
363
 
363
364
  ObjTypeInference* getTypeInference();
364
365
 
366
+ inline ICFG* getICFG()
367
+ {
368
+ return icfg;
369
+ }
370
+
365
371
  private:
366
372
  /// Create SVFTypes
367
373
  SVFType* addSVFTypeInfo(const Type* t);
@@ -29,6 +29,7 @@
29
29
  */
30
30
 
31
31
  #include "SVF-LLVM/ICFGBuilder.h"
32
+ #include "SVF-LLVM/CppUtil.h"
32
33
  #include "SVF-LLVM/LLVMModule.h"
33
34
  #include "SVF-LLVM/LLVMUtil.h"
34
35
 
@@ -39,7 +40,7 @@ using namespace SVFUtil;
39
40
  /*!
40
41
  * Create ICFG nodes and edges
41
42
  */
42
- void ICFGBuilder::build()
43
+ ICFG* ICFGBuilder::build()
43
44
  {
44
45
  DBOUT(DGENERAL, outs() << pasMsg("\t Building ICFG ...\n"));
45
46
  // Add the unique global ICFGNode at the entry of a program (before the main method).
@@ -77,6 +78,7 @@ void ICFGBuilder::build()
77
78
 
78
79
  }
79
80
  connectGlobalToProgEntry();
81
+ return icfg;
80
82
  }
81
83
 
82
84
  void ICFGBuilder::checkICFGNodesVisited(const Function* fun)
@@ -234,22 +236,35 @@ void ICFGBuilder::processFunExit(const Function* f)
234
236
  */
235
237
  InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
236
238
  {
237
- SVFInstruction* svfInst =
238
- llvmModuleSet()->getSVFInstruction(inst);
239
239
  assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
240
240
  assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
241
241
  assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
242
- CallICFGNode* callICFGNode =
243
- new CallICFGNode(icfg->totalICFGNode++, svfInst,
244
- llvmModuleSet()->getSVFType(inst->getType()));
245
- icfg->addICFGNode(callICFGNode);
242
+ const CallBase* cb = SVFUtil::dyn_cast<CallBase>(inst);
243
+ bool isvcall = cppUtil::isVirtualCallSite(cb);
244
+ SVFFunction* calledFunc = nullptr;
245
+ auto called_llvmval = cb->getCalledOperand()->stripPointerCasts();
246
+ if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
247
+ {
248
+ calledFunc = llvmModuleSet()->getSVFFunction(called_llvmfunc);
249
+ }
250
+ else
251
+ {
252
+ calledFunc = SVFUtil::dyn_cast<SVFFunction>(
253
+ llvmModuleSet()->getSVFValue(called_llvmval));
254
+ }
255
+
256
+ SVFBasicBlock* bb = llvmModuleSet()->getSVFBasicBlock(inst->getParent());
257
+
258
+ CallICFGNode* callICFGNode = icfg->addCallICFGNode(
259
+ bb, llvmModuleSet()->getSVFType(inst->getType()),
260
+ calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
261
+ isvcall ? cppUtil::getVCallIdx(cb) : 0,
262
+ isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
246
263
  csToCallNodeMap()[inst] = callICFGNode;
247
264
  llvmModuleSet()->setValueAttr(inst, callICFGNode);
248
265
 
249
266
  assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
250
- RetICFGNode* retICFGNode = new RetICFGNode(icfg->totalICFGNode++, svfInst, callICFGNode);
251
- callICFGNode->setRetICFGNode(retICFGNode);
252
- icfg->addICFGNode(retICFGNode);
267
+ RetICFGNode* retICFGNode = icfg->addRetICFGNode(callICFGNode);
253
268
  csToRetNodeMap()[inst] = retICFGNode;
254
269
  llvmModuleSet()->setValueAttr(inst, retICFGNode);
255
270
 
@@ -316,27 +331,22 @@ void ICFGBuilder::connectGlobalToProgEntry()
316
331
  inline ICFGNode* ICFGBuilder::addBlockICFGNode(const Instruction* inst)
317
332
  {
318
333
  ICFGNode* node;
319
- SVFInstruction* svfINst =
320
- llvmModuleSet()->getSVFInstruction(inst);
321
334
  if(LLVMUtil::isNonInstricCallSite(inst))
322
335
  node = addInterBlockICFGNode(inst);
323
336
  else
324
337
  node = addIntraBlockICFGNode(inst);
325
- const_cast<SVFBasicBlock*>(svfINst->getParent())
338
+ const_cast<SVFBasicBlock*>(
339
+ llvmModuleSet()->getSVFBasicBlock(inst->getParent()))
326
340
  ->addICFGNode(node);
327
341
  return node;
328
342
  }
329
343
 
330
344
  IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
331
345
  {
332
- SVFInstruction* svfInst =
333
- llvmModuleSet()->getSVFInstruction(inst);
334
346
  IntraICFGNode* node = llvmModuleSet()->getIntraBlock(inst);
335
347
  assert (node==nullptr && "no IntraICFGNode for this instruction?");
336
- IntraICFGNode* sNode =
337
- new IntraICFGNode(icfg->totalICFGNode++, svfInst->getParent(),
338
- SVFUtil::isa<ReturnInst>(inst));
339
- icfg->addICFGNode(sNode);
348
+ IntraICFGNode* sNode = icfg->addIntraICFGNode(
349
+ llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
340
350
  instToBlockNodeMap()[inst] = sNode;
341
351
  llvmModuleSet()->setValueAttr(inst, sNode);
342
352
  return sNode;
@@ -344,22 +354,12 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
344
354
 
345
355
  FunEntryICFGNode* ICFGBuilder::addFunEntryBlock(const Function* fun)
346
356
  {
347
- SVFFunction* svfFunc =
348
- llvmModuleSet()->getSVFFunction(fun);
349
- FunEntryICFGNode* sNode = new FunEntryICFGNode(icfg->totalICFGNode++,svfFunc);
350
- icfg->addICFGNode(sNode);
351
- funToFunEntryNodeMap()[fun] = sNode;
352
- icfg->FunToFunEntryNodeMap[svfFunc] = sNode;
353
- return sNode;
357
+ return funToFunEntryNodeMap()[fun] =
358
+ icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
354
359
  }
355
360
 
356
361
  inline FunExitICFGNode* ICFGBuilder::addFunExitBlock(const Function* fun)
357
362
  {
358
- SVFFunction* svfFunc =
359
- llvmModuleSet()->getSVFFunction(fun);
360
- FunExitICFGNode* sNode = new FunExitICFGNode(icfg->totalICFGNode++, svfFunc);
361
- icfg->addICFGNode(sNode);
362
- funToFunExitNodeMap()[fun] = sNode;
363
- icfg->FunToFunExitNodeMap[svfFunc] = sNode;
364
- return sNode;
363
+ return funToFunExitNodeMap()[fun] =
364
+ icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
365
365
  }
@@ -40,6 +40,7 @@
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"
43
44
 
44
45
  using namespace std;
45
46
  using namespace SVF;
@@ -166,6 +167,8 @@ void LLVMModuleSet::build()
166
167
 
167
168
  createSVFDataStructure();
168
169
  initSVFFunction();
170
+ ICFGBuilder icfgbuilder;
171
+ icfg = icfgbuilder.build();
169
172
  }
170
173
 
171
174
  void LLVMModuleSet::createSVFDataStructure()
@@ -60,10 +60,7 @@ SVFIR* SVFIRBuilder::build()
60
60
  pag->setModule(svfModule);
61
61
 
62
62
  // Build ICFG
63
- ICFG* icfg = new ICFG();
64
- ICFGBuilder icfgbuilder(icfg);
65
- icfgbuilder.build();
66
- pag->setICFG(icfg);
63
+ pag->setICFG(llvmModuleSet()->getICFG());
67
64
 
68
65
  // Set icfgnode in memobj
69
66
  for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())
@@ -871,6 +868,11 @@ void SVFIRBuilder::visitCallSite(CallBase* cs)
871
868
  if(!cs->getType()->isVoidTy())
872
869
  pag->addCallSiteRets(retBlockNode,pag->getGNode(getValueNode(cs)));
873
870
 
871
+ if (callBlockNode->isVirtualCall())
872
+ {
873
+ const Value* value = cppUtil::getVCallVtblPtr(cs);
874
+ callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
875
+ }
874
876
  if (const Function *callee = LLVMUtil::getCallee(cs))
875
877
  {
876
878
  const SVFFunction* svfcallee = llvmModuleSet()->getSVFFunction(callee);