36 using namespace SVFUtil;
49 rawstr <<
"PAGNode ID: " << getId();
57 if (SVFUtil::isa<ValPN>(
this))
59 if(SVFUtil::isa<GepValPN>(
this))
60 return "shape=hexagon";
61 else if (SVFUtil::isa<DummyValPN>(
this))
62 return "shape=diamond";
66 else if (SVFUtil::isa<ObjPN>(
this))
68 if(SVFUtil::isa<GepObjPN>(
this))
69 return "shape=doubleoctagon";
70 else if(SVFUtil::isa<FIObjPN>(
this))
72 else if (SVFUtil::isa<DummyObjPN>(
this))
75 return "shape=component";
77 else if (SVFUtil::isa<RetPN>(
this))
79 return "shape=Mrecord";
81 else if (SVFUtil::isa<VarArgPN>(
this))
83 return "shape=octagon";
87 assert(0 &&
"no such kind!!");
93 outs() << this->toString() <<
"\n";
99 rawstr <<
"ValPN ID: " << getId();
110 rawstr <<
"ObjPN ID: " << getId();
121 rawstr <<
"GepValPN ID: " << getId() <<
" with offset_" + llvm::utostr(getOffset());
132 rawstr <<
"GepObjPN ID: " << getId() <<
" with offset_" + llvm::itostr(ls.getOffset());
143 rawstr <<
"FIObjPN ID: " << getId() <<
" (base object)";
154 rawstr <<
"RetPN ID: " << getId() <<
" unique return node for function " << SVFUtil::cast<Function>(value)->getName();
161 rawstr <<
"VarArgPN ID: " << getId() <<
" Var arg node for function " << SVFUtil::cast<Function>(value)->getName();
168 rawstr <<
"DummyValPN ID: " << getId();
175 rawstr <<
"DummyObjPN ID: " << getId();
182 rawstr <<
"CloneDummyObjPN ID: " << getId();
189 rawstr <<
"CloneGepObjPN ID: " << getId();
196 rawstr <<
"CloneFIObjPN ID: " << getId();
203 rawstr <<
"PAGEdge: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
210 rawstr <<
"AddrPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
221 rawstr <<
"CopyPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
232 rawstr <<
"CmpPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
243 rawstr <<
"BinaryOPPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
254 rawstr <<
"UnaryOPPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
265 rawstr <<
"LoadPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
276 rawstr <<
"StorePE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
287 rawstr <<
"GepPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
298 rawstr <<
"NormalGepPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
309 rawstr <<
"VariantGepPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
320 rawstr <<
"CallPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
331 rawstr <<
"RetPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
342 rawstr <<
"TDForkPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
353 rawstr <<
"TDJoinPE: [" << getDstID() <<
"<--" << getSrcID() <<
"]\t";
362 PAG::PAG(
bool buildFromFile) : fromFile(buildFromFile), nodeNumAfterPAGBuild(0), totalPTAPAGEdge(0)
378 return SVFUtil::cast<AddrPE>(edge);
382 addEdge(srcNode,dstNode, addrPE);
395 return SVFUtil::cast<CopyPE>(edge);
399 addEdge(srcNode,dstNode, copyPE);
412 return SVFUtil::cast<CmpPE>(edge);
430 return SVFUtil::cast<BinaryOPPE>(edge);
434 addEdge(srcNode,dstNode, binaryOP);
447 return SVFUtil::cast<UnaryOPPE>(edge);
451 addEdge(srcNode,dstNode, unaryOP);
464 return SVFUtil::cast<LoadPE>(edge);
468 addEdge(srcNode,dstNode, loadPE);
482 return SVFUtil::cast<StorePE>(edge);
486 addEdge(srcNode,dstNode, storePE);
499 return SVFUtil::cast<CallPE>(edge);
503 addEdge(srcNode,dstNode, callPE);
516 return SVFUtil::cast<RetPE>(edge);
519 RetPE* retPE =
new RetPE(srcNode, dstNode, cs);
520 addEdge(srcNode,dstNode, retPE);
544 return SVFUtil::cast<TDForkPE>(edge);
548 addEdge(srcNode,dstNode, forkPE);
561 return SVFUtil::cast<TDJoinPE>(edge);
565 addEdge(srcNode,dstNode, joinPE);
601 return SVFUtil::cast<NormalGepPE>(edge);
605 addEdge(baseNode, dstNode, gepPE);
620 return SVFUtil::cast<VariantGepPE>(edge);
624 addEdge(baseNode, dstNode, gepPE);
640 &&
"this node should not be created before");
652 if (
GepObjPN* gepNode = SVFUtil::dyn_cast<GepObjPN>(node))
653 return getGepObjNode(gepNode->getMemObj(), gepNode->getLocationSet() + ls);
654 else if (
FIObjPN* baseNode = SVFUtil::dyn_cast<FIObjPN>(node))
656 else if (
DummyObjPN* baseNode = SVFUtil::dyn_cast<DummyObjPN>(node))
660 assert(
false &&
"new gep obj node kind?");
684 NodeLocationSetMap::iterator iter =
GepObjNodeMap.find(std::make_pair(base, newLS));
700 &&
"this node should not be created before");
758 outs() <<
"add edge from " << src->
getId() <<
" kind :" 764 assert(added &&
"duplicated edge, not added!!!");
788 assert(SVFUtil::isa<ObjPN>(node) &&
"need an object node");
789 const ObjPN* obj = SVFUtil::cast<ObjPN>(node);
801 assert(SVFUtil::isa<ObjPN>(node) &&
"need an object node");
802 const MemObj* mem = SVFUtil::cast<ObjPN>(node)->getMemObj();
826 assert(((ngeps.size()+vgeps.size())==1) &&
"one node can only be connected by at most one gep edge!");
834 assert(SVFUtil::isa<GepPE>(*it) &&
"not a gep edge??");
835 return (*it)->getSrcID();
855 assert(geps.size()==1 &&
"one node can only be connected by at most one gep edge!");
858 assert(SVFUtil::isa<NormalGepPE>(edge) &&
"not a get edge??");
859 const NormalGepPE* gepEdge = SVFUtil::cast<NormalGepPE>(edge);
868 for (PAGEdge::PAGKindToEdgeSetMapTy::iterator I =
872 for (PAGEdge::PAGEdgeSetTy::iterator edgeIt = I->second.begin(),
873 endEdgeIt = I->second.end(); edgeIt != endEdgeIt; ++edgeIt)
888 outs() <<
"-------------------PAG------------------------------------\n";
890 for (PAGEdge::PAGEdgeSetTy::iterator iter = addrs.begin(), eiter =
891 addrs.end(); iter != eiter; ++iter)
893 outs() << (*iter)->getSrcID() <<
" -- Addr --> " << (*iter)->getDstID()
898 for (PAGEdge::PAGEdgeSetTy::iterator iter = copys.begin(), eiter =
899 copys.end(); iter != eiter; ++iter)
901 outs() << (*iter)->getSrcID() <<
" -- Copy --> " << (*iter)->getDstID()
906 for (PAGEdge::PAGEdgeSetTy::iterator iter = calls.begin(), eiter =
907 calls.end(); iter != eiter; ++iter)
909 outs() << (*iter)->getSrcID() <<
" -- Call --> " << (*iter)->getDstID()
914 for (PAGEdge::PAGEdgeSetTy::iterator iter = rets.begin(), eiter =
915 rets.end(); iter != eiter; ++iter)
917 outs() << (*iter)->getSrcID() <<
" -- Ret --> " << (*iter)->getDstID()
922 for (PAGEdge::PAGEdgeSetTy::iterator iter = tdfks.begin(), eiter =
923 tdfks.end(); iter != eiter; ++iter)
925 outs() << (*iter)->getSrcID() <<
" -- ThreadFork --> " 926 << (*iter)->getDstID() <<
"\n";
930 for (PAGEdge::PAGEdgeSetTy::iterator iter = tdjns.begin(), eiter =
931 tdjns.end(); iter != eiter; ++iter)
933 outs() << (*iter)->getSrcID() <<
" -- ThreadJoin --> " 934 << (*iter)->getDstID() <<
"\n";
938 for (PAGEdge::PAGEdgeSetTy::iterator iter = ngeps.begin(), eiter =
939 ngeps.end(); iter != eiter; ++iter)
941 NormalGepPE* gep = SVFUtil::cast<NormalGepPE>(*iter);
943 <<
") --> " << gep->
getDstID() <<
"\n";
947 for (PAGEdge::PAGEdgeSetTy::iterator iter = vgeps.begin(), eiter =
948 vgeps.end(); iter != eiter; ++iter)
950 outs() << (*iter)->getSrcID() <<
" -- VariantGep --> " 951 << (*iter)->getDstID() <<
"\n";
955 for (PAGEdge::PAGEdgeSetTy::iterator iter = loads.begin(), eiter =
956 loads.end(); iter != eiter; ++iter)
958 outs() << (*iter)->getSrcID() <<
" -- Load --> " << (*iter)->getDstID()
963 for (PAGEdge::PAGEdgeSetTy::iterator iter = stores.begin(), eiter =
964 stores.end(); iter != eiter; ++iter)
966 outs() << (*iter)->getSrcID() <<
" -- Store --> " << (*iter)->getDstID()
969 outs() <<
"----------------------------------------------------------\n";
1001 GenericPAGEdgeTy(s,d,k),value(nullptr),basicBlock(nullptr),icfgNode(nullptr)
1029 assert(val !=
nullptr &&
"value is nullptr for ValPN or GepValNode");
1037 assert(val !=
nullptr &&
"value is nullptr for RetNode");
1038 isTLPointer = SVFUtil::cast<Function>(val)->getReturnType()->isPointerTy();
1071 else if (
value && SVFUtil::isa<Function>(
value))
1091 llvm::ViewGraph(
this,
"ProgramAssignmentGraph");
1108 struct DOTGraphTraits<
PAG*> :
public DefaultDOTGraphTraits
1114 DefaultDOTGraphTraits(isSimple)
1126 #if LLVM_VERSION_MAJOR >= 12 1127 static bool isNodeHidden(
PAGNode *node,
PAG*) {
1142 rawstr <<
"[" << node->
getFunction()->getName() <<
"] ";
1146 return rawstr.str();
1155 template<
class EdgeIter>
1158 const PAGEdge* edge = *(EI.getCurrent());
1159 assert(edge &&
"No edge found!!");
1160 if (SVFUtil::isa<AddrPE>(edge))
1162 return "color=green";
1164 else if (SVFUtil::isa<CopyPE>(edge))
1166 return "color=black";
1168 else if (SVFUtil::isa<GepPE>(edge))
1170 return "color=purple";
1172 else if (SVFUtil::isa<StorePE>(edge))
1174 return "color=blue";
1176 else if (SVFUtil::isa<LoadPE>(edge))
1180 else if (SVFUtil::isa<CmpPE>(edge))
1182 return "color=grey";
1184 else if (SVFUtil::isa<BinaryOPPE>(edge))
1186 return "color=grey";
1188 else if (SVFUtil::isa<UnaryOPPE>(edge))
1190 return "color=grey";
1192 else if (SVFUtil::isa<TDForkPE>(edge))
1194 return "color=Turquoise";
1196 else if (SVFUtil::isa<TDJoinPE>(edge))
1198 return "color=Turquoise";
1200 else if (SVFUtil::isa<CallPE>(edge))
1202 return "color=black,style=dashed";
1204 else if (SVFUtil::isa<RetPE>(edge))
1206 return "color=black,style=dotted";
1209 assert(
false &&
"No such kind edge!!");
1213 template<
class EdgeIter>
1216 const PAGEdge* edge = *(EI.getCurrent());
1217 assert(edge &&
"No edge found!!");
1218 if(
const CallPE* calledge = SVFUtil::dyn_cast<CallPE>(edge))
1220 const Instruction* callInst= calledge->getCallSite()->getCallSite();
1223 else if(
const RetPE* retedge = SVFUtil::dyn_cast<RetPE>(edge))
1225 const Instruction* callInst= retedge->getCallSite()->getCallSite();
virtual const std::string toString() const
const LocationSet & getLocationSet() const
NodeID addValNode(const Value *val, NodeID i)
Add a value (pointer) node.
static PAG * pag
Singleton pattern here to enable instance of PAG can only be created once.
GEdgeKind getEdgeKind() const
u32_t getTotalEdgeNum() const
NodeID getValueNode(const Value *V)
Get PAG Node according to LLVM value.
virtual const std::string toString() const
bool isIsolatedNode() const
Whether this is an isoloated node on the PAG graph.
NodeID getBaseValNode(NodeID nodeId)
Base and Offset methods for Value and Object node.
static void handleBlackHole(bool b)
PAG build configurations.
virtual const std::string toString() const
virtual const std::string toString() const
NodeID addGepObjNode(const MemObj *obj, const LocationSet &ls)
Add a field obj node, this method can only invoked by getGepObjNode.
virtual LocationSet getModulusOffset(const MemObj *obj, const LocationSet &ls)
Given an offset from a Gep Instruction, return it modulus offset by considering memory layout...
virtual const std::string toString() const
const GEdgeSetTy & getInEdges() const
const MemObj * getMemObj() const
Return memory object.
CallPE * addCallPE(NodeID src, NodeID dst, const CallBlockNode *cs)
Add Call edge.
BinaryOPPE * addBinaryOPPE(NodeID src, NodeID dst)
Add Copy edge.
virtual const std::string toString() const
DOTGraphTraits(bool isSimple=false)
virtual const std::string toString() const
bool hasIncomingEdges(PAGEdge::PEDGEK kind) const
Has incoming PAG edges.
bool addEdge(PAGNode *src, PAGNode *dst, PAGEdge *edge)
Add an edge into PAG.
GenericNode< PAGNode, PAGEdge >::GEdgeSetTy PAGEdgeSetTy
void destroy()
Clean up memory.
NodeID getSrcID() const
get methods of the components
static Inst2LabelMap inst2LabelMap
Call site Instruction to label map.
virtual const std::string toString() const
virtual const std::string toString() const
PAGEdge::PAGEdgeSetTy & getIncomingEdges(PAGEdge::PEDGEK kind)
Get incoming PAG edges.
static std::string getEdgeSourceLabel(PAGNode *, EdgeIter EI)
LocationSet getLocationSetFromBaseNode(NodeID nodeId)
static std::string getNodeLabel(PAGNode *node, PAG *)
NodeID addObjNode(const Value *val, NodeID i)
Add a memory obj node.
bool isFieldInsensitive() const
Return true if its field limit is 0.
MemObjToFieldsMap memToFieldsMap
Map a mem object id to all its fields.
std::string getSourceLoc(const Value *val)
Return source code including line number and file name from debug information.
PAGEdge::PAGKindToEdgeSetMapTy PTAPAGEdgeKindToSetMap
void view()
View graph from the debugger.
const Value * getValue() const
Get/has methods of the components.
GNodeK getNodeKind() const
Get node kind.
const Value * value
value of this PAG node
bool isPTAEdge() const
Whether src and dst nodes are both of pointer type.
GEdgeSetTy::iterator iterator
virtual const std::string toString() const
NodeID getObjectNode(const Value *V)
virtual const std::string toString() const
NodeID allocateGepObjectId(NodeID base, u32_t offset, u32_t maxFieldLimit)
GepPE * addGepPE(NodeID src, NodeID dst, const LocationSet &ls, bool constGep)
Add Gep edge.
bool isIntrinsicFun(const Function *func)
NodeID getFIObjNode(const MemObj *obj) const
Get a field-insensitive obj PAG node according to a mem obj.
NodeBS & getAllFieldsObjNode(const MemObj *obj)
Get all fields of an object.
PAGEdge::PAGKindToEdgeSetMapTy PAGEdgeKindToSetMap
virtual const std::string toString() const
static PAG * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis. ...
virtual const Function * getFunction() const
Return the function that this PAGNode resides in. Return nullptr if it is a global or constantexpr no...
bool isATPointer
top-level pointer
PAGEdge * addBlackHoleAddrPE(NodeID node)
Set a pointer points-to black hole (e.g. int2ptr)
void build(SVFModule *svfModule)
NodeID addGepValNode(const Value *curInst, const Value *val, const LocationSet &ls, NodeID i, const Type *type, u32_t fieldidx)
Add a temp field value node, this method can only invoked by getGepValNode.
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
virtual const std::string toString() const
PAGEdge * hasLabeledEdge(PAGNode *src, PAGNode *dst, PAGEdge::PEDGEK kind, const ICFGNode *cs)
virtual const std::string toString() const
const Value * getRefVal() const
Get the reference value to this object.
NodeType * getDstNode() const
static const llvm::cl::opt< bool > PAGDotGraphShorter
NodeBS getFieldsAfterCollapse(NodeID id)
static void releaseSymbolInfo()
bool isConstantData() const
llvm::Instruction Instruction
NodeID getGepObjNode(const MemObj *obj, const LocationSet &ls)
Get a field PAG Object node according to base mem obj and offset.
AddrPE * addAddrPE(NodeID src, NodeID dst)
Add Address edge.
static u64_t callEdgeLabelCounter
Call site Instruction counter.
NodeID getBlackHoleNode() const
Get black hole and constant id.
const GEdgeSetTy & getOutEdges() const
llvm::raw_string_ostream raw_string_ostream
static bool isNodeHidden(PAGNode *node)
NodeID getNullPtr() const
CopyPE * addCopyPE(NodeID src, NodeID dst)
Add Copy edge.
NormalGepPE * addNormalGepPE(NodeID src, NodeID dst, const LocationSet &ls)
Add Offset(Gep) edge.
static u32_t getMaxFieldLimit()
Map< const ICFGNode *, u32_t > Inst2LabelMap
virtual const std::string toString() const
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis. ...
const std::string value2String(const Value *value)
NodeType * getSrcNode() const
VariantGepPE * addVariantGepPE(NodeID src, NodeID dst)
Add Variant(Gep) edge.
CmpPE * addCmpPE(NodeID src, NodeID dst)
Add Copy edge.
raw_ostream & outs()
Overwrite llvm::outs()
RetPE * addRetPE(NodeID src, NodeID dst, const CallBlockNode *cs)
Add Return edge.
PAGEdge::PAGEdgeSetTy & getEdgeSet(PAGEdge::PEDGEK kind)
Get/set methods to get control flow information of a PAGEdge.
virtual const std::string toString() const
virtual const std::string toString() const
std::string getGraphName() const
Return graph name.
SVFModule * getModule()
Get LLVM Module.
SymID getSymId() const
Get the memory object id.
static const llvm::cl::opt< bool > FirstFieldEqBase
void dump(std::string name)
Dump PAG.
bool isTopLevelPtr() const
Whether it is a top-level pointer.
bool ArgInNoCallerFunction(const Value *val)
Return true if the argument in a function does not have a caller.
GepValPNMap GepValNodeMap
Map a pair<base,off> to a gep value node id.
TDForkPE * addThreadForkPE(NodeID src, NodeID dst, const CallBlockNode *cs)
Add Thread fork edge for parameter passing.
Size_t getOffset() const
Get methods.
static llvm::cl::opt< bool > HandBlackHole
bool hasIncomingVariantGepEdge() const
Has incoming VariantGepEdges.
bool isValidPointer(NodeID nodeId) const
Whether a node is a valid pointer.
bool isValidTopLevelPtr(const PAGNode *node)
virtual const std::string toString() const
void addInEdge(PAGEdge *inEdge)
add methods of the components
static GEdgeFlag makeEdgeFlagWithCallInst(GEdgeKind k, const ICFGNode *cs)
Compute the unique edgeFlag value from edge kind and call site Instruction.
virtual const std::string toString() const
virtual const std::string toString() const
virtual const std::string toString() const
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID getId() const
Get ID.
StorePE * addStorePE(NodeID src, NodeID dst, const IntraBlockNode *val)
Add Store edge.
llvm::SparseBitVector NodeBS
static std::string getGraphName(PAG *graph)
Return name of the graph.
PAGNode(const Value *val, NodeID i, PNODEK k)
address-taken pointer
TDJoinPE * addThreadJoinPE(NodeID src, NodeID dst, const CallBlockNode *cs)
Add Thread join edge for parameter passing.
virtual const std::string toString() const
static std::string getNodeAttributes(PAGNode *node, PAG *)
virtual const std::string toString() const
PAGEdge(PAGNode *s, PAGNode *d, GEdgeFlag k)
Constructor.
virtual const std::string toString() const
static std::string getEdgeAttributes(PAGNode *, EdgeIter EI, PAG *)
virtual const std::string toString() const
virtual const std::string getNodeAttrForDotDisplay() const
Get shape and/or color of node for .dot display.
NodeType::iterator ChildIteratorType
const Value * value
LLVM value.
LoadPE * addLoadPE(NodeID src, NodeID dst)
Add Load edge.
NodeLocationSetMap GepObjNodeMap
Map a pair<base,off> to a gep obj node id.
NodeID addFIObjNode(const MemObj *obj)
Add a field-insensitive node, this method can only invoked by getFIGepObjNode.
u32_t getOffset() const
offset of the gep edge
virtual const std::string toString() const
PAG(bool buildFromFile)
all the callsites of a program
PAGEdge * hasNonlabeledEdge(PAGNode *src, PAGNode *dst, PAGEdge::PEDGEK kind)
static u64_t storeEdgeLabelCounter
Store Instruction counter.
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DEBUG model of each pass.
UnaryOPPE * addUnaryOPPE(NodeID src, NodeID dst)
Add Unary edge.
virtual const std::string toString() const
void dump() const
Dump to console for debugging.
virtual bool isPointer() const
Whether it is a pointer.
virtual const std::string toString() const
SymbolTableInfo * symInfo
void addOutEdge(PAGEdge *outEdge)
static void WriteGraphToFile(llvm::raw_ostream &O, const std::string &GraphName, const GraphType >, bool simple=false)