Static Value-Flow Analysis
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 
49 #include "AE/Core/AbstractValue.h"
50 #include "AE/Core/IntervalValue.h"
51 #include "SVFIR/SVFVariables.h"
52 #include "Util/Z3Expr.h"
53 
54 #include <iomanip>
55 
56 namespace SVF
57 {
59 {
60  friend class SVFIR2AbsState;
61  friend class RelationSolver;
62 public:
64 
66 
67 public:
70  {
71  }
72 
73  AbstractState(VarToAbsValMap&_varToValMap, AddrToAbsValMap&_locToValMap) : _varToAbsVal(_varToValMap), _addrToAbsVal(_locToValMap) {}
74 
77  {
78 
79  }
80 
81  virtual ~AbstractState() = default;
82 
83  // getGepObjAddrs
85 
86  // initObjVar
87  void initObjVar(ObjVar* objVar);
88  // getElementIndex
90  // getByteOffset
92  // printAbstractState
93  // loadValue
95  // storeValue
96  void storeValue(NodeID varId, AbstractValue val);
97 
99 
100 
102  static inline u32_t getVirtualMemAddress(u32_t idx)
103  {
105  }
106 
108  static inline bool isVirtualMemAddress(u32_t val)
109  {
111  }
112 
114  static inline u32_t getInternalID(u32_t idx)
115  {
116  return AddressValue::getInternalID(idx);
117  }
118 
119  static inline bool isNullPtr(u32_t addr)
120  {
121  return getInternalID(addr) == 0;
122  }
123 
125  {
126  if (rhs != *this)
127  {
130  }
131  return *this;
132  }
133 
136  _addrToAbsVal(std::move(rhs._addrToAbsVal))
137  {
138 
139  }
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  {
179  AbstractState inv;
180  for (u32_t id: sl)
181  {
182  inv._varToAbsVal[id] = _varToAbsVal[id];
183  }
184  return inv;
185  }
186 
187 protected:
191 
192 public:
193 
194 
196  inline virtual AbstractValue &operator[](u32_t varId)
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 
271 public:
272 
274  AbstractState widening(const AbstractState&other);
275 
278 
280  void joinWith(const AbstractState&other);
281 
282 
284  void meetWith(const AbstractState&other);
285 
293  const SVFType* getPointeeElement(NodeID id);
294 
295 
296  u32_t hash() const;
297 
298 public:
299  inline void store(u32_t addr, const AbstractValue &val)
300  {
301  assert(isVirtualMemAddress(addr) && "not virtual address?");
302  if (isNullPtr(addr)) return;
303  u32_t objId = getInternalID(addr);
304  _addrToAbsVal[objId] = val;
305  }
306 
307  inline virtual AbstractValue &load(u32_t addr)
308  {
309  assert(isVirtualMemAddress(addr) && "not virtual address?");
310  u32_t objId = getInternalID(addr);
311  return _addrToAbsVal[objId];
312 
313  }
314 
315 
316  void printAbstractState() const;
317 
319  {
320  return "";
321  }
322 
323  bool equals(const AbstractState&other) const;
324 
325 
326  static bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs)
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 
343  static bool lessThanVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs)
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
357  static bool geqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&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()) &&
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  {
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 char *const string
Definition: cJSON.h:172
u32_t getAllocaInstByteSize(const AddrStmt *addr)
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
Definition: AbstractState.h:60
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
u32_t hash() const
void joinWith(const AbstractState &other)
domain join with other, important! other widen this.
AbstractState(const AbstractState &rhs)
copy constructor
Definition: AbstractState.h:76
const VarToAbsValMap & getVarToVal() const
get var2val map
bool operator!=(const AbstractState &rhs) const
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)
static bool lessThanVarToValMap(const VarToAbsValMap &lhs, const VarToAbsValMap &rhs)
virtual AbstractValue & operator[](u32_t varId)
get abstract value of variable
AbstractState(VarToAbsValMap &_varToValMap, AddrToAbsValMap &_locToValMap)
Definition: AbstractState.h:73
IntervalValue getByteOffset(const GepStmt *gep)
virtual AbstractValue & load(u32_t addr)
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.
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
Definition: AbstractState.h:69
static bool isNullPtr(u32_t addr)
virtual bool inVarToValTable(u32_t id) const
whether the variable is in varToVal table
const AddrToAbsValMap & getLocToVal() const
get loc2val map
Map< u32_t, AbstractValue > VarToAbsValMap
Definition: AbstractState.h:63
virtual ~AbstractState()=default
VarToAbsValMap AddrToAbsValMap
Definition: AbstractState.h:65
AbstractState top() const
Set all value top.
bool operator==(const AbstractState &rhs) const
virtual const AbstractValue & operator[](u32_t varId) const
get abstract value of variable
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
AbstractState & operator=(const AbstractState &rhs)
AddressValue getGepObjAddrs(u32_t pointer, IntervalValue offset)
AbstractState sliceState(Set< u32_t > &sl)
Copy some values and return a new IntervalExeState.
AbstractState & operator=(AbstractState &&rhs)
operator= move constructor
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.
Definition: AddressValue.h:226
static u32_t getVirtualMemAddress(u32_t idx)
The physical address starts with 0x7f...... + idx.
Definition: AddressValue.h:212
static bool isVirtualMemAddress(u32_t val)
Check bit value of val start with 0x7F000000, filter by 0xFF000000.
Definition: AddressValue.h:220
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
unsigned u32_t
Definition: GeneralType.h:46
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96