Static Value-Flow Analysis
Loading...
Searching...
No Matches
SrcSnkDDA.cpp
Go to the documentation of this file.
1//===- SrcSnkDDA.cpp -- Source-sink analyzer --------------------------------//
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 * SrcSnkDDA.cpp
25 *
26 * Created on: Apr 1, 2014
27 * Author: Yulei Sui
28 */
29
30
31#include "Util/Options.h"
32#include "SABER/SrcSnkDDA.h"
33#include "Graphs/SVFGStat.h"
34#include "Util/Options.h"
35#include "WPA/Andersen.h"
36
37using namespace SVF;
38using namespace SVFUtil;
39
42{
43 SVFIR* pag = PAG::getPAG();
44
48 svfg = memSSA.buildFullSVFG(ander);
49 else
52 callgraph = ander->getCallGraph();
53 //AndersenWaveDiff::releaseAndersenWaveDiff();
55 getSaberCondAllocator()->allocate(getPAG()->getModule());
56
57 initSrcs();
58 initSnks();
59}
60
62{
63
65
67
69 iter != eiter; ++iter)
70 {
72
73 DBOUT(DGENERAL, outs() << "Analysing slice:" << (*iter)->getId() << ")\n");
74 ContextCond cxt;
75 DPIm item((*iter)->getId(),cxt);
77
80 if (getCurSlice()->isReachGlobal())
81 {
82 DBOUT(DSaber, outs() << "Forward analysis reaches globals for slice:" << (*iter)->getId() << ")\n");
83 }
84 else
85 {
86 DBOUT(DSaber, outs() << "Forward process for slice:" << (*iter)->getId() << " (size = " << getCurSlice()->getForwardSliceSize() << ")\n");
87
89 getCurSlice()->sinksEnd(); sit != esit; ++sit)
90 {
91 ContextCond cxt;
92 DPIm item((*sit)->getId(),cxt);
94 }
95
96 DBOUT(DSaber, outs() << "Backward process for slice:" << (*iter)->getId() << " (size = " << getCurSlice()->getBackwardSliceSize() << ")\n");
97
100
103
104 DBOUT(DSaber, outs() << "Guard computation for slice:" << (*iter)->getId() << ")\n");
105 }
106
108 }
109 finalize();
110
111}
112
113
119{
120
121 bool reachFunExit = false;
122
124 worklist.push(src);
125 SVFGNodeBS visited;
126 u32_t step = 0;
127 while (!worklist.empty())
128 {
129 const SVFGNode* node = worklist.pop();
130
131 if(visited.test(node->getId())==0)
132 visited.set(node->getId());
133 else
134 continue;
135 // reaching maximum steps when traversing on SVFG to identify a memory allocation wrapper
137 return false;
138
140 node->OutEdgeEnd(); it != eit; ++it)
141 {
142 const SVFGEdge* edge = (*it);
143 //assert(edge->isDirectVFGEdge() && "the edge should always be direct VF");
144 // if this is a call edge
145 if(edge->isCallDirectVFGEdge())
146 {
147 return false;
148 }
149 // if this is a return edge
150 else if(edge->isRetDirectVFGEdge())
151 {
152 reachFunExit = true;
153 csIdSet.insert(getSVFG()->getCallSite(SVFUtil::cast<RetDirSVFGEdge>(edge)->getCallSiteId()));
154 }
155 // (1) an intra direct edge, we will keep tracking
156 // (2) an intra indirect edge, we only track if the succ SVFGNode is a load, which means we only track one level store-load pair .
157 // (3) do not track for all other interprocedural edges.
158 else
159 {
160 const SVFGNode* succ = edge->getDstNode();
161 if(SVFUtil::isa<IntraDirSVFGEdge>(edge))
162 {
166 {
167 worklist.push(succ);
168 }
169 }
170 else if(SVFUtil::isa<IntraIndSVFGEdge>(edge))
171 {
172 if(SVFUtil::isa<LoadSVFGNode, IntraMSSAPHISVFGNode>(succ))
173 {
174 worklist.push(succ);
175 }
176 }
177 else
178 return false;
179 }
180 }
181 }
182 if(reachFunExit)
183 return true;
184 else
185 return false;
186}
187
188
193{
194 DBOUT(DSaber,outs() << "\n##processing source: " << getCurSlice()->getSource()->getId() <<" forward propagate from (" << edge->getSrcID());
195
196 // for indirect SVFGEdge, the propagation should follow the def-use chains
197 // points-to on the edge indicate whether the object of source node can be propagated
198
199 const SVFGNode* dstNode = edge->getDstNode();
200 DPIm newItem(dstNode->getId(),item.getContexts());
201
203 if(isGlobalSVFGNode(dstNode) || getCurSlice()->isReachGlobal())
204 {
206 return;
207 }
208
209
211 // push context for calling
212 if (edge->isCallVFGEdge())
213 {
214 CallSiteID csId = 0;
215 if(const CallDirSVFGEdge* callEdge = SVFUtil::dyn_cast<CallDirSVFGEdge>(edge))
216 csId = callEdge->getCallSiteId();
217 else
218 csId = SVFUtil::cast<CallIndSVFGEdge>(edge)->getCallSiteId();
219
220 newItem.pushContext(csId);
221 DBOUT(DSaber, outs() << " push cxt [" << csId << "] ");
222 }
223 // match context for return
224 else if (edge->isRetVFGEdge())
225 {
226 CallSiteID csId = 0;
227 if(const RetDirSVFGEdge* callEdge = SVFUtil::dyn_cast<RetDirSVFGEdge>(edge))
228 csId = callEdge->getCallSiteId();
229 else
230 csId = SVFUtil::cast<RetIndSVFGEdge>(edge)->getCallSiteId();
231
232 if (newItem.matchContext(csId) == false)
233 {
234 DBOUT(DSaber, outs() << "-|-\n");
235 return;
236 }
237 DBOUT(DSaber, outs() << " pop cxt [" << csId << "] ");
238 }
239
242 {
243 DBOUT(DSaber,outs() << " node "<< dstNode->getId() <<" has been visited\n");
244 return;
245 }
246 else
248
250 DBOUT(DSaber,outs() << " --> " << edge->getDstID() << ", cxt size: " << newItem.getContexts().cxtSize() <<")\n");
251
252}
253
258{
259 DBOUT(DSaber,outs() << "backward propagate from (" << edge->getDstID() << " --> " << edge->getSrcID() << ")\n");
260 const SVFGNode* srcNode = edge->getSrcNode();
262 return;
263 else
265
266 ContextCond cxt;
267 DPIm newItem(srcNode->getId(), cxt);
269}
270
273{
274 if(_curSlice!=nullptr)
275 {
276 delete _curSlice;
277 _curSlice = nullptr;
279 }
280
282}
283
285{
286 getSVFG()->getStat()->addToSources(slice->getSource());
287 for(SVFGNodeSetIter it = slice->sinksBegin(), eit = slice->sinksEnd(); it!=eit; ++it )
289 for(SVFGNodeSetIter it = slice->forwardSliceBegin(), eit = slice->forwardSliceEnd(); it!=eit; ++it )
291 for(SVFGNodeSetIter it = slice->backwardSliceBegin(), eit = slice->backwardSliceEnd(); it!=eit; ++it )
293}
294
296{
297
299 const_cast<SVFG*>(getSVFG())->dump("Slice",true);
300}
301
303{
304
305 outs() << "Z3 Mem usage: " << getSaberCondAllocator()->getMemUsage() << "\n";
306 outs() << "Z3 Number: " << getSaberCondAllocator()->getCondNum() << "\n";
307}
#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 DSaber
Definition SVFType.h:504
cJSON * item
Definition cJSON.h:222
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition Andersen.h:408
static void setMaxCxtLen(u32_t max)
set max context limit
Definition DPItem.h:265
iterator OutEdgeEnd()
iterator OutEdgeBegin()
iterators
void setGraph(GraphType g)
WorkList worklist
Worklist for resolution.
bool pushIntoWorklist(DPIm &item)
virtual void backwardTraverse(DPIm &it)
CFL forward traverse solve.
virtual void forwardTraverse(DPIm &it)
CFL forward traverse solve.
static const Option< u32_t > CxtLimit
Definition Options.h:173
static const Option< bool > SABERFULLSVFG
Definition Options.h:222
static const Option< u32_t > MaxStepInWrapper
Definition Options.h:86
static const Option< bool > DumpSlice
Definition Options.h:172
PTACallGraph * getCallGraph() const
Return call graph.
bool setReachGlobal()
Definition ProgSlice.h:151
bool AllPathReachableSolve()
Guarded reachability solve.
Definition ProgSlice.cpp:43
void setAllReachable()
Definition ProgSlice.h:147
NodeID getId() const
Get ID.
SVFG * getSVFG() const
Get SVFG instance.
Definition SVFGBuilder.h:61
SVFG * buildFullSVFG(BVDataPTAImpl *pta)
SVFG * buildPTROnlySVFG(BVDataPTAImpl *pta)
void addToBackwardSlice(const SVFGNode *node)
Definition SVFGStat.h:249
void addToSources(const SVFGNode *node)
Definition SVFGStat.h:237
void addToSinks(const SVFGNode *node)
Definition SVFGStat.h:241
void addToForwardSlice(const SVFGNode *node)
Definition SVFGStat.h:245
SVFGStat * getStat() const
Return statistics.
Definition SVFG.h:126
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition SVFIR.h:116
void allocate(const SVFModule *module)
Perform path allocation.
std::string getMemUsage()
Statistics.
void setSaberCondAllocator(SaberCondAllocator *allocator)
bool test(unsigned Idx) const
void set(unsigned Idx)
SVFGNodeSetIter sourcesBegin() const
Definition SrcSnkDDA.h:210
virtual void initSnks()=0
virtual void initSrcs()=0
bool backwardVisited(const SVFGNode *node)
Definition SrcSnkDDA.h:291
bool isGlobalSVFGNode(const SVFGNode *node) const
Whether this svfg node may access global variable.
Definition SrcSnkDDA.h:138
SVFIR * getPAG() const
Get SVFIR.
Definition SrcSnkDDA.h:120
void BWProcessIncomingEdge(const DPIm &item, SVFGEdge *edge) override
Propagate information backward without matching context, as forward analysis already did it.
ProgSlice::VFWorkList WorkList
Definition SrcSnkDDA.h:66
Set< const CallICFGNode * > CallSiteSet
Definition SrcSnkDDA.h:64
void addForwardVisited(const SVFGNode *node, const DPIm &item)
Definition SrcSnkDDA.h:287
PTACallGraph * callgraph
Definition SrcSnkDDA.h:79
ProgSlice * _curSlice
Definition SrcSnkDDA.h:69
SVFGNodeSetIter sinksBegin() const
Definition SrcSnkDDA.h:226
ProgSlice * getCurSlice() const
Definition SrcSnkDDA.h:146
void annotateSlice(ProgSlice *slice)
virtual void initialize(SVFModule *module)
Initialize analysis.
Definition SrcSnkDDA.cpp:41
bool forwardVisited(const SVFGNode *node, const DPIm &item)
Whether has been visited or not, in order to avoid recursion on SVFG.
Definition SrcSnkDDA.h:279
void addBackwardVisited(const SVFGNode *node)
Definition SrcSnkDDA.h:295
virtual void reportBug(ProgSlice *slice)=0
report bug on the current analyzed slice
SVFGNodeSetIter sinksEnd() const
Definition SrcSnkDDA.h:230
virtual void setCurSlice(const SVFGNode *src)
Slice operations.
SaberSVFGBuilder memSSA
Definition SrcSnkDDA.h:77
virtual void analyze(SVFModule *module)
Start analysis here.
Definition SrcSnkDDA.cpp:61
void dumpSlices()
Dump SVFG with annotated slice information.
void FWProcessOutgoingEdge(const DPIm &item, SVFGEdge *edge) override
Propagate information forward by matching context.
SVFGNodeSetIter sourcesEnd() const
Definition SrcSnkDDA.h:214
SVFGNodeSet::const_iterator SVFGNodeSetIter
Definition SrcSnkDDA.h:60
const SVFG * getSVFG() const
Get SVFG.
Definition SrcSnkDDA.h:126
SaberCondAllocator * getSaberCondAllocator() const
Get saber condition allocator.
Definition SrcSnkDDA.h:241
void clearVisitedMap()
Definition SrcSnkDDA.h:299
virtual void finalize()
Finalize analysis.
Definition SrcSnkDDA.h:114
bool isInAWrapper(const SVFGNode *src, CallSiteSet &csIdSet)
Identify allocation wrappers.
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
Definition VFGNode.h:55
const CallICFGNode * getCallSite(CallSiteID id) const
Definition VFG.h:182
LLVM_NODISCARD bool isa(const Y &Val)
Definition Casting.h:241
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
for isBitcode
Definition BasicTypes.h:68
unsigned CallSiteID
Definition GeneralType.h:58
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
void dump(const SparseBitVector< ElementSize > &LHS, std::ostream &out)
unsigned u32_t
Definition GeneralType.h:46