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.
- package/SVF-doxygen/html/html/AndersenStat_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/AndersenWaveDiff_8cpp_source.html +1 -3
- package/SVF-doxygen/html/html/Andersen_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/Andersen_8h_source.html +5 -6
- package/SVF-doxygen/html/html/CallGraphBuilder_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/DCHG_8cpp_source.html +10 -10
- package/SVF-doxygen/html/html/DCHG_8h_source.html +5 -5
- package/SVF-doxygen/html/html/DDAPass_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/DataFlowUtil_8h_source.html +2 -2
- package/SVF-doxygen/html/html/ExtAPI_8cpp_source.html +43 -36
- package/SVF-doxygen/html/html/ExtAPI_8h.html +2 -0
- package/SVF-doxygen/html/html/ExtAPI_8h_source.html +80 -69
- package/SVF-doxygen/html/html/FlowSensitive_8h_source.html +1 -1
- package/SVF-doxygen/html/html/ICFGBuilder_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/LLVMUtil_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/LockAnalysis_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/MHP_8cpp.html +1 -1
- package/SVF-doxygen/html/html/MHP_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/MHP_8h_source.html +1 -1
- package/SVF-doxygen/html/html/MTAAnnotator_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/MTAStat_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/MTA_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/MTA_8h_source.html +2 -2
- package/SVF-doxygen/html/html/PCG_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/SVF-FE_2BasicTypes_8h.html +80 -0
- package/SVF-doxygen/html/html/SVF-FE_2BasicTypes_8h_source.html +62 -22
- package/SVF-doxygen/html/html/SVFIRBuilder_8cpp_source.html +4 -10
- package/SVF-doxygen/html/html/SVFIRBuilder_8h.html +0 -1
- package/SVF-doxygen/html/html/SVFIRBuilder_8h_source.html +60 -62
- package/SVF-doxygen/html/html/SVFIR_8h_source.html +1 -1
- package/SVF-doxygen/html/html/SVFUtil_8cpp_source.html +3 -1
- package/SVF-doxygen/html/html/SVFUtil_8h_source.html +7 -7
- package/SVF-doxygen/html/html/SrcSnkDDA_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/SymbolTableBuilder_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/TCT_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/TCT_8h_source.html +1 -1
- package/SVF-doxygen/html/html/VersionedFlowSensitive_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/WPAFSSolver_8h_source.html +6 -6
- package/SVF-doxygen/html/html/WPAPass_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/WPASolver_8h_source.html +17 -18
- package/SVF-doxygen/html/html/annotated.html +2 -1
- package/SVF-doxygen/html/html/cfl_8cpp.html +1 -1
- package/SVF-doxygen/html/html/cfl_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1Andersen.html +12 -13
- package/SVF-doxygen/html/html/classSVF_1_1AndersenBase-members.html +175 -176
- package/SVF-doxygen/html/html/classSVF_1_1AndersenBase.html +5 -7
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSCD.html +11 -10
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSFR.html +5 -4
- package/SVF-doxygen/html/html/classSVF_1_1AndersenStat.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiff-members.html +9 -9
- package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiff.html +160 -208
- package/SVF-doxygen/html/html/classSVF_1_1CallGraphBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1DCHGraph.html +43 -43
- package/SVF-doxygen/html/html/classSVF_1_1DDAPass.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ExtAPI-members.html +19 -17
- package/SVF-doxygen/html/html/classSVF_1_1ExtAPI.html +230 -141
- package/SVF-doxygen/html/html/classSVF_1_1ExtAPI_1_1Operation-members.html +88 -0
- package/SVF-doxygen/html/html/classSVF_1_1ExtAPI_1_1Operation.html +344 -0
- package/SVF-doxygen/html/html/classSVF_1_1FSMPTA-members.html +240 -241
- package/SVF-doxygen/html/html/classSVF_1_1FSMPTA.html +1 -3
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive-members.html +230 -231
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive.html +5 -7
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ForkJoinAnalysis.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1ICFGBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1LockAnalysis.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1MHP.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1MTA.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1MTAAnnotator.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1MTAStat.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1PCG.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder-members.html +63 -64
- package/SVF-doxygen/html/html/classSVF_1_1SVFIRBuilder.html +306 -348
- package/SVF-doxygen/html/html/classSVF_1_1SrcSnkDDA.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1Steensgaard-members.html +187 -188
- package/SVF-doxygen/html/html/classSVF_1_1Steensgaard.html +5 -7
- package/SVF-doxygen/html/html/classSVF_1_1SymbolTableBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ThreadCallGraphBuilder.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis-members.html +179 -180
- package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis.html +1 -3
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive-members.html +281 -282
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive.html +6 -8
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitiveStat.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1WPAFSSolver-members.html +31 -32
- package/SVF-doxygen/html/html/classSVF_1_1WPAFSSolver.html +1 -3
- package/SVF-doxygen/html/html/classSVF_1_1WPAMinimumSolver-members.html +42 -43
- package/SVF-doxygen/html/html/classSVF_1_1WPAMinimumSolver.html +6 -8
- package/SVF-doxygen/html/html/classSVF_1_1WPAPass.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1WPASCCSolver-members.html +38 -39
- package/SVF-doxygen/html/html/classSVF_1_1WPASCCSolver.html +8 -10
- package/SVF-doxygen/html/html/classSVF_1_1WPASolver-members.html +29 -30
- package/SVF-doxygen/html/html/classSVF_1_1WPASolver.html +51 -86
- package/SVF-doxygen/html/html/classes.html +90 -90
- package/SVF-doxygen/html/html/functions_a.html +8 -5
- package/SVF-doxygen/html/html/functions_c.html +19 -20
- package/SVF-doxygen/html/html/functions_e.html +4 -7
- package/SVF-doxygen/html/html/functions_eval_e.html +2 -5
- package/SVF-doxygen/html/html/functions_func_c.html +12 -13
- package/SVF-doxygen/html/html/functions_func_g.html +23 -11
- package/SVF-doxygen/html/html/functions_func_m.html +0 -1
- package/SVF-doxygen/html/html/functions_func_o.html +7 -4
- package/SVF-doxygen/html/html/functions_func_p.html +1 -1
- package/SVF-doxygen/html/html/functions_func_s.html +11 -5
- package/SVF-doxygen/html/html/functions_g.html +21 -9
- package/SVF-doxygen/html/html/functions_i.html +3 -3
- package/SVF-doxygen/html/html/functions_l.html +3 -3
- package/SVF-doxygen/html/html/functions_m.html +0 -1
- package/SVF-doxygen/html/html/functions_n.html +4 -4
- package/SVF-doxygen/html/html/functions_o.html +21 -19
- package/SVF-doxygen/html/html/functions_p.html +7 -9
- package/SVF-doxygen/html/html/functions_r.html +4 -2
- package/SVF-doxygen/html/html/functions_s.html +22 -18
- package/SVF-doxygen/html/html/functions_v.html +3 -3
- package/SVF-doxygen/html/html/functions_vars_a.html +3 -0
- package/SVF-doxygen/html/html/functions_vars_o.html +3 -0
- package/SVF-doxygen/html/html/functions_w.html +11 -11
- package/SVF-doxygen/html/html/hierarchy.html +99 -98
- package/SVF-doxygen/html/html/namespaceSVF.html +741 -21
- package/SVF-doxygen/html/html/namespaceSVF_1_1LLVMUtil.html +3 -3
- package/SVF-doxygen/html/html/namespaceSVF_1_1SVFUtil.html +3 -1
- package/SVF-doxygen/html/html/namespacemembers.html +33 -0
- package/SVF-doxygen/html/html/namespacemembers_b.html +5 -2
- package/SVF-doxygen/html/html/namespacemembers_c.html +6 -0
- package/SVF-doxygen/html/html/namespacemembers_d.html +19 -1
- package/SVF-doxygen/html/html/namespacemembers_g.html +15 -3
- package/SVF-doxygen/html/html/namespacemembers_i.html +16 -4
- package/SVF-doxygen/html/html/namespacemembers_m.html +21 -0
- package/SVF-doxygen/html/html/namespacemembers_n.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_p.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_s.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_type.html +33 -0
- package/SVF-doxygen/html/html/namespacemembers_type_b.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_type_c.html +6 -0
- package/SVF-doxygen/html/html/namespacemembers_type_d.html +18 -0
- package/SVF-doxygen/html/html/namespacemembers_type_g.html +12 -0
- package/SVF-doxygen/html/html/namespacemembers_type_i.html +12 -0
- package/SVF-doxygen/html/html/namespacemembers_type_m.html +21 -0
- package/SVF-doxygen/html/html/namespacemembers_type_n.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_type_p.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_type_s.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_type_v.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_type_w.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_v.html +3 -0
- package/SVF-doxygen/html/html/namespacemembers_w.html +3 -0
- package/SVF-doxygen/html/html/search/all_1.js +12 -0
- package/SVF-doxygen/html/html/search/all_10.js +8 -7
- package/SVF-doxygen/html/html/search/all_11.js +2 -2
- package/SVF-doxygen/html/html/search/all_12.js +12 -9
- package/SVF-doxygen/html/html/search/all_13.js +3 -3
- package/SVF-doxygen/html/html/search/all_14.js +1 -1
- package/SVF-doxygen/html/html/search/all_15.js +4 -3
- package/SVF-doxygen/html/html/search/all_16.js +2 -1
- package/SVF-doxygen/html/html/search/all_2.js +1 -0
- package/SVF-doxygen/html/html/search/all_3.js +4 -2
- package/SVF-doxygen/html/html/search/all_4.js +6 -0
- package/SVF-doxygen/html/html/search/all_5.js +1 -2
- package/SVF-doxygen/html/html/search/all_7.js +9 -1
- package/SVF-doxygen/html/html/search/all_9.js +5 -1
- package/SVF-doxygen/html/html/search/all_c.js +2 -2
- package/SVF-doxygen/html/html/search/all_d.js +8 -1
- package/SVF-doxygen/html/html/search/all_e.js +2 -1
- package/SVF-doxygen/html/html/search/all_f.js +3 -2
- package/SVF-doxygen/html/html/search/classes_c.js +1 -0
- package/SVF-doxygen/html/html/search/enumvalues_4.js +1 -2
- package/SVF-doxygen/html/html/search/functions_11.js +2 -0
- package/SVF-doxygen/html/html/search/functions_2.js +1 -1
- package/SVF-doxygen/html/html/search/functions_6.js +5 -1
- package/SVF-doxygen/html/html/search/functions_c.js +1 -1
- package/SVF-doxygen/html/html/search/functions_e.js +1 -0
- package/SVF-doxygen/html/html/search/functions_f.js +1 -1
- package/SVF-doxygen/html/html/search/typedefs_0.js +11 -0
- package/SVF-doxygen/html/html/search/typedefs_1.js +1 -0
- package/SVF-doxygen/html/html/search/typedefs_10.js +1 -0
- package/SVF-doxygen/html/html/search/typedefs_13.js +1 -0
- package/SVF-doxygen/html/html/search/typedefs_14.js +1 -0
- package/SVF-doxygen/html/html/search/typedefs_2.js +2 -0
- package/SVF-doxygen/html/html/search/typedefs_3.js +6 -0
- package/SVF-doxygen/html/html/search/typedefs_6.js +4 -0
- package/SVF-doxygen/html/html/search/typedefs_7.js +4 -0
- package/SVF-doxygen/html/html/search/typedefs_b.js +7 -0
- package/SVF-doxygen/html/html/search/typedefs_c.js +1 -0
- package/SVF-doxygen/html/html/search/typedefs_e.js +1 -0
- package/SVF-doxygen/html/html/search/variables_1.js +1 -0
- package/SVF-doxygen/html/html/search/variables_13.js +1 -1
- package/SVF-doxygen/html/html/search/variables_14.js +1 -1
- package/SVF-doxygen/html/html/search/variables_f.js +1 -0
- package/SVF-doxygen/html/html/svf-ex_8cpp.html +1 -1
- package/SVF-doxygen/html/html/svf-ex_8cpp_source.html +1 -1
- package/include/SVF-FE/BasicTypes.h +43 -0
- package/include/SVF-FE/SVFIRBuilder.h +0 -2
- package/include/Util/ExtAPI.h +49 -5
- package/include/Util/ExtAPI.json +1312 -320
- package/include/WPA/Andersen.h +1 -4
- package/include/WPA/WPASolver.h +1 -3
- package/lib/SVF-FE/SVFIRBuilder.cpp +219 -238
- package/lib/Util/ExtAPI.cpp +109 -0
- package/lib/WPA/AndersenWaveDiff.cpp +0 -14
- package/package.json +1 -1
package/include/WPA/Andersen.h
CHANGED
|
@@ -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
|
package/include/WPA/WPASolver.h
CHANGED
|
@@ -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
|
|
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
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
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
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
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
|
-
|
|
1246
|
-
// Get the first operation of the function
|
|
1247
|
-
obj = obj -> next -> next;
|
|
1248
|
-
while (obj)
|
|
1195
|
+
for (auto operations: allOperations)
|
|
1249
1196
|
{
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1197
|
+
NodeID tempNode = -1;
|
|
1198
|
+
// Record the previous operation
|
|
1199
|
+
ExtAPI::Operation *preOp = nullptr;
|
|
1200
|
+
for (auto op : operations)
|
|
1253
1201
|
{
|
|
1254
|
-
|
|
1255
|
-
|
|
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
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
{
|
|
1270
|
-
if (args.size() == 1)
|
|
1205
|
+
switch (opName)
|
|
1206
|
+
{
|
|
1207
|
+
case ExtAPI::EXT_ADDR:
|
|
1271
1208
|
{
|
|
1272
|
-
if (
|
|
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
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1319
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1338
|
-
NodeID
|
|
1339
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1352
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1372
|
-
|
|
1316
|
+
LocationSet ls(offset);
|
|
1317
|
+
addNormalGepEdge(vnS, vnD, ls);
|
|
1373
1318
|
}
|
|
1374
1319
|
}
|
|
1320
|
+
break;
|
|
1375
1321
|
}
|
|
1376
|
-
|
|
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
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
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
|
-
|
|
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
|
package/lib/Util/ExtAPI.cpp
CHANGED
|
@@ -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
|
{
|