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"
35#include "AE/Svfexe/AEWTO.h"
36#include "AE/Svfexe/AbsExtAPI.h"
37#include "AE/Svfexe/AEStat.h"
38#include "SVFIR/SVFIR.h"
39#include "Util/SVFBugReport.h"
40#include "Util/WorkList.h"
41#include "Graphs/SCC.h"
42#include "Graphs/CallGraph.h"
43
44namespace SVF
45{
46class AbstractInterpretation;
47class AbsExtAPI;
48class AEStat;
49class AEAPI;
50class AndersenWaveDiff;
51
52template<typename T> class FILOWorkList;
53
61{
62 friend class AEStat;
63 friend class AEAPI;
64 friend class BufOverflowDetector;
66
67public:
68 /*
69 * For recursive test case
70 * int demo(int a) {
71 if (a >= 10000)
72 return a;
73 demo(a+1);
74 }
75
76 int main() {
77 int result = demo(0);
78 }
79 * 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.
80 * if set WIDEN_ONLY, result = [10000, +oo] since only widening is applied at the cycle head of recursive functions without narrowing.
81 * if set WIDEN_NARROW, result = [10000, 10000] since both widening and narrowing are applied at the cycle head of recursive functions.
82 * */
89
96
102
103 virtual void runOnModule();
104
106 virtual ~AbstractInterpretation();
107
109 void analyse();
110
113
116
123
124 void addDetector(std::unique_ptr<AEDetector> detector)
125 {
126 detectors.push_back(std::move(detector));
127 }
128
130 inline const SVFVar* getSVFVar(NodeID varId) const
131 {
132 return svfir->getSVFVar(varId);
133 }
134
135 // ---- Abstract Value Access ----------------------------------------
136
142 virtual const AbstractValue& getAbsValue(const ValVar* var, const ICFGNode* node);
143 virtual const AbstractValue& getAbsValue(const ObjVar* var, const ICFGNode* node);
144 virtual const AbstractValue& getAbsValue(const SVFVar* var, const ICFGNode* node);
145
147 virtual bool hasAbsValue(const ValVar* var, const ICFGNode* node) const;
148 virtual bool hasAbsValue(const ObjVar* var, const ICFGNode* node) const;
149 virtual bool hasAbsValue(const SVFVar* var, const ICFGNode* node) const;
150
153 virtual void updateAbsValue(const ValVar* var, const AbstractValue& val, const ICFGNode* node);
154 virtual void updateAbsValue(const ObjVar* var, const AbstractValue& val, const ICFGNode* node);
155 virtual void updateAbsValue(const SVFVar* var, const AbstractValue& val, const ICFGNode* node);
156
157 // ---- State Access -------------------------------------------------
158
159 AbstractState& getAbsState(const ICFGNode* node);
160
163 virtual void updateAbsState(const ICFGNode* node, const AbstractState& state);
164
167 virtual void joinStates(AbstractState& dst, const AbstractState& src);
168
169 bool hasAbsState(const ICFGNode* node);
170
174
175 // ---- GEP / Load-Store / Type Helpers ------------------------------
176
180
182 virtual AbstractValue loadValue(const ValVar* pointer,
183 const ICFGNode* node);
184 virtual void storeValue(const ValVar* pointer, const AbstractValue& val,
185 const ICFGNode* node);
186
187 const SVFType* getPointeeElement(const ObjVar* var, const ICFGNode* node);
189
190 // ---- Direct Trace Access ------------------------------------------
191
197 {
198 return abstractTrace[node];
199 }
200
201protected:
205
206 // ---- Cycle helpers overridden by SparseAbstractInterpretation ----
207 // The dense versions write only to trace[cycle_head]. The semi-sparse
208 // subclass adds def-site scatter on top for body ValVars.
209
213
217 virtual bool widenCycleState(const AbstractState& prev, const AbstractState& cur,
218 const ICFGCycleWTO* cycle);
219
223 virtual bool narrowCycleState(const AbstractState& prev, const AbstractState& cur,
224 const ICFGCycleWTO* cycle);
225
226protected:
232 virtual bool mergeStatesFromPredecessors(const ICFGNode* node);
233
237
241
249 const IntervalValue& narrowed,
251 const ICFGNode* loadIcfg,
252 const ICFGNode* succ);
253
254private:
257 virtual void handleGlobalNode();
258
260 virtual void handleCallSite(const ICFGNode* node);
261
263 virtual void handleLoopOrRecursion(const ICFGCycleWTO* cycle, const CallICFGNode* caller);
264
267
269 bool handleICFGNode(const ICFGNode* node);
270
272 virtual void handleSVFStatement(const SVFStmt* stmt);
273
276
280
281 void updateStateOnAddr(const AddrStmt *addr);
282
284
285 void updateStateOnCmp(const CmpStmt *cmp);
286
287 void updateStateOnLoad(const LoadStmt *load);
288
289 void updateStateOnStore(const StoreStmt *store);
290
291 void updateStateOnCopy(const CopyStmt *copy);
292
293 void updateStateOnCall(const CallPE *callPE);
294
295 void updateStateOnRet(const RetPE *retPE);
296
297 void updateStateOnGep(const GepStmt *gep);
298
300
301 void updateStateOnPhi(const PhiStmt *phi);
302
304 AEAPI* api{nullptr};
305
309
311 {
312 return utils;
313 }
314
315 // helper functions in handleCallSite
316 virtual bool isExtCall(const CallICFGNode* callNode);
317 virtual void handleExtCall(const CallICFGNode* callNode);
318 virtual bool isRecursiveFun(const FunObjVar* fun);
319 virtual void skipRecursionWithTop(const CallICFGNode *callNode);
320 virtual bool isRecursiveCallSite(const CallICFGNode* callNode, const FunObjVar *);
321 virtual void handleFunCall(const CallICFGNode* callNode);
322
325
326 // there data should be shared with subclasses
327 Map<std::string, std::function<void(const CallICFGNode*)>> func_map;
328
329 Set<const ICFGNode*> allAnalyzedNodes; // All nodes ever analyzed (across all entry points)
330 std::string moduleName;
331
332 std::vector<std::unique_ptr<AEDetector>> detectors;
334
335protected:
337 SVFIR* svfir{nullptr};
340
341 bool shouldApplyNarrowing(const FunObjVar* fun);
342};
343} // namespace SVF
copy
Definition cJSON.cpp:414
newitem prev
Definition cJSON.cpp:2285
buffer offset
Definition cJSON.cpp:1113
AEStat: Statistic for AE.
Definition AEStat.h:36
Handles external API calls and manages abstract states.
Definition AbsExtAPI.h:43
void handleFunction(const ICFGNode *funEntry, const CallICFGNode *caller)
Handle a function body via worklist-driven WTO traversal starting from funEntry.
void updateStateOnCall(const CallPE *callPE)
const FunObjVar * getCallee(const CallICFGNode *callNode)
Get callee function: directly for direct calls, via pointer analysis for indirect calls.
AbstractState & getAbsState(const ICFGNode *node)
u32_t getAllocaInstByteSize(const AddrStmt *addr)
Map< std::string, std::function< void(const CallICFGNode *)> > func_map
void updateStateOnStore(const StoreStmt *store)
virtual bool narrowCycleState(const AbstractState &prev, const AbstractState &cur, const ICFGCycleWTO *cycle)
virtual void handleFunCall(const CallICFGNode *callNode)
void analyzeFromAllProgEntries()
Analyze all entry points (functions without callers)
void updateStateOnGep(const GepStmt *gep)
bool isCmpBranchEdgeFeasible(const IntraCFGEdge *edge, AbstractState &as)
Returns true if the cmp-conditional branch is feasible.
virtual bool hasAbsValue(const ValVar *var, const ICFGNode *node) const
Side-effect-free existence check.
virtual bool isExtCall(const CallICFGNode *callNode)
AbstractState & operator[](const ICFGNode *node)
virtual AbstractState getFullCycleHeadState(const ICFGCycleWTO *cycle)
void updateStateOnPhi(const PhiStmt *phi)
bool handleICFGNode(const ICFGNode *node)
Handle an ICFG node: execute statements; return true if state changed.
IntervalValue getGepByteOffset(const GepStmt *gep)
std::vector< std::unique_ptr< AEDetector > > detectors
void addDetector(std::unique_ptr< AEDetector > detector)
virtual AbstractValue loadValue(const ValVar *pointer, const ICFGNode *node)
Virtual so full-sparse can layer the GepObj overlay on top.
virtual void handleExtCall(const CallICFGNode *callNode)
Map< const ICFGNode *, AbstractState > & getTrace()
bool isBranchEdgeFeasible(const IntraCFGEdge *edge, AbstractState &as)
AddressValue getGepObjAddrs(const ValVar *pointer, IntervalValue offset)
virtual void skipRecursionWithTop(const CallICFGNode *callNode)
virtual bool widenCycleState(const AbstractState &prev, const AbstractState &cur, const ICFGCycleWTO *cycle)
IntervalValue getGepElementIndex(const GepStmt *gep)
virtual void joinStates(AbstractState &dst, const AbstractState &src)
virtual 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
Data and helpers reachable from SparseAbstractInterpretation.
virtual bool isRecursiveCallSite(const CallICFGNode *callNode, const FunObjVar *)
Check if caller and callee are in the same CallGraph SCC (i.e. a recursive callsite)
virtual void handleLoopOrRecursion(const ICFGCycleWTO *cycle, const CallICFGNode *caller)
Handle a WTO cycle (loop or recursive function) using widening/narrowing iteration.
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.
virtual const AbstractValue & getAbsValue(const ValVar *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 collectBranchRefinement(const IntraCFGEdge *edge, AbstractState &as)
void updateStateOnRet(const RetPE *retPE)
bool hasAbsState(const ICFGNode *node)
void updateStateOnCopy(const CopyStmt *copy)
FIFOWorkList< 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.
const SVFType * getPointeeElement(const ObjVar *var, const ICFGNode *node)
bool isSwitchBranchEdgeFeasible(const IntraCFGEdge *edge, AbstractState &as)
Returns true if the switch branch is feasible.
void updateStateOnLoad(const LoadStmt *load)
void updateStateOnBinary(const BinaryOPStmt *binary)
Map< const ICFGNode *, AbstractState > abstractTrace
per-node trace; owned here
static AbstractInterpretation & getAEInstance()
virtual void recordBranchRefinement(NodeID objId, const IntervalValue &narrowed, AbstractState &as, const ICFGNode *loadIcfg, const ICFGNode *succ)
virtual void updateAbsValue(const ValVar *var, const AbstractValue &val, const ICFGNode *node)
Set< const ICFGNode * > allAnalyzedNodes
virtual void storeValue(const ValVar *pointer, const AbstractValue &val, const ICFGNode *node)
const SVFVar * getSVFVar(NodeID varId) const
Retrieve SVFVar given its ID; asserts if no such variable exists.
void updateStateOnCmp(const CmpStmt *cmp)
virtual void updateAbsState(const ICFGNode *node, const AbstractState &state)
Detector for identifying buffer overflow issues.
Definition AEDetector.h:139
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
unsigned u32_t
Definition GeneralType.h:47