svf-tools 1.0.993 → 1.0.995

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 (59) hide show
  1. package/package.json +1 -1
  2. package/svf/include/Graphs/CDG.h +18 -1
  3. package/svf/include/Graphs/CFLGraph.h +19 -1
  4. package/svf/include/Graphs/CHG.h +19 -1
  5. package/svf/include/Graphs/CallGraph.h +19 -1
  6. package/svf/include/Graphs/ConsGNode.h +19 -1
  7. package/svf/include/Graphs/GenericGraph.h +243 -17
  8. package/svf/include/Graphs/ICFG.h +0 -96
  9. package/svf/include/Graphs/ICFGNode.h +55 -22
  10. package/svf/include/Graphs/SVFG.h +2 -2
  11. package/svf/include/Graphs/SVFGNode.h +5 -17
  12. package/svf/include/Graphs/SVFGOPT.h +2 -1
  13. package/svf/include/Graphs/ThreadCallGraph.h +5 -4
  14. package/svf/include/Graphs/VFG.h +2 -2
  15. package/svf/include/Graphs/VFGNode.h +99 -26
  16. package/svf/include/MTA/TCT.h +19 -1
  17. package/svf/include/MemoryModel/PointerAnalysis.h +1 -1
  18. package/svf/include/MemoryModel/PointerAnalysisImpl.h +4 -0
  19. package/svf/include/SABER/SaberCondAllocator.h +2 -2
  20. package/svf/include/SVFIR/SVFFileSystem.h +1 -1
  21. package/svf/include/SVFIR/SVFIR.h +2 -2
  22. package/svf/include/SVFIR/SVFVariables.h +68 -38
  23. package/svf/include/SVFIR/SymbolTableInfo.h +11 -1
  24. package/svf/include/Util/SVFUtil.h +1 -1
  25. package/svf/include/Util/ThreadAPI.h +8 -2
  26. package/svf/include/WPA/Andersen.h +26 -13
  27. package/svf/include/WPA/Steensgaard.h +10 -20
  28. package/svf/include/WPA/TypeAnalysis.h +10 -3
  29. package/svf/lib/AE/Svfexe/AEDetector.cpp +4 -2
  30. package/svf/lib/AE/Svfexe/AbsExtAPI.cpp +10 -12
  31. package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +2 -0
  32. package/svf/lib/DDA/ContextDDA.cpp +12 -8
  33. package/svf/lib/Graphs/ICFG.cpp +9 -93
  34. package/svf/lib/Graphs/SVFG.cpp +1 -1
  35. package/svf/lib/Graphs/ThreadCallGraph.cpp +10 -2
  36. package/svf/lib/Graphs/VFG.cpp +2 -4
  37. package/svf/lib/MSSA/MemRegion.cpp +2 -2
  38. package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +37 -0
  39. package/svf/lib/SABER/LeakChecker.cpp +1 -2
  40. package/svf/lib/SABER/SaberCondAllocator.cpp +13 -16
  41. package/svf/lib/SABER/SaberSVFGBuilder.cpp +2 -2
  42. package/svf/lib/SVFIR/SVFFileSystem.cpp +0 -6
  43. package/svf/lib/SVFIR/SVFVariables.cpp +3 -0
  44. package/svf/lib/SVFIR/SymbolTableInfo.cpp +3 -2
  45. package/svf/lib/Util/ThreadAPI.cpp +15 -5
  46. package/svf/lib/WPA/Andersen.cpp +205 -151
  47. package/svf/lib/WPA/Steensgaard.cpp +1 -163
  48. package/svf-llvm/include/SVF-LLVM/DCHG.h +1 -1
  49. package/svf-llvm/include/SVF-LLVM/ICFGBuilder.h +93 -23
  50. package/svf-llvm/include/SVF-LLVM/LLVMModule.h +84 -0
  51. package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +15 -0
  52. package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +19 -12
  53. package/svf-llvm/lib/ICFGBuilder.cpp +125 -54
  54. package/svf-llvm/lib/LLVMLoopAnalysis.cpp +6 -11
  55. package/svf-llvm/lib/LLVMModule.cpp +54 -0
  56. package/svf-llvm/lib/LLVMUtil.cpp +15 -0
  57. package/svf-llvm/lib/SVFIRBuilder.cpp +92 -76
  58. package/svf-llvm/lib/SVFIRExtAPI.cpp +5 -5
  59. package/svf-llvm/lib/SymbolTableBuilder.cpp +4 -4
@@ -187,6 +187,211 @@ void AndersenBase::cleanConsCG(NodeID id)
187
187
  assert(!consCG->hasGNode(id) && "this is either a rep nodeid or a sub nodeid should have already been merged to its field-insensitive base! ");
188
188
  }
189
189
 
190
+ bool AndersenBase::updateCallGraph(const CallSiteToFunPtrMap& callsites)
191
+ {
192
+
193
+ double cgUpdateStart = stat->getClk();
194
+
195
+ CallEdgeMap newEdges;
196
+ onTheFlyCallGraphSolve(callsites, newEdges);
197
+ NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge
198
+ for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end();
199
+ it != eit; ++it)
200
+ {
201
+ for (FunctionSet::iterator cit = it->second.begin(),
202
+ ecit = it->second.end();
203
+ cit != ecit; ++cit)
204
+ {
205
+ connectCaller2CalleeParams(it->first, *cit, cpySrcNodes);
206
+ }
207
+ }
208
+
209
+ bool hasNewForkEdges = updateThreadCallGraph(callsites, cpySrcNodes);
210
+
211
+ for (NodePairSet::iterator it = cpySrcNodes.begin(),
212
+ eit = cpySrcNodes.end();
213
+ it != eit; ++it)
214
+ {
215
+ pushIntoWorklist(it->first);
216
+ }
217
+
218
+ double cgUpdateEnd = stat->getClk();
219
+ timeOfUpdateCallGraph += (cgUpdateEnd - cgUpdateStart) / TIMEINTERVAL;
220
+
221
+ return ((!newEdges.empty()) || hasNewForkEdges);
222
+ }
223
+
224
+ bool AndersenBase::updateThreadCallGraph(const CallSiteToFunPtrMap& callsites,
225
+ NodePairSet& cpySrcNodes)
226
+ {
227
+ CallEdgeMap newForkEdges;
228
+ onTheFlyThreadCallGraphSolve(callsites, newForkEdges);
229
+ for (CallEdgeMap::iterator it = newForkEdges.begin(), eit = newForkEdges.end(); it != eit; it++)
230
+ {
231
+ for (FunctionSet::iterator cit = it->second.begin(),
232
+ ecit = it->second.end();
233
+ cit != ecit; ++cit)
234
+ {
235
+ connectCaller2ForkedFunParams(it->first, *cit, cpySrcNodes);
236
+ }
237
+ }
238
+ return !newForkEdges.empty();
239
+ }
240
+
241
+ /*!
242
+ * Connect formal and actual parameters for indirect forksites
243
+ */
244
+ void AndersenBase::connectCaller2ForkedFunParams(const CallICFGNode* cs, const SVFFunction* F,
245
+ NodePairSet& cpySrcNodes)
246
+ {
247
+ assert(F);
248
+
249
+ DBOUT(DAndersen, outs() << "connect parameters from indirect forksite "
250
+ << cs.getInstruction()->toString() << " to forked function "
251
+ << *F << "\n");
252
+
253
+ ThreadCallGraph *tdCallGraph = SVFUtil::dyn_cast<ThreadCallGraph>(callgraph);
254
+
255
+ const PAGNode *cs_arg = tdCallGraph->getThreadAPI()->getActualParmAtForkSite(cs);
256
+ const PAGNode *fun_arg = tdCallGraph->getThreadAPI()->getFormalParmOfForkedFun(F);
257
+
258
+ if(cs_arg->isPointer() && fun_arg->isPointer())
259
+ {
260
+ DBOUT(DAndersen, outs() << "process actual parm"
261
+ << cs_arg->toString() << "\n");
262
+ NodeID srcAA = sccRepNode(cs_arg->getId());
263
+ NodeID dstFA = sccRepNode(fun_arg->getId());
264
+ if (addCopyEdge(srcAA, dstFA))
265
+ {
266
+ cpySrcNodes.insert(std::make_pair(srcAA, dstFA));
267
+ }
268
+ }
269
+ }
270
+
271
+ ///*!
272
+ // * Connect formal and actual parameters for indirect callsites
273
+ // */
274
+ void AndersenBase::connectCaller2CalleeParams(const CallICFGNode* cs,
275
+ const SVFFunction* F, NodePairSet &cpySrcNodes)
276
+ {
277
+ assert(F);
278
+
279
+ DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " <<
280
+ cs.getInstruction()->toString() << " to callee " << *F << "\n");
281
+
282
+ const CallICFGNode* callBlockNode = cs;
283
+ const RetICFGNode* retBlockNode = cs->getRetICFGNode();
284
+
285
+ if(SVFUtil::isHeapAllocExtFunViaRet(F) && pag->callsiteHasRet(retBlockNode))
286
+ {
287
+ heapAllocatorViaIndCall(cs,cpySrcNodes);
288
+ }
289
+
290
+ if (pag->funHasRet(F) && pag->callsiteHasRet(retBlockNode))
291
+ {
292
+ const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
293
+ const PAGNode* fun_return = pag->getFunRet(F);
294
+ if (cs_return->isPointer() && fun_return->isPointer())
295
+ {
296
+ NodeID dstrec = sccRepNode(cs_return->getId());
297
+ NodeID srcret = sccRepNode(fun_return->getId());
298
+ if(addCopyEdge(srcret, dstrec))
299
+ {
300
+ cpySrcNodes.insert(std::make_pair(srcret,dstrec));
301
+ }
302
+ }
303
+ else
304
+ {
305
+ DBOUT(DAndersen, outs() << "not a pointer ignored\n");
306
+ }
307
+ }
308
+
309
+ if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(F))
310
+ {
311
+
312
+ // connect actual and formal param
313
+ const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callBlockNode);
314
+ const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(F);
315
+ //Go through the fixed parameters.
316
+ DBOUT(DPAGBuild, outs() << " args:");
317
+ SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
318
+ SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
319
+ for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt)
320
+ {
321
+ //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
322
+ if (csArgIt == csArgEit)
323
+ {
324
+ DBOUT(DAndersen, outs() << " !! not enough args\n");
325
+ break;
326
+ }
327
+ const PAGNode *cs_arg = *csArgIt ;
328
+ const PAGNode *fun_arg = *funArgIt;
329
+
330
+ if (cs_arg->isPointer() && fun_arg->isPointer())
331
+ {
332
+ DBOUT(DAndersen, outs() << "process actual parm " << cs_arg->toString() << " \n");
333
+ NodeID srcAA = sccRepNode(cs_arg->getId());
334
+ NodeID dstFA = sccRepNode(fun_arg->getId());
335
+ if(addCopyEdge(srcAA, dstFA))
336
+ {
337
+ cpySrcNodes.insert(std::make_pair(srcAA,dstFA));
338
+ }
339
+ }
340
+ }
341
+
342
+ //Any remaining actual args must be varargs.
343
+ if (F->isVarArg())
344
+ {
345
+ NodeID vaF = sccRepNode(pag->getVarargNode(F));
346
+ DBOUT(DPAGBuild, outs() << "\n varargs:");
347
+ for (; csArgIt != csArgEit; ++csArgIt)
348
+ {
349
+ const PAGNode *cs_arg = *csArgIt;
350
+ if (cs_arg->isPointer())
351
+ {
352
+ NodeID vnAA = sccRepNode(cs_arg->getId());
353
+ if (addCopyEdge(vnAA,vaF))
354
+ {
355
+ cpySrcNodes.insert(std::make_pair(vnAA,vaF));
356
+ }
357
+ }
358
+ }
359
+ }
360
+ if(csArgIt != csArgEit)
361
+ {
362
+ writeWrnMsg("too many args to non-vararg func.");
363
+ writeWrnMsg("(" + cs->getSourceLoc() + ")");
364
+ }
365
+ }
366
+ }
367
+
368
+ void AndersenBase::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet &cpySrcNodes)
369
+ {
370
+ assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
371
+ const RetICFGNode* retBlockNode = cs->getRetICFGNode();
372
+ const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
373
+ NodeID srcret;
374
+ CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
375
+ if(it != callsite2DummyValPN.end())
376
+ {
377
+ srcret = sccRepNode(it->second);
378
+ }
379
+ else
380
+ {
381
+ NodeID valNode = pag->addDummyValNode();
382
+ NodeID objNode = pag->addDummyObjNode(cs->getCallSite()->getType());
383
+ addPts(valNode,objNode);
384
+ callsite2DummyValPN.insert(std::make_pair(cs,valNode));
385
+ consCG->addConstraintNode(new ConstraintNode(valNode),valNode);
386
+ consCG->addConstraintNode(new ConstraintNode(objNode),objNode);
387
+ srcret = valNode;
388
+ }
389
+
390
+ NodeID dstrec = sccRepNode(cs_return->getId());
391
+ if(addCopyEdge(srcret, dstrec))
392
+ cpySrcNodes.insert(std::make_pair(srcret,dstrec));
393
+ }
394
+
190
395
  void AndersenBase::normalizePointsTo()
191
396
  {
192
397
  SVFIR::MemObjToFieldsMap &memToFieldsMap = pag->getMemToFieldsMap();
@@ -648,157 +853,6 @@ NodeStack& Andersen::SCCDetect()
648
853
  return getSCCDetector()->topoNodeStack();
649
854
  }
650
855
 
651
- /*!
652
- * Update call graph for the input indirect callsites
653
- */
654
- bool Andersen::updateCallGraph(const CallSiteToFunPtrMap& callsites)
655
- {
656
-
657
- double cgUpdateStart = stat->getClk();
658
-
659
- CallEdgeMap newEdges;
660
- onTheFlyCallGraphSolve(callsites,newEdges);
661
- NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge
662
- for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it )
663
- {
664
- for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
665
- {
666
- connectCaller2CalleeParams(it->first,*cit,cpySrcNodes);
667
- }
668
- }
669
- for(NodePairSet::iterator it = cpySrcNodes.begin(), eit = cpySrcNodes.end(); it!=eit; ++it)
670
- {
671
- pushIntoWorklist(it->first);
672
- }
673
-
674
- double cgUpdateEnd = stat->getClk();
675
- timeOfUpdateCallGraph += (cgUpdateEnd - cgUpdateStart) / TIMEINTERVAL;
676
-
677
- return (!newEdges.empty());
678
- }
679
-
680
- void Andersen::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet &cpySrcNodes)
681
- {
682
- assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
683
- const RetICFGNode* retBlockNode = cs->getRetICFGNode();
684
- const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
685
- NodeID srcret;
686
- CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
687
- if(it != callsite2DummyValPN.end())
688
- {
689
- srcret = sccRepNode(it->second);
690
- }
691
- else
692
- {
693
- NodeID valNode = pag->addDummyValNode();
694
- NodeID objNode = pag->addDummyObjNode(cs->getCallSite()->getType());
695
- addPts(valNode,objNode);
696
- callsite2DummyValPN.insert(std::make_pair(cs,valNode));
697
- consCG->addConstraintNode(new ConstraintNode(valNode),valNode);
698
- consCG->addConstraintNode(new ConstraintNode(objNode),objNode);
699
- srcret = valNode;
700
- }
701
-
702
- NodeID dstrec = sccRepNode(cs_return->getId());
703
- if(addCopyEdge(srcret, dstrec))
704
- cpySrcNodes.insert(std::make_pair(srcret,dstrec));
705
- }
706
-
707
- /*!
708
- * Connect formal and actual parameters for indirect callsites
709
- */
710
- void Andersen::connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F, NodePairSet &cpySrcNodes)
711
- {
712
- assert(F);
713
-
714
- DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() << " to callee " << *F << "\n");
715
-
716
- const CallICFGNode* callBlockNode = cs;
717
- const RetICFGNode* retBlockNode = cs->getRetICFGNode();
718
-
719
- if(SVFUtil::isHeapAllocExtFunViaRet(F) && pag->callsiteHasRet(retBlockNode))
720
- {
721
- heapAllocatorViaIndCall(cs,cpySrcNodes);
722
- }
723
-
724
- if (pag->funHasRet(F) && pag->callsiteHasRet(retBlockNode))
725
- {
726
- const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
727
- const PAGNode* fun_return = pag->getFunRet(F);
728
- if (cs_return->isPointer() && fun_return->isPointer())
729
- {
730
- NodeID dstrec = sccRepNode(cs_return->getId());
731
- NodeID srcret = sccRepNode(fun_return->getId());
732
- if(addCopyEdge(srcret, dstrec))
733
- {
734
- cpySrcNodes.insert(std::make_pair(srcret,dstrec));
735
- }
736
- }
737
- else
738
- {
739
- DBOUT(DAndersen, outs() << "not a pointer ignored\n");
740
- }
741
- }
742
-
743
- if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(F))
744
- {
745
-
746
- // connect actual and formal param
747
- const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callBlockNode);
748
- const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(F);
749
- //Go through the fixed parameters.
750
- DBOUT(DPAGBuild, outs() << " args:");
751
- SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
752
- SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
753
- for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt)
754
- {
755
- //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
756
- if (csArgIt == csArgEit)
757
- {
758
- DBOUT(DAndersen, outs() << " !! not enough args\n");
759
- break;
760
- }
761
- const PAGNode *cs_arg = *csArgIt ;
762
- const PAGNode *fun_arg = *funArgIt;
763
-
764
- if (cs_arg->isPointer() && fun_arg->isPointer())
765
- {
766
- DBOUT(DAndersen, outs() << "process actual parm " << cs_arg->toString() << " \n");
767
- NodeID srcAA = sccRepNode(cs_arg->getId());
768
- NodeID dstFA = sccRepNode(fun_arg->getId());
769
- if(addCopyEdge(srcAA, dstFA))
770
- {
771
- cpySrcNodes.insert(std::make_pair(srcAA,dstFA));
772
- }
773
- }
774
- }
775
-
776
- //Any remaining actual args must be varargs.
777
- if (F->isVarArg())
778
- {
779
- NodeID vaF = sccRepNode(pag->getVarargNode(F));
780
- DBOUT(DPAGBuild, outs() << "\n varargs:");
781
- for (; csArgIt != csArgEit; ++csArgIt)
782
- {
783
- const PAGNode *cs_arg = *csArgIt;
784
- if (cs_arg->isPointer())
785
- {
786
- NodeID vnAA = sccRepNode(cs_arg->getId());
787
- if (addCopyEdge(vnAA,vaF))
788
- {
789
- cpySrcNodes.insert(std::make_pair(vnAA,vaF));
790
- }
791
- }
792
- }
793
- }
794
- if(csArgIt != csArgEit)
795
- {
796
- writeWrnMsg("too many args to non-vararg func.");
797
- writeWrnMsg("(" + cs->getSourceLoc() + ")");
798
- }
799
- }
800
- }
801
-
802
856
  /*!
803
857
  * merge nodeId to newRepId. Return true if the newRepId is a PWC node
804
858
  */
@@ -122,166 +122,4 @@ void Steensgaard::processAllAddr()
122
122
  pushIntoWorklist(dst);
123
123
  }
124
124
  }
125
- }
126
-
127
- bool Steensgaard::updateCallGraph(const CallSiteToFunPtrMap& callsites)
128
- {
129
-
130
- double cgUpdateStart = stat->getClk();
131
-
132
- CallEdgeMap newEdges;
133
- onTheFlyCallGraphSolve(callsites, newEdges);
134
- NodePairSet cpySrcNodes; /// nodes as a src of a generated new copy edge
135
- for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end();
136
- it != eit; ++it)
137
- {
138
- for (FunctionSet::iterator cit = it->second.begin(),
139
- ecit = it->second.end();
140
- cit != ecit; ++cit)
141
- {
142
- connectCaller2CalleeParams(it->first, *cit, cpySrcNodes);
143
- }
144
- }
145
- for (NodePairSet::iterator it = cpySrcNodes.begin(),
146
- eit = cpySrcNodes.end();
147
- it != eit; ++it)
148
- {
149
- pushIntoWorklist(it->first);
150
- }
151
-
152
- double cgUpdateEnd = stat->getClk();
153
- timeOfUpdateCallGraph += (cgUpdateEnd - cgUpdateStart) / TIMEINTERVAL;
154
-
155
- return (!newEdges.empty());
156
- }
157
-
158
- void Steensgaard::heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet& cpySrcNodes)
159
- {
160
- assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
161
- const RetICFGNode* retBlockNode = cs->getRetICFGNode();
162
- const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
163
- NodeID srcret;
164
- CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
165
- if (it != callsite2DummyValPN.end())
166
- {
167
- srcret = getEC(it->second);
168
- }
169
- else
170
- {
171
- NodeID valNode = pag->addDummyValNode();
172
- NodeID objNode = pag->addDummyObjNode(cs->getCallSite()->getType());
173
- addPts(valNode, objNode);
174
- callsite2DummyValPN.insert(std::make_pair(cs, valNode));
175
- consCG->addConstraintNode(new ConstraintNode(valNode), valNode);
176
- consCG->addConstraintNode(new ConstraintNode(objNode), objNode);
177
- srcret = valNode;
178
- }
179
-
180
- NodeID dstrec = getEC(cs_return->getId());
181
- if (addCopyEdge(srcret, dstrec))
182
- cpySrcNodes.insert(std::make_pair(srcret, dstrec));
183
- }
184
-
185
- /*!
186
- * Connect formal and actual parameters for indirect callsites
187
- */
188
- void Steensgaard::connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F,
189
- NodePairSet& cpySrcNodes)
190
- {
191
- assert(F);
192
-
193
- DBOUT(DAndersen, outs() << "connect parameters from indirect callsite "
194
- << cs.getInstruction()->toString() << " to callee "
195
- << *F << "\n");
196
-
197
- const CallICFGNode* callBlockNode = cs;
198
- const RetICFGNode* retBlockNode = cs->getRetICFGNode();
199
-
200
- if (SVFUtil::isHeapAllocExtFunViaRet(F) &&
201
- pag->callsiteHasRet(retBlockNode))
202
- {
203
- heapAllocatorViaIndCall(cs, cpySrcNodes);
204
- }
205
-
206
- if (pag->funHasRet(F) && pag->callsiteHasRet(retBlockNode))
207
- {
208
- const PAGNode* cs_return = pag->getCallSiteRet(retBlockNode);
209
- const PAGNode* fun_return = pag->getFunRet(F);
210
- if (cs_return->isPointer() && fun_return->isPointer())
211
- {
212
- NodeID dstrec = getEC(cs_return->getId());
213
- NodeID srcret = getEC(fun_return->getId());
214
- if (addCopyEdge(srcret, dstrec))
215
- {
216
- cpySrcNodes.insert(std::make_pair(srcret, dstrec));
217
- }
218
- }
219
- else
220
- {
221
- DBOUT(DAndersen, outs() << "not a pointer ignored\n");
222
- }
223
- }
224
-
225
- if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(F))
226
- {
227
-
228
- // connect actual and formal param
229
- const SVFIR::SVFVarList& csArgList =
230
- pag->getCallSiteArgsList(callBlockNode);
231
- const SVFIR::SVFVarList& funArgList = pag->getFunArgsList(F);
232
- // Go through the fixed parameters.
233
- DBOUT(DPAGBuild, outs() << " args:");
234
- SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(),
235
- funArgEit = funArgList.end();
236
- SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(),
237
- csArgEit = csArgList.end();
238
- for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt)
239
- {
240
- // Some programs (e.g. Linux kernel) leave unneeded parameters
241
- // empty.
242
- if (csArgIt == csArgEit)
243
- {
244
- DBOUT(DAndersen, outs() << " !! not enough args\n");
245
- break;
246
- }
247
- const PAGNode* cs_arg = *csArgIt;
248
- const PAGNode* fun_arg = *funArgIt;
249
-
250
- if (cs_arg->isPointer() && fun_arg->isPointer())
251
- {
252
- DBOUT(DAndersen, outs() << "process actual parm "
253
- << cs_arg->toString() << " \n");
254
- NodeID srcAA = getEC(cs_arg->getId());
255
- NodeID dstFA = getEC(fun_arg->getId());
256
- if (addCopyEdge(srcAA, dstFA))
257
- {
258
- cpySrcNodes.insert(std::make_pair(srcAA, dstFA));
259
- }
260
- }
261
- }
262
-
263
- // Any remaining actual args must be varargs.
264
- if (F->isVarArg())
265
- {
266
- NodeID vaF = getEC(pag->getVarargNode(F));
267
- DBOUT(DPAGBuild, outs() << "\n varargs:");
268
- for (; csArgIt != csArgEit; ++csArgIt)
269
- {
270
- const PAGNode* cs_arg = *csArgIt;
271
- if (cs_arg->isPointer())
272
- {
273
- NodeID vnAA = getEC(cs_arg->getId());
274
- if (addCopyEdge(vnAA, vaF))
275
- {
276
- cpySrcNodes.insert(std::make_pair(vnAA, vaF));
277
- }
278
- }
279
- }
280
- }
281
- if (csArgIt != csArgEit)
282
- {
283
- writeWrnMsg("too many args to non-vararg func.");
284
- writeWrnMsg("(" + cs->getSourceLoc() + ")");
285
- }
286
- }
287
- }
125
+ }
@@ -73,7 +73,7 @@ public:
73
73
 
74
74
  typedef std::vector<const Function*> FuncVector;
75
75
 
76
- DCHNode(const DIType* diType, NodeID i = 0, GNodeK k = 0)
76
+ DCHNode(const DIType* diType, NodeID i = 0, GNodeK k = GNodeK::DCHNodeKd)
77
77
  : GenericNode<DCHNode, DCHEdge>(i, k), vtable(nullptr), flags(0)
78
78
  {
79
79
  this->diType = diType;
@@ -33,6 +33,7 @@
33
33
  #include "Graphs/ICFG.h"
34
34
  #include "Util/WorkList.h"
35
35
  #include "BasicTypes.h"
36
+ #include "LLVMModule.h"
36
37
 
37
38
  namespace SVF
38
39
  {
@@ -44,6 +45,12 @@ public:
44
45
 
45
46
  typedef std::vector<const Instruction*> InstVec;
46
47
  typedef Set<const Instruction*> BBSet;
48
+ typedef Map<const Instruction*, CallICFGNode *> CSToCallNodeMapTy;
49
+ typedef Map<const Instruction*, RetICFGNode *> CSToRetNodeMapTy;
50
+ typedef Map<const Instruction*, IntraICFGNode *> InstToBlockNodeMapTy;
51
+ typedef Map<const Function*, FunEntryICFGNode *> FunToFunEntryNodeMapTy;
52
+ typedef Map<const Function*, FunExitICFGNode *> FunToFunExitNodeMapTy;
53
+
47
54
 
48
55
  private:
49
56
  ICFG* icfg;
@@ -55,9 +62,42 @@ public:
55
62
  {
56
63
 
57
64
  }
58
- void build(SVFModule* svfModule);
65
+ void build();
59
66
 
60
67
  private:
68
+
69
+ LLVMModuleSet* llvmModuleSet()
70
+ {
71
+ return LLVMModuleSet::getLLVMModuleSet();
72
+ }
73
+
74
+ CSToRetNodeMapTy& csToRetNodeMap()
75
+ {
76
+ return llvmModuleSet()->CSToRetNodeMap;
77
+ }
78
+
79
+ CSToCallNodeMapTy& csToCallNodeMap()
80
+ {
81
+ return llvmModuleSet()->CSToCallNodeMap;
82
+ }
83
+
84
+ InstToBlockNodeMapTy& instToBlockNodeMap()
85
+ {
86
+ return llvmModuleSet()->InstToBlockNodeMap;
87
+ }
88
+
89
+ FunToFunEntryNodeMapTy& funToFunEntryNodeMap()
90
+ {
91
+ return llvmModuleSet()->FunToFunEntryNodeMap;
92
+ }
93
+
94
+ FunToFunExitNodeMapTy& funToFunExitNodeMap()
95
+ {
96
+ return llvmModuleSet()->FunToFunExitNodeMap;
97
+ }
98
+
99
+ private:
100
+
61
101
  /// Create edges between ICFG nodes within a function
62
102
  ///@{
63
103
  void processFunEntry(const Function* fun, WorkList& worklist);
@@ -71,41 +111,71 @@ private:
71
111
 
72
112
  void checkICFGNodesVisited(const Function* fun);
73
113
 
74
- void connectGlobalToProgEntry(SVFModule* svfModule);
114
+ void connectGlobalToProgEntry();
75
115
 
76
- /// Add/Get an inter block ICFGNode
77
- InterICFGNode* addInterBlockICFGNode(const SVFInstruction* inst);
78
116
 
79
- /// Add/Get a basic block ICFGNode
80
- inline ICFGNode* addBlockICFGNode(const SVFInstruction* inst)
117
+ /// Create edges between ICFG nodes across functions
118
+ void addICFGInterEdges(const Instruction* cs, const Function* callee);
119
+
120
+ inline ICFGNode* getICFGNode(const Instruction* inst)
81
121
  {
82
- ICFGNode* node;
83
- if(SVFUtil::isNonInstricCallSite(inst))
84
- node = addInterBlockICFGNode(inst);
85
- else
86
- node = addIntraBlockICFGNode(inst);
87
- const_cast<SVFBasicBlock*>(inst->getParent())->addICFGNode(node);
88
- return node;
122
+ return llvmModuleSet()->getICFGNode(inst);
89
123
  }
90
124
 
91
- /// Create edges between ICFG nodes across functions
92
- void addICFGInterEdges(const SVFInstruction* cs, const SVFFunction* callee);
125
+ inline bool hasICFGNode(const Instruction* inst)
126
+ {
127
+ return llvmModuleSet()->hasICFGNode(inst);
128
+ }
93
129
 
94
- /// Add a call node
95
- inline CallICFGNode* getCallICFGNode(const SVFInstruction* cs)
130
+ /// get a call node
131
+ inline CallICFGNode* getCallICFGNode(const Instruction* cs)
96
132
  {
97
- return icfg->getCallICFGNode(cs);
133
+ return llvmModuleSet()->getCallICFGNode(cs);
98
134
  }
99
- /// Add a return node
100
- inline RetICFGNode* getRetICFGNode(const SVFInstruction* cs)
135
+ /// get a return node
136
+ inline RetICFGNode* getRetICFGNode(const Instruction* cs)
101
137
  {
102
- return icfg->getRetICFGNode(cs);
138
+ return llvmModuleSet()->getRetICFGNode(cs);
139
+ }
140
+ /// get a intra node
141
+ inline IntraICFGNode* getIntraICFGNode(const Instruction* inst)
142
+ {
143
+ return llvmModuleSet()->getIntraICFGNode(inst);
103
144
  }
104
145
 
146
+ /// get a function entry node
147
+ inline FunEntryICFGNode* getFunEntryICFGNode(const Function* fun)
148
+ {
149
+ return llvmModuleSet()->getFunEntryICFGNode(fun);
150
+ }
151
+ /// get a function exit node
152
+ inline FunExitICFGNode* getFunExitICFGNode(const Function* fun)
153
+ {
154
+ return llvmModuleSet()->getFunExitICFGNode(fun);
155
+ }
156
+
157
+ inline GlobalICFGNode* getGlobalICFGNode() const
158
+ {
159
+ return icfg->getGlobalICFGNode();
160
+ }
161
+
162
+ /// Add/Get an inter block ICFGNode
163
+ InterICFGNode* addInterBlockICFGNode(const Instruction* inst);
164
+
165
+ /// Add/Get a basic block ICFGNode
166
+ inline ICFGNode* addBlockICFGNode(const Instruction* inst);
167
+
105
168
  /// Add and get IntraBlock ICFGNode
106
- IntraICFGNode* addIntraBlockICFGNode(const SVFInstruction* inst)
169
+ IntraICFGNode* addIntraBlockICFGNode(const Instruction* inst);
170
+
171
+ FunEntryICFGNode* addFunEntryBlock(const Function* fun);
172
+
173
+ FunExitICFGNode* addFunExitBlock(const Function* fun);
174
+
175
+ inline void addGlobalICFGNode()
107
176
  {
108
- return icfg->addIntraICFGNode(inst);
177
+ icfg->globalBlockNode = new GlobalICFGNode(icfg->totalICFGNode++);
178
+ icfg->addICFGNode(icfg->globalBlockNode);
109
179
  }
110
180
 
111
181
  private: