37 using namespace SVFUtil;
64 std::stringstream rawstr(str);
65 rawstr <<
"ICFGNode" <<
getId();
77 std::stringstream rawstr(str);
78 rawstr <<
"GlobalICFGNode" <<
getId();
80 rawstr <<
"\n" << stmt->toString();
88 std::stringstream rawstr(str);
89 rawstr <<
"IntraICFGNode" <<
getId();
92 rawstr <<
"\n" << stmt->toString();
102 std::stringstream rawstr(str);
103 rawstr <<
"FunEntryICFGNode" <<
getId();
109 rawstr <<
"\n" << stmt->toString();
117 std::stringstream rawstr(str);
118 rawstr <<
"FunExitICFGNode" <<
getId();
123 rawstr << intraICFGNode->getSourceLoc();
126 rawstr <<
"\n" << stmt->toString();
134 std::stringstream rawstr(str);
135 rawstr <<
"CallICFGNode" <<
getId();
138 rawstr <<
"\n" << stmt->toString();
147 std::stringstream rawstr(str);
148 rawstr <<
"RetICFGNode" <<
getId();
151 rawstr <<
"\n" << stmt->toString();
160 std::stringstream rawstr(str);
161 rawstr <<
"ICFGEdge: [ICFGNode" <<
getDstID() <<
" <-- ICFGNode" <<
getSrcID() <<
"]\t";
168 std::stringstream rawstr(str);
170 rawstr <<
"IntraCFGEdge: [ICFGNode" <<
getDstID() <<
" <-- ICFGNode" <<
getSrcID() <<
"]\t";
180 std::stringstream rawstr(str);
181 rawstr <<
"CallCFGEdge " <<
" [ICFGNode";
189 std::stringstream rawstr(str);
190 rawstr <<
"RetCFGEdge " <<
" [ICFGNode";
198 assert(SVFUtil::isa<RetICFGNode>(
getDstNode()) &&
"not a RetICFGNode?");
199 return SVFUtil::cast<RetICFGNode>(
getDstNode())->getCallICFGNode();
219 for (
const auto &loop: it.second)
225 for (
const auto &it: loops)
237 assert (entry &&
"fun entry not created in ICFGBuilder?");
244 assert (exit &&
"fun exit not created in ICFGBuilder?");
256 if (outEdge && inEdge)
258 assert(outEdge == inEdge &&
"edges not match");
273 if (outEdge && inEdge)
275 assert(outEdge == inEdge &&
"edges not match");
290 if (outEdge && inEdge)
292 assert(outEdge == inEdge &&
"edges not match");
308 for (ICFGEdge::ICFGEdgeSetTy::iterator iter = src->
OutEdgeBegin();
311 if ((*iter)->getDstID() == dst->
getId() && (*iter)->getEdgeKind() == kind)
317 assert(counter <= 1 &&
"there's more than one edge between two ICFG nodes");
331 assert(edge->
isIntraCFGEdge() &&
"this should be an intra CFG edge!");
337 return (
addICFGEdge(intraEdge) ? intraEdge :
nullptr);
351 assert(edge->
isIntraCFGEdge() &&
"this should be an intra CFG edge!");
358 return (
addICFGEdge(intraEdge) ? intraEdge :
nullptr);
371 assert(edge->
isCallCFGEdge() &&
"this should be a call CFG edge!");
377 return (
addICFGEdge(callEdge) ? callEdge :
nullptr);
389 assert(edge->
isRetCFGEdge() &&
"this should be a return CFG edge!");
421 PTACallGraph::CallEdgeMap::const_iterator iter = callgraph->
getIndCallMap().begin();
422 PTACallGraph::CallEdgeMap::const_iterator eiter = callgraph->
getIndCallMap().end();
423 for (; iter != eiter; iter++)
426 assert(callBlockNode->
isIndirectCall() &&
"this is not an indirect call?");
428 for (PTACallGraph::FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
443 if(
const CallPE *callPE = SVFUtil::dyn_cast<CallPE>(stmt))
445 if(callPE->getFunEntryICFGNode() == calleeEntryNode)
446 SVFUtil::cast<CallCFGEdge>(callEdge)->addCallPE(callPE);
454 if(
const RetPE *retPE = SVFUtil::dyn_cast<RetPE>(stmt))
456 if(retPE->getFunExitICFGNode() == calleeExitNode)
457 SVFUtil::cast<RetCFGEdge>(retEdge)->addRetPE(retPE);
499 return getSimpleNodeLabel(node, graph);
519 std::stringstream rawstr(str);
521 if(SVFUtil::isa<IntraICFGNode>(node))
523 rawstr <<
"color=black";
525 else if(SVFUtil::isa<FunEntryICFGNode>(node))
527 rawstr <<
"color=yellow";
529 else if(SVFUtil::isa<FunExitICFGNode>(node))
531 rawstr <<
"color=green";
533 else if(SVFUtil::isa<CallICFGNode>(node))
535 rawstr <<
"color=red";
537 else if(SVFUtil::isa<RetICFGNode>(node))
539 rawstr <<
"color=blue";
541 else if(SVFUtil::isa<GlobalICFGNode>(node))
543 rawstr <<
"color=purple";
546 assert(
false &&
"no such kind of node!!");
553 template<
class EdgeIter>
556 ICFGEdge* edge = *(EI.getCurrent());
557 assert(edge &&
"No edge found!!");
558 if (SVFUtil::isa<CallCFGEdge>(edge))
559 return "style=solid,color=red";
560 else if (SVFUtil::isa<RetCFGEdge>(edge))
561 return "style=solid,color=blue";
563 return "style=solid";
567 template<
class EdgeIter>
570 ICFGEdge* edge = *(EI.getCurrent());
571 assert(edge &&
"No edge found!!");
574 std::stringstream rawstr(str);
575 if (
CallCFGEdge* dirCall = SVFUtil::dyn_cast<CallCFGEdge>(edge))
576 rawstr << dirCall->getSrcNode();
577 else if (
RetCFGEdge* dirRet = SVFUtil::dyn_cast<RetCFGEdge>(edge))
579 if(
RetICFGNode* ret = SVFUtil::dyn_cast<RetICFGNode>(dirRet->getDstNode()))
580 rawstr << ret->getCallICFGNode();
virtual const std::string toString() const
const std::string toString() const override
bool isIndirectCall() const
Return true if this is an indirect call.
const RetICFGNode * getRetICFGNode() const
Return callsite.
FunEntryICFGNode(NodeID id)
Constructor to create empty FunEntryICFGNode (for SVFIRReader/deserialization)
const SVFFunction * getFun() const override
Return function.
const std::string toString() const override
const std::string toString() const override
FunExitICFGNode(NodeID id)
Constructor to create empty FunExitICFGNode (for SVFIRReader/deserialization)
const SVFFunction * getFun() const override
Return function.
NodeType * getSrcNode() const
NodeID getSrcID() const
get methods of the components
NodeType * getDstNode() const
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
const GEdgeSetTy & getOutEdges() const
iterator OutEdgeBegin()
iterators
const GEdgeSetTy & getInEdges() const
const std::string toString() const override
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType >, bool simple=false)
bool isCallCFGEdge() const
bool isIntraCFGEdge() const
virtual const std::string toString() const
bool isRetCFGEdge() const
const SVFStmtList & getSVFStmts() const
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
virtual const std::string toString() const
void view()
View graph from the debugger.
FunEntryICFGNode * getFunEntryICFGNode(const SVFFunction *fun)
Add a function entry node.
FunExitICFGNode * getFunExitBlock(const SVFFunction *fun)
Get/Add a function exit node.
ICFGEdge * hasThreadICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
bool addICFGEdge(ICFGEdge *edge)
Add ICFG edge, only used by addIntraEdge, addCallEdge, addRetEdge etc.
void removeICFGEdge(ICFGEdge *edge)
Remove a ICFG edge.
void updateCallGraph(PTACallGraph *callgraph)
update ICFG for indirect calls
ICFGEdge * getICFGEdge(const ICFGNode *src, const ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Get a SVFG edge according to src and dst.
void checkIntraEdgeParents(const ICFGNode *srcNode, const ICFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
ICFGEdge * addCallEdge(ICFGNode *srcNode, ICFGNode *dstNode)
ICFGNodeToSVFLoopVec icfgNodeToSVFLoopVec
map ICFG node to the SVF loops where it resides
ICFGEdge * hasInterICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
ICFGEdge * addRetEdge(ICFGNode *srcNode, ICFGNode *dstNode)
ICFGEdge * hasIntraICFGEdge(ICFGNode *src, ICFGNode *dst, ICFGEdge::ICFGEdgeK kind)
Whether we has a SVFG edge.
ICFGEdge * addConditionalIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode, s64_t branchCondVal)
FunEntryICFGNode * getFunEntryBlock(const SVFFunction *fun)
Get/Add a function entry node.
ICFGEdge * addIntraEdge(ICFGNode *srcNode, ICFGNode *dstNode)
Add intraprocedural and interprocedural control-flow edges.
~ICFG() override
Destructor.
FunExitICFGNode * getFunExitICFGNode(const SVFFunction *fun)
Add a function exit node.
s64_t getSuccessorCondValue() const
virtual const std::string toString() const
void setBranchCondVal(s64_t bVal)
const SVFVar * getCondition() const
const std::string toString() const override
static const Option< bool > ShowHiddenNode
static const Option< bool > DumpICFG
Set< const SVFFunction * > FunctionSet
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
const CallICFGNode * getCallSite() const
Return call ICFGNode at the callsite.
virtual const std::string toString() const
const std::string toString() const override
NodeID getId() const
Get ID.
const std::string valueOnlyToString() const
virtual const std::string getSourceLoc() const
const ICFGNode * front() const
const_iterator end() const
const_iterator begin() const
const SVFBasicBlock * getEntryBlock() const
const SVFBasicBlock * getExitBB() const
const std::string & getName() const
virtual const std::string getSourceLoc() const
virtual const std::string toString() const
bool isExtCall(const SVFFunction *fun)
std::ostream & outs()
Overwrite llvm::outs()
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
std::string getNodeLabel(NodeType *node, ICFG *graph)
static std::string getGraphName(ICFG *)
Return name of the graph.
static bool isNodeHidden(ICFGNode *node, ICFG *)
static std::string getSimpleNodeLabel(NodeType *node, ICFG *)
Return the label of an ICFG node.
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, ICFG *)
static std::string getNodeAttributes(NodeType *node, ICFG *)
DOTGraphTraits(bool isSimple=false)