38using namespace SVFUtil;
126 rawstr <<
it->second->getId() <<
", ";
146 rawstr <<
"BinaryOPVFGNode ID: " <<
getId() <<
" ";
150 rawstr <<
it->second->getId() <<
", ";
174 rawstr <<
it->second->getId() <<
", ";
228 rawstr <<
it->second->getId() <<
", ";
242 rawstr <<
"IntraPHIVFGNode ID: " <<
getId() <<
" ";
246 rawstr <<
it->second->getId() <<
", ";
276 rawstr <<
"ArgumentVFGNode ID: " <<
getId() <<
" ";
292 rawstr <<
"ActualParmVFGNode ID: " <<
getId() <<
" ";
309 rawstr <<
"FormalParmVFGNode ID: " <<
getId() <<
" ";
326 rawstr <<
"ActualRetVFGNode ID: " <<
getId() <<
" ";
344 rawstr <<
"FormalRetVFGNode ID: " <<
getId() <<
" ";
473 for (SVFStmt::SVFStmtSetTy::iterator
iter = addrs.begin(),
eiter =
481 for (SVFStmt::SVFStmtSetTy::iterator
iter =
copys.begin(),
eiter =
491 for (SVFStmt::SVFStmtSetTy::iterator
iter =
ngeps.begin(),
eiter =
499 for (SVFStmt::SVFStmtSetTy::iterator
iter =
loads.begin(),
eiter =
514 for (SVFStmt::SVFStmtSetTy::iterator
iter =
forks.begin(),
eiter =
606 const RetPE* retPE = SVFUtil::cast<RetPE>(*
cit);
608 retPEs.insert(retPE);
618 for (SVFStmt::SVFStmtSetTy::iterator
iter =
phis.begin(),
eiter =
654 for (SVFStmt::SVFStmtSetTy::iterator
iter =
brs.begin(),
eiter =
663 for (SVFStmt::SVFStmtSetTy::iterator
iter =
cmps.begin(),
eiter =
683 assert(
edge->isDirectVFGEdge() &&
"this should be a direct value flow edge!");
708 assert(
edge->isCallDirectVFGEdge() &&
"this should be a direct value flow edge!");
728 assert(
edge->isRetDirectVFGEdge() &&
"this should be a direct value flow edge!");
753 if(SVFUtil::isa<AddrVFGNode>(
stmtNode))
756 if (
stmtNode->getPAGSrcNode()->isConstDataOrAggDataButNotNullPtr() ==
false)
762 for (
const auto &
varType:
gepStmt->getOffsetVarAndGepTypePairVec())
770 if(SVFUtil::isa<StoreVFGNode>(
stmtNode) && (
stmtNode->getPAGDstNode()->isConstDataOrAggDataButNotNullPtr() ==
false))
780 if (
it->second->isConstDataOrAggDataButNotNullPtr() ==
false)
788 if (
it->second->isConstDataOrAggDataButNotNullPtr() ==
false)
796 if (
it->second->isConstDataOrAggDataButNotNullPtr() ==
false)
804 if (
it->second->isConstDataOrAggDataButNotNullPtr() ==
false)
816 if (
actualParm->getParam()->isConstDataOrAggDataButNotNullPtr() ==
false)
838 const CallICFGNode* callBlockNode = (*it)->getCallSite();
851 for (SVFStmt::SVFStmtSetTy::iterator
iter =
forks.begin(),
eiter =
861 for (SVFStmt::SVFStmtSetTy::iterator
iter =
joins.begin(),
eiter =
954 PointerAnalysis::CallEdgeMap::const_iterator
iter = pta->
getIndCallMap().begin();
959 assert(
newcs->isIndirectCall() &&
"this is not an indirect call?");
1028 return addr->getPAGDstNode();
1029 else if(
const CopyVFGNode*
copy = SVFUtil::dyn_cast<CopyVFGNode>(node))
1030 return copy->getPAGDstNode();
1031 else if(
const GepVFGNode*
gep = SVFUtil::dyn_cast<GepVFGNode>(node))
1032 return gep->getPAGDstNode();
1033 else if(
const LoadVFGNode* load = SVFUtil::dyn_cast<LoadVFGNode>(node))
1034 return load->getPAGDstNode();
1035 else if(
const PHIVFGNode*
phi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1036 return phi->getRes();
1037 else if(
const CmpVFGNode*
cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1038 return cmp->getRes();
1040 return bop->getRes();
1042 return uop->getRes();
1043 else if(
const ActualParmVFGNode* ap = SVFUtil::dyn_cast<ActualParmVFGNode>(node))
1044 return ap->getParam();
1046 return fp->getParam();
1048 return ar->getRev();
1050 return fr->getRet();
1054 assert(
false &&
"unexpected node kind!");
1065 return fp->getFun();
1069 if(
phi->isFormalParmPHI())
1070 return phi->getFun();
1125 return getSimpleNodeLabel(node, graph);
1127 return getCompleteNodeLabel(node, graph);
1149 rawstr << ap->toString();
1159 else if(SVFUtil::isa<NullPtrVFGNode>(node))
1171 else if(
CmpVFGNode*
cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1180 assert(
false &&
"what else kinds of nodes do we have??");
1203 else if(
CmpVFGNode*
cmp = SVFUtil::dyn_cast<CmpVFGNode>(node))
1207 else if(
PHIVFGNode*
phi = SVFUtil::dyn_cast<PHIVFGNode>(node))
1217 rawstr << ap->toString();
1231 else if (
MRSVFGNode* mr = SVFUtil::dyn_cast<MRSVFGNode>(node))
1233 rawstr << mr->toString();
1240 assert(
false &&
"what else kinds of nodes do we have??");
1253 if (SVFUtil::isa<AddrStmt>(
edge))
1257 else if (SVFUtil::isa<CopyStmt>(
edge))
1261 else if (SVFUtil::isa<RetPE>(
edge))
1263 rawstr <<
"color=black,style=dotted";
1265 else if (SVFUtil::isa<GepStmt>(
edge))
1267 rawstr <<
"color=purple";
1269 else if (SVFUtil::isa<StoreStmt>(
edge))
1273 else if (SVFUtil::isa<LoadStmt>(
edge))
1279 assert(0 &&
"No such kind edge!!");
1283 else if (SVFUtil::isa<CmpVFGNode>(node))
1287 else if (SVFUtil::isa<BinaryOPVFGNode>(node))
1291 else if (SVFUtil::isa<UnaryOPVFGNode>(node))
1295 else if(SVFUtil::isa<PHIVFGNode>(node))
1299 else if(SVFUtil::isa<NullPtrVFGNode>(node))
1303 else if(SVFUtil::isa<FormalParmVFGNode>(node))
1305 rawstr <<
"color=yellow,penwidth=2";
1307 else if(SVFUtil::isa<ActualParmVFGNode>(node))
1309 rawstr <<
"color=yellow,penwidth=2";
1311 else if (SVFUtil::isa<ActualRetVFGNode>(node))
1313 rawstr <<
"color=yellow,penwidth=2";
1315 else if (SVFUtil::isa<FormalRetVFGNode>(node))
1317 rawstr <<
"color=yellow,penwidth=2";
1319 else if (SVFUtil::isa<MRSVFGNode>(node))
1321 rawstr <<
"color=orange,penwidth=2";
1323 else if (SVFUtil::isa<BranchVFGNode>(node))
1325 rawstr <<
"color=gold,penwidth=2";
1328 assert(
false &&
"no such kind of node!!");
1335 template<
class EdgeIter>
1340 if (SVFUtil::isa<DirectSVFGEdge>(
edge))
1342 if (SVFUtil::isa<CallDirSVFGEdge>(
edge))
1343 return "style=solid,color=red";
1344 else if (SVFUtil::isa<RetDirSVFGEdge>(
edge))
1345 return "style=solid,color=blue";
1347 return "style=solid";
1349 else if (SVFUtil::isa<IndirectSVFGEdge>(
edge))
1351 if (SVFUtil::isa<CallIndSVFGEdge>(
edge))
1352 return "style=dashed,color=red";
1353 else if (SVFUtil::isa<RetIndSVFGEdge>(
edge))
1354 return "style=dashed,color=blue";
1356 return "style=dashed";
1360 assert(
false &&
"what else edge we have?");
1365 template<
class EdgeIter>
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
const std::string toString() const override
const PAGNode * getParam() const
Return parameter.
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const CallICFGNode * getCallSite() const
Return callsite.
const CallICFGNode * getCallSite() const
Return callsite.
const std::string toString() const override
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const PAGNode * getRev() const
Receive parameter at callsite.
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const std::string toString() const override
const std::string toString() const override
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
SVFVar * getLHSVar() const
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
const PAGNode * getRes() const
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const std::string toString() const override
OPVers::const_iterator opVerBegin() const
OPVers::const_iterator opVerEnd() const
virtual const std::string toString() const override
virtual const std::string toString() const override
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const BranchStmt * brstmt
CallSiteID getCallSiteId() const
Return callsite ID.
virtual const std::string toString() const
const RetICFGNode * getRetICFGNode() const
Return callsite.
const std::string getSourceLoc() const override
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
OPVers::const_iterator opVerBegin() const
const std::string toString() const override
const PAGNode * getRes() const
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
OPVers::const_iterator opVerEnd() const
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const std::string toString() const override
virtual const std::string toString() const
NodeID getSrcID() const
get methods of the components
iterator begin()
Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
const GEdgeSetTy & getOutEdges() const
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const std::string toString() const override
static void WriteGraphToFile(SVF::OutStream &O, const std::string &GraphName, const GraphType >, bool simple=false)
virtual const SVFFunction * getFun() const
Return the function of this ICFGNode.
NodeID getNullPtr() const
NodeID getVarargNode(const SVFFunction *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
bool isFormalParmPHI() const
const std::string toString() const override
virtual const std::string toString() const
const std::string toString() const override
const std::string toString() const override
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const std::string toString() const override
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const PAGNode * getPAGNode() const
Return corresponding PAGNode.
static const Option< bool > EnableThreadCallGraph
OPVers::const_iterator opVerBegin() const
const PAGNode * getRes() const
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const std::string toString() const override
OPVers::const_iterator opVerEnd() const
PHIVFGNode(NodeID id, const PAGNode *r, VFGNodeK k=TPhi)
Constructor.
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Set< const SVFFunction * > FunctionSet
virtual const std::string toString() const
CallSiteID getCallSiteId() const
Return callsite ID.
NodeID getId() const
Get ID.
CSToArgsListMap & getCallSiteArgsMap()
Get callsite argument list.
std::vector< const SVFVar * > SVFVarList
const SVFVarList & getFunArgsList(const SVFFunction *func) const
Get function arguments list.
CSToRetMap & getCallSiteRets()
Get callsite return.
FunToRetMap & getFunRets()
Get function return list.
const SVFVar * getFunRet(const SVFFunction *func) const
Get function return list.
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
bool callsiteHasRet(const RetICFGNode *cs) const
bool hasFunArgsList(const SVFFunction *func) const
Function has arguments list.
const SVFVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
const SVFVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
FunToArgsListMap & getFunArgsMap()
Get function arguments list.
bool funHasRet(const SVFFunction *func) const
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
const SVFValue * getValue() const
virtual const std::string toString() const
std::string toString() const
Needs to be implemented by a SVF front end.
const std::string & getName() const
bool isConstDataOrAggDataButNotNullPtr() const
const SVFValue * getValue() const
Get/has methods of the components.
bool hasIncomingEdges(SVFStmt::PEDGEK kind) const
Has incoming SVFIR statements (edges)
SVFStmt::SVFStmtSetTy::iterator getIncomingEdgesBegin(SVFStmt::PEDGEK kind) const
Get incoming SVFStmt iterator.
virtual const std::string toString() const
SVFStmt::SVFStmtSetTy::iterator getIncomingEdgesEnd(SVFStmt::PEDGEK kind) const
Get incoming SVFStmt iterator.
NodeID getPAGDstNodeID() const
const PAGEdge * getPAGEdge() const
const SVFValue * getValue() const override
Return the corresponding LLVM value, if possible, nullptr otherwise.
const std::string toString() const override
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
const std::string toString() const override
const NodeBS getDefSVFVars() const override
Return the left hand side SVF Vars.
OPVers::const_iterator opVerBegin() const
virtual const std::string toString() const override
const PAGNode * getRes() const
OPVers::const_iterator opVerEnd() const
static GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs)
Compute the unique edgeFlag value from edge kind and CallSiteID.
virtual const std::string toString() const
virtual const std::string toString() const
VFGEdge::VFGEdgeSetTy VFGEdgeSetTy
void updateCallGraph(PointerAnalysis *pta)
Update VFG based on pointer analysis results.
VFGEdge * addInterEdgeFromAPToFP(ActualParmVFGNode *src, FormalParmVFGNode *dst, CallSiteID csId)
Add inter VF edge from actual to formal parameters.
void addStoreVFGNode(const StoreStmt *store)
VFGEdge * addInterEdgeFromFRToAR(FormalRetVFGNode *src, ActualRetVFGNode *dst, CallSiteID csId)
Add inter VF edge from callee return to callsite receive parameter.
void addBranchVFGNode(const BranchStmt *edge)
Add a BranchVFGNode.
virtual SVFStmt::SVFStmtSetTy & getPAGEdgeSet(SVFStmt::PEDGEK kind)
Get PAGEdge set.
const PAGNode * getLHSTopLevPtr(const VFGNode *node) const
FormalParmVFGNode * getFormalParmVFGNode(const PAGNode *fparm) const
VFGNodeIDToNodeMapTy::iterator iterator
ActualRetVFGNode * getActualRetVFGNode(const PAGNode *aret) const
VFGEdge * addRetEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
virtual void connectAParamAndFParam(const PAGNode *csArg, const PAGNode *funArg, const CallICFGNode *cbn, CallSiteID csId, VFGEdgeSetTy &edges)
Connect VFG nodes between caller and callee for indirect call site.
FormalRetVFGNode * getFormalRetVFGNode(const PAGNode *fret) const
void addVFGNodes()
Create VFG nodes.
void addLoadVFGNode(const LoadStmt *load)
Add a Load VFG node.
VFGEdge * addIntraDirectVFEdge(NodeID srcId, NodeID dstId)
void checkIntraEdgeParents(const VFGNode *srcNode, const VFGNode *dstNode)
sanitize Intra edges, verify that both nodes belong to the same function.
void addCopyVFGNode(const CopyStmt *copy)
Add a Copy VFG node.
void addGepVFGNode(const GepStmt *gep)
Add a Gep VFG node.
void addNullPtrVFGNode(const PAGNode *pagNode)
CallSiteID getCallSiteID(const CallICFGNode *cs, const SVFFunction *func) const
Get callsite given a callsiteID.
void addActualRetVFGNode(const PAGNode *ret, const CallICFGNode *cs)
Add a callsite Receive VFG node.
void addUnaryOPVFGNode(const UnaryOPStmt *edge)
Add a UnaryOperator VFG node.
void addActualParmVFGNode(const PAGNode *aparm, const CallICFGNode *cs)
void addCmpVFGNode(const CmpStmt *edge)
Add a Compare VFG node.
NodeID getDef(const PAGNode *pagNode) const
bool addVFGEdge(VFGEdge *edge)
Add VFG edge.
virtual bool isInterestedPAGNode(const SVFVar *node) const
bool hasBlackHoleConstObjAddrAsDef(const PAGNode *pagNode) const
Whether a PAGNode has a blackhole or const object as its definition.
const SVFFunction * isFunEntryVFGNode(const VFGNode *node) const
Whether a node is function entry VFGNode.
VFG(PTACallGraph *callgraph, VFGK k=FULLSVFG)
Constructor.
ActualParmVFGNode * getActualParmVFGNode(const PAGNode *aparm, const CallICFGNode *cs) const
bool isPhiCopyEdge(const PAGEdge *copy) const
VFGNode * getVFGNode(NodeID id) const
Get a VFG node.
VFGEdge * addCallEdge(NodeID srcId, NodeID dstId, CallSiteID csId)
virtual void connectCallerAndCallee(const CallICFGNode *cs, const SVFFunction *callee, VFGEdgeSetTy &edges)
Connect VFG nodes between caller and callee for indirect call site.
void addFormalRetVFGNode(const PAGNode *uniqueFunRet, const SVFFunction *fun, RetPESet &retPEs)
virtual void connectFRetAndARet(const PAGNode *funReturn, const PAGNode *csReturn, CallSiteID csId, VFGEdgeSetTy &edges)
Connect formal-ret and actual ret.
bool hasDef(const PAGNode *pagNode) const
FormalRetVFGNode::RetPESet RetPESet
VFGEdge * hasIntraVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
Whether we has a SVFG edge.
void addBinaryOPVFGNode(const BinaryOPStmt *edge)
Add a BinaryOperator VFG node.
void addAddrVFGNode(const AddrStmt *addr)
Add an Address VFG node.
VFGEdge * hasInterVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind, CallSiteID csId)
FormalParmVFGNode::CallPESet CallPESet
void connectDirectVFGEdges()
Create edges between VFG nodes within a function.
VFGEdge * getIntraVFGEdge(const VFGNode *src, const VFGNode *dst, VFGEdge::VFGEdgeK kind)
Get a SVFG edge according to src and dst.
void view()
Dump graph into dot file.
VFGEdge * hasThreadVFGEdge(VFGNode *src, VFGNode *dst, VFGEdge::VFGEdgeK kind)
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
void destroy()
Clean up memory.
void addIntraPHIVFGNode(const MultiOpndStmt *edge)
Add an llvm PHI VFG node.
void addFormalParmVFGNode(const PAGNode *fparm, const SVFFunction *fun, CallPESet &callPEs)
Add a formal parameter VFG node.
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
std::ostream & outs()
Overwrite llvm::outs()
bool matchArgs(const CallICFGNode *cs, const SVFFunction *callee)
void ViewGraph(const GraphType &G, const std::string &name, bool ShortNames=false, GraphProgram::Name Program=GraphProgram::DOT)
llvm::IRBuilder IRBuilder
static std::string getCompleteNodeLabel(NodeType *node, VFG *)
Return label of a VFG node with MemSSA information.
static std::string getNodeAttributes(NodeType *node, VFG *)
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
DOTGraphTraits(bool isSimple=false)
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, VFG *)
std::string getNodeLabel(NodeType *node, VFG *graph)
static std::string getSimpleNodeLabel(NodeType *node, VFG *)
Return label of a VFG node without MemSSA information.
static std::string getGraphName(VFG *)
Return name of the graph.