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 // 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
150
151protected:
155
156public:
157
158
161 {
162 assert(!isVirtualMemAddress(varId) && "varId is a virtual memory address, use load() instead");
163 return _varToAbsVal[varId];
164 }
165
167 inline virtual const AbstractValue &operator[](u32_t varId) const
168 {
169 assert(!isVirtualMemAddress(varId) && "varId is a virtual memory address, use load() instead");
170 return _varToAbsVal.at(varId);
171 }
172
173 inline virtual AbstractValue &load(u32_t addr)
174 {
175 assert(isVirtualMemAddress(addr) && "not virtual address?");
177 return _addrToAbsVal[objId];
178 }
179
180 inline virtual const AbstractValue &load(u32_t addr) const
181 {
182 assert(isVirtualMemAddress(addr) && "not virtual address?");
184 return _addrToAbsVal.at(objId);
185 }
186
187 inline void store(u32_t addr, const AbstractValue &val)
188 {
189 assert(isVirtualMemAddress(addr) && "not virtual address?");
191 if (isNullMem(addr)) return;
193 }
194
196 inline bool inVarToAddrsTable(u32_t id) const
197 {
198 if (_varToAbsVal.find(id)!= _varToAbsVal.end())
199 {
200 if (_varToAbsVal.at(id).isAddr())
201 return true;
202 }
203 return false;
204 }
205
207 inline virtual bool inVarToValTable(u32_t id) const
208 {
209 if (_varToAbsVal.find(id) != _varToAbsVal.end())
210 {
211 if (_varToAbsVal.at(id).isInterval())
212 return true;
213 }
214 return false;
215 }
216
218 inline bool inAddrToAddrsTable(u32_t id) const
219 {
220 if (_addrToAbsVal.find(id)!= _addrToAbsVal.end())
221 {
222 if (_addrToAbsVal.at(id).isAddr())
223 {
224 return true;
225 }
226 }
227 return false;
228 }
229
231 inline virtual bool inAddrToValTable(u32_t id) const
232 {
233 if (_addrToAbsVal.find(id) != _addrToAbsVal.end())
234 {
235 if (_addrToAbsVal.at(id).isInterval())
236 {
237 return true;
238 }
239 }
240 return false;
241 }
242
244 inline const VarToAbsValMap&getVarToVal() const
245 {
246 return _varToAbsVal;
247 }
248
250 inline const AddrToAbsValMap&getLocToVal() const
251 {
252 return _addrToAbsVal;
253 }
254
257
260
262 void joinWith(const AbstractState&other);
263
264
267 {
268 _addrToAbsVal = other._addrToAbsVal;
269 _freedAddrs = other._freedAddrs;
270 }
271
273 void meetWith(const AbstractState&other);
274
276 {
277 _freedAddrs.insert(addr);
278 }
279
281 {
282 return _freedAddrs.find(addr) != _freedAddrs.end();
283 }
284
285
286 void printAbstractState() const;
287
288 std::string toString() const;
289
290 u32_t hash() const;
291
292 // lhs == rhs for varToValMap
293 bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) const;
294 // lhs >= rhs for varToValMap
295 bool geqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs) const;
296 // lhs == rhs for AbstractState
297 bool equals(const AbstractState&other) const;
298
301 {
302 if (&rhs != this)
303 {
305 _addrToAbsVal = rhs._addrToAbsVal;
306 _freedAddrs = rhs._freedAddrs;
307 }
308 return *this;
309 }
310
313 {
314 if (&rhs != this)
315 {
316 _varToAbsVal = std::move(rhs._varToAbsVal);
317 _addrToAbsVal = std::move(rhs._addrToAbsVal);
318 _freedAddrs = std::move(rhs._freedAddrs);
319 }
320 return *this;
321 }
322
323 bool operator==(const AbstractState&rhs) const
324 {
325 return eqVarToValMap(_varToAbsVal, rhs.getVarToVal()) &&
326 eqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
327 }
328
329 bool operator!=(const AbstractState&rhs) const
330 {
331 return !(*this == rhs);
332 }
333
334 bool operator<(const AbstractState&rhs) const
335 {
336 return !(*this >= rhs);
337 }
338
339 bool operator>=(const AbstractState&rhs) const
340 {
341 return geqVarToValMap(_varToAbsVal, rhs.getVarToVal()) && geqVarToValMap(_addrToAbsVal, rhs.getLocToVal());
342 }
343
344 void clear()
345 {
346 _addrToAbsVal.clear();
347 _varToAbsVal.clear();
348 _freedAddrs.clear();
349 }
350
356 {
357 _varToAbsVal.clear();
358 }
359
360
361};
362
363}
364
365
366#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
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:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:47