svf-tools 1.0.533 → 1.0.536

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 (198) hide show
  1. package/SVF-doxygen/html/html/AndersenStat_8cpp_source.html +1 -1
  2. package/SVF-doxygen/html/html/AndersenWaveDiff_8cpp_source.html +1 -3
  3. package/SVF-doxygen/html/html/Andersen_8cpp_source.html +2 -2
  4. package/SVF-doxygen/html/html/Andersen_8h_source.html +5 -6
  5. package/SVF-doxygen/html/html/CallGraphBuilder_8cpp_source.html +2 -2
  6. package/SVF-doxygen/html/html/DCHG_8cpp_source.html +10 -10
  7. package/SVF-doxygen/html/html/DCHG_8h_source.html +5 -5
  8. package/SVF-doxygen/html/html/DDAPass_8cpp_source.html +1 -1
  9. package/SVF-doxygen/html/html/DataFlowUtil_8h_source.html +2 -2
  10. package/SVF-doxygen/html/html/ExtAPI_8cpp_source.html +43 -36
  11. package/SVF-doxygen/html/html/ExtAPI_8h.html +2 -0
  12. package/SVF-doxygen/html/html/ExtAPI_8h_source.html +80 -69
  13. package/SVF-doxygen/html/html/FlowSensitive_8h_source.html +1 -1
  14. package/SVF-doxygen/html/html/ICFGBuilder_8cpp_source.html +1 -1
  15. package/SVF-doxygen/html/html/LLVMUtil_8cpp_source.html +1 -1
  16. package/SVF-doxygen/html/html/LockAnalysis_8cpp_source.html +1 -1
  17. package/SVF-doxygen/html/html/MHP_8cpp.html +1 -1
  18. package/SVF-doxygen/html/html/MHP_8cpp_source.html +4 -4
  19. package/SVF-doxygen/html/html/MHP_8h_source.html +1 -1
  20. package/SVF-doxygen/html/html/MTAAnnotator_8cpp_source.html +1 -1
  21. package/SVF-doxygen/html/html/MTAStat_8cpp_source.html +1 -1
  22. package/SVF-doxygen/html/html/MTA_8cpp_source.html +2 -2
  23. package/SVF-doxygen/html/html/MTA_8h_source.html +2 -2
  24. package/SVF-doxygen/html/html/PCG_8cpp_source.html +1 -1
  25. package/SVF-doxygen/html/html/SVF-FE_2BasicTypes_8h.html +80 -0
  26. package/SVF-doxygen/html/html/SVF-FE_2BasicTypes_8h_source.html +62 -22
  27. package/SVF-doxygen/html/html/SVFIRBuilder_8cpp_source.html +4 -10
  28. package/SVF-doxygen/html/html/SVFIRBuilder_8h.html +0 -1
  29. package/SVF-doxygen/html/html/SVFIRBuilder_8h_source.html +60 -62
  30. package/SVF-doxygen/html/html/SVFIR_8h_source.html +1 -1
  31. package/SVF-doxygen/html/html/SVFUtil_8cpp_source.html +3 -1
  32. package/SVF-doxygen/html/html/SVFUtil_8h_source.html +7 -7
  33. package/SVF-doxygen/html/html/SrcSnkDDA_8cpp_source.html +1 -1
  34. package/SVF-doxygen/html/html/SymbolTableBuilder_8cpp_source.html +1 -1
  35. package/SVF-doxygen/html/html/TCT_8cpp_source.html +1 -1
  36. package/SVF-doxygen/html/html/TCT_8h_source.html +1 -1
  37. package/SVF-doxygen/html/html/VersionedFlowSensitive_8cpp_source.html +3 -3
  38. package/SVF-doxygen/html/html/WPAFSSolver_8h_source.html +6 -6
  39. package/SVF-doxygen/html/html/WPAPass_8cpp_source.html +1 -1
  40. package/SVF-doxygen/html/html/WPASolver_8h_source.html +17 -18
  41. package/SVF-doxygen/html/html/annotated.html +2 -1
  42. package/SVF-doxygen/html/html/cfl_8cpp.html +1 -1
  43. package/SVF-doxygen/html/html/cfl_8cpp_source.html +1 -1
  44. package/SVF-doxygen/html/html/classSVF_1_1Andersen.html +12 -13
  45. package/SVF-doxygen/html/html/classSVF_1_1AndersenBase-members.html +175 -176
  46. package/SVF-doxygen/html/html/classSVF_1_1AndersenBase.html +5 -7
  47. package/SVF-doxygen/html/html/classSVF_1_1AndersenSCD.html +11 -10
  48. package/SVF-doxygen/html/html/classSVF_1_1AndersenSFR.html +5 -4
  49. package/SVF-doxygen/html/html/classSVF_1_1AndersenStat.html +1 -1
  50. package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiff-members.html +9 -9
  51. package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiff.html +160 -208
  52. package/SVF-doxygen/html/html/classSVF_1_1CallGraphBuilder.html +1 -1
  53. package/SVF-doxygen/html/html/classSVF_1_1DCHGraph.html +43 -43
  54. package/SVF-doxygen/html/html/classSVF_1_1DDAPass.html +1 -1
  55. package/SVF-doxygen/html/html/classSVF_1_1ExtAPI-members.html +19 -17
  56. package/SVF-doxygen/html/html/classSVF_1_1ExtAPI.html +230 -141
  57. package/SVF-doxygen/html/html/classSVF_1_1ExtAPI_1_1Operation-members.html +88 -0
  58. package/SVF-doxygen/html/html/classSVF_1_1ExtAPI_1_1Operation.html +344 -0
  59. package/SVF-doxygen/html/html/classSVF_1_1FSMPTA-members.html +240 -241
  60. package/SVF-doxygen/html/html/classSVF_1_1FSMPTA.html +1 -3
  61. package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive-members.html +230 -231
  62. package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive.html +5 -7
  63. package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat.html +1 -1
  64. package/SVF-doxygen/html/html/classSVF_1_1ForkJoinAnalysis.html +2 -2
  65. package/SVF-doxygen/html/html/classSVF_1_1ICFGBuilder.html +1 -1
  66. package/SVF-doxygen/html/html/classSVF_1_1LockAnalysis.html +1 -1
  67. package/SVF-doxygen/html/html/classSVF_1_1MHP.html +1 -1
  68. package/SVF-doxygen/html/html/classSVF_1_1MTA.html +3 -3
  69. package/SVF-doxygen/html/html/classSVF_1_1MTAAnnotator.html +1 -1
  70. package/SVF-doxygen/html/html/classSVF_1_1MTAStat.html +1 -1
  71. package/SVF-doxygen/html/html/classSVF_1_1PCG.html +1 -1
  72. package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder-members.html +63 -64
  73. package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder.html +306 -348
  74. package/SVF-doxygen/html/html/classSVF_1_1SrcSnkDDA.html +1 -1
  75. package/SVF-doxygen/html/html/classSVF_1_1Steensgaard-members.html +187 -188
  76. package/SVF-doxygen/html/html/classSVF_1_1Steensgaard.html +5 -7
  77. package/SVF-doxygen/html/html/classSVF_1_1SymbolTableBuilder.html +1 -1
  78. package/SVF-doxygen/html/html/classSVF_1_1ThreadCallGraphBuilder.html +1 -1
  79. package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis-members.html +179 -180
  80. package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis.html +1 -3
  81. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive-members.html +281 -282
  82. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive.html +6 -8
  83. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitiveStat.html +1 -1
  84. package/SVF-doxygen/html/html/classSVF_1_1WPAFSSolver-members.html +31 -32
  85. package/SVF-doxygen/html/html/classSVF_1_1WPAFSSolver.html +1 -3
  86. package/SVF-doxygen/html/html/classSVF_1_1WPAMinimumSolver-members.html +42 -43
  87. package/SVF-doxygen/html/html/classSVF_1_1WPAMinimumSolver.html +6 -8
  88. package/SVF-doxygen/html/html/classSVF_1_1WPAPass.html +1 -1
  89. package/SVF-doxygen/html/html/classSVF_1_1WPASCCSolver-members.html +38 -39
  90. package/SVF-doxygen/html/html/classSVF_1_1WPASCCSolver.html +8 -10
  91. package/SVF-doxygen/html/html/classSVF_1_1WPASolver-members.html +29 -30
  92. package/SVF-doxygen/html/html/classSVF_1_1WPASolver.html +51 -86
  93. package/SVF-doxygen/html/html/classes.html +90 -90
  94. package/SVF-doxygen/html/html/functions_a.html +8 -5
  95. package/SVF-doxygen/html/html/functions_c.html +19 -20
  96. package/SVF-doxygen/html/html/functions_e.html +4 -7
  97. package/SVF-doxygen/html/html/functions_eval_e.html +2 -5
  98. package/SVF-doxygen/html/html/functions_func_c.html +12 -13
  99. package/SVF-doxygen/html/html/functions_func_g.html +23 -11
  100. package/SVF-doxygen/html/html/functions_func_m.html +0 -1
  101. package/SVF-doxygen/html/html/functions_func_o.html +7 -4
  102. package/SVF-doxygen/html/html/functions_func_p.html +1 -1
  103. package/SVF-doxygen/html/html/functions_func_s.html +11 -5
  104. package/SVF-doxygen/html/html/functions_g.html +21 -9
  105. package/SVF-doxygen/html/html/functions_i.html +3 -3
  106. package/SVF-doxygen/html/html/functions_l.html +3 -3
  107. package/SVF-doxygen/html/html/functions_m.html +0 -1
  108. package/SVF-doxygen/html/html/functions_n.html +4 -4
  109. package/SVF-doxygen/html/html/functions_o.html +21 -19
  110. package/SVF-doxygen/html/html/functions_p.html +7 -9
  111. package/SVF-doxygen/html/html/functions_r.html +4 -2
  112. package/SVF-doxygen/html/html/functions_s.html +22 -18
  113. package/SVF-doxygen/html/html/functions_v.html +3 -3
  114. package/SVF-doxygen/html/html/functions_vars_a.html +3 -0
  115. package/SVF-doxygen/html/html/functions_vars_o.html +3 -0
  116. package/SVF-doxygen/html/html/functions_w.html +11 -11
  117. package/SVF-doxygen/html/html/hierarchy.html +99 -98
  118. package/SVF-doxygen/html/html/namespaceSVF.html +741 -21
  119. package/SVF-doxygen/html/html/namespaceSVF_1_1LLVMUtil.html +3 -3
  120. package/SVF-doxygen/html/html/namespaceSVF_1_1SVFUtil.html +3 -1
  121. package/SVF-doxygen/html/html/namespacemembers.html +33 -0
  122. package/SVF-doxygen/html/html/namespacemembers_b.html +5 -2
  123. package/SVF-doxygen/html/html/namespacemembers_c.html +6 -0
  124. package/SVF-doxygen/html/html/namespacemembers_d.html +19 -1
  125. package/SVF-doxygen/html/html/namespacemembers_g.html +15 -3
  126. package/SVF-doxygen/html/html/namespacemembers_i.html +16 -4
  127. package/SVF-doxygen/html/html/namespacemembers_m.html +21 -0
  128. package/SVF-doxygen/html/html/namespacemembers_n.html +3 -0
  129. package/SVF-doxygen/html/html/namespacemembers_p.html +3 -0
  130. package/SVF-doxygen/html/html/namespacemembers_s.html +3 -0
  131. package/SVF-doxygen/html/html/namespacemembers_type.html +33 -0
  132. package/SVF-doxygen/html/html/namespacemembers_type_b.html +3 -0
  133. package/SVF-doxygen/html/html/namespacemembers_type_c.html +6 -0
  134. package/SVF-doxygen/html/html/namespacemembers_type_d.html +18 -0
  135. package/SVF-doxygen/html/html/namespacemembers_type_g.html +12 -0
  136. package/SVF-doxygen/html/html/namespacemembers_type_i.html +12 -0
  137. package/SVF-doxygen/html/html/namespacemembers_type_m.html +21 -0
  138. package/SVF-doxygen/html/html/namespacemembers_type_n.html +3 -0
  139. package/SVF-doxygen/html/html/namespacemembers_type_p.html +3 -0
  140. package/SVF-doxygen/html/html/namespacemembers_type_s.html +3 -0
  141. package/SVF-doxygen/html/html/namespacemembers_type_v.html +3 -0
  142. package/SVF-doxygen/html/html/namespacemembers_type_w.html +3 -0
  143. package/SVF-doxygen/html/html/namespacemembers_v.html +3 -0
  144. package/SVF-doxygen/html/html/namespacemembers_w.html +3 -0
  145. package/SVF-doxygen/html/html/search/all_1.js +12 -0
  146. package/SVF-doxygen/html/html/search/all_10.js +8 -7
  147. package/SVF-doxygen/html/html/search/all_11.js +2 -2
  148. package/SVF-doxygen/html/html/search/all_12.js +12 -9
  149. package/SVF-doxygen/html/html/search/all_13.js +3 -3
  150. package/SVF-doxygen/html/html/search/all_14.js +1 -1
  151. package/SVF-doxygen/html/html/search/all_15.js +4 -3
  152. package/SVF-doxygen/html/html/search/all_16.js +2 -1
  153. package/SVF-doxygen/html/html/search/all_2.js +1 -0
  154. package/SVF-doxygen/html/html/search/all_3.js +4 -2
  155. package/SVF-doxygen/html/html/search/all_4.js +6 -0
  156. package/SVF-doxygen/html/html/search/all_5.js +1 -2
  157. package/SVF-doxygen/html/html/search/all_7.js +9 -1
  158. package/SVF-doxygen/html/html/search/all_9.js +5 -1
  159. package/SVF-doxygen/html/html/search/all_c.js +2 -2
  160. package/SVF-doxygen/html/html/search/all_d.js +8 -1
  161. package/SVF-doxygen/html/html/search/all_e.js +2 -1
  162. package/SVF-doxygen/html/html/search/all_f.js +3 -2
  163. package/SVF-doxygen/html/html/search/classes_c.js +1 -0
  164. package/SVF-doxygen/html/html/search/enumvalues_4.js +1 -2
  165. package/SVF-doxygen/html/html/search/functions_11.js +2 -0
  166. package/SVF-doxygen/html/html/search/functions_2.js +1 -1
  167. package/SVF-doxygen/html/html/search/functions_6.js +5 -1
  168. package/SVF-doxygen/html/html/search/functions_c.js +1 -1
  169. package/SVF-doxygen/html/html/search/functions_e.js +1 -0
  170. package/SVF-doxygen/html/html/search/functions_f.js +1 -1
  171. package/SVF-doxygen/html/html/search/typedefs_0.js +11 -0
  172. package/SVF-doxygen/html/html/search/typedefs_1.js +1 -0
  173. package/SVF-doxygen/html/html/search/typedefs_10.js +1 -0
  174. package/SVF-doxygen/html/html/search/typedefs_13.js +1 -0
  175. package/SVF-doxygen/html/html/search/typedefs_14.js +1 -0
  176. package/SVF-doxygen/html/html/search/typedefs_2.js +2 -0
  177. package/SVF-doxygen/html/html/search/typedefs_3.js +6 -0
  178. package/SVF-doxygen/html/html/search/typedefs_6.js +4 -0
  179. package/SVF-doxygen/html/html/search/typedefs_7.js +4 -0
  180. package/SVF-doxygen/html/html/search/typedefs_b.js +7 -0
  181. package/SVF-doxygen/html/html/search/typedefs_c.js +1 -0
  182. package/SVF-doxygen/html/html/search/typedefs_e.js +1 -0
  183. package/SVF-doxygen/html/html/search/variables_1.js +1 -0
  184. package/SVF-doxygen/html/html/search/variables_13.js +1 -1
  185. package/SVF-doxygen/html/html/search/variables_14.js +1 -1
  186. package/SVF-doxygen/html/html/search/variables_f.js +1 -0
  187. package/SVF-doxygen/html/html/svf-ex_8cpp.html +1 -1
  188. package/SVF-doxygen/html/html/svf-ex_8cpp_source.html +1 -1
  189. package/include/SVF-FE/BasicTypes.h +43 -0
  190. package/include/SVF-FE/SVFIRBuilder.h +0 -2
  191. package/include/Util/ExtAPI.h +49 -5
  192. package/include/Util/ExtAPI.json +1312 -320
  193. package/include/WPA/Andersen.h +1 -4
  194. package/include/WPA/WPASolver.h +1 -3
  195. package/lib/SVF-FE/SVFIRBuilder.cpp +219 -238
  196. package/lib/Util/ExtAPI.cpp +109 -0
  197. package/lib/WPA/AndersenWaveDiff.cpp +0 -14
  198. package/package.json +1 -1
@@ -344,7 +344,7 @@ protected:
344
344
  //@}
345
345
  /// Collapse a field object into its base for field insensitive anlaysis
346
346
  //@{
347
- void collapsePWCNode(NodeID nodeId);
347
+ virtual void collapsePWCNode(NodeID nodeId);
348
348
  void collapseFields();
349
349
  bool collapseNodePts(NodeID nodeId);
350
350
  bool collapseField(NodeID nodeId);
@@ -440,9 +440,6 @@ public:
440
440
  virtual void postProcessNode(NodeID nodeId);
441
441
  virtual bool handleLoad(NodeID id, const ConstraintEdge* load);
442
442
  virtual bool handleStore(NodeID id, const ConstraintEdge* store);
443
-
444
- protected:
445
- virtual void mergeNodeToRep(NodeID nodeId,NodeID newRepId);
446
443
  };
447
444
 
448
445
  } // End namespace SVF
@@ -114,7 +114,6 @@ protected:
114
114
  while (!isWorklistEmpty())
115
115
  {
116
116
  NodeID nodeId = popFromWorklist();
117
- collapsePWCNode(nodeId);
118
117
  // Keep solving until workList is empty.
119
118
  processNode(nodeId);
120
119
  collapseFields();
@@ -126,8 +125,7 @@ protected:
126
125
  /// Process each node on the graph, to be implemented in the child class
127
126
  virtual inline void processNode(NodeID) {}
128
127
  /// collapse positive weight cycles of a graph
129
- virtual void collapsePWCNode(NodeID) {}
130
- virtual void collapseFields() {};
128
+ virtual void collapseFields() {}
131
129
  /// dump statistics
132
130
  /// Propagation for the solving, to be implemented in the child class
133
131
  virtual void propagate(GNODE* v)
@@ -1123,76 +1123,20 @@ void SVFIRBuilder::addComplexConsForExt(Value *D, Value *S, const Value* szValue
1123
1123
  }
1124
1124
  }
1125
1125
 
1126
-
1127
- /*!
1128
- * Get numeric index of the argument in external function
1129
- */
1130
- u32_t SVFIRBuilder::getArgPos(std::string s)
1131
- {
1132
- if(s[0] != 'A')
1133
- assert(false && "the argument of extern function in ExtAPI.json should start with 'A' !");
1134
- u32_t i = 1;
1135
- u32_t start = i;
1136
- while(i < s.size() && isdigit(s[i]))
1137
- i++;
1138
- std::string digitStr = s.substr(start, i-start);
1139
- u32_t argNum = atoi(digitStr.c_str());
1140
- return argNum;
1141
- }
1142
-
1143
-
1144
1126
  /*!
1145
1127
  * Get NodeId of s
1146
1128
  */
1147
1129
  NodeID SVFIRBuilder::parseNode(std::string s, CallSite cs, const Instruction *inst)
1148
1130
  {
1149
- Value* V = nullptr;
1150
- NodeID res = -1;
1151
- size_t argNumPre = -1;
1152
- bool flag = true;
1153
- for (size_t i = 0; i < s.size();)
1154
- {
1155
- if(!flag)
1156
- assert(false && "The operand format of function operation is illegal!");
1157
- // 'A' represents an argument
1158
- if (s[i] == 'A')
1159
- {
1160
- i = i + 1;
1161
- size_t start = i;
1162
- while(i < s.size() && isdigit(s[i]))
1163
- i++;
1164
- std::string digitStr = s.substr(start, i-start);
1165
- argNumPre = atoi(digitStr.c_str());
1166
- V = cs.getArgument(argNumPre);
1167
- if(i >= s.size())
1168
- res = getValueNode(V);
1169
- }
1170
- // 'R' represents a reference
1171
- else if(s[i] == 'R')
1172
- {
1173
- i = i + 1;
1174
- if(i >= s.size())
1175
- res = getValueNode(V);
1176
- }
1177
- // 'L' represents a return value
1178
- else if(s[i] == 'L')
1179
- {
1180
- res = getValueNode(inst);
1181
- if(i++ != 0)
1182
- flag = false;
1183
- }
1184
- // 'V' represents a dummy node
1185
- else if(s[i] == 'V')
1186
- {
1187
- res = pag->addDummyValNode();
1188
- if(i++ != 0)
1189
- flag = false;
1190
- }
1191
- else
1192
- flag = false;
1193
-
1194
- }
1195
- return res;
1131
+ int nodeIDType = ExtAPI::getExtAPI()->getNodeIDType(s);
1132
+ if (nodeIDType >=0)
1133
+ return getValueNode(cs.getArgument(nodeIDType));
1134
+ if (nodeIDType == -1)
1135
+ return getValueNode(inst);
1136
+ if (nodeIDType == -2)
1137
+ return pag->addDummyValNode();
1138
+ assert(false && "The operand format of function operation is illegal!");
1139
+ return -1;
1196
1140
  }
1197
1141
 
1198
1142
  /*!
@@ -1238,206 +1182,243 @@ void SVFIRBuilder::handleExtCall(CallSite cs, const SVFFunction *callee)
1238
1182
  if (isExtCall(callee))
1239
1183
  {
1240
1184
  std::string funName = ExtAPI::getExtAPI()->get_name(callee);
1241
- cJSON *item = ExtAPI::getExtAPI()->get_FunJson(funName);
1242
- // The external function exists in ExtAPI.json
1243
- if (item != nullptr)
1185
+ std::vector<std::vector<ExtAPI::Operation *>> allOperations = ExtAPI::getExtAPI()->getAllOperations(funName);
1186
+ if (allOperations.size() == 0)
1187
+ {
1188
+ std::string str;
1189
+ raw_string_ostream rawstr(str);
1190
+ rawstr << "function " << callee->getName() << " not in the external function summary ExtAPI.json file";
1191
+ writeWrnMsg(rawstr.str());
1192
+ }
1193
+ else
1244
1194
  {
1245
- cJSON *obj = item->child;
1246
- // Get the first operation of the function
1247
- obj = obj -> next -> next;
1248
- while (obj)
1195
+ for (auto operations: allOperations)
1249
1196
  {
1250
- std::string op = obj->string;
1251
- std::vector<std::string> args;
1252
- if (obj->type == cJSON_Array)
1197
+ NodeID tempNode = -1;
1198
+ // Record the previous operation
1199
+ ExtAPI::Operation *preOp = nullptr;
1200
+ for (auto op : operations)
1253
1201
  {
1254
- // Get the first argument of the operation
1255
- cJSON *value = obj->child;
1256
- args = ExtAPI::getExtAPI()->get_opArgs(value);
1257
- obj = obj->next;
1258
- }
1259
- else
1260
- {
1261
- assert(false && "The function operation format is illegal!");
1262
- }
1263
-
1264
- ExtAPI::extf_t opName = ExtAPI::getExtAPI()->get_opName(op);
1202
+ ExtAPI::extf_t opName = ExtAPI::getExtAPI()->get_opName(op->getOperation());
1203
+ std::vector<std::string> args = op->getArgs();
1265
1204
 
1266
- switch (opName)
1267
- {
1268
- case ExtAPI::EXT_ADDR:
1269
- {
1270
- if (args.size() == 1)
1205
+ switch (opName)
1206
+ {
1207
+ case ExtAPI::EXT_ADDR:
1271
1208
  {
1272
- if (!SVFUtil::isa<PointerType>(inst->getType()))
1273
- break;
1274
- // e.g. void *realloc(void *ptr, size_t size)
1275
- // if ptr is null then we will treat it as a malloc
1276
- // if ptr is not null, then we assume a new data memory will be attached to
1277
- // the tail of old allocated memory block.
1278
- if (SVFUtil::isa<ConstantPointerNull>(cs.getArgument(0)))
1209
+ if (args.size() == 1)
1279
1210
  {
1280
- NodeID val = parseNode(args[0], cs, inst);
1281
- NodeID obj = getObjectNode(inst);
1282
- addAddrEdge(obj, val);
1211
+ if (!SVFUtil::isa<PointerType>(inst->getType()))
1212
+ break;
1213
+ // e.g. void *realloc(void *ptr, size_t size)
1214
+ // if ptr is null then we will treat it as a malloc
1215
+ // if ptr is not null, then we assume a new data memory will be attached to
1216
+ // the tail of old allocated memory block.
1217
+ if (SVFUtil::isa<ConstantPointerNull>(cs.getArgument(0)))
1218
+ {
1219
+ NodeID val = parseNode(args[0], cs, inst);
1220
+ NodeID obj = getObjectNode(inst);
1221
+ if (val && obj)
1222
+ addAddrEdge(obj, val);
1223
+ }
1283
1224
  }
1225
+ break;
1284
1226
  }
1285
- break;
1286
- }
1287
- case ExtAPI::EXT_COPY:
1288
- {
1289
- NodeID vnS = parseNode(args[0], cs, inst);
1290
- NodeID vnD = parseNode(args[1], cs, inst);
1291
- if (vnS && vnD)
1292
- addCopyEdge(vnS, vnD);
1293
- break;
1294
- }
1295
- case ExtAPI::EXT_LOAD:
1296
- {
1297
- NodeID vnS = parseNode(args[0], cs, inst);
1298
- NodeID vnD = parseNode(args[1], cs, inst);
1299
- if (vnS && vnD)
1300
- addLoadEdge(vnS, vnD);
1301
- break;
1302
- }
1303
- case ExtAPI::EXT_STORE:
1304
- {
1305
- NodeID vnS = parseNode(args[0], cs, inst);
1306
- NodeID vnD = parseNode(args[1], cs, inst);
1307
- if (vnS && vnD)
1308
- addStoreEdge(vnS, vnD);
1309
- break;
1310
- }
1311
- case ExtAPI::EXT_LOADSTORE:
1312
- {
1313
- NodeID vnS = parseNode(args[0], cs, inst);
1314
- NodeID vnV = parseNode(args[1], cs, inst);
1315
- NodeID vnD = parseNode(args[2], cs, inst);
1316
- if (vnD && vnV && vnS)
1227
+ case ExtAPI::EXT_COPY:
1317
1228
  {
1318
- addLoadEdge(vnS, vnV);
1319
- addStoreEdge(vnV, vnD);
1229
+ if(operations.size() == 1)
1230
+ {
1231
+ NodeID vnS = parseNode(args[0], cs, inst);
1232
+ NodeID vnD = parseNode(args[1], cs, inst);
1233
+ if (vnS && vnD)
1234
+ addCopyEdge(vnS, vnD);
1235
+ }
1236
+ break;
1320
1237
  }
1321
- break;
1322
- }
1323
- case ExtAPI::EXT_COPY_N:
1324
- {
1325
- // void *memset(void *str, int c, size_t n)
1326
- // this is for memset(void *str, int c, size_t n)
1327
- // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
1328
- u32_t arg_posA = getArgPos(args[0]);
1329
- u32_t arg_posB = getArgPos(args[1]);
1330
- u32_t arg_posC = getArgPos(args[2]);
1331
- std::vector<LocationSet> dstFields;
1332
- const Type *dtype = getBaseTypeAndFlattenedFields(cs.getArgument(arg_posA), dstFields, cs.getArgument(arg_posC));
1333
- u32_t sz = dstFields.size();
1334
- // For each field (i), add store edge *(arg0 + i) = arg1
1335
- for (u32_t index = 0; index < sz; index++)
1238
+ case ExtAPI::EXT_LOAD:
1336
1239
  {
1337
- const Type *dElementType = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(dtype, dstFields[index].accumulateConstantFieldIdx());
1338
- NodeID dField = getGepValVar(cs.getArgument(arg_posA), dstFields[index], dElementType);
1339
- addStoreEdge(pag->getValueNode(cs.getArgument(arg_posB)), dField);
1240
+ NodeID vnS = parseNode(args[0], cs, inst);
1241
+ NodeID vnD = parseNode(args[1], cs, inst);
1242
+ if (vnS && vnD)
1243
+ {
1244
+ addLoadEdge(vnS, vnD);
1245
+ if (operations.size() > 1 && !preOp)
1246
+ {
1247
+ preOp = op;
1248
+ tempNode = vnD;
1249
+ }
1250
+ }
1251
+ break;
1340
1252
  }
1341
- if (SVFUtil::isa<PointerType>(inst->getType()))
1342
- addCopyEdge(getValueNode(cs.getArgument(arg_posA)), getValueNode(inst));
1343
- break;
1344
- }
1345
- case ExtAPI::EXT_COPY_MN:
1346
- {
1347
- u32_t arg_posA = getArgPos(args[0]);
1348
- u32_t arg_posB = getArgPos(args[1]);
1349
- if (args.size() >= 3)
1253
+ case ExtAPI::EXT_STORE:
1350
1254
  {
1351
- u32_t arg_posC = getArgPos(args[2]);
1352
- addComplexConsForExt(cs.getArgument(arg_posA), cs.getArgument(arg_posB), cs.getArgument(arg_posC));
1255
+ if (operations.size() == 1)
1256
+ {
1257
+ NodeID vnS = parseNode(args[0], cs, inst);
1258
+ NodeID vnD = parseNode(args[1], cs, inst);
1259
+ if (vnS && vnD)
1260
+ addStoreEdge(vnS, vnD);
1261
+ }
1262
+ else
1263
+ {
1264
+ if(preOp && preOp->getArgs()[1] == op->getArgs()[0])
1265
+ {
1266
+ NodeID vnD = parseNode(args[1], cs, inst);
1267
+ addStoreEdge(tempNode, vnD);
1268
+ }
1269
+ }
1270
+ break;
1353
1271
  }
1354
- else
1355
- addComplexConsForExt(cs.getArgument(arg_posA), cs.getArgument(arg_posB), nullptr);
1356
- break;
1357
- }
1358
- case ExtAPI::EXT_FUNPTR:
1359
- {
1360
- /// handling external function e.g., void *dlsym(void *handle, const char *funname);
1361
- u32_t arg_posA = getArgPos(args[0]);
1362
- const Value *src = cs.getArgument(arg_posA);
1363
- if (const GetElementPtrInst *gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
1364
- src = stripConstantCasts(gep->getPointerOperand());
1365
- if (const GlobalVariable *glob = SVFUtil::dyn_cast<GlobalVariable>(src))
1272
+ case ExtAPI::EXT_GEP:
1366
1273
  {
1367
- if (const ConstantDataArray *constarray = SVFUtil::dyn_cast<ConstantDataArray>(glob->getInitializer()))
1274
+ // "compound"
1275
+ if(operations.size() > 1)
1276
+ {
1277
+ // multiple GEP operations
1278
+ if (!preOp)
1279
+ {
1280
+ NodeID vnS = parseNode(args[0], cs, inst);
1281
+ NodeID vnD = parseNode(args[1], cs, inst);
1282
+ u32_t offset = stoul(args[2]);
1283
+ if (vnD && vnS)
1284
+ {
1285
+ LocationSet ls(offset);
1286
+ addNormalGepEdge(vnS, vnD, ls);
1287
+ tempNode = vnD;
1288
+ }
1289
+ }
1290
+ else
1291
+ {
1292
+ if(op->getArgs()[0] == preOp->getArgs()[1])
1293
+ {
1294
+ NodeID vnD = parseNode(args[1], cs, inst);
1295
+ u32_t offset = stoul(args[2]);
1296
+ if (vnD)
1297
+ {
1298
+ LocationSet ls(offset);
1299
+ addNormalGepEdge(tempNode, vnD, ls);
1300
+ }
1301
+ }
1302
+ }
1303
+
1304
+ if (operations.back() == op)
1305
+ preOp = nullptr;
1306
+ preOp = op;
1307
+ }
1308
+ // General GEP operation
1309
+ else
1368
1310
  {
1369
- if (const SVFFunction *fun = getProgFunction(svfMod, constarray->getAsCString().str()))
1311
+ NodeID vnS = parseNode(args[0], cs, inst);
1312
+ NodeID vnD = parseNode(args[1], cs, inst);
1313
+ u32_t offset = stoul(args[2]);
1314
+ if (vnD && vnS)
1370
1315
  {
1371
- NodeID srcNode = getValueNode(fun->getLLVMFun());
1372
- addCopyEdge(srcNode, getValueNode(inst));
1316
+ LocationSet ls(offset);
1317
+ addNormalGepEdge(vnS, vnD, ls);
1373
1318
  }
1374
1319
  }
1320
+ break;
1375
1321
  }
1376
- break;
1377
- }
1378
- case ExtAPI::EXT_COMPLEX:
1379
- {
1380
- assert(cs.arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
1381
- Value *argA = cs.getArgument(getArgPos(args[0]));
1382
- Value *argB = cs.getArgument(getArgPos(args[1]));
1383
-
1384
- // We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
1385
- // Now we calculate the offset from base to vArg3
1386
- NodeID vnB = pag->getValueNode(argB);
1387
- s32_t offset = getLocationSetFromBaseNode(vnB).accumulateConstantFieldIdx();
1388
-
1389
- // We get all flattened fields of base
1390
- vector<LocationSet> fields;
1391
- const Type *type = getBaseTypeAndFlattenedFields(argB, fields, nullptr);
1392
-
1393
- // We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
1394
- // Note that arg0 is aligned with "offset".
1395
- for (s32_t i = offset + 1; i <= offset + 3; ++i)
1322
+ case ExtAPI::EXT_COPY_N:
1396
1323
  {
1397
- if ((u32_t)i >= fields.size())
1398
- break;
1399
- const Type *elementType = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(type, fields[i].accumulateConstantFieldIdx());
1400
- NodeID vnD = getGepValVar(argB, fields[i], elementType);
1401
- NodeID vnS = getValueNode(argA);
1402
- if (vnD && vnS)
1403
- addStoreEdge(vnS, vnD);
1324
+ // void *memset(void *str, int c, size_t n)
1325
+ // this is for memset(void *str, int c, size_t n)
1326
+ // which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
1327
+ u32_t arg_posA = ExtAPI::getExtAPI()->getArgPos(args[0]);
1328
+ u32_t arg_posB = ExtAPI::getExtAPI()->getArgPos(args[1]);
1329
+ u32_t arg_posC = ExtAPI::getExtAPI()->getArgPos(args[2]);
1330
+ std::vector<LocationSet> dstFields;
1331
+ const Type *dtype = getBaseTypeAndFlattenedFields(cs.getArgument(arg_posA), dstFields, cs.getArgument(arg_posC));
1332
+ u32_t sz = dstFields.size();
1333
+ // For each field (i), add store edge *(arg0 + i) = arg1
1334
+ for (u32_t index = 0; index < sz; index++)
1335
+ {
1336
+ const Type *dElementType = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(dtype, dstFields[index].accumulateConstantFieldIdx());
1337
+ NodeID dField = getGepValVar(cs.getArgument(arg_posA), dstFields[index], dElementType);
1338
+ addStoreEdge(pag->getValueNode(cs.getArgument(arg_posB)), dField);
1339
+ }
1340
+ if (SVFUtil::isa<PointerType>(inst->getType()))
1341
+ addCopyEdge(getValueNode(cs.getArgument(arg_posA)), getValueNode(inst));
1342
+ break;
1404
1343
  }
1405
- break;
1406
- }
1407
- case ExtAPI::EXT_GEPGEP:
1408
- {
1409
- NodeID vnS = parseNode(args[0], cs, inst);
1410
- u32_t offset1 = stoul(args[1]);
1411
- NodeID vnV = parseNode(args[2], cs, inst);
1412
- u32_t offset2 = stoul(args[3]);
1413
- NodeID vnD = parseNode(args[4], cs, inst);
1414
- if (vnD && vnV && vnS)
1344
+ case ExtAPI::EXT_COPY_MN:
1415
1345
  {
1416
- LocationSet l1(offset1);
1417
- LocationSet l2(offset2);
1418
- addNormalGepEdge(vnS, vnV, l1);
1419
- addNormalGepEdge(vnV, vnD, l2);
1346
+ u32_t arg_posA = ExtAPI::getExtAPI()->getArgPos(args[0]);
1347
+ u32_t arg_posB = ExtAPI::getExtAPI()->getArgPos(args[1]);
1348
+ if (args.size() >= 3)
1349
+ {
1350
+ u32_t arg_posC = ExtAPI::getExtAPI()->getArgPos(args[2]);
1351
+ addComplexConsForExt(cs.getArgument(arg_posA), cs.getArgument(arg_posB), cs.getArgument(arg_posC));
1352
+ }
1353
+ else
1354
+ addComplexConsForExt(cs.getArgument(arg_posA), cs.getArgument(arg_posB), nullptr);
1355
+ break;
1356
+ }
1357
+ case ExtAPI::EXT_FUNPTR:
1358
+ {
1359
+ /// handling external function e.g., void *dlsym(void *handle, const char *funname);
1360
+ u32_t arg_posA = ExtAPI::getExtAPI()->getArgPos(args[0]);
1361
+ const Value *src = cs.getArgument(arg_posA);
1362
+ if (const GetElementPtrInst *gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
1363
+ src = stripConstantCasts(gep->getPointerOperand());
1364
+ if (const GlobalVariable *glob = SVFUtil::dyn_cast<GlobalVariable>(src))
1365
+ {
1366
+ if (const ConstantDataArray *constarray = SVFUtil::dyn_cast<ConstantDataArray>(glob->getInitializer()))
1367
+ {
1368
+ if (const SVFFunction *fun = getProgFunction(svfMod, constarray->getAsCString().str()))
1369
+ {
1370
+ NodeID srcNode = getValueNode(fun->getLLVMFun());
1371
+ addCopyEdge(srcNode, getValueNode(inst));
1372
+ }
1373
+ }
1374
+ }
1375
+ break;
1376
+ }
1377
+ case ExtAPI::EXT_COMPLEX:
1378
+ {
1379
+ assert(cs.arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");
1380
+
1381
+ Value *argA = cs.getArgument(ExtAPI::getExtAPI()->getArgPos(args[0]));
1382
+ Value *argB = cs.getArgument(ExtAPI::getExtAPI()->getArgPos(args[1]));
1383
+
1384
+ // We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
1385
+ // Now we calculate the offset from base to vArg3
1386
+ NodeID vnB = pag->getValueNode(argB);
1387
+ s32_t offset = getLocationSetFromBaseNode(vnB).accumulateConstantFieldIdx();
1388
+
1389
+ // We get all flattened fields of base
1390
+ vector<LocationSet> fields;
1391
+ const Type *type = getBaseTypeAndFlattenedFields(argB, fields, nullptr);
1392
+
1393
+ // We summarize the side effects: arg3->parent = arg1, arg3->left = arg1, arg3->right = arg1
1394
+ // Note that arg0 is aligned with "offset".
1395
+ for (s32_t i = offset + 1; i <= offset + 3; ++i)
1396
+ {
1397
+ if ((u32_t)i >= fields.size())
1398
+ break;
1399
+ const Type *elementType = SymbolTableInfo::SymbolInfo()->getFlatternedElemType(type, fields[i].accumulateConstantFieldIdx());
1400
+ NodeID vnD = getGepValVar(argB, fields[i], elementType);
1401
+ NodeID vnS = getValueNode(argA);
1402
+ if (vnD && vnS)
1403
+ addStoreEdge(vnS, vnD);
1404
+ }
1405
+ break;
1406
+ }
1407
+ // default
1408
+ // illegal function operation of external function
1409
+ case ExtAPI::EXT_OTHER:
1410
+ default:
1411
+ {
1412
+ assert(false && "new type of SVFStmt for external calls?");
1413
+ }
1420
1414
  }
1421
- break;
1422
- }
1423
- // default
1424
- // illegal function operation of external function
1425
- case ExtAPI::EXT_OTHER:
1426
- default:
1427
- {
1428
- assert(false && "new type of SVFStmt for external calls?");
1429
- }
1430
1415
  }
1416
+ for(u32_t it = 0; it != operations.size(); ++it)
1417
+ delete operations[it];
1418
+ operations.clear();
1431
1419
  }
1432
1420
  }
1433
- // // The external function doesn't exist in ExtAPI.json
1434
- else
1435
- {
1436
- std::string str;
1437
- raw_string_ostream rawstr(str);
1438
- rawstr << "function " << callee->getName() << " not in the external function summary ExtAPI.json file";
1439
- writeWrnMsg(rawstr.str());
1440
- }
1421
+ allOperations.clear();
1441
1422
  }
1442
1423
 
1443
1424
  /// create inter-procedural SVFIR edges for thread forks
@@ -224,6 +224,48 @@ const std::string& ExtAPI::extType_toString(extType type)
224
224
  return it->first;
225
225
  }
226
226
 
227
+ // Get numeric index of the argument in external function
228
+ u32_t ExtAPI::getArgPos(std::string s)
229
+ {
230
+ if(s[0] != 'A')
231
+ assert(false && "the argument of extern function in ExtAPI.json should start with 'A' !");
232
+ u32_t i = 1;
233
+ u32_t start = i;
234
+ while(i < s.size() && isdigit(s[i]))
235
+ i++;
236
+ std::string digitStr = s.substr(start, i-start);
237
+ u32_t argNum = atoi(digitStr.c_str());
238
+ return argNum;
239
+ }
240
+
241
+ // return value >= 0 is an argument node
242
+ // return value = -1 is an inst node
243
+ // return value = -2 is a Dummy node
244
+ // return value = -2 is an illegal operand format
245
+ int ExtAPI::getNodeIDType(std::string s)
246
+ {
247
+ size_t argPos = -1;
248
+ // 'A' represents an argument
249
+ if (s.size() == 0)
250
+ return -3;
251
+ if (s[0] == 'A')
252
+ {
253
+ size_t start = 1;
254
+ size_t end = 1;
255
+ while(end < s.size() && isdigit(s[end]))
256
+ end++;
257
+ std::string digitStr = s.substr(start, end - start);
258
+ argPos = atoi(digitStr.c_str());
259
+ return argPos;
260
+ }
261
+ if(s[0] == 'L')
262
+ return -1;
263
+ if(s[0] == 'D')
264
+ return -2;
265
+
266
+ return -3;
267
+ }
268
+
227
269
  // Get external function name, e.g "memcpy"
228
270
  std::string ExtAPI::get_name(const SVFFunction *F)
229
271
  {
@@ -245,6 +287,73 @@ cJSON *ExtAPI::get_FunJson(const std::string &funName)
245
287
  return cJSON_GetObjectItemCaseSensitive(root, funName.c_str());
246
288
  }
247
289
 
290
+ // Get all operations of an extern function
291
+ std::vector<std::vector<ExtAPI::Operation *>> ExtAPI::getAllOperations(std::string funName)
292
+ {
293
+ std::vector<std::vector<ExtAPI::Operation *>> allOperations;
294
+ cJSON *item = get_FunJson(funName);
295
+ if (item != nullptr)
296
+ {
297
+ cJSON *obj = item->child;
298
+ // Get the first operation of the function
299
+ obj = obj -> next -> next;
300
+ std::vector<ExtAPI::Operation *> operations;
301
+ while (obj)
302
+ {
303
+ std::string operationName;
304
+ std::vector<std::string> arguments;
305
+ Operation operation;
306
+ // All operations in "compound" are related to each other.
307
+ // For example, the first parameter of the second operation
308
+ // depends on the second parameter of the first operation.
309
+ // Therefore, all operations in "compound" need to be processed uniformly
310
+ if (strstr(obj->string, "compound") != NULL)
311
+ {
312
+ if (obj->type == cJSON_Object)
313
+ {
314
+ cJSON *value = obj->child;
315
+ while (value)
316
+ {
317
+ operationName = value -> string;
318
+ if (value->type == cJSON_Object)
319
+ {
320
+ cJSON *edge = value->child;
321
+ arguments = ExtAPI::getExtAPI()->get_opArgs(edge);
322
+ }
323
+ else
324
+ {
325
+ if (value->type == cJSON_String)
326
+ arguments.push_back(value->valuestring);
327
+ else
328
+ assert(false && "The function operation format is illegal!");
329
+ }
330
+ operations.push_back(new ExtAPI::Operation(operationName, arguments));
331
+ arguments.clear();
332
+ value = value->next;
333
+ }
334
+ }
335
+ }
336
+ // General operation(Independent operation, the operation does not need to dependent other operations' arguments)
337
+ else
338
+ {
339
+ if (obj->type == cJSON_Object || obj->type == cJSON_Array)
340
+ {
341
+ operationName = obj -> string;
342
+ cJSON *edge = obj->child;
343
+ arguments = ExtAPI::getExtAPI()->get_opArgs(edge);
344
+ operations.push_back(new ExtAPI::Operation(operationName, arguments));
345
+ arguments.clear();
346
+ }
347
+ }
348
+ allOperations.push_back(operations);
349
+ operations.clear();
350
+
351
+ obj = obj -> next;
352
+ }
353
+ }
354
+ return allOperations;
355
+ }
356
+
248
357
  // Get arguments of the operation, e.g. ["A1R", "A0", "A2"]
249
358
  std::vector<std::string> ExtAPI::get_opArgs(const cJSON *value)
250
359
  {