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:
64
66
67public:
70 {
71 }
72
74
80
81 virtual ~AbstractState() = default;
82
83 // getGepObjAddrs
85
86 // initObjVar
88 // getElementIndex
90 // getByteOffset
92 // printAbstractState
93 // loadValue
95 // storeValue
97
99
100
106
108 static inline bool isVirtualMemAddress(u32_t val)
109 {
111 }
112
115 {
117 }
118
119 static inline bool isNullPtr(u32_t addr)
120 {
121 return getInternalID(addr) == 0;
122 }
123
125 {
126 if (rhs != *this)
127 {
129 _addrToAbsVal = rhs._addrToAbsVal;
130 }
131 return *this;
132 }
133
140
143 {
144 if (&rhs != this)
145 {
146 _varToAbsVal = std::move(rhs._varToAbsVal);
147 _addrToAbsVal = std::move(rhs._addrToAbsVal);
148 }
149 return *this;
150 }
151
154 {
155 AbstractState inv = *this;
156 for (auto &item: inv._varToAbsVal)
157 {
158 if (item.second.isInterval())
159 item.second.getInterval().set_to_bottom();
160 }
161 return inv;
162 }
163
166 {
167 AbstractState inv = *this;
168 for (auto &item: inv._varToAbsVal)
169 {
170 if (item.second.isInterval())
171 item.second.getInterval().set_to_top();
172 }
173 return inv;
174 }
175
178 {
180 for (u32_t id: sl)
181 {
182 inv._varToAbsVal[id] = _varToAbsVal[id];
183 }
184 return inv;
185 }
186
187protected:
191
192public:
193
194
197 {
198 return _varToAbsVal[varId];
199 }
200
202 inline virtual const AbstractValue &operator[](u32_t varId) const
203 {
204 return _varToAbsVal.at(varId);
205 }
206
208 inline bool inVarToAddrsTable(u32_t id) const
209 {
210 if (_varToAbsVal.find(id)!= _varToAbsVal.end())
211 {
212 if (_varToAbsVal.at(id).isAddr())
213 {
214 return true;
215 }
216 }
217 return false;
218 }
219
221 inline virtual bool inVarToValTable(u32_t id) const
222 {
223 if (_varToAbsVal.find(id) != _varToAbsVal.end())
224 {
225 if (_varToAbsVal.at(id).isInterval())
226 {
227 return true;
228 }
229 }
230 return false;
231 }
232
234 inline bool inAddrToAddrsTable(u32_t id) const
235 {
236 if (_addrToAbsVal.find(id)!= _addrToAbsVal.end())
237 {
238 if (_addrToAbsVal.at(id).isAddr())
239 {
240 return true;
241 }
242 }
243 return false;
244 }
245
247 inline virtual bool inAddrToValTable(u32_t id) const
248 {
249 if (_addrToAbsVal.find(id) != _addrToAbsVal.end())
250 {
251 if (_addrToAbsVal.at(id).isInterval())
252 {
253 return true;
254 }
255 }
256 return false;
257 }
258
261 {
262 return _varToAbsVal;
263 }
264
267 {
268 return _addrToAbsVal;
269 }
270
271public:
272
275
278
280 void joinWith(const AbstractState&other);
281
282
284 void meetWith(const AbstractState&other);
285
294
295
296 u32_t hash() const;
297
298public:
299 inline void store(u32_t addr, const AbstractValue &val)
300 {
301 assert(isVirtualMemAddress(addr) && "not virtual address?");
302 if (isNullPtr(addr)) return;
305 }
306
307 inline virtual AbstractValue &load(u32_t addr)
308 {
309 assert(isVirtualMemAddress(addr) && "not virtual address?");
311 return _addrToAbsVal[objId];
312
313 }
314
315
316 void printAbstractState() const;
317
318 std::string toString() const
319 {
320 return "";
321 }
322
323 bool equals(const AbstractState&other) const;
324
325
327 {
328 if (lhs.size() != rhs.size()) return false;
329 for (const auto &item: lhs)
330 {
331 auto it = rhs.find(item.first);
332 if (it == rhs.end())
333 return false;
334 if (!item.second.equals(it->second))
335 return false;
336 else
337 {
338 }
339 }
340 return true;
341 }
342
344 {
345 if (lhs.empty()) return !rhs.empty();
346 for (const auto &item: lhs)
347 {
348 auto it = rhs.find(item.first);
349 if (it == rhs.end()) return false;
350 // judge from expr id
351 if (item.second.getInterval().contain(it->second.getInterval())) return false;
352 }
353 return true;
354 }
355
356 // lhs >= rhs
358 {
359 if (rhs.empty()) return true;
360 for (const auto &item: rhs)
361 {
362 auto it = lhs.find(item.first);
363 if (it == lhs.end()) return false;
364 // judge from expr id
365 if (!it->second.getInterval().contain(
366 item.second.getInterval()))
367 return false;
368
369 }
370 return true;
371 }
372
373 bool operator==(const AbstractState&rhs) const
374 {
375 return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) &&
376 eqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
377 }
378
379 bool operator!=(const AbstractState&rhs) const
380 {
381 return !(*this == rhs);
382 }
383
384 bool operator<(const AbstractState&rhs) const
385 {
386 return !(*this >= rhs);
387 }
388
389
390 bool operator>=(const AbstractState&rhs) const
391 {
392 return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
393 }
394
395 void clear()
396 {
397 _addrToAbsVal.clear();
398 _varToAbsVal.clear();
399 }
400
401};
402
403}
404
405
406#endif //Z3_EXAMPLE_INTERVAL_DOMAIN_H
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
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
VarToAbsValMap _varToAbsVal
Map a variable (symbol) to its abstract value.
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
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
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
AbstractState()
default constructor
static bool isNullPtr(u32_t 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:55
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
unsigned u32_t
Definition GeneralType.h:46