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 // We tell the compiler count is used as DBOUT ignores the statement on some builds.
58 u32_t count = 0;
59 (void)count;
60 for (OrderedNodeSet::iterator nIter = candidateQueries.begin();
61 nIter != candidateQueries.end(); ++nIter,++count)
62 {
63 const SVFVar* node = pta->getPAG()->getSVFVar(*nIter);
64 if(pta->getPAG()->isValidTopLevelPtr(node))
65 {
66 DBOUT(DGENERAL,outs() << "\n@@Computing PointsTo for :" << node->getId() <<
67 " [" << count + 1<< "/" << candidateQueries.size() << "]" << " \n");
68 DBOUT(DDDA,outs() << "\n@@Computing PointsTo for :" << node->getId() <<
69 " [" << count + 1<< "/" << candidateQueries.size() << "]" << " \n");
71 pta->computeDDAPts(node->getId());
72 }
73 }
74
75 vmrss = vmsize = 0;
78}
79
81{
82 setPAG(p);
83 for(SVFIR::CallSiteToFunPtrMap::const_iterator it = pag->getIndirectCallsites().begin(),
84 eit = pag->getIndirectCallsites().end(); it!=eit; ++it)
85 {
86 if (it->first->isVirtualCall())
87 {
88 const SVFVar* vtblPtr = it->first->getVtablePtr();
89 assert(vtblPtr != nullptr && "not a vtable pointer?");
90 NodeID vtblId = vtblPtr->getId();
93 }
94 else
95 {
96 addCandidate(it->second);
97 }
98 }
99 return candidateQueries;
100}
101
103{
104
112
113 for (VTablePtrToCallSiteMap::iterator nIter = vtableToCallSiteMap.begin();
114 nIter != vtableToCallSiteMap.end(); ++nIter)
115 {
116 NodeID vtptr = nIter->first;
117 const PointsTo& ddaPts = pta->getPts(vtptr);
118 const PointsTo& anderPts = ander->getPts(vtptr);
119
120 CallGraph* callgraph = ander->getCallGraph();
121 const CallICFGNode* cbn = nIter->second;
122
123 if(!callgraph->hasIndCSCallees(cbn))
124 {
125 //outs() << "virtual callsite has no callee" << *(nIter->second.getInstruction()) << "\n";
126 continue;
127 }
128
131 if(callees.size() == 0)
133 else if(callees.size() == 1)
135 else if(callees.size() == 2)
137 else
139
140 if(ddaPts.count() >= anderPts.count() || ddaPts.empty())
141 continue;
142
147
149 outs() << "============more precise callsite =================\n";
150 outs() << (nIter->second)->toString() << "\n";
151 outs() << (nIter->second)->getSourceLoc() << "\n";
152 outs() << "\n";
153 outs() << "------ander pts or vtable num---(" << anderPts.count() << ")--\n";
154 outs() << "------DDA vfn num---(" << ander_vfns.size() << ")--\n";
155 //ander->dumpPts(vtptr, anderPts);
156 outs() << "------DDA pts or vtable num---(" << ddaPts.count() << ")--\n";
157 outs() << "------DDA vfn num---(" << dda_vfns.size() << ")--\n";
158 //pta->dumpPts(vtptr, ddaPts);
159 outs() << "-------------------------\n";
160 outs() << "\n";
161 outs() << "=================================================\n";
162 }
163
164 outs() << "=================================================\n";
165 outs() << "Total virtual callsites: " << vtableToCallSiteMap.size() << "\n";
166 outs() << "Total analyzed virtual callsites: " << totalCallsites << "\n";
167 outs() << "Indirect call map size: " << ander->getCallGraph()->getIndCallMap().size() << "\n";
168 outs() << "Precise callsites: " << morePreciseCallsites << "\n";
169 outs() << "Zero target callsites: " << zeroTargetCallsites << "\n";
170 outs() << "One target callsites: " << oneTargetCallsites << "\n";
171 outs() << "Two target callsites: " << twoTargetCallsites << "\n";
172 outs() << "More than two target callsites: " << moreThanTwoCallsites << "\n";
173 outs() << "=================================================\n";
174}
175
176
179{
180 setPAG(pag);
182 for (SVFStmt::SVFStmtSetTy::iterator iter = loads.begin(), eiter =
183 loads.end(); iter != eiter; ++iter)
184 {
185 PAGNode* loadsrc = (*iter)->getSrcNode();
186 loadSrcNodes.insert(loadsrc);
187 addCandidate(loadsrc->getId());
188 }
189
191 for (SVFStmt::SVFStmtSetTy::iterator iter = stores.begin(), eiter =
192 stores.end(); iter != eiter; ++iter)
193 {
194 PAGNode* storedst = (*iter)->getDstNode();
195 storeDstNodes.insert(storedst);
196 addCandidate(storedst->getId());
197 }
199 for (SVFStmt::SVFStmtSetTy::iterator iter = geps.begin(), eiter =
200 geps.end(); iter != eiter; ++iter)
201 {
202 PAGNode* gepsrc = (*iter)->getSrcNode();
203 gepSrcNodes.insert(gepsrc);
204 addCandidate(gepsrc->getId());
205 }
206 return candidateQueries;
207}
208
210{
211
212 for(PAGNodeSet::const_iterator lit = loadSrcNodes.begin(); lit!=loadSrcNodes.end(); lit++)
213 {
214 for(PAGNodeSet::const_iterator sit = storeDstNodes.begin(); sit!=storeDstNodes.end(); sit++)
215 {
216 const PAGNode* node1 = *lit;
217 const PAGNode* node2 = *sit;
218 AliasResult result = pta->alias(node1->getId(), node2->getId());
219 outs() << "\n=================================================\n";
220 outs() << "Alias Query for (" << node1->valueOnlyToString() << ",";
221 outs() << node2->valueOnlyToString() << ") \n";
222 outs() << "[NodeID:" << node1->getId() << ", NodeID:" << node2->getId() << " " << result << "]\n";
223 outs() << "=================================================\n";
224 }
225 }
226}
227
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:593
#define DGENERAL
Definition SVFType.h:599
#define DDDA
Definition SVFType.h:605
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:156
virtual void performStat(PointerAnalysis *pta)
PAGNodeSet storeDstNodes
Definition DDAClient.h:157
PAGNodeSet gepSrcNodes
Definition DDAClient.h:158
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition Andersen.h:407
virtual const PointsTo & getPts(NodeID id)
Operation of points-to set.
Definition Andersen.h:238
bool hasIndCSCallees(const CallICFGNode *cs) const
Definition CallGraph.h:335
const FunctionSet & getIndCSCallees(const CallICFGNode *cs) const
Definition CallGraph.h:339
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
Definition CallGraph.h:331
Set< const FunObjVar * > FunctionSet
Definition CallGraph.h:247
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:107
void addCandidate(NodeID id)
Definition DDAClient.h:101
OrderedNodeSet candidateQueries
store all candidate pointers to be queried
Definition DDAClient.h:109
virtual OrderedNodeSet & collectCandidateQueries(SVFIR *p)
Collect candidate pointers for query.
Definition DDAClient.h:58
VTablePtrToCallSiteMap vtableToCallSiteMap
Definition DDAClient.h:124
virtual OrderedNodeSet & collectCandidateQueries(SVFIR *p)
Only collect function pointers as query candidates.
Definition DDAClient.cpp:80
virtual void performStat(PointerAnalysis *pta)
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
CallGraph * getCallGraph() const
Return call graph.
virtual AliasResult alias(const SVFVar *V1, const SVFVar *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
PTAStat * getStat() const
Get PTA stat.
SVFStmt::SVFStmtSetTy & getSVFStmtSet(SVFStmt::PEDGEK kind)
Get/set methods to get SVFStmts based on their kinds and ICFGNodes.
Definition SVFIR.h:296
bool isValidTopLevelPtr(const SVFVar *node)
Definition SVFIR.cpp:764
const CallSiteToFunPtrMap & getIndirectCallsites() const
Add/get indirect callsites.
Definition SVFIR.h:451
const SVFVar * getSVFVar(NodeID id) const
ObjVar/GepObjVar/BaseObjVar.
Definition SVFIR.h:133
GenericNode< SVFVar, SVFStmt >::GEdgeSetTy SVFStmtSetTy
NodeID getId() const
Get ID.
Definition SVFValue.h:163
bool getMemoryUsageKB(u32_t *vmrss_kb, u32_t *vmsize_kb)
Get memory usage from system file. Return TRUE if succeed.
Definition SVFUtil.cpp:179
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
OrderedSet< NodeID > OrderedNodeSet
u32_t NodeID
Definition GeneralType.h:56
AliasResult
Definition SVFType.h:636
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:47