Static Value-Flow Analysis
Loading...
Searching...
No Matches
CallGraph.h
Go to the documentation of this file.
1//===- PTACallGraph.h -- Call graph representation----------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <Yulei Sui>
6//
7
8// This program is free software: you can redistribute it and/or modify
9// it under the terms of the GNU Affero General Public License as published by
10// the Free Software Foundation, either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17
18// You should have received a copy of the GNU Affero General Public License
19// along with this program. If not, see <http://www.gnu.org/licenses/>.
20//
21//===----------------------------------------------------------------------===//
22
23/*
24 * PTACallGraph.h
25 *
26 * Created on: Nov 7, 2013
27 * Author: Yulei Sui
28 */
29
30#ifndef PTACALLGRAPH_H_
31#define PTACALLGRAPH_H_
32
33#include "Graphs/GenericGraph.h"
34#include "SVFIR/SVFValue.h"
35#include "Graphs/ICFG.h"
36#include <set>
37
38namespace SVF
39{
40
41class CallGraphNode;
42class CallGraph;
43
44
45/*
46 * Call Graph edge representing a calling relation between two functions
47 * Multiple calls from function A to B are merged into one call edge
48 * Each call edge has a set of direct callsites and a set of indirect callsites
49 */
52{
53
54public:
60
61
62private:
66public:
74 {
75 }
78 {
79 return (cs << EdgeKindMaskBits) | k;
80 }
82
84 {
85 return csId;
86 }
87 inline bool isDirectCallEdge() const
88 {
89 return !directCalls.empty() && indirectCalls.empty();
90 }
91 inline bool isIndirectCallEdge() const
92 {
93 return directCalls.empty() && !indirectCalls.empty();
94 }
96 {
97 return directCalls;
98 }
100 {
101 return indirectCalls;
102 }
103 inline const CallInstSet& getDirectCalls() const
104 {
105 return directCalls;
106 }
107 inline const CallInstSet& getIndirectCalls() const
108 {
109 return indirectCalls;
110 }
112
114
115 void addDirectCallSite(const CallICFGNode* call);
116
117 void addInDirectCallSite(const CallICFGNode* call);
119
121
122 inline CallInstSet::const_iterator directCallsBegin() const
123 {
124 return directCalls.begin();
125 }
126 inline CallInstSet::const_iterator directCallsEnd() const
127 {
128 return directCalls.end();
129 }
130
131 inline CallInstSet::const_iterator indirectCallsBegin() const
132 {
133 return indirectCalls.begin();
134 }
135 inline CallInstSet::const_iterator indirectCallsEnd() const
136 {
137 return indirectCalls.end();
138 }
140
142
143 static inline bool classof(const CallGraphEdge*)
144 {
145 return true;
146 }
147 static inline bool classof(const GenericPTACallGraphEdgeTy *edge)
148 {
149 return edge->getEdgeKind() == CallGraphEdge::CallRetEdge ||
150 edge->getEdgeKind() == CallGraphEdge::TDForkEdge ||
151 edge->getEdgeKind() == CallGraphEdge::TDJoinEdge;
152 }
154
156
158 {
159 o << edge.toString();
160 return o;
161 }
163
164 virtual const std::string toString() const;
165
167
168};
169
170class FunObjVar;
171
172/*
173 * Call Graph node representing a function
174 */
177{
178private:
180
181public:
187
188 const std::string &getName() const;
189
191 inline const FunObjVar* getFunction() const
192 {
193 return fun;
194 }
195
198
199
201
203 {
204 o << node.toString();
205 return o;
206 }
208
209 virtual const std::string toString() const;
210
212
213 static inline bool classof(const CallGraphNode*)
214 {
215 return true;
216 }
217
218 static inline bool classof(const GenericICFGNodeTy* node)
219 {
220 return node->getNodeKind() == CallNodeKd;
221 }
222
223 static inline bool classof(const SVFValue* node)
224 {
225 return node->getNodeKind() == CallNodeKd;
226 }
227
229};
230
236{
237 friend class GraphDBClient;
238
239
240public:
244 typedef std::pair<const CallICFGNode*, const FunObjVar*> CallSitePair;
249 typedef CallGraphEdgeSet::iterator CallGraphEdgeIter;
250 typedef CallGraphEdgeSet::const_iterator CallGraphEdgeConstIter;
251
256
257private:
260
265
266protected:
269
273
275 void destroy();
276
277protected:
280 {
281 std::pair<const CallICFGNode*, const FunObjVar*> newCS(std::make_pair(cs, callee));
282 CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS);
283 //assert(it == csToIdMap.end() && "cannot add a callsite twice");
284 if(it == csToIdMap.end())
285 {
287 addCallSite(cs,callee,id, newCS);
288 return id;
289 }
290 return it->second;
291 }
292
293 CallSiteID addCallSite(const CallICFGNode* cs, const FunObjVar* callee, const CallSiteID csid, std::pair<const CallICFGNode*, const FunObjVar*> newCS);
294
297 {
298 edge->getDstNode()->addIncomingEdge(edge);
299 edge->getSrcNode()->addOutgoingEdge(edge);
300 }
301
304
306 void addCallGraphNode(CallGraphNode* cgNode);
307
310public:
313
315 CallGraph(const CallGraph& other);
316
318 virtual ~CallGraph()
319 {
320 destroy();
321 }
322
324 inline CGEK getKind() const
325 {
326 return kind;
327 }
328
330
332 {
333 return indirectCallMap;
334 }
335 inline bool hasIndCSCallees(const CallICFGNode* cs) const
336 {
337 return (indirectCallMap.find(cs) != indirectCallMap.end());
338 }
339 inline const FunctionSet& getIndCSCallees(const CallICFGNode* cs) const
340 {
341 CallEdgeMap::const_iterator it = indirectCallMap.find(cs);
342 assert(it!=indirectCallMap.end() && "not an indirect callsite!");
343 return it->second;
344 }
347 {
348 return totalCallSiteNum;
349 }
350
352 {
354 }
355
360
362 void verifyCallGraph();
363
366
367 void addCallGraphNode(const FunObjVar* fun);
368
370
371
372 const CallGraphNode* getCallGraphNode(const std::string& name) const;
373
375 {
376 return getGNode(id);
377 }
378 inline CallGraphNode* getCallGraphNode(const FunObjVar* fun) const
379 {
380 FunToCallGraphNodeMap::const_iterator it = funToCallGraphNodeMap.find(fun);
381 assert(it!=funToCallGraphNodeMap.end() && "call graph node not found!!");
382 return it->second;
383 }
384
386
388
389 inline CallSiteID getCallSiteID(const CallICFGNode* cs, const FunObjVar* callee) const
390 {
391 CallSitePair newCS(std::make_pair(cs, callee));
392 CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS);
393 assert(it != csToIdMap.end() && "callsite id not found! This maybe a partially resolved callgraph, please check the indCallEdge limit");
394 return it->second;
395 }
396 inline bool hasCallSiteID(const CallICFGNode* cs, const FunObjVar* callee) const
397 {
398 CallSitePair newCS(std::make_pair(cs, callee));
399 CallSiteToIdMap::const_iterator it = csToIdMap.find(newCS);
400 return it != csToIdMap.end();
401 }
403 {
404 IdToCallSiteMap::const_iterator it = idToCSMap.find(id);
405 assert(it != idToCSMap.end() && "cannot find call site for this CallSiteID");
406 return (it->second);
407 }
408 inline const CallICFGNode* getCallSite(CallSiteID id) const
409 {
410 return getCallSitePair(id).first;
411 }
414 {
415 return getCallSitePair(id).second;
416 }
418
424
427 {
428 if(hasCallGraphEdge(cs))
429 {
430 for (CallGraphEdgeSet::const_iterator it = getCallEdgeBegin(cs), eit =
431 getCallEdgeEnd(cs); it != eit; ++it)
432 {
433 callees.insert((*it)->getDstNode()->getFunction());
434 }
435 }
436 }
437
439
440
441 inline bool hasCallGraphEdge(const CallICFGNode* inst) const
442 {
444 }
445 inline CallGraphEdgeSet::const_iterator getCallEdgeBegin(const CallICFGNode* inst) const
446 {
447 CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst);
449 && "call instruction does not have a valid callee");
450 return it->second.begin();
451 }
452 inline CallGraphEdgeSet::const_iterator getCallEdgeEnd(const CallICFGNode* inst) const
453 {
454 CallInstToCallGraphEdgesMap::const_iterator it = callinstToCallGraphEdgesMap.find(inst);
456 && "call instruction does not have a valid callee");
457 return it->second.end();
458 }
460
461
463
466
468
473
475 bool isReachableBetweenFunctions(const FunObjVar* srcFn, const FunObjVar* dstFn) const;
476
478 void dump(const std::string& filename);
479
481 void view();
482};
483
484} // End namespace SVF
485
486namespace SVF
487{
488/* !
489 * GenericGraphTraits specializations for generic graph algorithms.
490 * Provide graph traits for traversing from a constraint node using standard graph traversals.
491 */
492template<> struct GenericGraphTraits<SVF::CallGraphNode*> : public GenericGraphTraits<SVF::GenericNode<SVF::CallGraphNode,SVF::CallGraphEdge>* >
493{
494};
495
497template<>
498struct GenericGraphTraits<Inverse<SVF::CallGraphNode*> > : public GenericGraphTraits<Inverse<SVF::GenericNode<SVF::CallGraphNode,SVF::CallGraphEdge>* > >
499{
500};
501
502template<> struct GenericGraphTraits<SVF::CallGraph*> : public GenericGraphTraits<SVF::GenericGraph<SVF::CallGraphNode,SVF::CallGraphEdge>* >
503{
505};
506
507} // End namespace llvm
508
509#endif /* PTACALLGRAPH_H_ */
const char *const name
Definition cJSON.h:264
static bool classof(const CallGraphEdge *)
ClassOf.
Definition CallGraph.h:143
void addInDirectCallSite(const CallICFGNode *call)
Definition CallGraph.cpp:60
void addDirectCallSite(const CallICFGNode *call)
Add direct and indirect callsite.
Definition CallGraph.cpp:54
CallSiteID csId
Definition CallGraph.h:65
CallInstSet::const_iterator indirectCallsBegin() const
Definition CallGraph.h:131
CallInstSet & getIndirectCalls()
Definition CallGraph.h:99
virtual ~CallGraphEdge()
Destructor.
Definition CallGraph.h:73
CallInstSet indirectCalls
Definition CallGraph.h:64
GenericNode< CallGraphNode, CallGraphEdge >::GEdgeSetTy CallGraphEdgeSet
Definition CallGraph.h:166
bool isIndirectCallEdge() const
Definition CallGraph.h:91
CallInstSet & getDirectCalls()
Definition CallGraph.h:95
CallGraphEdge(CallGraphNode *s, CallGraphNode *d, CEDGEK kind, CallSiteID cs)
Constructor.
Definition CallGraph.h:68
static GEdgeFlag makeEdgeFlagWithInvokeID(GEdgeKind k, CallSiteID cs)
Compute the unique edgeFlag value from edge kind and CallSiteID.
Definition CallGraph.h:77
virtual const std::string toString() const
Definition CallGraph.cpp:68
CallInstSet::const_iterator directCallsEnd() const
Definition CallGraph.h:126
const CallInstSet & getIndirectCalls() const
Definition CallGraph.h:107
bool isDirectCallEdge() const
Definition CallGraph.h:87
const CallInstSet & getDirectCalls() const
Definition CallGraph.h:103
static bool classof(const GenericPTACallGraphEdgeTy *edge)
Definition CallGraph.h:147
CallInstSet::const_iterator indirectCallsEnd() const
Definition CallGraph.h:135
friend OutStream & operator<<(OutStream &o, const CallGraphEdge &edge)
Overloading operator << for dumping ICFG node ID.
Definition CallGraph.h:157
Set< const CallICFGNode * > CallInstSet
Definition CallGraph.h:55
CallInstSet directCalls
Definition CallGraph.h:63
CallInstSet::const_iterator directCallsBegin() const
Iterators for direct and indirect callsites.
Definition CallGraph.h:122
CallSiteID getCallSiteID() const
Get direct and indirect calls.
Definition CallGraph.h:83
CallGraphNode(NodeID i, const FunObjVar *f)
Constructor.
Definition CallGraph.h:183
static bool classof(const GenericICFGNodeTy *node)
Definition CallGraph.h:218
const FunObjVar * getFunction() const
Get function of this call node.
Definition CallGraph.h:191
const std::string & getName() const
Definition CallGraph.cpp:46
static bool classof(const SVFValue *node)
Definition CallGraph.h:223
virtual const std::string toString() const
Definition CallGraph.cpp:81
bool isReachableFromProgEntry(Map< NodeID, bool > &reachableFromEntry, NodeBS &visitedNodes) const
Return TRUE if this function can be reached from main.
Definition CallGraph.cpp:94
const FunObjVar * fun
Definition CallGraph.h:179
friend OutStream & operator<<(OutStream &o, const CallGraphNode &node)
Overloading operator << for dumping ICFG node ID.
Definition CallGraph.h:202
static bool classof(const CallGraphNode *)
Methods for support type inquiry through isa, cast, and dyn_cast:
Definition CallGraph.h:213
CallGraphNode * getCallGraphNode(const FunObjVar *fun) const
Definition CallGraph.h:378
CallInstToCallGraphEdgesMap callinstToCallGraphEdgesMap
Map a call instruction to its corresponding call edges.
Definition CallGraph.h:268
void getAllCallSitesInvokingCallee(const FunObjVar *callee, CallGraphEdge::CallInstSet &csSet)
Get callsites invoking the callee.
Map< const CallICFGNode *, CallGraphEdgeSet > CallInstToCallGraphEdgesMap
Definition CallGraph.h:243
CGEK getKind() const
Return type of this callgraph.
Definition CallGraph.h:324
void addIndirectCallGraphEdge(const CallICFGNode *cs, const FunObjVar *callerFun, const FunObjVar *calleeFun)
Add indirect call edges.
CallGraphEdge * hasGraphEdge(CallGraphEdge *cgEdge) const
Whether we have already created this call graph edge.
CallEdgeMap indirectCallMap
Indirect call map.
Definition CallGraph.h:259
void addCallGraphNode(CallGraphNode *cgNode)
add call graph node from database [only used this function when loading cgNodes from db results]
bool hasIndCSCallees(const CallICFGNode *cs) const
Definition CallGraph.h:335
CallGraphEdgeSet::iterator CallGraphEdgeIter
Definition CallGraph.h:249
void addEdge(CallGraphEdge *edge)
Add call graph edge.
Definition CallGraph.h:296
const FunObjVar * getCallerOfCallSite(CallSiteID id) const
Definition CallGraph.cpp:89
u32_t getNumOfResolvedIndCallEdge() const
Definition CallGraph.h:351
void getIndCallSitesInvokingCallee(const FunObjVar *callee, CallGraphEdge::CallInstSet &csSet)
static IdToCallSiteMap idToCSMap
Map a callsite ID to a pair of call instruction and callee.
Definition CallGraph.h:263
static CallSiteID totalCallSiteNum
CallSiteIDs, start from 1;.
Definition CallGraph.h:264
Map< CallSiteID, CallSitePair > IdToCallSiteMap
Definition CallGraph.h:246
NodeID callGraphNodeNum
Definition CallGraph.h:270
const CallInstToCallGraphEdgesMap & getCallInstToCallGraphEdgesMap() const
Definition CallGraph.h:356
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
Map< const FunObjVar *, CallGraphNode * > FunToCallGraphNodeMap
Definition CallGraph.h:242
void destroy()
Clean up memory.
CallSiteID addCallSite(const CallICFGNode *cs, const FunObjVar *callee)
Add CallSiteID.
Definition CallGraph.h:279
FunToCallGraphNodeMap funToCallGraphNodeMap
Call Graph node map.
Definition CallGraph.h:267
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
Definition CallGraph.h:248
CallGraphEdgeSet::const_iterator CallGraphEdgeConstIter
Definition CallGraph.h:250
CallGraphEdge::CallGraphEdgeSet CallGraphEdgeSet
Definition CallGraph.h:241
CallGraphEdgeSet::const_iterator getCallEdgeBegin(const CallICFGNode *inst) const
Definition CallGraph.h:445
CallGraphNode * getCallGraphNode(NodeID id) const
Definition CallGraph.h:374
static CallSiteToIdMap csToIdMap
Call site information.
Definition CallGraph.h:262
const CallICFGNode * getCallSite(CallSiteID id) const
Definition CallGraph.h:408
bool isReachableBetweenFunctions(const FunObjVar *srcFn, const FunObjVar *dstFn) const
Whether its reachable between two functions.
const FunctionSet & getIndCSCallees(const CallICFGNode *cs) const
Definition CallGraph.h:339
void view()
View the graph from the debugger.
void dump(const std::string &filename)
Dump the graph.
void getDirCallSitesInvokingCallee(const FunObjVar *callee, CallGraphEdge::CallInstSet &csSet)
u32_t getTotalCallSiteNumber() const
Definition CallGraph.h:346
void verifyCallGraph()
Issue a warning if the function which has indirect call sites can not be reached from program entry.
friend class GraphDBClient
Definition CallGraph.h:237
u32_t numOfResolvedIndCallEdge
Definition CallGraph.h:271
std::pair< const CallICFGNode *, const FunObjVar * > CallSitePair
Definition CallGraph.h:244
CallGraphEdge * getGraphEdge(CallGraphNode *src, CallGraphNode *dst, CallGraphEdge::CEDGEK kind, CallSiteID csId)
Get call graph edge via nodes.
bool hasCallGraphEdge(const CallICFGNode *inst) const
Get call graph edge via call instruction.
Definition CallGraph.h:441
void getCallees(const CallICFGNode *cs, FunctionSet &callees)
Get all callees for a callsite.
Definition CallGraph.h:426
const FunObjVar * getCalleeOfCallSite(CallSiteID id) const
Definition CallGraph.h:413
bool hasCallSiteID(const CallICFGNode *cs, const FunObjVar *callee) const
Definition CallGraph.h:396
virtual ~CallGraph()
Destructor.
Definition CallGraph.h:318
const CallSitePair & getCallSitePair(CallSiteID id) const
Definition CallGraph.h:402
CallSiteID getCallSiteID(const CallICFGNode *cs, const FunObjVar *callee) const
Get CallSiteID.
Definition CallGraph.h:389
Map< CallSitePair, CallSiteID > CallSiteToIdMap
Definition CallGraph.h:245
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Definition CallGraph.h:331
void addDirectCallGraphEdge(CallGraphEdge *cgEdge)
add direct call graph edge from database [only used this function when loading cgEdges from db result...
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:247
CallGraphEdgeSet::const_iterator getCallEdgeEnd(const CallICFGNode *inst) const
Definition CallGraph.h:452
static constexpr unsigned char EdgeKindMaskBits
We use the lower 8 bits to denote edge kind.
NodeType * getGNode(NodeID id) const
Get a node.
OrderedSet< EdgeType *, typename EdgeType::equalGEdge > GEdgeSetTy
Edge kind.
GNodeK getNodeKind() const
Get node kind.
Definition SVFValue.h:166
for isBitcode
Definition BasicTypes.h:68
unsigned CallSiteID
Definition GeneralType.h:58
u32_t NodeID
Definition GeneralType.h:56
GenericEdge< CallGraphNode > GenericPTACallGraphEdgeTy
Definition CallGraph.h:50
GenericNode< CallGraphNode, CallGraphEdge > GenericPTACallGraphNodeTy
Definition CallGraph.h:175
std::ostream OutStream
Definition GeneralType.h:46
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
GenericGraph< CallGraphNode, CallGraphEdge > GenericPTACallGraphTy
Definition CallGraph.h:234
unsigned u32_t
Definition GeneralType.h:47