Static Value-Flow Analysis
ContextDDA.h
Go to the documentation of this file.
1 //===- ContextDDA.h -- Context-sensitive 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  * ContextDDA.h
25  *
26  * Created on: Aug 17, 2014
27  * Author: Yulei Sui
28  *
29  * The implementation is based on
30  * (1) Yulei Sui and Jingling Xue. "On-Demand Strong Update Analysis via Value-Flow Refinement".
31  * ACM SIGSOFT International Symposium on the Foundation of Software Engineering (FSE'16)
32  *
33  * (2) Yulei Sui and Jingling Xue. "Value-Flow-Based Demand-Driven Pointer Analysis for C and C++".
34  * IEEE Transactions on Software Engineering (TSE'18)
35  */
36 
37 #ifndef ContextDDA_H_
38 #define ContextDDA_H_
39 
41 #include "DDA/DDAVFSolver.h"
42 #include "Util/DPItem.h"
43 
44 namespace SVF
45 {
46 
47 class FlowDDA;
48 class DDAClient;
50 
54 class ContextDDA : public CondPTAImpl<ContextCond>, public DDAVFSolver<CxtVar,CxtPtSet,CxtLocDPItem>
55 {
56 
57 public:
59  ContextDDA(SVFIR* _pag, DDAClient* client);
60 
62  virtual ~ContextDDA();
63 
65  virtual void initialize() override;
66 
68  virtual inline void finalize() override
69  {
71  }
72 
74  virtual void analyze() override {}
75 
77  virtual void computeDDAPts(NodeID id) override;
78 
80  virtual const CxtPtSet& computeDDAPts(const CxtVar& cxtVar);
81 
83  void handleOutOfBudgetDpm(const CxtLocDPItem& dpm);
84 
86  virtual CxtPtSet getConservativeCPts(const CxtLocDPItem& dpm) override
87  {
88  const PointsTo& pts = getAndersenAnalysis()->getPts(dpm.getCurNodeID());
89  CxtPtSet tmpCPts;
90  ContextCond cxt;
91  for (PointsTo::iterator piter = pts.begin(); piter != pts.end(); ++piter)
92  {
93  CxtVar var(cxt,*piter);
94  tmpCPts.set(var);
95  }
96  return tmpCPts;
97  }
98 
100  virtual inline NodeID getPtrNodeID(const CxtVar& var) const override
101  {
102  return var.get_id();
103  }
105  virtual bool handleBKCondition(CxtLocDPItem& dpm, const SVFGEdge* edge) override;
106 
110  virtual bool isHeapCondMemObj(const CxtVar& var, const StoreSVFGNode* store) override;
111 
113  bool testIndCallReachability(CxtLocDPItem& dpm, const SVFFunction* callee, const CallICFGNode* cs);
114 
116  CallSiteID getCSIDAtCall(CxtLocDPItem& dpm, const SVFGEdge* edge);
117 
119  CallSiteID getCSIDAtRet(CxtLocDPItem& dpm, const SVFGEdge* edge);
120 
121 
123  inline virtual void popRecursiveCallSites(CxtLocDPItem& dpm)
124  {
125  ContextCond& cxtCond = dpm.getCond();
126  cxtCond.setNonConcreteCxt();
127  CallStrCxt& cxt = cxtCond.getContexts();
128  while(!cxt.empty() && isEdgeInRecursion(cxt.back()))
129  {
130  cxt.pop_back();
131  }
132  }
134  inline virtual bool isEdgeInRecursion(CallSiteID csId)
135  {
136  const SVFFunction* caller = getCallGraph()->getCallerOfCallSite(csId);
137  const SVFFunction* callee = getCallGraph()->getCalleeOfCallSite(csId);
138  return inSameCallGraphSCC(caller, callee);
139  }
141 
142  virtual void updateCallGraphAndSVFG(const CxtLocDPItem& dpm,const CallICFGNode* cs,SVFGEdgeSet& svfgEdges) override
143  {
144  CallEdgeMap newEdges;
145  resolveIndCalls(cs, getBVPointsTo(getCachedPointsTo(dpm)), newEdges);
146  for (CallEdgeMap::const_iterator iter = newEdges.begin(),eiter = newEdges.end(); iter != eiter; iter++)
147  {
148  const CallICFGNode* newcs = iter->first;
149  const FunctionSet & functions = iter->second;
150  for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
151  {
152  const SVFFunction* func = *func_iter;
153  getSVFG()->connectCallerAndCallee(newcs, func, svfgEdges);
154  }
155  }
156  }
158 
160  inline bool edgeInCallGraphSCC(const SVFGEdge* edge)
161  {
162  const SVFFunction* srcfun = edge->getSrcNode()->getFun();
163  const SVFFunction* dstfun = edge->getDstNode()->getFun();
164 
165  if(srcfun && dstfun)
166  return inSameCallGraphSCC(srcfun,dstfun);
167 
168  assert(edge->isRetVFGEdge() == false && "should not be an inter-procedural return edge" );
169 
170  return false;
171  }
172 
174  virtual CxtPtSet processGepPts(const GepSVFGNode* gep, const CxtPtSet& srcPts) override;
175 
177  virtual void handleAddr(CxtPtSet& pts,const CxtLocDPItem& dpm,const AddrSVFGNode* addr) override
178  {
179  NodeID srcID = addr->getPAGSrcNodeID();
181  if (isFieldInsensitive(srcID))
182  srcID = getFIObjVar(srcID);
183 
184  CxtVar var(dpm.getCond(),srcID);
185  addDDAPts(pts,var);
186  DBOUT(DDDA, SVFUtil::outs() << "\t add points-to target " << var << " to dpm ");
187  DBOUT(DDDA, dpm.dump());
188  }
189 
191  virtual inline bool propagateViaObj(const CxtVar& storeObj, const CxtVar& loadObj) override
192  {
193  return isSameVar(storeObj,loadObj);
194  }
195 
199  virtual inline bool isCondCompatible(const ContextCond& cxt1, const ContextCond& cxt2, bool singleton) const override;
200 
202  bool isInsensitiveCallRet(const SVFGEdge* edge)
203  {
204  return insensitveEdges.find(edge) != insensitveEdges.end();
205  }
208  {
209  return insensitveEdges;
210  }
212  virtual inline void dumpContexts(const ContextCond& cxts)
213  {
214  SVFUtil::outs() << cxts.toString() << "\n";
215  }
216 
217  virtual const std::string PTAName() const override
218  {
219  return "Context Sensitive DDA";
220  }
221 
222 private:
226 };
227 
228 } // End namespace SVF
229 
230 #endif /* ContextDDA_H_ */
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DDDA
Definition: SVFType.h:496
const char *const string
Definition: cJSON.h:172
virtual const PointsTo & getPts(NodeID id)
Operation of points-to set.
Definition: Andersen.h:239
bool isSameVar(const CVar &var1, const CVar &var2) const
Whether two pointers/objects are the same one by considering their conditions.
virtual PointsTo getBVPointsTo(const CPtSet &cpts) const
Given a conditional pts return its bit vector points-to.
virtual void finalize()
Finalization of pointer analysis, and normalize points-to information to Bit Vector representation.
void set(const Element &var)
Add the element into set.
NodeID get_id() const
std::string toString() const
Dump context condition.
Definition: DPItem.h:360
const CallStrCxt & getContexts() const
Get context.
Definition: DPItem.h:235
void setNonConcreteCxt()
Whether it is an concrete context.
Definition: DPItem.h:250
virtual bool isHeapCondMemObj(const CxtVar &var, const StoreSVFGNode *store) override
Definition: ContextDDA.cpp:335
bool testIndCallReachability(CxtLocDPItem &dpm, const SVFFunction *callee, const CallICFGNode *cs)
refine indirect call edge
Definition: ContextDDA.cpp:189
ConstSVFGEdgeSet & getInsensitiveEdgeSet()
Return insensitive edge set.
Definition: ContextDDA.h:207
void handleOutOfBudgetDpm(const CxtLocDPItem &dpm)
Handle out-of-budget dpm.
Definition: ContextDDA.cpp:115
virtual void handleAddr(CxtPtSet &pts, const CxtLocDPItem &dpm, const AddrSVFGNode *addr) override
Handle Address SVFGNode to add proper conditional points-to.
Definition: ContextDDA.h:177
virtual void popRecursiveCallSites(CxtLocDPItem &dpm)
Pop recursive callsites.
Definition: ContextDDA.h:123
FlowDDA * flowDDA
downgrade to flowDDA if out-of-budget
Definition: ContextDDA.h:224
CallSiteID getCSIDAtCall(CxtLocDPItem &dpm, const SVFGEdge *edge)
get callsite id from call, return 0 if it is a spurious call edge
Definition: ContextDDA.cpp:210
virtual CxtPtSet getConservativeCPts(const CxtLocDPItem &dpm) override
Override parent method.
Definition: ContextDDA.h:86
virtual void computeDDAPts(NodeID id) override
Compute points-to set for an unconditional pointer.
Definition: ContextDDA.cpp:105
virtual bool propagateViaObj(const CxtVar &storeObj, const CxtVar &loadObj) override
Propagate along indirect value-flow if two objects of load and store are same.
Definition: ContextDDA.h:191
virtual bool isEdgeInRecursion(CallSiteID csId)
Whether call/return inside recursion.
Definition: ContextDDA.h:134
virtual bool isCondCompatible(const ContextCond &cxt1, const ContextCond &cxt2, bool singleton) const override
Definition: ContextDDA.cpp:136
virtual ~ContextDDA()
Destructor.
Definition: ContextDDA.cpp:52
virtual NodeID getPtrNodeID(const CxtVar &var) const override
Override parent method.
Definition: ContextDDA.h:100
virtual void updateCallGraphAndSVFG(const CxtLocDPItem &dpm, const CallICFGNode *cs, SVFGEdgeSet &svfgEdges) override
Update call graph.
Definition: ContextDDA.h:142
bool isInsensitiveCallRet(const SVFGEdge *edge)
Whether this edge is treated context-insensitively.
Definition: ContextDDA.h:202
CallSiteID getCSIDAtRet(CxtLocDPItem &dpm, const SVFGEdge *edge)
get callsite id from return, return 0 if it is a spurious return edge
Definition: ContextDDA.cpp:234
ConstSVFGEdgeSet insensitveEdges
insensitive call-return edges
Definition: ContextDDA.h:223
virtual bool handleBKCondition(CxtLocDPItem &dpm, const SVFGEdge *edge) override
Handle condition for context or path analysis (backward analysis)
Definition: ContextDDA.cpp:256
virtual void dumpContexts(const ContextCond &cxts)
dump context call strings
Definition: ContextDDA.h:212
ContextDDA(SVFIR *_pag, DDAClient *client)
Constructor.
Definition: ContextDDA.cpp:42
virtual void analyze() override
dummy analyze method
Definition: ContextDDA.h:74
bool edgeInCallGraphSCC(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: ContextDDA.h:160
virtual void initialize() override
Initialization of the analysis.
Definition: ContextDDA.cpp:62
virtual void finalize() override
Finalize analysis.
Definition: ContextDDA.h:68
DDAClient * _client
DDA client.
Definition: ContextDDA.h:225
virtual CxtPtSet processGepPts(const GepSVFGNode *gep, const CxtPtSet &srcPts) override
processGep node
Definition: ContextDDA.cpp:154
virtual const std::string PTAName() const override
Return PTA name.
Definition: ContextDDA.h:217
void dump() const
Definition: DPItem.h:466
const ContextCond & getCond() const
Get context.
Definition: DPItem.h:414
virtual void addDDAPts(CxtPtSet &pts, const CxtVar &var)
Add pts.
Definition: DDAVFSolver.h:113
AndersenWaveDiff * getAndersenAnalysis() const
Return Andersen's analysis.
Definition: DDAVFSolver.h:717
virtual const CxtPtSet & getCachedPointsTo(const CxtLocDPItem &dpm)
Points-to Caching for top-level pointers and address-taken objects.
Definition: DDAVFSolver.h:556
OrderedSet< const SVFGEdge * > ConstSVFGEdgeSet
Definition: DDAVFSolver.h:60
NodeID getCurNodeID() const
Definition: DPItem.h:77
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
NodeType * getDstNode() const
Definition: GenericGraph.h:101
const SVFFunction * getCallerOfCallSite(CallSiteID id) const
Definition: PTACallGraph.h:391
const SVFFunction * getCalleeOfCallSite(CallSiteID id) const
Definition: PTACallGraph.h:395
bool isFieldInsensitive(NodeID id) const
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
NodeID getFIObjVar(NodeID id)
PTACallGraph * getCallGraph() const
Return call graph.
virtual void resolveIndCalls(const CallICFGNode *cs, const PointsTo &target, CallEdgeMap &newEdges)
Resolve indirect call edges.
Set< const SVFFunction * > FunctionSet
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...
const_iterator end() const
Definition: PointsTo.h:132
const_iterator begin() const
Definition: PointsTo.h:128
virtual void connectCallerAndCallee(const CallICFGNode *cs, const SVFFunction *callee, SVFGEdgeSetTy &edges)
Connect SVFG nodes between caller and callee for indirect call site.
Definition: SVFG.cpp:658
NodeID getPAGSrcNodeID() const
Definition: VFGNode.h:152
bool isRetVFGEdge() const
Definition: VFGEdge.h:88
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
unsigned CallSiteID
Definition: GeneralType.h:58
u32_t NodeID
Definition: GeneralType.h:55
CxtStmtDPItem< SVFGNode > CxtLocDPItem
Definition: ContextDDA.h:48
std::vector< u32_t > CallStrCxt
Definition: GeneralType.h:122