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/AbsExtAPI.h"
36#include "Util/SVFBugReport.h"
37#include "Util/SVFStat.h"
38#include "Graphs/SCC.h"
39#include "Graphs/CallGraph.h"
40#include <deque>
41
42namespace SVF
43{
44class AbstractInterpretation;
45class AbsExtAPI;
46class AEStat;
47class AEAPI;
48
49template<typename T> class FILOWorkList;
50
52class AEStat : public SVFStat
53{
54public:
55 void countStateSize();
61 {
62 }
63 inline std::string getMemUsage()
64 {
66 return SVFUtil::getMemoryUsageKB(&vmrss, &vmsize) ? std::to_string(vmsize) + "KB" : "cannot read memory usage";
67 }
68
69 void finializeStat();
70 void performStat() override;
71
72public:
75 std::string memory_usage;
76 std::string memUsage;
77
78
80 {
81 if (generalNumMap.count("Function_Trace") == 0)
82 {
83 generalNumMap["Function_Trace"] = 0;
84 }
85 return generalNumMap["Function_Trace"];
86 }
88 {
89 if (generalNumMap.count("Block_Trace") == 0)
90 {
91 generalNumMap["Block_Trace"] = 0;
92 }
93 return generalNumMap["Block_Trace"];
94 }
96 {
97 if (generalNumMap.count("ICFG_Node_Trace") == 0)
98 {
99 generalNumMap["ICFG_Node_Trace"] = 0;
100 }
101 return generalNumMap["ICFG_Node_Trace"];
102 }
103};
104
107{
108 friend class AEStat;
109 friend class AEAPI;
112
113public:
115
116 /*
117 * For recursive test case
118 * int demo(int a) {
119 if (a >= 10000)
120 return a;
121 demo(a+1);
122 }
123
124 int main() {
125 int result = demo(0);
126 }
127 * 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.
128 * if set WIDEN_ONLY, result = [10000, +oo] since only widening is applied at the cycle head of recursive functions without narrowing.
129 * if set WIDEN_NARROW, result = [10000, 10000] since both widening and narrowing are applied at the cycle head of recursive functions.
130 * */
137
140
141 virtual void runOnModule(ICFG* icfg);
142
144 virtual ~AbstractInterpretation();
145
147 void analyse();
148
151
153 std::deque<const FunObjVar*> collectProgEntryFuns();
154
155
157 {
159 return instance;
160 }
161
162 void addDetector(std::unique_ptr<AEDetector> detector)
163 {
164 detectors.push_back(std::move(detector));
165 }
166
168
176 {
177 if (abstractTrace.count(node) == 0)
178 {
179 assert(false && "No preAbsTrace for this node");
180 abort();
181 }
182 else
183 {
184 return abstractTrace[node];
185 }
186 }
187
188private:
190 virtual void handleGlobalNode();
191
193 void initWTO();
194
201 bool mergeStatesFromPredecessors(const ICFGNode * icfgNode);
202
210
217
223 virtual void handleCallSite(const ICFGNode* node);
224
230 virtual void handleLoopOrRecursion(const ICFGCycleWTO* cycle, const CallICFGNode* caller = nullptr);
231
237 void handleFunction(const ICFGNode* funEntry, const CallICFGNode* caller = nullptr);
238
245 bool handleICFGNode(const ICFGNode* node);
246
253 std::vector<const ICFGNode*> getNextNodes(const ICFGNode* node) const;
254
261 std::vector<const ICFGNode*> getNextNodesOfCycle(const ICFGCycleWTO* cycle) const;
262
268 void collectCycleHeads(const std::list<const ICFGWTOComp*>& comps);
269
270
276 virtual void handleSVFStatement(const SVFStmt* stmt);
277
278 virtual void setTopToObjInRecursion(const CallICFGNode* callnode);
279
280
290
300
301
302 void collectCheckPoint();
303 void checkPointAllSet();
304
305 void updateStateOnAddr(const AddrStmt *addr);
306
308
309 void updateStateOnCmp(const CmpStmt *cmp);
310
311 void updateStateOnLoad(const LoadStmt *load);
312
313 void updateStateOnStore(const StoreStmt *store);
314
315 void updateStateOnCopy(const CopyStmt *copy);
316
317 void updateStateOnCall(const CallPE *callPE);
318
319 void updateStateOnRet(const RetPE *retPE);
320
321 void updateStateOnGep(const GepStmt *gep);
322
324
325 void updateStateOnPhi(const PhiStmt *phi);
326
327
331 AEAPI* api{nullptr};
332
336
341
342
344 {
345 return abstractTrace.count(node) != 0;
346 }
347
349 {
350 return utils;
351 }
352
353 // helper functions in handleCallSite
354 virtual bool isExtCall(const CallICFGNode* callNode);
355 virtual void handleExtCall(const CallICFGNode* callNode);
356 virtual bool isRecursiveFun(const FunObjVar* fun);
357 virtual bool isRecursiveCall(const CallICFGNode* callNode);
358 virtual void recursiveCallPass(const CallICFGNode *callNode);
359 virtual bool isRecursiveCallSite(const CallICFGNode* callNode, const FunObjVar *);
360 virtual void handleFunCall(const CallICFGNode* callNode);
361
364 bool shouldApplyNarrowing(const FunObjVar* fun);
365
366 // there data should be shared with subclasses
367 Map<std::string, std::function<void(const CallICFGNode*)>> func_map;
368
369 Map<const ICFGNode*, AbstractState> abstractTrace; // abstract states immediately after nodes
370 Set<const ICFGNode*> allAnalyzedNodes; // All nodes ever analyzed (across all entry points)
371 std::string moduleName;
372
373 std::vector<std::unique_ptr<AEDetector>> detectors;
375
376 // according to varieties of cmp insts,
377 // maybe var X var, var X const, const X var, const X const
378 // we accept 'var X const' 'var X var' 'const X const'
379 // if 'const X var', we need to reverse op0 op1 and its predicate 'var X' const'
380 // X' is reverse predicate of X
381 // == -> !=, != -> ==, > -> <=, >= -> <, < -> >=, <= -> >
382
402
403
423
424};
425}
copy
Definition cJSON.cpp:414
AEStat: Statistic for AE.
std::string memory_usage
void performStat() override
AEStat(AbstractInterpretation *ae)
std::string getMemUsage()
AbstractInterpretation * _ae
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.
std::vector< const ICFGNode * > getNextNodesOfCycle(const ICFGCycleWTO *cycle) const
virtual bool isRecursiveCall(const CallICFGNode *callNode)
Check if a call node calls a recursive function.
virtual void recursiveCallPass(const CallICFGNode *callNode)
Handle recursive call in TOP mode: set all stores and return value to TOP.
Map< std::string, std::function< void(const CallICFGNode *)> > func_map
void updateStateOnStore(const StoreStmt *store)
bool hasAbsStateFromTrace(const ICFGNode *node)
void collectCycleHeads(const std::list< const ICFGWTOComp * > &comps)
Recursively collect cycle heads from nested WTO components.
virtual void handleFunCall(const CallICFGNode *callNode)
void analyzeFromAllProgEntries()
Analyze all entry points (functions without callers)
static AbstractInterpretation & getAEInstance()
Set< const FunObjVar * > recursiveFuns
void updateStateOnGep(const GepStmt *gep)
virtual void handleGlobalNode()
Global ICFGNode is handled at the entry of the program,.
bool mergeStatesFromPredecessors(const ICFGNode *icfgNode)
void handleFunction(const ICFGNode *funEntry, const CallICFGNode *caller=nullptr)
virtual bool isExtCall(const CallICFGNode *callNode)
void initWTO()
Compute IWTO for each function partition entry.
void updateStateOnPhi(const PhiStmt *phi)
bool handleICFGNode(const ICFGNode *node)
bool isBranchFeasible(const IntraCFGEdge *intraEdge, AbstractState &as)
std::vector< std::unique_ptr< AEDetector > > detectors
void addDetector(std::unique_ptr< AEDetector > detector)
std::vector< const ICFGNode * > getNextNodes(const ICFGNode *node) const
virtual void handleExtCall(const CallICFGNode *callNode)
AbstractState & getAbsStateFromTrace(const ICFGNode *node)
Retrieves the abstract state from the trace for a given ICFG node.
Set< const CallICFGNode * > checkpoints
bool isSwitchBranchFeasible(const SVFVar *var, s64_t succ, AbstractState &as)
void updateStateOnSelect(const SelectStmt *select)
virtual void handleSVFStatement(const SVFStmt *stmt)
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 a call is a recursive callsite (within same SCC, not entry call from outside)
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 isCmpBranchFeasible(const CmpStmt *cmpStmt, s64_t succ, AbstractState &as)
Map< const ICFGNode *, const ICFGCycleWTO * > cycleHeadToCycle
virtual void handleCallSite(const ICFGNode *node)
void updateStateOnRet(const RetPE *retPE)
void updateStateOnCopy(const CopyStmt *copy)
Set< std::pair< const CallICFGNode *, NodeID > > nonRecursiveCallSites
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)
Map< const ICFGNode *, AbstractState > abstractTrace
SCCDetection< CallGraph * > CallGraphSCC
Set< const ICFGNode * > allAnalyzedNodes
virtual void handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto)
handle instructions in svf basic blocks
virtual void setTopToObjInRecursion(const CallICFGNode *callnode)
Set all store values in a recursive function to TOP (used in TOP mode)
virtual void handleLoopOrRecursion(const ICFGCycleWTO *cycle, const CallICFGNode *caller=nullptr)
Map< s32_t, s32_t > _switch_lhsrhs_predicate
void updateStateOnCmp(const CmpStmt *cmp)
Map< const FunObjVar *, const ICFGWTO * > funcToWTO
Detector for identifying buffer overflow issues.
Definition AEDetector.h:136
@ ICMP_SGT
signed greater than
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ ICMP_NE
not equal
@ ICMP_ULT
unsigned less than
@ ICMP_SLT
signed less than
@ ICMP_UGT
unsigned greater than
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_SLE
signed less or equal
NUMStatMap generalNumMap
Definition SVFStat.h:76
double startTime
Definition SVFStat.h:80
static double getClk(bool mark=false)
Definition SVFStat.cpp:48
bool getMemoryUsageKB(u32_t *vmrss_kb, u32_t *vmsize_kb)
Get memory usage from system file. Return TRUE if succeed.
Definition SVFUtil.cpp:179
for isBitcode
Definition BasicTypes.h:68
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
signed s32_t
Definition GeneralType.h:48
unsigned u32_t
Definition GeneralType.h:47
signed long long s64_t
Definition GeneralType.h:50