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
53namespace SVF
54{
56{
57 friend class SVFIR2AbsState;
58 friend class RelationSolver;
59public:
64 {
65 }
66
68
74
75 virtual ~AbstractState() = default;
76
77 // getGepObjAddrs
79
80 // initObjVar
81 void initObjVar(const ObjVar* objVar);
82 // getElementIndex
84 // getByteOffset
86 // printAbstractState
87 // loadValue
89 // storeValue
91
93
94
100
102 static inline bool isVirtualMemAddress(u32_t val)
103 {
105 }
106
112
115 _addrToAbsVal(std::move(rhs._addrToAbsVal)),
116 _freedAddrs(std::move(rhs._freedAddrs))
117 {
118
119 }
120
123 {
124 AbstractState inv = *this;
125 for (auto &item: inv._varToAbsVal)
126 {
127 if (item.second.isInterval())
128 item.second.getInterval().set_to_bottom();
129 }
130 return inv;
131 }
132
135 {
136 AbstractState inv = *this;
137 for (auto &item: inv._varToAbsVal)
138 {
139 if (item.second.isInterval())
140 item.second.getInterval().set_to_top();
141 }
142 return inv;
143 }
144
147 {
149 for (u32_t id: sl)
150 inv._varToAbsVal[id] = _varToAbsVal[id];
151 return inv;
152 }
153
154 static inline bool isNullMem(u32_t addr)
155 {
156 return addr == NullMemAddr;
157 }
158
159 static inline bool isBlackHoleObjAddr(u32_t addr)
160 {
161 return addr == BlackHoleObjAddr;
162 }
163
164
165protected:
169
170public:
171
172
175 {
176 assert(!isVirtualMemAddress(varId) && "varId is a virtual memory address, use load() instead");
177 return _varToAbsVal[varId];
178 }
179
181 inline virtual const AbstractValue &operator[](u32_t varId) const
182 {
183 assert(!isVirtualMemAddress(varId) && "varId is a virtual memory address, use load() instead");
184 return _varToAbsVal.at(varId);
185 }
186
187 inline virtual AbstractValue &load(u32_t addr)
188 {
189 assert(isVirtualMemAddress(addr) && "not virtual address?");
191 return _addrToAbsVal[objId];
192 }
193
194 inline virtual const AbstractValue &load(u32_t addr) const
195 {
196 assert(isVirtualMemAddress(addr) && "not virtual address?");
198 return _addrToAbsVal.at(objId);
199 }
200
201 inline void store(u32_t addr, const AbstractValue &val)
202 {
203 assert(isVirtualMemAddress(addr) && "not virtual address?");
205 if (isNullMem(addr)) return;
207 }
208
210 inline bool inVarToAddrsTable(u32_t id) const
211 {
212 if (_varToAbsVal.find(id)!= _varToAbsVal.end())
213 {
214 if (_varToAbsVal.at(id).isAddr())
215 return true;
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 return true;
227 }
228 return false;
229 }
230
232 inline bool inAddrToAddrsTable(u32_t id) const
233 {
234 if (_addrToAbsVal.find(id)!= _addrToAbsVal.end())
235 {
236 if (_addrToAbsVal.at(id).isAddr())
237 {
238 return true;
239 }
240 }
241 return false;
242 }
243
245 inline virtual bool inAddrToValTable(u32_t id) const
246 {
247 if (_addrToAbsVal.find(id) != _addrToAbsVal.end())
248 {
249 if (_addrToAbsVal.at(id).isInterval())
250 {
251 return true;
252 }
253 }
254 return false;
255 }
256
258 inline const VarToAbsValMap&getVarToVal() const
259 {
260 return _varToAbsVal;
261 }
262
264 inline const AddrToAbsValMap&getLocToVal() const
265 {
266 return _addrToAbsVal;
267 }
268
271
274
276 void joinWith(const AbstractState&other);
277
279 void meetWith(const AbstractState&other);
280
282 {
283 _freedAddrs.insert(addr);
284 }
285
287 {
288 return _freedAddrs.find(addr) != _freedAddrs.end();
289 }
290
291
300
301 void printAbstractState() const;
302
303 std::string toString() const;
304
305 u32_t hash() const;
306
307 // lhs == rhs for varToValMap
308 bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) const;
309 // lhs >= rhs for varToValMap
310 bool geqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) const;
311 // lhs == rhs for AbstractState
312 bool equals(const AbstractState&other) const;
313
316 {
317 if (&rhs != this)
318 {
320 _addrToAbsVal = rhs._addrToAbsVal;
321 _freedAddrs = rhs._freedAddrs;
322 }
323 return *this;
324 }
325
328 {
329 if (&rhs != this)
330 {
331 _varToAbsVal = std::move(rhs._varToAbsVal);
332 _addrToAbsVal = std::move(rhs._addrToAbsVal);
333 _freedAddrs = std::move(rhs._freedAddrs);
334 }
335 return *this;
336 }
337
338 bool operator==(const AbstractState&rhs) const
339 {
340 return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) &&
341 eqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
342 }
343
344 bool operator!=(const AbstractState&rhs) const
345 {
346 return !(*this == rhs);
347 }
348
349 bool operator<(const AbstractState&rhs) const
350 {
351 return !(*this >= rhs);
352 }
353
354 bool operator>=(const AbstractState&rhs) const
355 {
356 return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
357 }
358
359 void clear()
360 {
361 _addrToAbsVal.clear();
362 _varToAbsVal.clear();
363 _freedAddrs.clear();
364 }
365
366};
367
368}
369
370
371#endif //Z3_EXAMPLE_INTERVAL_DOMAIN_H
#define NullMemAddr
#define BlackHoleObjAddr
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
u32_t getIDFromAddr(u32_t addr) const
Return the internal index if addr is an address otherwise return the value of idx.
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
std::string toString() const
void printAbstractState() const
bool inAddrToAddrsTable(u32_t id) const
whether the memory address stores memory addresses
virtual const AbstractValue & load(u32_t addr) const
void joinWith(const AbstractState &other)
domain join with other, important! other widen this.
static bool isBlackHoleObjAddr(u32_t addr)
bool eqVarToValMap(const VarToAbsValMap &lhs, const VarToAbsValMap &rhs) const
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
bool geqVarToValMap(const VarToAbsValMap &lhs, const VarToAbsValMap &rhs) const
AbstractState(AbstractState &&rhs)
move constructor
VarToAbsValMap _varToAbsVal
Map a variable (symbol) to its abstract value.
bool isFreedMem(u32_t addr) const
Set< NodeID > _freedAddrs
void initObjVar(const ObjVar *objVar)
AddrToAbsValMap _addrToAbsVal
Map a memory address to its stored abstract value.
const SVFType * getPointeeElement(NodeID id)
AbstractState & operator=(AbstractState &&rhs)
operator= move constructor
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
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)
Assignment operator.
static bool isVirtualMemAddress(u32_t val)
Check bit value of val start with 0x7F000000, filter by 0xFF000000.
void storeValue(NodeID varId, AbstractValue val)
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.
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