diff --git a/include/MemoryModel/ICFGBuilderFromFile.h b/include/MemoryModel/ICFGBuilderFromFile.h new file mode 100644 index 000000000..cc8b6ee9f --- /dev/null +++ b/include/MemoryModel/ICFGBuilderFromFile.h @@ -0,0 +1,48 @@ +#ifndef INCLUDE_MEMORYMODEL_ICFGBUILDERFROMFILE_H_ +#define INCLUDE_MEMORYMODEL_ICFGBUILDERFROMFILE_H_ + +#include "Util/ICFG.h" +#include "MemoryModel/PAG.h" +#include "llvm/Support/JSON.h" + + +/*! + * Build ICFG from a user specified file + */ +class ICFGBuilderFromFile{ + +private: + ICFG* icfg; + std::string file; + PAG pag; + +public: + //Constructor + ICFGBuilderFromFile(std::string f, PAG pag){ + this->pag = pag; + } + + // Destructor + ~ICFGBuilderFromFile() {} + + // Return ICFG + ICFG* getICFG() const{ + return icfg; + } + + std::string getFileName() const { + return file; + } + + PAG getPAG() const{ + return pag; + } + //Start building + ICFG* build(); + + void addNode(NodeID nodeID, std::string nodeType, llvm::json::Array* pagEdges); + + void addEdge(llvm::json::Object* edge_obj); +}; + +#endif /* INCLUDE_MEMORYMODEL_ICFGBUILDERFROMFILE_H_ */ \ No newline at end of file diff --git a/include/MemoryModel/PAG.h b/include/MemoryModel/PAG.h index d4ff08f5e..93d9ff7a9 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; @@ -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 @@ -705,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/include/MemoryModel/PAGBuilderFromFile.h b/include/MemoryModel/PAGBuilderFromFile.h index fcfd7c9e5..49a9073ca 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,8 +61,11 @@ class PAGBuilderFromFile { return file; } - /// Start building - PAG* build(); + //start building pag from ICFG json file + PAG* buildFromICFG(); + + //add pag nodes + 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/include/Util/ICFG.h b/include/Util/ICFG.h index 0897c10fa..2f2aa9e7f 100644 --- a/include/Util/ICFG.h +++ b/include/Util/ICFG.h @@ -76,6 +76,7 @@ class ICFG : public GenericICFGTy { public: /// Constructor ICFG(PTACallGraph* callgraph); + ICFG(); /// Destructor virtual ~ICFG() { @@ -104,6 +105,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); @@ -135,13 +144,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/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/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/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/lib/CMakeLists.txt b/lib/CMakeLists.txt index 3840c9f37..7f27796b9 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 @@ -28,6 +30,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..23e59441d --- /dev/null +++ b/lib/MemoryModel/ICFGBuilderFromFile.cpp @@ -0,0 +1,148 @@ +#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(); + 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 + 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,llvm::json::Array* pagEdges){ + const std::string *value = new std::string(""); + if(!icfg->hasICFGNode(nodeId)){ + if(nodeType=="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"){ + 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"){ + 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"){ + 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"){ + RetBlockNode *node = new RetBlockNode(nodeId,*(new CallSite())); + // 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/PAG.cpp b/lib/MemoryModel/PAG.cpp index 4f234a852..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 @@ -438,7 +605,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 +814,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 b55c1fab7..96a46c67b 100644 --- a/lib/MemoryModel/PAGBuilderFromFile.cpp +++ b/lib/MemoryModel/PAGBuilderFromFile.cpp @@ -31,92 +31,94 @@ #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 - */ -PAG* PAGBuilderFromFile::build() { +void PAGBuilderFromFile::addNode(NodeID ID, string node_type, const char* str_val){ + if(node_type=="DummyValNode"){ + pag->addDummyValNode(ID); + } + 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); + } + 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); + } + +} - string line; +//build pag from icfg file +PAG* PAGBuilderFromFile::buildFromICFG(){ 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::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(); + + //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(); + 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 + string var = ""; + const char *val = var.c_str(); + if(!pag->hasGNode(source_node)) + addNode(source_node,source_node_type,val); + if(!pag->hasGNode(destination_node)) + addNode(destination_node,destination_node_type,val); + if(pag->hasGNode(source_node)&&pag->hasGNode(destination_node)){ + if(offset!="") + addEdge(source_node, destination_node, std::stol(offset), edge_type); + else + addEdge(source_node, destination_node, NULL, 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; @@ -138,34 +140,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"){ + 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 == "gep") - pag->addNormalGepEdge(srcID, dstID, LocationSet(offsetOrCSId)); - else if (edge == "variant-gep") - 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 == "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/MemoryModel/PointerAnalysis.cpp b/lib/MemoryModel/PointerAnalysis.cpp index ad6353439..912e78ae9 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,11 @@ 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(); + 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")); @@ -152,13 +157,12 @@ 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 - if (PAGPrint) - pag->print(); + // // dump the PAG graph + // if (dumpGraph()) + // PAG::getPAG()->dump("pag_initial"); + // // print to command line of the PAG graph + // if (PAGPrint) + // pag->print(); } /// initialise pta call graph for every pointer analysis instance @@ -210,7 +214,6 @@ bool PointerAnalysis::dumpGraph() { */ void PointerAnalysis::dumpStat() { - if(print_stat && stat) stat->performStat(); } @@ -223,8 +226,7 @@ void PointerAnalysis::dumpStat() { void PointerAnalysis::finalize() { /// Print statistics - dumpStat(); - + //dumpStat(); PAG* pag = PAG::getPAG(); // dump the PAG graph if (dumpGraph()) @@ -241,7 +243,6 @@ void PointerAnalysis::finalize() { if (TYPEPrint) dumpAllTypes(); - if(PTSAllPrint) dumpAllPts(); diff --git a/lib/Util/ICFG.cpp b/lib/Util/ICFG.cpp index 76dd2d947..fda0cc70b 100644 --- a/lib/Util/ICFG.cpp +++ b/lib/Util/ICFG.cpp @@ -54,6 +54,8 @@ ICFG::ICFG(PTACallGraph* cg): totalICFGNode(0), callgraph(cg), pag(PAG::getPAG() addPAGEdgeToICFG(); } +ICFG::ICFG(){} + /*! * Memory has been cleaned up at GenericGraph */ 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; 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