From b827181c3d675580c9f305fe4c30e4bd8d85e357 Mon Sep 17 00:00:00 2001 From: "jason.zhongzexin@gmail.com" <42635164+JasonZhongZexin@users.noreply.github.com> Date: Sat, 8 Feb 2020 20:44:11 +0800 Subject: [PATCH 1/9] read from json file read pag from json file --- include/MemoryModel/PAGBuilderFromFile.h | 2 + lib/MemoryModel/PAGBuilderFromFile.cpp | 193 +++++++++++++---------- 2 files changed, 112 insertions(+), 83 deletions(-) diff --git a/include/MemoryModel/PAGBuilderFromFile.h b/include/MemoryModel/PAGBuilderFromFile.h index fcfd7c9e5..99acdb7bd 100644 --- a/include/MemoryModel/PAGBuilderFromFile.h +++ b/include/MemoryModel/PAGBuilderFromFile.h @@ -63,6 +63,8 @@ class PAGBuilderFromFile { /// Start building PAG* build(); + void addNode(NodeID s_id, std::string node_type); + // Add edges void addEdge(NodeID nodeSrc, NodeID nodeDst, Size_t offset, std::string edge); diff --git a/lib/MemoryModel/PAGBuilderFromFile.cpp b/lib/MemoryModel/PAGBuilderFromFile.cpp index b55c1fab7..0b512aee9 100644 --- a/lib/MemoryModel/PAGBuilderFromFile.cpp +++ b/lib/MemoryModel/PAGBuilderFromFile.cpp @@ -31,92 +31,119 @@ #include // for PAGBuilderFromFile #include // for PAGBuilderFromFile #include // for PAGBuilderFromFile +#include "llvm/Support/JSON.h" using namespace std; using namespace SVFUtil; static u32_t gepNodeNumIndex = 100000; -/* - * You can build a PAG from a file written by yourself - * - * The file should follow the format: - * Node: nodeID Nodetype - * Edge: nodeID edgetype NodeID Offset - * - * like: -5 o -6 v -7 v -8 v -9 v -5 addr 6 0 -6 gep 7 4 -7 copy 8 0 -6 store 8 0 -8 load 9 0 - */ +void PAGBuilderFromFile::addNode(NodeID ID, string node_type){ + // outs()<<"type:"<addDummyValNode(ID); + // outs()<<"add dummyvalnode:"<addDummyMemObj(ID, NULL); + pag->addFIObjNode(mem); + // outs()<<"add FIOBJNODE:"<> tmps; - token_count++; - } - - if (token_count == 0) - continue; - - else if (token_count == 2) { - NodeID nodeId; - string nodetype; - istringstream ss(line); - ss >> nodeId; - ss >> nodetype; - outs() << "reading node :" << nodeId << "\n"; - if (nodetype == "v") - pag->addDummyValNode(nodeId); - else if (nodetype == "o") { - const MemObj* mem = pag->addDummyMemObj(nodeId, NULL); - pag->addFIObjNode(mem); - } else - assert(false && "format not support, pls specify node type"); - } - - // do consider gep edge - else if (token_count == 4) { - NodeID nodeSrc; - NodeID nodeDst; - Size_t offsetOrCSId; - string edge; - istringstream ss(line); - ss >> nodeSrc; - ss >> edge; - ss >> nodeDst; - ss >> offsetOrCSId; - outs() << "reading edge :" << nodeSrc << " " << edge << " " - << nodeDst << " offsetOrCSId=" << offsetOrCSId << " \n"; - addEdge(nodeSrc, nodeDst, offsetOrCSId, edge); - } else { - if (!line.empty()) { - outs() << "format not supported, token count = " - << token_count << "\n"; - assert(false && "format not supported"); + if(myfile.is_open()){ + std::stringstream jsonStringStream; + while(myfile >> jsonStringStream.rdbuf()); + llvm::json::Value root_value = llvm::json::parse(jsonStringStream.str()).get(); + llvm::json::Object* root_obj; + root_obj = root_value.getAsObject(); + + //get the Instructions array + llvm::json::Value* root_array_value; + root_array_value= root_obj->get("Instructions"); + llvm::json::Array* root_array; + root_array = root_array_value->getAsArray(); + + //get the global edge array + llvm::json::Value* global_edges_value; + global_edges_value = root_obj->get("global edge"); + llvm::json::Array* global_edges_array; + global_edges_array = global_edges_value->getAsArray(); + + for(llvm::json::Array::const_iterator it = root_array->begin(); + it!=root_array->end();it++){ + llvm::json::Value currentInst_value = *it; + llvm::json::Object* currentInst_obj; + currentInst_obj = currentInst_value.getAsObject(); + llvm::json::Value* edges_array_value; + edges_array_value = currentInst_obj->get("edges"); + llvm::json::Array* edges_array; + edges_array = edges_array_value->getAsArray(); + for(llvm::json::Array::const_iterator eit = edges_array->begin(); + eit!=edges_array->end(); eit++){ + llvm::json::Value edge_value = *eit; + llvm::json::Object* edge_obj; + edge_obj = edge_value.getAsObject(); + NodeID source_node; + source_node = edge_obj->get("source node")->getAsInteger().getValue(); + NodeID destination_node; + destination_node = edge_obj->get("destination node")->getAsInteger().getValue(); + string source_node_type; + source_node_type = edge_obj->get("source node type")->getAsString()->str(); + string destination_node_type; + destination_node_type = edge_obj->get("destination node type")->getAsString()->str(); + string edge_type; + edge_type = edge_obj->get("edge type")->getAsString()->str(); + llvm::json::Value* offset_value = edge_obj->get("offset"); + string offset; + if(offset_value!=NULL){ + offset = offset_value->getAsString()->str(); + } + //add new node + if(!pag->hasGNode(source_node)){ + addNode(source_node,source_node_type); + }else if(!pag->hasGNode(destination_node)){ + addNode(destination_node,destination_node_type); + }else{ + addEdge(source_node, destination_node, std::stol(offset), edge_type); } } } + for(llvm::json::Array::const_iterator it = global_edges_array->begin(); + it!=global_edges_array->end();it++){ + llvm::json::Object global_edge_obj = *it->getAsObject(); + NodeID source_node; + source_node = global_edge_obj.get("source node")->getAsInteger().getValue(); + NodeID destination_node; + destination_node = global_edge_obj.get("destination node")->getAsInteger().getValue(); + string source_node_type; + source_node_type = global_edge_obj.get("source node type")->getAsString()->str(); + string destination_node_type; + destination_node_type = global_edge_obj.get("destination node type")->getAsString()->str(); + string edge_type; + edge_type = global_edge_obj.get("edge type")->getAsString()->str(); + llvm::json::Value* offset_value = global_edge_obj.get("offset"); + string offset; + if(offset_value!=NULL) + offset = offset_value->getAsString()->str(); + //add new node + if(!pag->hasGNode(source_node)){ + addNode(source_node,source_node_type); + }else if(!pag->hasGNode(destination_node)){ + addNode(destination_node,destination_node_type); + }else{ + addEdge(source_node, destination_node, std::stol(offset), edge_type); + } + } myfile.close(); - } - - else + }else{ outs() << "Unable to open file\n"; + } /// new gep node's id from lower bound, nodeNum may not reflect the total nodes. u32_t lower_bound = gepNodeNumIndex; @@ -145,26 +172,26 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID, else assert(!SVFUtil::isa(srcNode) && "src not an object node?"); - if (edge == "addr"){ + if (edge == "Addr"){ pag->addAddrEdge(srcID, dstID); } - else if (edge == "copy") + else if (edge == "Copy") pag->addCopyEdge(srcID, dstID); - else if (edge == "load") + else if (edge == "Load") pag->addLoadEdge(srcID, dstID); - else if (edge == "store") + else if (edge == "Store") pag->addStoreEdge(srcID, dstID); - else if (edge == "gep") + else if (edge == "NormalGep") pag->addNormalGepEdge(srcID, dstID, LocationSet(offsetOrCSId)); - else if (edge == "variant-gep") + else if (edge == "VariantGep") pag->addVariantGepEdge(srcID, dstID); - else if (edge == "call") + else if (edge == "Call") pag->addEdge(srcNode, dstNode, new CallPE(srcNode, dstNode, NULL)); - else if (edge == "ret") + else if (edge == "Ret") pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, NULL)); - else if (edge == "cmp") + else if (edge == "Cmp") pag->addCmpEdge(srcID, dstID); - else if (edge == "binary-op") + else if (edge == "BinaryOp") pag->addBinaryOPEdge(srcID, dstID); else assert(false && "format not support, can not create such edge"); From b81f9d8002fd3fa404acd2a31747f496c56b1056 Mon Sep 17 00:00:00 2001 From: JasonZhongZexin Date: Wed, 26 Feb 2020 11:32:32 +0800 Subject: [PATCH 2/9] build pag from json file --- include/MemoryModel/PAGBuilderFromFile.h | 4 + lib/CMakeLists.txt | 2 + lib/MemoryModel/PAGBuilderFromFile.cpp | 193 +++++++++++++---------- lib/Util/PTACallGraph.cpp | 1 + 4 files changed, 117 insertions(+), 83 deletions(-) diff --git a/include/MemoryModel/PAGBuilderFromFile.h b/include/MemoryModel/PAGBuilderFromFile.h index fcfd7c9e5..f156b103d 100644 --- a/include/MemoryModel/PAGBuilderFromFile.h +++ b/include/MemoryModel/PAGBuilderFromFile.h @@ -63,6 +63,10 @@ class PAGBuilderFromFile { /// Start building PAG* build(); + // PAG* buildFromJSON(); + + void addNode(NodeID s_id, std::string node_type); + // Add edges void addEdge(NodeID nodeSrc, NodeID nodeDst, Size_t offset, std::string edge); diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index b0adb8eb7..e9e7f9382 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -7,6 +7,8 @@ set(SOURCES Util/SVFUtil.cpp Util/CPPUtil.cpp Util/DataFlowUtil.cpp + Util/SVFFunction.cpp + Util/SVFPTACallGraph.cpp Util/PTACallGraph.cpp Util/RaceAnnotator.cpp Util/ThreadCallGraph.cpp diff --git a/lib/MemoryModel/PAGBuilderFromFile.cpp b/lib/MemoryModel/PAGBuilderFromFile.cpp index b55c1fab7..c8dfc331d 100644 --- a/lib/MemoryModel/PAGBuilderFromFile.cpp +++ b/lib/MemoryModel/PAGBuilderFromFile.cpp @@ -31,92 +31,119 @@ #include // for PAGBuilderFromFile #include // for PAGBuilderFromFile #include // for PAGBuilderFromFile +#include "llvm/Support/JSON.h" using namespace std; using namespace SVFUtil; static u32_t gepNodeNumIndex = 100000; -/* - * You can build a PAG from a file written by yourself - * - * The file should follow the format: - * Node: nodeID Nodetype - * Edge: nodeID edgetype NodeID Offset - * - * like: -5 o -6 v -7 v -8 v -9 v -5 addr 6 0 -6 gep 7 4 -7 copy 8 0 -6 store 8 0 -8 load 9 0 - */ +void PAGBuilderFromFile::addNode(NodeID ID, string node_type){ + if(node_type=="DummyValNode"){ + pag->addDummyValNode(ID); + } + if(node_type=="FIObjNode"){ + const MemObj* mem = pag->addDummyMemObj(ID, NULL); + pag->addFIObjNode(mem); + } + if(node_type == "DummyObjNode"){ + pag->addDummyObjNode(ID); + } + // else + // assert(false && "format not support, pls specify node type"); + +} + PAG* PAGBuilderFromFile::build() { - string line; ifstream myfile(file.c_str()); - if (myfile.is_open()) { - while (myfile.good()) { - getline(myfile, line); - - Size_t token_count = 0; - string tmps; - istringstream ss(line); - while (ss.good()) { - ss >> tmps; - token_count++; - } - - if (token_count == 0) - continue; - - else if (token_count == 2) { - NodeID nodeId; - string nodetype; - istringstream ss(line); - ss >> nodeId; - ss >> nodetype; - outs() << "reading node :" << nodeId << "\n"; - if (nodetype == "v") - pag->addDummyValNode(nodeId); - else if (nodetype == "o") { - const MemObj* mem = pag->addDummyMemObj(nodeId, NULL); - pag->addFIObjNode(mem); - } else - assert(false && "format not support, pls specify node type"); - } - - // do consider gep edge - else if (token_count == 4) { - NodeID nodeSrc; - NodeID nodeDst; - Size_t offsetOrCSId; - string edge; - istringstream ss(line); - ss >> nodeSrc; - ss >> edge; - ss >> nodeDst; - ss >> offsetOrCSId; - outs() << "reading edge :" << nodeSrc << " " << edge << " " - << nodeDst << " offsetOrCSId=" << offsetOrCSId << " \n"; - addEdge(nodeSrc, nodeDst, offsetOrCSId, edge); - } else { - if (!line.empty()) { - outs() << "format not supported, token count = " - << token_count << "\n"; - assert(false && "format not supported"); + if(myfile.is_open()){ + std::stringstream jsonStringStream; + while(myfile >> jsonStringStream.rdbuf()); + llvm::json::Value root_value = llvm::json::parse(jsonStringStream.str()).get(); + llvm::json::Object* root_obj; + root_obj = root_value.getAsObject(); + + //get the Instructions array + llvm::json::Value* root_array_value; + root_array_value= root_obj->get("Instructions"); + llvm::json::Array* root_array; + root_array = root_array_value->getAsArray(); + + //get the global edge array + llvm::json::Value* global_edges_value; + global_edges_value = root_obj->get("global edge"); + llvm::json::Array* global_edges_array; + global_edges_array = global_edges_value->getAsArray(); + + for(llvm::json::Array::const_iterator it = root_array->begin(); + it!=root_array->end();it++){ + llvm::json::Value currentInst_value = *it; + llvm::json::Object* currentInst_obj; + currentInst_obj = currentInst_value.getAsObject(); + llvm::json::Value* edges_array_value; + edges_array_value = currentInst_obj->get("edges"); + llvm::json::Array* edges_array; + edges_array = edges_array_value->getAsArray(); + for(llvm::json::Array::const_iterator eit = edges_array->begin(); + eit!=edges_array->end(); eit++){ + llvm::json::Value edge_value = *eit; + llvm::json::Object* edge_obj; + edge_obj = edge_value.getAsObject(); + NodeID source_node; + source_node = edge_obj->get("source node")->getAsInteger().getValue(); + NodeID destination_node; + destination_node = edge_obj->get("destination node")->getAsInteger().getValue(); + string source_node_type; + source_node_type = edge_obj->get("source node type")->getAsString()->str(); + string destination_node_type; + destination_node_type = edge_obj->get("destination node type")->getAsString()->str(); + string edge_type; + edge_type = edge_obj->get("edge type")->getAsString()->str(); + llvm::json::Value* offset_value = edge_obj->get("offset"); + string offset; + if(offset_value!=NULL){ + offset = offset_value->getAsString()->str(); + } + //add new node + if(!pag->hasGNode(source_node)){ + addNode(source_node,source_node_type); + }else if(!pag->hasGNode(destination_node)){ + addNode(destination_node,destination_node_type); + }else{ + addEdge(source_node, destination_node, std::stol(offset), edge_type); } } } + for(llvm::json::Array::const_iterator it = global_edges_array->begin(); + it!=global_edges_array->end();it++){ + llvm::json::Object global_edge_obj = *it->getAsObject(); + NodeID source_node; + source_node = global_edge_obj.get("source node")->getAsInteger().getValue(); + NodeID destination_node; + destination_node = global_edge_obj.get("destination node")->getAsInteger().getValue(); + string source_node_type; + source_node_type = global_edge_obj.get("source node type")->getAsString()->str(); + string destination_node_type; + destination_node_type = global_edge_obj.get("destination node type")->getAsString()->str(); + string edge_type; + edge_type = global_edge_obj.get("edge type")->getAsString()->str(); + llvm::json::Value* offset_value = global_edge_obj.get("offset"); + string offset; + if(offset_value!=NULL) + offset = offset_value->getAsString()->str(); + //add new node + if(!pag->hasGNode(source_node)){ + addNode(source_node,source_node_type); + }else if(!pag->hasGNode(destination_node)){ + addNode(destination_node,destination_node_type); + }else{ + addEdge(source_node, destination_node, std::stol(offset), edge_type); + } + } myfile.close(); - } - - else + }else{ outs() << "Unable to open file\n"; + } /// new gep node's id from lower bound, nodeNum may not reflect the total nodes. u32_t lower_bound = gepNodeNumIndex; @@ -145,26 +172,26 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID, else assert(!SVFUtil::isa(srcNode) && "src not an object node?"); - if (edge == "addr"){ + if (edge == "Addr"){ pag->addAddrEdge(srcID, dstID); } - else if (edge == "copy") + else if (edge == "Copy") pag->addCopyEdge(srcID, dstID); - else if (edge == "load") + else if (edge == "Load") pag->addLoadEdge(srcID, dstID); - else if (edge == "store") + else if (edge == "Store") pag->addStoreEdge(srcID, dstID); - else if (edge == "gep") + else if (edge == "NormalGep") pag->addNormalGepEdge(srcID, dstID, LocationSet(offsetOrCSId)); - else if (edge == "variant-gep") + else if (edge == "VariantGep") pag->addVariantGepEdge(srcID, dstID); - else if (edge == "call") + else if (edge == "Call") pag->addEdge(srcNode, dstNode, new CallPE(srcNode, dstNode, NULL)); - else if (edge == "ret") + else if (edge == "Ret") pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, NULL)); - else if (edge == "cmp") + else if (edge == "Cmp") pag->addCmpEdge(srcID, dstID); - else if (edge == "binary-op") + else if (edge == "BinaryOp") pag->addBinaryOPEdge(srcID, dstID); else assert(false && "format not support, can not create such edge"); diff --git a/lib/Util/PTACallGraph.cpp b/lib/Util/PTACallGraph.cpp index b352c89f8..c5a00a68b 100644 --- a/lib/Util/PTACallGraph.cpp +++ b/lib/Util/PTACallGraph.cpp @@ -30,6 +30,7 @@ #include "Util/SVFModule.h" #include "Util/PTACallGraph.h" +#include "Util/SVFFunction.h" using namespace SVFUtil; From 62e52bd855f381aa8f4b0faa2bec6c47eee873e9 Mon Sep 17 00:00:00 2001 From: JasonZhongZexin Date: Thu, 5 Mar 2020 17:20:21 +0800 Subject: [PATCH 3/9] add icfg builder --- include/MemoryModel/ICFGBuilderFromFile.h | 41 +++ include/MemoryModel/PAGBuilderFromFile.h | 5 +- include/Util/ICFG.h | 16 +- include/Util/SVFFunction.h | 17 ++ include/Util/SVFPTACallGraph.h | 350 ++++++++++++++++++++++ lib/CMakeLists.txt | 1 + lib/MemoryModel/ICFGBuilderFromFile.cpp | 96 ++++++ lib/MemoryModel/PAGBuilderFromFile.cpp | 55 ++++ lib/MemoryModel/PointerAnalysis.cpp | 8 +- lib/Util/ICFG.cpp | 2 + lib/Util/SVFFunction.cpp | 17 ++ lib/Util/SVFPTACallGraph.cpp | 182 +++++++++++ 12 files changed, 779 insertions(+), 11 deletions(-) create mode 100644 include/MemoryModel/ICFGBuilderFromFile.h create mode 100644 include/Util/SVFFunction.h create mode 100644 include/Util/SVFPTACallGraph.h create mode 100644 lib/MemoryModel/ICFGBuilderFromFile.cpp create mode 100644 lib/Util/SVFFunction.cpp create mode 100644 lib/Util/SVFPTACallGraph.cpp diff --git a/include/MemoryModel/ICFGBuilderFromFile.h b/include/MemoryModel/ICFGBuilderFromFile.h new file mode 100644 index 000000000..3dc735bad --- /dev/null +++ b/include/MemoryModel/ICFGBuilderFromFile.h @@ -0,0 +1,41 @@ +#ifndef INCLUDE_MEMORYMODEL_ICFGBUILDERFROMFILE_H_ +#define INCLUDE_MEMORYMODEL_ICFGBUILDERFROMFILE_H_ + +#include "Util/ICFG.h" +#include "llvm/Support/JSON.h" + + +/*! + * Build ICFG from a user specified file + */ +class ICFGBuilderFromFile{ + +private: + ICFG* icfg; + std::string file; + +public: + //Constructor + ICFGBuilderFromFile(std::string f){} + + // Destructor + ~ICFGBuilderFromFile() {} + + // Return ICFG + ICFG* getICFG() const{ + return icfg; + } + + std::string getFileName() const { + return file; + } + + //Start building + ICFG* build(); + + void addNode(NodeID nodeID, std::string nodeType); + + void addEdge(llvm::json::Object* edge_obj); +}; + +#endif /* INCLUDE_MEMORYMODEL_ICFGBUILDERFROMFILE_H_ */ \ No newline at end of file diff --git a/include/MemoryModel/PAGBuilderFromFile.h b/include/MemoryModel/PAGBuilderFromFile.h index f156b103d..3bd18cb15 100644 --- a/include/MemoryModel/PAGBuilderFromFile.h +++ b/include/MemoryModel/PAGBuilderFromFile.h @@ -31,6 +31,7 @@ #define INCLUDE_MEMORYMODEL_PAGBUILDERFROMFILE_H_ #include "MemoryModel/PAG.h" +#include "Util/ICFG.h" /*! @@ -60,11 +61,11 @@ class PAGBuilderFromFile { return file; } + PAG* buildFromICFG(); + /// Start building PAG* build(); - // PAG* buildFromJSON(); - void addNode(NodeID s_id, std::string node_type); // Add edges diff --git a/include/Util/ICFG.h b/include/Util/ICFG.h index 009952bf1..77db00249 100644 --- a/include/Util/ICFG.h +++ b/include/Util/ICFG.h @@ -82,6 +82,7 @@ class ICFG : public GenericICFGTy { public: /// Constructor ICFG(PTACallGraph* callgraph); + ICFG(); /// Destructor virtual ~ICFG() { @@ -120,6 +121,14 @@ class ICFG : public GenericICFGTy { ICFGEdge* hasThreadICFGEdge(ICFGNode* src, ICFGNode* dst, ICFGEdge::ICFGEdgeK kind); //@} + + /// Add control-flow edges for top level pointers + //@{ + ICFGEdge* addIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode); + ICFGEdge* addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, CallSiteID csId); + ICFGEdge* addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, CallSiteID csId); + //@} + /// Get a SVFG edge according to src and dst ICFGEdge* getICFGEdge(const ICFGNode* src, const ICFGNode* dst, ICFGEdge::ICFGEdgeK kind); @@ -154,13 +163,6 @@ class ICFG : public GenericICFGTy { removeGNode(node); } - /// Add control-flow edges for top level pointers - //@{ - ICFGEdge* addIntraEdge(ICFGNode* srcNode, ICFGNode* dstNode); - ICFGEdge* addCallEdge(ICFGNode* srcNode, ICFGNode* dstNode, CallSiteID csId); - ICFGEdge* addRetEdge(ICFGNode* srcNode, ICFGNode* dstNode, CallSiteID csId); - //@} - /// sanitize Intra edges, verify that both nodes belong to the same function. inline void checkIntraEdgeParents(const ICFGNode *srcNode, const ICFGNode *dstNode) { const BasicBlock *srcBB = srcNode->getBB(); diff --git a/include/Util/SVFFunction.h b/include/Util/SVFFunction.h new file mode 100644 index 000000000..0f76b1c3f --- /dev/null +++ b/include/Util/SVFFunction.h @@ -0,0 +1,17 @@ +#ifndef SVFFUNCTION_H_ +#define SVFFUNCTION_H_ + +#include "Util/BasicTypes.h" + +class SVFFunction +{ + private: + std::string functionName; + public: + SVFFunction(); + SVFFunction(std::string functionName); + std::string getFunctionName(); + void setFunctionName(std::string functionName); +}; + +#endif \ No newline at end of file diff --git a/include/Util/SVFPTACallGraph.h b/include/Util/SVFPTACallGraph.h new file mode 100644 index 000000000..96ffc93b8 --- /dev/null +++ b/include/Util/SVFPTACallGraph.h @@ -0,0 +1,350 @@ +// #ifndef SVFPTACALLGRAPH_H_ +// #define SVFPTACALLGRAPH_H_ + +// #include "MemoryModel/GenericGraph.h" +// #include "Util/SVFUtil.h" +// #include "Util/BasicTypes.h" +// #include "Util/SVFFunction.h" +// #include + +// class PTACallGraphNode; +// class SVFModule; + +// /* +// * Call Graph edge representing a calling relation between two functions +// * Multiple calls from function A to B are merged into one call edge +// * Each call edge has a set of direct callsites and a set of indirect callsites +// */ +// typedef GenericEdge GenericCallGraphEdgeTy; +// class PTACallGraphEdge : public GenericCallGraphEdgeTy { + +// public: +// typedef std::set CallInstSet; +// enum CEDGEK { +// CallRetEdge,TDForkEdge,TDJoinEdge,HareParForEdge +// }; + + +// private: +// CallInstSet directCalls; +// CallInstSet indirectCalls; +// CallSiteID csId; +// public: +// /// Constructor +// PTACallGraphEdge(PTACallGraphNode* s, PTACallGraphNode* d, CEDGEK kind, CallSiteID cs) : +// GenericCallGraphEdgeTy(s, d, makeEdgeFlagWithInvokeID(kind, cs)), csId(cs) { +// } +// /// Destructor +// virtual ~PTACallGraphEdge() { +// } +// /// Compute the unique edgeFlag value from edge kind and CallSiteID. +// static inline GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs) { +// return (cs << EdgeKindMaskBits) | k; +// } +// /// Get direct and indirect calls +// //@{ +// inline CallSiteID getCallSiteID() const { +// return csId; +// } +// inline bool isDirectCallEdge() const { +// return !directCalls.empty() && indirectCalls.empty(); +// } +// inline bool isIndirectCallEdge() const { +// return directCalls.empty() && !indirectCalls.empty(); +// } +// inline CallInstSet& getDirectCalls() { +// return directCalls; +// } +// inline CallInstSet& getIndirectCalls() { +// return indirectCalls; +// } +// inline const CallInstSet& getDirectCalls() const { +// return directCalls; +// } +// inline const CallInstSet& getIndirectCalls() const { +// return indirectCalls; +// } +// //@} + +// /// Add direct and indirect callsite +// //@{ +// void addDirectCallSite(const std::string* call) { +// // assert((SVFUtil::isa(call) || SVFUtil::isa(call)) && "not a call or inovke??"); +// // assert(SVFUtil::getCallee(call) && "not a direct callsite??"); +// directCalls.insert(call); +// } + +// void addInDirectCallSite(const std::string* call) { +// // assert((SVFUtil::isa(call) || SVFUtil::isa(call)) && "not a call or inovke??"); +// // assert((NULL == SVFUtil::getCallee(call) || NULL == SVFUtil::dyn_cast (SVFUtil::getForkedFun(call))) && "not an indirect callsite??"); +// indirectCalls.insert(call); +// } +// //@} + +// /// Iterators for direct and indirect callsites +// //@{ +// inline CallInstSet::iterator directCallsBegin() const { +// return directCalls.begin(); +// } +// inline CallInstSet::iterator directCallsEnd() const { +// return directCalls.end(); +// } + +// inline CallInstSet::iterator indirectCallsBegin() const { +// return indirectCalls.begin(); +// } +// inline CallInstSet::iterator indirectCallsEnd() const { +// return indirectCalls.end(); +// } +// //@} + +// /// ClassOf +// //@{ +// static inline bool classof(const PTACallGraphEdge *edge) { +// return true; +// } +// static inline bool classof(const GenericCallGraphEdgeTy *edge) { +// return edge->getEdgeKind() == PTACallGraphEdge::CallRetEdge || +// edge->getEdgeKind() == PTACallGraphEdge::TDForkEdge || +// edge->getEdgeKind() == PTACallGraphEdge::TDJoinEdge; +// } +// //@} + +// typedef GenericNode::GEdgeSetTy CallGraphEdgeSet; + +// }; + +// /* +// * Call Graph node representing a function +// */ +// typedef GenericNode GenericCallGraphNodeTy; +// class PTACallGraphNode : public GenericCallGraphNodeTy { + +// public: +// typedef PTACallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; +// typedef PTACallGraphEdge::CallGraphEdgeSet::iterator iterator; +// typedef PTACallGraphEdge::CallGraphEdgeSet::const_iterator const_iterator; + +// private: +// const SVFFunction* fun; + +// public: +// /// Constructor +// PTACallGraphNode(NodeID i, const SVFFunction* f) : GenericCallGraphNodeTy(i,0), fun(f) { + +// } + +// /// Get function of this call node +// inline const SVFFunction* getFunction() const { +// return fun; +// } + +// /// Return TRUE if this function can be reached from main. +// bool isReachableFromProgEntry() const; +// }; + +// /*! +// * Pointer Analysis Call Graph used internally for various pointer analysis +// */ +// typedef GenericGraph GenericCallGraphTy; +// class SVFPTACallGraph : public GenericCallGraphTy { + +// public: +// typedef PTACallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; +// typedef llvm::DenseMap FunToCallGraphNodeMap; +// typedef llvm::DenseMap CallInstToCallGraphEdgesMap; +// typedef std::pair CallSitePair; +// typedef std::map CallSiteToIdMap; +// typedef std::map IdToCallSiteMap; +// typedef std::set FunctionSet; +// typedef std::map CallEdgeMap; +// typedef CallGraphEdgeSet::iterator CallGraphNodeIter; + +// enum CGEK { +// NormCallGraph, ThdCallGraph +// }; + +// private: +// CGEK kind; + +// SVFModule svfMod; + +// /// Indirect call map +// CallEdgeMap indirectCallMap; + +// /// Call site information +// static CallSiteToIdMap csToIdMap; ///< Map a pair of call instruction and callee to a callsite ID +// static IdToCallSiteMap idToCSMap; ///< Map a callsite ID to a pair of call instruction and callee +// static CallSiteID totalCallSiteNum; ///< CallSiteIDs, start from 1; + +// protected: +// FunToCallGraphNodeMap funToCallGraphNodeMap; ///< Call Graph node map +// CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap; ///< Map a call instruction to its corresponding call edges + +// NodeID callGraphNodeNum; +// Size_t numOfResolvedIndCallEdge; + +// /// Build Call Graph +// void buildCallGraph(SVFModule svfModule); + +// /// Add callgraph Node +// void addCallGraphNode(const SVFFunction* fun); + +// /// Clean up memory +// void destroy(); + +// public: +// /// Constructor +// SVFPTACallGraph(SVFModule svfModule, CGEK k = NormCallGraph); + +// /// Destructor +// virtual ~SVFPTACallGraph() { +// destroy(); +// } + +// /// Return type of this callgraph +// inline CGEK getKind() const { +// return kind; +// } + +// /// Get callees from an indirect callsite +// //@{ +// inline CallEdgeMap& getIndCallMap() { +// return indirectCallMap; +// } +// inline bool hasIndCSCallees(CallSite cs) const { +// return (indirectCallMap.find(cs) != indirectCallMap.end()); +// } +// inline const FunctionSet& getIndCSCallees(CallSite cs) const { +// CallEdgeMap::const_iterator it = indirectCallMap.find(cs); +// assert(it!=indirectCallMap.end() && "not an indirect callsite!"); +// return it->second; +// } +// inline const FunctionSet& getIndCSCallees(CallInst* csInst) const { +// CallSite cs = SVFUtil::getLLVMCallSite(csInst); +// return getIndCSCallees(cs); +// } +// //@} +// inline u32_t getTotalCallSiteNumber() const { +// return totalCallSiteNum; +// } + +// inline Size_t getNumOfResolvedIndCallEdge() const { +// return numOfResolvedIndCallEdge; +// } + +// inline const CallInstToCallGraphEdgesMap& getCallInstToCallGraphEdgesMap() const { +// return callinstToCallGraphEdgesMap; +// } + +// /// Issue a warning if the function which has indirect call sites can not be reached from program entry. +// void verifyCallGraph(); + +// /// Get call graph node +// //@{ +// inline PTACallGraphNode* getCallGraphNode(NodeID id) const { +// return getGNode(id); +// } +// inline PTACallGraphNode* getCallGraphNode(const SVFFunction* fun) const { +// FunToCallGraphNodeMap::const_iterator it = funToCallGraphNodeMap.find(fun); +// assert(it!=funToCallGraphNodeMap.end() && "call graph node not found!!"); +// return it->second; +// } +// //@} + +// /// Add/Get CallSiteID +// //@{ +// inline CallSiteID addCallSite(CallSite cs, const SVFFunction* callee) { +// std::pair newCS(std::make_pair(cs, callee)); +// CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); +// //assert(it == csToIdMap.end() && "cannot add a callsite twice"); +// if(it == csToIdMap.end()) { +// CallSiteID id = totalCallSiteNum++; +// csToIdMap.insert(std::make_pair(newCS, id)); +// idToCSMap.insert(std::make_pair(id, newCS)); +// return id; +// } +// return it->second; +// } +// inline CallSiteID getCallSiteID(CallSite cs, const SVFFunction* callee) const { +// CallSitePair newCS(std::make_pair(cs, callee)); +// CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); +// assert(it != csToIdMap.end() && "callsite id not found! This maybe a partially resolved callgraph, please check the indCallEdge limit"); +// return it->second; +// } +// inline bool hasCallSiteID(CallSite cs, const SVFFunction* callee) const { +// CallSitePair newCS(std::make_pair(cs, callee)); +// CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); +// return it != csToIdMap.end(); +// } +// inline const CallSitePair& getCallSitePair(CallSiteID id) const { +// IdToCallSiteMap::const_iterator it = idToCSMap.find(id); +// assert(it != idToCSMap.end() && "cannot find call site for this CallSiteID"); +// return (it->second); +// } +// inline CallSite getCallSite(CallSiteID id) const { +// return getCallSitePair(id).first; +// } +// // inline const SVFFunction* getCallerOfCallSite(CallSiteID id) const { +// // return getCallSite(id).getCaller(); +// // } +// inline const SVFFunction* getCalleeOfCallSite(CallSiteID id) const { +// return getCallSitePair(id).second; +// } +// //@} +// /// Get Module +// inline SVFModule getModule() { +// return svfMod; +// } +// inline SVFModule getSVFModule() { +// return svfMod; +// } +// /// Whether we have aleady created this call graph edge +// PTACallGraphEdge* hasGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId) const; +// /// Get call graph edge via nodes +// PTACallGraphEdge* getGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId); +// /// Get call graph edge via call instruction +// //@{ +// /// whether this call instruction has a valid call graph edge +// inline bool hasCallGraphEdge(const std::string* inst) const { +// return callinstToCallGraphEdgesMap.find(inst)!=callinstToCallGraphEdgesMap.end(); +// } +// inline CallGraphEdgeSet::const_iterator getCallEdgeBegin(const std::string* inst) const { +// CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst); +// assert(it!=callinstToCallGraphEdgesMap.end() +// && "call instruction does not have a valid callee"); +// return it->second.begin(); +// } +// inline CallGraphEdgeSet::const_iterator getCallEdgeEnd(const std::string* inst) const { +// CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst); +// assert(it!=callinstToCallGraphEdgesMap.end() +// && "call instruction does not have a valid callee"); +// return it->second.end(); +// } +// //@} +// /// Add call graph edge +// inline void addEdge(PTACallGraphEdge* edge) { +// edge->getDstNode()->addIncomingEdge(edge); +// edge->getSrcNode()->addOutgoingEdge(edge); +// } + +// /// Add direct/indirect call edges +// //@{ +// void addDirectCallGraphEdge(PTACallGraphNode* caller,PTACallGraphNode* callee, CallSiteID csID); +// void addIndirectCallGraphEdge(PTACallGraphNode* caller,PTACallGraphNode* callee, CallSiteID csID); +// //@} + +// /// Get callsites invoking the callee +// //@{ +// void getAllCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); +// void getDirCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); +// void getIndCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); +// //@} + +// /// Dump the graph +// void dump(const std::string& filename); +// }; + + + +// #endif /* PTACALLGRAPH_H_ */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index e9e7f9382..672e4c8bc 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -29,6 +29,7 @@ set(SOURCES MemoryModel/ExternalPAG.cpp MemoryModel/PAGBuilder.cpp MemoryModel/PAGBuilderFromFile.cpp + MemoryModel/ICFGBuilderFromFile.cpp MemoryModel/PAG.cpp MemoryModel/CHA.cpp MemoryModel/PointerAnalysis.cpp diff --git a/lib/MemoryModel/ICFGBuilderFromFile.cpp b/lib/MemoryModel/ICFGBuilderFromFile.cpp new file mode 100644 index 000000000..37b00b8a0 --- /dev/null +++ b/lib/MemoryModel/ICFGBuilderFromFile.cpp @@ -0,0 +1,96 @@ +#include "MemoryModel/ICFGBuilderFromFile.h" +#include // for ICFGBuilderFromFile +#include // for ICFGBuilderFromFile +#include // for ICFGBuilderFromFile +#include "llvm/Support/JSON.h" + +using namespace std; +using namespace SVFUtil; + +ICFG* ICFGBuilderFromFile::build(){ + icfg = new ICFG(); + ifstream myfile(file.c_str()); + if(myfile.is_open()){ + //read the json stream from file + std::stringstream jsonStringStream; + while(myfile >> jsonStringStream.rdbuf()); + + //parse the json json data + llvm::json::Value root_value = llvm::json::parse(jsonStringStream.str()).get(); + llvm::json::Array* root_array = root_value.getAsArray(); + + //add all node + for(llvm::json::Array::const_iterator it = root_array->begin(); + it!=root_array->end();it++){ + llvm::json::Value ICFG_Node_obj_val = *it; + llvm::json::Object* ICFG_Node_obj = ICFG_Node_obj_val.getAsObject(); + string node_type = ICFG_Node_obj->get("Node Type")->getAsString()->str(); + NodeID nodeID = ICFG_Node_obj->get("ICFG_ID")->getAsInteger().getValue(); + addNode(nodeID,node_type); + } + + //add all edges + for(llvm::json::Array::const_iterator it = root_array->begin(); + it!=root_array->end();it++){ + llvm::json::Value ICFG_Node_obj_val = *it; + llvm::json::Object* ICFG_Node_obj = ICFG_Node_obj_val.getAsObject(); + llvm::json::Array* icfg_edges_array = ICFG_Node_obj->get("ICFGEdges")->getAsArray(); + for(llvm::json::Array::const_iterator eit = icfg_edges_array->begin(); + eit!=icfg_edges_array->end();eit++){ + llvm::json::Value icfgEdge_value = *eit; + llvm::json::Object* icfg_edge_obj = icfgEdge_value.getAsObject(); + addEdge(icfg_edge_obj); + } + } + } + return icfg; +} + +void ICFGBuilderFromFile::addNode(NodeID nodeId, std::string nodeType){ + if(!icfg->hasICFGNode(nodeId)){ + if(nodeType=="IntraBlock"){ + ICFGNode* node = new ICFGNode(nodeId,ICFGNode::IntraBlock); + icfg->addGNode(nodeId,node); + outs()<<"adding IntraBlock node....\n"; + } + else if(nodeType=="FunEntryBlock"){ + ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunEntryBlock); + icfg->addGNode(nodeId,node); + outs()<<"adding FunEntryBlock node....\n"; + } + else if(nodeType=="FunExitBlock"){ + ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunExitBlock); + icfg->addGNode(nodeId,node); + outs()<<"adding FunExitBlock node....\n"; + } + else if(nodeType=="FunCallBlock"){ + ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunCallBlock); + icfg->addGNode(nodeId,node); + outs()<<"adding FunCallBlock node....\n"; + } + else if(nodeType=="FunRetBlock"){ + ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunCallBlock); + icfg->addGNode(nodeId,node); + outs()<<"adding FunRetBlock node....\n"; + } + } +} + +void ICFGBuilderFromFile::addEdge(llvm::json::Object* edge_obj){ + NodeID srcNodeID = edge_obj->get("ICFGEdgeSrcID")->getAsInteger().getValue(); + NodeID dstNodeID = edge_obj->get("ICFGEdgeDstID")->getAsInteger().getValue(); + ICFGNode* srcICFGNode = icfg->getICFGNode(srcNodeID); + ICFGNode* dstICFGNode = icfg->getICFGNode(dstNodeID); + std::string icfg_edge_type = edge_obj->get("ICFG Edge Type")->getAsString()->str(); + if(icfg_edge_type=="IntraCFGEdge"){ + icfg->addIntraEdge(srcICFGNode,dstICFGNode); + } + else if(icfg_edge_type=="RetCFGEdge"){ + CallSiteID csID = edge_obj->get("csID")->getAsInteger().getValue(); + icfg->addRetEdge(srcICFGNode,dstICFGNode,csID); + } + else if(icfg_edge_type=="CallCFGEdge"){ + CallSiteID csID = edge_obj->get("csID")->getAsInteger().getValue(); + icfg->addCallEdge(srcICFGNode,dstICFGNode,csID); + } +} diff --git a/lib/MemoryModel/PAGBuilderFromFile.cpp b/lib/MemoryModel/PAGBuilderFromFile.cpp index c8dfc331d..eda06895e 100644 --- a/lib/MemoryModel/PAGBuilderFromFile.cpp +++ b/lib/MemoryModel/PAGBuilderFromFile.cpp @@ -155,6 +155,61 @@ PAG* PAGBuilderFromFile::build() { return pag; } +//build pag from icfg file +PAG* PAGBuilderFromFile::buildFromICFG(){ + ifstream myfile(file.c_str()); + if(myfile.is_open()){ + std::stringstream jsonStringStream; + while(myfile >> jsonStringStream.rdbuf()); + llvm::json::Value root_value = llvm::json::parse(jsonStringStream.str()).get(); + llvm::json::Array* root_array = root_value.getAsArray(); + for(llvm::json::Array::const_iterator it = root_array->begin(); + it!=root_array->end();it++){ + llvm::json::Value ICFG_Node_obj_val = *it; + llvm::json::Object* ICFG_Node_obj = ICFG_Node_obj_val.getAsObject(); + string node_type = ICFG_Node_obj->get("Node Type")->getAsString()->str(); + if(node_type == "IntraBlock"){ + llvm::json::Array* pag_edges_array = ICFG_Node_obj->get("PAG Edges")->getAsArray(); + for(llvm::json::Array::const_iterator eit = pag_edges_array->begin(); + eit!=pag_edges_array->end();eit++){ + llvm::json::Value edge_value = *eit; + llvm::json::Object* edge_obj = edge_value.getAsObject(); + NodeID source_node = edge_obj->get("Source Node")->getAsInteger().getValue(); + NodeID destination_node = edge_obj->get("Destination Node")->getAsInteger().getValue(); + string source_node_type = edge_obj->get("Source Type")->getAsString()->str(); + string destination_node_type = edge_obj->get("Destination Type")->getAsString()->str(); + string edge_type = edge_obj->get("Edge Type")->getAsString()->str(); + llvm::json::Value* offset_value = edge_obj->get("offset"); + string offset; + if(offset_value!=NULL){ + offset = offset_value->getAsString()->str(); + } + //add new node + if(!pag->hasGNode(source_node)){ + addNode(source_node,source_node_type); + }else if(!pag->hasGNode(destination_node)){ + addNode(destination_node,destination_node_type); + }else{ + addEdge(source_node, destination_node, std::stol(offset), edge_type); + } + } + } + } + myfile.close(); + }else{ + outs() << "Unable to open file\n"; + } + + /// new gep node's id from lower bound, nodeNum may not reflect the total nodes. + u32_t lower_bound = gepNodeNumIndex; + for(u32_t i = 0; i < lower_bound; i++) + pag->incNodeNum(); + + pag->setNodeNumAfterPAGBuild(pag->getTotalNodeNum()); + + return pag; +} + /*! * Add PAG edge according to a file format */ diff --git a/lib/MemoryModel/PointerAnalysis.cpp b/lib/MemoryModel/PointerAnalysis.cpp index ad6353439..3e5bd633d 100644 --- a/lib/MemoryModel/PointerAnalysis.cpp +++ b/lib/MemoryModel/PointerAnalysis.cpp @@ -30,6 +30,7 @@ #include "MemoryModel/PointerAnalysis.h" #include "MemoryModel/PAGBuilder.h" #include "MemoryModel/PAGBuilderFromFile.h" +#include "MemoryModel/ICFGBuilderFromFile.h" #include "Util/SVFUtil.h" #include "Util/PTAStat.h" #include "Util/ThreadCallGraph.h" @@ -136,7 +137,10 @@ void PointerAnalysis::initialize(SVFModule svfModule) { // We read PAG from a user-defined txt instead of parsing PAG from LLVM IR if (SVFModule::pagReadFromTXT()) { PAGBuilderFromFile fileBuilder(SVFModule::pagFileName()); - pag = fileBuilder.build(); + //pag = fileBuilder.build(); + ICFGBuilderFromFile icfgFileBuilder(SVFModule::pagFileName()); + icfg = icfgFileBuilder.build(); + pag = fileBuilder.buildFromICFG(); } else { DBOUT(DGENERAL, outs() << pasMsg("Building Symbol table ...\n")); @@ -155,10 +159,10 @@ void PointerAnalysis::initialize(SVFModule svfModule) { // dump the PAG graph if (dumpGraph()) PAG::getPAG()->dump("pag_initial"); - // print to command line of the PAG graph if (PAGPrint) pag->print(); + icfg->dump("icfg-dump"); } /// initialise pta call graph for every pointer analysis instance diff --git a/lib/Util/ICFG.cpp b/lib/Util/ICFG.cpp index 221022c4f..1c1e48dbd 100644 --- a/lib/Util/ICFG.cpp +++ b/lib/Util/ICFG.cpp @@ -58,6 +58,8 @@ ICFG::ICFG(PTACallGraph* cg): totalICFGNode(0), callgraph(cg), pag(PAG::getPAG() addVFGToICFG(); } +ICFG::ICFG(){} + /*! * Memory has been cleaned up at GenericGraph */ diff --git a/lib/Util/SVFFunction.cpp b/lib/Util/SVFFunction.cpp new file mode 100644 index 000000000..35ce43ee3 --- /dev/null +++ b/lib/Util/SVFFunction.cpp @@ -0,0 +1,17 @@ +#include "Util/SVFFunction.h" + +using namespace SVFUtil; + +SVFFunction::SVFFunction(){} + +SVFFunction::SVFFunction(std::string functionName){ + this->functionName = functionName; +} + +std::string SVFFunction::getFunctionName(){ + return this->functionName; +} + +void SVFFunction::setFunctionName(std::string functionName){ + this->functionName = functionName; +} \ No newline at end of file diff --git a/lib/Util/SVFPTACallGraph.cpp b/lib/Util/SVFPTACallGraph.cpp new file mode 100644 index 000000000..eebefc886 --- /dev/null +++ b/lib/Util/SVFPTACallGraph.cpp @@ -0,0 +1,182 @@ +// #include "Util/SVFModule.h" +// #include "Util/SVFPTACallGraph.h" +// #include "Util/SVFFunction.h" + +// using namespace SVFUtil; +// static llvm::cl::opt CallGraphDotGraph("dump-callgraph", llvm::cl::init(false), +// llvm::cl::desc("Dump dot graph of Call Graph")); + +// SVFPTACallGraph::CallSiteToIdMap SVFPTACallGraph::csToIdMap; +// SVFPTACallGraph::IdToCallSiteMap SVFPTACallGraph::idToCSMap; +// CallSiteID SVFPTACallGraph::totalCallSiteNum = 1; + + +// /// Constructor +// SVFPTACallGraph::SVFPTACallGraph(SVFModule svfModule, CGEK k): kind(k) { +// svfMod = svfModule; +// callGraphNodeNum = 0; +// numOfResolvedIndCallEdge = 0; +// buildCallGraph(svfModule); +// } + +// // /*! +// // * Build call graph, connect direct call edge only +// // */ +// // void PTACallGraph::buildCallGraph(SVFModule svfModule) { + +// // /// create nodes +// // for (SVFModule::iterator F = svfModule.begin(), E = svfModule.end(); F != E; ++F) { +// // addCallGraphNode(*F); +// // } + +// // /// create edges +// // for (SVFModule::iterator F = svfModule.begin(), E = svfModule.end(); F != E; ++F) { +// // Function *fun = *F; +// // for (inst_iterator II = inst_begin(*fun), E = inst_end(*fun); II != E; ++II) { +// // const Instruction *inst = &*II; +// // if (isNonInstricCallSite(inst)) { +// // if(getCallee(inst)) +// // addDirectCallGraphEdge(inst); +// // } +// // } +// // } + +// // dump("callgraph_initial"); +// // } + +// /*! +// * Memory has been cleaned up at GenericGraph +// */ +// void SVFPTACallGraph::destroy() { +// } + +// /*! +// * Add call graph node +// */ +// void SVFPTACallGraph::addCallGraphNode(const SVFFunction* fun) { +// NodeID id = callGraphNodeNum; +// PTACallGraphNode* callGraphNode = new PTACallGraphNode(id, fun); +// addGNode(id,callGraphNode); +// funToCallGraphNodeMap[fun] = callGraphNode; +// callGraphNodeNum++; +// } + +// /*! +// * Whether we have already created this call graph edge +// */ +// PTACallGraphEdge* SVFPTACallGraph::hasGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId) const { +// PTACallGraphEdge edge(src,dst,kind,csId); +// PTACallGraphEdge* outEdge = src->hasOutgoingEdge(&edge); +// PTACallGraphEdge* inEdge = dst->hasIncomingEdge(&edge); +// if (outEdge && inEdge) { +// assert(outEdge == inEdge && "edges not match"); +// return outEdge; +// } +// else +// return NULL; +// } + +// /*! +// * get CallGraph edge via nodes +// */ +// PTACallGraphEdge* SVFPTACallGraph::getGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId) { +// for (PTACallGraphEdge::CallGraphEdgeSet::iterator iter = src->OutEdgeBegin(); +// iter != src->OutEdgeEnd(); ++iter) { +// PTACallGraphEdge* edge = (*iter); +// if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId()) +// return edge; +// } +// return NULL; +// } + +// /*! +// * Add direct call edges +// */ +// void SVFPTACallGraph::addDirectCallGraphEdge(const std::string* call, PTACallGraphNode* caller,PTACallGraphNode* callee, CallSiteID csID) { +// // assert(getCallee(call) && "no callee found"); + +// // PTACallGraphNode* caller = getCallGraphNode(call->getParent()->getParent()); +// // PTACallGraphNode* callee = getCallGraphNode(getCallee(call)); + +// // CallSite cs = SVFUtil::getLLVMCallSite(call); +// // CallSiteID csId = addCallSite(cs, callee->getFunction()); + +// if(!hasGraphEdge(caller,callee, PTACallGraphEdge::CallRetEdge,csID)) { +// // assert(call->getParent()->getParent() == caller->getFunction() +// // && "callee instruction not inside caller??"); + +// PTACallGraphEdge* edge = new PTACallGraphEdge(caller,callee,PTACallGraphEdge::CallRetEdge,csID); +// edge->addDirectCallSite(call); +// addEdge(edge); +// callinstToCallGraphEdgesMap[call].insert(edge); +// } +// } + +// /*! +// * Add indirect call edge to update call graph +// */ +// void SVFPTACallGraph::addIndirectCallGraphEdge(const std::string* call, PTACallGraphNode* caller,PTACallGraphNode* callee, CallSiteID csID) { +// // PTACallGraphNode* caller = getCallGraphNode(call->getParent()->getParent()); +// // PTACallGraphNode* callee = getCallGraphNode(calleefun); + +// numOfResolvedIndCallEdge++; + +// // CallSite cs = SVFUtil::getLLVMCallSite(call); +// // CallSiteID csId = addCallSite(csID, callee->getFunction()); + +// if(!hasGraphEdge(caller,callee, PTACallGraphEdge::CallRetEdge,csID)) { +// // assert(call->getParent()->getParent() == caller->getFunction() +// // && "callee instruction not inside caller??"); + +// PTACallGraphEdge* edge = new PTACallGraphEdge(caller,callee,PTACallGraphEdge::CallRetEdge, csID); +// edge->addInDirectCallSite(call); +// addEdge(edge); +// callinstToCallGraphEdgesMap[call].insert(edge); +// } +// } + +// /*! +// * Get all callsite invoking this callee +// */ +// void SVFPTACallGraph::getAllCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) { +// PTACallGraphNode* callGraphNode = getCallGraphNode(callee); +// for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); +// it!=eit; ++it) { +// for(PTACallGraphEdge::CallInstSet::iterator cit = (*it)->directCallsBegin(), +// ecit = (*it)->directCallsEnd(); cit!=ecit; ++cit) { +// csSet.insert((*cit)); +// } +// for(PTACallGraphEdge::CallInstSet::iterator cit = (*it)->indirectCallsBegin(), +// ecit = (*it)->indirectCallsEnd(); cit!=ecit; ++cit) { +// csSet.insert((*cit)); +// } +// } +// } + +// /*! +// * Get direct callsite invoking this callee +// */ +// void SVFPTACallGraph::getDirCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) { +// PTACallGraphNode* callGraphNode = getCallGraphNode(callee); +// for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); +// it!=eit; ++it) { +// for(PTACallGraphEdge::CallInstSet::iterator cit = (*it)->directCallsBegin(), +// ecit = (*it)->directCallsEnd(); cit!=ecit; ++cit) { +// csSet.insert((*cit)); +// } +// } +// } + +// /*! +// * Get indirect callsite invoking this callee +// */ +// void SVFPTACallGraph::getIndCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) { +// PTACallGraphNode* callGraphNode = getCallGraphNode(callee); +// for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); +// it!=eit; ++it) { +// for(PTACallGraphEdge::CallInstSet::iterator cit = (*it)->indirectCallsBegin(), +// ecit = (*it)->indirectCallsEnd(); cit!=ecit; ++cit) { +// csSet.insert((*cit)); +// } +// } +// } From d74afaf1a8021074994ae06d045fbb3d4c69a601 Mon Sep 17 00:00:00 2001 From: JasonZhongZexin Date: Mon, 9 Mar 2020 11:24:20 +0800 Subject: [PATCH 4/9] update pag builder --- include/MemoryModel/PAG.h | 15 +++++++ include/MemoryModel/PAGBuilderFromFile.h | 2 +- include/MemoryModel/PAGNode.h | 27 ++++++++++- lib/MemoryModel/PAG.cpp | 37 ++++++++++++++- lib/MemoryModel/PAGBuilderFromFile.cpp | 57 ++++++++++++++++++------ lib/MemoryModel/PointerAnalysis.cpp | 12 ++--- 6 files changed, 128 insertions(+), 22 deletions(-) diff --git a/include/MemoryModel/PAG.h b/include/MemoryModel/PAG.h index d4ff08f5e..ef8e99f76 100644 --- a/include/MemoryModel/PAG.h +++ b/include/MemoryModel/PAG.h @@ -619,19 +619,34 @@ class PAG : public GenericGraph { inline NodeID addValNode(const Value* val, PAGNode *node, NodeID i) { return addNode(node,i); } + + inline NodeID addValNodeFromFile(const std::string val, PAGNode* node, NodeID i){ + return addNode(node,i); + } /// Add a memory obj node inline NodeID addObjNode(const Value* val, PAGNode *node, NodeID i) { return addNode(node,i); } + + inline NodeID addObjNodeFromFile(const std::string str_val, PAGNode* node, NodeID i){ + return addNode(node,i); + } /// Add a unique return node for a procedure inline NodeID addRetNode(const Function* val, PAGNode *node, NodeID i) { return addNode(node,i); } + inline NodeID addRetNodeFromFile(const std::string str_val, PAGNode *node, NodeID i){ + return addNode(node, i); + } /// Add a unique vararg node for a procedure inline NodeID addVarargNode(const Function* val, PAGNode *node, NodeID i) { return addNode(node,i); } + inline NodeID addVarargNodeFromFile(const std::string val, PAGNode * node, NodeID i){ + return addNode(node,i); + } + /// Add an edge into PAG //@{ /// Add a PAG edge diff --git a/include/MemoryModel/PAGBuilderFromFile.h b/include/MemoryModel/PAGBuilderFromFile.h index 3bd18cb15..cb431887b 100644 --- a/include/MemoryModel/PAGBuilderFromFile.h +++ b/include/MemoryModel/PAGBuilderFromFile.h @@ -66,7 +66,7 @@ class PAGBuilderFromFile { /// Start building PAG* build(); - void addNode(NodeID s_id, std::string node_type); + void addNode(NodeID s_id, std::string node_type,const char* str_val); // Add edges void addEdge(NodeID nodeSrc, NodeID nodeDst, Size_t offset, diff --git a/include/MemoryModel/PAGNode.h b/include/MemoryModel/PAGNode.h index 6859f2ae3..595ce8e53 100644 --- a/include/MemoryModel/PAGNode.h +++ b/include/MemoryModel/PAGNode.h @@ -67,14 +67,16 @@ class PAGNode : public GenericPAGNodeTy { PAGEdge::PAGKindToEdgeSetMapTy OutEdgeKindToSetMap; bool isTLPointer; /// top-level pointer bool isATPointer; /// address-taken pointer - + const char* str_value; public: /// Constructor + PAGNode(NodeID i,PNODEK k,const char* str_val); PAGNode(const Value* val, NodeID i, PNODEK k); /// Destructor virtual ~PAGNode() { } + /// Get/has methods of the components //@{ inline const Value* getValue() const { @@ -273,6 +275,10 @@ class ValPN: public PAGNode { ValPN(const Value* val, NodeID i, PNODEK ty = ValNode) : PAGNode(val, i, ty) { } + ValPN(NodeID i, const char* str_val, PNODEK ty = ValNode): + PAGNode(i, ty, str_val ){ + + } /// Return name of a LLVM value inline const std::string getValueName() const { if (value && value->hasName()) @@ -294,6 +300,9 @@ class ObjPN: public PAGNode { PAGNode(val, i, ty), mem(m) { } public: + ObjPN( NodeID i, const char* str_val, const MemObj* m, PNODEK ty = ObjNode) : + PAGNode(i, ty, str_val ), mem(m) { + } /// Methods for support type inquiry through isa, cast, and dyn_cast: //@{ static inline bool classof(const ObjPN *) { @@ -365,6 +374,10 @@ class GepValPN: public ValPN { ValPN(val, i, GepValNode), ls(l), gepValType(ty), fieldIdx(idx) { } + GepValPN(const char* str_val, NodeID i, const LocationSet& l, const Type *ty, u32_t idx) : + ValPN(i, str_val, GepValNode), ls(l), gepValType(ty), fieldIdx(idx) { + } + /// offset of the base value node inline u32_t getOffset() const { return ls.getOffset(); @@ -463,6 +476,10 @@ class FIObjPN: public ObjPN { ObjPN(val, i, mem, FIObjNode) { } + FIObjPN(const char* str_val, NodeID i, const MemObj* mem) : + ObjPN(i,str_val, mem, FIObjNode) { + } + /// Return name of a LLVM value inline const std::string getValueName() const { if (value && value->hasName()) @@ -495,6 +512,10 @@ class RetPN: public PAGNode { PAGNode(val, i, RetNode) { } + RetPN(const char* str_val, NodeID i, PNODEK ty=RetNode) : + PAGNode( i, RetNode, str_val) { + } + /// Return name of a LLVM value const std::string getValueName() const { const Function* fun = SVFUtil::cast(value); @@ -527,6 +548,10 @@ class VarArgPN: public PAGNode { PAGNode(val, i, VarargNode) { } + VarArgPN(NodeID i,const char* str_val,PNODEK ty=VarargNode) : + PAGNode( i, VarargNode, str_val) { + } + /// Return name of a LLVM value inline const std::string getValueName() const { const Function* fun = SVFUtil::cast(value); diff --git a/lib/MemoryModel/PAG.cpp b/lib/MemoryModel/PAG.cpp index 4f234a852..993f2faef 100644 --- a/lib/MemoryModel/PAG.cpp +++ b/lib/MemoryModel/PAG.cpp @@ -438,7 +438,7 @@ bool PAG::addEdge(PAGNode* src, PAGNode* dst, PAGEdge* edge) { PTAPAGEdgeKindToSetMap[edge->getEdgeKind()].insert(edge); } if (!SVFModule::pagReadFromTXT()) - setCurrentBBAndValueForPAGEdge(edge); + // setCurrentBBAndValueForPAGEdge(edge); return true; } @@ -647,6 +647,41 @@ bool PAGEdge::isPTAEdge() const { return getSrcNode()->isPointer() && getDstNode()->isPointer(); } +PAGNode::PAGNode(NodeID i,PNODEK k,const char* str_val): + GenericPAGNodeTy(i,k), str_value(str_val){ + assert(ValNode <= k && k<= DummyObjNode && "new PAG node kind?"); + switch (k) { + case ValNode: + case GepValNode: { + assert(str_val != NULL && "value is NULL for ValPN or GepValNode"); + isATPointer = false; + break; + } + + case RetNode: { + assert(str_val != NULL && "value is NULL for RetNode"); + isATPointer = false; + break; + } + + case VarargNode: + case DummyValNode: { + isTLPointer = true; + isATPointer = false; + break; + } + + case ObjNode: + case GepObjNode: + case FIObjNode: + case DummyObjNode: { + isTLPointer = false; + isATPointer = true; + break; + } + } +} + /*! * PAGNode constructor */ diff --git a/lib/MemoryModel/PAGBuilderFromFile.cpp b/lib/MemoryModel/PAGBuilderFromFile.cpp index eda06895e..6d6d6455e 100644 --- a/lib/MemoryModel/PAGBuilderFromFile.cpp +++ b/lib/MemoryModel/PAGBuilderFromFile.cpp @@ -37,16 +37,32 @@ using namespace std; using namespace SVFUtil; static u32_t gepNodeNumIndex = 100000; -void PAGBuilderFromFile::addNode(NodeID ID, string node_type){ +void PAGBuilderFromFile::addNode(NodeID ID, string node_type, const char* str_val){ if(node_type=="DummyValNode"){ pag->addDummyValNode(ID); } - if(node_type=="FIObjNode"){ + else if(node_type=="FIObjNode"){ const MemObj* mem = pag->addDummyMemObj(ID, NULL); pag->addFIObjNode(mem); + }else if(node_type=="ValNode"){ + ValPN* node = new ValPN(ID,str_val,PAGNode::ValNode); + pag->addValNodeFromFile(str_val,node,ID); } - if(node_type == "DummyObjNode"){ - pag->addDummyObjNode(ID); + else if(node_type == "DummyObjNode"){ + pag->addDummyObjNode(ID,NULL); + } + else if(node_type=="ObjNode"){ + const MemObj* mem = pag->addDummyMemObj(ID, NULL); + ObjPN* node = new ObjPN(ID,str_val,mem,PAGNode::ObjNode); + pag->addObjNodeFromFile(str_val,node,ID); + } + else if(node_type == "RetNode"){ + RetPN *node = new RetPN(str_val,ID,PAGNode::RetNode); + pag->addRetNodeFromFile(str_val,node,ID); + } + else if(node_type == "VarargNode"){ + VarArgPN* node = new VarArgPN(ID,str_val,PAGNode::VarargNode); + pag->addVarargNodeFromFile(str_val,node,ID); } // else // assert(false && "format not support, pls specify node type"); @@ -104,13 +120,18 @@ PAG* PAGBuilderFromFile::build() { if(offset_value!=NULL){ offset = offset_value->getAsString()->str(); } + string var = "hello world"; + const char *val = var.c_str(); //add new node if(!pag->hasGNode(source_node)){ - addNode(source_node,source_node_type); + addNode(source_node,source_node_type,val); }else if(!pag->hasGNode(destination_node)){ - addNode(destination_node,destination_node_type); + addNode(destination_node,destination_node_type,"a"); }else{ - addEdge(source_node, destination_node, std::stol(offset), edge_type); + if(offset!="") + addEdge(source_node, destination_node, std::stol(offset), edge_type); + else + addEdge(source_node, destination_node, NULL, edge_type); } } } @@ -132,12 +153,17 @@ PAG* PAGBuilderFromFile::build() { if(offset_value!=NULL) offset = offset_value->getAsString()->str(); //add new node + string var = "hello world"; + const char *val = var.c_str(); if(!pag->hasGNode(source_node)){ - addNode(source_node,source_node_type); + addNode(source_node,source_node_type,val); }else if(!pag->hasGNode(destination_node)){ - addNode(destination_node,destination_node_type); + addNode(destination_node,destination_node_type,val); }else{ - addEdge(source_node, destination_node, std::stol(offset), edge_type); + if(offset!="") + addEdge(source_node, destination_node, std::stol(offset), edge_type); + else + addEdge(source_node, destination_node, NULL, edge_type); } } myfile.close(); @@ -185,12 +211,17 @@ PAG* PAGBuilderFromFile::buildFromICFG(){ offset = offset_value->getAsString()->str(); } //add new node + string var = "hello world"; + const char *val = var.c_str(); if(!pag->hasGNode(source_node)){ - addNode(source_node,source_node_type); + addNode(source_node,source_node_type,val); }else if(!pag->hasGNode(destination_node)){ - addNode(destination_node,destination_node_type); + addNode(destination_node,destination_node_type,val); }else{ - addEdge(source_node, destination_node, std::stol(offset), edge_type); + if(offset!="") + addEdge(source_node, destination_node, std::stol(offset), edge_type); + else + addEdge(source_node, destination_node, NULL, edge_type); } } } diff --git a/lib/MemoryModel/PointerAnalysis.cpp b/lib/MemoryModel/PointerAnalysis.cpp index 3e5bd633d..c4222f10e 100644 --- a/lib/MemoryModel/PointerAnalysis.cpp +++ b/lib/MemoryModel/PointerAnalysis.cpp @@ -137,7 +137,7 @@ void PointerAnalysis::initialize(SVFModule svfModule) { // We read PAG from a user-defined txt instead of parsing PAG from LLVM IR if (SVFModule::pagReadFromTXT()) { PAGBuilderFromFile fileBuilder(SVFModule::pagFileName()); - //pag = fileBuilder.build(); + // pag = fileBuilder.build(); ICFGBuilderFromFile icfgFileBuilder(SVFModule::pagFileName()); icfg = icfgFileBuilder.build(); pag = fileBuilder.buildFromICFG(); @@ -156,13 +156,13 @@ void PointerAnalysis::initialize(SVFModule svfModule) { //typeSystem = new TypeSystem(pag); } - // dump the PAG graph - if (dumpGraph()) - PAG::getPAG()->dump("pag_initial"); - // print to command line of the PAG graph + // // dump the PAG graph + // if (dumpGraph()) + // PAG::getPAG()->dump("pag_initial"); + // // print to command line of the PAG graph if (PAGPrint) pag->print(); - icfg->dump("icfg-dump"); + // icfg->dump("icfg-dump"); } /// initialise pta call graph for every pointer analysis instance From 856080750599a48aa1a6dcccd4ac64cd77c5fb42 Mon Sep 17 00:00:00 2001 From: JasonZhongZexin Date: Sun, 15 Mar 2020 04:09:07 +0800 Subject: [PATCH 5/9] update pag to ICFG node --- include/MemoryModel/ICFGBuilderFromFile.h | 11 +++- include/MemoryModel/PAG.h | 10 ++-- include/Util/ICFGNode.h | 25 +++++++++ lib/MemoryModel/ICFGBuilderFromFile.cpp | 66 ++++++++++++++++++++--- lib/MemoryModel/PointerAnalysis.cpp | 15 +++--- 5 files changed, 104 insertions(+), 23 deletions(-) diff --git a/include/MemoryModel/ICFGBuilderFromFile.h b/include/MemoryModel/ICFGBuilderFromFile.h index 3dc735bad..cc8b6ee9f 100644 --- a/include/MemoryModel/ICFGBuilderFromFile.h +++ b/include/MemoryModel/ICFGBuilderFromFile.h @@ -2,6 +2,7 @@ #define INCLUDE_MEMORYMODEL_ICFGBUILDERFROMFILE_H_ #include "Util/ICFG.h" +#include "MemoryModel/PAG.h" #include "llvm/Support/JSON.h" @@ -13,10 +14,13 @@ class ICFGBuilderFromFile{ private: ICFG* icfg; std::string file; + PAG pag; public: //Constructor - ICFGBuilderFromFile(std::string f){} + ICFGBuilderFromFile(std::string f, PAG pag){ + this->pag = pag; + } // Destructor ~ICFGBuilderFromFile() {} @@ -30,10 +34,13 @@ class ICFGBuilderFromFile{ return file; } + PAG getPAG() const{ + return pag; + } //Start building ICFG* build(); - void addNode(NodeID nodeID, std::string nodeType); + void addNode(NodeID nodeID, std::string nodeType, llvm::json::Array* pagEdges); void addEdge(llvm::json::Object* edge_obj); }; diff --git a/include/MemoryModel/PAG.h b/include/MemoryModel/PAG.h index ef8e99f76..2e3f35745 100644 --- a/include/MemoryModel/PAG.h +++ b/include/MemoryModel/PAG.h @@ -97,17 +97,17 @@ class PAG : public GenericGraph { NodeSet candidatePointers; NodeID nodeNumAfterPAGBuild; // initial node number after building PAG, excluding later added nodes, e.g., gepobj nodes - /// Constructor - PAG(bool buildFromFile) : fromFile(buildFromFile), curBB(NULL),curVal(NULL), totalPTAPAGEdge(0),nodeNumAfterPAGBuild(0) { - symInfo = SymbolTableInfo::Symbolnfo(); - } - /// Clean up memory void destroy(); public: u32_t totalPTAPAGEdge; + /// Constructor + PAG(bool buildFromFile) : fromFile(buildFromFile), curBB(NULL),curVal(NULL), totalPTAPAGEdge(0),nodeNumAfterPAGBuild(0) { + symInfo = SymbolTableInfo::Symbolnfo(); + } + PAG(){} /// Return valid pointers inline NodeSet& getAllValidPtrs() { return candidatePointers; diff --git a/include/Util/ICFGNode.h b/include/Util/ICFGNode.h index 9a7afa2a2..03c25f5cb 100644 --- a/include/Util/ICFGNode.h +++ b/include/Util/ICFGNode.h @@ -90,16 +90,24 @@ class IntraBlockNode : public ICFGNode { private: const Instruction *inst; + const std::string* str_value; StmtOrPHIVec vnodes; public: IntraBlockNode(NodeID id, const Instruction *i) : ICFGNode(id, IntraBlock), inst(i) { bb = inst->getParent(); } + IntraBlockNode(NodeID id, const std::string *i) : ICFGNode(id, IntraBlock), str_value(i) { + } + inline const Instruction *getInst() const { return inst; } + inline const std::string *getInst_str_value() const { + return str_value; + } + inline void addPAGEdge(const PAGEdge *s) { // avoid duplicate element for(StmtOrPHIVec::const_iterator it = vnodes.begin(), eit = vnodes.end(); it!=eit; ++it) @@ -176,6 +184,7 @@ class FunEntryBlockNode : public InterBlockNode { typedef std::vector FormalParmNodeVec; private: const Function *fun; + const std::string* str_fun; FormalParmNodeVec FPNodes; public: FunEntryBlockNode(NodeID id, const Function *f) : InterBlockNode(id, FunEntryBlock), fun(f) { @@ -183,11 +192,18 @@ class FunEntryBlockNode : public InterBlockNode { bb = &(fun->getEntryBlock()); } + FunEntryBlockNode(NodeID id, const std::string *f) : InterBlockNode(id, FunEntryBlock), str_fun(f) { + } + /// Return function inline const Function *getFun() const { return fun; } + inline const std::string *getStr_fun() const { + return str_fun; + } + /// Return the set of formal parameters inline const FormalParmNodeVec &getFormalParms() const { return FPNodes; @@ -224,6 +240,7 @@ class FunEntryBlockNode : public InterBlockNode { class FunExitBlockNode : public InterBlockNode { private: + const std::string *str_fun; const Function *fun; const PAGNode *formalRet; public: @@ -232,11 +249,19 @@ class FunExitBlockNode : public InterBlockNode { bb = SVFUtil::getFunExitBB(fun); } + FunExitBlockNode(NodeID id, const std::string *f) : InterBlockNode(id, FunExitBlock), str_fun(f), formalRet(NULL) { + } + /// Return function inline const Function *getFun() const { return fun; } + + inline const std::string *getStrFun() const { + return str_fun; + } + /// Return actual return parameter inline const PAGNode *getFormalRet() const { return formalRet; diff --git a/lib/MemoryModel/ICFGBuilderFromFile.cpp b/lib/MemoryModel/ICFGBuilderFromFile.cpp index 37b00b8a0..23e59441d 100644 --- a/lib/MemoryModel/ICFGBuilderFromFile.cpp +++ b/lib/MemoryModel/ICFGBuilderFromFile.cpp @@ -26,7 +26,11 @@ ICFG* ICFGBuilderFromFile::build(){ llvm::json::Object* ICFG_Node_obj = ICFG_Node_obj_val.getAsObject(); string node_type = ICFG_Node_obj->get("Node Type")->getAsString()->str(); NodeID nodeID = ICFG_Node_obj->get("ICFG_ID")->getAsInteger().getValue(); - addNode(nodeID,node_type); + if(node_type=="IntraBlock"){ + llvm::json::Array* pagEdges = ICFG_Node_obj->get("PAG Edges")->getAsArray(); + addNode(nodeID,node_type,pagEdges); + } + addNode(nodeID,node_type,NULL); } //add all edges @@ -46,30 +50,78 @@ ICFG* ICFGBuilderFromFile::build(){ return icfg; } -void ICFGBuilderFromFile::addNode(NodeID nodeId, std::string nodeType){ +void ICFGBuilderFromFile::addNode(NodeID nodeId, std::string nodeType,llvm::json::Array* pagEdges){ + const std::string *value = new std::string(""); if(!icfg->hasICFGNode(nodeId)){ if(nodeType=="IntraBlock"){ - ICFGNode* node = new ICFGNode(nodeId,ICFGNode::IntraBlock); + IntraBlockNode *node = new IntraBlockNode(nodeId,value); + for(llvm::json::Array::const_iterator it = pagEdges->begin(); it!=pagEdges->end();it++){ + llvm::json::Value pagEdge_value = *it; + llvm::json::Object* pagEdge = pagEdge_value.getAsObject(); + NodeID source_node = pagEdge->get("Source Node")->getAsInteger().getValue(); + NodeID destination_node = pagEdge->get("Destination Node")->getAsInteger().getValue(); + string source_node_type = pagEdge->get("Source Type")->getAsString()->str(); + string destination_node_type = pagEdge->get("Destination Type")->getAsString()->str(); + string edge_type = pagEdge->get("Edge Type")->getAsString()->str(); + llvm::json::Value* offset_value = pagEdge->get("offset"); + string offset; + if(offset_value!=NULL){ + offset = offset_value->getAsString()->str(); + } + PAGNode* srcNode = pag.getPAGNode(source_node); + PAGNode* dstNode = pag.getPAGNode(destination_node); + PAGEdge* edge = NULL; + if (edge_type == "Addr"){ + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::Addr); + } + else if (edge_type == "Copy") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::Copy); + else if (edge_type == "Load") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::Load); + else if (edge_type == "Store") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::Store); + else if (edge_type == "NormalGep") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::NormalGep); + else if (edge_type == "VariantGep") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::VariantGep); + else if (edge_type == "Call") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::Call); + else if (edge_type == "Ret") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::Ret); + else if (edge_type == "Cmp") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::Cmp); + else if (edge_type == "BinaryOp") + edge = pag.getIntraPAGEdge(srcNode,dstNode,PAGEdge::BinaryOp); + else + assert(false && "format not support, can not create such edge"); + //add pag edge to the node + if(edge!=NULL) + node->addPAGEdge(edge); + } icfg->addGNode(nodeId,node); outs()<<"adding IntraBlock node....\n"; } else if(nodeType=="FunEntryBlock"){ - ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunEntryBlock); + FunEntryBlockNode *node = new FunEntryBlockNode(nodeId,value); + // ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunEntryBlock); icfg->addGNode(nodeId,node); outs()<<"adding FunEntryBlock node....\n"; } else if(nodeType=="FunExitBlock"){ - ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunExitBlock); + FunExitBlockNode *node = new FunExitBlockNode(nodeId,value); + // ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunExitBlock); icfg->addGNode(nodeId,node); outs()<<"adding FunExitBlock node....\n"; } else if(nodeType=="FunCallBlock"){ - ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunCallBlock); + CallBlockNode *node = new CallBlockNode(nodeId,*(new CallSite())); + // ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunCallBlock); icfg->addGNode(nodeId,node); outs()<<"adding FunCallBlock node....\n"; } else if(nodeType=="FunRetBlock"){ - ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunCallBlock); + RetBlockNode *node = new RetBlockNode(nodeId,*(new CallSite())); + // ICFGNode* node = new ICFGNode(nodeId,ICFGNode::FunCallBlock); icfg->addGNode(nodeId,node); outs()<<"adding FunRetBlock node....\n"; } diff --git a/lib/MemoryModel/PointerAnalysis.cpp b/lib/MemoryModel/PointerAnalysis.cpp index c4222f10e..912e78ae9 100644 --- a/lib/MemoryModel/PointerAnalysis.cpp +++ b/lib/MemoryModel/PointerAnalysis.cpp @@ -138,9 +138,10 @@ void PointerAnalysis::initialize(SVFModule svfModule) { if (SVFModule::pagReadFromTXT()) { PAGBuilderFromFile fileBuilder(SVFModule::pagFileName()); // pag = fileBuilder.build(); - ICFGBuilderFromFile icfgFileBuilder(SVFModule::pagFileName()); - icfg = icfgFileBuilder.build(); pag = fileBuilder.buildFromICFG(); + ICFGBuilderFromFile* icfgFileBuilder = new ICFGBuilderFromFile(SVFModule::pagFileName(),pag); + icfg = icfgFileBuilder->build(); + outs()<<"pag build successed ....\n\n\n"; } else { DBOUT(DGENERAL, outs() << pasMsg("Building Symbol table ...\n")); @@ -160,9 +161,8 @@ void PointerAnalysis::initialize(SVFModule svfModule) { // if (dumpGraph()) // PAG::getPAG()->dump("pag_initial"); // // print to command line of the PAG graph - if (PAGPrint) - pag->print(); - // icfg->dump("icfg-dump"); + // if (PAGPrint) + // pag->print(); } /// initialise pta call graph for every pointer analysis instance @@ -214,7 +214,6 @@ bool PointerAnalysis::dumpGraph() { */ void PointerAnalysis::dumpStat() { - if(print_stat && stat) stat->performStat(); } @@ -227,8 +226,7 @@ void PointerAnalysis::dumpStat() { void PointerAnalysis::finalize() { /// Print statistics - dumpStat(); - + //dumpStat(); PAG* pag = PAG::getPAG(); // dump the PAG graph if (dumpGraph()) @@ -245,7 +243,6 @@ void PointerAnalysis::finalize() { if (TYPEPrint) dumpAllTypes(); - if(PTSAllPrint) dumpAllPts(); From ae7fb7070739e305d3798e22f3450a334a07be69 Mon Sep 17 00:00:00 2001 From: JasonZhongZexin Date: Sun, 15 Mar 2020 13:04:45 +0800 Subject: [PATCH 6/9] update pag builder --- include/MemoryModel/PAG.h | 6 + lib/MemoryModel/PAG.cpp | 167 +++++++++++++++++++++++++ lib/MemoryModel/PAGBuilderFromFile.cpp | 50 ++++---- 3 files changed, 199 insertions(+), 24 deletions(-) diff --git a/include/MemoryModel/PAG.h b/include/MemoryModel/PAG.h index 2e3f35745..93d9ff7a9 100644 --- a/include/MemoryModel/PAG.h +++ b/include/MemoryModel/PAG.h @@ -720,6 +720,12 @@ class PAG : public GenericGraph { /// Print PAG void print(); + void printInst2JsonFile(const std::string& filename); + + std::string getNodeKindValue(int kind); + + std::string getEdgeKindValue(int kind); + /// Dump PAG void dump(std::string name); diff --git a/lib/MemoryModel/PAG.cpp b/lib/MemoryModel/PAG.cpp index 993f2faef..0ae56f3f8 100644 --- a/lib/MemoryModel/PAG.cpp +++ b/lib/MemoryModel/PAG.cpp @@ -29,6 +29,7 @@ #include "MemoryModel/PAG.h" #include "Util/SVFUtil.h" +#include "llvm/Support/JSON.h" using namespace SVFUtil; @@ -246,6 +247,172 @@ bool PAG::addFormalParamBlackHoleAddrEdge(NodeID node, const Argument *arg) return added; } +void PAG::printInst2JsonFile(const std::string& filename){ + outs() << "write symbols to '" << filename << "'..."; + + std::error_code err; + ToolOutputFile F(filename.c_str(), err, llvm::sys::fs::F_None); + if (err) { + outs() << " error opening file for writing!\n"; + F.os().clear_error(); + return; + } + + llvm::json::Array root_array; + for(Inst2PAGEdgesMap::const_iterator it = inst2PAGEdgesMap.begin(); + it!=inst2PAGEdgesMap.end(); it++){ + llvm::json::Object currentInst; + char hex_char[30]; + const Instruction* inst = it->first; + const PAGEdgeList& pagEdgeList = it->second; + std::sprintf(hex_char,"%p",inst); + currentInst["current Inst"] =std::string(hex_char); + + llvm::json::Array next_inst_array; + std::vector instList; + getNextInsts(inst,instList); + for (std::vector::const_iterator nit = instList.begin(); + nit!=instList.end(); ++nit){ + std::sprintf(hex_char,"%p",*nit); + next_inst_array.push_back(std::string(hex_char)); + } + llvm::json::Value next_inst_value = llvm::json::Array{next_inst_array}; + currentInst["next Inst"] = next_inst_value; + + llvm::json::Array edges_array; + for (PAGEdgeList::const_iterator bit = pagEdgeList.begin(), + ebit = pagEdgeList.end(); bit != ebit; ++bit) { + const PAGEdge* edge = *bit; + llvm::json::Object edge_obj; + edge_obj["source node"] = edge->getSrcID(); + edge_obj["destination node"] = edge->getDstID(); + edge_obj["source node type"] = getNodeKindValue(edge->getSrcNode()->getNodeKind()); + edge_obj["destination node type"] = getNodeKindValue(edge->getDstNode()->getNodeKind()); + edge_obj["edge type"] = getEdgeKindValue(edge->getEdgeKind()); + if(edge->getEdgeKind()==PAGEdge::NormalGep){ + const NormalGepPE* gepEdge = SVFUtil::cast(edge); + edge_obj["offset"] = gepEdge->getOffset(); + } + llvm::json::Value edge_value = llvm::json::Object{edge_obj}; + edges_array.push_back(edge_value); + } + + llvm::json::Value edges_array_value = llvm::json::Array{edges_array}; + currentInst["edges"] = edges_array_value; + + llvm::json::Value currentInst_value = llvm::json::Object{currentInst}; + root_array.push_back(currentInst_value); + } + + llvm::json::Value root_array_value = llvm::json::Array{root_array}; + llvm::json::Object root; + root["Instructions"] = root_array_value; + llvm::json::Array global_edge_array; + for(PAGEdgeSet::const_iterator it = globPAGEdgesSet.begin(); it!=globPAGEdgesSet.end(); it++){ + const PAGEdge* edge = *it; + llvm::json::Object global_edge_obj; + global_edge_obj["source node"] = edge->getSrcID(); + global_edge_obj["destination node"]= edge->getDstID(); + global_edge_obj["source node type"] = getNodeKindValue(edge->getSrcNode()->getNodeKind()); + global_edge_obj["destination node type"] = getNodeKindValue(edge->getDstNode()->getNodeKind()); + global_edge_obj["edge type"] = getEdgeKindValue(edge->getEdgeKind()); + if(edge->getEdgeKind()==PAGEdge::NormalGep){ + const NormalGepPE* gepEdge = SVFUtil::cast(edge); + global_edge_obj["offset"] = gepEdge->getOffset(); + } + llvm::json::Value edge_value = llvm::json::Object{global_edge_obj}; + global_edge_array.push_back(edge_value); + } + llvm::json::Value global_edge_array_value = llvm::json::Array{global_edge_array}; + root["global edge"] = global_edge_array_value; + llvm::json::Value root_value = llvm::json::Object{root}; + + llvm::json::operator<<(F.os(),root_value); + + F.os().close(); + if (!F.os().has_error()) { + outs() << "\n"; + F.keep(); + return; + } + +} + +std::string PAG::getNodeKindValue(int kind){ + switch (kind){ + case (PAGNode::ValNode): + return "ValNode"; + break; + case PAGNode::ObjNode: + return "ObjNode"; + break; + case PAGNode::RetNode: + return "RetNode"; + break; + case PAGNode::VarargNode: + return "VarargNode"; + break; + case PAGNode::GepValNode: + return "GepValNode"; + break; + case PAGNode::GepObjNode: + return "GepObjNode"; + break; + case PAGNode::FIObjNode: + return "FIObjNode"; + break; + case PAGNode::DummyValNode: + return "DummyValNode"; + break; + case PAGNode::DummyObjNode: + return "DummyObjNode"; + break; + } + return ""; +} + +std::string PAG::getEdgeKindValue(int kind){ + switch(kind){ + case (PAGEdge::Addr): + return "Addr"; + break; + case (PAGEdge::Copy): + return "Copy"; + break; + case (PAGEdge::Store): + return "Store"; + break; + case (PAGEdge::Load): + return "Load"; + break; + case (PAGEdge::Call): + return "Call"; + break; + case (PAGEdge::Ret): + return "Ret"; + break; + case (PAGEdge::NormalGep): + return "NormalGep"; + break; + case (PAGEdge::VariantGep): + return "VariantGep"; + break; + case (PAGEdge::ThreadFork): + return "ThreadFork"; + break; + case (PAGEdge::ThreadJoin): + return "ThreadJoin"; + break; + case (PAGEdge::Cmp): + return "Cmp"; + break; + case (PAGEdge::BinaryOp): + return "BinaryOp"; + break; + } + return ""; +} + /*! * Add a temp field value node according to base value and offset diff --git a/lib/MemoryModel/PAGBuilderFromFile.cpp b/lib/MemoryModel/PAGBuilderFromFile.cpp index 047f82b84..da4a00b59 100644 --- a/lib/MemoryModel/PAGBuilderFromFile.cpp +++ b/lib/MemoryModel/PAGBuilderFromFile.cpp @@ -213,11 +213,11 @@ PAG* PAGBuilderFromFile::buildFromICFG(){ //add new node string var = "hello world"; const char *val = var.c_str(); - if(!pag->hasGNode(source_node)){ + if(!pag->hasGNode(source_node)) addNode(source_node,source_node_type,val); - }else if(!pag->hasGNode(destination_node)){ + if(!pag->hasGNode(destination_node)) addNode(destination_node,destination_node_type,val); - }else{ + if(pag->hasGNode(source_node)&&pag->hasGNode(destination_node)){ if(offset!="") addEdge(source_node, destination_node, std::stol(offset), edge_type); else @@ -251,34 +251,36 @@ void PAGBuilderFromFile::addEdge(NodeID srcID, NodeID dstID, PAGNode* srcNode = pag->getPAGNode(srcID); PAGNode* dstNode = pag->getPAGNode(dstID); - /// sanity check for PAG from txt - assert(SVFUtil::isa(dstNode) && "dst not an value node?"); - if(edge=="addr") - assert(SVFUtil::isa(srcNode) && "src not an value node?"); - else - assert(!SVFUtil::isa(srcNode) && "src not an object node?"); - if (edge == "Addr"){ pag->addAddrEdge(srcID, dstID); } - else if (edge == "Copy") - pag->addCopyEdge(srcID, dstID); - else if (edge == "Load") - pag->addLoadEdge(srcID, dstID); - else if (edge == "Store") - pag->addStoreEdge(srcID, dstID); - else if (edge == "NormalGep") - pag->addNormalGepEdge(srcID, dstID, LocationSet(offsetOrCSId)); - else if (edge == "VariantGep") - pag->addVariantGepEdge(srcID, dstID); - else if (edge == "Call") + else if (edge == "Copy"){ + pag->addCopyEdge(srcID, dstID); + } + else if (edge == "Load"){ + pag->addLoadEdge(srcID, dstID); + } + else if (edge == "Store"){ + pag->addStoreEdge(srcID, dstID); + } + else if (edge == "NormalGep"){ + pag->addNormalGepEdge(srcID, dstID, LocationSet(offsetOrCSId)); + } + else if (edge == "VariantGep"){ + pag->addVariantGepEdge(srcID, dstID); + } + else if (edge == "Call"){ pag->addEdge(srcNode, dstNode, new CallPE(srcNode, dstNode, NULL)); - else if (edge == "Ret") + } + else if (edge == "Ret"){ pag->addEdge(srcNode, dstNode, new RetPE(srcNode, dstNode, NULL)); - else if (edge == "Cmp") + } + else if (edge == "Cmp"){ pag->addCmpEdge(srcID, dstID); - else if (edge == "BinaryOp") + } + else if (edge == "BinaryOp"){ pag->addBinaryOPEdge(srcID, dstID); + } else assert(false && "format not support, can not create such edge"); } From 29662b0be48dea630016f6bf382f29ae981c089f Mon Sep 17 00:00:00 2001 From: JasonZhongZexin Date: Sun, 15 Mar 2020 14:13:34 +0800 Subject: [PATCH 7/9] clean code --- include/MemoryModel/PAGBuilderFromFile.h | 5 +- lib/MemoryModel/PAGBuilderFromFile.cpp | 117 +---------------------- 2 files changed, 6 insertions(+), 116 deletions(-) diff --git a/include/MemoryModel/PAGBuilderFromFile.h b/include/MemoryModel/PAGBuilderFromFile.h index cb431887b..49a9073ca 100644 --- a/include/MemoryModel/PAGBuilderFromFile.h +++ b/include/MemoryModel/PAGBuilderFromFile.h @@ -61,11 +61,10 @@ class PAGBuilderFromFile { return file; } + //start building pag from ICFG json file PAG* buildFromICFG(); - - /// Start building - PAG* build(); + //add pag nodes void addNode(NodeID s_id, std::string node_type,const char* str_val); // Add edges diff --git a/lib/MemoryModel/PAGBuilderFromFile.cpp b/lib/MemoryModel/PAGBuilderFromFile.cpp index da4a00b59..24e63bd90 100644 --- a/lib/MemoryModel/PAGBuilderFromFile.cpp +++ b/lib/MemoryModel/PAGBuilderFromFile.cpp @@ -69,118 +69,6 @@ void PAGBuilderFromFile::addNode(NodeID ID, string node_type, const char* str_v } -PAG* PAGBuilderFromFile::build() { - - ifstream myfile(file.c_str()); - if(myfile.is_open()){ - std::stringstream jsonStringStream; - while(myfile >> jsonStringStream.rdbuf()); - llvm::json::Value root_value = llvm::json::parse(jsonStringStream.str()).get(); - llvm::json::Object* root_obj; - root_obj = root_value.getAsObject(); - - //get the Instructions array - llvm::json::Value* root_array_value; - root_array_value= root_obj->get("Instructions"); - llvm::json::Array* root_array; - root_array = root_array_value->getAsArray(); - - //get the global edge array - llvm::json::Value* global_edges_value; - global_edges_value = root_obj->get("global edge"); - llvm::json::Array* global_edges_array; - global_edges_array = global_edges_value->getAsArray(); - - for(llvm::json::Array::const_iterator it = root_array->begin(); - it!=root_array->end();it++){ - llvm::json::Value currentInst_value = *it; - llvm::json::Object* currentInst_obj; - currentInst_obj = currentInst_value.getAsObject(); - llvm::json::Value* edges_array_value; - edges_array_value = currentInst_obj->get("edges"); - llvm::json::Array* edges_array; - edges_array = edges_array_value->getAsArray(); - for(llvm::json::Array::const_iterator eit = edges_array->begin(); - eit!=edges_array->end(); eit++){ - llvm::json::Value edge_value = *eit; - llvm::json::Object* edge_obj; - edge_obj = edge_value.getAsObject(); - NodeID source_node; - source_node = edge_obj->get("source node")->getAsInteger().getValue(); - NodeID destination_node; - destination_node = edge_obj->get("destination node")->getAsInteger().getValue(); - string source_node_type; - source_node_type = edge_obj->get("source node type")->getAsString()->str(); - string destination_node_type; - destination_node_type = edge_obj->get("destination node type")->getAsString()->str(); - string edge_type; - edge_type = edge_obj->get("edge type")->getAsString()->str(); - llvm::json::Value* offset_value = edge_obj->get("offset"); - string offset; - if(offset_value!=NULL){ - offset = offset_value->getAsString()->str(); - } - string var = "hello world"; - const char *val = var.c_str(); - //add new node - if(!pag->hasGNode(source_node)){ - addNode(source_node,source_node_type,val); - }else if(!pag->hasGNode(destination_node)){ - addNode(destination_node,destination_node_type,"a"); - }else{ - if(offset!="") - addEdge(source_node, destination_node, std::stol(offset), edge_type); - else - addEdge(source_node, destination_node, NULL, edge_type); - } - } - } - for(llvm::json::Array::const_iterator it = global_edges_array->begin(); - it!=global_edges_array->end();it++){ - llvm::json::Object global_edge_obj = *it->getAsObject(); - NodeID source_node; - source_node = global_edge_obj.get("source node")->getAsInteger().getValue(); - NodeID destination_node; - destination_node = global_edge_obj.get("destination node")->getAsInteger().getValue(); - string source_node_type; - source_node_type = global_edge_obj.get("source node type")->getAsString()->str(); - string destination_node_type; - destination_node_type = global_edge_obj.get("destination node type")->getAsString()->str(); - string edge_type; - edge_type = global_edge_obj.get("edge type")->getAsString()->str(); - llvm::json::Value* offset_value = global_edge_obj.get("offset"); - string offset; - if(offset_value!=NULL) - offset = offset_value->getAsString()->str(); - //add new node - string var = ""; - const char *val = var.c_str(); - if(!pag->hasGNode(source_node)){ - addNode(source_node,source_node_type,val); - }else if(!pag->hasGNode(destination_node)){ - addNode(destination_node,destination_node_type,val); - }else{ - if(offset!="") - addEdge(source_node, destination_node, std::stol(offset), edge_type); - else - addEdge(source_node, destination_node, NULL, edge_type); - } - } - myfile.close(); - }else{ - outs() << "Unable to open file\n"; - } - - /// new gep node's id from lower bound, nodeNum may not reflect the total nodes. - u32_t lower_bound = gepNodeNumIndex; - for(u32_t i = 0; i < lower_bound; i++) - pag->incNodeNum(); - - pag->setNodeNumAfterPAGBuild(pag->getTotalNodeNum()); - - return pag; -} - //build pag from icfg file PAG* PAGBuilderFromFile::buildFromICFG(){ ifstream myfile(file.c_str()); @@ -194,6 +82,8 @@ PAG* PAGBuilderFromFile::buildFromICFG(){ llvm::json::Value ICFG_Node_obj_val = *it; llvm::json::Object* ICFG_Node_obj = ICFG_Node_obj_val.getAsObject(); string node_type = ICFG_Node_obj->get("Node Type")->getAsString()->str(); + + //add pag edges to IntraBlock node if(node_type == "IntraBlock"){ llvm::json::Array* pag_edges_array = ICFG_Node_obj->get("PAG Edges")->getAsArray(); for(llvm::json::Array::const_iterator eit = pag_edges_array->begin(); @@ -210,8 +100,9 @@ PAG* PAGBuilderFromFile::buildFromICFG(){ if(offset_value!=NULL){ offset = offset_value->getAsString()->str(); } + //add new node - string var = "hello world"; + string var = ""; const char *val = var.c_str(); if(!pag->hasGNode(source_node)) addNode(source_node,source_node_type,val); From be2c70bb19f8d0a4ccdbe411906501b1c330b288 Mon Sep 17 00:00:00 2001 From: JasonZhongZexin Date: Sun, 15 Mar 2020 14:40:14 +0800 Subject: [PATCH 8/9] remove svffunction --- include/Util/PTACallGraph.h | 398 ------------------------- lib/MemoryModel/PAGBuilderFromFile.cpp | 2 - lib/Util/SVFPTACallGraph.cpp | 182 ----------- 3 files changed, 582 deletions(-) delete mode 100644 include/Util/PTACallGraph.h delete mode 100644 lib/Util/SVFPTACallGraph.cpp diff --git a/include/Util/PTACallGraph.h b/include/Util/PTACallGraph.h deleted file mode 100644 index f55fba41a..000000000 --- a/include/Util/PTACallGraph.h +++ /dev/null @@ -1,398 +0,0 @@ -//===- PTACallGraph.h -- Call graph representation----------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-2017> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// - -/* - * PTACallGraph.h - * - * Created on: Nov 7, 2013 - * Author: Yulei Sui - */ - -#ifndef PTACALLGRAPH_H_ -#define PTACALLGRAPH_H_ - -#include "MemoryModel/GenericGraph.h" -#include "Util/SVFUtil.h" -#include "Util/BasicTypes.h" -#include - -class PTACallGraphNode; -class SVFModule; - -/* - * Call Graph edge representing a calling relation between two functions - * Multiple calls from function A to B are merged into one call edge - * Each call edge has a set of direct callsites and a set of indirect callsites - */ -typedef GenericEdge GenericCallGraphEdgeTy; -class PTACallGraphEdge : public GenericCallGraphEdgeTy { - -public: - typedef std::set CallInstSet; - enum CEDGEK { - CallRetEdge,TDForkEdge,TDJoinEdge,HareParForEdge - }; - - -private: - CallInstSet directCalls; - CallInstSet indirectCalls; - CallSiteID csId; -public: - /// Constructor - PTACallGraphEdge(PTACallGraphNode* s, PTACallGraphNode* d, CEDGEK kind, CallSiteID cs) : - GenericCallGraphEdgeTy(s, d, makeEdgeFlagWithInvokeID(kind, cs)), csId(cs) { - } - /// Destructor - virtual ~PTACallGraphEdge() { - } - /// Compute the unique edgeFlag value from edge kind and CallSiteID. - static inline GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs) { - return (cs << EdgeKindMaskBits) | k; - } - /// Get direct and indirect calls - //@{ - inline CallSiteID getCallSiteID() const { - return csId; - } - inline bool isDirectCallEdge() const { - return !directCalls.empty() && indirectCalls.empty(); - } - inline bool isIndirectCallEdge() const { - return directCalls.empty() && !indirectCalls.empty(); - } - inline CallInstSet& getDirectCalls() { - return directCalls; - } - inline CallInstSet& getIndirectCalls() { - return indirectCalls; - } - inline const CallInstSet& getDirectCalls() const { - return directCalls; - } - inline const CallInstSet& getIndirectCalls() const { - return indirectCalls; - } - //@} - - /// Add direct and indirect callsite - //@{ - void addDirectCallSite(const Instruction* call) { - assert((SVFUtil::isa(call) || SVFUtil::isa(call)) && "not a call or inovke??"); - assert(SVFUtil::getCallee(call) && "not a direct callsite??"); - directCalls.insert(call); - } - - void addInDirectCallSite(const Instruction* call) { - assert((SVFUtil::isa(call) || SVFUtil::isa(call)) && "not a call or inovke??"); - assert((NULL == SVFUtil::getCallee(call) || NULL == SVFUtil::dyn_cast (SVFUtil::getForkedFun(call))) && "not an indirect callsite??"); - indirectCalls.insert(call); - } - //@} - - /// Iterators for direct and indirect callsites - //@{ - inline CallInstSet::iterator directCallsBegin() const { - return directCalls.begin(); - } - inline CallInstSet::iterator directCallsEnd() const { - return directCalls.end(); - } - - inline CallInstSet::iterator indirectCallsBegin() const { - return indirectCalls.begin(); - } - inline CallInstSet::iterator indirectCallsEnd() const { - return indirectCalls.end(); - } - //@} - - /// ClassOf - //@{ - static inline bool classof(const PTACallGraphEdge *edge) { - return true; - } - static inline bool classof(const GenericCallGraphEdgeTy *edge) { - return edge->getEdgeKind() == PTACallGraphEdge::CallRetEdge || - edge->getEdgeKind() == PTACallGraphEdge::TDForkEdge || - edge->getEdgeKind() == PTACallGraphEdge::TDJoinEdge; - } - //@} - - typedef GenericNode::GEdgeSetTy CallGraphEdgeSet; - -}; - -/* - * Call Graph node representing a function - */ -typedef GenericNode GenericCallGraphNodeTy; -class PTACallGraphNode : public GenericCallGraphNodeTy { - -public: - typedef PTACallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; - typedef PTACallGraphEdge::CallGraphEdgeSet::iterator iterator; - typedef PTACallGraphEdge::CallGraphEdgeSet::const_iterator const_iterator; - -private: - const Function* fun; - -public: - /// Constructor - PTACallGraphNode(NodeID i, const Function* f) : GenericCallGraphNodeTy(i,0), fun(f) { - - } - - /// Get function of this call node - inline const Function* getFunction() const { - return fun; - } - - /// Return TRUE if this function can be reached from main. - bool isReachableFromProgEntry() const; -}; - -/*! - * Pointer Analysis Call Graph used internally for various pointer analysis - */ -typedef GenericGraph GenericCallGraphTy; -class PTACallGraph : public GenericCallGraphTy { - -public: - typedef PTACallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; - typedef llvm::DenseMap FunToCallGraphNodeMap; - typedef llvm::DenseMap CallInstToCallGraphEdgesMap; - typedef std::pair CallSitePair; - typedef std::map CallSiteToIdMap; - typedef std::map IdToCallSiteMap; - typedef std::set FunctionSet; - typedef std::map CallEdgeMap; - typedef CallGraphEdgeSet::iterator CallGraphNodeIter; - - enum CGEK { - NormCallGraph, ThdCallGraph - }; - -private: - CGEK kind; - - SVFModule svfMod; - - /// Indirect call map - CallEdgeMap indirectCallMap; - - /// Call site information - static CallSiteToIdMap csToIdMap; ///< Map a pair of call instruction and callee to a callsite ID - static IdToCallSiteMap idToCSMap; ///< Map a callsite ID to a pair of call instruction and callee - static CallSiteID totalCallSiteNum; ///< CallSiteIDs, start from 1; - -protected: - FunToCallGraphNodeMap funToCallGraphNodeMap; ///< Call Graph node map - CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap; ///< Map a call instruction to its corresponding call edges - - NodeID callGraphNodeNum; - Size_t numOfResolvedIndCallEdge; - - /// Build Call Graph - void buildCallGraph(SVFModule svfModule); - - /// Add callgraph Node - void addCallGraphNode(const Function* fun); - - /// Clean up memory - void destroy(); - -public: - /// Constructor - PTACallGraph(SVFModule svfModule, CGEK k = NormCallGraph); - - /// Destructor - virtual ~PTACallGraph() { - destroy(); - } - - /// Return type of this callgraph - inline CGEK getKind() const { - return kind; - } - - /// Get callees from an indirect callsite - //@{ - inline CallEdgeMap& getIndCallMap() { - return indirectCallMap; - } - inline bool hasIndCSCallees(CallSite cs) const { - return (indirectCallMap.find(cs) != indirectCallMap.end()); - } - inline const FunctionSet& getIndCSCallees(CallSite cs) const { - CallEdgeMap::const_iterator it = indirectCallMap.find(cs); - assert(it!=indirectCallMap.end() && "not an indirect callsite!"); - return it->second; - } - inline const FunctionSet& getIndCSCallees(CallInst* csInst) const { - CallSite cs = SVFUtil::getLLVMCallSite(csInst); - return getIndCSCallees(cs); - } - //@} - inline u32_t getTotalCallSiteNumber() const { - return totalCallSiteNum; - } - - inline Size_t getNumOfResolvedIndCallEdge() const { - return numOfResolvedIndCallEdge; - } - - inline const CallInstToCallGraphEdgesMap& getCallInstToCallGraphEdgesMap() const { - return callinstToCallGraphEdgesMap; - } - - /// Issue a warning if the function which has indirect call sites can not be reached from program entry. - void verifyCallGraph(); - - /// Get call graph node - //@{ - inline PTACallGraphNode* getCallGraphNode(NodeID id) const { - return getGNode(id); - } - inline PTACallGraphNode* getCallGraphNode(const Function* fun) const { - FunToCallGraphNodeMap::const_iterator it = funToCallGraphNodeMap.find(fun); - assert(it!=funToCallGraphNodeMap.end() && "call graph node not found!!"); - return it->second; - } - //@} - - /// Add/Get CallSiteID - //@{ - inline CallSiteID addCallSite(CallSite cs, const Function* callee) { - std::pair newCS(std::make_pair(cs, callee)); - CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); - //assert(it == csToIdMap.end() && "cannot add a callsite twice"); - if(it == csToIdMap.end()) { - CallSiteID id = totalCallSiteNum++; - csToIdMap.insert(std::make_pair(newCS, id)); - idToCSMap.insert(std::make_pair(id, newCS)); - return id; - } - return it->second; - } - inline CallSiteID getCallSiteID(CallSite cs, const Function* callee) const { - CallSitePair newCS(std::make_pair(cs, callee)); - CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); - assert(it != csToIdMap.end() && "callsite id not found! This maybe a partially resolved callgraph, please check the indCallEdge limit"); - return it->second; - } - inline bool hasCallSiteID(CallSite cs, const Function* callee) const { - CallSitePair newCS(std::make_pair(cs, callee)); - CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); - return it != csToIdMap.end(); - } - inline const CallSitePair& getCallSitePair(CallSiteID id) const { - IdToCallSiteMap::const_iterator it = idToCSMap.find(id); - assert(it != idToCSMap.end() && "cannot find call site for this CallSiteID"); - return (it->second); - } - inline CallSite getCallSite(CallSiteID id) const { - return getCallSitePair(id).first; - } - inline const Function* getCallerOfCallSite(CallSiteID id) const { - return getCallSite(id).getCaller(); - } - inline const Function* getCalleeOfCallSite(CallSiteID id) const { - return getCallSitePair(id).second; - } - //@} - /// Get Module - inline SVFModule getModule() { - return svfMod; - } - inline SVFModule getSVFModule() { - return svfMod; - } - /// Whether we have aleady created this call graph edge - PTACallGraphEdge* hasGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId) const; - /// Get call graph edge via nodes - PTACallGraphEdge* getGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId); - /// Get call graph edge via call instruction - //@{ - /// whether this call instruction has a valid call graph edge - inline bool hasCallGraphEdge(const Instruction* inst) const { - return callinstToCallGraphEdgesMap.find(inst)!=callinstToCallGraphEdgesMap.end(); - } - inline CallGraphEdgeSet::const_iterator getCallEdgeBegin(const Instruction* inst) const { - CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst); - assert(it!=callinstToCallGraphEdgesMap.end() - && "call instruction does not have a valid callee"); - return it->second.begin(); - } - inline CallGraphEdgeSet::const_iterator getCallEdgeEnd(const Instruction* inst) const { - CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst); - assert(it!=callinstToCallGraphEdgesMap.end() - && "call instruction does not have a valid callee"); - return it->second.end(); - } - //@} - /// Add call graph edge - inline void addEdge(PTACallGraphEdge* edge) { - edge->getDstNode()->addIncomingEdge(edge); - edge->getSrcNode()->addOutgoingEdge(edge); - } - - /// Add direct/indirect call edges - //@{ - void addDirectCallGraphEdge(const Instruction* call); - void addIndirectCallGraphEdge(const Instruction* call, const Function* callee); - //@} - - /// Get callsites invoking the callee - //@{ - void getAllCallSitesInvokingCallee(const Function* callee, PTACallGraphEdge::CallInstSet& csSet); - void getDirCallSitesInvokingCallee(const Function* callee, PTACallGraphEdge::CallInstSet& csSet); - void getIndCallSitesInvokingCallee(const Function* callee, PTACallGraphEdge::CallInstSet& csSet); - //@} - - /// Dump the graph - void dump(const std::string& filename); -}; - - -namespace llvm { -/* ! - * GraphTraits specializations for generic graph algorithms. - * Provide graph traits for traversing from a constraint node using standard graph traversals. - */ -template<> struct GraphTraits : public GraphTraits* > { -}; - -/// Inverse GraphTraits specializations for call graph node, it is used for inverse traversal. -template<> -struct GraphTraits > : public GraphTraits* > > { -}; - -template<> struct GraphTraits : public GraphTraits* > { - typedef PTACallGraphNode *NodeRef; -}; - - -} - - -#endif /* PTACALLGRAPH_H_ */ diff --git a/lib/MemoryModel/PAGBuilderFromFile.cpp b/lib/MemoryModel/PAGBuilderFromFile.cpp index 24e63bd90..96a46c67b 100644 --- a/lib/MemoryModel/PAGBuilderFromFile.cpp +++ b/lib/MemoryModel/PAGBuilderFromFile.cpp @@ -64,8 +64,6 @@ void PAGBuilderFromFile::addNode(NodeID ID, string node_type, const char* str_v VarArgPN* node = new VarArgPN(ID,str_val,PAGNode::VarargNode); pag->addVarargNodeFromFile(str_val,node,ID); } - // else - // assert(false && "format not support, pls specify node type"); } diff --git a/lib/Util/SVFPTACallGraph.cpp b/lib/Util/SVFPTACallGraph.cpp deleted file mode 100644 index eebefc886..000000000 --- a/lib/Util/SVFPTACallGraph.cpp +++ /dev/null @@ -1,182 +0,0 @@ -// #include "Util/SVFModule.h" -// #include "Util/SVFPTACallGraph.h" -// #include "Util/SVFFunction.h" - -// using namespace SVFUtil; -// static llvm::cl::opt CallGraphDotGraph("dump-callgraph", llvm::cl::init(false), -// llvm::cl::desc("Dump dot graph of Call Graph")); - -// SVFPTACallGraph::CallSiteToIdMap SVFPTACallGraph::csToIdMap; -// SVFPTACallGraph::IdToCallSiteMap SVFPTACallGraph::idToCSMap; -// CallSiteID SVFPTACallGraph::totalCallSiteNum = 1; - - -// /// Constructor -// SVFPTACallGraph::SVFPTACallGraph(SVFModule svfModule, CGEK k): kind(k) { -// svfMod = svfModule; -// callGraphNodeNum = 0; -// numOfResolvedIndCallEdge = 0; -// buildCallGraph(svfModule); -// } - -// // /*! -// // * Build call graph, connect direct call edge only -// // */ -// // void PTACallGraph::buildCallGraph(SVFModule svfModule) { - -// // /// create nodes -// // for (SVFModule::iterator F = svfModule.begin(), E = svfModule.end(); F != E; ++F) { -// // addCallGraphNode(*F); -// // } - -// // /// create edges -// // for (SVFModule::iterator F = svfModule.begin(), E = svfModule.end(); F != E; ++F) { -// // Function *fun = *F; -// // for (inst_iterator II = inst_begin(*fun), E = inst_end(*fun); II != E; ++II) { -// // const Instruction *inst = &*II; -// // if (isNonInstricCallSite(inst)) { -// // if(getCallee(inst)) -// // addDirectCallGraphEdge(inst); -// // } -// // } -// // } - -// // dump("callgraph_initial"); -// // } - -// /*! -// * Memory has been cleaned up at GenericGraph -// */ -// void SVFPTACallGraph::destroy() { -// } - -// /*! -// * Add call graph node -// */ -// void SVFPTACallGraph::addCallGraphNode(const SVFFunction* fun) { -// NodeID id = callGraphNodeNum; -// PTACallGraphNode* callGraphNode = new PTACallGraphNode(id, fun); -// addGNode(id,callGraphNode); -// funToCallGraphNodeMap[fun] = callGraphNode; -// callGraphNodeNum++; -// } - -// /*! -// * Whether we have already created this call graph edge -// */ -// PTACallGraphEdge* SVFPTACallGraph::hasGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId) const { -// PTACallGraphEdge edge(src,dst,kind,csId); -// PTACallGraphEdge* outEdge = src->hasOutgoingEdge(&edge); -// PTACallGraphEdge* inEdge = dst->hasIncomingEdge(&edge); -// if (outEdge && inEdge) { -// assert(outEdge == inEdge && "edges not match"); -// return outEdge; -// } -// else -// return NULL; -// } - -// /*! -// * get CallGraph edge via nodes -// */ -// PTACallGraphEdge* SVFPTACallGraph::getGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId) { -// for (PTACallGraphEdge::CallGraphEdgeSet::iterator iter = src->OutEdgeBegin(); -// iter != src->OutEdgeEnd(); ++iter) { -// PTACallGraphEdge* edge = (*iter); -// if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId()) -// return edge; -// } -// return NULL; -// } - -// /*! -// * Add direct call edges -// */ -// void SVFPTACallGraph::addDirectCallGraphEdge(const std::string* call, PTACallGraphNode* caller,PTACallGraphNode* callee, CallSiteID csID) { -// // assert(getCallee(call) && "no callee found"); - -// // PTACallGraphNode* caller = getCallGraphNode(call->getParent()->getParent()); -// // PTACallGraphNode* callee = getCallGraphNode(getCallee(call)); - -// // CallSite cs = SVFUtil::getLLVMCallSite(call); -// // CallSiteID csId = addCallSite(cs, callee->getFunction()); - -// if(!hasGraphEdge(caller,callee, PTACallGraphEdge::CallRetEdge,csID)) { -// // assert(call->getParent()->getParent() == caller->getFunction() -// // && "callee instruction not inside caller??"); - -// PTACallGraphEdge* edge = new PTACallGraphEdge(caller,callee,PTACallGraphEdge::CallRetEdge,csID); -// edge->addDirectCallSite(call); -// addEdge(edge); -// callinstToCallGraphEdgesMap[call].insert(edge); -// } -// } - -// /*! -// * Add indirect call edge to update call graph -// */ -// void SVFPTACallGraph::addIndirectCallGraphEdge(const std::string* call, PTACallGraphNode* caller,PTACallGraphNode* callee, CallSiteID csID) { -// // PTACallGraphNode* caller = getCallGraphNode(call->getParent()->getParent()); -// // PTACallGraphNode* callee = getCallGraphNode(calleefun); - -// numOfResolvedIndCallEdge++; - -// // CallSite cs = SVFUtil::getLLVMCallSite(call); -// // CallSiteID csId = addCallSite(csID, callee->getFunction()); - -// if(!hasGraphEdge(caller,callee, PTACallGraphEdge::CallRetEdge,csID)) { -// // assert(call->getParent()->getParent() == caller->getFunction() -// // && "callee instruction not inside caller??"); - -// PTACallGraphEdge* edge = new PTACallGraphEdge(caller,callee,PTACallGraphEdge::CallRetEdge, csID); -// edge->addInDirectCallSite(call); -// addEdge(edge); -// callinstToCallGraphEdgesMap[call].insert(edge); -// } -// } - -// /*! -// * Get all callsite invoking this callee -// */ -// void SVFPTACallGraph::getAllCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) { -// PTACallGraphNode* callGraphNode = getCallGraphNode(callee); -// for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); -// it!=eit; ++it) { -// for(PTACallGraphEdge::CallInstSet::iterator cit = (*it)->directCallsBegin(), -// ecit = (*it)->directCallsEnd(); cit!=ecit; ++cit) { -// csSet.insert((*cit)); -// } -// for(PTACallGraphEdge::CallInstSet::iterator cit = (*it)->indirectCallsBegin(), -// ecit = (*it)->indirectCallsEnd(); cit!=ecit; ++cit) { -// csSet.insert((*cit)); -// } -// } -// } - -// /*! -// * Get direct callsite invoking this callee -// */ -// void SVFPTACallGraph::getDirCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) { -// PTACallGraphNode* callGraphNode = getCallGraphNode(callee); -// for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); -// it!=eit; ++it) { -// for(PTACallGraphEdge::CallInstSet::iterator cit = (*it)->directCallsBegin(), -// ecit = (*it)->directCallsEnd(); cit!=ecit; ++cit) { -// csSet.insert((*cit)); -// } -// } -// } - -// /*! -// * Get indirect callsite invoking this callee -// */ -// void SVFPTACallGraph::getIndCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet) { -// PTACallGraphNode* callGraphNode = getCallGraphNode(callee); -// for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); -// it!=eit; ++it) { -// for(PTACallGraphEdge::CallInstSet::iterator cit = (*it)->indirectCallsBegin(), -// ecit = (*it)->indirectCallsEnd(); cit!=ecit; ++cit) { -// csSet.insert((*cit)); -// } -// } -// } From 3f55f0770a86186893ad475150bc56cc8e4a178c Mon Sep 17 00:00:00 2001 From: "Zexin Zhong(Jason)" <42635164+JasonZhongZexin@users.noreply.github.com> Date: Sun, 15 Mar 2020 14:44:09 +0800 Subject: [PATCH 9/9] remove svfptacallGraph --- include/Util/SVFPTACallGraph.h | 350 --------------------------------- 1 file changed, 350 deletions(-) delete mode 100644 include/Util/SVFPTACallGraph.h diff --git a/include/Util/SVFPTACallGraph.h b/include/Util/SVFPTACallGraph.h deleted file mode 100644 index 96ffc93b8..000000000 --- a/include/Util/SVFPTACallGraph.h +++ /dev/null @@ -1,350 +0,0 @@ -// #ifndef SVFPTACALLGRAPH_H_ -// #define SVFPTACALLGRAPH_H_ - -// #include "MemoryModel/GenericGraph.h" -// #include "Util/SVFUtil.h" -// #include "Util/BasicTypes.h" -// #include "Util/SVFFunction.h" -// #include - -// class PTACallGraphNode; -// class SVFModule; - -// /* -// * Call Graph edge representing a calling relation between two functions -// * Multiple calls from function A to B are merged into one call edge -// * Each call edge has a set of direct callsites and a set of indirect callsites -// */ -// typedef GenericEdge GenericCallGraphEdgeTy; -// class PTACallGraphEdge : public GenericCallGraphEdgeTy { - -// public: -// typedef std::set CallInstSet; -// enum CEDGEK { -// CallRetEdge,TDForkEdge,TDJoinEdge,HareParForEdge -// }; - - -// private: -// CallInstSet directCalls; -// CallInstSet indirectCalls; -// CallSiteID csId; -// public: -// /// Constructor -// PTACallGraphEdge(PTACallGraphNode* s, PTACallGraphNode* d, CEDGEK kind, CallSiteID cs) : -// GenericCallGraphEdgeTy(s, d, makeEdgeFlagWithInvokeID(kind, cs)), csId(cs) { -// } -// /// Destructor -// virtual ~PTACallGraphEdge() { -// } -// /// Compute the unique edgeFlag value from edge kind and CallSiteID. -// static inline GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs) { -// return (cs << EdgeKindMaskBits) | k; -// } -// /// Get direct and indirect calls -// //@{ -// inline CallSiteID getCallSiteID() const { -// return csId; -// } -// inline bool isDirectCallEdge() const { -// return !directCalls.empty() && indirectCalls.empty(); -// } -// inline bool isIndirectCallEdge() const { -// return directCalls.empty() && !indirectCalls.empty(); -// } -// inline CallInstSet& getDirectCalls() { -// return directCalls; -// } -// inline CallInstSet& getIndirectCalls() { -// return indirectCalls; -// } -// inline const CallInstSet& getDirectCalls() const { -// return directCalls; -// } -// inline const CallInstSet& getIndirectCalls() const { -// return indirectCalls; -// } -// //@} - -// /// Add direct and indirect callsite -// //@{ -// void addDirectCallSite(const std::string* call) { -// // assert((SVFUtil::isa(call) || SVFUtil::isa(call)) && "not a call or inovke??"); -// // assert(SVFUtil::getCallee(call) && "not a direct callsite??"); -// directCalls.insert(call); -// } - -// void addInDirectCallSite(const std::string* call) { -// // assert((SVFUtil::isa(call) || SVFUtil::isa(call)) && "not a call or inovke??"); -// // assert((NULL == SVFUtil::getCallee(call) || NULL == SVFUtil::dyn_cast (SVFUtil::getForkedFun(call))) && "not an indirect callsite??"); -// indirectCalls.insert(call); -// } -// //@} - -// /// Iterators for direct and indirect callsites -// //@{ -// inline CallInstSet::iterator directCallsBegin() const { -// return directCalls.begin(); -// } -// inline CallInstSet::iterator directCallsEnd() const { -// return directCalls.end(); -// } - -// inline CallInstSet::iterator indirectCallsBegin() const { -// return indirectCalls.begin(); -// } -// inline CallInstSet::iterator indirectCallsEnd() const { -// return indirectCalls.end(); -// } -// //@} - -// /// ClassOf -// //@{ -// static inline bool classof(const PTACallGraphEdge *edge) { -// return true; -// } -// static inline bool classof(const GenericCallGraphEdgeTy *edge) { -// return edge->getEdgeKind() == PTACallGraphEdge::CallRetEdge || -// edge->getEdgeKind() == PTACallGraphEdge::TDForkEdge || -// edge->getEdgeKind() == PTACallGraphEdge::TDJoinEdge; -// } -// //@} - -// typedef GenericNode::GEdgeSetTy CallGraphEdgeSet; - -// }; - -// /* -// * Call Graph node representing a function -// */ -// typedef GenericNode GenericCallGraphNodeTy; -// class PTACallGraphNode : public GenericCallGraphNodeTy { - -// public: -// typedef PTACallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; -// typedef PTACallGraphEdge::CallGraphEdgeSet::iterator iterator; -// typedef PTACallGraphEdge::CallGraphEdgeSet::const_iterator const_iterator; - -// private: -// const SVFFunction* fun; - -// public: -// /// Constructor -// PTACallGraphNode(NodeID i, const SVFFunction* f) : GenericCallGraphNodeTy(i,0), fun(f) { - -// } - -// /// Get function of this call node -// inline const SVFFunction* getFunction() const { -// return fun; -// } - -// /// Return TRUE if this function can be reached from main. -// bool isReachableFromProgEntry() const; -// }; - -// /*! -// * Pointer Analysis Call Graph used internally for various pointer analysis -// */ -// typedef GenericGraph GenericCallGraphTy; -// class SVFPTACallGraph : public GenericCallGraphTy { - -// public: -// typedef PTACallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet; -// typedef llvm::DenseMap FunToCallGraphNodeMap; -// typedef llvm::DenseMap CallInstToCallGraphEdgesMap; -// typedef std::pair CallSitePair; -// typedef std::map CallSiteToIdMap; -// typedef std::map IdToCallSiteMap; -// typedef std::set FunctionSet; -// typedef std::map CallEdgeMap; -// typedef CallGraphEdgeSet::iterator CallGraphNodeIter; - -// enum CGEK { -// NormCallGraph, ThdCallGraph -// }; - -// private: -// CGEK kind; - -// SVFModule svfMod; - -// /// Indirect call map -// CallEdgeMap indirectCallMap; - -// /// Call site information -// static CallSiteToIdMap csToIdMap; ///< Map a pair of call instruction and callee to a callsite ID -// static IdToCallSiteMap idToCSMap; ///< Map a callsite ID to a pair of call instruction and callee -// static CallSiteID totalCallSiteNum; ///< CallSiteIDs, start from 1; - -// protected: -// FunToCallGraphNodeMap funToCallGraphNodeMap; ///< Call Graph node map -// CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap; ///< Map a call instruction to its corresponding call edges - -// NodeID callGraphNodeNum; -// Size_t numOfResolvedIndCallEdge; - -// /// Build Call Graph -// void buildCallGraph(SVFModule svfModule); - -// /// Add callgraph Node -// void addCallGraphNode(const SVFFunction* fun); - -// /// Clean up memory -// void destroy(); - -// public: -// /// Constructor -// SVFPTACallGraph(SVFModule svfModule, CGEK k = NormCallGraph); - -// /// Destructor -// virtual ~SVFPTACallGraph() { -// destroy(); -// } - -// /// Return type of this callgraph -// inline CGEK getKind() const { -// return kind; -// } - -// /// Get callees from an indirect callsite -// //@{ -// inline CallEdgeMap& getIndCallMap() { -// return indirectCallMap; -// } -// inline bool hasIndCSCallees(CallSite cs) const { -// return (indirectCallMap.find(cs) != indirectCallMap.end()); -// } -// inline const FunctionSet& getIndCSCallees(CallSite cs) const { -// CallEdgeMap::const_iterator it = indirectCallMap.find(cs); -// assert(it!=indirectCallMap.end() && "not an indirect callsite!"); -// return it->second; -// } -// inline const FunctionSet& getIndCSCallees(CallInst* csInst) const { -// CallSite cs = SVFUtil::getLLVMCallSite(csInst); -// return getIndCSCallees(cs); -// } -// //@} -// inline u32_t getTotalCallSiteNumber() const { -// return totalCallSiteNum; -// } - -// inline Size_t getNumOfResolvedIndCallEdge() const { -// return numOfResolvedIndCallEdge; -// } - -// inline const CallInstToCallGraphEdgesMap& getCallInstToCallGraphEdgesMap() const { -// return callinstToCallGraphEdgesMap; -// } - -// /// Issue a warning if the function which has indirect call sites can not be reached from program entry. -// void verifyCallGraph(); - -// /// Get call graph node -// //@{ -// inline PTACallGraphNode* getCallGraphNode(NodeID id) const { -// return getGNode(id); -// } -// inline PTACallGraphNode* getCallGraphNode(const SVFFunction* fun) const { -// FunToCallGraphNodeMap::const_iterator it = funToCallGraphNodeMap.find(fun); -// assert(it!=funToCallGraphNodeMap.end() && "call graph node not found!!"); -// return it->second; -// } -// //@} - -// /// Add/Get CallSiteID -// //@{ -// inline CallSiteID addCallSite(CallSite cs, const SVFFunction* callee) { -// std::pair newCS(std::make_pair(cs, callee)); -// CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); -// //assert(it == csToIdMap.end() && "cannot add a callsite twice"); -// if(it == csToIdMap.end()) { -// CallSiteID id = totalCallSiteNum++; -// csToIdMap.insert(std::make_pair(newCS, id)); -// idToCSMap.insert(std::make_pair(id, newCS)); -// return id; -// } -// return it->second; -// } -// inline CallSiteID getCallSiteID(CallSite cs, const SVFFunction* callee) const { -// CallSitePair newCS(std::make_pair(cs, callee)); -// CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); -// assert(it != csToIdMap.end() && "callsite id not found! This maybe a partially resolved callgraph, please check the indCallEdge limit"); -// return it->second; -// } -// inline bool hasCallSiteID(CallSite cs, const SVFFunction* callee) const { -// CallSitePair newCS(std::make_pair(cs, callee)); -// CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS); -// return it != csToIdMap.end(); -// } -// inline const CallSitePair& getCallSitePair(CallSiteID id) const { -// IdToCallSiteMap::const_iterator it = idToCSMap.find(id); -// assert(it != idToCSMap.end() && "cannot find call site for this CallSiteID"); -// return (it->second); -// } -// inline CallSite getCallSite(CallSiteID id) const { -// return getCallSitePair(id).first; -// } -// // inline const SVFFunction* getCallerOfCallSite(CallSiteID id) const { -// // return getCallSite(id).getCaller(); -// // } -// inline const SVFFunction* getCalleeOfCallSite(CallSiteID id) const { -// return getCallSitePair(id).second; -// } -// //@} -// /// Get Module -// inline SVFModule getModule() { -// return svfMod; -// } -// inline SVFModule getSVFModule() { -// return svfMod; -// } -// /// Whether we have aleady created this call graph edge -// PTACallGraphEdge* hasGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId) const; -// /// Get call graph edge via nodes -// PTACallGraphEdge* getGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind, CallSiteID csId); -// /// Get call graph edge via call instruction -// //@{ -// /// whether this call instruction has a valid call graph edge -// inline bool hasCallGraphEdge(const std::string* inst) const { -// return callinstToCallGraphEdgesMap.find(inst)!=callinstToCallGraphEdgesMap.end(); -// } -// inline CallGraphEdgeSet::const_iterator getCallEdgeBegin(const std::string* inst) const { -// CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst); -// assert(it!=callinstToCallGraphEdgesMap.end() -// && "call instruction does not have a valid callee"); -// return it->second.begin(); -// } -// inline CallGraphEdgeSet::const_iterator getCallEdgeEnd(const std::string* inst) const { -// CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst); -// assert(it!=callinstToCallGraphEdgesMap.end() -// && "call instruction does not have a valid callee"); -// return it->second.end(); -// } -// //@} -// /// Add call graph edge -// inline void addEdge(PTACallGraphEdge* edge) { -// edge->getDstNode()->addIncomingEdge(edge); -// edge->getSrcNode()->addOutgoingEdge(edge); -// } - -// /// Add direct/indirect call edges -// //@{ -// void addDirectCallGraphEdge(PTACallGraphNode* caller,PTACallGraphNode* callee, CallSiteID csID); -// void addIndirectCallGraphEdge(PTACallGraphNode* caller,PTACallGraphNode* callee, CallSiteID csID); -// //@} - -// /// Get callsites invoking the callee -// //@{ -// void getAllCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); -// void getDirCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); -// void getIndCallSitesInvokingCallee(const SVFFunction* callee, PTACallGraphEdge::CallInstSet& csSet); -// //@} - -// /// Dump the graph -// void dump(const std::string& filename); -// }; - - - -// #endif /* PTACALLGRAPH_H_ */