Static Value-Flow Analysis
Loading...
Searching...
No Matches
AbstractState.h
Go to the documentation of this file.
1//===- AbstractExeState.h ----Interval Domain-------------------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2022> <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 * IntervalExeState.h
24 *
25 * Created on: Jul 9, 2022
26 * Author: Xiao Cheng, Jiawei Wang
27 *
28 * [-oo,+oo]
29 * / / \ \
30 * [-oo,1] ... [-oo,10] ... [-1,+oo] ... [0,+oo]
31 * \ \ / /
32 * \ [-1,10] /
33 * \ / \ /
34 * ... [-1,1] ... [0,10] ...
35 * \ | \ / \ /
36 * ... [-1,0] [0,1] ... [1,9] ...
37 * \ | \ | \ /
38 * ... [-1,-1] [0,0] [1,1] ...
39 * \ \ \ / /
40 * ⊥
41 */
42// The implementation is based on
43// Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction.
44// 46th International Conference on Software Engineering. (ICSE24)
45
46#ifndef Z3_EXAMPLE_INTERVAL_DOMAIN_H
47#define Z3_EXAMPLE_INTERVAL_DOMAIN_H
48
51#include "SVFIR/SVFVariables.h"
52#include "Util/Z3Expr.h"
53
54#include <iomanip>
55
56namespace SVF
57{
59{
60 friend class SVFIR2AbsState;
61 friend class RelationSolver;
62public:
66
67
68public:
71 {
72 }
73
75
81
82 virtual ~AbstractState() = default;
83
84 // getGepObjAddrs
86
87 // initObjVar
89 // getElementIndex
91 // getByteOffset
93 // printAbstractState
94 // loadValue
96 // storeValue
98
100
101
107
109 static inline bool isVirtualMemAddress(u32_t val)
110 {
112 }
113
119
121 {
122 if (rhs != *this)
123 {
125 _addrToAbsVal = rhs._addrToAbsVal;
126 _freedAddrs = rhs._freedAddrs;
127 }
128 return *this;
129 }
130
137
140 {
141 if (&rhs != this)
142 {
143 _varToAbsVal = std::move(rhs._varToAbsVal);
144 _addrToAbsVal = std::move(rhs._addrToAbsVal);
145 _freedAddrs = std::move(rhs._freedAddrs);
146 }
147 return *this;
148 }
149
152 {
153 AbstractState inv = *this;
154 for (auto &item: inv._varToAbsVal)
155 {
156 if (item.second.isInterval())
157 item.second.getInterval().set_to_bottom();
158 }
159 return inv;
160 }
161
164 {
165 AbstractState inv = *this;
166 for (auto &item: inv._varToAbsVal)
167 {
168 if (item.second.isInterval())
169 item.second.getInterval().set_to_top();
170 }
171 return inv;
172 }
173
176 {
178 for (u32_t id: sl)
179 {
180 inv._varToAbsVal[id] = _varToAbsVal[id];
181 }
182 return inv;
183 }
184
185 static inline bool isNullMem(u32_t addr)
186 {
188 }
189
190 static inline bool isInvalidMem(u32_t addr)
191 {
193 }
194
195
196protected:
200
201public:
202
203
206 {
207 return _varToAbsVal[varId];
208 }
209
211 inline virtual const AbstractValue &operator[](u32_t varId) const
212 {
213 return _varToAbsVal.at(varId);
214 }
215
217 inline bool inVarToAddrsTable(u32_t id) const
218 {
219 if (_varToAbsVal.find(id)!= _varToAbsVal.end())
220 {
221 if (_varToAbsVal.at(id).isAddr())
222 {
223 return true;
224 }
225 }
226 return false;
227 }
228
230 inline virtual bool inVarToValTable(u32_t id) const
231 {
232 if (_varToAbsVal.find(id) != _varToAbsVal.end())
233 {
234 if (_varToAbsVal.at(id).isInterval())
235 {
236 return true;
237 }
238 }
239 return false;
240 }
241
243 inline bool inAddrToAddrsTable(u32_t id) const
244 {
245 if (_addrToAbsVal.find(id)!= _addrToAbsVal.end())
246 {
247 if (_addrToAbsVal.at(id).isAddr())
248 {
249 return true;
250 }
251 }
252 return false;
253 }
254
256 inline virtual bool inAddrToValTable(u32_t id) const
257 {
258 if (_addrToAbsVal.find(id) != _addrToAbsVal.end())
259 {
260 if (_addrToAbsVal.at(id).isInterval())
261 {
262 return true;
263 }
264 }
265 return false;
266 }
267
270 {
271 return _varToAbsVal;
272 }
273
276 {
277 return _addrToAbsVal;
278 }
279
280public:
281
284
287
289 void joinWith(const AbstractState&other);
290
292 void meetWith(const AbstractState&other);
293
295 {
296 _freedAddrs.insert(addr);
297 }
298
300 {
301 return _freedAddrs.find(addr) != _freedAddrs.end();
302 }
303
304
313
314
315 u32_t hash() const;
316
317public:
318 inline void store(u32_t addr, const AbstractValue &val)
319 {
320 assert(isVirtualMemAddress(addr) && "not virtual address?");
322 if (isNullMem(addr)) return;
324 }
325
326 inline virtual AbstractValue &load(u32_t addr)
327 {
328 assert(isVirtualMemAddress(addr) && "not virtual address?");
330 return _addrToAbsVal[objId];
331
332 }
333
334 void printAbstractState() const;
335
336 std::string toString() const
337 {
338 return "";
339 }
340
341 bool equals(const AbstractState&other) const;
342
343
345 {
346 if (lhs.size() != rhs.size()) return false;
347 for (const auto &item: lhs)
348 {
349 auto it = rhs.find(item.first);
350 if (it == rhs.end())
351 return false;
352 if (!item.second.equals(it->second))
353 return false;
354 else
355 {
356 }
357 }
358 return true;
359 }
360
362 {
363 if (lhs.empty()) return !rhs.empty();
364 for (const auto &item: lhs)
365 {
366 auto it = rhs.find(item.first);
367 if (it == rhs.end()) return false;
368 // judge from expr id
369 if (item.second.getInterval().contain(it->second.getInterval())) return false;
370 }
371 return true;
372 }
373
374 // lhs >= rhs
376 {
377 if (rhs.empty()) return true;
378 for (const auto &item: rhs)
379 {
380 auto it = lhs.find(item.first);
381 if (it == lhs.end()) return false;
382 // judge from expr id
383 if (!it->second.getInterval().contain(
384 item.second.getInterval()))
385 return false;
386
387 }
388 return true;
389 }
390
391 bool operator==(const AbstractState&rhs) const
392 {
393 return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) &&
394 eqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
395 }
396
397 bool operator!=(const AbstractState&rhs) const
398 {
399 return !(*this == rhs);
400 }
401
402 bool operator<(const AbstractState&rhs) const
403 {
404 return !(*this >= rhs);
405 }
406
407
408 bool operator>=(const AbstractState&rhs) const
409 {
410 return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
411 }
412
413 void clear()
414 {
415 _addrToAbsVal.clear();
416 _varToAbsVal.clear();
417 _freedAddrs.clear();
418 }
419
420};
421
422}
423
424
425#endif //Z3_EXAMPLE_INTERVAL_DOMAIN_H
#define InvalidMemAddr
#define NullMemAddr
buffer offset
Definition cJSON.cpp:1113
cJSON * item
Definition cJSON.h:222
const AddrToAbsValMap & getLocToVal() const
get loc2val map
u32_t getAllocaInstByteSize(const AddrStmt *addr)
const VarToAbsValMap & getVarToVal() const
get var2val map
static bool geqVarToValMap(const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)
bool operator>=(const AbstractState &rhs) const
void store(u32_t addr, const AbstractValue &val)
friend class SVFIR2AbsState
static bool isNullMem(u32_t addr)
AbstractState bottom() const
Set all value bottom.
virtual bool inAddrToValTable(u32_t id) const
whether the memory address stores abstract value
void printAbstractState() const
bool inAddrToAddrsTable(u32_t id) const
whether the memory address stores memory addresses
void joinWith(const AbstractState &other)
domain join with other, important! other widen this.
AbstractState(const AbstractState &rhs)
copy constructor
bool operator!=(const AbstractState &rhs) const
virtual const AbstractValue & operator[](u32_t varId) const
get abstract value of variable
IntervalValue getElementIndex(const GepStmt *gep)
bool equals(const AbstractState &other) const
AbstractState(AbstractState &&rhs)
move constructor
static bool isInvalidMem(u32_t addr)
VarToAbsValMap _varToAbsVal
Map a variable (symbol) to its abstract value.
bool isFreedMem(u32_t addr) const
Set< NodeID > _freedAddrs
std::string toString() const
AddrToAbsValMap _addrToAbsVal
Map a memory address to its stored abstract value.
const SVFType * getPointeeElement(NodeID id)
AbstractState & operator=(AbstractState &&rhs)
operator= move constructor
static bool lessThanVarToValMap(const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)
virtual AbstractValue & load(u32_t addr)
AbstractState(VarToAbsValMap &_varToValMap, AddrToAbsValMap &_locToValMap)
IntervalValue getByteOffset(const GepStmt *gep)
AbstractValue loadValue(NodeID varId)
bool inVarToAddrsTable(u32_t id) const
whether the variable is in varToAddrs table
u32_t getIDFromAddr(u32_t addr)
Return the internal index if addr is an address otherwise return the value of idx.
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
virtual AbstractValue & operator[](u32_t varId)
get abstract value of variable
AbstractState narrowing(const AbstractState &other)
domain narrow with other, and return the narrowed domain
AbstractState()
default constructor
void addToFreedAddrs(NodeID addr)
virtual bool inVarToValTable(u32_t id) const
whether the variable is in varToVal table
Map< u32_t, AbstractValue > VarToAbsValMap
virtual ~AbstractState()=default
VarToAbsValMap AddrToAbsValMap
AbstractState top() const
Set all value top.
bool operator==(const AbstractState &rhs) const
AbstractState & operator=(const AbstractState &rhs)
static bool isVirtualMemAddress(u32_t val)
Check bit value of val start with 0x7F000000, filter by 0xFF000000.
void storeValue(NodeID varId, AbstractValue val)
static bool eqVarToValMap(const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)
void meetWith(const AbstractState &other)
domain meet with other, important! other widen this.
bool operator<(const AbstractState &rhs) const
AddressValue getGepObjAddrs(u32_t pointer, IntervalValue offset)
AbstractState sliceState(Set< u32_t > &sl)
Copy some values and return a new IntervalExeState.
void initObjVar(ObjVar *objVar)
AbstractState widening(const AbstractState &other)
domain widen with other, and return the widened domain
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
static bool isVirtualMemAddress(u32_t val)
Check bit value of val start with 0x7F000000, filter by 0xFF000000.
for isBitcode
Definition BasicTypes.h:68
u32_t NodeID
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned u32_t
Definition GeneralType.h:47