12 "human-readable",
"Whether to output human-readable JSON",
true);
22 ABORT_MSG(kind <<
" is an impossible SVFTyKind in create()");
24 ABORT_MSG(
"Creation of RAW SVFType isn't allowed");
26 ABORT_IFNOT(isSingleValTy,
"Pointer type must be single-valued");
29 ABORT_IFNOT(isSingleValTy,
"Integer type must be single-valued");
32 ABORT_IFNOT(!isSingleValTy,
"Function type must be multi-valued");
35 ABORT_IFNOT(!isSingleValTy,
"Struct type must be multi-valued");
38 ABORT_IFNOT(!isSingleValTy,
"Array type must be multi-valued");
53 ABORT_MSG(kind <<
" is an impossible SVFValueKind in create()");
55 ABORT_MSG(
"Creation of RAW SVFValue isn't allowed");
93 template <
typename SmallNumberType>
99 template <
typename BigNumberType,
typename CStrToVal>
103 "Expect (number) string JSON for " <<
JSON_KEY(obj));
152 auto kind =
type->getKind();
157 assert(
false &&
"Impossible SVFType kind");
160 case SVFType::Kind: \
161 return contentToJson(static_cast<const Kind##pe*>(type))
181 assert(
false &&
"Impossible SVFValue kind");
183 #define CASE(ValueKind, type) \
184 case SVFValue::ValueKind: \
185 return contentToJson(static_cast<const type*>(value))
212 assert(
false &&
"Unknown SVFVar kind");
214 #define CASE(VarKind, VarType) \
215 case SVFVar::VarKind: \
216 return contentToJson(static_cast<const VarType*>(var))
236 assert(
false &&
"Unknown SVFStmt kind");
238 #define CASE(EdgeKind, EdgeType) \
239 case SVFStmt::EdgeKind: \
240 return contentToJson(static_cast<const EdgeType*>(stmt))
266 assert(
false &&
"Unknown ICFGNode kind");
268 #define CASE(NodeKind, NodeType) \
269 case ICFGNode::NodeKind: \
270 return contentToJson(static_cast<const NodeType*>(node))
287 assert(
false &&
"Unknown ICFGEdge kind");
376 assert(node->
VFGNodes.empty() &&
"VFGNodes list not empty?");
538 #define F(f) JSON_WRITE_FIELD(root, value, f);
664 #define F(field) JSON_WRITE_FIELD(root, loop, field)
795 cJSON* node = cJSON_CreateStringReference(str);
808 : cJSON_IsNumber(
item) &&
816 if (!cJSON_IsBool(
item))
818 flag = cJSON_IsTrue(
item);
823 if (!cJSON_IsNumber(
item))
832 return cJSON_IsNumber(
item);
837 return cJSON_IsString(
item);
843 return cJSON_IsNull(
item);
848 return cJSON_IsArray(
item);
853 return cJSON_IsArray(
item);
870 ABORT_IFNOT(child1,
"Missing first child of pair");
872 ABORT_IFNOT(child2,
"Missing first child of pair");
874 return {child1, child2};
886 return cJSON_CreateNull();
896 return cJSON_CreateArray();
902 return cJSON_CreateArray();
907 return cJSON_CreateStringReference(str);
912 constexpr
size_t maxPreciseIntInDouble = (1ull << 53);
913 (void)maxPreciseIntInDouble;
914 assert(
index <= maxPreciseIntInDouble);
915 return cJSON_CreateNumber(
index);
921 return hr ? cJSON_CreateBool(flag) : cJSON_CreateNumber(flag);
926 return cJSON_CreateNumber(num);
931 cJSON* pair = cJSON_CreateArray();
941 : cJSON_AddItemToArray(obj,
item);
946 return cJSON_AddItemToArray(array,
item);
953 for (
const SVFLoop* loop : pair.second)
965 const auto& svfTypes = symTab->getSVFTypes();
972 const auto& stInfos = symTab->getStInfos();
974 for (
const StInfo* stInfo : stInfos)
985 : svfIR(svfir), svfModuleWriter(svfir->svfModule), icfgWriter(svfir->icfg),
999 std::ofstream jsonFile(path);
1000 if (jsonFile.is_open())
1008 <<
"' to write SVFIR's JSON\n";
1017 return it->second.c_str();
1019 return numToStrMap.emplace_hint(it,
n, std::to_string(
n))->second.c_str();
1026 : cJSON_PrintUnformatted(
object.get());
1027 return {str, cJSON_free};
1034 assert(nodeIDAllocator &&
"NodeIDAllocator is not initialized?");
1037 #define F(field) JSON_WRITE_FIELD(root, svfIR, field)
1043 F(icfgNode2SVFStmtsMap);
1044 F(icfgNode2PTASVFStmtsMap);
1052 F(callSiteArgsListMap);
1055 F(indCallSiteToFunPtrMap);
1056 F(funPtrToCallSitesMap);
1057 F(candidatePointers);
1080 #define F(field) JSON_WRITE_FIELD(root, graph, field)
1081 F(KindToSVFStmtSetMap);
1082 F(KindToPTASVFStmtSetMap);
1084 F(nodeNumAfterPAGBuild);
1110 #define F(field) JSON_WRITE_FIELD(root, icfg, field)
1114 F(FunToFunEntryNodeMap);
1115 F(FunToFunExitNodeMap);
1117 F(icfgNodeToSVFLoopVec);
1124 assert(node &&
"ICFGNode is null!");
1130 assert(edge &&
"ICFGNode is null!");
1136 auto chg = SVFUtil::dyn_cast<CHGraph>(graph);
1137 assert(chg &&
"Unsupported CHGraph type!");
1144 #define F(field) JSON_WRITE_FIELD(root, graph, field)
1149 F(classNameToNodeMap);
1150 F(classNameToDescendantsMap);
1151 F(classNameToAncestorsMap);
1152 F(classNameToInstAndDescsMap);
1153 F(templateNameToInstancesMap);
1154 F(callNodeToClassesMap);
1155 F(virtualFunctionToIDMap);
1156 F(callNodeToCHAVtblsMap);
1157 F(callNodeToCHAVFnsMap);
1189 #define F(field) JSON_WRITE_FIELD(root, stInfo, field)
1191 F(numOfFlattenElements);
1192 F(numOfFlattenFields);
1197 F(flattenElementTypes);
1266 for (
const auto& pair : symTable->
objMap)
1268 const MemObj* memObj = pair.second;
1273 #define F(field) JSON_WRITE_FIELD(root, symTable, field)
1313 #define F(field) JSON_WRITE_FIELD(root, module, field)
1318 F(moduleIdentifier);
1344 auto icfg =
new ICFG();
1345 auto chgraph =
new CHGraph(svfModule);
1347 symInfo->mod = svfModule;
1353 #define F(field) JSON_READ_FIELD_FWD(svfirField, svfIR, field)
1360 F(icfgNode2SVFStmtsMap);
1361 F(icfgNode2PTASVFStmtsMap);
1369 F(callSiteArgsListMap);
1372 F(indCallSiteToFunPtrMap);
1373 F(funPtrToCallSitesMap);
1374 F(candidatePointers);
1386 #define READ_CREATE_NODE_FWD(GType) \
1387 [](const cJSON*& nodeJson) { \
1388 JSON_DEF_READ_FWD(nodeJson, NodeID, id); \
1389 JSON_DEF_READ_FWD(nodeJson, GNodeK, nodeKind); \
1390 return std::make_pair(id, create##GType##Node(id, nodeKind)); \
1392 #define READ_CREATE_EDGE_FWD(GType) \
1393 [](const cJSON*& edgeJson) { \
1394 JSON_DEF_READ_FWD(edgeJson, GEdgeFlag, edgeFlag); \
1395 auto kind = applyEdgeMask(edgeFlag); \
1396 auto edge = create##GType##Edge(kind); \
1397 setEdgeFlag(edge, edgeFlag); \
1408 [](
const cJSON*& svfTypeFldJson)
1420 [
this](
const cJSON*& svfValueFldJson)
1433 [
this](
const cJSON*& stInfoFldJson)
1436 auto si =
new StInfo(stride);
1437 fill(stInfoFldJson, si);
1438 ABORT_IFNOT(!stInfoFldJson,
"StInfo has extra field");
1442 const cJSON*
const symInfo = svfModule->
next;
1447 [
this](
const cJSON*& memObjFldJson)
1452 return std::make_pair(symId,
new MemObj(symId, typeInfo, refVal));
1455 const cJSON*
const icfg = symInfo->
next;
1464 const cJSON*
const chgraph = icfg->
next;
1469 const cJSON*
const irGraph = chgraph->
next;
1506 return irGraph->
next;
1508 #undef READ_CREATE_EDGE_FWD
1509 #undef READ_CREATE_NODE_FWD
1575 ABORT_MSG(kind <<
" is an impossible ICFGNodeKind in create()");
1576 #define CASE(kind, constructor) \
1577 case ICFGNode::kind: \
1578 return new constructor(id);
1597 ABORT_MSG(kind <<
" is an impossible ICFGEdgeKind in create()");
1609 ABORT_IFNOT(kind == 0,
"Impossible CHNode kind " << kind);
1610 return new CHNode(
"",
id);
1615 ABORT_IFNOT(kind == 0,
"Unsupported CHEdge kind " << kind);
1616 return new CHEdge(
nullptr,
nullptr, {});
1624 ABORT_MSG(kind <<
" is an impossible SVFVarKind in create()");
1625 #define CASE(kind, constructor) \
1626 case SVFVar::kind: \
1627 return new constructor(id);
1646 ABORT_MSG(kind <<
" is an impossible SVFStmtKind in create()");
1647 #define CASE(kind, constructor) \
1648 case SVFStmt::kind: \
1649 return new constructor;
1671 assert(idAllocator &&
"idAllocator should be nonempty");
1677 static_assert(
sizeof(idAllocator->
strategy) ==
sizeof(strategy),
1678 "idAllocator->strategy should be represented by int");
1691 #define F(field) JSON_READ_FIELD_FWD(obj, symTabInfo, field)
1712 valToEdgeMap.clear();
1716 #define F(field) JSON_READ_FIELD_FWD(obj, graph, field)
1718 F(KindToSVFStmtSetMap);
1719 F(KindToPTASVFStmtSetMap);
1721 F(nodeNumAfterPAGBuild);
1726 auto nullit = valToEdgeMap.find(
nullptr);
1727 ABORT_IFNOT(nullit != valToEdgeMap.end(),
"valueToEdgeMap should has key NULL");
1728 ABORT_IFNOT(nullit->second.empty(),
"valueToEdgeMap[NULL] should be empty");
1735 #define F(field) JSON_READ_FIELD_FWD(obj, icfg, field)
1737 F(FunToFunEntryNodeMap);
1738 F(FunToFunExitNodeMap);
1740 F(icfgNodeToSVFLoopVec);
1748 #define F(field) JSON_READ_FIELD_FWD(obj, graph, field)
1751 F(classNameToNodeMap);
1752 F(classNameToDescendantsMap);
1753 F(classNameToAncestorsMap);
1754 F(classNameToInstAndDescsMap);
1755 F(templateNameToInstancesMap);
1756 F(callNodeToClassesMap);
1757 F(virtualFunctionToIDMap);
1758 F(callNodeToCHAVtblsMap);
1759 F(callNodeToCHAVFnsMap);
1767 assert(symInfo &&
"SymbolTableInfo should be non-NULL");
1771 #define F(field) JSON_READ_FIELD_FWD(obj, module, field)
1773 F(moduleIdentifier);
1784 assert(!
type &&
"SVFType already read?");
1790 assert(!stInfo &&
"StInfo already read?");
1796 assert(!value &&
"SVFValue already read?");
1802 assert(!var &&
"SVFVar already read?");
1811 assert(!stmt &&
"SVFStmt already read?");
1817 assert(!node &&
"ICFGNode already read?");
1824 assert(!edge &&
"ICFGEdge already read?");
1830 assert(!node &&
"CHNode already read?");
1836 assert(!edge &&
"CHEdge already read?");
1851 assert(!loop &&
"SVFLoop already read?");
1858 assert(!memObj &&
"MemObj already read?");
1864 assert(!objTypeInfo &&
"ObjTypeInfo already read?");
1875 objTypeInfo->
flags = flags;
1876 objTypeInfo->
elemNum = elemNum;
1881 assert(!ldInfo &&
"SVFLoopAndDomInfo already read?");
1896 "Extra field in SVFLoopAndDomInfo: " <<
JSON_KEY(field));
1904 assert(
false &&
"Unknown SVFVar kind");
1906 #define CASE(VarKind, VarType) \
1907 case SVFVar::VarKind: \
1908 return fill(fieldJson, static_cast<VarType*>(var))
1989 ABORT_MSG(
"Unknown SVFStmt kind " << kind);
1991 #define CASE(EdgeKind, EdgeType) \
1992 case SVFStmt::EdgeKind: \
1993 return fill(fieldJson, static_cast<EdgeType*>(stmt))
2121 fill(fieldJson,
static_cast<RetPE*
>(stmt));
2133 #define F(field) JSON_READ_FIELD_FWD(fieldJson, stInfo, field)
2135 F(numOfFlattenElements);
2136 F(numOfFlattenFields);
2141 F(flattenElementTypes);
2152 #define CASE(NodeKind, NodeType) \
2153 case ICFGNode::NodeKind: \
2154 return fill(fieldJson, static_cast<NodeType*>(node))
2223 ABORT_MSG(
"Unknown ICFGEdge kind " << kind);
2259 #define F(field) JSON_READ_FIELD_FWD(fieldJson, loop, field)
2271 assert(node->
getNodeKind() == 0 &&
"Unknown CHNode kind");
2281 assert(edge->
getEdgeKind() == 0 &&
"Unknown CHEdge kind");
2290 ABORT_MSG(
"Unknown CHEdge type " << edgeType);
2300 ABORT_MSG(
"Impossible SVFValue kind " << kind);
2302 #define CASE(ValueKind, Type) \
2303 case SVFValue::ValueKind: \
2304 return fill(fieldJson, static_cast<Type*>(value))
2337 #define F(f) JSON_READ_FIELD_FWD(fieldJson, value, f)
2443 auto kind =
type->getKind();
2448 assert(
false &&
"Impossible SVFType kind");
2450 #define CASE(Kind) \
2451 case SVFType::Kind: \
2452 return fill(fieldJson, SVFUtil::dyn_cast<Kind##pe>(type))
2457 CASE(SVFFunctionTy);
2510 int fd = open(path.c_str(), O_RDONLY);
2514 perror(info.c_str());
2517 if (fstat(fd, &buf) == -1)
2520 perror(info.c_str());
2524 (
char*)mmap(
nullptr, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
2525 if (addr == MAP_FAILED)
2527 std::string info =
"mmap(content of \"" + path +
"\")";
2528 perror(info.c_str());
2532 auto root = cJSON_ParseWithLength(addr, buf.st_size);
2534 if (munmap(addr, buf.st_size) == -1)
#define ABORT_IFNOT(condition, msg)
#define READ_CREATE_EDGE_FWD(GType)
#define READ_CREATE_NODE_FWD(GType)
static const Option< bool > humanReadableOption("human-readable", "Whether to output human-readable JSON", true)
#define JSON_READ_OBJ_FWD(json, obj)
#define FIELD_NAME_ITEM(field)
#define JSON_DEF_READ_FWD(json, type, obj,...)
#define JSON_READ_FIELD_FWD(json, objptr, field)
#define ENSURE_NOT_VISITED(graph)
#define CHECK_JSON_KEY(obj)
#define JSON_WRITE_FIELD(root, objptr, field)
const char *const const double number
Common base for class hierarchy graph. Only implements what PointerAnalysis needs.
GEdgeKind getEdgeKind() const
void createObjs(const cJSON *graphJson, NodeCreator nodeCreator, EdgeCreator edgeCreator)
void saveToGenericGraph(GenericGraph< NodeTy, EdgeTy > *graph) const
EdgeTy * getEdgePtr(unsigned id) const
const cJSON * getFieldJson() const
NodeTy * getNodePtr(unsigned id) const
void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller)
size_t getEdgeID(const EdgeType *edge)
WriterPtrPool< EdgeType > edgePool
SVFLoop * getSVFLoopPtr(size_t id) const
void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller, LoopFiller loopFiller)
void createObjs(const cJSON *icfgJson, NodeCreator nodeCreator, EdgeCreator edgeCreator, SVFLoopCreator svfLoopCreator)
WriterPtrPool< SVFLoop > svfLoopPool
size_t getSvfLoopID(const SVFLoop *loop)
ICFGWriter(const ICFG *icfg)
const ICFGNodeToSVFLoopVec & getIcfgNodeToSVFLoopVec() const
ValueToEdgeMap valueToEdgeMap
Map SVFValues (e.g., ICFGNodes) to all corresponding PAGEdges.
SymbolTableInfo * symInfo
SymID getId() const
Get the memory object id.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
enum Strategy strategy
Strategy to allocate with.
static NodeIDAllocator * allocator
Single allocator.
Strategy
Allocation strategy to use.
u32_t elemNum
Size of the object or number of elements.
GNodeK getNodeKind() const
Get node kind.
NodeID getId() const
Get ID.
IRGraphReader irGraphReader
SVFModuleReader svfModuleReader
static CHNode * createCHNode(NodeID id, GNodeK kind)
static ICFGEdge * createICFGEdge(GEdgeKind kind)
void fill(const cJSON *&fieldJson, SVFVar *var)
GenericEdge< void >::GEdgeKind GEdgeKind
static void readJson(const cJSON *obj, bool &flag)
static ICFGNode * createICFGNode(NodeID id, GNodeK type)
static CHEdge * createCHEdge(GEdgeKind kind)
static SVFStmt * createPAGEdge(GEdgeKind kind)
CHGraphReader chGraphReader
static SVFIR * read(const std::string &path)
const cJSON * createObjs(const cJSON *root)
static SVFVar * createPAGNode(NodeID id, GNodeK kind)
void virtFill(const cJSON *&fieldJson, SVFVar *var)
SymbolTableInfoReader symTableReader
const char * numToStr(size_t n)
static void writeJsonToOstream(const SVFIR *svfir, std::ostream &os)
std::unique_ptr< char, decltype(&cJSON_free)> autoCStr
static void writeJsonToPath(const SVFIR *svfir, const std::string &path)
std::unique_ptr< cJSON, decltype(&cJSON_Delete)> autoJSON
cJSON * genericNodeToJson(const GenericNode< NodeTy, EdgeTy > *node)
OrderedMap< size_t, std::string > numToStrMap
autoJSON generateJson()
Main logic to dump a SVFIR to a JSON object.
cJSON * toJson(const NodeIDAllocator *nodeIDAllocator)
cJSON * genericGraphToJson(const GenericGraph< NodeTy, EdgeTy > *graph, const std::vector< const EdgeTy * > &edgePool)
IRGraphWriter irGraphWriter
SVFIRWriter(const SVFIR *svfir)
Constructor.
SVFModuleWriter svfModuleWriter
cJSON * contentToJson(const SVFVar *var)
autoCStr generateJsonString()
bool jsonAddJsonableToObject(cJSON *obj, const char *name, const T &item)
cJSON * virtToJson(const SVFType *type)
Parameter types of these functions are all pointers. When they are used as arguments of toJson(),...
cJSON * genericEdgeToJson(const GenericEdge< NodeTy > *edge)
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
ReaderPtrPool< StInfo > stInfoPool
StInfo * getStInfoPtr(size_t id) const
void createObjs(const cJSON *svfModuleJson, SVFTypeCreator typeCreator, SVFTypeFiller typeFiller, SVFValueCreator valueCreator, SVFValueFiller valueFiller, StInfoCreator stInfoCreator)
ReaderPtrPool< SVFType > svfTypePool
SVFValue * getSVFValuePtr(size_t id) const
SVFType * getSVFTypePtr(size_t id) const
const cJSON * getFieldJson() const
size_t getSVFValueID(const SVFValue *value)
size_t sizeSVFValuePool() const
const SVFValue * getSVFValuePtr(size_t id) const
SVFModuleWriter(const SVFModule *svfModule)
WriterPtrPool< SVFValue > svfValuePool
size_t getStInfoID(const StInfo *stInfo)
size_t getSVFTypeID(const SVFType *type)
WriterPtrPool< StInfo > stInfoPool
WriterPtrPool< SVFType > svfTypePool
const ConstantType & getConstantSet() const
static SVFModule * getSVFModule()
const FunctionSetType & getFunctionSet() const
const OtherValueType & getOtherValueSet() const
GNodeK getKind() const
Get the type of this SVFValue.
ReaderIDToObjMap< MemObj > memObjMap
void createObjs(const cJSON *symTabJson, MemObjCreator memObjCreator)
MemObj * getMemObjPtr(unsigned id) const
const cJSON * getFieldJson() const
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.
static SymbolTableInfo * symInfo
IDToMemMapTy objMap
map a memory sym id to its obj
const std::vector< const T * > & getPool() const
long long strtoll(const char *str, char **endptr, int base)
unsigned long long strtoull(const char *str, char **endptr, int base)
unsigned long int strtoul(const char *str, char **endptr, int base)
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
std::ostream & errs()
Overwrite llvm::errs()
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
bool jsonAddNumberToObject(cJSON *obj, const char *name, double number)
Helper function to write a number to a JSON object.
cJSON * jsonCreateNullId()
double jsonGetNumber(const cJSON *item)
static void readSmallNumber(const cJSON *obj, SmallNumberType &val)
cJSON * jsonCreateNumber(double num)
bool jsonKeyEquals(const cJSON *item, const char *key)
bool jsonIsNumber(const cJSON *item)
bool jsonIsNullId(const cJSON *item)
static SVFValue * createSVFValue(SVFValue::GNodeK kind, const SVFType *type, std::string &&name)
bool jsonAddPairToMap(cJSON *obj, cJSON *key, cJSON *value)
bool jsonIsMap(const cJSON *item)
cJSON * jsonCreateBool(bool flag)
bool jsonIsArray(const cJSON *item)
bool jsonAddItemToArray(cJSON *array, cJSON *item)
SVFType * createSVFType(SVFType::GNodeK kind, bool isSingleValTy)
bool jsonAddStringToObject(cJSON *obj, const char *name, const char *str)
std::pair< const cJSON *, const cJSON * > jsonUnpackPair(const cJSON *item)
bool jsonIsObject(const cJSON *item)
static void readBigNumber(const cJSON *obj, BigNumberType &val, CStrToVal conv)
cJSON * jsonCreateObject()
bool jsonAddItemToObject(cJSON *obj, const char *name, cJSON *item)
bool jsonIsBool(const cJSON *item)
cJSON * jsonCreateString(const char *str)
bool jsonIsString(const cJSON *item)
cJSON * jsonCreateIndex(size_t index)
cJSON * jsonCreateArray()