svf-tools 1.0.984 → 1.0.985

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 (44) hide show
  1. package/package.json +1 -1
  2. package/svf/include/CFL/CFLAlias.h +3 -3
  3. package/svf/include/Graphs/CHG.h +13 -31
  4. package/svf/include/Graphs/ICFG.h +2 -2
  5. package/svf/include/Graphs/ICFGEdge.h +4 -16
  6. package/svf/include/Graphs/ICFGNode.h +58 -0
  7. package/svf/include/Graphs/ThreadCallGraph.h +6 -6
  8. package/svf/include/MTA/MHP.h +3 -3
  9. package/svf/include/MTA/TCT.h +1 -1
  10. package/svf/include/SVFIR/SVFFileSystem.h +0 -2
  11. package/svf/include/SVFIR/SVFValue.h +0 -131
  12. package/svf/include/Util/SVFUtil.h +20 -37
  13. package/svf/include/Util/ThreadAPI.h +5 -26
  14. package/svf/include/WPA/Andersen.h +3 -3
  15. package/svf/include/WPA/Steensgaard.h +3 -3
  16. package/svf/include/WPA/WPAPass.h +3 -3
  17. package/svf/lib/AE/Svfexe/AEDetector.cpp +14 -18
  18. package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +51 -66
  19. package/svf/lib/CFL/CFLAlias.cpp +11 -12
  20. package/svf/lib/DDA/DDAClient.cpp +2 -2
  21. package/svf/lib/Graphs/CHG.cpp +33 -9
  22. package/svf/lib/Graphs/ICFG.cpp +13 -10
  23. package/svf/lib/MSSA/MemRegion.cpp +3 -3
  24. package/svf/lib/MTA/MHP.cpp +1 -1
  25. package/svf/lib/MemoryModel/PointerAnalysis.cpp +21 -23
  26. package/svf/lib/MemoryModel/PointerAnalysisImpl.cpp +2 -2
  27. package/svf/lib/SABER/SaberCondAllocator.cpp +1 -1
  28. package/svf/lib/SABER/SaberSVFGBuilder.cpp +1 -1
  29. package/svf/lib/SVFIR/SVFFileSystem.cpp +2 -20
  30. package/svf/lib/Util/SVFUtil.cpp +34 -18
  31. package/svf/lib/Util/ThreadAPI.cpp +32 -15
  32. package/svf/lib/WPA/Andersen.cpp +8 -9
  33. package/svf/lib/WPA/AndersenSCD.cpp +1 -2
  34. package/svf/lib/WPA/Steensgaard.cpp +8 -12
  35. package/svf/lib/WPA/TypeAnalysis.cpp +2 -3
  36. package/svf/lib/WPA/WPAPass.cpp +6 -13
  37. package/svf-llvm/include/SVF-LLVM/DCHG.h +7 -7
  38. package/svf-llvm/include/SVF-LLVM/LLVMUtil.h +0 -8
  39. package/svf-llvm/lib/CHGBuilder.cpp +4 -4
  40. package/svf-llvm/lib/DCHG.cpp +8 -7
  41. package/svf-llvm/lib/ICFGBuilder.cpp +2 -2
  42. package/svf-llvm/lib/LLVMModule.cpp +0 -2
  43. package/svf-llvm/lib/LLVMUtil.cpp +0 -58
  44. package/svf-llvm/lib/SVFIRExtAPI.cpp +2 -2
@@ -171,7 +171,7 @@ class Andersen: public AndersenBase
171
171
 
172
172
  public:
173
173
  typedef SCCDetection<ConstraintGraph*> CGSCC;
174
- typedef OrderedMap<CallSite, NodeID> CallSite2DummyValPN;
174
+ typedef OrderedMap<const CallICFGNode*, NodeID> CallSite2DummyValPN;
175
175
 
176
176
  /// Constructor
177
177
  Andersen(SVFIR* _pag, PTATY type = Andersen_WPA, bool alias_check = true)
@@ -243,7 +243,7 @@ public:
243
243
  protected:
244
244
 
245
245
  CallSite2DummyValPN callsite2DummyValPN; ///< Map an instruction to a dummy obj which created at an indirect callsite, which invokes a heap allocator
246
- void heapAllocatorViaIndCall(CallSite cs,NodePairSet &cpySrcNodes);
246
+ void heapAllocatorViaIndCall(const CallICFGNode* cs,NodePairSet &cpySrcNodes);
247
247
 
248
248
  /// Handle diff points-to set.
249
249
  virtual inline void computeDiffPts(NodeID id)
@@ -315,7 +315,7 @@ protected:
315
315
  virtual bool updateCallGraph(const CallSiteToFunPtrMap& callsites);
316
316
 
317
317
  /// Connect formal and actual parameters for indirect callsites
318
- void connectCaller2CalleeParams(CallSite cs, const SVFFunction* F, NodePairSet& cpySrcNodes);
318
+ void connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F, NodePairSet& cpySrcNodes);
319
319
 
320
320
  /// Merge sub node to its rep
321
321
  virtual void mergeNodeToRep(NodeID nodeId,NodeID newRepId);
@@ -23,7 +23,7 @@ class Steensgaard : public AndersenBase
23
23
  public:
24
24
  typedef Map<NodeID, NodeID> NodeToEquivClassMap;
25
25
  typedef Map<NodeID, Set<NodeID>> NodeToSubsMap;
26
- typedef OrderedMap<CallSite, NodeID> CallSite2DummyValPN;
26
+ typedef OrderedMap<const CallICFGNode*, NodeID> CallSite2DummyValPN;
27
27
 
28
28
  /// Constructor
29
29
  Steensgaard(SVFIR* _pag) : AndersenBase(_pag, Steensgaard_WPA, true) {}
@@ -121,13 +121,13 @@ protected:
121
121
  callsite2DummyValPN; ///< Map an instruction to a dummy obj which
122
122
  ///< created at an indirect callsite, which invokes
123
123
  ///< a heap allocator
124
- void heapAllocatorViaIndCall(CallSite cs, NodePairSet& cpySrcNodes);
124
+ void heapAllocatorViaIndCall(const CallICFGNode* cs, NodePairSet& cpySrcNodes);
125
125
 
126
126
  /// Update call graph for the input indirect callsites
127
127
  virtual bool updateCallGraph(const CallSiteToFunPtrMap& callsites);
128
128
 
129
129
  /// Connect formal and actual parameters for indirect callsites
130
- void connectCaller2CalleeParams(CallSite cs, const SVFFunction* F,
130
+ void connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F,
131
131
  NodePairSet& cpySrcNodes);
132
132
 
133
133
  private:
@@ -86,7 +86,7 @@ public:
86
86
  virtual void PrintAliasPairs(PointerAnalysis* pta);
87
87
 
88
88
  /// Interface of mod-ref analysis to determine whether a CallSite instruction can mod or ref any memory location
89
- virtual ModRefInfo getModRefInfo(const CallSite callInst);
89
+ virtual ModRefInfo getModRefInfo(const CallICFGNode* callInst);
90
90
 
91
91
  /// Interface of mod-ref analysis to determine whether a CallSite instruction can mod or ref a specific memory location, given Location infos
92
92
  // virtual inline ModRefInfo getModRefInfo(const CallSite callInst, const MemoryLocation& Loc)
@@ -95,10 +95,10 @@ public:
95
95
  // }
96
96
 
97
97
  /// Interface of mod-ref analysis to determine whether a CallSite instruction can mod or ref a specific memory location, given Value infos
98
- virtual ModRefInfo getModRefInfo(const CallSite callInst, const SVFValue* V);
98
+ virtual ModRefInfo getModRefInfo(const CallICFGNode* callInst, const SVFValue* V);
99
99
 
100
100
  /// Interface of mod-ref analysis between two CallSite instructions
101
- virtual ModRefInfo getModRefInfo(const CallSite callInst1, const CallSite callInst2);
101
+ virtual ModRefInfo getModRefInfo(const CallICFGNode* callInst1, const CallICFGNode* callInst2);
102
102
 
103
103
  /// Run pointer analysis on SVFModule
104
104
  virtual void runOnModule(SVFIR* svfModule);
@@ -148,7 +148,6 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
148
148
  SVFIR* svfir = PAG::getPAG();
149
149
  const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite());
150
150
  assert(fun && "SVFFunction* is nullptr");
151
- CallSite cs = SVFUtil::getSVFCallSite(call);
152
151
 
153
152
  AbstractInterpretation::ExtAPIType extType = AbstractInterpretation::UNCLASSIFIED;
154
153
 
@@ -177,10 +176,10 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
177
176
  extAPIBufOverflowCheckRules.at(fun->getName());
178
177
  for (auto arg : args)
179
178
  {
180
- IntervalValue offset = as[svfir->getValueNode(cs.getArgument(arg.second))].getInterval() - IntervalValue(1);
181
- if (!canSafelyAccessMemory(as, cs.getArgument(arg.first), offset))
179
+ IntervalValue offset = as[svfir->getValueNode(call->getArgument(arg.second))].getInterval() - IntervalValue(1);
180
+ if (!canSafelyAccessMemory(as, call->getArgument(arg.first), offset))
182
181
  {
183
- AEException bug(call->getCallSite()->toString());
182
+ AEException bug(call->toString());
184
183
  addBugToReporter(bug, call);
185
184
  }
186
185
  }
@@ -196,10 +195,10 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
196
195
  extAPIBufOverflowCheckRules.at(fun->getName());
197
196
  for (auto arg : args)
198
197
  {
199
- IntervalValue offset = as[svfir->getValueNode(cs.getArgument(arg.second))].getInterval() - IntervalValue(1);
200
- if (!canSafelyAccessMemory(as, cs.getArgument(arg.first), offset))
198
+ IntervalValue offset = as[svfir->getValueNode(call->getArgument(arg.second))].getInterval() - IntervalValue(1);
199
+ if (!canSafelyAccessMemory(as, call->getArgument(arg.first), offset))
201
200
  {
202
- AEException bug(call->getCallSite()->toString());
201
+ AEException bug(call->toString());
203
202
  addBugToReporter(bug, call);
204
203
  }
205
204
  }
@@ -208,7 +207,7 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
208
207
  {
209
208
  if (!detectStrcpy(as, call))
210
209
  {
211
- AEException bug(call->getCallSite()->toString());
210
+ AEException bug(call->toString());
212
211
  addBugToReporter(bug, call);
213
212
  }
214
213
  }
@@ -216,7 +215,7 @@ void BufOverflowDetector::detectExtAPI(AbstractState& as,
216
215
  {
217
216
  if (!detectStrcat(as, call))
218
217
  {
219
- AEException bug(call->getCallSite()->toString());
218
+ AEException bug(call->toString());
220
219
  addBugToReporter(bug, call);
221
220
  }
222
221
  }
@@ -322,9 +321,8 @@ void BufOverflowDetector::updateGepObjOffsetFromBase(SVF::AddressValue gepAddrs,
322
321
  */
323
322
  bool BufOverflowDetector::detectStrcpy(AbstractState& as, const CallICFGNode *call)
324
323
  {
325
- CallSite cs = SVFUtil::getSVFCallSite(call);
326
- const SVFValue* arg0Val = cs.getArgument(0);
327
- const SVFValue* arg1Val = cs.getArgument(1);
324
+ const SVFValue* arg0Val = call->getArgument(0);
325
+ const SVFValue* arg1Val = call->getArgument(1);
328
326
  IntervalValue strLen = AbstractInterpretation::getAEInstance().getStrlen(as, arg1Val);
329
327
  return canSafelyAccessMemory(as, arg0Val, strLen);
330
328
  }
@@ -349,9 +347,8 @@ bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *ca
349
347
 
350
348
  if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
351
349
  {
352
- CallSite cs = SVFUtil::getSVFCallSite(call);
353
- const SVFValue* arg0Val = cs.getArgument(0);
354
- const SVFValue* arg1Val = cs.getArgument(1);
350
+ const SVFValue* arg0Val = call->getArgument(0);
351
+ const SVFValue* arg1Val = call->getArgument(1);
355
352
  IntervalValue strLen0 = AbstractInterpretation::getAEInstance().getStrlen(as, arg0Val);
356
353
  IntervalValue strLen1 = AbstractInterpretation::getAEInstance().getStrlen(as, arg1Val);
357
354
  IntervalValue totalLen = strLen0 + strLen1;
@@ -359,9 +356,8 @@ bool BufOverflowDetector::detectStrcat(AbstractState& as, const CallICFGNode *ca
359
356
  }
360
357
  else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
361
358
  {
362
- CallSite cs = SVFUtil::getSVFCallSite(call);
363
- const SVFValue* arg0Val = cs.getArgument(0);
364
- const SVFValue* arg2Val = cs.getArgument(2);
359
+ const SVFValue* arg0Val = call->getArgument(0);
360
+ const SVFValue* arg2Val = call->getArgument(2);
365
361
  IntervalValue arg2Num = as[svfir->getValueNode(arg2Val)].getInterval();
366
362
  IntervalValue strLen0 = AbstractInterpretation::getAEInstance().getStrlen(as, arg0Val);
367
363
  IntervalValue totalLen = strLen0 + arg2Num;
@@ -906,7 +906,7 @@ void AEStat::finializeStat()
906
906
  }
907
907
  if (const CallICFGNode *callNode = dyn_cast<CallICFGNode>(it.second))
908
908
  {
909
- if (!isExtCall(callNode->getCallSite()))
909
+ if (!isExtCall(callNode))
910
910
  {
911
911
  callSiteNum++;
912
912
  }
@@ -965,13 +965,12 @@ void AbstractInterpretation::initExtFunMap()
965
965
  #define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \
966
966
  auto sse_##FUNC_NAME = [this](const CallICFGNode *callNode) { \
967
967
  /* run real ext function */ \
968
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode); \
969
968
  AbstractState& as = getAbsStateFromTrace(callNode); \
970
- u32_t rhs_id = svfir->getValueNode(cs.getArgument(0)); \
969
+ u32_t rhs_id = svfir->getValueNode(callNode->getArgument(0)); \
971
970
  if (!as.inVarToValTable(rhs_id)) return; \
972
971
  u32_t rhs = as[rhs_id].getInterval().lb().getIntNumeral(); \
973
972
  s32_t res = FUNC_NAME(rhs); \
974
- u32_t lhsId = svfir->getValueNode(cs.getInstruction()); \
973
+ u32_t lhsId = svfir->getValueNode(callNode->getCallSite()); \
975
974
  as[lhsId] = IntervalValue(res); \
976
975
  return; \
977
976
  }; \
@@ -999,7 +998,7 @@ void AbstractInterpretation::initExtFunMap()
999
998
  auto sse_svf_assert = [this](const CallICFGNode* callNode)
1000
999
  {
1001
1000
  checkpoints.erase(callNode);
1002
- u32_t arg0 = svfir->getValueNode(SVFUtil::getSVFCallSite(callNode).getArgument(0));
1001
+ u32_t arg0 = svfir->getValueNode(callNode->getArgument(0));
1003
1002
  AbstractState&as = getAbsStateFromTrace(callNode);
1004
1003
  as[arg0].getInterval().meet_with(IntervalValue(1, 1));
1005
1004
  if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
@@ -1017,14 +1016,13 @@ void AbstractInterpretation::initExtFunMap()
1017
1016
 
1018
1017
  auto svf_print = [&](const CallICFGNode* callNode)
1019
1018
  {
1020
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1021
- if (cs.arg_size() < 2) return;
1019
+ if (callNode->arg_size() < 2) return;
1022
1020
  AbstractState&as = getAbsStateFromTrace(callNode);
1023
- u32_t num_id = svfir->getValueNode(cs.getArgument(0));
1024
- std::string text = strRead(as, cs.getArgument(1));
1021
+ u32_t num_id = svfir->getValueNode(callNode->getArgument(0));
1022
+ std::string text = strRead(as, callNode->getArgument(1));
1025
1023
  assert(as.inVarToValTable(num_id) && "print() should pass integer");
1026
1024
  IntervalValue itv = as[num_id].getInterval();
1027
- std::cout << "Text: " << text <<", Value: " << cs.getArgument(0)->toString() << ", PrintVal: " << itv.toString() << std::endl;
1025
+ std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString() << ", PrintVal: " << itv.toString() << std::endl;
1028
1026
  return;
1029
1027
  };
1030
1028
  func_map["svf_print"] = svf_print;
@@ -1033,11 +1031,10 @@ void AbstractInterpretation::initExtFunMap()
1033
1031
  auto sse_scanf = [&](const CallICFGNode* callNode)
1034
1032
  {
1035
1033
  AbstractState& as = getAbsStateFromTrace(callNode);
1036
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1037
1034
  //scanf("%d", &data);
1038
- if (cs.arg_size() < 2) return;
1035
+ if (callNode->arg_size() < 2) return;
1039
1036
 
1040
- u32_t dst_id = svfir->getValueNode(cs.getArgument(1));
1037
+ u32_t dst_id = svfir->getValueNode(callNode->getArgument(1));
1041
1038
  if (!as.inVarToAddrsTable(dst_id))
1042
1039
  {
1043
1040
  return;
@@ -1056,10 +1053,9 @@ void AbstractInterpretation::initExtFunMap()
1056
1053
  auto sse_fscanf = [&](const CallICFGNode* callNode)
1057
1054
  {
1058
1055
  //fscanf(stdin, "%d", &data);
1059
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1060
- if (cs.arg_size() < 3) return;
1056
+ if (callNode->arg_size() < 3) return;
1061
1057
  AbstractState& as = getAbsStateFromTrace(callNode);
1062
- u32_t dst_id = svfir->getValueNode(cs.getArgument(2));
1058
+ u32_t dst_id = svfir->getValueNode(callNode->getArgument(2));
1063
1059
  if (!as.inVarToAddrsTable(dst_id))
1064
1060
  {
1065
1061
  }
@@ -1086,11 +1082,10 @@ void AbstractInterpretation::initExtFunMap()
1086
1082
 
1087
1083
  auto sse_fread = [&](const CallICFGNode *callNode)
1088
1084
  {
1089
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1090
- if (cs.arg_size() < 3) return;
1085
+ if (callNode->arg_size() < 3) return;
1091
1086
  AbstractState&as = getAbsStateFromTrace(callNode);
1092
- u32_t block_count_id = svfir->getValueNode(cs.getArgument(2));
1093
- u32_t block_size_id = svfir->getValueNode(cs.getArgument(1));
1087
+ u32_t block_count_id = svfir->getValueNode(callNode->getArgument(2));
1088
+ u32_t block_size_id = svfir->getValueNode(callNode->getArgument(1));
1094
1089
  IntervalValue block_count = as[block_count_id].getInterval();
1095
1090
  IntervalValue block_size = as[block_size_id].getInterval();
1096
1091
  IntervalValue block_byte = block_count * block_size;
@@ -1104,20 +1099,19 @@ void AbstractInterpretation::initExtFunMap()
1104
1099
 
1105
1100
  auto sse_snprintf = [&](const CallICFGNode *callNode)
1106
1101
  {
1107
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1108
- if (cs.arg_size() < 2) return;
1102
+ if (callNode->arg_size() < 2) return;
1109
1103
  AbstractState&as = getAbsStateFromTrace(callNode);
1110
- u32_t size_id = svfir->getValueNode(cs.getArgument(1));
1111
- u32_t dst_id = svfir->getValueNode(cs.getArgument(0));
1104
+ u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
1105
+ u32_t dst_id = svfir->getValueNode(callNode->getArgument(0));
1112
1106
  // get elem size of arg2
1113
1107
  u32_t elemSize = 1;
1114
- if (cs.getArgument(2)->getType()->isArrayTy())
1108
+ if (callNode->getArgument(2)->getType()->isArrayTy())
1115
1109
  {
1116
- elemSize = SVFUtil::dyn_cast<SVFArrayType>(cs.getArgument(2)->getType())->getTypeOfElement()->getByteSize();
1110
+ elemSize = SVFUtil::dyn_cast<SVFArrayType>(callNode->getArgument(2)->getType())->getTypeOfElement()->getByteSize();
1117
1111
  }
1118
- else if (cs.getArgument(2)->getType()->isPointerTy())
1112
+ else if (callNode->getArgument(2)->getType()->isPointerTy())
1119
1113
  {
1120
- elemSize = as.getPointeeElement(svfir->getValueNode(cs.getArgument(2)))->getByteSize();
1114
+ elemSize = as.getPointeeElement(svfir->getValueNode(callNode->getArgument(2)))->getByteSize();
1121
1115
  }
1122
1116
  else
1123
1117
  {
@@ -1145,10 +1139,9 @@ void AbstractInterpretation::initExtFunMap()
1145
1139
  {
1146
1140
  // itoa(num, ch, 10);
1147
1141
  // num: int, ch: char*, 10 is decimal
1148
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1149
- if (cs.arg_size() < 3) return;
1142
+ if (callNode->arg_size() < 3) return;
1150
1143
  AbstractState&as = getAbsStateFromTrace(callNode);
1151
- u32_t num_id = svfir->getValueNode(cs.getArgument(0));
1144
+ u32_t num_id = svfir->getValueNode(callNode->getArgument(0));
1152
1145
 
1153
1146
  u32_t num = (u32_t) as[num_id].getInterval().getNumeral();
1154
1147
  std::string snum = std::to_string(num);
@@ -1159,12 +1152,11 @@ void AbstractInterpretation::initExtFunMap()
1159
1152
  auto sse_strlen = [&](const CallICFGNode *callNode)
1160
1153
  {
1161
1154
  // check the arg size
1162
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1163
- if (cs.arg_size() < 1) return;
1164
- const SVFValue* strValue = cs.getArgument(0);
1155
+ if (callNode->arg_size() < 1) return;
1156
+ const SVFValue* strValue = callNode->getArgument(0);
1165
1157
  AbstractState& as = getAbsStateFromTrace(callNode);
1166
1158
  NodeID value_id = svfir->getValueNode(strValue);
1167
- u32_t lhsId = svfir->getValueNode(cs.getInstruction());
1159
+ u32_t lhsId = svfir->getValueNode(callNode->getCallSite());
1168
1160
  u32_t dst_size = 0;
1169
1161
  for (const auto& addr : as[value_id].getAddrs())
1170
1162
  {
@@ -1220,24 +1212,22 @@ void AbstractInterpretation::initExtFunMap()
1220
1212
  auto sse_recv = [&](const CallICFGNode *callNode)
1221
1213
  {
1222
1214
  // recv(sockfd, buf, len, flags);
1223
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1224
- if (cs.arg_size() < 4) return;
1215
+ if (callNode->arg_size() < 4) return;
1225
1216
  AbstractState&as = getAbsStateFromTrace(callNode);
1226
- u32_t len_id = svfir->getValueNode(cs.getArgument(2));
1217
+ u32_t len_id = svfir->getValueNode(callNode->getArgument(2));
1227
1218
  IntervalValue len = as[len_id].getInterval() - IntervalValue(1);
1228
- u32_t lhsId = svfir->getValueNode(cs.getInstruction());
1219
+ u32_t lhsId = svfir->getValueNode(callNode->getCallSite());
1229
1220
  as[lhsId] = len;
1230
1221
  };
1231
1222
  func_map["recv"] = sse_recv;
1232
1223
  func_map["__recv"] = sse_recv;
1233
1224
  auto safe_bufaccess = [&](const CallICFGNode *callNode)
1234
1225
  {
1235
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1236
1226
  checkpoints.erase(callNode);
1237
1227
  //void SAFE_BUFACCESS(void* data, int size);
1238
- if (cs.arg_size() < 2) return;
1228
+ if (callNode->arg_size() < 2) return;
1239
1229
  AbstractState&as = getAbsStateFromTrace(callNode);
1240
- u32_t size_id = svfir->getValueNode(cs.getArgument(1));
1230
+ u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
1241
1231
  IntervalValue val = as[size_id].getInterval();
1242
1232
  if (val.isBottom())
1243
1233
  {
@@ -1250,7 +1240,7 @@ void AbstractInterpretation::initExtFunMap()
1250
1240
  if (SVFUtil::isa<BufOverflowDetector>(detector))
1251
1241
  {
1252
1242
  BufOverflowDetector* bufDetector = SVFUtil::cast<BufOverflowDetector>(detector.get());
1253
- bool isSafe = bufDetector->canSafelyAccessMemory(as, cs.getArgument(0), val);
1243
+ bool isSafe = bufDetector->canSafelyAccessMemory(as, callNode->getArgument(0), val);
1254
1244
  if (isSafe)
1255
1245
  {
1256
1246
  std::cout << "safe buffer access success: " << callNode->toString() << std::endl;
@@ -1259,7 +1249,7 @@ void AbstractInterpretation::initExtFunMap()
1259
1249
  else
1260
1250
  {
1261
1251
  std::string err_msg = "this SAFE_BUFACCESS should be a safe access but detected buffer overflow. Pos: ";
1262
- err_msg += cs.getInstruction()->getSourceLoc();
1252
+ err_msg += callNode->getSourceLoc();
1263
1253
  std::cerr << err_msg << std::endl;
1264
1254
  assert(false);
1265
1255
  }
@@ -1270,12 +1260,11 @@ void AbstractInterpretation::initExtFunMap()
1270
1260
 
1271
1261
  auto unsafe_bufaccess = [&](const CallICFGNode *callNode)
1272
1262
  {
1273
- const CallSite& cs = SVFUtil::getSVFCallSite(callNode);
1274
1263
  checkpoints.erase(callNode);
1275
1264
  //void UNSAFE_BUFACCESS(void* data, int size);
1276
- if (cs.arg_size() < 2) return;
1265
+ if (callNode->arg_size() < 2) return;
1277
1266
  AbstractState&as = getAbsStateFromTrace(callNode);
1278
- u32_t size_id = svfir->getValueNode(cs.getArgument(1));
1267
+ u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
1279
1268
  IntervalValue val = as[size_id].getInterval();
1280
1269
  if (val.isBottom())
1281
1270
  {
@@ -1287,7 +1276,7 @@ void AbstractInterpretation::initExtFunMap()
1287
1276
  if (SVFUtil::isa<BufOverflowDetector>(detector))
1288
1277
  {
1289
1278
  BufOverflowDetector* bufDetector = SVFUtil::cast<BufOverflowDetector>(detector.get());
1290
- bool isSafe = bufDetector->canSafelyAccessMemory(as, cs.getArgument(0), val);
1279
+ bool isSafe = bufDetector->canSafelyAccessMemory(as, callNode->getArgument(0), val);
1291
1280
  if (!isSafe)
1292
1281
  {
1293
1282
  std::cout << "detect buffer overflow success: " << callNode->toString() << std::endl;
@@ -1296,7 +1285,7 @@ void AbstractInterpretation::initExtFunMap()
1296
1285
  else
1297
1286
  {
1298
1287
  std::string err_msg = "this UNSAFE_BUFACCESS should be a buffer overflow but not detected. Pos: ";
1299
- err_msg += cs.getInstruction()->getSourceLoc();
1288
+ err_msg += callNode->getSourceLoc();
1300
1289
  std::cerr << err_msg << std::endl;
1301
1290
  assert(false);
1302
1291
  }
@@ -1346,7 +1335,6 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
1346
1335
  AbstractState& as = getAbsStateFromTrace(call);
1347
1336
  const SVFFunction *fun = SVFUtil::getCallee(call->getCallSite());
1348
1337
  assert(fun && "SVFFunction* is nullptr");
1349
- CallSite cs = SVFUtil::getSVFCallSite(call);
1350
1338
  ExtAPIType extType = UNCLASSIFIED;
1351
1339
  // get type of mem api
1352
1340
  for (const std::string &annotation: fun->getAnnotations())
@@ -1368,7 +1356,7 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
1368
1356
  }
1369
1357
  else
1370
1358
  {
1371
- u32_t lhsId = svfir->getValueNode(SVFUtil::getSVFCallSite(call).getInstruction());
1359
+ u32_t lhsId = svfir->getValueNode(call->getCallSite());
1372
1360
  if (as.inVarToAddrsTable(lhsId))
1373
1361
  {
1374
1362
 
@@ -1383,15 +1371,15 @@ void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
1383
1371
  // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
1384
1372
  else if (extType == MEMCPY)
1385
1373
  {
1386
- IntervalValue len = as[svfir->getValueNode(cs.getArgument(2))].getInterval();
1387
- handleMemcpy(as, cs.getArgument(0), cs.getArgument(1), len, 0);
1374
+ IntervalValue len = as[svfir->getValueNode(call->getArgument(2))].getInterval();
1375
+ handleMemcpy(as, call->getArgument(0), call->getArgument(1), len, 0);
1388
1376
  }
1389
1377
  else if (extType == MEMSET)
1390
1378
  {
1391
1379
  // memset dst is arg0, elem is arg1, size is arg2
1392
- IntervalValue len = as[svfir->getValueNode(cs.getArgument(2))].getInterval();
1393
- IntervalValue elem = as[svfir->getValueNode(cs.getArgument(1))].getInterval();
1394
- handleMemset(as,cs.getArgument(0), elem, len);
1380
+ IntervalValue len = as[svfir->getValueNode(call->getArgument(2))].getInterval();
1381
+ IntervalValue elem = as[svfir->getValueNode(call->getArgument(1))].getInterval();
1382
+ handleMemset(as,call->getArgument(0), elem, len);
1395
1383
  }
1396
1384
  else if (extType == STRCPY)
1397
1385
  {
@@ -1450,9 +1438,8 @@ void AbstractInterpretation::handleStrcpy(const CallICFGNode *call)
1450
1438
  // strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk
1451
1439
  // get the dst and src
1452
1440
  AbstractState& as = getAbsStateFromTrace(call);
1453
- CallSite cs = SVFUtil::getSVFCallSite(call);
1454
- const SVFValue* arg0Val = cs.getArgument(0);
1455
- const SVFValue* arg1Val = cs.getArgument(1);
1441
+ const SVFValue* arg0Val = call->getArgument(0);
1442
+ const SVFValue* arg1Val = call->getArgument(1);
1456
1443
  IntervalValue strLen = getStrlen(as, arg1Val);
1457
1444
  // no need to -1, since it has \0 as the last byte
1458
1445
  handleMemcpy(as, arg0Val, arg1Val, strLen, strLen.lb().getIntNumeral());
@@ -1545,9 +1532,8 @@ void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call)
1545
1532
  const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
1546
1533
  if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
1547
1534
  {
1548
- CallSite cs = SVFUtil::getSVFCallSite(call);
1549
- const SVFValue* arg0Val = cs.getArgument(0);
1550
- const SVFValue* arg1Val = cs.getArgument(1);
1535
+ const SVFValue* arg0Val = call->getArgument(0);
1536
+ const SVFValue* arg1Val = call->getArgument(1);
1551
1537
  IntervalValue strLen0 = getStrlen(as, arg0Val);
1552
1538
  IntervalValue strLen1 = getStrlen(as, arg1Val);
1553
1539
  IntervalValue totalLen = strLen0 + strLen1;
@@ -1556,10 +1542,9 @@ void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call)
1556
1542
  }
1557
1543
  else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
1558
1544
  {
1559
- CallSite cs = SVFUtil::getSVFCallSite(call);
1560
- const SVFValue* arg0Val = cs.getArgument(0);
1561
- const SVFValue* arg1Val = cs.getArgument(1);
1562
- const SVFValue* arg2Val = cs.getArgument(2);
1545
+ const SVFValue* arg0Val = call->getArgument(0);
1546
+ const SVFValue* arg1Val = call->getArgument(1);
1547
+ const SVFValue* arg2Val = call->getArgument(2);
1563
1548
  IntervalValue arg2Num = as[svfir->getValueNode(arg2Val)].getInterval();
1564
1549
  IntervalValue strLen0 = getStrlen(as, arg0Val);
1565
1550
  IntervalValue totalLen = strLen0 + arg2Num;
@@ -42,9 +42,9 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call
42
42
  {
43
43
  const CallICFGNode* cs = iter->first;
44
44
 
45
- if (SVFUtil::getSVFCallSite(cs).isVirtualCall())
45
+ if (cs->isVirtualCall())
46
46
  {
47
- const SVFValue* vtbl = SVFUtil::getSVFCallSite(cs).getVtablePtr();
47
+ const SVFValue* vtbl = cs->getVtablePtr();
48
48
  assert(pag->hasValueNode(vtbl));
49
49
  NodeID vtblId = pag->getValueNode(vtbl);
50
50
  resolveCPPIndCalls(cs, getCFLPts(vtblId), newEdges);
@@ -58,14 +58,14 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call
58
58
  * Connect formal and actual parameters for indirect callsites
59
59
  */
60
60
 
61
- void CFLAlias::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F)
61
+ void CFLAlias::connectCaller2CalleeParams(const CallICFGNode* cs, const SVFFunction* F)
62
62
  {
63
63
  assert(F);
64
64
 
65
- DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs.getInstruction()->toString() << " to callee " << *F << "\n");
65
+ DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs->toString() << " to callee " << *F << "\n");
66
66
 
67
- CallICFGNode* callBlockNode = svfir->getICFG()->getCallICFGNode(cs.getInstruction());
68
- RetICFGNode* retBlockNode = svfir->getICFG()->getRetICFGNode(cs.getInstruction());
67
+ const CallICFGNode* callBlockNode = cs;
68
+ const RetICFGNode* retBlockNode = cs->getRetICFGNode();
69
69
 
70
70
  if(SVFUtil::isHeapAllocExtFunViaRet(F) && svfir->callsiteHasRet(retBlockNode))
71
71
  {
@@ -136,15 +136,15 @@ void CFLAlias::connectCaller2CalleeParams(CallSite cs, const SVFFunction* F)
136
136
  if(csArgIt != csArgEit)
137
137
  {
138
138
  writeWrnMsg("too many args to non-vararg func.");
139
- writeWrnMsg("(" + cs.getInstruction()->getSourceLoc() + ")");
139
+ writeWrnMsg("(" + cs->getSourceLoc() + ")");
140
140
  }
141
141
  }
142
142
  }
143
143
 
144
- void CFLAlias::heapAllocatorViaIndCall(CallSite cs)
144
+ void CFLAlias::heapAllocatorViaIndCall(const CallICFGNode* cs)
145
145
  {
146
146
  assert(SVFUtil::getCallee(cs) == nullptr && "not an indirect callsite?");
147
- RetICFGNode* retBlockNode = svfir->getICFG()->getRetICFGNode(cs.getInstruction());
147
+ const RetICFGNode* retBlockNode = cs->getRetICFGNode();
148
148
  const PAGNode* cs_return = svfir->getCallSiteRet(retBlockNode);
149
149
  NodeID srcret;
150
150
  CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
@@ -155,7 +155,7 @@ void CFLAlias::heapAllocatorViaIndCall(CallSite cs)
155
155
  else
156
156
  {
157
157
  NodeID valNode = svfir->addDummyValNode();
158
- NodeID objNode = svfir->addDummyObjNode(cs.getType());
158
+ NodeID objNode = svfir->addDummyObjNode(cs->getCallSite()->getType());
159
159
  callsite2DummyValPN.insert(std::make_pair(cs,valNode));
160
160
  graph->addCFLNode(valNode, new CFLNode(valNode));
161
161
  graph->addCFLNode(objNode, new CFLNode(objNode));
@@ -175,10 +175,9 @@ bool CFLAlias::updateCallGraph(const CallSiteToFunPtrMap& callsites)
175
175
  onTheFlyCallGraphSolve(callsites,newEdges);
176
176
  for(CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end(); it!=eit; ++it )
177
177
  {
178
- CallSite cs = SVFUtil::getSVFCallSite(it->first);
179
178
  for(FunctionSet::iterator cit = it->second.begin(), ecit = it->second.end(); cit!=ecit; ++cit)
180
179
  {
181
- connectCaller2CalleeParams(cs,*cit);
180
+ connectCaller2CalleeParams(it->first,*cit);
182
181
  }
183
182
  }
184
183
 
@@ -81,9 +81,9 @@ OrderedNodeSet& FunptrDDAClient::collectCandidateQueries(SVFIR* p)
81
81
  for(SVFIR::CallSiteToFunPtrMap::const_iterator it = pag->getIndirectCallsites().begin(),
82
82
  eit = pag->getIndirectCallsites().end(); it!=eit; ++it)
83
83
  {
84
- if (SVFUtil::getSVFCallSite(it->first).isVirtualCall())
84
+ if (it->first->isVirtualCall())
85
85
  {
86
- const SVFValue* vtblPtr = SVFUtil::getSVFCallSite(it->first).getVtablePtr();
86
+ const SVFValue* vtblPtr = it->first->getVtablePtr();
87
87
  assert(pag->hasValueNode(vtblPtr) && "not a vtable pointer?");
88
88
  NodeID vtblId = pag->getValueNode(vtblPtr);
89
89
  addCandidate(vtblId);
@@ -29,6 +29,7 @@
29
29
 
30
30
  #include "Graphs/CHG.h"
31
31
  #include "Util/SVFUtil.h"
32
+ #include "Graphs/ICFG.h"
32
33
 
33
34
  using namespace SVF;
34
35
  using namespace SVFUtil;
@@ -48,16 +49,16 @@ static bool hasEdge(const CHNode *src, const CHNode *dst,
48
49
  return false;
49
50
  }
50
51
 
51
- static bool checkArgTypes(CallSite cs, const SVFFunction* fn)
52
+ static bool checkArgTypes(const SVFCallInst* cs, const SVFFunction* fn)
52
53
  {
53
54
 
54
55
  // here we skip the first argument (i.e., this pointer)
55
- u32_t arg_size = (fn->arg_size() > cs.arg_size()) ? cs.arg_size(): fn->arg_size();
56
+ u32_t arg_size = (fn->arg_size() > cs->arg_size()) ? cs->arg_size(): fn->arg_size();
56
57
  if(arg_size > 1)
57
58
  {
58
59
  for (unsigned i = 1; i < arg_size; i++)
59
60
  {
60
- auto cs_arg = cs.getArgOperand(i);
61
+ auto cs_arg = cs->getArgOperand(i);
61
62
  auto fn_arg = fn->getArg(i);
62
63
  if (cs_arg->getType() != fn_arg->getType())
63
64
  {
@@ -69,6 +70,29 @@ static bool checkArgTypes(CallSite cs, const SVFFunction* fn)
69
70
  return true;
70
71
  }
71
72
 
73
+ bool CHGraph::csHasVtblsBasedonCHA(const CallICFGNode* cs)
74
+ {
75
+ CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs->getCallSite());
76
+ return it != csToCHAVtblsMap.end();
77
+ }
78
+ bool CHGraph::csHasVFnsBasedonCHA(const CallICFGNode* cs)
79
+ {
80
+ CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs->getCallSite());
81
+ return it != csToCHAVFnsMap.end();
82
+ }
83
+ const VTableSet& CHGraph::getCSVtblsBasedonCHA(const CallICFGNode* cs)
84
+ {
85
+ CallSiteToVTableSetMap::const_iterator it = csToCHAVtblsMap.find(cs->getCallSite());
86
+ assert(it != csToCHAVtblsMap.end() && "cs does not have vtabls based on CHA.");
87
+ return it->second;
88
+ }
89
+ const VFunSet& CHGraph::getCSVFsBasedonCHA(const CallICFGNode* cs)
90
+ {
91
+ CallSiteToVFunSetMap::const_iterator it = csToCHAVFnsMap.find(cs->getCallSite());
92
+ assert(it != csToCHAVFnsMap.end() && "cs does not have vfns based on CHA.");
93
+ return it->second;
94
+ }
95
+
72
96
  void CHGraph::addEdge(const string className, const string baseClassName,
73
97
  CHEdge::CHEDGETYPE edgeType)
74
98
  {
@@ -96,13 +120,13 @@ CHNode *CHGraph::getNode(const string name) const
96
120
  * Get virtual functions for callsite "cs" based on vtbls (calculated
97
121
  * based on pointsto set)
98
122
  */
99
- void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &virtualFunctions)
123
+ void CHGraph::getVFnsFromVtbls(const SVFCallInst* callsite, const VTableSet &vtbls, VFunSet &virtualFunctions)
100
124
  {
101
-
125
+ const SVFVirtualCallInst* cs = SVFUtil::cast<SVFVirtualCallInst>(callsite);
102
126
  /// get target virtual functions
103
- size_t idx = cs.getFunIdxInVtable();
127
+ size_t idx = cs->getFunIdxInVtable();
104
128
  /// get the function name of the virtual callsite
105
- string funName = cs.getFunNameOfVirtualCall();
129
+ string funName = cs->getFunNameOfVirtualCall();
106
130
  for (const SVFGlobalValue *vt : vtbls)
107
131
  {
108
132
  const CHNode *child = getNode(vt->getName());
@@ -114,8 +138,8 @@ void CHGraph::getVFnsFromVtbls(CallSite cs, const VTableSet &vtbls, VFunSet &vir
114
138
  feit = vfns.end(); fit != feit; ++fit)
115
139
  {
116
140
  const SVFFunction* callee = *fit;
117
- if (cs.arg_size() == callee->arg_size() ||
118
- (cs.isVarArg() && callee->isVarArg()))
141
+ if (cs->arg_size() == callee->arg_size() ||
142
+ (cs->isVarArg() && callee->isVarArg()))
119
143
  {
120
144
 
121
145
  // if argument types do not match