svf-tools 1.0.995 → 1.0.997

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.
Files changed (43) hide show
  1. package/package.json +1 -1
  2. package/setup.sh +0 -1
  3. package/svf/include/Graphs/CDG.h +1 -1
  4. package/svf/include/Graphs/CHG.h +10 -8
  5. package/svf/include/Graphs/GenericGraph.h +22 -1
  6. package/svf/include/Graphs/ICFGNode.h +37 -62
  7. package/svf/include/MSSA/MSSAMuChi.h +2 -2
  8. package/svf/include/MTA/LockAnalysis.h +2 -2
  9. package/svf/include/MTA/MHP.h +3 -3
  10. package/svf/include/Util/SVFUtil.h +1 -8
  11. package/svf/include/Util/ThreadAPI.h +6 -6
  12. package/svf/lib/AE/Svfexe/AEDetector.cpp +14 -20
  13. package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +49 -45
  14. package/svf/lib/CFL/CFLAlias.cpp +1 -1
  15. package/svf/lib/DDA/DDAClient.cpp +2 -2
  16. package/svf/lib/Graphs/CHG.cpp +17 -17
  17. package/svf/lib/Graphs/CallGraph.cpp +2 -1
  18. package/svf/lib/Graphs/ICFG.cpp +9 -9
  19. package/svf/lib/Graphs/SVFG.cpp +6 -6
  20. package/svf/lib/Graphs/ThreadCallGraph.cpp +8 -8
  21. package/svf/lib/Graphs/VFG.cpp +2 -2
  22. package/svf/lib/MTA/MTAStat.cpp +1 -1
  23. package/svf/lib/MTA/TCT.cpp +3 -3
  24. package/svf/lib/MemoryModel/PointerAnalysis.cpp +11 -11
  25. package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +1 -1
  26. package/svf/lib/SABER/DoubleFreeChecker.cpp +8 -8
  27. package/svf/lib/SABER/LeakChecker.cpp +10 -10
  28. package/svf/lib/SVFIR/SVFFileSystem.cpp +8 -8
  29. package/svf/lib/Util/CallGraphBuilder.cpp +2 -1
  30. package/svf/lib/Util/SVFUtil.cpp +10 -3
  31. package/svf/lib/Util/ThreadAPI.cpp +14 -16
  32. package/svf/lib/WPA/Andersen.cpp +1 -1
  33. package/svf-llvm/include/SVF-LLVM/CHGBuilder.h +5 -0
  34. package/svf-llvm/include/SVF-LLVM/DCHG.h +2 -2
  35. package/svf-llvm/include/SVF-LLVM/LLVMModule.h +10 -0
  36. package/svf-llvm/lib/CHGBuilder.cpp +23 -17
  37. package/svf-llvm/lib/DCHG.cpp +18 -18
  38. package/svf-llvm/lib/ICFGBuilder.cpp +9 -2
  39. package/svf-llvm/lib/LLVMModule.cpp +6 -0
  40. package/svf-llvm/lib/LLVMUtil.cpp +25 -8
  41. package/svf-llvm/lib/SVFIRBuilder.cpp +2 -2
  42. package/svf-llvm/lib/SVFIRExtAPI.cpp +1 -1
  43. package/svf-llvm/lib/SymbolTableBuilder.cpp +2 -2
@@ -94,15 +94,15 @@ void DoubleFreeChecker::validateSuccessTests(ProgSlice *slice, const SVFFunction
94
94
  if (success)
95
95
  {
96
96
  outs() << sucMsg("\t SUCCESS :") << funName << " check <src id:" << source->getId()
97
- << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at ("
98
- << cs->getCallSite()->getSourceLoc() << ")\n";
97
+ << ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
98
+ << cs->getSourceLoc() << ")\n";
99
99
  outs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
100
100
  }
101
101
  else
102
102
  {
103
103
  SVFUtil::errs() << errMsg("\t FAILURE :") << funName << " check <src id:" << source->getId()
104
- << ", cs id:" <<getSrcCSID(source)->getCallSite()->toString() << "> at ("
105
- << cs->getCallSite()->getSourceLoc() << ")\n";
104
+ << ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
105
+ << cs->getSourceLoc() << ")\n";
106
106
  SVFUtil::errs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
107
107
  assert(false && "test case failed!");
108
108
  }
@@ -140,16 +140,16 @@ void DoubleFreeChecker::validateExpectedFailureTests(ProgSlice *slice, const SVF
140
140
  if (expectedFailure)
141
141
  {
142
142
  outs() << sucMsg("\t EXPECTED-FAILURE :") << funName << " check <src id:" << source->getId()
143
- << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at ("
144
- << cs->getCallSite()->getSourceLoc() << ")\n";
143
+ << ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
144
+ << cs->getSourceLoc() << ")\n";
145
145
  outs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
146
146
  }
147
147
  else
148
148
  {
149
149
  SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName
150
150
  << " check <src id:" << source->getId()
151
- << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at ("
152
- << cs->getCallSite()->getSourceLoc() << ")\n";
151
+ << ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
152
+ << cs->getSourceLoc() << ")\n";
153
153
  SVFUtil::errs() << "\t\t double free path: \n" << slice->evalFinalCond() << "\n";
154
154
  assert(false && "test case failed!");
155
155
  }
@@ -48,7 +48,7 @@ void LeakChecker::initSrcs()
48
48
  /// if this callsite return reside in a dead function then we do not care about its leaks
49
49
  /// for example instruction `int* p = malloc(size)` is in a dead function, then program won't allocate this memory
50
50
  /// for example a customized malloc `int p = malloc()` returns an integer value, then program treat it as a system malloc
51
- if(cs->getCallSite()->ptrInUncalledFunction() || !cs->getCallSite()->getType()->isPointerTy())
51
+ if(cs->getFun()->isUncalledFunction() || !cs->getType()->isPointerTy())
52
52
  continue;
53
53
 
54
54
  CallGraph::FunctionSet callees;
@@ -86,7 +86,7 @@ void LeakChecker::initSrcs()
86
86
  else
87
87
  {
88
88
  // exclude sources in dead functions or sources in functions that have summary
89
- if (!cs->getCallSite()->ptrInUncalledFunction() && !isExtCall(cs->getCallSite()->getParent()->getParent()))
89
+ if (!cs->getFun()->isUncalledFunction() && !isExtCall(cs->getBB()->getParent()))
90
90
  {
91
91
  addToSources(node);
92
92
  addSrcToCSID(node, cs);
@@ -231,14 +231,14 @@ void LeakChecker::validateSuccessTests(const SVFGNode* source, const SVFFunction
231
231
  if (success)
232
232
  {
233
233
  outs() << sucMsg("\t SUCCESS :") << funName << " check <src id:" << source->getId()
234
- << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at ("
235
- << cs->getCallSite()->getSourceLoc() << ")\n";
234
+ << ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
235
+ << cs->getSourceLoc() << ")\n";
236
236
  }
237
237
  else
238
238
  {
239
239
  SVFUtil::errs() << errMsg("\t FAILURE :") << funName << " check <src id:" << source->getId()
240
- << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at ("
241
- << cs->getCallSite()->getSourceLoc() << ")\n";
240
+ << ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
241
+ << cs->getSourceLoc() << ")\n";
242
242
  assert(false && "test case failed!");
243
243
  }
244
244
  }
@@ -281,15 +281,15 @@ void LeakChecker::validateExpectedFailureTests(const SVFGNode* source, const SVF
281
281
  if (expectedFailure)
282
282
  {
283
283
  outs() << sucMsg("\t EXPECTED-FAILURE :") << funName << " check <src id:" << source->getId()
284
- << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at ("
285
- << cs->getCallSite()->getSourceLoc() << ")\n";
284
+ << ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
285
+ << cs->getSourceLoc() << ")\n";
286
286
  }
287
287
  else
288
288
  {
289
289
  SVFUtil::errs() << errMsg("\t UNEXPECTED FAILURE :") << funName
290
290
  << " check <src id:" << source->getId()
291
- << ", cs id:" << getSrcCSID(source)->getCallSite()->toString() << "> at ("
292
- << cs->getCallSite()->getSourceLoc() << ")\n";
291
+ << ", cs id:" << (getSrcCSID(source))->toString() << "> at ("
292
+ << cs->getSourceLoc() << ")\n";
293
293
  assert(false && "test case failed!");
294
294
  }
295
295
  }
@@ -386,7 +386,7 @@ cJSON* SVFIRWriter::contentToJson(const GlobalICFGNode* node)
386
386
  cJSON* SVFIRWriter::contentToJson(const IntraICFGNode* node)
387
387
  {
388
388
  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
389
- JSON_WRITE_FIELD(root, node, inst);
389
+ JSON_WRITE_FIELD(root, node, isRet);
390
390
  return root;
391
391
  }
392
392
 
@@ -1153,10 +1153,10 @@ cJSON* SVFIRWriter::toJson(const CHGraph* graph)
1153
1153
  F(classNameToAncestorsMap);
1154
1154
  F(classNameToInstAndDescsMap);
1155
1155
  F(templateNameToInstancesMap);
1156
- F(csToClassesMap);
1156
+ F(callNodeToClassesMap);
1157
1157
  F(virtualFunctionToIDMap);
1158
- F(csToCHAVtblsMap);
1159
- F(csToCHAVFnsMap);
1158
+ F(callNodeToCHAVtblsMap);
1159
+ F(callNodeToCHAVFnsMap);
1160
1160
  #undef F
1161
1161
  return root;
1162
1162
  }
@@ -1755,10 +1755,10 @@ void SVFIRReader::readJson(CHGraph* graph)
1755
1755
  F(classNameToAncestorsMap);
1756
1756
  F(classNameToInstAndDescsMap);
1757
1757
  F(templateNameToInstancesMap);
1758
- F(csToClassesMap);
1758
+ F(callNodeToClassesMap);
1759
1759
  F(virtualFunctionToIDMap);
1760
- F(csToCHAVtblsMap);
1761
- F(csToCHAVFnsMap);
1760
+ F(callNodeToCHAVtblsMap);
1761
+ F(callNodeToCHAVFnsMap);
1762
1762
  #undef F
1763
1763
  }
1764
1764
 
@@ -2182,7 +2182,7 @@ void SVFIRReader::fill(const cJSON*& fieldJson, GlobalICFGNode* node)
2182
2182
  void SVFIRReader::fill(const cJSON*& fieldJson, IntraICFGNode* node)
2183
2183
  {
2184
2184
  fill(fieldJson, static_cast<ICFGNode*>(node));
2185
- JSON_READ_FIELD_FWD(fieldJson, node, inst);
2185
+ JSON_READ_FIELD_FWD(fieldJson, node, isRet);
2186
2186
  }
2187
2187
 
2188
2188
  void SVFIRReader::fill(const cJSON*& fieldJson, InterICFGNode* node)
@@ -31,6 +31,7 @@
31
31
  #include "Util/SVFUtil.h"
32
32
  #include "Util/CallGraphBuilder.h"
33
33
  #include "Graphs/ICFG.h"
34
+ #include "SVFIR/SVFIR.h"
34
35
 
35
36
  using namespace SVF;
36
37
  using namespace SVFUtil;
@@ -84,7 +85,7 @@ CallGraph* ThreadCallGraphBuilder::buildThreadCallGraph(SVFModule* svfModule)
84
85
  {
85
86
  const CallICFGNode* cs = cast<CallICFGNode>(inst);
86
87
  cg->addForksite(cs);
87
- const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs));
88
+ const SVFFunction* forkee = SVFUtil::dyn_cast<SVFFunction>(tdAPI->getForkedFun(cs)->getValue());
88
89
  if (forkee)
89
90
  {
90
91
  cg->addDirectForkEdge(cs);
@@ -374,13 +374,13 @@ bool SVFUtil::isHeapAllocExtCall(const ICFGNode* cs)
374
374
 
375
375
  bool SVFUtil::isHeapAllocExtCallViaRet(const CallICFGNode* cs)
376
376
  {
377
- bool isPtrTy = cs->getCallSite()->getType()->isPointerTy();
377
+ bool isPtrTy = cs->getType()->isPointerTy();
378
378
  return isPtrTy && isHeapAllocExtFunViaRet(cs->getCalledFunction());
379
379
  }
380
380
 
381
381
  bool SVFUtil::isReallocExtCall(const CallICFGNode* cs)
382
382
  {
383
- bool isPtrTy = cs->getCallSite()->getType()->isPointerTy();
383
+ bool isPtrTy = cs->getType()->isPointerTy();
384
384
  return isPtrTy && isReallocExtFun(cs->getCalledFunction());
385
385
  }
386
386
 
@@ -388,7 +388,7 @@ bool SVFUtil::isReallocExtCall(const CallICFGNode* cs)
388
388
  bool SVFUtil::isRetInstNode(const ICFGNode* node)
389
389
  {
390
390
  if (const auto& intraNode = dyn_cast<IntraICFGNode>(node))
391
- return intraNode->getInst()->isRetInst();
391
+ return intraNode->isRetInst();
392
392
  else
393
393
  return false;
394
394
  }
@@ -396,4 +396,11 @@ 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
+ __attribute__((weak))
402
+ const std::string SVFBaseNode::toString() const
403
+ {
404
+ assert("SVFBaseNode::toString should be implemented or supported by fronted" && false);
405
+ abort();
399
406
  }
@@ -160,25 +160,24 @@ bool ThreadAPI::isTDBarWait(const CallICFGNode *inst) const
160
160
  }
161
161
 
162
162
 
163
- const SVFValue* ThreadAPI::getForkedThread(const CallICFGNode *inst) const
163
+ const SVFVar* ThreadAPI::getForkedThread(const CallICFGNode *inst) const
164
164
  {
165
165
  assert(isTDFork(inst) && "not a thread fork function!");
166
166
  return inst->getArgument(0);
167
167
  }
168
168
 
169
- const SVFValue* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
169
+ const SVFVar* ThreadAPI::getForkedFun(const CallICFGNode *inst) const
170
170
  {
171
171
  assert(isTDFork(inst) && "not a thread fork function!");
172
172
  return inst->getArgument(2);
173
173
  }
174
174
 
175
- const SVFVar* ThreadAPI::getActualParmAtForkSite(const CallICFGNode* inst) const
175
+ /// Return the forth argument of the call,
176
+ /// Note that, it is the sole argument of start routine ( a void* pointer )
177
+ const SVFVar* ThreadAPI::getActualParmAtForkSite(const CallICFGNode *inst) const
176
178
  {
177
- assert(PAG::getPAG()->hasCallSiteArgsMap(inst) && "forksite has no args list!");
178
- const SVFIR::SVFVarList& csArgList = PAG::getPAG()->getCallSiteArgsList(inst);
179
- // pthread_create has 4 parameters
180
- assert(csArgList.size() == 4 && "num of forksite args is not 4");
181
- return csArgList[3];
179
+ assert(isTDFork(inst) && "not a thread fork function!");
180
+ return inst->getArgument(3);
182
181
  }
183
182
 
184
183
  const SVFVar* ThreadAPI::getFormalParmOfForkedFun(const SVFFunction* F) const
@@ -190,13 +189,13 @@ const SVFVar* ThreadAPI::getFormalParmOfForkedFun(const SVFFunction* F) const
190
189
  return funArgList[0];
191
190
  }
192
191
 
193
- const SVFValue* ThreadAPI::getRetParmAtJoinedSite(const CallICFGNode *inst) const
192
+ const SVFVar* ThreadAPI::getRetParmAtJoinedSite(const CallICFGNode *inst) const
194
193
  {
195
194
  assert(isTDJoin(inst) && "not a thread join function!");
196
195
  return inst->getArgument(1);
197
196
  }
198
197
 
199
- const SVFValue* ThreadAPI::getLockVal(const ICFGNode *cs) const
198
+ const SVFVar* ThreadAPI::getLockVal(const ICFGNode *cs) const
200
199
  {
201
200
  const CallICFGNode* call = SVFUtil::dyn_cast<CallICFGNode>(cs);
202
201
  assert(call && "not a call ICFGNode?");
@@ -204,17 +203,16 @@ const SVFValue* ThreadAPI::getLockVal(const ICFGNode *cs) const
204
203
  return call->getArgument(0);
205
204
  }
206
205
 
207
- const SVFValue* ThreadAPI::getJoinedThread(const CallICFGNode *cs) const
206
+ const SVFVar* ThreadAPI::getJoinedThread(const CallICFGNode *cs) const
208
207
  {
209
208
  assert(isTDJoin(cs) && "not a thread join function!");
210
- const SVFValue* join = cs->getArgument(0);
211
- const SVFVar* var = PAG::getPAG()->getGNode(PAG::getPAG()->getValueNode(join));
212
- for(const SVFStmt* stmt : var->getInEdges())
209
+ const SVFVar* join = cs->getArgument(0);
210
+ for(const SVFStmt* stmt : join->getInEdges())
213
211
  {
214
212
  if(SVFUtil::isa<LoadStmt>(stmt))
215
- return stmt->getSrcNode()->getValue();
213
+ return stmt->getSrcNode();
216
214
  }
217
- if(SVFUtil::isa<SVFArgument>(join))
215
+ if(SVFUtil::isa<SVFArgument>(join->getValue()))
218
216
  return join;
219
217
 
220
218
  assert(false && "the value of the first argument at join is not a load instruction?");
@@ -379,7 +379,7 @@ void AndersenBase::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet &
379
379
  else
380
380
  {
381
381
  NodeID valNode = pag->addDummyValNode();
382
- NodeID objNode = pag->addDummyObjNode(cs->getCallSite()->getType());
382
+ NodeID objNode = pag->addDummyObjNode(cs->getType());
383
383
  addPts(valNode,objNode);
384
384
  callsite2DummyValPN.insert(std::make_pair(cs,valNode));
385
385
  consCG->addConstraintNode(new ConstraintNode(valNode),valNode);
@@ -33,6 +33,8 @@
33
33
  namespace SVF
34
34
  {
35
35
 
36
+ class LLVMModuleSet;
37
+
36
38
  class CHGBuilder
37
39
  {
38
40
 
@@ -67,6 +69,9 @@ public:
67
69
  void buildCSToCHAVtblsAndVfnsMap();
68
70
  const CHNodeSetTy& getCSClasses(const CallBase* cs);
69
71
  void addFuncToFuncVector(CHNode::FuncVector &v, const Function *f);
72
+
73
+ private:
74
+ LLVMModuleSet* llvmModuleSet();
70
75
  };
71
76
 
72
77
  } // End namespace SVF
@@ -93,7 +93,7 @@ public:
93
93
 
94
94
  ~DCHNode() { }
95
95
 
96
- const DIType *getType(void) const
96
+ const DIType * getDIType(void) const
97
97
  {
98
98
  return diType;
99
99
  }
@@ -275,7 +275,7 @@ public:
275
275
  }
276
276
 
277
277
  virtual const VTableSet &getCSVtblsBasedonCHA(const CallICFGNode* cs) override;
278
- virtual void getVFnsFromVtbls(const SVFCallInst* cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override;
278
+ virtual void getVFnsFromVtbls(const CallICFGNode* cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override;
279
279
 
280
280
  /// Returns true if a is a transitive base of b. firstField determines
281
281
  /// whether to consider first-field edges.
@@ -60,6 +60,7 @@ public:
60
60
  typedef Map<const Constant*, SVFConstant*> LLVMConst2SVFConstMap;
61
61
  typedef Map<const Value*, SVFOtherValue*> LLVMValue2SVFOtherValueMap;
62
62
  typedef Map<const SVFValue*, const Value*> SVFValue2LLVMValueMap;
63
+ typedef Map<const SVFBaseNode*, const Value*> SVFBaseNode2LLVMValueMap;
63
64
  typedef Map<const Type*, SVFType*> LLVMType2SVFTypeMap;
64
65
  typedef Map<const Type*, StInfo*> Type2TypeInfoMap;
65
66
  typedef Map<std::string, std::vector<std::string>> Fun2AnnoMap;
@@ -97,6 +98,7 @@ private:
97
98
  Type2TypeInfoMap Type2TypeInfo;
98
99
  ObjTypeInference* typeInference;
99
100
 
101
+ SVFBaseNode2LLVMValueMap SVFBaseNode2LLVMValue;
100
102
  CSToCallNodeMapTy CSToCallNodeMap; ///< map a callsite to its CallICFGNode
101
103
  CSToRetNodeMapTy CSToRetNodeMap; ///< map a callsite to its RetICFGNode
102
104
  InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode
@@ -216,6 +218,13 @@ public:
216
218
  return it->second;
217
219
  }
218
220
 
221
+ const Value* getLLVMValue(const SVFBaseNode* value) const
222
+ {
223
+ SVFBaseNode2LLVMValueMap ::const_iterator it = SVFBaseNode2LLVMValue.find(value);
224
+ assert(it!=SVFBaseNode2LLVMValue.end() && "can't find corresponding llvm value!");
225
+ return it->second;
226
+ }
227
+
219
228
  inline SVFFunction* getSVFFunction(const Function* fun) const
220
229
  {
221
230
  LLVMFun2SVFFunMap::const_iterator it = LLVMFunc2SVFFunc.find(fun);
@@ -378,6 +387,7 @@ private:
378
387
  void initSVFBasicBlock(const Function* func);
379
388
  void initDomTree(SVFFunction* func, const Function* f);
380
389
  void setValueAttr(const Value* val, SVFValue* value);
390
+ void setValueAttr(const Value* val, SVFBaseNode* svfBaseNode);
381
391
  void buildFunToFunMap();
382
392
  void buildGlobalDefToRepMap();
383
393
  /// Invoke llvm passes to modify module
@@ -57,13 +57,17 @@ const string pureVirtualFunName = "__cxa_pure_virtual";
57
57
 
58
58
  const string ztiLabel = "_ZTI";
59
59
 
60
+ LLVMModuleSet* CHGBuilder::llvmModuleSet()
61
+ {
62
+ return LLVMModuleSet::getLLVMModuleSet();
63
+ }
60
64
 
61
65
  void CHGBuilder::buildCHG()
62
66
  {
63
67
 
64
68
  double timeStart, timeEnd;
65
69
  timeStart = PTAStat::getClk(true);
66
- for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
70
+ for (Module &M : llvmModuleSet()->getLLVMModules())
67
71
  {
68
72
  DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("construct CHGraph From module "
69
73
  + M.getName().str() + "...\n"));
@@ -375,7 +379,7 @@ void CHGBuilder::analyzeVTables(const Module &M)
375
379
  assert(node && "node not found?");
376
380
 
377
381
  SVFGlobalValue* pValue =
378
- LLVMModuleSet::getLLVMModuleSet()->getSVFGlobalValue(
382
+ llvmModuleSet()->getSVFGlobalValue(
379
383
  globalvalue);
380
384
  pValue->setName(vtblClassName);
381
385
  node->setVTable(pValue);
@@ -655,7 +659,7 @@ void CHGBuilder::buildVirtualFunctionToIDMap()
655
659
  void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()
656
660
  {
657
661
 
658
- for (Module &M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
662
+ for (Module &M : llvmModuleSet()->getLLVMModules())
659
663
  {
660
664
  for (Module::const_iterator F = M.begin(), E = M.end(); F != E; ++F)
661
665
  {
@@ -679,12 +683,13 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()
679
683
  }
680
684
  if (vtbls.size() > 0)
681
685
  {
682
- const SVFInstruction* cs = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(callInst);
683
- chg->csToCHAVtblsMap[cs] = vtbls;
686
+ ICFGNode* icfgNode =
687
+ llvmModuleSet()->getICFGNode(callInst);
688
+ chg->callNodeToCHAVtblsMap[icfgNode] = vtbls;
684
689
  VFunSet virtualFunctions;
685
- chg->getVFnsFromVtbls(SVFUtil::cast<SVFCallInst>(cs), vtbls, virtualFunctions);
690
+ chg->getVFnsFromVtbls(SVFUtil::cast<CallICFGNode>(icfgNode), vtbls, virtualFunctions);
686
691
  if (virtualFunctions.size() > 0)
687
- chg->csToCHAVFnsMap[cs] = virtualFunctions;
692
+ chg->callNodeToCHAVFnsMap[icfgNode] = virtualFunctions;
688
693
  }
689
694
  }
690
695
  }
@@ -696,10 +701,11 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()
696
701
  const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
697
702
  {
698
703
  assert(cppUtil::isVirtualCallSite(cs) && "not virtual callsite!");
699
- const SVFInstruction* svfcall = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
700
704
 
701
- CHGraph::CallSiteToCHNodesMap::const_iterator it = chg->csToClassesMap.find(svfcall);
702
- if (it != chg->csToClassesMap.end())
705
+ ICFGNode* icfgNode = llvmModuleSet()->getICFGNode(cs);
706
+
707
+ CHGraph::CallNodeToCHNodesMap::const_iterator it = chg->callNodeToClassesMap.find(icfgNode);
708
+ if (it != chg->callNodeToClassesMap.end())
703
709
  {
704
710
  return it->second;
705
711
  }
@@ -712,9 +718,9 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
712
718
  // if we cannot infer classname, conservatively push all class nodes
713
719
  for (const auto &node: *chg)
714
720
  {
715
- chg->csToClassesMap[svfcall].insert(node.second);
721
+ chg->callNodeToClassesMap[icfgNode].insert(node.second);
716
722
  }
717
- return chg->csToClassesMap[svfcall];
723
+ return chg->callNodeToClassesMap[icfgNode];
718
724
  }
719
725
 
720
726
  for (const auto &thisPtrClassName: thisPtrClassNames)
@@ -722,12 +728,12 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
722
728
  if (const CHNode* thisNode = chg->getNode(thisPtrClassName))
723
729
  {
724
730
  const CHGraph::CHNodeSetTy& instAndDesces = getInstancesAndDescendants(thisPtrClassName);
725
- chg->csToClassesMap[svfcall].insert(thisNode);
731
+ chg->callNodeToClassesMap[icfgNode].insert(thisNode);
726
732
  for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); it2 != eit; ++it2)
727
- chg->csToClassesMap[svfcall].insert(*it2);
733
+ chg->callNodeToClassesMap[icfgNode].insert(*it2);
728
734
  }
729
735
  }
730
- return chg->csToClassesMap[svfcall];
736
+ return chg->callNodeToClassesMap[icfgNode];
731
737
  }
732
738
  }
733
739
 
@@ -738,14 +744,14 @@ void CHGBuilder::addFuncToFuncVector(CHNode::FuncVector &v, const Function *lf)
738
744
  if (const auto* tf = cppUtil::getThunkTarget(lf))
739
745
  {
740
746
  SVFFunction* pFunction =
741
- LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(tf);
747
+ llvmModuleSet()->getSVFFunction(tf);
742
748
  v.push_back(pFunction);
743
749
  }
744
750
  }
745
751
  else
746
752
  {
747
753
  SVFFunction* pFunction =
748
- LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(lf);
754
+ llvmModuleSet()->getSVFFunction(lf);
749
755
  v.push_back(pFunction);
750
756
  }
751
757
  }
@@ -251,7 +251,7 @@ const NodeBS &DCHGraph::cha(const DIType *type, bool firstField)
251
251
  continue;
252
252
  }
253
253
 
254
- const NodeBS &cchildren = cha(edge->getSrcNode()->getType(), firstField);
254
+ const NodeBS &cchildren = cha(edge->getSrcNode()->getDIType(), firstField);
255
255
  // Children's children are my children.
256
256
  for (NodeID cchild : cchildren)
257
257
  {
@@ -530,10 +530,10 @@ void DCHGraph::buildCHG(bool extend)
530
530
  for (iterator nodeI = begin(); nodeI != end(); ++nodeI)
531
531
  {
532
532
  // Everything without a parent gets char as a parent.
533
- if (nodeI->second->getType() != nullptr
533
+ if (nodeI->second->getDIType() != nullptr
534
534
  && nodeI->second->getOutEdges().size() == 0)
535
535
  {
536
- addEdge(nodeI->second->getType(), charType, DCHEdge::STD_DEF);
536
+ addEdge(nodeI->second->getDIType(), charType, DCHEdge::STD_DEF);
537
537
  }
538
538
  }
539
539
  }
@@ -553,7 +553,7 @@ const VFunSet &DCHGraph::getCSVFsBasedonCHA(const CallICFGNode* cs)
553
553
 
554
554
  VFunSet vfns;
555
555
  const VTableSet &vtbls = getCSVtblsBasedonCHA(cs);
556
- getVFnsFromVtbls(SVFUtil::cast<SVFCallInst>(cs->getCallSite()), vtbls, vfns);
556
+ getVFnsFromVtbls(cs, vtbls, vfns);
557
557
 
558
558
  // Cache.
559
559
  csCHAMap.insert({cs, vfns});
@@ -589,11 +589,10 @@ const VTableSet &DCHGraph::getCSVtblsBasedonCHA(const CallICFGNode* cs)
589
589
  return vtblCHAMap[type];
590
590
  }
591
591
 
592
- void DCHGraph::getVFnsFromVtbls(const SVFCallInst* callsite, const VTableSet &vtbls, VFunSet &virtualFunctions)
592
+ void DCHGraph::getVFnsFromVtbls(const CallICFGNode* callsite, const VTableSet &vtbls, VFunSet &virtualFunctions)
593
593
  {
594
- const SVFVirtualCallInst* cs = SVFUtil::cast<SVFVirtualCallInst>(callsite);
595
- size_t idx = cs->getFunIdxInVtable();
596
- std::string funName = cs->getFunNameOfVirtualCall();
594
+ size_t idx = callsite->getFunIdxInVtable();
595
+ std::string funName = callsite->getFunNameOfVirtualCall();
597
596
  for (const SVFGlobalValue *vtbl : vtbls)
598
597
  {
599
598
  assert(vtblToTypeMap.find(vtbl) != vtblToTypeMap.end() && "floating vtbl");
@@ -611,7 +610,7 @@ void DCHGraph::getVFnsFromVtbls(const SVFCallInst* callsite, const VTableSet &vt
611
610
 
612
611
  const Function* callee = vfnV[idx];
613
612
  // Practically a copy of that in lib/MemoryModel/CHA.cpp
614
- if (cs->arg_size() == callee->arg_size() || (cs->isVarArg() && callee->isVarArg()))
613
+ if (callsite->arg_size() == callee->arg_size() || (callsite->isVarArg() && callee->isVarArg()))
615
614
  {
616
615
  cppUtil::DemangledName dname = cppUtil::demangle(callee->getName().str());
617
616
  std::string calleeName = dname.funcName;
@@ -957,8 +956,8 @@ bool DCHGraph::isFirstField(const DIType *f, const DIType *b)
957
956
  // Only care about first-field edges.
958
957
  if (edge->getEdgeKind() == DCHEdge::FIRST_FIELD)
959
958
  {
960
- if (edge->getSrcNode()->getType() == b) return true;
961
- if (isFirstField(edge->getSrcNode()->getType(), b)) return true;
959
+ if (edge->getSrcNode()->getDIType() == b) return true;
960
+ if (isFirstField(edge->getSrcNode()->getDIType(), b)) return true;
962
961
  }
963
962
  }
964
963
 
@@ -1163,13 +1162,14 @@ void DCHGraph::print(void)
1163
1162
 
1164
1163
  const DCHNode *node = getGNode(id);
1165
1164
 
1166
- SVFUtil::outs() << indent(currIndent) << id << ": " << diTypeToStr(node->getType()) << " [" << node->getType() << "]" << "\n";
1167
- if (node->getType() != nullptr
1168
- && (node->getType()->getTag() == dwarf::DW_TAG_class_type
1169
- || node->getType()->getTag() == dwarf::DW_TAG_structure_type))
1165
+ SVFUtil::outs() << indent(currIndent) << id << ": " << diTypeToStr(node->getDIType()) << " [" << node->getDIType() << "]" << "\n";
1166
+ if (node->getDIType() != nullptr
1167
+ && (node->getDIType()->getTag() == dwarf::DW_TAG_class_type
1168
+ ||
1169
+ node->getDIType()->getTag() == dwarf::DW_TAG_structure_type))
1170
1170
  {
1171
1171
  ++numStructs;
1172
- unsigned numFields = getFieldTypes(node->getType()).size();
1172
+ unsigned numFields = getFieldTypes(node->getDIType()).size();
1173
1173
  largestStruct = numFields > largestStruct ? numFields : largestStruct;
1174
1174
  }
1175
1175
 
@@ -1225,8 +1225,8 @@ void DCHGraph::print(void)
1225
1225
  arrow = "----unknown---->";
1226
1226
  }
1227
1227
 
1228
- SVFUtil::outs() << indent(currIndent) << "[ " << diTypeToStr(node->getType()) << " ] "
1229
- << arrow << " [ " << diTypeToStr(edge->getDstNode()->getType()) << " ]\n";
1228
+ SVFUtil::outs() << indent(currIndent) << "[ " << diTypeToStr(node->getDIType()) << " ] "
1229
+ << arrow << " [ " << diTypeToStr(edge->getDstNode()->getDIType()) << " ]\n";
1230
1230
  }
1231
1231
 
1232
1232
  if (node->getOutEdges().size() == 0)
@@ -239,15 +239,19 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* 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 = new CallICFGNode(icfg->totalICFGNode++, svfInst);
242
+ CallICFGNode* callICFGNode =
243
+ new CallICFGNode(icfg->totalICFGNode++, svfInst,
244
+ llvmModuleSet()->getSVFType(inst->getType()));
243
245
  icfg->addICFGNode(callICFGNode);
244
246
  csToCallNodeMap()[inst] = callICFGNode;
247
+ llvmModuleSet()->setValueAttr(inst, callICFGNode);
245
248
 
246
249
  assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
247
250
  RetICFGNode* retICFGNode = new RetICFGNode(icfg->totalICFGNode++, svfInst, callICFGNode);
248
251
  callICFGNode->setRetICFGNode(retICFGNode);
249
252
  icfg->addICFGNode(retICFGNode);
250
253
  csToRetNodeMap()[inst] = retICFGNode;
254
+ llvmModuleSet()->setValueAttr(inst, retICFGNode);
251
255
 
252
256
  addICFGInterEdges(inst, LLVMUtil::getCallee(SVFUtil::cast<CallBase>(inst))); //creating interprocedural edges
253
257
  return callICFGNode;
@@ -329,9 +333,12 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
329
333
  llvmModuleSet()->getSVFInstruction(inst);
330
334
  IntraICFGNode* node = llvmModuleSet()->getIntraBlock(inst);
331
335
  assert (node==nullptr && "no IntraICFGNode for this instruction?");
332
- IntraICFGNode* sNode = new IntraICFGNode(icfg->totalICFGNode++,svfInst);
336
+ IntraICFGNode* sNode =
337
+ new IntraICFGNode(icfg->totalICFGNode++, svfInst->getParent(),
338
+ SVFUtil::isa<ReturnInst>(inst));
333
339
  icfg->addICFGNode(sNode);
334
340
  instToBlockNodeMap()[inst] = sNode;
341
+ llvmModuleSet()->setValueAttr(inst, sNode);
335
342
  return sNode;
336
343
  }
337
344
 
@@ -1230,6 +1230,12 @@ void LLVMModuleSet::setValueAttr(const Value* val, SVFValue* svfvalue)
1230
1230
  svfvalue->setSourceLoc(LLVMUtil::getSourceLoc(val));
1231
1231
  }
1232
1232
 
1233
+ void LLVMModuleSet::setValueAttr(const SVF::Value* val, SVF::SVFBaseNode* svfBaseNode)
1234
+ {
1235
+ SVFBaseNode2LLVMValue[svfBaseNode] = val;
1236
+ svfBaseNode->setSourceLoc(LLVMUtil::getSourceLoc(val));
1237
+ }
1238
+
1233
1239
  SVFConstantData* LLVMModuleSet::getSVFConstantData(const ConstantData* cd)
1234
1240
  {
1235
1241
  LLVMConst2SVFConstMap::const_iterator it = LLVMConst2SVFConst.find(cd);