svf-tools 1.0.677 → 1.0.679
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/wiki/cpu2017-wllvm.cfg +999 -0
- package/package.json +1 -1
- package/svf/include/Graphs/CHG.h +27 -14
- package/svf/include/Graphs/GenericGraph.h +10 -4
- package/svf/include/Graphs/ICFG.h +6 -1
- package/svf/include/Graphs/ICFGEdge.h +41 -31
- package/svf/include/Graphs/ICFGNode.h +14 -2
- package/svf/include/Graphs/IRGraph.h +22 -14
- package/svf/include/MemoryModel/LocationSet.h +10 -8
- package/svf/include/MemoryModel/SVFLoop.h +2 -0
- package/svf/include/SVFIR/SVFIR.h +42 -23
- package/svf/include/SVFIR/SVFIRRW.h +624 -0
- package/svf/include/SVFIR/SVFModule.h +1 -0
- package/svf/include/SVFIR/SVFModuleRW.h +3 -6
- package/svf/include/SVFIR/SVFStatements.h +247 -185
- package/svf/include/SVFIR/SVFType.h +4 -0
- package/svf/include/SVFIR/SVFValue.h +28 -9
- package/svf/include/SVFIR/SVFVariables.h +75 -78
- package/svf/include/SVFIR/SymbolTableInfo.h +19 -11
- package/svf/include/Util/CommandLine.h +1 -1
- package/svf/include/Util/Options.h +1 -0
- package/svf/include/Util/SparseBitVector.h +6 -0
- package/svf/include/Util/ThreadAPI.h +15 -15
- package/svf/lib/AbstractExecution/SVFIR2ItvExeState.cpp +61 -17
- package/svf/lib/Graphs/ICFG.cpp +2 -3
- package/svf/lib/SVFIR/SVFIRRW.cpp +1118 -0
- package/svf/lib/SVFIR/SymbolTableInfo.cpp +1 -1
- package/svf/lib/Util/Options.cpp +6 -0
- package/svf-llvm/include/SVF-LLVM/DCHG.h +36 -35
- package/svf-llvm/lib/LLVMModule.cpp +0 -5
- package/svf-llvm/lib/SVFIRBuilder.cpp +10 -2
- package/svf-llvm/tools/WPA/wpa.cpp +4 -0
|
@@ -0,0 +1,1118 @@
|
|
|
1
|
+
#include "SVFIR/SVFIRRW.h"
|
|
2
|
+
#include "Graphs/CHG.h"
|
|
3
|
+
#include "SVFIR/SVFIR.h"
|
|
4
|
+
#include "Util/CommandLine.h"
|
|
5
|
+
|
|
6
|
+
static const Option<bool> humanReadableOption(
|
|
7
|
+
"human-readable", "Whether to output human-readable JSON", true);
|
|
8
|
+
|
|
9
|
+
namespace SVF
|
|
10
|
+
{
|
|
11
|
+
|
|
12
|
+
cJSON* SVFIRWriter::toJson(unsigned number)
|
|
13
|
+
{
|
|
14
|
+
// OK, double precision enough
|
|
15
|
+
return jsonCreateNumber(number);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
cJSON* SVFIRWriter::toJson(int number)
|
|
19
|
+
{
|
|
20
|
+
// OK, double precision enough
|
|
21
|
+
return jsonCreateNumber(number);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
cJSON* SVFIRWriter::toJson(float number)
|
|
25
|
+
{
|
|
26
|
+
return jsonCreateNumber(number);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
cJSON* SVFIRWriter::toJson(unsigned long number)
|
|
30
|
+
{
|
|
31
|
+
// unsigned long is subset of unsigned long long
|
|
32
|
+
return toJson(static_cast<unsigned long long>(number));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
cJSON* SVFIRWriter::toJson(long long number)
|
|
36
|
+
{
|
|
37
|
+
return toJson(static_cast<unsigned long long>(number));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
cJSON* SVFIRWriter::toJson(unsigned long long number)
|
|
41
|
+
{
|
|
42
|
+
return jsonCreateString(numToStr(number));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
cJSON* SVFIRWriter::virtToJson(const SVFType* type)
|
|
46
|
+
{
|
|
47
|
+
auto kind = type->getKind();
|
|
48
|
+
|
|
49
|
+
switch (kind)
|
|
50
|
+
{
|
|
51
|
+
default:
|
|
52
|
+
assert(false && "Impossible SVFType kind");
|
|
53
|
+
|
|
54
|
+
#define CASE(Kind) \
|
|
55
|
+
case SVFType::Kind: \
|
|
56
|
+
return contentToJson(SVFUtil::dyn_cast<Kind##pe>(type))
|
|
57
|
+
|
|
58
|
+
CASE(SVFTy);
|
|
59
|
+
CASE(SVFPointerTy);
|
|
60
|
+
CASE(SVFIntegerTy);
|
|
61
|
+
CASE(SVFFunctionTy);
|
|
62
|
+
CASE(SVFStructTy);
|
|
63
|
+
CASE(SVFArrayTy);
|
|
64
|
+
CASE(SVFOtherTy);
|
|
65
|
+
#undef CASE
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
cJSON* SVFIRWriter::virtToJson(const SVFValue* value)
|
|
70
|
+
{
|
|
71
|
+
auto kind = value->getKind();
|
|
72
|
+
|
|
73
|
+
switch (kind)
|
|
74
|
+
{
|
|
75
|
+
default:
|
|
76
|
+
assert(false && "Impossible SVFValue kind");
|
|
77
|
+
|
|
78
|
+
#define CASE(ValueKind, type) \
|
|
79
|
+
case SVFValue::ValueKind: \
|
|
80
|
+
return contentToJson(static_cast<const type*>(value))
|
|
81
|
+
|
|
82
|
+
CASE(SVFVal, SVFValue);
|
|
83
|
+
CASE(SVFFunc, SVFFunction);
|
|
84
|
+
CASE(SVFBB, SVFBasicBlock);
|
|
85
|
+
CASE(SVFInst, SVFInstruction);
|
|
86
|
+
CASE(SVFCall, SVFCallInst);
|
|
87
|
+
CASE(SVFVCall, SVFVirtualCallInst);
|
|
88
|
+
CASE(SVFGlob, SVFGlobalValue);
|
|
89
|
+
CASE(SVFArg, SVFArgument);
|
|
90
|
+
CASE(SVFConst, SVFConstant);
|
|
91
|
+
CASE(SVFConstData, SVFConstantData);
|
|
92
|
+
CASE(SVFConstInt, SVFConstantInt);
|
|
93
|
+
CASE(SVFConstFP, SVFConstantFP);
|
|
94
|
+
CASE(SVFNullPtr, SVFConstantNullPtr);
|
|
95
|
+
CASE(SVFBlackHole, SVFBlackHoleValue);
|
|
96
|
+
CASE(SVFMetaAsValue, SVFMetadataAsValue);
|
|
97
|
+
CASE(SVFOther, SVFOtherValue);
|
|
98
|
+
#undef CASE
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
cJSON* SVFIRWriter::virtToJson(const SVFVar* var)
|
|
103
|
+
{
|
|
104
|
+
switch (var->getNodeKind())
|
|
105
|
+
{
|
|
106
|
+
default:
|
|
107
|
+
assert(false && "Unknown SVFVar kind");
|
|
108
|
+
|
|
109
|
+
#define CASE(VarKind, VarType) \
|
|
110
|
+
case SVFVar::VarKind: \
|
|
111
|
+
return contentToJson(static_cast<const VarType*>(var))
|
|
112
|
+
|
|
113
|
+
CASE(ValNode, ValVar);
|
|
114
|
+
CASE(ObjNode, ObjVar);
|
|
115
|
+
CASE(RetNode, RetPN);
|
|
116
|
+
CASE(VarargNode, VarArgPN);
|
|
117
|
+
CASE(GepValNode, GepValVar);
|
|
118
|
+
CASE(GepObjNode, GepObjVar);
|
|
119
|
+
CASE(FIObjNode, FIObjVar);
|
|
120
|
+
CASE(DummyValNode, DummyValVar);
|
|
121
|
+
CASE(DummyObjNode, DummyObjVar);
|
|
122
|
+
#undef CASE
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
cJSON* SVFIRWriter::virtToJson(const SVFStmt* stmt)
|
|
127
|
+
{
|
|
128
|
+
switch (stmt->getEdgeKind())
|
|
129
|
+
{
|
|
130
|
+
default:
|
|
131
|
+
assert(false && "Unknown SVFStmt kind");
|
|
132
|
+
|
|
133
|
+
#define CASE(EdgeKind, EdgeType) \
|
|
134
|
+
case SVFStmt::EdgeKind: \
|
|
135
|
+
return contentToJson(static_cast<const EdgeType*>(stmt))
|
|
136
|
+
|
|
137
|
+
CASE(Addr, AddrStmt);
|
|
138
|
+
CASE(Copy, CopyStmt);
|
|
139
|
+
CASE(Store, StoreStmt);
|
|
140
|
+
CASE(Load, LoadStmt);
|
|
141
|
+
CASE(Call, CallPE);
|
|
142
|
+
CASE(Ret, RetPE);
|
|
143
|
+
CASE(Gep, GepStmt);
|
|
144
|
+
CASE(Phi, PhiStmt);
|
|
145
|
+
CASE(Select, SelectStmt);
|
|
146
|
+
CASE(Cmp, CmpStmt);
|
|
147
|
+
CASE(BinaryOp, BinaryOPStmt);
|
|
148
|
+
CASE(UnaryOp, UnaryOPStmt);
|
|
149
|
+
CASE(Branch, BranchStmt);
|
|
150
|
+
CASE(ThreadFork, TDForkPE);
|
|
151
|
+
CASE(ThreadJoin, TDJoinPE);
|
|
152
|
+
#undef CASE
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
cJSON* SVFIRWriter::virtToJson(const ICFGNode* node)
|
|
157
|
+
{
|
|
158
|
+
switch (node->getNodeKind())
|
|
159
|
+
{
|
|
160
|
+
default:
|
|
161
|
+
assert(false && "Unknown ICFGNode kind");
|
|
162
|
+
|
|
163
|
+
#define CASE(NodeKind, NodeType) \
|
|
164
|
+
case ICFGNode::NodeKind: \
|
|
165
|
+
return contentToJson(static_cast<const NodeType*>(node))
|
|
166
|
+
|
|
167
|
+
CASE(IntraBlock, IntraICFGNode);
|
|
168
|
+
CASE(FunEntryBlock, FunEntryICFGNode);
|
|
169
|
+
CASE(FunExitBlock, FunExitICFGNode);
|
|
170
|
+
CASE(FunCallBlock, CallICFGNode);
|
|
171
|
+
CASE(FunRetBlock, RetICFGNode);
|
|
172
|
+
CASE(GlobalBlock, GlobalICFGNode);
|
|
173
|
+
#undef CASE
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
cJSON* SVFIRWriter::virtToJson(const ICFGEdge* edge)
|
|
178
|
+
{
|
|
179
|
+
switch (edge->getEdgeKind())
|
|
180
|
+
{
|
|
181
|
+
default:
|
|
182
|
+
assert(false && "Unknown ICFGEdge kind");
|
|
183
|
+
case ICFGEdge::IntraCF:
|
|
184
|
+
return contentToJson(static_cast<const IntraCFGEdge*>(edge));
|
|
185
|
+
case ICFGEdge::CallCF:
|
|
186
|
+
return contentToJson(static_cast<const CallCFGEdge*>(edge));
|
|
187
|
+
case ICFGEdge::RetCF:
|
|
188
|
+
return contentToJson(static_cast<const RetCFGEdge*>(edge));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
cJSON* SVFIRWriter::virtToJson(const CHNode* node)
|
|
193
|
+
{
|
|
194
|
+
return contentToJson(node);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
cJSON* SVFIRWriter::virtToJson(const CHEdge* edge)
|
|
198
|
+
{
|
|
199
|
+
return contentToJson(edge);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
cJSON* SVFIRWriter::contentToJson(const SVFVar* var)
|
|
203
|
+
{
|
|
204
|
+
cJSON* root = genericNodeToJson(var);
|
|
205
|
+
JSON_WRITE_FIELD(root, var, value);
|
|
206
|
+
JSON_WRITE_FIELD(root, var, InEdgeKindToSetMap);
|
|
207
|
+
JSON_WRITE_FIELD(root, var, OutEdgeKindToSetMap);
|
|
208
|
+
JSON_WRITE_FIELD(root, var, isPtr);
|
|
209
|
+
return root;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
cJSON* SVFIRWriter::contentToJson(const ValVar* var)
|
|
213
|
+
{
|
|
214
|
+
return contentToJson(static_cast<const SVFVar*>(var));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
cJSON* SVFIRWriter::contentToJson(const ObjVar* var)
|
|
218
|
+
{
|
|
219
|
+
cJSON* root = contentToJson(static_cast<const SVFVar*>(var));
|
|
220
|
+
JSON_WRITE_FIELD(root, var, mem);
|
|
221
|
+
return root;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
cJSON* SVFIRWriter::contentToJson(const GepValVar* var)
|
|
225
|
+
{
|
|
226
|
+
cJSON* root = contentToJson(static_cast<const ValVar*>(var));
|
|
227
|
+
JSON_WRITE_FIELD(root, var, ls);
|
|
228
|
+
JSON_WRITE_FIELD(root, var, gepValType);
|
|
229
|
+
return root;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
cJSON* SVFIRWriter::contentToJson(const GepObjVar* var)
|
|
233
|
+
{
|
|
234
|
+
cJSON* root = contentToJson(static_cast<const ObjVar*>(var));
|
|
235
|
+
JSON_WRITE_FIELD(root, var, ls);
|
|
236
|
+
JSON_WRITE_FIELD(root, var, base);
|
|
237
|
+
return root;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
cJSON* SVFIRWriter::contentToJson(const FIObjVar* var)
|
|
241
|
+
{
|
|
242
|
+
return contentToJson(static_cast<const ObjVar*>(var));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
cJSON* SVFIRWriter::contentToJson(const RetPN* var)
|
|
246
|
+
{
|
|
247
|
+
return contentToJson(static_cast<const ValVar*>(var));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
cJSON* SVFIRWriter::contentToJson(const VarArgPN* var)
|
|
251
|
+
{
|
|
252
|
+
return contentToJson(static_cast<const ValVar*>(var));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
cJSON* SVFIRWriter::contentToJson(const DummyValVar* var)
|
|
256
|
+
{
|
|
257
|
+
return contentToJson(static_cast<const ValVar*>(var));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
cJSON* SVFIRWriter::contentToJson(const DummyObjVar* var)
|
|
261
|
+
{
|
|
262
|
+
return contentToJson(static_cast<const ObjVar*>(var));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
cJSON* SVFIRWriter::contentToJson(const ICFGNode* node)
|
|
266
|
+
{
|
|
267
|
+
cJSON* root = genericNodeToJson(node);
|
|
268
|
+
JSON_WRITE_FIELD(root, node, fun);
|
|
269
|
+
JSON_WRITE_FIELD(root, node, bb);
|
|
270
|
+
// TODO: Ensure this?
|
|
271
|
+
assert(node->VFGNodes.empty() && "VFGNodes list not empty?");
|
|
272
|
+
JSON_WRITE_FIELD(root, node, pagEdges);
|
|
273
|
+
return root;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
cJSON* SVFIRWriter::contentToJson(const GlobalICFGNode* node)
|
|
277
|
+
{
|
|
278
|
+
return contentToJson(static_cast<const ICFGNode*>(node));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
cJSON* SVFIRWriter::contentToJson(const IntraICFGNode* node)
|
|
282
|
+
{
|
|
283
|
+
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
|
|
284
|
+
JSON_WRITE_FIELD(root, node, inst);
|
|
285
|
+
return root;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
cJSON* SVFIRWriter::contentToJson(const InterICFGNode* node)
|
|
289
|
+
{
|
|
290
|
+
return contentToJson(static_cast<const ICFGNode*>(node));
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
cJSON* SVFIRWriter::contentToJson(const FunEntryICFGNode* node)
|
|
294
|
+
{
|
|
295
|
+
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
|
|
296
|
+
JSON_WRITE_FIELD(root, node, FPNodes);
|
|
297
|
+
return root;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
cJSON* SVFIRWriter::contentToJson(const FunExitICFGNode* node)
|
|
301
|
+
{
|
|
302
|
+
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
|
|
303
|
+
JSON_WRITE_FIELD(root, node, formalRet);
|
|
304
|
+
return root;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
|
|
308
|
+
{
|
|
309
|
+
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
|
|
310
|
+
JSON_WRITE_FIELD(root, node, cs);
|
|
311
|
+
JSON_WRITE_FIELD(root, node, ret);
|
|
312
|
+
JSON_WRITE_FIELD(root, node, APNodes);
|
|
313
|
+
return root;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
cJSON* SVFIRWriter::contentToJson(const RetICFGNode* node)
|
|
317
|
+
{
|
|
318
|
+
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
|
|
319
|
+
JSON_WRITE_FIELD(root, node, cs);
|
|
320
|
+
JSON_WRITE_FIELD(root, node, actualRet);
|
|
321
|
+
JSON_WRITE_FIELD(root, node, callBlockNode);
|
|
322
|
+
return root;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
cJSON* SVFIRWriter::contentToJson(const ICFGEdge* edge)
|
|
326
|
+
{
|
|
327
|
+
return genericEdgeToJson(edge);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
cJSON* SVFIRWriter::contentToJson(const IntraCFGEdge* edge)
|
|
331
|
+
{
|
|
332
|
+
cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
|
|
333
|
+
JSON_WRITE_FIELD(root, edge, conditionVar);
|
|
334
|
+
JSON_WRITE_FIELD(root, edge, branchCondVal);
|
|
335
|
+
return root;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
cJSON* SVFIRWriter::contentToJson(const CallCFGEdge* edge)
|
|
339
|
+
{
|
|
340
|
+
cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
|
|
341
|
+
JSON_WRITE_FIELD(root, edge, cs);
|
|
342
|
+
JSON_WRITE_FIELD(root, edge, callPEs);
|
|
343
|
+
return root;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
cJSON* SVFIRWriter::contentToJson(const RetCFGEdge* edge)
|
|
347
|
+
{
|
|
348
|
+
cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
|
|
349
|
+
JSON_WRITE_FIELD(root, edge, cs);
|
|
350
|
+
JSON_WRITE_FIELD(root, edge, retPE);
|
|
351
|
+
return root;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
cJSON* SVFIRWriter::contentToJson(const CHNode* node)
|
|
355
|
+
{
|
|
356
|
+
cJSON* root = genericNodeToJson(node);
|
|
357
|
+
JSON_WRITE_FIELD(root, node, vtable);
|
|
358
|
+
JSON_WRITE_FIELD(root, node, className);
|
|
359
|
+
JSON_WRITE_FIELD(root, node, flags);
|
|
360
|
+
JSON_WRITE_FIELD(root, node, virtualFunctionVectors);
|
|
361
|
+
return root;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
cJSON* SVFIRWriter::contentToJson(const CHEdge* edge)
|
|
365
|
+
{
|
|
366
|
+
cJSON* root = genericEdgeToJson(edge);
|
|
367
|
+
JSON_WRITE_FIELD(root, edge, edgeType);
|
|
368
|
+
return root;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
cJSON* SVFIRWriter::contentToJson(const SVFType* type)
|
|
372
|
+
{
|
|
373
|
+
cJSON* root = jsonCreateObject();
|
|
374
|
+
JSON_WRITE_FIELD(root, type, kind);
|
|
375
|
+
JSON_WRITE_FIELD(root, type, getPointerToTy);
|
|
376
|
+
JSON_WRITE_FIELD(root, type, typeinfo);
|
|
377
|
+
JSON_WRITE_FIELD(root, type, isSingleValTy);
|
|
378
|
+
return root;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
cJSON* SVFIRWriter::contentToJson(const SVFPointerType* type)
|
|
382
|
+
{
|
|
383
|
+
cJSON* root = contentToJson(static_cast<const SVFType*>(type));
|
|
384
|
+
JSON_WRITE_FIELD(root, type, ptrElementType);
|
|
385
|
+
return root;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
cJSON* SVFIRWriter::contentToJson(const SVFIntegerType* type)
|
|
389
|
+
{
|
|
390
|
+
return contentToJson(static_cast<const SVFType*>(type));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
cJSON* SVFIRWriter::contentToJson(const SVFFunctionType* type)
|
|
394
|
+
{
|
|
395
|
+
cJSON* root = contentToJson(static_cast<const SVFType*>(type));
|
|
396
|
+
JSON_WRITE_FIELD(root, type, retTy);
|
|
397
|
+
return root;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
cJSON* SVFIRWriter::contentToJson(const SVFStructType* type)
|
|
401
|
+
{
|
|
402
|
+
return contentToJson(static_cast<const SVFType*>(type));
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
cJSON* SVFIRWriter::contentToJson(const SVFArrayType* type)
|
|
406
|
+
{
|
|
407
|
+
return contentToJson(static_cast<const SVFType*>(type));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
cJSON* SVFIRWriter::contentToJson(const SVFOtherType* type)
|
|
411
|
+
{
|
|
412
|
+
return contentToJson(static_cast<const SVFType*>(type));
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
cJSON* SVFIRWriter::contentToJson(const SVFValue* value)
|
|
416
|
+
{
|
|
417
|
+
cJSON* root = jsonCreateObject();
|
|
418
|
+
JSON_WRITE_FIELD(root, value, kind);
|
|
419
|
+
JSON_WRITE_FIELD(root, value, ptrInUncalledFun);
|
|
420
|
+
JSON_WRITE_FIELD(root, value, constDataOrAggData);
|
|
421
|
+
JSON_WRITE_FIELD(root, value, type);
|
|
422
|
+
JSON_WRITE_FIELD(root, value, name);
|
|
423
|
+
JSON_WRITE_FIELD(root, value, sourceLoc);
|
|
424
|
+
|
|
425
|
+
return root;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
cJSON* SVFIRWriter::contentToJson(const SVFFunction* value)
|
|
429
|
+
{
|
|
430
|
+
cJSON* root = contentToJson(static_cast<const SVFValue*>(value));
|
|
431
|
+
JSON_WRITE_FIELD(root, value, isDecl);
|
|
432
|
+
JSON_WRITE_FIELD(root, value, intrinsic);
|
|
433
|
+
JSON_WRITE_FIELD(root, value, addrTaken);
|
|
434
|
+
JSON_WRITE_FIELD(root, value, isUncalled);
|
|
435
|
+
JSON_WRITE_FIELD(root, value, isNotRet);
|
|
436
|
+
JSON_WRITE_FIELD(root, value, varArg);
|
|
437
|
+
JSON_WRITE_FIELD(root, value, funcType);
|
|
438
|
+
JSON_WRITE_FIELD(root, value, loopAndDom);
|
|
439
|
+
JSON_WRITE_FIELD(root, value, realDefFun);
|
|
440
|
+
JSON_WRITE_FIELD(root, value, allBBs);
|
|
441
|
+
JSON_WRITE_FIELD(root, value, allArgs);
|
|
442
|
+
return root;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
cJSON* SVFIRWriter::contentToJson(const SVFBasicBlock* value)
|
|
446
|
+
{
|
|
447
|
+
cJSON* root = contentToJson(static_cast<const SVFValue*>(value));
|
|
448
|
+
JSON_WRITE_FIELD(root, value, allInsts);
|
|
449
|
+
JSON_WRITE_FIELD(root, value, succBBs);
|
|
450
|
+
JSON_WRITE_FIELD(root, value, predBBs);
|
|
451
|
+
JSON_WRITE_FIELD(root, value, fun);
|
|
452
|
+
return root;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
cJSON* SVFIRWriter::contentToJson(const SVFInstruction* value)
|
|
456
|
+
{
|
|
457
|
+
cJSON* root = contentToJson(static_cast<const SVFValue*>(value));
|
|
458
|
+
JSON_WRITE_FIELD(root, value, bb);
|
|
459
|
+
JSON_WRITE_FIELD(root, value, terminator);
|
|
460
|
+
JSON_WRITE_FIELD(root, value, ret);
|
|
461
|
+
JSON_WRITE_FIELD(root, value, succInsts);
|
|
462
|
+
JSON_WRITE_FIELD(root, value, predInsts);
|
|
463
|
+
return root;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
cJSON* SVFIRWriter::contentToJson(const SVFCallInst* value)
|
|
467
|
+
{
|
|
468
|
+
cJSON* root = contentToJson(static_cast<const SVFInstruction*>(value));
|
|
469
|
+
JSON_WRITE_FIELD(root, value, args);
|
|
470
|
+
JSON_WRITE_FIELD(root, value, varArg);
|
|
471
|
+
JSON_WRITE_FIELD(root, value, calledVal);
|
|
472
|
+
return root;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
cJSON* SVFIRWriter::contentToJson(const SVFVirtualCallInst* value)
|
|
476
|
+
{
|
|
477
|
+
cJSON* root = contentToJson(static_cast<const SVFCallInst*>(value));
|
|
478
|
+
JSON_WRITE_FIELD(root, value, vCallVtblPtr);
|
|
479
|
+
JSON_WRITE_FIELD(root, value, virtualFunIdx);
|
|
480
|
+
JSON_WRITE_FIELD(root, value, funNameOfVcall);
|
|
481
|
+
return root;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
cJSON* SVFIRWriter::contentToJson(const SVFConstant* value)
|
|
485
|
+
{
|
|
486
|
+
return contentToJson(static_cast<const SVFValue*>(value));
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
cJSON* SVFIRWriter::contentToJson(const SVFGlobalValue* value)
|
|
490
|
+
{
|
|
491
|
+
cJSON* root = contentToJson(static_cast<const SVFConstant*>(value));
|
|
492
|
+
JSON_WRITE_FIELD(root, value, realDefGlobal);
|
|
493
|
+
return root;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
cJSON* SVFIRWriter::contentToJson(const SVFArgument* value)
|
|
497
|
+
{
|
|
498
|
+
cJSON* root = contentToJson(static_cast<const SVFValue*>(value));
|
|
499
|
+
JSON_WRITE_FIELD(root, value, fun);
|
|
500
|
+
JSON_WRITE_FIELD(root, value, argNo);
|
|
501
|
+
JSON_WRITE_FIELD(root, value, uncalled);
|
|
502
|
+
return root;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
cJSON* SVFIRWriter::contentToJson(const SVFConstantData* value)
|
|
506
|
+
{
|
|
507
|
+
return contentToJson(static_cast<const SVFConstant*>(value));
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
cJSON* SVFIRWriter::contentToJson(const SVFConstantInt* value)
|
|
511
|
+
{
|
|
512
|
+
cJSON* root = contentToJson(static_cast<const SVFConstantData*>(value));
|
|
513
|
+
JSON_WRITE_FIELD(root, value, zval);
|
|
514
|
+
JSON_WRITE_FIELD(root, value, sval);
|
|
515
|
+
return root;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
cJSON* SVFIRWriter::contentToJson(const SVFConstantFP* value)
|
|
519
|
+
{
|
|
520
|
+
cJSON* root = contentToJson(static_cast<const SVFConstantData*>(value));
|
|
521
|
+
JSON_WRITE_FIELD(root, value, dval);
|
|
522
|
+
return root;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
cJSON* SVFIRWriter::contentToJson(const SVFConstantNullPtr* value)
|
|
526
|
+
{
|
|
527
|
+
return contentToJson(static_cast<const SVFConstantData*>(value));
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
cJSON* SVFIRWriter::contentToJson(const SVFBlackHoleValue* value)
|
|
531
|
+
{
|
|
532
|
+
return contentToJson(static_cast<const SVFConstantData*>(value));
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
cJSON* SVFIRWriter::contentToJson(const SVFOtherValue* value)
|
|
536
|
+
{
|
|
537
|
+
return contentToJson(static_cast<const SVFValue*>(value));
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
cJSON* SVFIRWriter::contentToJson(const SVFMetadataAsValue* value)
|
|
541
|
+
{
|
|
542
|
+
return contentToJson(static_cast<const SVFOtherValue*>(value));
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
cJSON* SVFIRWriter::contentToJson(const SVFStmt* edge)
|
|
546
|
+
{
|
|
547
|
+
cJSON* root = genericEdgeToJson(edge);
|
|
548
|
+
JSON_WRITE_FIELD(root, edge, value);
|
|
549
|
+
JSON_WRITE_FIELD(root, edge, basicBlock);
|
|
550
|
+
JSON_WRITE_FIELD(root, edge, icfgNode);
|
|
551
|
+
JSON_WRITE_FIELD(root, edge, edgeId);
|
|
552
|
+
return root;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
cJSON* SVFIRWriter::contentToJson(const SVFLoop* loop)
|
|
556
|
+
{
|
|
557
|
+
cJSON* root = jsonCreateObject();
|
|
558
|
+
#define F(field) JSON_WRITE_FIELD(root, loop, field)
|
|
559
|
+
F(entryICFGEdges);
|
|
560
|
+
F(backICFGEdges);
|
|
561
|
+
F(inICFGEdges);
|
|
562
|
+
F(outICFGEdges);
|
|
563
|
+
F(icfgNodes);
|
|
564
|
+
F(loopBound);
|
|
565
|
+
#undef F
|
|
566
|
+
return root;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
cJSON* SVFIRWriter::contentToJson(const SymbolTableInfo* symTable)
|
|
570
|
+
{
|
|
571
|
+
// Owns values of objMap & svfTypes (?)
|
|
572
|
+
cJSON* root = jsonCreateObject();
|
|
573
|
+
JSON_WRITE_FIELD(root, symTable, valSymMap);
|
|
574
|
+
JSON_WRITE_FIELD(root, symTable, objSymMap);
|
|
575
|
+
JSON_WRITE_FIELD(root, symTable, returnSymMap);
|
|
576
|
+
JSON_WRITE_FIELD(root, symTable, varargSymMap);
|
|
577
|
+
|
|
578
|
+
// objMap
|
|
579
|
+
cJSON* objMap = jsonCreateMap();
|
|
580
|
+
for (const auto &pair : symTable->objMap)
|
|
581
|
+
{
|
|
582
|
+
SymID id = pair.first;
|
|
583
|
+
const MemObj* memObj = pair.second;
|
|
584
|
+
|
|
585
|
+
cJSON* keyJson = toJson(id);
|
|
586
|
+
cJSON* valueJson = contentToJson(memObj);
|
|
587
|
+
jsonAddPairToMap(objMap, keyJson, valueJson);
|
|
588
|
+
}
|
|
589
|
+
jsonAddItemToObject(root, "objMap", objMap);
|
|
590
|
+
|
|
591
|
+
// TODO: Check symTable->module == module
|
|
592
|
+
JSON_WRITE_FIELD(root, symTable, modelConstants);
|
|
593
|
+
JSON_WRITE_FIELD(root, symTable, totalSymNum);
|
|
594
|
+
JSON_WRITE_FIELD(root, symTable, svfTypes);
|
|
595
|
+
return root;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
cJSON* SVFIRWriter::contentToJson(const AssignStmt* edge)
|
|
599
|
+
{
|
|
600
|
+
return contentToJson(static_cast<const SVFStmt*>(edge));
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
cJSON* SVFIRWriter::contentToJson(const AddrStmt* edge)
|
|
604
|
+
{
|
|
605
|
+
return contentToJson(static_cast<const AssignStmt*>(edge));
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
cJSON* SVFIRWriter::contentToJson(const CopyStmt* edge)
|
|
609
|
+
{
|
|
610
|
+
return contentToJson(static_cast<const AssignStmt*>(edge));
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
cJSON* SVFIRWriter::contentToJson(const StoreStmt* edge)
|
|
614
|
+
{
|
|
615
|
+
return contentToJson(static_cast<const AssignStmt*>(edge));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
cJSON* SVFIRWriter::contentToJson(const LoadStmt* edge)
|
|
619
|
+
{
|
|
620
|
+
return contentToJson(static_cast<const AssignStmt*>(edge));
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
cJSON* SVFIRWriter::contentToJson(const GepStmt* edge)
|
|
624
|
+
{
|
|
625
|
+
cJSON* root = contentToJson(static_cast<const AssignStmt*>(edge));
|
|
626
|
+
JSON_WRITE_FIELD(root, edge, ls);
|
|
627
|
+
JSON_WRITE_FIELD(root, edge, variantField);
|
|
628
|
+
return root;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
cJSON* SVFIRWriter::contentToJson(const CallPE* edge)
|
|
632
|
+
{
|
|
633
|
+
cJSON* root = contentToJson(static_cast<const AssignStmt*>(edge));
|
|
634
|
+
JSON_WRITE_FIELD(root, edge, call);
|
|
635
|
+
JSON_WRITE_FIELD(root, edge, entry);
|
|
636
|
+
return root;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
cJSON* SVFIRWriter::contentToJson(const RetPE* edge)
|
|
640
|
+
{
|
|
641
|
+
cJSON* root = contentToJson(static_cast<const AssignStmt*>(edge));
|
|
642
|
+
JSON_WRITE_FIELD(root, edge, call);
|
|
643
|
+
JSON_WRITE_FIELD(root, edge, exit);
|
|
644
|
+
return root;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
cJSON* SVFIRWriter::contentToJson(const MultiOpndStmt* edge)
|
|
648
|
+
{
|
|
649
|
+
cJSON* root = contentToJson(static_cast<const SVFStmt*>(edge));
|
|
650
|
+
JSON_WRITE_FIELD(root, edge, opVars);
|
|
651
|
+
return root;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
cJSON* SVFIRWriter::contentToJson(const PhiStmt* edge)
|
|
655
|
+
{
|
|
656
|
+
cJSON* root = contentToJson(static_cast<const MultiOpndStmt*>(edge));
|
|
657
|
+
JSON_WRITE_FIELD(root, edge, opICFGNodes);
|
|
658
|
+
return root;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
cJSON* SVFIRWriter::contentToJson(const SelectStmt* edge)
|
|
662
|
+
{
|
|
663
|
+
cJSON* root = contentToJson(static_cast<const MultiOpndStmt*>(edge));
|
|
664
|
+
JSON_WRITE_FIELD(root, edge, condition);
|
|
665
|
+
return root;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
cJSON* SVFIRWriter::contentToJson(const CmpStmt* edge)
|
|
669
|
+
{
|
|
670
|
+
cJSON* root = contentToJson(static_cast<const MultiOpndStmt*>(edge));
|
|
671
|
+
JSON_WRITE_FIELD(root, edge, predicate);
|
|
672
|
+
return root;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
cJSON* SVFIRWriter::contentToJson(const BinaryOPStmt* edge)
|
|
676
|
+
{
|
|
677
|
+
cJSON* root = contentToJson(static_cast<const MultiOpndStmt*>(edge));
|
|
678
|
+
JSON_WRITE_FIELD(root, edge, opcode);
|
|
679
|
+
return root;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
cJSON* SVFIRWriter::contentToJson(const UnaryOPStmt* edge)
|
|
683
|
+
{
|
|
684
|
+
cJSON* root = contentToJson(static_cast<const SVFStmt*>(edge));
|
|
685
|
+
JSON_WRITE_FIELD(root, edge, opcode);
|
|
686
|
+
return root;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
cJSON* SVFIRWriter::contentToJson(const BranchStmt* edge)
|
|
690
|
+
{
|
|
691
|
+
cJSON* root = contentToJson(static_cast<const SVFStmt*>(edge));
|
|
692
|
+
JSON_WRITE_FIELD(root, edge, successors);
|
|
693
|
+
JSON_WRITE_FIELD(root, edge, cond);
|
|
694
|
+
JSON_WRITE_FIELD(root, edge, brInst);
|
|
695
|
+
return root;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
cJSON* SVFIRWriter::contentToJson(const TDForkPE* edge)
|
|
699
|
+
{
|
|
700
|
+
return contentToJson(static_cast<const CallPE*>(edge));
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
cJSON* SVFIRWriter::contentToJson(const TDJoinPE* edge)
|
|
704
|
+
{
|
|
705
|
+
return contentToJson(static_cast<const RetPE*>(edge));
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
bool jsonAddNumberToObject(cJSON* obj, const char* name, double number)
|
|
709
|
+
{
|
|
710
|
+
cJSON* node = cJSON_CreateNumber(number);
|
|
711
|
+
return jsonAddItemToObject(obj, name, node);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
bool jsonAddStringToObject(cJSON* obj, const char* name, const char* str)
|
|
715
|
+
{
|
|
716
|
+
cJSON* node = cJSON_CreateStringReference(str);
|
|
717
|
+
return jsonAddItemToObject(obj, name, node);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
bool jsonAddStringToObject(cJSON* obj, const char* name, const std::string& str)
|
|
721
|
+
{
|
|
722
|
+
return jsonAddStringToObject(obj, name, str.c_str());
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
cJSON* jsonCreateNullId()
|
|
726
|
+
{
|
|
727
|
+
// TODO: optimize
|
|
728
|
+
return cJSON_CreateNull();
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
bool jsonIsNullId(const cJSON* item)
|
|
732
|
+
{
|
|
733
|
+
// TODO: optimize
|
|
734
|
+
return cJSON_IsNull(item);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
cJSON* jsonCreateObject()
|
|
738
|
+
{
|
|
739
|
+
return humanReadableOption() ? cJSON_CreateObject() : cJSON_CreateArray();
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
cJSON* jsonCreateArray()
|
|
743
|
+
{
|
|
744
|
+
return cJSON_CreateArray();
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
cJSON* jsonCreateMap()
|
|
748
|
+
{
|
|
749
|
+
// Don't use cJSON_CreateObject() here, because it only allows string keys.
|
|
750
|
+
return cJSON_CreateArray();
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
cJSON* jsonCreateString(const char* str)
|
|
754
|
+
{
|
|
755
|
+
return cJSON_CreateStringReference(str);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
cJSON* jsonCreateIndex(size_t index)
|
|
759
|
+
{
|
|
760
|
+
constexpr size_t maxPreciseIntInDouble = (1ull << 53);
|
|
761
|
+
assert(index <= maxPreciseIntInDouble);
|
|
762
|
+
return cJSON_CreateNumber(index);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
cJSON* jsonCreateNumber(double num)
|
|
766
|
+
{
|
|
767
|
+
return cJSON_CreateNumber(num);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
bool jsonAddPairToMap(cJSON* mapObj, cJSON* key, cJSON* value)
|
|
771
|
+
{
|
|
772
|
+
cJSON* pair = cJSON_CreateArray();
|
|
773
|
+
jsonAddItemToArray(pair, key);
|
|
774
|
+
jsonAddItemToArray(pair, value);
|
|
775
|
+
jsonAddItemToArray(mapObj, pair);
|
|
776
|
+
return pair;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
bool jsonAddItemToObject(cJSON* obj, const char* name, cJSON* item)
|
|
780
|
+
{
|
|
781
|
+
return humanReadableOption() ? cJSON_AddItemToObject(obj, name, item)
|
|
782
|
+
: cJSON_AddItemToArray(obj, item);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
bool jsonAddItemToArray(cJSON* array, cJSON* item)
|
|
786
|
+
{
|
|
787
|
+
return cJSON_AddItemToArray(array, item);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
ICFGWriter::ICFGWriter(const ICFG* icfg) : GenericICFGWriter(icfg)
|
|
791
|
+
{
|
|
792
|
+
for (const auto& pair : icfg->getIcfgNodeToSVFLoopVec())
|
|
793
|
+
{
|
|
794
|
+
for (const SVFLoop* loop : pair.second)
|
|
795
|
+
{
|
|
796
|
+
svfLoopPool.saveID(loop);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
SymID SymbolTableInfoWriter::getMemObjID(const MemObj* memObj)
|
|
802
|
+
{
|
|
803
|
+
auto it = memObjToID.find(memObj);
|
|
804
|
+
assert(it != memObjToID.end() && "MemObj not found!");
|
|
805
|
+
return it->second;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
SymbolTableInfoWriter::SymbolTableInfoWriter(const SymbolTableInfo* symTab)
|
|
809
|
+
: symbolTableInfo(symTab)
|
|
810
|
+
{
|
|
811
|
+
assert(symbolTableInfo && "SymbolTableInfo is null!");
|
|
812
|
+
|
|
813
|
+
for (const auto& pair : symbolTableInfo->idToObjMap())
|
|
814
|
+
{
|
|
815
|
+
const SymID id = pair.first;
|
|
816
|
+
const MemObj* obj = pair.second;
|
|
817
|
+
memObjToID.emplace(obj, id);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
size_t SVFModuleWriter::getSvfTypeID(const SVFType* type)
|
|
822
|
+
{
|
|
823
|
+
return svfTypePool.getID(type);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
size_t SVFModuleWriter::getSvfValueID(const SVFValue* value)
|
|
827
|
+
{
|
|
828
|
+
return svfValuePool.getID(value);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
SVFIRWriter::SVFIRWriter(const SVFIR* svfir)
|
|
832
|
+
: svfIR(svfir), irGraphWriter(svfir), icfgWriter(svfir->icfg),
|
|
833
|
+
chgWriter(SVFUtil::dyn_cast<CHGraph>(svfir->chgraph)),
|
|
834
|
+
symbolTableInfoWriter(svfir->symInfo)
|
|
835
|
+
{
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
void SVFIRWriter::writeJsonToOstream(const SVFIR* svfir, std::ostream& os)
|
|
839
|
+
{
|
|
840
|
+
SVFIRWriter writer(svfir);
|
|
841
|
+
os << writer.generateJsonString().get() << '\n';
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
void SVFIRWriter::writeJsonToPath(const SVFIR* svfir, const std::string& path)
|
|
845
|
+
{
|
|
846
|
+
std::ofstream jsonFile(path);
|
|
847
|
+
if (jsonFile.is_open())
|
|
848
|
+
{
|
|
849
|
+
writeJsonToOstream(svfir, jsonFile);
|
|
850
|
+
jsonFile.close();
|
|
851
|
+
}
|
|
852
|
+
else
|
|
853
|
+
{
|
|
854
|
+
SVFUtil::errs() << "Failed to open file '" << path
|
|
855
|
+
<< "' to write SVFIR's JSON\n";
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
const char* SVFIRWriter::numToStr(size_t n)
|
|
860
|
+
{
|
|
861
|
+
auto it = numToStrMap.find(n);
|
|
862
|
+
if (it != numToStrMap.end() && !(numToStrMap.key_comp()(n, it->first)))
|
|
863
|
+
{
|
|
864
|
+
return it->second.c_str();
|
|
865
|
+
}
|
|
866
|
+
return numToStrMap.emplace_hint(it, n, std::to_string(n))->second.c_str();
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
SVFIRWriter::autoCStr SVFIRWriter::generateJsonString()
|
|
870
|
+
{
|
|
871
|
+
autoJSON object = generateJson();
|
|
872
|
+
char* str = humanReadableOption() ? cJSON_Print(object.get())
|
|
873
|
+
: cJSON_PrintUnformatted(object.get());
|
|
874
|
+
return {str, cJSON_free};
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
SVFIRWriter::autoJSON SVFIRWriter::generateJson()
|
|
878
|
+
{
|
|
879
|
+
cJSON* root = jsonCreateObject();
|
|
880
|
+
|
|
881
|
+
#define F(field) JSON_WRITE_FIELD(root, svfIR, field)
|
|
882
|
+
F(icfgNode2SVFStmtsMap);
|
|
883
|
+
F(icfgNode2PTASVFStmtsMap);
|
|
884
|
+
F(GepValObjMap);
|
|
885
|
+
F(GepObjVarMap);
|
|
886
|
+
F(memToFieldsMap);
|
|
887
|
+
F(globSVFStmtSet);
|
|
888
|
+
F(phiNodeMap);
|
|
889
|
+
F(funArgsListMap);
|
|
890
|
+
F(callSiteArgsListMap);
|
|
891
|
+
F(callSiteRetMap);
|
|
892
|
+
F(funRetMap);
|
|
893
|
+
F(indCallSiteToFunPtrMap);
|
|
894
|
+
F(funPtrToCallSitesMap);
|
|
895
|
+
F(candidatePointers);
|
|
896
|
+
F(icfg);
|
|
897
|
+
F(chgraph);
|
|
898
|
+
F(callSiteSet);
|
|
899
|
+
|
|
900
|
+
F(svfModule); // Keep this last one
|
|
901
|
+
#undef F
|
|
902
|
+
|
|
903
|
+
return {root, cJSON_Delete};
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
cJSON* SVFIRWriter::toJson(const SVFType* type)
|
|
907
|
+
{
|
|
908
|
+
return jsonCreateIndex(svfModuleWriter.getSvfTypeID(type));
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
cJSON* SVFIRWriter::toJson(const SVFValue* value)
|
|
912
|
+
{
|
|
913
|
+
return jsonCreateIndex(svfModuleWriter.getSvfValueID(value));
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
cJSON* SVFIRWriter::toJson(const IRGraph* graph)
|
|
917
|
+
{
|
|
918
|
+
ENSURE_NOT_VISITED(graph);
|
|
919
|
+
|
|
920
|
+
cJSON* root = genericGraphToJson(graph, irGraphWriter.edgePool.getPool());
|
|
921
|
+
#define F(field) JSON_WRITE_FIELD(root, graph, field)
|
|
922
|
+
F(KindToSVFStmtSetMap);
|
|
923
|
+
F(KindToPTASVFStmtSetMap);
|
|
924
|
+
F(fromFile);
|
|
925
|
+
F(nodeNumAfterPAGBuild);
|
|
926
|
+
F(totalPTAPAGEdge);
|
|
927
|
+
F(valueToEdgeMap);
|
|
928
|
+
jsonAddContentToObject(root, "symInfo", graph->symInfo);
|
|
929
|
+
#undef F
|
|
930
|
+
return root;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
cJSON* SVFIRWriter::toJson(const SVFVar* var)
|
|
934
|
+
{
|
|
935
|
+
return var ? jsonCreateIndex(irGraphWriter.getNodeID(var))
|
|
936
|
+
: jsonCreateNullId();
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
cJSON* SVFIRWriter::toJson(const SVFStmt* stmt)
|
|
940
|
+
{
|
|
941
|
+
return jsonCreateIndex(irGraphWriter.getEdgeID(stmt));
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
cJSON* SVFIRWriter::toJson(const ICFG* icfg)
|
|
945
|
+
{
|
|
946
|
+
cJSON* root = genericGraphToJson(icfg, icfgWriter.edgePool.getPool());
|
|
947
|
+
|
|
948
|
+
#define F(field) JSON_WRITE_FIELD(root, icfg, field)
|
|
949
|
+
F(FunToFunEntryNodeMap);
|
|
950
|
+
F(FunToFunExitNodeMap);
|
|
951
|
+
F(CSToCallNodeMap);
|
|
952
|
+
F(CSToRetNodeMap);
|
|
953
|
+
F(InstToBlockNodeMap);
|
|
954
|
+
F(globalBlockNode);
|
|
955
|
+
F(icfgNodeToSVFLoopVec);
|
|
956
|
+
#undef F
|
|
957
|
+
return root;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
cJSON* SVFIRWriter::toJson(const ICFGNode* node)
|
|
961
|
+
{
|
|
962
|
+
return jsonCreateIndex(icfgWriter.getNodeID(node));
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
cJSON* SVFIRWriter::toJson(const ICFGEdge* edge)
|
|
966
|
+
{
|
|
967
|
+
return jsonCreateIndex(icfgWriter.getEdgeID(edge));
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
cJSON* SVFIRWriter::toJson(const CommonCHGraph* graph)
|
|
971
|
+
{
|
|
972
|
+
auto chg = SVFUtil::dyn_cast<CHGraph>(graph);
|
|
973
|
+
assert(chg && "Unsupported CHGraph type!");
|
|
974
|
+
return toJson(chg);
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
cJSON* SVFIRWriter::toJson(const CHGraph* graph)
|
|
978
|
+
{
|
|
979
|
+
cJSON* root = genericGraphToJson(graph, chgWriter.edgePool.getPool());
|
|
980
|
+
#define F(field) JSON_WRITE_FIELD(root, graph, field)
|
|
981
|
+
// TODO: Ensure svfMod is the same as the SVFIR's?
|
|
982
|
+
F(classNum);
|
|
983
|
+
F(vfID);
|
|
984
|
+
// F(buildingCHGTime); No need
|
|
985
|
+
F(classNameToNodeMap);
|
|
986
|
+
F(classNameToDescendantsMap);
|
|
987
|
+
F(classNameToAncestorsMap);
|
|
988
|
+
F(classNameToInstAndDescsMap);
|
|
989
|
+
F(templateNameToInstancesMap);
|
|
990
|
+
F(csToClassesMap);
|
|
991
|
+
F(virtualFunctionToIDMap);
|
|
992
|
+
F(csToCHAVtblsMap);
|
|
993
|
+
F(csToCHAVFnsMap);
|
|
994
|
+
#undef F
|
|
995
|
+
return root;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
cJSON* SVFIRWriter::toJson(const CHNode* node)
|
|
999
|
+
{
|
|
1000
|
+
return jsonCreateIndex(chgWriter.getNodeID(node));
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
cJSON* SVFIRWriter::toJson(const CHEdge* edge)
|
|
1004
|
+
{
|
|
1005
|
+
return jsonCreateIndex(chgWriter.getEdgeID(edge));
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
cJSON* SVFIRWriter::toJson(const CallSite& cs)
|
|
1009
|
+
{
|
|
1010
|
+
return toJson(cs.getInstruction());
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
cJSON* SVFIRWriter::toJson(const SVFLoop* loop)
|
|
1014
|
+
{
|
|
1015
|
+
return jsonCreateIndex(icfgWriter.getSvfLoopID(loop));
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
cJSON* SVFIRWriter::contentToJson(const MemObj* memObj)
|
|
1019
|
+
{
|
|
1020
|
+
cJSON* root = jsonCreateObject();
|
|
1021
|
+
JSON_WRITE_FIELD(root, memObj, typeInfo); // Owns this pointer
|
|
1022
|
+
JSON_WRITE_FIELD(root, memObj, refVal);
|
|
1023
|
+
JSON_WRITE_FIELD(root, memObj, symId);
|
|
1024
|
+
return root;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
cJSON* SVFIRWriter::toJson(const ObjTypeInfo* objTypeInfo)
|
|
1028
|
+
{
|
|
1029
|
+
ENSURE_NOT_VISITED(objTypeInfo);
|
|
1030
|
+
|
|
1031
|
+
cJSON* root = jsonCreateObject();
|
|
1032
|
+
JSON_WRITE_FIELD(root, objTypeInfo, type);
|
|
1033
|
+
JSON_WRITE_FIELD(root, objTypeInfo, flags);
|
|
1034
|
+
JSON_WRITE_FIELD(root, objTypeInfo, maxOffsetLimit);
|
|
1035
|
+
JSON_WRITE_FIELD(root, objTypeInfo, elemNum);
|
|
1036
|
+
JSON_WRITE_FIELD(root, objTypeInfo, type);
|
|
1037
|
+
JSON_WRITE_FIELD(root, objTypeInfo, flags);
|
|
1038
|
+
JSON_WRITE_FIELD(root, objTypeInfo, maxOffsetLimit);
|
|
1039
|
+
JSON_WRITE_FIELD(root, objTypeInfo, elemNum);
|
|
1040
|
+
return root;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
cJSON* SVFIRWriter::toJson(const MemObj* memObj)
|
|
1044
|
+
{
|
|
1045
|
+
return jsonCreateIndex(symbolTableInfoWriter.getMemObjID(memObj));
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
cJSON* SVFIRWriter::toJson(const SVFLoopAndDomInfo* ldInfo)
|
|
1049
|
+
{
|
|
1050
|
+
ENSURE_NOT_VISITED(ldInfo);
|
|
1051
|
+
|
|
1052
|
+
cJSON* root = jsonCreateObject();
|
|
1053
|
+
JSON_WRITE_FIELD(root, ldInfo, reachableBBs);
|
|
1054
|
+
JSON_WRITE_FIELD(root, ldInfo, dtBBsMap);
|
|
1055
|
+
JSON_WRITE_FIELD(root, ldInfo, pdtBBsMap);
|
|
1056
|
+
JSON_WRITE_FIELD(root, ldInfo, dfBBsMap);
|
|
1057
|
+
JSON_WRITE_FIELD(root, ldInfo, bb2LoopMap);
|
|
1058
|
+
return root;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
cJSON* SVFIRWriter::toJson(const StInfo* type)
|
|
1062
|
+
{
|
|
1063
|
+
ENSURE_NOT_VISITED(type);
|
|
1064
|
+
|
|
1065
|
+
cJSON* root = jsonCreateObject();
|
|
1066
|
+
#define F(field) JSON_WRITE_FIELD(root, type, field)
|
|
1067
|
+
F(fldIdxVec);
|
|
1068
|
+
F(elemIdxVec);
|
|
1069
|
+
F(fldIdx2TypeMap);
|
|
1070
|
+
F(finfo);
|
|
1071
|
+
F(stride);
|
|
1072
|
+
F(numOfFlattenElements);
|
|
1073
|
+
F(flattenElementTypes);
|
|
1074
|
+
#undef F
|
|
1075
|
+
return root;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
cJSON* SVFIRWriter::toJson(const LocationSet& ls)
|
|
1079
|
+
{
|
|
1080
|
+
cJSON* root = jsonCreateObject();
|
|
1081
|
+
JSON_WRITE_FIELD(root, &ls, fldIdx);
|
|
1082
|
+
JSON_WRITE_FIELD(root, &ls, offsetVarAndGepTypePairs);
|
|
1083
|
+
return root;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
cJSON* SVFIRWriter::toJson(const SVFModule* module)
|
|
1087
|
+
{
|
|
1088
|
+
cJSON* root = jsonCreateObject();
|
|
1089
|
+
|
|
1090
|
+
JSON_WRITE_FIELD(root, module, pagReadFromTxt);
|
|
1091
|
+
JSON_WRITE_FIELD(root, module, moduleIdentifier);
|
|
1092
|
+
|
|
1093
|
+
JSON_WRITE_FIELD(root, module, FunctionSet);
|
|
1094
|
+
JSON_WRITE_FIELD(root, module, GlobalSet);
|
|
1095
|
+
JSON_WRITE_FIELD(root, module, AliasSet);
|
|
1096
|
+
JSON_WRITE_FIELD(root, module, ConstantSet);
|
|
1097
|
+
JSON_WRITE_FIELD(root, module, OtherValueSet);
|
|
1098
|
+
|
|
1099
|
+
cJSON* values = jsonCreateArray();
|
|
1100
|
+
for (size_t i = 1; i <= svfModuleWriter.svfValuePool.size(); ++i)
|
|
1101
|
+
{
|
|
1102
|
+
cJSON* value = toJson(svfModuleWriter.svfValuePool.getPtr(i));
|
|
1103
|
+
jsonAddItemToArray(values, value);
|
|
1104
|
+
}
|
|
1105
|
+
jsonAddItemToObject(root, "values", values);
|
|
1106
|
+
|
|
1107
|
+
cJSON* types = jsonCreateArray();
|
|
1108
|
+
for (size_t i = 1; i <= svfModuleWriter.svfTypePool.size(); ++i)
|
|
1109
|
+
{
|
|
1110
|
+
cJSON* type = toJson(svfModuleWriter.svfTypePool.getPtr(i));
|
|
1111
|
+
jsonAddItemToArray(types, type);
|
|
1112
|
+
}
|
|
1113
|
+
jsonAddItemToObject(root, "types", types);
|
|
1114
|
+
|
|
1115
|
+
return root;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
} // namespace SVF
|