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 "Util/GeneralType.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 // initObjVar
78 void initObjVar(const ObjVar* objVar);
79
80
86
88 static inline bool isVirtualMemAddress(u32_t val)
89 {
91 }
92
98
101 _addrToAbsVal(std::move(rhs._addrToAbsVal)),
102 _freedAddrs(std::move(rhs._freedAddrs))
103 {
104
105 }
106
109 {
110 AbstractState inv = *this;
111 for (auto &item: inv._varToAbsVal)
112 {
113 if (item.second.isInterval())
114 item.second.getInterval().set_to_bottom();
115 }
116 return inv;
117 }
118
121 {
122 AbstractState inv = *this;
123 for (auto &item: inv._varToAbsVal)
124 {
125 if (item.second.isInterval())
126 item.second.getInterval().set_to_top();
127 }
128 return inv;
129 }
130
133 {
135 for (u32_t id: sl)
136 inv._varToAbsVal[id] = _varToAbsVal[id];
137 return inv;
138 }
139
140 static inline bool isNullMem(u32_t addr)
141 {
142 return addr == NullMemAddr;
143 }
144
145 static inline bool isBlackHoleObjAddr(u32_t addr)
146 {
147 return addr == BlackHoleObjAddr;
148 }
149
151 static inline bool isNullOrBlackHoleAddr(u32_t addr)
152 {
154 }
155
156
157protected:
161
162public:
163
164
167 {
168 assert(!isVirtualMemAddress(varId) && "varId is a virtual memory address, use load() instead");
169 return _varToAbsVal[varId];
170 }
171
173 inline virtual const AbstractValue &operator[](u32_t varId) const
174 {
175 assert(!isVirtualMemAddress(varId) && "varId is a virtual memory address, use load() instead");
176 return _varToAbsVal.at(varId);
177 }
178
179 inline virtual AbstractValue &load(u32_t addr)
180 {
181 assert(isVirtualMemAddress(addr) && "not virtual address?");
183 return _addrToAbsVal[objId];
184 }
185
186 inline virtual const AbstractValue &load(u32_t addr) const
187 {
188 assert(isVirtualMemAddress(addr) && "not virtual address?");
190 return _addrToAbsVal.at(objId);
191 }
192
193 inline void store(u32_t addr, const AbstractValue &val)
194 {
195 assert(isVirtualMemAddress(addr) && "not virtual address?");
198 }
199
201 inline bool inVarToAddrsTable(u32_t id) const
202 {
203 if (_varToAbsVal.find(id)!= _varToAbsVal.end())
204 {
205 if (_varToAbsVal.at(id).isAddr())
206 return true;
207 }
208 return false;
209 }
210
212 inline virtual bool inVarToValTable(u32_t id) const
213 {
214 if (_varToAbsVal.find(id) != _varToAbsVal.end())
215 {
216 if (_varToAbsVal.at(id).isInterval())
217 return true;
218 }
219 return false;
220 }
221
223 inline bool inAddrToAddrsTable(u32_t id) const
224 {
225 if (_addrToAbsVal.find(id)!= _addrToAbsVal.end())
226 {
227 if (_addrToAbsVal.at(id).isAddr())
228 {
229 return true;
230 }
231 }
232 return false;
233 }
234
236 inline virtual bool inAddrToValTable(u32_t id) const
237 {
238 if (_addrToAbsVal.find(id) != _addrToAbsVal.end())
239 {
240 if (_addrToAbsVal.at(id).isInterval())
241 {
242 return true;
243 }
244 }
245 return false;
246 }
247
249 inline const VarToAbsValMap&getVarToVal() const
250 {
251 return _varToAbsVal;
252 }
253
255 inline const AddrToAbsValMap&getLocToVal() const
256 {
257 return _addrToAbsVal;
258 }
259
262
265
267 void joinWith(const AbstractState&other);
268
271 {
273 _freedAddrs = other._freedAddrs;
274 }
275
277 void meetWith(const AbstractState&other);
278
280 {
281 _freedAddrs.insert(addr);
282 }
283
285 {
286 return _freedAddrs;
287 }
288
290 {
291 return _freedAddrs.find(addr) != _freedAddrs.end();
292 }
293
294
295 void printAbstractState() const;
296
297 std::string toString() const;
298
299 u32_t hash() const;
300
301 // lhs == rhs for varToValMap
302 bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) const;
303 // lhs >= rhs for varToValMap
304 bool geqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) const;
305 // lhs == rhs for AbstractState
306 bool equals(const AbstractState&other) const;
307
310 {
311 if (&rhs != this)
312 {
314 _addrToAbsVal = rhs._addrToAbsVal;
315 _freedAddrs = rhs._freedAddrs;
316 }
317 return *this;
318 }
319
322 {
323 if (&rhs != this)
324 {
325 _varToAbsVal = std::move(rhs._varToAbsVal);
326 _addrToAbsVal = std::move(rhs._addrToAbsVal);
327 _freedAddrs = std::move(rhs._freedAddrs);
328 }
329 return *this;
330 }
331
332 bool operator==(const AbstractState&rhs) const
333 {
334 return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) &&
335 eqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
336 }
337
338 bool operator!=(const AbstractState&rhs) const
339 {
340 return !(*this == rhs);
341 }
342
343 bool operator<(const AbstractState&rhs) const
344 {
345 return !(*this >= rhs);
346 }
347
348 bool operator>=(const AbstractState&rhs) const
349 {
350 return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
351 }
352
353 void clear()
354 {
355 _addrToAbsVal.clear();
356 _varToAbsVal.clear();
357 _freedAddrs.clear();
358 }
359
365 {
366 _varToAbsVal.clear();
367 }
368
369
370};
371
372}
373
374
375#endif //Z3_EXAMPLE_INTERVAL_DOMAIN_H
#define NullMemAddr
#define BlackHoleObjAddr
cJSON * item
Definition cJSON.h:222
const AddrToAbsValMap & getLocToVal() const
get loc2val map
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
static bool isNullOrBlackHoleAddr(u32_t addr)
Whether addr has no concrete backing memory object.
const Set< NodeID > & getFreedAddrs() const
virtual const AbstractValue & operator[](u32_t varId) const
get abstract value of variable
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.
AbstractState & operator=(AbstractState &&rhs)
operator= move constructor
virtual AbstractValue & load(u32_t addr)
AbstractState(VarToAbsValMap &_varToValMap, AddrToAbsValMap &_locToValMap)
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
void updateAddrStateOnly(const AbstractState &other)
Replace address-taken (ObjVar) state with other's, preserving ValVar state.
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 meetWith(const AbstractState &other)
domain meet with other, important! other widen this.
bool operator<(const AbstractState &rhs) const
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:70
u32_t NodeID
Definition GeneralType.h:76
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:67