Static Value-Flow Analysis
DDAPass.cpp
Go to the documentation of this file.
1 //===- DDAPass.cpp -- Demand-driven analysis driver pass-------------//
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 /*
25  * @file: DDAPass.cpp
26  * @author: Yulei Sui
27  * @date: 01/07/2014
28  */
29 
30 
31 #include "Util/Options.h"
33 #include "DDA/DDAPass.h"
34 #include "DDA/FlowDDA.h"
35 #include "DDA/ContextDDA.h"
36 #include "DDA/DDAClient.h"
37 
38 #include <sstream>
39 #include <limits.h>
40 
41 using namespace SVF;
42 using namespace SVFUtil;
43 using namespace std;
44 
45 char DDAPass::ID = 0;
46 
48 {
49  // _pta->dumpStat();
50  if (_client != nullptr)
51  delete _client;
52 }
53 
54 
56 {
58  //InitializeAliasAnalysis(this, getDataLayout(&module));
59 
60  selectClient(pag->getModule());
61 
64  {
65  PointerAnalysis::PTATY iPtTy = static_cast<PointerAnalysis::PTATY>(i);
66  if (Options::DDASelected(iPtTy))
67  runPointerAnalysis(pag, i);
68  }
69 }
70 
73 {
74 
75  if (!Options::UserInputQuery().empty())
76  {
78  if (Options::UserInputQuery() == "funptr")
79  {
80  _client = new FunptrDDAClient(module);
81  }
82  else if (Options::UserInputQuery() == "alias")
83  {
84  _client = new AliasDDAClient(module);
85  }
87  else
88  {
89  _client = new DDAClient(module);
90  if (Options::UserInputQuery() != "all")
91  {
92  u32_t buf; // Have a buffer
93  stringstream ss(Options::UserInputQuery()); // Insert the user input string into a stream
94  while (ss >> buf)
95  _client->setQuery(buf);
96  }
97  }
98  }
99  else
100  {
101  assert(false && "Please specify query options!");
102  }
103 
104  _client->initialise(module);
105 }
106 
109 {
110 
113 
115  switch (kind)
116  {
118  {
119  _pta = std::make_unique<ContextDDA>(pag, _client);
120  break;
121  }
123  {
124  _pta = std::make_unique<FlowDDA>(pag, _client);
125  break;
126  }
127  default:
128  outs() << "This pointer analysis has not been implemented yet.\n";
129  break;
130  }
131 
132  if(Options::WPANum())
133  {
134  _client->collectWPANum(pag->getModule());
135  }
136  else
137  {
139  _pta->initialize();
141  _client->answerQueries(_pta.get());
143  _pta->finalize();
144  if(Options::PrintCPts())
145  _pta->dumpCPts();
146 
147  if (_pta->printStat())
148  _client->performStat(_pta.get());
149 
151  printQueryPTS();
152  }
153 }
154 
155 
159 void DDAPass::initCxtInsensitiveEdges(PointerAnalysis* pta, const SVFG* svfg,const SVFGSCC* svfgSCC, SVFGEdgeSet& insensitveEdges)
160 {
161  if(Options::InsenRecur())
162  collectCxtInsenEdgeForRecur(pta,svfg,insensitveEdges);
163  else if(Options::InsenCycle())
164  collectCxtInsenEdgeForVFCycle(pta,svfg,svfgSCC,insensitveEdges);
165 }
166 
170 bool DDAPass::edgeInSVFGSCC(const SVFGSCC* svfgSCC,const SVFGEdge* edge)
171 {
172  return (svfgSCC->repNode(edge->getSrcID()) == svfgSCC->repNode(edge->getDstID()));
173 }
174 
179 {
180  const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun();
181  const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun();
182 
183  if(srcFun && dstFun)
184  {
185  return pta->inSameCallGraphSCC(srcFun,dstFun);
186  }
187 
188  assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge" );
189 
190  return false;
191 }
192 
197 {
198 
199  for (SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(),eit = svfg->end(); it != eit; ++it)
200  {
201 
202  SVFGEdge::SVFGEdgeSetTy::const_iterator edgeIt = it->second->InEdgeBegin();
203  SVFGEdge::SVFGEdgeSetTy::const_iterator edgeEit = it->second->InEdgeEnd();
204  for (; edgeIt != edgeEit; ++edgeIt)
205  {
206  const SVFGEdge* edge = *edgeIt;
207  if(edge->isCallVFGEdge() || edge->isRetVFGEdge())
208  {
209  if(edgeInCallGraphSCC(pta,edge))
210  insensitveEdges.insert(edge);
211  }
212  }
213  }
214 }
215 
219 void DDAPass::collectCxtInsenEdgeForVFCycle(PointerAnalysis* pta, const SVFG* svfg,const SVFGSCC* svfgSCC, SVFGEdgeSet& insensitveEdges)
220 {
221 
222  OrderedSet<NodePair> insensitvefunPairs;
223 
224  for (SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(),eit = svfg->end(); it != eit; ++it)
225  {
226 
227  SVFGEdge::SVFGEdgeSetTy::const_iterator edgeIt = it->second->InEdgeBegin();
228  SVFGEdge::SVFGEdgeSetTy::const_iterator edgeEit = it->second->InEdgeEnd();
229  for (; edgeIt != edgeEit; ++edgeIt)
230  {
231  const SVFGEdge* edge = *edgeIt;
232  if(edge->isCallVFGEdge() || edge->isRetVFGEdge())
233  {
234  if(this->edgeInSVFGSCC(svfgSCC,edge))
235  {
236 
237  const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun();
238  const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun();
239 
240  if(srcFun && dstFun)
241  {
242  NodeID src = pta->getCallGraph()->getCallGraphNode(srcFun)->getId();
243  NodeID dst = pta->getCallGraph()->getCallGraphNode(dstFun)->getId();
244  insensitvefunPairs.insert(std::make_pair(src,dst));
245  insensitvefunPairs.insert(std::make_pair(dst,src));
246  }
247  else
248  assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge" );
249  }
250  }
251  }
252  }
253 
254  for(SVFG::SVFGNodeIDToNodeMapTy::const_iterator it = svfg->begin(),eit = svfg->end(); it != eit; ++it)
255  {
256  SVFGEdge::SVFGEdgeSetTy::const_iterator edgeIt = it->second->InEdgeBegin();
257  SVFGEdge::SVFGEdgeSetTy::const_iterator edgeEit = it->second->InEdgeEnd();
258  for (; edgeIt != edgeEit; ++edgeIt)
259  {
260  const SVFGEdge* edge = *edgeIt;
261 
262  if(edge->isCallVFGEdge() || edge->isRetVFGEdge())
263  {
264  const SVFFunction* srcFun = edge->getSrcNode()->getICFGNode()->getFun();
265  const SVFFunction* dstFun = edge->getDstNode()->getICFGNode()->getFun();
266 
267  if(srcFun && dstFun)
268  {
269  NodeID src = pta->getCallGraph()->getCallGraphNode(srcFun)->getId();
270  NodeID dst = pta->getCallGraph()->getCallGraphNode(dstFun)->getId();
271  if(insensitvefunPairs.find(std::make_pair(src,dst))!=insensitvefunPairs.end())
272  insensitveEdges.insert(edge);
273  else if(insensitvefunPairs.find(std::make_pair(dst,src))!=insensitvefunPairs.end())
274  insensitveEdges.insert(edge);
275  }
276  }
277  }
278  }
279 }
280 
282 {
283  SVFIR* pag = _pta->getPAG();
284 
285  if(pag->isValidTopLevelPtr(pag->getGNode(node1)))
286  _pta->computeDDAPts(node1);
287 
288  if(pag->isValidTopLevelPtr(pag->getGNode(node2)))
289  _pta->computeDDAPts(node2);
290 
291  return _pta->alias(node1,node2);
292 }
298 {
299  SVFIR* pag = _pta->getPAG();
300 
306  if (pag->hasValueNode(V1) && pag->hasValueNode(V2))
307  {
308  PAGNode* node1 = pag->getGNode(pag->getValueNode(V1));
309  if(pag->isValidTopLevelPtr(node1))
310  _pta->computeDDAPts(node1->getId());
311 
312  PAGNode* node2 = pag->getGNode(pag->getValueNode(V2));
313  if(pag->isValidTopLevelPtr(node2))
314  _pta->computeDDAPts(node2->getId());
315 
316  return _pta->alias(V1,V2);
317  }
318 
319  return AliasResult::MayAlias;
320 }
321 
326 {
327  const OrderedNodeSet& candidates = _client->getCandidateQueries();
328  for (OrderedNodeSet::const_iterator it = candidates.begin(), eit = candidates.end(); it != eit; ++it)
329  {
330  const PointsTo& pts = _pta->getPts(*it);
331  _pta->dumpPts(*it,pts);
332  }
333 }
static void setMaxPathLen(u32_t max)
set max path limit
Definition: DPItem.h:270
static void setMaxCxtLen(u32_t max)
set max context limit
Definition: DPItem.h:265
virtual AliasResult alias(const SVFValue *V1, const SVFValue *V2)
Interface expose to users of our pointer analysis, given Value infos.
Definition: DDAPass.cpp:297
bool edgeInSVFGSCC(const SVFGSCC *svfgSCC, const SVFGEdge *edge)
Return TRUE if this edge is inside a SVFG SCC, i.e., src node and dst node are in the same SCC on the...
Definition: DDAPass.cpp:170
virtual void selectClient(SVFModule *module)
Select a client.
Definition: DDAPass.cpp:72
bool edgeInCallGraphSCC(PointerAnalysis *pta, const SVFGEdge *edge)
Return TRUE if this edge is inside a SVFG SCC, i.e., src node and dst node are in the same SCC on the...
Definition: DDAPass.cpp:178
void runPointerAnalysis(SVFIR *module, u32_t kind)
Create pointer analysis according to specified kind and analyze the module.
Definition: DDAPass.cpp:108
virtual void runOnModule(SVFIR *module)
We start from here.
Definition: DDAPass.cpp:55
OrderedSet< const SVFGEdge * > SVFGEdgeSet
Definition: DDAPass.h:53
static char ID
Pass ID.
Definition: DDAPass.h:51
void initCxtInsensitiveEdges(PointerAnalysis *pta, const SVFG *svfg, const SVFGSCC *svfgSCC, SVFGEdgeSet &insensitveEdges)
Context insensitive Edge for DDA.
Definition: DDAPass.cpp:159
void collectCxtInsenEdgeForVFCycle(PointerAnalysis *pta, const SVFG *svfg, const SVFGSCC *svfgSCC, SVFGEdgeSet &insensitveEdges)
Definition: DDAPass.cpp:219
void collectCxtInsenEdgeForRecur(PointerAnalysis *pta, const SVFG *svfg, SVFGEdgeSet &insensitveEdges)
Definition: DDAPass.cpp:196
void printQueryPTS()
Print queries' pts.
Definition: DDAPass.cpp:325
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
NodeID getDstID() const
Definition: GenericGraph.h:85
NodeID getSrcID() const
get methods of the components
Definition: GenericGraph.h:81
NodeType * getDstNode() const
Definition: GenericGraph.h:101
iterator begin()
Iterators.
Definition: GenericGraph.h:627
NodeType * getGNode(NodeID id) const
Get a node.
Definition: GenericGraph.h:653
bool hasValueNode(const SVFValue *V)
Definition: IRGraph.h:141
NodeID getValueNode(const SVFValue *V)
Definition: IRGraph.h:137
static const Option< bool > InsenCycle
Definition: Options.h:89
static const Option< std::string > UserInputQuery
Definition: Options.h:87
static const Option< u32_t > MaxContextLen
Definition: Options.h:85
static const Option< u32_t > MaxPathLen
Definition: Options.h:84
static const Option< bool > WPANum
Definition: Options.h:92
static const Option< bool > PrintCPts
Definition: Options.h:90
static const Option< bool > PrintQueryPts
Definition: Options.h:91
static const Option< bool > InsenRecur
Definition: Options.h:88
static OptionMultiple< PointerAnalysis::PTATY > DDASelected
register this into alias analysis group
Definition: Options.h:93
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.
Definition: PTACallGraph.h:339
PTATY
Pointer analysis type list.
@ Cxt_DDA
context sensitive DDA
@ FlowS_DDA
Flow sensitive DDA.
@ Default_PTA
default pta without any analysis
PTACallGraph * getCallGraph() const
Return call graph.
bool inSameCallGraphSCC(const SVFFunction *fun1, const SVFFunction *fun2)
Return TRUE if this edge is inside a PTACallGraph SCC, i.e., src node and dst node are in the same SC...
NodeID repNode(NodeID n) const
get the rep node if not found return itself
Definition: SCC.h:139
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
Definition: SVFG.h:66
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
bool isValidTopLevelPtr(const SVFVar *node)
Definition: SVFIR.cpp:673
SVFModule * getModule()
Definition: SVFIR.h:161
bool isRetVFGEdge() const
Definition: VFGEdge.h:88
bool isCallVFGEdge() const
Definition: VFGEdge.h:84
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
OrderedSet< NodeID > OrderedNodeSet
Definition: GeneralType.h:112
u32_t NodeID
Definition: GeneralType.h:55
std::set< Key, Compare, Allocator > OrderedSet
Definition: GeneralType.h:105
AliasResult
Definition: SVFType.h:527
@ MayAlias
Definition: SVFType.h:529
unsigned u32_t
Definition: GeneralType.h:46