svf-tools 1.0.702 → 1.0.704
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/package.json +1 -1
- package/svf/include/SVFIR/{SVFIRRW.h → SVFFileSystem.h} +43 -12
- package/svf/include/SVFIR/SVFIR.h +13 -0
- package/svf/include/SVFIR/SVFModule.h +0 -4
- package/svf/include/SVFIR/SVFType.h +0 -8
- package/svf/include/SVFIR/SVFValue.h +0 -34
- package/svf/include/Util/ExtAPI.h +3 -0
- package/svf/include/Util/ExtAPI.json +0 -7
- package/svf/include/Util/NodeIDAllocator.h +3 -0
- package/svf/include/Util/SVFUtil.h +6 -0
- package/svf/lib/SVFIR/{SVFIRRW.cpp → SVFFileSystem.cpp} +54 -8
- package/svf/lib/SVFIR/SVFModule.cpp +0 -7
- package/svf/lib/Util/ExtAPI.cpp +7 -0
- package/svf-llvm/include/SVF-LLVM/SVFIRBuilder.h +5 -4
- package/svf-llvm/lib/LLVMModule.cpp +0 -1
- package/svf-llvm/lib/SVFIRBuilder.cpp +129 -84
- package/svf-llvm/tools/LLVM2SVF/llvm2svf.cpp +1 -1
- package/svf-llvm/tools/WPA/wpa.cpp +1 -1
- package/svf/include/SVFIR/SVFModuleRW.h +0 -197
- package/svf/lib/SVFIR/SVFModuleRW.cpp +0 -1206
|
@@ -1,1206 +0,0 @@
|
|
|
1
|
-
#include "SVFIR/SVFModuleRW.h"
|
|
2
|
-
#include "SVFIR/SVFModule.h"
|
|
3
|
-
#include "Util/SVFUtil.h"
|
|
4
|
-
#include "Util/cJSON.h"
|
|
5
|
-
#include <fstream>
|
|
6
|
-
#include <sys/fcntl.h>
|
|
7
|
-
#include <sys/mman.h>
|
|
8
|
-
#include <sys/stat.h>
|
|
9
|
-
#include <sys/types.h>
|
|
10
|
-
#include <unistd.h>
|
|
11
|
-
|
|
12
|
-
using namespace SVF;
|
|
13
|
-
|
|
14
|
-
/// @brief Helper function to create a new empty SVFType instance
|
|
15
|
-
static SVFType* createType(SVFType::SVFTyKind kind);
|
|
16
|
-
/// @brief Helper function to create a new empty SVFValue instance
|
|
17
|
-
static SVFValue* createValue(SVFValue::SVFValKind kind);
|
|
18
|
-
|
|
19
|
-
#define ABORT_IFNOT(condition, reason) \
|
|
20
|
-
do \
|
|
21
|
-
{ \
|
|
22
|
-
if (!(condition)) \
|
|
23
|
-
{ \
|
|
24
|
-
SVFUtil::errs() \
|
|
25
|
-
<< __FILE__ << ":" << __LINE__ << ": " << reason << "\n"; \
|
|
26
|
-
abort(); \
|
|
27
|
-
} \
|
|
28
|
-
} while (0)
|
|
29
|
-
|
|
30
|
-
/// Create a bool cJSON node, with bool value `objptr->field` and string name
|
|
31
|
-
/// #field, then attach it to the root cJSON node.
|
|
32
|
-
#define JSON_DUMP_BOOL(root, objptr, field) \
|
|
33
|
-
do \
|
|
34
|
-
{ \
|
|
35
|
-
cJSON* node_##field = cJSON_CreateBool((objptr)->field); \
|
|
36
|
-
cJSON_AddItemToObjectCS((root), #field, node_##field); \
|
|
37
|
-
} while (0)
|
|
38
|
-
|
|
39
|
-
/// Create a number cJSON node, with number `objptr->field` and string name
|
|
40
|
-
/// #field, then attach it to the root cJSON node.
|
|
41
|
-
#define JSON_DUMP_NUMBER(root, objptr, field) \
|
|
42
|
-
do \
|
|
43
|
-
{ \
|
|
44
|
-
cJSON* node_##field = cJSON_CreateNumber((objptr)->field); \
|
|
45
|
-
cJSON_AddItemToObjectCS((root), #field, node_##field); \
|
|
46
|
-
} while (0)
|
|
47
|
-
|
|
48
|
-
/// Get the string representation of the index of a SVFType pointer in the
|
|
49
|
-
/// SVFType pool (represeted by `typePool`), create a string cJSON node of it,
|
|
50
|
-
/// then attach it to the `root` cJSON node.
|
|
51
|
-
#define JSON_DUMP_SVFTYPE(root, objptr, field) \
|
|
52
|
-
do \
|
|
53
|
-
{ \
|
|
54
|
-
const char* _strIdx = getStrTypeIndex((objptr)->field); \
|
|
55
|
-
cJSON* node_##field = cJSON_CreateStringReference(_strIdx); \
|
|
56
|
-
cJSON_AddItemToObjectCS((root), #field, node_##field); \
|
|
57
|
-
} while (0)
|
|
58
|
-
|
|
59
|
-
/// Get the string representation of the index of a SVFValue pointer in the
|
|
60
|
-
/// SVFType pool (represeted by `valuePool`), create a string cJSON node of it,
|
|
61
|
-
/// then attach it to the `root` cJSON node.
|
|
62
|
-
#define JSON_DUMP_SVFVALUE(root, objptr, field) \
|
|
63
|
-
do \
|
|
64
|
-
{ \
|
|
65
|
-
const char* _strIdx = getStrValueIndex((objptr)->field); \
|
|
66
|
-
cJSON* node_##field = cJSON_CreateStringReference(_strIdx); \
|
|
67
|
-
cJSON_AddItemToObjectCS((root), #field, node_##field); \
|
|
68
|
-
} while (0)
|
|
69
|
-
|
|
70
|
-
/// Create a string cJSON node with value `objptr->field.c_str()` and name
|
|
71
|
-
/// #field, then attach it to the `root` cJSON node.
|
|
72
|
-
#define JSON_DUMP_STRING(root, objptr, field) \
|
|
73
|
-
do \
|
|
74
|
-
{ \
|
|
75
|
-
const char* _str = (objptr)->field.c_str(); \
|
|
76
|
-
cJSON* node_##field = cJSON_CreateStringReference(_str); \
|
|
77
|
-
cJSON_AddItemToObjectCS((root), #field, node_##field); \
|
|
78
|
-
} while (0)
|
|
79
|
-
|
|
80
|
-
/// Create a cJSON array with name #field and contents in `obj->field` where
|
|
81
|
-
/// each element is a SVFValue pointer, and then attach it to the `root` cJSON
|
|
82
|
-
/// node.
|
|
83
|
-
#define JSON_DUMP_CONTAINER_OF_SVFVALUE(root, obj, field) \
|
|
84
|
-
do \
|
|
85
|
-
{ \
|
|
86
|
-
cJSON* node_##field = cJSON_CreateArray(); \
|
|
87
|
-
for (const auto val : (obj)->field) \
|
|
88
|
-
cJSON_AddItemToArray(node_##field, cJSON_CreateStringReference( \
|
|
89
|
-
getStrValueIndex(val))); \
|
|
90
|
-
cJSON_AddItemToObjectCS((root), #field, node_##field); \
|
|
91
|
-
} while (0)
|
|
92
|
-
|
|
93
|
-
/// Create a cJSON array with name #field and contents in `obj->field` where
|
|
94
|
-
/// each element is a SVFType pointer, and then attach it to the `root` cJSON
|
|
95
|
-
/// node.
|
|
96
|
-
#define JSON_DUMP_CONTAINER_OF_SVFTYPE(root, obj, field) \
|
|
97
|
-
do \
|
|
98
|
-
{ \
|
|
99
|
-
cJSON* node_##field = cJSON_CreateArray(); \
|
|
100
|
-
for (const auto ty : (obj)->field) \
|
|
101
|
-
cJSON_AddItemToArray(node_##field, cJSON_CreateStringReference( \
|
|
102
|
-
getStrTypeIndex(ty))); \
|
|
103
|
-
cJSON_AddItemToObjectCS((root), #field, node_##field); \
|
|
104
|
-
} while (0)
|
|
105
|
-
|
|
106
|
-
/// Create a cJSON array with name #field and contents in `obj->field` where
|
|
107
|
-
/// each element is a number, and then attach it to the `root` cJSON node.
|
|
108
|
-
#define JSON_DUMP_CONTAINER_OF_NUMBER(root, obj, field) \
|
|
109
|
-
do \
|
|
110
|
-
{ \
|
|
111
|
-
cJSON* node_##field = cJSON_CreateArray(); \
|
|
112
|
-
for (const auto num : (obj)->field) \
|
|
113
|
-
cJSON_AddItemToArray(node_##field, cJSON_CreateNumber(num)); \
|
|
114
|
-
cJSON_AddItemToObjectCS((root), #field, node_##field); \
|
|
115
|
-
} while (0)
|
|
116
|
-
|
|
117
|
-
SVFModuleWrite::SVFModuleWrite(const SVFModule* module)
|
|
118
|
-
: module(module), jsonStr(nullptr)
|
|
119
|
-
{
|
|
120
|
-
const std::size_t reserveSize =
|
|
121
|
-
module->getFunctionSet().size() + module->getGlobalSet().size() +
|
|
122
|
-
module->getAliasSet().size() + module->getConstantSet().size() +
|
|
123
|
-
module->getConstantSet().size() +
|
|
124
|
-
module->getOtherValueSet().size(); // Estimated size
|
|
125
|
-
|
|
126
|
-
typePool.reserve(reserveSize);
|
|
127
|
-
valuePool.reserve(reserveSize);
|
|
128
|
-
allIndices.reserve(1000);
|
|
129
|
-
getStrOfIndex(0);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
SVFModuleWrite::SVFModuleWrite(const SVFModule* module, const std::string& path)
|
|
133
|
-
: SVFModuleWrite(module)
|
|
134
|
-
{
|
|
135
|
-
dumpJsonToPath(path);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
SVFModuleWrite::~SVFModuleWrite()
|
|
139
|
-
{
|
|
140
|
-
if (jsonStr)
|
|
141
|
-
{
|
|
142
|
-
cJSON_free((void*)jsonStr);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
void SVFModuleWrite::dumpJsonToPath(const std::string& path)
|
|
147
|
-
{
|
|
148
|
-
std::ofstream jsonFile(path);
|
|
149
|
-
if (jsonFile.is_open())
|
|
150
|
-
{
|
|
151
|
-
dumpJsonToOstream(jsonFile);
|
|
152
|
-
jsonFile.close();
|
|
153
|
-
}
|
|
154
|
-
else
|
|
155
|
-
{
|
|
156
|
-
SVFUtil::errs() << "Failed to open '" << path
|
|
157
|
-
<< "' to dump SVFModule\n";
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
void SVFModuleWrite::dumpJsonToOstream(std::ostream& os)
|
|
162
|
-
{
|
|
163
|
-
if (!jsonStr)
|
|
164
|
-
{
|
|
165
|
-
cJSON* json = moduleToJson(module);
|
|
166
|
-
jsonStr = cJSON_PrintUnformatted(json);
|
|
167
|
-
cJSON_Delete(json);
|
|
168
|
-
}
|
|
169
|
-
os << jsonStr << std::endl;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
TypeIndex SVFModuleWrite::getTypeIndex(const SVFType* type)
|
|
173
|
-
{
|
|
174
|
-
if (type == nullptr)
|
|
175
|
-
return 0;
|
|
176
|
-
auto pair = typeToIndex.emplace(type, 1 + typePool.size());
|
|
177
|
-
if (pair.second)
|
|
178
|
-
{
|
|
179
|
-
// This SVFType pointer was NOT recorded before. It gets inserted.
|
|
180
|
-
typePool.push_back(type);
|
|
181
|
-
}
|
|
182
|
-
return pair.first->second;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
ValueIndex SVFModuleWrite::getValueIndex(const SVFValue* value)
|
|
186
|
-
{
|
|
187
|
-
if (value == nullptr)
|
|
188
|
-
return 0;
|
|
189
|
-
auto pair = valueToIndex.emplace(value, 1 + valuePool.size());
|
|
190
|
-
if (pair.second)
|
|
191
|
-
{
|
|
192
|
-
// The SVFValue pointer was NOT recorded before. It gets inserted.
|
|
193
|
-
valuePool.push_back(value);
|
|
194
|
-
}
|
|
195
|
-
return pair.first->second;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const char* SVFModuleWrite::getStrOfIndex(std::size_t index)
|
|
199
|
-
{
|
|
200
|
-
// Invariant: forall i: allIndices[i] == hex(i) /\ len(allIndices) == N
|
|
201
|
-
for (std::size_t i = allIndices.size(); i <= index; ++i)
|
|
202
|
-
{
|
|
203
|
-
allIndices.emplace_back(
|
|
204
|
-
std::make_unique<std::string>(std::to_string(i)));
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return allIndices[index]->c_str();
|
|
208
|
-
// Postcondition: ensures len(allIndices) >= index + 1
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const char* SVFModuleWrite::getStrValueIndex(const SVFValue* value)
|
|
212
|
-
{
|
|
213
|
-
return getStrOfIndex(getValueIndex(value));
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const char* SVFModuleWrite::getStrTypeIndex(const SVFType* type)
|
|
217
|
-
{
|
|
218
|
-
return getStrOfIndex(getTypeIndex(type));
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
cJSON* SVFModuleWrite::moduleToJson(const SVFModule* module)
|
|
222
|
-
{
|
|
223
|
-
// Top-level json creation
|
|
224
|
-
cJSON* root = cJSON_CreateObject();
|
|
225
|
-
|
|
226
|
-
cJSON* nodeAllTypes = cJSON_CreateArray();
|
|
227
|
-
cJSON_AddItemToObjectCS(root, "typePool", nodeAllTypes);
|
|
228
|
-
cJSON* nodeAllValues = cJSON_CreateArray();
|
|
229
|
-
cJSON_AddItemToObjectCS(root, "valuePool", nodeAllValues);
|
|
230
|
-
|
|
231
|
-
JSON_DUMP_STRING(root, module, pagReadFromTxt);
|
|
232
|
-
JSON_DUMP_STRING(root, module, moduleIdentifier);
|
|
233
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, module, FunctionSet);
|
|
234
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, module, GlobalSet);
|
|
235
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, module, AliasSet);
|
|
236
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, module, ConstantSet);
|
|
237
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, module, OtherValueSet);
|
|
238
|
-
|
|
239
|
-
// N.B. Be sure to use index-based loop instead of iterater based loop
|
|
240
|
-
// (including range-based loop). Because all `toJson()` functions may append
|
|
241
|
-
// new elements to the end of the vectors and the vector buffer might get
|
|
242
|
-
// reallocated, thus invalidating all old iterators.
|
|
243
|
-
for (size_t i = 0; i < valuePool.size(); ++i)
|
|
244
|
-
{
|
|
245
|
-
cJSON* nodeVal = valueToJson(valuePool[i]);
|
|
246
|
-
cJSON_AddItemToArray(nodeAllValues, nodeVal);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
for (size_t i = 0; i < typePool.size(); ++i)
|
|
250
|
-
{
|
|
251
|
-
cJSON* nodeType = typeToJson(typePool[i]);
|
|
252
|
-
cJSON_AddItemToArray(nodeAllTypes, nodeType);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return root;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
cJSON* SVFModuleWrite::toJson(const StInfo* stInfo)
|
|
259
|
-
{
|
|
260
|
-
cJSON* root = cJSON_CreateObject();
|
|
261
|
-
|
|
262
|
-
JSON_DUMP_CONTAINER_OF_NUMBER(root, stInfo, fldIdxVec);
|
|
263
|
-
JSON_DUMP_CONTAINER_OF_NUMBER(root, stInfo, elemIdxVec);
|
|
264
|
-
|
|
265
|
-
cJSON* nodeFldMap = cJSON_CreateObject();
|
|
266
|
-
for (const auto& pair : stInfo->fldIdx2TypeMap)
|
|
267
|
-
{
|
|
268
|
-
const char* key = getStrOfIndex(pair.first);
|
|
269
|
-
cJSON* ty = cJSON_CreateStringReference(getStrTypeIndex(pair.second));
|
|
270
|
-
cJSON_AddItemToObjectCS(nodeFldMap, key, ty);
|
|
271
|
-
}
|
|
272
|
-
cJSON_AddItemToObjectCS(root, "fldIdx2TypeMap", nodeFldMap);
|
|
273
|
-
|
|
274
|
-
JSON_DUMP_CONTAINER_OF_SVFTYPE(root, stInfo, finfo);
|
|
275
|
-
JSON_DUMP_NUMBER(root, stInfo, stride);
|
|
276
|
-
JSON_DUMP_NUMBER(root, stInfo, numOfFlattenElements);
|
|
277
|
-
JSON_DUMP_NUMBER(root, stInfo, numOfFlattenFields);
|
|
278
|
-
JSON_DUMP_CONTAINER_OF_SVFTYPE(root, stInfo, flattenElementTypes);
|
|
279
|
-
|
|
280
|
-
return root;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
cJSON* SVFModuleWrite::toJson(const SVFType* type)
|
|
284
|
-
{
|
|
285
|
-
cJSON* root = cJSON_CreateObject();
|
|
286
|
-
|
|
287
|
-
JSON_DUMP_NUMBER(root, type, kind);
|
|
288
|
-
JSON_DUMP_SVFTYPE(root, type, getPointerToTy);
|
|
289
|
-
|
|
290
|
-
cJSON* nodeTypeInfo = toJson(type->typeinfo);
|
|
291
|
-
cJSON_AddItemToObjectCS(root, "typeinfo", nodeTypeInfo);
|
|
292
|
-
|
|
293
|
-
JSON_DUMP_BOOL(root, type, isSingleValTy);
|
|
294
|
-
|
|
295
|
-
return root;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
cJSON* SVFModuleWrite::toJson(const SVFPointerType* type)
|
|
299
|
-
{
|
|
300
|
-
cJSON* root = toJson(static_cast<const SVFType*>(type));
|
|
301
|
-
JSON_DUMP_SVFTYPE(root, type, ptrElementType);
|
|
302
|
-
return root;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
cJSON* SVFModuleWrite::toJson(const SVFIntegerType* type)
|
|
306
|
-
{
|
|
307
|
-
return toJson(static_cast<const SVFType*>(type));
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
cJSON* SVFModuleWrite::toJson(const SVFFunctionType* type)
|
|
311
|
-
{
|
|
312
|
-
cJSON* root = toJson(static_cast<const SVFType*>(type));
|
|
313
|
-
JSON_DUMP_SVFTYPE(root, type, retTy);
|
|
314
|
-
return root;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
cJSON* SVFModuleWrite::toJson(const SVFStructType* type)
|
|
318
|
-
{
|
|
319
|
-
return toJson(static_cast<const SVFType*>(type));
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
cJSON* SVFModuleWrite::toJson(const SVFArrayType* type)
|
|
323
|
-
{
|
|
324
|
-
return toJson(static_cast<const SVFType*>(type));
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
cJSON* SVFModuleWrite::toJson(const SVFOtherType* type)
|
|
328
|
-
{
|
|
329
|
-
return toJson(static_cast<const SVFType*>(type));
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
cJSON* SVFModuleWrite::typeToJson(const SVFType* type)
|
|
333
|
-
{
|
|
334
|
-
using SVFUtil::dyn_cast;
|
|
335
|
-
auto kind = type->getKind();
|
|
336
|
-
|
|
337
|
-
switch (kind)
|
|
338
|
-
{
|
|
339
|
-
default:
|
|
340
|
-
SVFUtil::errs() << "Impossible SVFType kind " << kind
|
|
341
|
-
<< " in typeToJson()\n";
|
|
342
|
-
assert(false);
|
|
343
|
-
|
|
344
|
-
#define CASE(Kind) \
|
|
345
|
-
case SVFType::Kind: \
|
|
346
|
-
return toJson(SVFUtil::dyn_cast<Kind##pe>(type));
|
|
347
|
-
|
|
348
|
-
CASE(SVFTy);
|
|
349
|
-
CASE(SVFPointerTy);
|
|
350
|
-
CASE(SVFIntegerTy);
|
|
351
|
-
CASE(SVFFunctionTy);
|
|
352
|
-
CASE(SVFStructTy);
|
|
353
|
-
CASE(SVFArrayTy);
|
|
354
|
-
CASE(SVFOtherTy);
|
|
355
|
-
#undef CASE
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
cJSON* SVFModuleWrite::toJson(const SVFLoopAndDomInfo* ldInfo)
|
|
360
|
-
{
|
|
361
|
-
cJSON* root = cJSON_CreateObject();
|
|
362
|
-
|
|
363
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, ldInfo, reachableBBs);
|
|
364
|
-
|
|
365
|
-
#define JSON_DUMP_BB_MAP(field) \
|
|
366
|
-
do \
|
|
367
|
-
{ \
|
|
368
|
-
cJSON* node_##field = cJSON_CreateObject(); \
|
|
369
|
-
for (const auto& BB2BBs : (ldInfo)->field) \
|
|
370
|
-
{ \
|
|
371
|
-
cJSON* nodeBBs = cJSON_CreateArray(); \
|
|
372
|
-
for (const SVFBasicBlock* bb : BB2BBs.second) \
|
|
373
|
-
cJSON_AddItemToArray(nodeBBs, cJSON_CreateStringReference( \
|
|
374
|
-
getStrValueIndex(bb))); \
|
|
375
|
-
cJSON_AddItemToObjectCS(node_##field, \
|
|
376
|
-
getStrValueIndex(BB2BBs.first), nodeBBs); \
|
|
377
|
-
} \
|
|
378
|
-
cJSON_AddItemToObjectCS(root, #field, node_##field); \
|
|
379
|
-
} while (0)
|
|
380
|
-
JSON_DUMP_BB_MAP(dtBBsMap);
|
|
381
|
-
JSON_DUMP_BB_MAP(pdtBBsMap);
|
|
382
|
-
JSON_DUMP_BB_MAP(dfBBsMap);
|
|
383
|
-
JSON_DUMP_BB_MAP(bb2LoopMap);
|
|
384
|
-
#undef BB_MAP_TO_JSON
|
|
385
|
-
|
|
386
|
-
return root;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
cJSON* SVFModuleWrite::toJson(const SVFValue* value)
|
|
390
|
-
{
|
|
391
|
-
cJSON* root = cJSON_CreateObject();
|
|
392
|
-
JSON_DUMP_NUMBER(root, value, kind);
|
|
393
|
-
JSON_DUMP_BOOL(root, value, ptrInUncalledFun);
|
|
394
|
-
JSON_DUMP_BOOL(root, value, constDataOrAggData);
|
|
395
|
-
JSON_DUMP_SVFTYPE(root, value, type);
|
|
396
|
-
JSON_DUMP_STRING(root, value, name);
|
|
397
|
-
JSON_DUMP_STRING(root, value, sourceLoc);
|
|
398
|
-
return root;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
cJSON* SVFModuleWrite::toJson(const SVFFunction* value)
|
|
402
|
-
{
|
|
403
|
-
cJSON* root = toJson(static_cast<const SVFValue*>(value));
|
|
404
|
-
|
|
405
|
-
// isDecl
|
|
406
|
-
JSON_DUMP_BOOL(root, value, isDecl);
|
|
407
|
-
// intrinsic
|
|
408
|
-
JSON_DUMP_BOOL(root, value, intrinsic);
|
|
409
|
-
// addrTaken
|
|
410
|
-
JSON_DUMP_BOOL(root, value, addrTaken);
|
|
411
|
-
// isUncalled
|
|
412
|
-
JSON_DUMP_BOOL(root, value, isUncalled);
|
|
413
|
-
// isNotRet
|
|
414
|
-
JSON_DUMP_BOOL(root, value, isNotRet);
|
|
415
|
-
// varArg
|
|
416
|
-
JSON_DUMP_BOOL(root, value, varArg);
|
|
417
|
-
// funcType
|
|
418
|
-
JSON_DUMP_SVFTYPE(root, value, funcType);
|
|
419
|
-
// loopAndDom
|
|
420
|
-
cJSON* nodeLD = toJson(value->loopAndDom);
|
|
421
|
-
cJSON_AddItemToObjectCS(root, "loopAndDom", nodeLD);
|
|
422
|
-
// realDefFun
|
|
423
|
-
JSON_DUMP_SVFVALUE(root, value, realDefFun);
|
|
424
|
-
// allBBs
|
|
425
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, value, allBBs);
|
|
426
|
-
// owns allArgs
|
|
427
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, value, allArgs);
|
|
428
|
-
|
|
429
|
-
return root;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
cJSON* SVFModuleWrite::toJson(const SVFBasicBlock* value)
|
|
433
|
-
{
|
|
434
|
-
cJSON* root = toJson(static_cast<const SVFValue*>(value));
|
|
435
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, value, allInsts);
|
|
436
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, value, succBBs);
|
|
437
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, value, predBBs);
|
|
438
|
-
JSON_DUMP_SVFVALUE(root, value, fun);
|
|
439
|
-
return root;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
cJSON* SVFModuleWrite::toJson(const SVFInstruction* value)
|
|
443
|
-
{
|
|
444
|
-
cJSON* root = toJson(static_cast<const SVFValue*>(value));
|
|
445
|
-
JSON_DUMP_SVFVALUE(root, value, bb);
|
|
446
|
-
JSON_DUMP_BOOL(root, value, terminator);
|
|
447
|
-
JSON_DUMP_BOOL(root, value, ret);
|
|
448
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, value, succInsts);
|
|
449
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, value, predInsts);
|
|
450
|
-
return root;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
cJSON* SVFModuleWrite::toJson(const SVFCallInst* value)
|
|
454
|
-
{
|
|
455
|
-
cJSON* root = toJson(static_cast<const SVFInstruction*>(value));
|
|
456
|
-
JSON_DUMP_CONTAINER_OF_SVFVALUE(root, value, args);
|
|
457
|
-
JSON_DUMP_BOOL(root, value, varArg);
|
|
458
|
-
JSON_DUMP_SVFVALUE(root, value, calledVal);
|
|
459
|
-
return root;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
cJSON* SVFModuleWrite::toJson(const SVFVirtualCallInst* value)
|
|
463
|
-
{
|
|
464
|
-
cJSON* root = toJson(static_cast<const SVFCallInst*>(value));
|
|
465
|
-
JSON_DUMP_SVFVALUE(root, value, vCallVtblPtr);
|
|
466
|
-
JSON_DUMP_NUMBER(root, value, virtualFunIdx);
|
|
467
|
-
JSON_DUMP_STRING(root, value, funNameOfVcall);
|
|
468
|
-
return root;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
cJSON* SVFModuleWrite::toJson(const SVFConstant* value)
|
|
472
|
-
{
|
|
473
|
-
return toJson(static_cast<const SVFValue*>(value));
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
cJSON* SVFModuleWrite::toJson(const SVFGlobalValue* value)
|
|
477
|
-
{
|
|
478
|
-
cJSON* root = toJson(static_cast<const SVFConstant*>(value));
|
|
479
|
-
JSON_DUMP_SVFVALUE(root, value, realDefGlobal);
|
|
480
|
-
return root;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
cJSON* SVFModuleWrite::toJson(const SVFArgument* value)
|
|
484
|
-
{
|
|
485
|
-
cJSON* root = toJson(static_cast<const SVFValue*>(value));
|
|
486
|
-
JSON_DUMP_SVFVALUE(root, value, fun);
|
|
487
|
-
JSON_DUMP_NUMBER(root, value, argNo);
|
|
488
|
-
JSON_DUMP_BOOL(root, value, uncalled);
|
|
489
|
-
return root;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
cJSON* SVFModuleWrite::toJson(const SVFConstantData* value)
|
|
493
|
-
{
|
|
494
|
-
return toJson(static_cast<const SVFConstant*>(value));
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
cJSON* SVFModuleWrite::toJson(const SVFConstantInt* value)
|
|
498
|
-
{
|
|
499
|
-
cJSON* root = toJson(static_cast<const SVFConstantData*>(value));
|
|
500
|
-
JSON_DUMP_NUMBER(root, value, zval);
|
|
501
|
-
JSON_DUMP_NUMBER(root, value, sval);
|
|
502
|
-
return root;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
cJSON* SVFModuleWrite::toJson(const SVFConstantFP* value)
|
|
506
|
-
{
|
|
507
|
-
cJSON* root = toJson(static_cast<const SVFConstantData*>(value));
|
|
508
|
-
JSON_DUMP_NUMBER(root, value, dval);
|
|
509
|
-
return root;
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
cJSON* SVFModuleWrite::toJson(const SVFConstantNullPtr* value)
|
|
513
|
-
{
|
|
514
|
-
return toJson(static_cast<const SVFConstantData*>(value));
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
cJSON* SVFModuleWrite::toJson(const SVFBlackHoleValue* value)
|
|
518
|
-
{
|
|
519
|
-
return toJson(static_cast<const SVFConstantData*>(value));
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
cJSON* SVFModuleWrite::toJson(const SVFOtherValue* value)
|
|
523
|
-
{
|
|
524
|
-
return toJson(static_cast<const SVFValue*>(value));
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
cJSON* SVFModuleWrite::toJson(const SVFMetadataAsValue* value)
|
|
528
|
-
{
|
|
529
|
-
return toJson(static_cast<const SVFOtherValue*>(value));
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
cJSON* SVFModuleWrite::valueToJson(const SVFValue* value)
|
|
533
|
-
{
|
|
534
|
-
using SVFUtil::dyn_cast;
|
|
535
|
-
auto kind = value->getKind();
|
|
536
|
-
|
|
537
|
-
switch (kind)
|
|
538
|
-
{
|
|
539
|
-
default:
|
|
540
|
-
SVFUtil::errs() << "Impossible SVFValue kind in" << kind
|
|
541
|
-
<< " in typeToJson()\n";
|
|
542
|
-
assert(false);
|
|
543
|
-
|
|
544
|
-
#define CASE(kind, type) \
|
|
545
|
-
case SVFValue::kind: \
|
|
546
|
-
return toJson(SVFUtil::dyn_cast<type>(value));
|
|
547
|
-
CASE(SVFVal, SVFValue);
|
|
548
|
-
CASE(SVFFunc, SVFFunction);
|
|
549
|
-
CASE(SVFBB, SVFBasicBlock);
|
|
550
|
-
CASE(SVFInst, SVFInstruction);
|
|
551
|
-
CASE(SVFCall, SVFCallInst);
|
|
552
|
-
CASE(SVFVCall, SVFVirtualCallInst);
|
|
553
|
-
CASE(SVFGlob, SVFGlobalValue);
|
|
554
|
-
CASE(SVFArg, SVFArgument);
|
|
555
|
-
CASE(SVFConst, SVFConstant);
|
|
556
|
-
CASE(SVFConstData, SVFConstantData);
|
|
557
|
-
CASE(SVFConstInt, SVFConstantInt);
|
|
558
|
-
CASE(SVFConstFP, SVFConstantFP);
|
|
559
|
-
CASE(SVFNullPtr, SVFConstantNullPtr);
|
|
560
|
-
CASE(SVFBlackHole, SVFBlackHoleValue);
|
|
561
|
-
CASE(SVFMetaAsValue, SVFMetadataAsValue);
|
|
562
|
-
CASE(SVFOther, SVFOtherValue);
|
|
563
|
-
#undef CASE
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
#define JSON_READ_VECTOR_OF_NUMBER(iter, obj, field) \
|
|
568
|
-
do \
|
|
569
|
-
{ \
|
|
570
|
-
ABORT_IFNOT( \
|
|
571
|
-
(cJSON_IsArray(iter) && !std::strcmp(#field, (iter)->string)), \
|
|
572
|
-
#field " expects `" #iter "` to be an array"); \
|
|
573
|
-
cJSON* _element; \
|
|
574
|
-
cJSON_ArrayForEach(_element, (iter)) \
|
|
575
|
-
{ \
|
|
576
|
-
ABORT_IFNOT(cJSON_IsNumber(_element), \
|
|
577
|
-
#field " expects numbers in object `" #iter "`"); \
|
|
578
|
-
using _T = decltype(obj->field)::value_type; \
|
|
579
|
-
(obj)->field.push_back(static_cast<_T>(_element->valuedouble)); \
|
|
580
|
-
} \
|
|
581
|
-
iter = (iter)->next; \
|
|
582
|
-
} while (0)
|
|
583
|
-
|
|
584
|
-
#define JSON_READ_VECTOR_OF_SVFREF(iter, obj, field, type) \
|
|
585
|
-
do \
|
|
586
|
-
{ \
|
|
587
|
-
ABORT_IFNOT( \
|
|
588
|
-
(cJSON_IsArray(iter) && !std::strcmp(#field, (iter)->string)), \
|
|
589
|
-
#field " expects `" #field "` to be an array"); \
|
|
590
|
-
cJSON* _element; \
|
|
591
|
-
cJSON_ArrayForEach(_element, (iter)) \
|
|
592
|
-
{ \
|
|
593
|
-
ABORT_IFNOT(cJSON_IsString(_element), \
|
|
594
|
-
#field " expects string indices in `" #iter "`"); \
|
|
595
|
-
SVF##type* _v = indexTo##type(std::atoi(_element->valuestring)); \
|
|
596
|
-
ABORT_IFNOT(_v, "Some index in `" #iter "` refers to NULL"); \
|
|
597
|
-
using _T = std::decay_t<decltype(*(obj)->field[0])>; \
|
|
598
|
-
_T* _t = SVFUtil::dyn_cast<_T>(_v); \
|
|
599
|
-
ABORT_IFNOT(_t, \
|
|
600
|
-
"dyn_cast from SVF" #type "* for " #field " failed"); \
|
|
601
|
-
(obj)->field.push_back(_t); \
|
|
602
|
-
} \
|
|
603
|
-
iter = (iter)->next; \
|
|
604
|
-
} while (0)
|
|
605
|
-
|
|
606
|
-
#define JSON_READ_VECTOR_OF_SVFVALUE(iter, obj, field) \
|
|
607
|
-
JSON_READ_VECTOR_OF_SVFREF(iter, obj, field, Value)
|
|
608
|
-
|
|
609
|
-
#define JSON_READ_VECTOR_OF_SVFTYPE(iter, obj, field) \
|
|
610
|
-
JSON_READ_VECTOR_OF_SVFREF(iter, obj, field, Type)
|
|
611
|
-
|
|
612
|
-
#define JSON_READ_SVFREF(iter, obj, field, type) \
|
|
613
|
-
do \
|
|
614
|
-
{ \
|
|
615
|
-
ABORT_IFNOT( \
|
|
616
|
-
(cJSON_IsString(iter) && !std::strcmp(#field, (iter)->string)), \
|
|
617
|
-
#field " expects `" #iter "` to be a " #type "Index JSON string"); \
|
|
618
|
-
SVF##type* _p = indexTo##type(std::atoi((iter)->valuestring)); \
|
|
619
|
-
using _T = std::decay_t<decltype(*(obj)->field)>; \
|
|
620
|
-
ABORT_IFNOT(_p, "Some index in `" #iter "` refers to NULL"); \
|
|
621
|
-
_T* _t = SVFUtil::dyn_cast<_T>(_p); \
|
|
622
|
-
ABORT_IFNOT(_t, "dyn_cast from SVF" #type "* for " #field " failed"); \
|
|
623
|
-
(obj)->field = _t; \
|
|
624
|
-
iter = (iter)->next; \
|
|
625
|
-
} while (0)
|
|
626
|
-
|
|
627
|
-
#define JSON_READ_SVFTYPE(iter, obj, field) \
|
|
628
|
-
JSON_READ_SVFREF(iter, obj, field, Type)
|
|
629
|
-
|
|
630
|
-
#define JSON_READ_SVFVALUE(iter, obj, field) \
|
|
631
|
-
JSON_READ_SVFREF(iter, obj, field, Value)
|
|
632
|
-
|
|
633
|
-
#define JSON_READ_STRING(iter, obj, field) \
|
|
634
|
-
do \
|
|
635
|
-
{ \
|
|
636
|
-
ABORT_IFNOT( \
|
|
637
|
-
(cJSON_IsString(iter) && !std::strcmp(#field, (iter)->string)), \
|
|
638
|
-
#field " expects `" #iter "` to be a JSON string"); \
|
|
639
|
-
(obj)->field = (iter)->valuestring; \
|
|
640
|
-
iter = (iter)->next; \
|
|
641
|
-
} while (0)
|
|
642
|
-
|
|
643
|
-
#define JSON_READ_NUMBER(iter, obj, field) \
|
|
644
|
-
do \
|
|
645
|
-
{ \
|
|
646
|
-
ABORT_IFNOT( \
|
|
647
|
-
(cJSON_IsNumber(iter) && !std::strcmp(#field, (iter)->string)), \
|
|
648
|
-
#field " expects `" #iter "` to be a JSON number"); \
|
|
649
|
-
(obj)->field = \
|
|
650
|
-
static_cast<decltype((obj)->field)>((iter)->valuedouble); \
|
|
651
|
-
iter = (iter)->next; \
|
|
652
|
-
} while (0)
|
|
653
|
-
|
|
654
|
-
#define JSON_READ_BOOL(iter, obj, field) \
|
|
655
|
-
do \
|
|
656
|
-
{ \
|
|
657
|
-
ABORT_IFNOT( \
|
|
658
|
-
(cJSON_IsBool(iter) && !std::strcmp(#field, (iter)->string)), \
|
|
659
|
-
#field " expects `" #field "` to be a JSON bool"); \
|
|
660
|
-
(obj)->field = static_cast<bool>(cJSON_IsTrue(iter)); \
|
|
661
|
-
iter = (iter)->next; \
|
|
662
|
-
} while (0)
|
|
663
|
-
|
|
664
|
-
SVFType* createType(SVFType::SVFTyKind kind)
|
|
665
|
-
{
|
|
666
|
-
switch (kind)
|
|
667
|
-
{
|
|
668
|
-
default:
|
|
669
|
-
SVFUtil::errs() << "Impossible SVFTyKind " << kind
|
|
670
|
-
<< " in createType()\n";
|
|
671
|
-
assert(false);
|
|
672
|
-
case SVFType::SVFTy:
|
|
673
|
-
SVFUtil::errs() << "Construction of RAW SVFType isn't allowed\n";
|
|
674
|
-
assert(false);
|
|
675
|
-
case SVFType::SVFPointerTy:
|
|
676
|
-
return new SVFPointerType({});
|
|
677
|
-
case SVFType::SVFIntegerTy:
|
|
678
|
-
return new SVFIntegerType();
|
|
679
|
-
case SVFType::SVFFunctionTy:
|
|
680
|
-
return new SVFFunctionType({});
|
|
681
|
-
case SVFType::SVFStructTy:
|
|
682
|
-
return new SVFStructType();
|
|
683
|
-
case SVFType::SVFArrayTy:
|
|
684
|
-
return new SVFArrayType();
|
|
685
|
-
case SVFType::SVFOtherTy:
|
|
686
|
-
return new SVFOtherType({});
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
SVFValue* createValue(SVFValue::SVFValKind kind)
|
|
691
|
-
{
|
|
692
|
-
switch (kind)
|
|
693
|
-
{
|
|
694
|
-
default:
|
|
695
|
-
SVFUtil::errs() << "Impossible SVFValue kind " << kind
|
|
696
|
-
<< " in createValue()\n";
|
|
697
|
-
assert(false);
|
|
698
|
-
case SVFValue::SVFVal:
|
|
699
|
-
SVFUtil::errs() << "Creation of RAW SVFValue isn't allowed\n";
|
|
700
|
-
assert(false);
|
|
701
|
-
case SVFValue::SVFFunc:
|
|
702
|
-
return new SVFFunction({}, {}, {}, {}, {}, {}, {}, {});
|
|
703
|
-
case SVFValue::SVFBB:
|
|
704
|
-
return new SVFBasicBlock({}, {}, {});
|
|
705
|
-
case SVFValue::SVFInst:
|
|
706
|
-
return new SVFInstruction({}, {}, {}, {}, {});
|
|
707
|
-
case SVFValue::SVFCall:
|
|
708
|
-
return new SVFCallInst({}, {}, {}, {}, {});
|
|
709
|
-
case SVFValue::SVFVCall:
|
|
710
|
-
return new SVFVirtualCallInst({}, {}, {}, {}, {});
|
|
711
|
-
case SVFValue::SVFGlob:
|
|
712
|
-
return new SVFGlobalValue({}, {});
|
|
713
|
-
case SVFValue::SVFArg:
|
|
714
|
-
return new SVFArgument({}, {}, {}, {}, {});
|
|
715
|
-
case SVFValue::SVFConst:
|
|
716
|
-
return new SVFConstant({}, {});
|
|
717
|
-
case SVFValue::SVFConstData:
|
|
718
|
-
return new SVFConstantData({}, {});
|
|
719
|
-
case SVFValue::SVFConstInt:
|
|
720
|
-
return new SVFConstantInt({}, {}, {}, {});
|
|
721
|
-
case SVFValue::SVFConstFP:
|
|
722
|
-
return new SVFConstantFP({}, {}, {});
|
|
723
|
-
case SVFValue::SVFNullPtr:
|
|
724
|
-
return new SVFConstantNullPtr({}, {});
|
|
725
|
-
case SVFValue::SVFBlackHole:
|
|
726
|
-
return new SVFBlackHoleValue({}, {});
|
|
727
|
-
case SVFValue::SVFMetaAsValue:
|
|
728
|
-
return new SVFMetadataAsValue({}, {});
|
|
729
|
-
case SVFValue::SVFOther:
|
|
730
|
-
return new SVFOtherValue({}, {});
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
SVFModule* SVFModuleRead::get()
|
|
735
|
-
{
|
|
736
|
-
if (!svfModule)
|
|
737
|
-
{
|
|
738
|
-
ABORT_IFNOT(cJSON_IsObject(moduleJson), "Invalid moduleJson");
|
|
739
|
-
svfModule = readSvfModule(moduleJson->child);
|
|
740
|
-
}
|
|
741
|
-
return svfModule;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
SVFModule* SVFModuleRead::readSvfModule(cJSON* iter)
|
|
745
|
-
{
|
|
746
|
-
cJSON* element;
|
|
747
|
-
|
|
748
|
-
// Read typePool
|
|
749
|
-
ABORT_IFNOT((cJSON_IsArray(iter) && !std::strcmp("typePool", iter->string)),
|
|
750
|
-
"Module's first child should be a typePool array");
|
|
751
|
-
cJSON_ArrayForEach(element, iter)
|
|
752
|
-
{
|
|
753
|
-
ABORT_IFNOT(cJSON_IsObject(element),
|
|
754
|
-
"Element in typePool is not a json object");
|
|
755
|
-
typeArray.push_back(element);
|
|
756
|
-
}
|
|
757
|
-
typePool.reserve(typeArray.size());
|
|
758
|
-
for (const cJSON* typeElement : typeArray)
|
|
759
|
-
{
|
|
760
|
-
cJSON* elementChild = typeElement->child;
|
|
761
|
-
ABORT_IFNOT((cJSON_IsNumber(elementChild) &&
|
|
762
|
-
!std::strcmp("kind", elementChild->string)),
|
|
763
|
-
"Type JSON's 1st element is not kind number");
|
|
764
|
-
auto kind = static_cast<SVFType::SVFTyKind>(elementChild->valuedouble);
|
|
765
|
-
typePool.push_back(createType(kind));
|
|
766
|
-
}
|
|
767
|
-
iter = iter->next;
|
|
768
|
-
|
|
769
|
-
// Read valuePool
|
|
770
|
-
ABORT_IFNOT(
|
|
771
|
-
(cJSON_IsArray(iter) && !std::strcmp("valuePool", iter->string)),
|
|
772
|
-
"Module's 2nd child should be valuePool array");
|
|
773
|
-
cJSON_ArrayForEach(element, iter)
|
|
774
|
-
{
|
|
775
|
-
ABORT_IFNOT(cJSON_IsObject(element),
|
|
776
|
-
"Element in valuePool is not json object");
|
|
777
|
-
valueArray.push_back(element);
|
|
778
|
-
}
|
|
779
|
-
valuePool.reserve(valueArray.size());
|
|
780
|
-
for (const cJSON* valueElement : valueArray)
|
|
781
|
-
{
|
|
782
|
-
cJSON* elementChild = valueElement->child;
|
|
783
|
-
ABORT_IFNOT((cJSON_IsNumber(elementChild) &&
|
|
784
|
-
!std::strcmp("kind", elementChild->string)),
|
|
785
|
-
"Value JSON's 1st element is not kind number");
|
|
786
|
-
auto kind =
|
|
787
|
-
static_cast<SVFValue::SVFValKind>(elementChild->valuedouble);
|
|
788
|
-
valuePool.push_back(createValue(kind));
|
|
789
|
-
}
|
|
790
|
-
iter = iter->next;
|
|
791
|
-
|
|
792
|
-
// Read pagReadFromTxt
|
|
793
|
-
ABORT_IFNOT(
|
|
794
|
-
(cJSON_IsString(iter) && !std::strcmp("pagReadFromTxt", iter->string)),
|
|
795
|
-
"Module's 3rd child should be pagReadFromTxt string");
|
|
796
|
-
const char* pagReadFromTxt = iter->valuestring;
|
|
797
|
-
iter = iter->next;
|
|
798
|
-
|
|
799
|
-
// Read moduleIdentifier
|
|
800
|
-
ABORT_IFNOT((cJSON_IsString(iter) &&
|
|
801
|
-
!std::strcmp("moduleIdentifier", iter->string)),
|
|
802
|
-
"Module's 3rd child should be moduleIdentifier string");
|
|
803
|
-
|
|
804
|
-
SVFModule* svfModule = new SVFModule(iter->valuestring);
|
|
805
|
-
svfModule->setPagFromTXT(pagReadFromTxt);
|
|
806
|
-
iter = iter->next;
|
|
807
|
-
|
|
808
|
-
// Read other stuff
|
|
809
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, svfModule, FunctionSet);
|
|
810
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, svfModule, GlobalSet);
|
|
811
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, svfModule, AliasSet);
|
|
812
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, svfModule, ConstantSet);
|
|
813
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, svfModule, OtherValueSet);
|
|
814
|
-
|
|
815
|
-
ABORT_IFNOT(iter == nullptr, "Module has more children than expected");
|
|
816
|
-
|
|
817
|
-
// Fill incomplete values in valuePool and typePool
|
|
818
|
-
for (size_t i = 0; i < typePool.size(); ++i)
|
|
819
|
-
fillSVFTypeAt(i);
|
|
820
|
-
for (size_t i = 0; i < valuePool.size(); ++i)
|
|
821
|
-
fillSVFValueAt(i);
|
|
822
|
-
|
|
823
|
-
return svfModule;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
void SVFModuleRead::fillSVFTypeAt(size_t i)
|
|
827
|
-
{
|
|
828
|
-
cJSON* childIter = typeArray[i]->child;
|
|
829
|
-
SVFType* type = typePool[i];
|
|
830
|
-
auto kind = type->getKind();
|
|
831
|
-
|
|
832
|
-
switch (kind)
|
|
833
|
-
{
|
|
834
|
-
default:
|
|
835
|
-
SVFUtil::errs() << "Impossible SVFType kind " << kind
|
|
836
|
-
<< " in fillSVFTypeAt()\n";
|
|
837
|
-
assert(false);
|
|
838
|
-
|
|
839
|
-
#define CASE(Kind) \
|
|
840
|
-
case SVFType::Kind: { \
|
|
841
|
-
auto _iter = \
|
|
842
|
-
readJson(childIter->next, SVFUtil::dyn_cast<Kind##pe>(type)); \
|
|
843
|
-
ABORT_IFNOT(_iter == nullptr, #Kind " elements left unread"); \
|
|
844
|
-
break; \
|
|
845
|
-
}
|
|
846
|
-
CASE(SVFTy);
|
|
847
|
-
CASE(SVFPointerTy);
|
|
848
|
-
CASE(SVFIntegerTy);
|
|
849
|
-
CASE(SVFFunctionTy);
|
|
850
|
-
CASE(SVFStructTy);
|
|
851
|
-
CASE(SVFArrayTy);
|
|
852
|
-
CASE(SVFOtherTy);
|
|
853
|
-
#undef CASE
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
void SVFModuleRead::fillSVFValueAt(size_t i)
|
|
858
|
-
{
|
|
859
|
-
cJSON* childIter = valueArray[i]->child;
|
|
860
|
-
SVFValue* value = valuePool[i];
|
|
861
|
-
auto kind = value->getKind();
|
|
862
|
-
switch (kind)
|
|
863
|
-
{
|
|
864
|
-
default:
|
|
865
|
-
SVFUtil::errs() << "Impossible SVFValue kind " << kind
|
|
866
|
-
<< " in fillSVFValueAt()\n";
|
|
867
|
-
assert(false);
|
|
868
|
-
|
|
869
|
-
#define CASE(kind, type) \
|
|
870
|
-
case SVFValue::kind: { \
|
|
871
|
-
auto _iter = \
|
|
872
|
-
readJson(childIter->next, SVFUtil::dyn_cast<type>(value)); \
|
|
873
|
-
ABORT_IFNOT(_iter == nullptr, #type " elements left unread"); \
|
|
874
|
-
break; \
|
|
875
|
-
}
|
|
876
|
-
CASE(SVFVal, SVFValue);
|
|
877
|
-
CASE(SVFFunc, SVFFunction);
|
|
878
|
-
CASE(SVFBB, SVFBasicBlock);
|
|
879
|
-
CASE(SVFInst, SVFInstruction);
|
|
880
|
-
CASE(SVFCall, SVFCallInst);
|
|
881
|
-
CASE(SVFVCall, SVFVirtualCallInst);
|
|
882
|
-
CASE(SVFGlob, SVFGlobalValue);
|
|
883
|
-
CASE(SVFArg, SVFArgument);
|
|
884
|
-
CASE(SVFConst, SVFConstant);
|
|
885
|
-
CASE(SVFConstData, SVFConstantData);
|
|
886
|
-
CASE(SVFConstInt, SVFConstantInt);
|
|
887
|
-
CASE(SVFConstFP, SVFConstantFP);
|
|
888
|
-
CASE(SVFNullPtr, SVFConstantNullPtr);
|
|
889
|
-
CASE(SVFBlackHole, SVFBlackHoleValue);
|
|
890
|
-
CASE(SVFMetaAsValue, SVFMetadataAsValue);
|
|
891
|
-
CASE(SVFOther, SVFOtherValue);
|
|
892
|
-
#undef CASE
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
SVFType* SVFModuleRead::indexToType(TypeIndex i)
|
|
897
|
-
{
|
|
898
|
-
ABORT_IFNOT(i <= typePool.size(), "TypeIndex too large");
|
|
899
|
-
return i ? typePool[i - 1] : nullptr;
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
SVFValue* SVFModuleRead::indexToValue(ValueIndex i)
|
|
903
|
-
{
|
|
904
|
-
ABORT_IFNOT(i <= valuePool.size(), "ValueIndex too large");
|
|
905
|
-
return i ? valuePool[i - 1] : nullptr;
|
|
906
|
-
}
|
|
907
|
-
|
|
908
|
-
StInfo* SVFModuleRead::readStInfo(cJSON* iter)
|
|
909
|
-
{
|
|
910
|
-
StInfo* info = new StInfo({});
|
|
911
|
-
|
|
912
|
-
JSON_READ_VECTOR_OF_NUMBER(iter, info, fldIdxVec);
|
|
913
|
-
JSON_READ_VECTOR_OF_NUMBER(iter, info, elemIdxVec);
|
|
914
|
-
|
|
915
|
-
// Read map of StInfo::fldIdx2TypeMap (u32_t -> SVFType*)
|
|
916
|
-
ABORT_IFNOT(
|
|
917
|
-
(cJSON_IsObject(iter) && !std::strcmp("fldIdx2TypeMap", iter->string)),
|
|
918
|
-
"fldIdx2TypeMap expects an array");
|
|
919
|
-
cJSON* element;
|
|
920
|
-
cJSON_ArrayForEach(element, iter)
|
|
921
|
-
{
|
|
922
|
-
ABORT_IFNOT(cJSON_IsString(element),
|
|
923
|
-
"fldIdx2TypeMap expects TypeIndex strings in array");
|
|
924
|
-
info->fldIdx2TypeMap.emplace(
|
|
925
|
-
std::atoi(element->string),
|
|
926
|
-
indexToType(std::atoi(element->valuestring)));
|
|
927
|
-
}
|
|
928
|
-
iter = iter->next;
|
|
929
|
-
|
|
930
|
-
JSON_READ_VECTOR_OF_SVFTYPE(iter, info, finfo);
|
|
931
|
-
JSON_READ_NUMBER(iter, info, stride);
|
|
932
|
-
JSON_READ_NUMBER(iter, info, numOfFlattenElements);
|
|
933
|
-
JSON_READ_NUMBER(iter, info, numOfFlattenFields);
|
|
934
|
-
JSON_READ_VECTOR_OF_SVFTYPE(iter, info, flattenElementTypes);
|
|
935
|
-
return info;
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFType* type)
|
|
939
|
-
{
|
|
940
|
-
|
|
941
|
-
JSON_READ_SVFREF(iter, type, getPointerToTy, Type);
|
|
942
|
-
|
|
943
|
-
// Read typeinfo
|
|
944
|
-
ABORT_IFNOT(
|
|
945
|
-
(cJSON_IsObject(iter) && !std::strcmp("typeinfo", iter->string)),
|
|
946
|
-
"Field should be a typeinfo JSON object");
|
|
947
|
-
type->typeinfo = readStInfo(iter->child);
|
|
948
|
-
iter = iter->next;
|
|
949
|
-
|
|
950
|
-
JSON_READ_BOOL(iter, type, isSingleValTy);
|
|
951
|
-
|
|
952
|
-
return iter;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFPointerType* type)
|
|
956
|
-
{
|
|
957
|
-
iter = readJson(iter, static_cast<SVFType*>(type));
|
|
958
|
-
JSON_READ_SVFTYPE(iter, type, ptrElementType);
|
|
959
|
-
return iter;
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFIntegerType* type)
|
|
963
|
-
{
|
|
964
|
-
return readJson(iter, static_cast<SVFType*>(type));
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFFunctionType* type)
|
|
968
|
-
{
|
|
969
|
-
iter = readJson(iter, static_cast<SVFType*>(type));
|
|
970
|
-
JSON_READ_SVFTYPE(iter, type, retTy);
|
|
971
|
-
return iter;
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFStructType* type)
|
|
975
|
-
{
|
|
976
|
-
return readJson(iter, static_cast<SVFType*>(type));
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFArrayType* type)
|
|
980
|
-
{
|
|
981
|
-
return readJson(iter, static_cast<SVFType*>(type));
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFOtherType* type)
|
|
985
|
-
{
|
|
986
|
-
return readJson(iter, static_cast<SVFType*>(type));
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
SVFLoopAndDomInfo* SVF::SVFModuleRead::readSvfLoopAndDomInfo(cJSON* iter)
|
|
990
|
-
{
|
|
991
|
-
auto ldInfo = new SVFLoopAndDomInfo;
|
|
992
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, ldInfo, reachableBBs);
|
|
993
|
-
|
|
994
|
-
#define JSON_READ_BB_MAP(field) \
|
|
995
|
-
do \
|
|
996
|
-
{ \
|
|
997
|
-
ABORT_IFNOT( \
|
|
998
|
-
(cJSON_IsObject(iter) && !std::strcmp(#field, iter->string)), \
|
|
999
|
-
#field " expects a JSON object to represent mapping"); \
|
|
1000
|
-
cJSON *_kvJson, *_vJson; \
|
|
1001
|
-
cJSON_ArrayForEach(_kvJson, iter) \
|
|
1002
|
-
{ \
|
|
1003
|
-
ABORT_IFNOT(cJSON_IsArray(_kvJson), \
|
|
1004
|
-
"Elements in " #field " should be BB index array"); \
|
|
1005
|
-
SVFValue* _key = indexToValue(std::atoi(_kvJson->string)); \
|
|
1006
|
-
ABORT_IFNOT(_key, "Some key BB index refers to NULL"); \
|
|
1007
|
-
SVFBasicBlock* _bbKey = SVFUtil::dyn_cast<SVFBasicBlock>(_key); \
|
|
1008
|
-
ABORT_IFNOT(_bbKey, \
|
|
1009
|
-
"Some key index in " #field " is not a BasicBlock*"); \
|
|
1010
|
-
auto& _fieldRef = ldInfo->field[_bbKey]; \
|
|
1011
|
-
cJSON_ArrayForEach(_vJson, _kvJson) \
|
|
1012
|
-
{ \
|
|
1013
|
-
ABORT_IFNOT(cJSON_IsString(_vJson), \
|
|
1014
|
-
"Elements in " #field \
|
|
1015
|
-
" array should be a ValueIndex string"); \
|
|
1016
|
-
SVFValue* _val = indexToValue(std::atoi(_vJson->valuestring)); \
|
|
1017
|
-
ABORT_IFNOT(_val, "Some val BB index refers to NULL"); \
|
|
1018
|
-
SVFBasicBlock* _bb = SVFUtil::dyn_cast<SVFBasicBlock>(_val); \
|
|
1019
|
-
ABORT_IFNOT(_bb, "Some Value* in " #field \
|
|
1020
|
-
" array is not a BasicBlock*"); \
|
|
1021
|
-
_fieldRef.insert(_fieldRef.end(), _bb); \
|
|
1022
|
-
} \
|
|
1023
|
-
} \
|
|
1024
|
-
iter = iter->next; \
|
|
1025
|
-
} while (0);
|
|
1026
|
-
|
|
1027
|
-
JSON_READ_BB_MAP(dtBBsMap);
|
|
1028
|
-
JSON_READ_BB_MAP(pdtBBsMap);
|
|
1029
|
-
JSON_READ_BB_MAP(dfBBsMap);
|
|
1030
|
-
JSON_READ_BB_MAP(bb2LoopMap);
|
|
1031
|
-
|
|
1032
|
-
#undef JSON_READ_BB_MAP
|
|
1033
|
-
return ldInfo;
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFValue* value)
|
|
1037
|
-
{
|
|
1038
|
-
JSON_READ_BOOL(iter, value, ptrInUncalledFun);
|
|
1039
|
-
JSON_READ_BOOL(iter, value, constDataOrAggData);
|
|
1040
|
-
JSON_READ_SVFTYPE(iter, value, type);
|
|
1041
|
-
JSON_READ_STRING(iter, value, name);
|
|
1042
|
-
JSON_READ_STRING(iter, value, sourceLoc);
|
|
1043
|
-
return iter;
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFFunction* value)
|
|
1047
|
-
{
|
|
1048
|
-
iter = readJson(iter, static_cast<SVFValue*>(value));
|
|
1049
|
-
JSON_READ_BOOL(iter, value, isDecl);
|
|
1050
|
-
JSON_READ_BOOL(iter, value, intrinsic);
|
|
1051
|
-
JSON_READ_BOOL(iter, value, addrTaken);
|
|
1052
|
-
JSON_READ_BOOL(iter, value, isUncalled);
|
|
1053
|
-
JSON_READ_BOOL(iter, value, isNotRet);
|
|
1054
|
-
JSON_READ_BOOL(iter, value, varArg);
|
|
1055
|
-
JSON_READ_SVFTYPE(iter, value, funcType);
|
|
1056
|
-
// Read Loop and Dom
|
|
1057
|
-
ABORT_IFNOT(
|
|
1058
|
-
(cJSON_IsObject(iter) && !std::strcmp("loopAndDom", iter->string)),
|
|
1059
|
-
"Expect a `loopAndDom' json object");
|
|
1060
|
-
value->loopAndDom = readSvfLoopAndDomInfo(iter->child);
|
|
1061
|
-
iter = iter->next;
|
|
1062
|
-
// Others
|
|
1063
|
-
JSON_READ_SVFVALUE(iter, value, realDefFun);
|
|
1064
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, value, allBBs);
|
|
1065
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, value, allArgs);
|
|
1066
|
-
return iter;
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFBasicBlock* value)
|
|
1070
|
-
{
|
|
1071
|
-
iter = readJson(iter, static_cast<SVFValue*>(value));
|
|
1072
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, value, allInsts);
|
|
1073
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, value, succBBs);
|
|
1074
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, value, predBBs);
|
|
1075
|
-
JSON_READ_SVFVALUE(iter, value, fun);
|
|
1076
|
-
return iter;
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFInstruction* value)
|
|
1080
|
-
{
|
|
1081
|
-
iter = readJson(iter, static_cast<SVFValue*>(value));
|
|
1082
|
-
JSON_READ_SVFVALUE(iter, value, bb);
|
|
1083
|
-
JSON_READ_BOOL(iter, value, terminator);
|
|
1084
|
-
JSON_READ_BOOL(iter, value, ret);
|
|
1085
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, value, succInsts);
|
|
1086
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, value, predInsts);
|
|
1087
|
-
return iter;
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFCallInst* value)
|
|
1091
|
-
{
|
|
1092
|
-
iter = readJson(iter, static_cast<SVFInstruction*>(value));
|
|
1093
|
-
JSON_READ_VECTOR_OF_SVFVALUE(iter, value, args);
|
|
1094
|
-
JSON_READ_BOOL(iter, value, varArg);
|
|
1095
|
-
JSON_READ_SVFVALUE(iter, value, calledVal);
|
|
1096
|
-
return iter;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFVirtualCallInst* value)
|
|
1100
|
-
{
|
|
1101
|
-
iter = readJson(iter, static_cast<SVFCallInst*>(value));
|
|
1102
|
-
JSON_READ_SVFVALUE(iter, value, vCallVtblPtr);
|
|
1103
|
-
JSON_READ_NUMBER(iter, value, virtualFunIdx);
|
|
1104
|
-
JSON_READ_STRING(iter, value, funNameOfVcall);
|
|
1105
|
-
return iter;
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFConstant* value)
|
|
1109
|
-
{
|
|
1110
|
-
return readJson(iter, static_cast<SVFValue*>(value));
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFGlobalValue* value)
|
|
1114
|
-
{
|
|
1115
|
-
iter = readJson(iter, static_cast<SVFConstant*>(value));
|
|
1116
|
-
JSON_READ_SVFVALUE(iter, value, realDefGlobal);
|
|
1117
|
-
return iter;
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFArgument* value)
|
|
1121
|
-
{
|
|
1122
|
-
iter = readJson(iter, static_cast<SVFValue*>(value));
|
|
1123
|
-
JSON_READ_SVFVALUE(iter, value, fun);
|
|
1124
|
-
JSON_READ_NUMBER(iter, value, argNo);
|
|
1125
|
-
JSON_READ_BOOL(iter, value, uncalled);
|
|
1126
|
-
return iter;
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFConstantData* value)
|
|
1130
|
-
{
|
|
1131
|
-
return readJson(iter, static_cast<SVFConstant*>(value));
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFConstantInt* value)
|
|
1135
|
-
{
|
|
1136
|
-
iter = readJson(iter, static_cast<SVFConstantData*>(value));
|
|
1137
|
-
JSON_READ_NUMBER(iter, value, zval);
|
|
1138
|
-
JSON_READ_NUMBER(iter, value, sval);
|
|
1139
|
-
return iter;
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFConstantFP* value)
|
|
1143
|
-
{
|
|
1144
|
-
iter = readJson(iter, static_cast<SVFConstantData*>(value));
|
|
1145
|
-
JSON_READ_NUMBER(iter, value, dval);
|
|
1146
|
-
return iter;
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFConstantNullPtr* value)
|
|
1150
|
-
{
|
|
1151
|
-
return readJson(iter, static_cast<SVFConstantData*>(value));
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFBlackHoleValue* value)
|
|
1155
|
-
{
|
|
1156
|
-
return readJson(iter, static_cast<SVFConstantData*>(value));
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFOtherValue* value)
|
|
1160
|
-
{
|
|
1161
|
-
return readJson(iter, static_cast<SVFValue*>(value));
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
cJSON* SVFModuleRead::readJson(cJSON* iter, SVFMetadataAsValue* value)
|
|
1165
|
-
{
|
|
1166
|
-
return readJson(iter, static_cast<SVFOtherValue*>(value));
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
SVFModuleRead::SVFModuleRead(const std::string& path) : svfModule(nullptr)
|
|
1170
|
-
{
|
|
1171
|
-
struct stat buf;
|
|
1172
|
-
int fd = open(path.c_str(), O_RDONLY);
|
|
1173
|
-
if (fd == -1)
|
|
1174
|
-
{
|
|
1175
|
-
std::string info = "open(\"" + path + "\")";
|
|
1176
|
-
perror(info.c_str());
|
|
1177
|
-
abort();
|
|
1178
|
-
}
|
|
1179
|
-
if (fstat(fd, &buf) == -1)
|
|
1180
|
-
{
|
|
1181
|
-
std::string info = "fstate(\"" + path + "\")";
|
|
1182
|
-
perror(info.c_str());
|
|
1183
|
-
abort();
|
|
1184
|
-
}
|
|
1185
|
-
auto addr =
|
|
1186
|
-
(char*)mmap(nullptr, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
1187
|
-
if (addr == MAP_FAILED)
|
|
1188
|
-
{
|
|
1189
|
-
std::string info = "mmap(content of \"" + path + "\")";
|
|
1190
|
-
perror(info.c_str());
|
|
1191
|
-
abort();
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
moduleJson = cJSON_ParseWithLength(addr, buf.st_size);
|
|
1195
|
-
|
|
1196
|
-
if (munmap(addr, buf.st_size) == -1)
|
|
1197
|
-
perror("munmap()");
|
|
1198
|
-
|
|
1199
|
-
if (close(fd) < 0)
|
|
1200
|
-
perror("close()");
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
SVFModuleRead::~SVFModuleRead()
|
|
1204
|
-
{
|
|
1205
|
-
cJSON_Delete(moduleJson);
|
|
1206
|
-
}
|