Static Value-Flow Analysis
Loading...
Searching...
No Matches
AbstractInterpretation.h
Go to the documentation of this file.
1//===- AbstractInterpretation.h -- Abstract Execution----------//
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// Created on: Jan 10, 2024
26// Author: Xiao Cheng, Jiawei Wang
27// The implementation is based on
28// Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction.
29// 46th International Conference on Software Engineering. (ICSE24)
30//
31#pragma once
33#include "AE/Core/ICFGWTO.h"
37#include "AE/Svfexe/AbsExtAPI.h"
38#include "AE/Svfexe/AEStat.h"
39#include "Util/SVFBugReport.h"
40#include "Graphs/SCC.h"
41#include "Graphs/CallGraph.h"
42#include <deque>
43
44namespace SVF
45{
46class AbstractInterpretation;
47class AbsExtAPI;
48class AEStat;
49class AEAPI;
50
51template<typename T> class FILOWorkList;
52
55{
56 friend class AEStat;
57 friend class AEAPI;
58 friend class BufOverflowDetector;
60
61public:
62 /*
63 * For recursive test case
64 * int demo(int a) {
65 if (a >= 10000)
66 return a;
67 demo(a+1);
68 }
69
70 int main() {
71 int result = demo(0);
72 }
73 * if set TOP, result = [-oo, +oo] since the return value, and any stored object pointed by q at *q = p in recursive functions will be set to the top value.
74 * if set WIDEN_ONLY, result = [10000, +oo] since only widening is applied at the cycle head of recursive functions without narrowing.
75 * if set WIDEN_NARROW, result = [10000, 10000] since both widening and narrowing are applied at the cycle head of recursive functions.
76 * */
83
90
93
94 virtual void runOnModule(ICFG* icfg);
95
98
100 void analyse();
101
104
106 std::deque<const FunObjVar*> collectProgEntryFuns();
107
108
110 {
112 return instance;
113 }
114
115 void addDetector(std::unique_ptr<AEDetector> detector)
116 {
117 detectors.push_back(std::move(detector));
118 }
119
121 inline const SVFVar* getSVFVar(NodeID varId) const
122 {
123 return svfir->getSVFVar(varId);
124 }
125
128 {
129 return svfStateMgr;
130 }
131
132 // ---------------------------------------------------------------
133 // Convenience wrappers around AbstractStateManager
134 // ---------------------------------------------------------------
137 inline const AbstractState& getAbsState(const ICFGNode* node) const
138 {
139 return svfStateMgr->getAbstractState(node);
140 }
141
142 inline bool hasAbsState(const ICFGNode* node)
143 {
144 return svfStateMgr->hasAbstractState(node);
145 }
146
147 inline void updateAbsState(const ICFGNode* node, const AbstractState& state)
148 {
150 }
151
152 inline bool hasAbsValue(const SVFVar* var, const ICFGNode* node)
153 {
154 return svfStateMgr->hasAbstractValue(var, node);
155 }
156
157 inline const AbstractValue& getAbsValue(const SVFVar* var, const ICFGNode* node)
158 {
159 return svfStateMgr->getAbstractValue(var, node);
160 }
161
162 inline void updateAbsValue(const SVFVar* var, const AbstractValue& val, const ICFGNode* node)
163 {
165 }
166
168 void propagateObjVarAbsVal(const ObjVar* var, const ICFGNode* defSite);
169
170private:
172 virtual void handleGlobalNode();
173
177 bool mergeStatesFromPredecessors(const ICFGNode* node);
178
181
183 virtual void handleCallSite(const ICFGNode* node);
184
186 virtual void handleLoopOrRecursion(const ICFGCycleWTO* cycle, const CallICFGNode* caller = nullptr);
187
188 // ---- Semi-sparse cycle helpers ----
189 // ValVars whose def-site is inside the cycle but NOT cycle_head do not
190 // flow through cycle_head's merge in semi-sparse mode, so the around-merge
191 // widening cannot observe them. getFullCycleHeadState pulls these ValVars
192 // into a single AbstractState snapshot so widen/narrow can treat ValVars
193 // and ObjVars uniformly; after widen/narrow we scatter the ValVars back
194 // to their def-sites.
195
202
206 bool widenCycleState(const AbstractState& prev, const AbstractState& cur,
207 const ICFGCycleWTO* cycle);
209 bool narrowCycleState(const AbstractState& prev, const AbstractState& cur,
210 const ICFGCycleWTO* cycle);
211
213 void handleFunction(const ICFGNode* funEntry, const CallICFGNode* caller = nullptr);
214
216 bool handleICFGNode(const ICFGNode* node);
217
219 virtual void handleSVFStatement(const SVFStmt* stmt);
220
223
226
227 void updateStateOnAddr(const AddrStmt *addr);
228
230
231 void updateStateOnCmp(const CmpStmt *cmp);
232
233 void updateStateOnLoad(const LoadStmt *load);
234
235 void updateStateOnStore(const StoreStmt *store);
236
237 void updateStateOnCopy(const CopyStmt *copy);
238
239 void updateStateOnCall(const CallPE *callPE);
240
241 void updateStateOnRet(const RetPE *retPE);
242
243 void updateStateOnGep(const GepStmt *gep);
244
246
247 void updateStateOnPhi(const PhiStmt *phi);
248
252 AEAPI* api{nullptr};
253
257
259
261 {
262 return utils;
263 }
264
265 // helper functions in handleCallSite
266 virtual bool isExtCall(const CallICFGNode* callNode);
267 virtual void handleExtCall(const CallICFGNode* callNode);
268 virtual bool isRecursiveFun(const FunObjVar* fun);
269 virtual void skipRecursionWithTop(const CallICFGNode *callNode);
270 virtual bool isRecursiveCallSite(const CallICFGNode* callNode, const FunObjVar *);
271 virtual void handleFunCall(const CallICFGNode* callNode);
272
275 bool shouldApplyNarrowing(const FunObjVar* fun);
276
277 // there data should be shared with subclasses
278 Map<std::string, std::function<void(const CallICFGNode*)>> func_map;
279
280 AbstractStateManager* svfStateMgr{nullptr}; // state management (owns abstractTrace)
281 Set<const ICFGNode*> allAnalyzedNodes; // All nodes ever analyzed (across all entry points)
282 std::string moduleName;
283
284 std::vector<std::unique_ptr<AEDetector>> detectors;
286
287
288};
289}
copy
Definition cJSON.cpp:414
newitem prev
Definition cJSON.cpp:2285
AEStat: Statistic for AE.
Definition AEStat.h:36
Handles external API calls and manages abstract states.
Definition AbsExtAPI.h:44
AbstractInterpretation is same as Abstract Execution.
void updateStateOnCall(const CallPE *callPE)
const FunObjVar * getCallee(const CallICFGNode *callNode)
Get callee function: directly for direct calls, via pointer analysis for indirect calls.
bool isBranchFeasible(const IntraCFGEdge *edge, AbstractState &as)
Returns true if the branch is reachable; narrows as in-place.
Map< std::string, std::function< void(const CallICFGNode *)> > func_map
void updateStateOnStore(const StoreStmt *store)
bool hasAbsState(const ICFGNode *node)
bool narrowCycleState(const AbstractState &prev, const AbstractState &cur, const ICFGCycleWTO *cycle)
Narrow prev with cur; write the narrowed state back and scatter.
virtual void handleFunCall(const CallICFGNode *callNode)
void updateAbsValue(const SVFVar *var, const AbstractValue &val, const ICFGNode *node)
void analyzeFromAllProgEntries()
Analyze all entry points (functions without callers)
static AbstractInterpretation & getAEInstance()
void updateStateOnGep(const GepStmt *gep)
virtual void handleGlobalNode()
Initialize abstract state for the global ICFG node and process global statements.
void handleFunction(const ICFGNode *funEntry, const CallICFGNode *caller=nullptr)
Handle a function body via worklist-driven WTO traversal starting from funEntry.
virtual bool isExtCall(const CallICFGNode *callNode)
bool isSwitchBranchFeasible(const IntraCFGEdge *edge, AbstractState &as)
Returns true if the switch branch is feasible; narrows as in-place.
AbstractState getFullCycleHeadState(const ICFGCycleWTO *cycle)
void updateStateOnPhi(const PhiStmt *phi)
AbstractStateManager * getStateMgr()
Get the state manager instance.
bool handleICFGNode(const ICFGNode *node)
Handle an ICFG node: execute statements; return true if state changed.
std::vector< std::unique_ptr< AEDetector > > detectors
void addDetector(std::unique_ptr< AEDetector > detector)
virtual void handleExtCall(const CallICFGNode *callNode)
virtual void skipRecursionWithTop(const CallICFGNode *callNode)
bool widenCycleState(const AbstractState &prev, const AbstractState &cur, const ICFGCycleWTO *cycle)
const AbstractValue & getAbsValue(const SVFVar *var, const ICFGNode *node)
bool mergeStatesFromPredecessors(const ICFGNode *node)
void updateStateOnSelect(const SelectStmt *select)
virtual void handleSVFStatement(const SVFStmt *stmt)
Dispatch an SVF statement (Addr/Binary/Cmp/Load/Store/Copy/Gep/Select/Phi/Call/Ret) to its handler.
bool skipRecursiveCall(const CallICFGNode *callNode)
Skip recursive callsites (within SCC); entry calls from outside SCC are not skipped.
SVFIR * svfir
protected data members, also used in subclasses
virtual void runOnModule(ICFG *icfg)
virtual bool isRecursiveCallSite(const CallICFGNode *callNode, const FunObjVar *)
Check if caller and callee are in the same CallGraph SCC (i.e. a recursive callsite)
bool shouldApplyNarrowing(const FunObjVar *fun)
Check if narrowing should be applied: always for regular loops, mode-dependent for recursion.
virtual bool isRecursiveFun(const FunObjVar *fun)
Check if a function is recursive (part of a call graph SCC)
void updateStateOnAddr(const AddrStmt *addr)
virtual ~AbstractInterpretation()
Destructor.
bool hasAbsValue(const SVFVar *var, const ICFGNode *node)
virtual void handleCallSite(const ICFGNode *node)
Handle a call site node: dispatch to ext-call, direct-call, or indirect-call handling.
void updateStateOnRet(const RetPE *retPE)
void updateStateOnCopy(const CopyStmt *copy)
const AbstractState & getAbsState(const ICFGNode *node) const
void propagateObjVarAbsVal(const ObjVar *var, const ICFGNode *defSite)
Propagate an ObjVar's abstract value from defSite to all its use-sites.
std::deque< const FunObjVar * > collectProgEntryFuns()
Get all entry point functions (functions without callers)
AEAPI * api
Execution State, used to store the Interval Value of every SVF variable.
void updateStateOnLoad(const LoadStmt *load)
void updateStateOnBinary(const BinaryOPStmt *binary)
bool isCmpBranchFeasible(const IntraCFGEdge *edge, AbstractState &as)
Returns true if the cmp-conditional branch is feasible; narrows as in-place.
Set< const ICFGNode * > allAnalyzedNodes
void updateAbsState(const ICFGNode *node, const AbstractState &state)
virtual void handleLoopOrRecursion(const ICFGCycleWTO *cycle, const CallICFGNode *caller=nullptr)
Handle a WTO cycle (loop or recursive function) using widening/narrowing iteration.
const SVFVar * getSVFVar(NodeID varId) const
Retrieve SVFVar given its ID; asserts if no such variable exists.
void updateStateOnCmp(const CmpStmt *cmp)
void updateAbstractValue(const ValVar *var, const AbstractValue &val, const ICFGNode *node)
Write a top-level variable's abstract value into abstractTrace[node].
AbstractState & getAbstractState(const ICFGNode *node)
Retrieve the abstract state for a given ICFG node. Asserts if absent.
bool hasAbstractState(const ICFGNode *node)
Check if an abstract state exists for a given ICFG node.
bool hasAbstractValue(const ValVar *var, const ICFGNode *node) const
const AbstractValue & getAbstractValue(const ValVar *var, const ICFGNode *node)
void updateAbstractState(const ICFGNode *node, const AbstractState &state)
Detector for identifying buffer overflow issues.
Definition AEDetector.h:140
const SVFVar * getSVFVar(NodeID id) const
ObjVar/GepObjVar/BaseObjVar.
Definition SVFIR.h:133
for isBitcode
Definition BasicTypes.h:70
u32_t NodeID
Definition GeneralType.h:56
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76