Static Value-Flow Analysis
Loading...
Searching...
No Matches
DDAClient.cpp
Go to the documentation of this file.
1//===- DDAClient.cpp -- Clients of demand-driven analysis-------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-> <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 * @file: DDAClient.cpp
25 * @author: yesen
26 * @date: 16 Feb 2015
27 *
28 * LICENSE
29 *
30 */
31
32
33#include "Util/Options.h"
34#include "Util/SVFUtil.h"
36
37#include "DDA/DDAClient.h"
38#include "DDA/FlowDDA.h"
39#include <iostream>
40#include <iomanip> // for std::setw
41
42using namespace SVF;
43using namespace SVFUtil;
44
45
47{
48
49 DDAStat* stat = static_cast<DDAStat*>(pta->getStat());
50 u32_t vmrss = 0;
51 u32_t vmsize = 0;
54
56
57 u32_t count = 0;
58 for (OrderedNodeSet::iterator nIter = candidateQueries.begin();
59 nIter != candidateQueries.end(); ++nIter,++count)
60 {
61 PAGNode* node = pta->getPAG()->getGNode(*nIter);
62 if(pta->getPAG()->isValidTopLevelPtr(node))
63 {
64 DBOUT(DGENERAL,outs() << "\n@@Computing PointsTo for :" << node->getId() <<
65 " [" << count + 1<< "/" << candidateQueries.size() << "]" << " \n");
66 DBOUT(DDDA,outs() << "\n@@Computing PointsTo for :" << node->getId() <<
67 " [" << count + 1<< "/" << candidateQueries.size() << "]" << " \n");
69 pta->computeDDAPts(node->getId());
70 }
71 }
72
73 vmrss = vmsize = 0;
76}
77
79{
80 setPAG(p);
81 for(SVFIR::CallSiteToFunPtrMap::const_iterator it = pag->getIndirectCallsites().begin(),
82 eit = pag->getIndirectCallsites().end(); it!=eit; ++it)
83 {
84 if (it->first->isVirtualCall())
85 {
86 const SVFVar* vtblPtr = it->first->getVtablePtr();
87 assert(vtblPtr != nullptr && "not a vtable pointer?");
88 NodeID vtblId = vtblPtr->getId();
91 }
92 else
93 {
94 addCandidate(it->second);
95 }
96 }
97 return candidateQueries;
98}
99
101{
102
110
111 for (VTablePtrToCallSiteMap::iterator nIter = vtableToCallSiteMap.begin();
112 nIter != vtableToCallSiteMap.end(); ++nIter)
113 {
114 NodeID vtptr = nIter->first;
115 const PointsTo& ddaPts = pta->getPts(vtptr);
116 const PointsTo& anderPts = ander->getPts(vtptr);
117
118 PTACallGraph* callgraph = ander->getCallGraph();
119 const CallICFGNode* cbn = nIter->second;
120
121 if(!callgraph->hasIndCSCallees(cbn))
122 {
123 //outs() << "virtual callsite has no callee" << *(nIter->second.getInstruction()) << "\n";
124 continue;
125 }
126
129 if(callees.size() == 0)
131 else if(callees.size() == 1)
133 else if(callees.size() == 2)
135 else
137
138 if(ddaPts.count() >= anderPts.count() || ddaPts.empty())
139 continue;
140
145
147 outs() << "============more precise callsite =================\n";
148 outs() << (nIter->second)->toString() << "\n";
149 outs() << (nIter->second)->getSourceLoc() << "\n";
150 outs() << "\n";
151 outs() << "------ander pts or vtable num---(" << anderPts.count() << ")--\n";
152 outs() << "------DDA vfn num---(" << ander_vfns.size() << ")--\n";
153 //ander->dumpPts(vtptr, anderPts);
154 outs() << "------DDA pts or vtable num---(" << ddaPts.count() << ")--\n";
155 outs() << "------DDA vfn num---(" << dda_vfns.size() << ")--\n";
156 //pta->dumpPts(vtptr, ddaPts);
157 outs() << "-------------------------\n";
158 outs() << "\n";
159 outs() << "=================================================\n";
160 }
161
162 outs() << "=================================================\n";
163 outs() << "Total virtual callsites: " << vtableToCallSiteMap.size() << "\n";
164 outs() << "Total analyzed virtual callsites: " << totalCallsites << "\n";
165 outs() << "Indirect call map size: " << ander->getCallGraph()->getIndCallMap().size() << "\n";
166 outs() << "Precise callsites: " << morePreciseCallsites << "\n";
167 outs() << "Zero target callsites: " << zeroTargetCallsites << "\n";
168 outs() << "One target callsites: " << oneTargetCallsites << "\n";
169 outs() << "Two target callsites: " << twoTargetCallsites << "\n";
170 outs() << "More than two target callsites: " << moreThanTwoCallsites << "\n";
171 outs() << "=================================================\n";
172}
173
174
177{
178 setPAG(pag);
180 for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
181 loads.end(); iter != eiter; ++iter)
182 {
183 PAGNode* loadsrc = (*iter)->getSrcNode();
184 loadSrcNodes.insert(loadsrc);
185 addCandidate(loadsrc->getId());
186 }
187
189 for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
190 stores.end(); iter != eiter; ++iter)
191 {
192 PAGNode* storedst = (*iter)->getDstNode();
193 storeDstNodes.insert(storedst);
194 addCandidate(storedst->getId());
195 }
197 for (SVFStmt::SVFStmtSetTy::iterator iter = geps.begin(), eiter =
198 geps.end(); iter != eiter; ++iter)
199 {
200 PAGNode* gepsrc = (*iter)->getSrcNode();
201 gepSrcNodes.insert(gepsrc);
202 addCandidate(gepsrc->getId());
203 }
204 return candidateQueries;
205}
206
208{
209
210 for(PAGNodeSet::const_iterator lit = loadSrcNodes.begin(); lit!=loadSrcNodes.end(); lit++)
211 {
212 for(PAGNodeSet::const_iterator sit = storeDstNodes.begin(); sit!=storeDstNodes.end(); sit++)
213 {
214 const PAGNode* node1 = *lit;
215 const PAGNode* node2 = *sit;
216 if(node1->hasValue() && node2->hasValue())
217 {
218 AliasResult result = pta->alias(node1->getId(),node2->getId());
219
220 outs() << "\n=================================================\n";
221 outs() << "Alias Query for (" << node1->getValue()->toString() << ",";
222 outs() << node2->getValue()->toString() << ") \n";
223 outs() << "[NodeID:" << node1->getId() << ", NodeID:" << node2->getId() << " " << result << "]\n";
224 outs() << "=================================================\n";
225
226 }
227 }
228 }
229}
230
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define DGENERAL
Definition SVFType.h:490
#define DDDA
Definition SVFType.h:496
cJSON * p
Definition cJSON.cpp:2559
int count
Definition cJSON.h:216
virtual OrderedNodeSet & collectCandidateQueries(SVFIR *pag)
Only collect function pointers as query candidates.
PAGNodeSet loadSrcNodes
Definition DDAClient.h:161
virtual void performStat(PointerAnalysis *pta)
PAGNodeSet storeDstNodes
Definition DDAClient.h:162
PAGNodeSet gepSrcNodes
Definition DDAClient.h:163
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition Andersen.h:408
virtual const PointsTo & getPts(NodeID id)
Operation of points-to set.
Definition Andersen.h:239
void setPAG(SVFIR *g)
Set SVFIR graph.
Definition DDAClient.h:79
virtual void answerQueries(PointerAnalysis *pta)
Definition DDAClient.cpp:46
void setCurrentQueryPtr(NodeID ptr)
Set the pointer being queried.
Definition DDAClient.h:84
SVFIR * pag
SVFIR graph used by current DDA analysis.
Definition DDAClient.h:111
void addCandidate(NodeID id)
Definition DDAClient.h:105
OrderedNodeSet candidateQueries
store all candidate pointers to be queried
Definition DDAClient.h:114
virtual OrderedNodeSet & collectCandidateQueries(SVFIR *p)
Collect candidate pointers for query.
Definition DDAClient.h:58
VTablePtrToCallSiteMap vtableToCallSiteMap
Definition DDAClient.h:129
virtual OrderedNodeSet & collectCandidateQueries(SVFIR *p)
Only collect function pointers as query candidates.
Definition DDAClient.cpp:78
virtual void performStat(PointerAnalysis *pta)
NodeType * getGNode(NodeID id) const
Get a node.
const FunctionSet & getIndCSCallees(const CallICFGNode *cs) const
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Set< const SVFFunction * > FunctionSet
bool hasIndCSCallees(const CallICFGNode *cs) const
void setMemUsageBefore(u32_t vmrss, u32_t vmsize)
Definition PTAStat.h:56
void setMemUsageAfter(u32_t vmrss, u32_t vmsize)
Definition PTAStat.h:62
void getVFnsFromPts(const CallICFGNode *cs, const PointsTo &target, VFunSet &vfns)
virtual const PointsTo & getPts(NodeID ptr)=0
Get points-to targets of a pointer. It needs to be implemented in child class.
virtual void computeDDAPts(NodeID)
Compute points-to results on-demand, overridden by derived classes.
SVFIR * getPAG() const
PTACallGraph * getCallGraph() const
Return call graph.
PTAStat * getStat() const
Get PTA stat.
virtual AliasResult alias(const SVFValue *V1, const SVFValue *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
NodeID getId() const
Get ID.
SVFStmt::SVFStmtSetTy & getSVFStmtSet(SVFStmt::PEDGEK kind)
Get/set methods to get SVFStmts based on their kinds and ICFGNodes.
Definition SVFIR.h:202
bool isValidTopLevelPtr(const SVFVar *node)
Definition SVFIR.cpp:685
const CallSiteToFunPtrMap & getIndirectCallsites() const
Add/get indirect callsites.
Definition SVFIR.h:351
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
bool getMemoryUsageKB(u32_t *vmrss_kb, u32_t *vmsize_kb)
Get memory usage from system file. Return TRUE if succeed.
Definition SVFUtil.cpp:178
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
for isBitcode
Definition BasicTypes.h:68
OrderedSet< NodeID > OrderedNodeSet
u32_t NodeID
Definition GeneralType.h:55
AliasResult
Definition SVFType.h:527
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned u32_t
Definition GeneralType.h:46