svf-lib 1.0.1925 → 1.0.1926

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- //===- AbstractValue.h --Abstract Value for domains---------------------------//
1
+ //===- AbstractValue.h ----AbstractValue-------------------------//
2
2
  //
3
3
  // SVF: Static Value-Flow Analysis
4
4
  //
@@ -19,60 +19,535 @@
19
19
  // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
20
  //
21
21
  //===----------------------------------------------------------------------===//
22
- /*
23
- * AbstractValue.h
24
- *
25
- * Created on: Aug 4, 2022
26
- * Author: Xiao Cheng, Jiawei Wang
27
- *
28
- */
29
22
 
30
- #ifndef Z3_EXAMPLE_ABSTRACTVALUE_H
31
- #define Z3_EXAMPLE_ABSTRACTVALUE_H
32
-
33
- #include <type_traits>
34
- #include <string>
23
+ #include "AE/Core/IntervalValue.h"
24
+ #include "AE/Core/AddressValue.h"
35
25
 
36
26
  namespace SVF
37
27
  {
38
28
 
39
- class IntervalValue;
40
-
41
- /*!
42
- * Base class of abstract value
43
- */
44
- class AbstractValue
29
+ struct AbstractValue
45
30
  {
46
- public:
47
- /// Abstract value kind
48
- enum AbstractValueK
31
+ enum DataType
49
32
  {
50
- IntervalK, ConcreteK, AddressK
33
+ IntervalType,
34
+ AddressType,
35
+ UnknownType,
51
36
  };
52
- private:
53
- AbstractValueK _kind;
37
+ DataType type;
38
+ IntervalValue interval;
39
+ AddressValue addr;
40
+
41
+ AbstractValue() : type(IntervalType)
42
+ {
43
+ interval = IntervalValue::top();
44
+ }
45
+ AbstractValue(DataType type) : type(type)
46
+ {
47
+ switch (type)
48
+ {
49
+ case IntervalType:
50
+ interval = IntervalValue::top();
51
+ break;
52
+ case AddressType:
53
+ addr = AddressValue();
54
+ break;
55
+ case UnknownType:
56
+ break;
57
+ }
58
+ }
59
+
60
+ AbstractValue(const AbstractValue& other): type(other.type)
61
+ {
62
+ switch (type)
63
+ {
64
+ case IntervalType:
65
+ interval = other.interval;
66
+ break;
67
+ case AddressType:
68
+ addr = other.addr;
69
+ break;
70
+ case UnknownType:
71
+ break;
72
+ }
73
+ }
74
+
75
+ inline bool isInterval() const
76
+ {
77
+ return type == IntervalType;
78
+ }
79
+ inline bool isAddr() const
80
+ {
81
+ return type == AddressType;
82
+ }
83
+ inline bool isUnknown() const
84
+ {
85
+ return type == UnknownType;
86
+ }
87
+
88
+ inline DataType getType() const
89
+ {
90
+ return type;
91
+ }
92
+
93
+ AbstractValue(AbstractValue &&other) : type(other.type)
94
+ {
95
+ switch (type)
96
+ {
97
+ case IntervalType:
98
+ interval = other.interval;
99
+ break;
100
+ case AddressType:
101
+ addr = other.addr;
102
+ break;
103
+ case UnknownType:
104
+ break;
105
+ }
106
+ }
107
+
108
+ // operator overload, supporting both interval and address
109
+ AbstractValue& operator=(const AbstractValue& other)
110
+ {
111
+ type = other.type;
112
+ switch (type)
113
+ {
114
+ case IntervalType:
115
+ interval = other.interval;
116
+ break;
117
+ case AddressType:
118
+ addr = other.addr;
119
+ break;
120
+ case UnknownType:
121
+ break;
122
+ }
123
+ return *this;
124
+ }
125
+ AbstractValue operator==(const AbstractValue& other) const
126
+ {
127
+ assert(isInterval() && other.isInterval());
128
+ return interval == other.interval;
129
+ }
130
+
131
+ AbstractValue operator==(const IntervalValue& other) const
132
+ {
133
+ assert(isInterval());
134
+ return interval == other;
135
+ }
136
+
137
+ AbstractValue operator!=(const AbstractValue& other) const
138
+ {
139
+ assert(isInterval());
140
+ return interval != other.interval;
141
+ }
142
+
143
+ AbstractValue operator!=(const IntervalValue& other) const
144
+ {
145
+ assert(isInterval());
146
+ return interval != other;
147
+ }
148
+
149
+
150
+ AbstractValue(const IntervalValue& ival) : type(IntervalType), interval(ival) {}
151
+
152
+ AbstractValue(const AddressValue& addr) : type(AddressType), addr(addr) {}
153
+ // TODO: move constructor
154
+ IntervalValue& getInterval()
155
+ {
156
+ if (isUnknown())
157
+ {
158
+ interval = IntervalValue::top();
159
+ }
160
+ assert(isInterval());
161
+ return interval;
162
+ }
163
+
164
+ //
165
+ const IntervalValue getInterval() const
166
+ {
167
+ assert(isInterval());
168
+ return interval;
169
+ }
170
+
171
+ AddressValue& getAddrs()
172
+ {
173
+ assert(isAddr());
174
+ return addr;
175
+ }
54
176
 
55
- public:
56
- AbstractValue(AbstractValueK kind) : _kind(kind) {}
177
+ const AddressValue getAddrs() const
178
+ {
179
+ assert(isAddr());
180
+ return addr;
181
+ }
182
+ ~AbstractValue() {};
183
+
184
+
185
+ // interval visit funcs
186
+ bool isTop() const
187
+ {
188
+ assert(isInterval());
189
+ return interval.isTop();
190
+ }
191
+
192
+ bool isBottom() const
193
+ {
194
+ assert(isInterval());
195
+ return interval.isBottom();
196
+ }
197
+
198
+ const NumericLiteral& lb() const
199
+ {
200
+ assert(isInterval());
201
+ return interval.lb();
202
+ }
203
+
204
+ const NumericLiteral& ub() const
205
+ {
206
+ assert(isInterval());
207
+ return interval.ub();
208
+ }
209
+
210
+ void setLb(const NumericLiteral& lb)
211
+ {
212
+ assert(isInterval());
213
+ interval.setLb(lb);
214
+ }
215
+
216
+ void setUb(const NumericLiteral& ub)
217
+ {
218
+ assert(isInterval());
219
+ interval.setUb(ub);
220
+ }
221
+
222
+ void setValue(const NumericLiteral &lb, const NumericLiteral &ub)
223
+ {
224
+ assert(isInterval());
225
+ interval.setValue(lb, ub);
226
+ }
57
227
 
58
- virtual ~AbstractValue() = default;
228
+ bool is_zero() const
229
+ {
230
+ assert(isInterval());
231
+ return interval.is_zero();
232
+ }
233
+
234
+ bool is_infinite() const
235
+ {
236
+ assert(isInterval());
237
+ return interval.is_infinite();
238
+ }
239
+
240
+ bool is_int() const
241
+ {
242
+ assert(isInterval());
243
+ return interval.is_int();
244
+ }
245
+
246
+ bool is_real() const
247
+ {
248
+ assert(isInterval());
249
+ return interval.is_real();
250
+ }
251
+
252
+ s64_t getIntNumeral() const
253
+ {
254
+ assert(isInterval());
255
+ return interval.getIntNumeral();
256
+ }
59
257
 
60
- AbstractValue(const AbstractValue &) noexcept = default;
258
+ double getRealNumeral() const
259
+ {
260
+ assert(isInterval());
261
+ return interval.getRealNumeral();
262
+ }
61
263
 
62
- AbstractValue(AbstractValue &&) noexcept = default;
264
+ bool is_numeral() const
265
+ {
266
+ assert(isInterval());
267
+ return interval.is_numeral();
268
+ }
63
269
 
64
- AbstractValue &operator=(const AbstractValue &) noexcept = default;
270
+ void set_to_bottom()
271
+ {
272
+ assert(isInterval());
273
+ interval.set_to_bottom();
274
+ }
65
275
 
66
- AbstractValue &operator=(AbstractValue &&) noexcept = default;
276
+ void set_to_top()
277
+ {
278
+ assert(isInterval());
279
+ interval.set_to_top();
280
+ }
67
281
 
68
- inline AbstractValueK getAbstractValueKind() const
282
+ bool leq(const AbstractValue &other) const
69
283
  {
70
- return _kind;
284
+ assert(isInterval() && other.isInterval());
285
+ return interval.leq(other.interval);
71
286
  }
72
287
 
73
- virtual bool isTop() const = 0;
288
+ bool geq(const AbstractValue &other) const
289
+ {
290
+ assert(isInterval() && other.isInterval());
291
+ return interval.geq(other.interval);
292
+ }
293
+
294
+ bool contains(s64_t n) const
295
+ {
296
+ assert(isInterval());
297
+ return interval.contains(n);
298
+ }
299
+ // operator +-*/%>< >= <= << >> & | ^
300
+ AbstractValue operator+(const AbstractValue &other) const
301
+ {
302
+ assert(isInterval() && other.isInterval());
303
+ return interval + other.interval;
304
+ }
305
+ AbstractValue operator+(const IntervalValue &other) const
306
+ {
307
+ assert(isInterval());
308
+ return interval + other;
309
+ }
310
+
311
+ AbstractValue operator-(const AbstractValue &other) const
312
+ {
313
+ assert(isInterval() && other.isInterval());
314
+ return interval - other.interval;
315
+ }
316
+ AbstractValue operator-(const IntervalValue &other) const
317
+ {
318
+ assert(isInterval());
319
+ return interval - other;
320
+ }
321
+
322
+ AbstractValue operator*(const AbstractValue &other) const
323
+ {
324
+ assert(isInterval() && other.isInterval());
325
+ return interval * other.interval;
326
+ }
327
+ AbstractValue operator*(const IntervalValue &other) const
328
+ {
329
+ assert(isInterval());
330
+ return interval * other;
331
+ }
332
+
333
+ AbstractValue operator/(const AbstractValue &other) const
334
+ {
335
+ assert(isInterval() && other.isInterval());
336
+ return interval / other.interval;
337
+ }
338
+ AbstractValue operator/(const IntervalValue &other) const
339
+ {
340
+ assert(isInterval());
341
+ return interval / other;
342
+ }
343
+
344
+ AbstractValue operator%(const AbstractValue &other) const
345
+ {
346
+ assert(isInterval() && other.isInterval());
347
+ return interval % other.interval;
348
+ }
349
+ AbstractValue operator%(const IntervalValue &other) const
350
+ {
351
+ assert(isInterval());
352
+ return interval % other;
353
+ }
354
+
355
+ AbstractValue operator>>(const AbstractValue &other) const
356
+ {
357
+ assert(isInterval() && other.isInterval());
358
+ return interval >> other.interval;
359
+ }
360
+ AbstractValue operator>>(const IntervalValue &other) const
361
+ {
362
+ assert(isInterval());
363
+ return interval >> other;
364
+ }
365
+
366
+ AbstractValue operator<<(const AbstractValue &other) const
367
+ {
368
+ assert(isInterval() && other.isInterval());
369
+ return interval << other.interval;
370
+ }
371
+ AbstractValue operator<<(const IntervalValue &other) const
372
+ {
373
+ assert(isInterval());
374
+ return interval << other;
375
+ }
376
+
377
+ AbstractValue operator&(const AbstractValue &other) const
378
+ {
379
+ assert(isInterval() && other.isInterval());
380
+ return interval & other.interval;
381
+ }
382
+ AbstractValue operator&(const IntervalValue &other) const
383
+ {
384
+ assert(isInterval());
385
+ return interval & other;
386
+ }
387
+
388
+ AbstractValue operator|(const AbstractValue &other) const
389
+ {
390
+ assert(isInterval() && other.isInterval());
391
+ return interval | other.interval;
392
+ }
393
+ AbstractValue operator|(const IntervalValue &other) const
394
+ {
395
+ assert(isInterval());
396
+ return interval | other;
397
+ }
398
+
399
+ AbstractValue operator^(const AbstractValue &other) const
400
+ {
401
+ assert(isInterval() && other.isInterval());
402
+ return interval ^ other.interval;
403
+ }
404
+ AbstractValue operator^(const IntervalValue &other) const
405
+ {
406
+ assert(isInterval());
407
+ return interval ^ other;
408
+ }
409
+
410
+ AbstractValue operator>(const AbstractValue &other) const
411
+ {
412
+ assert(isInterval() && other.isInterval());
413
+ return interval > other.interval;
414
+ }
415
+ AbstractValue operator>(const IntervalValue &other) const
416
+ {
417
+ assert(isInterval());
418
+ return interval > other;
419
+ }
420
+
421
+ AbstractValue operator<(const AbstractValue &other) const
422
+ {
423
+ assert(isInterval() && other.isInterval());
424
+ return interval < other.interval;
425
+ }
426
+ AbstractValue operator<(const IntervalValue &other) const
427
+ {
428
+ assert(isInterval());
429
+ return interval < other;
430
+ }
431
+
432
+ AbstractValue operator>=(const AbstractValue &other) const
433
+ {
434
+ assert(isInterval() && other.isInterval());
435
+ return interval >= other.interval;
436
+ }
437
+ AbstractValue operator>=(const IntervalValue &other) const
438
+ {
439
+ assert(isInterval());
440
+ return interval >= other;
441
+ }
442
+
443
+ AbstractValue operator<=(const AbstractValue &other) const
444
+ {
445
+ assert(isInterval() && other.isInterval());
446
+ return interval <= other.interval;
447
+ }
448
+ AbstractValue operator<=(const IntervalValue &other) const
449
+ {
450
+ assert(isInterval());
451
+ return interval <= other;
452
+ }
453
+
454
+
455
+ // address visit funcs
456
+ std::pair<AddressValue::AddrSet::iterator, bool> insertAddr(u32_t id) // insertAddr
457
+ {
458
+ assert(isAddr());
459
+ return addr.insert(id);
460
+ }
461
+
462
+ // TODO: equals, join_with, meet_with, widen_with, narrow_with, toString,
463
+ // These should be merged with AddressValue
464
+
465
+ bool equals(const AbstractValue &rhs) const
466
+ {
467
+ if (type != rhs.type)
468
+ {
469
+ return false;
470
+ }
471
+ if (isInterval())
472
+ {
473
+ return interval.equals(rhs.interval);
474
+ }
475
+ if (isAddr())
476
+ {
477
+ return addr.equals(rhs.addr);
478
+ }
479
+ return false;
480
+ }
481
+
482
+ void join_with(const AbstractValue &other)
483
+ {
484
+ if (isUnknown())
485
+ {
486
+ *this = other;
487
+ return;
488
+ }
489
+ else if (type != other.type)
490
+ {
491
+ return;
492
+ }
493
+ if (isInterval() && other.isInterval())
494
+ {
495
+ interval.join_with(other.interval);
496
+ }
497
+ if (isAddr() && other.isAddr())
498
+ {
499
+ addr.join_with(other.addr);
500
+ }
501
+ return;
502
+ }
503
+
504
+ void meet_with(const AbstractValue &other)
505
+ {
506
+ if (type != other.type)
507
+ {
508
+ return;
509
+ }
510
+ if (isInterval() && other.isInterval())
511
+ {
512
+ interval.meet_with(other.interval);
513
+ }
514
+ if (isAddr() && other.isAddr())
515
+ {
516
+ addr.meet_with(other.addr);
517
+ }
518
+ return;
519
+ }
520
+
521
+ void widen_with(const AbstractValue &other)
522
+ {
523
+ // widen_with only in interval
524
+ if (isInterval() && other.isInterval())
525
+ {
526
+ interval.widen_with(other.interval);
527
+ }
528
+ }
529
+
530
+ void narrow_with(const AbstractValue &other)
531
+ {
532
+ // narrow_with only in interval
533
+ if (isInterval() && other.isInterval())
534
+ {
535
+ interval.narrow_with(other.interval);
536
+ }
537
+ }
538
+
539
+ std::string toString() const
540
+ {
541
+ if (isInterval())
542
+ {
543
+ return interval.toString();
544
+ }
545
+ else if (isAddr())
546
+ {
547
+ return addr.toString();
548
+ }
549
+ return "";
550
+ }
74
551
 
75
- virtual bool isBottom() const = 0;
76
- }; // end class AbstractValue
77
- } // end namespace SVF
78
- #endif //Z3_EXAMPLE_ABSTRACTVALUE_H
552
+ };
553
+ }
@@ -33,14 +33,14 @@
33
33
  #define AddressMask 0x7f000000
34
34
  #define FlippedAddressMask (AddressMask^0xffffffff)
35
35
  // the address of the black hole, getVirtualMemAddress(2);
36
- #define BlackHoleAddr 0x7f000000 + 2;
36
+ #define BlackHoleAddr 0x7f000000 + 2
37
37
 
38
- #include "AE/Core/AbstractValue.h"
39
38
  #include "Util/GeneralType.h"
39
+ #include <sstream>
40
40
 
41
41
  namespace SVF
42
42
  {
43
- class AddressValue : public AbstractValue
43
+ class AddressValue
44
44
  {
45
45
  public:
46
46
  typedef Set<u32_t> AddrSet;
@@ -48,21 +48,21 @@ private:
48
48
  AddrSet _addrs;
49
49
  public:
50
50
  /// Default constructor
51
- AddressValue() : AbstractValue(AddressK) {}
51
+ AddressValue() {}
52
52
 
53
53
  /// Constructor
54
- AddressValue(const Set<u32_t> &addrs) : AbstractValue(AddressK), _addrs(addrs) {}
54
+ AddressValue(const Set<u32_t> &addrs) : _addrs(addrs) {}
55
55
 
56
- AddressValue(u32_t addr) : AbstractValue(AddressK), _addrs({addr}) {}
56
+ AddressValue(u32_t addr) : _addrs({addr}) {}
57
57
 
58
58
  /// Default destructor
59
59
  ~AddressValue() = default;
60
60
 
61
61
  /// Copy constructor
62
- AddressValue(const AddressValue &other) : AbstractValue(AddressK), _addrs(other._addrs) {}
62
+ AddressValue(const AddressValue &other) : _addrs(other._addrs) {}
63
63
 
64
64
  /// Move constructor
65
- AddressValue(AddressValue &&other) noexcept: AbstractValue(AddressK), _addrs(std::move(other._addrs)) {}
65
+ AddressValue(AddressValue &&other) noexcept: _addrs(std::move(other._addrs)) {}
66
66
 
67
67
  /// Copy operator=
68
68
  AddressValue &operator=(const AddressValue &other)
@@ -70,7 +70,6 @@ public:
70
70
  if (!this->equals(other))
71
71
  {
72
72
  _addrs = other._addrs;
73
- AbstractValue::operator=(other);
74
73
  }
75
74
  return *this;
76
75
  }
@@ -81,7 +80,6 @@ public:
81
80
  if (this != &other)
82
81
  {
83
82
  _addrs = std::move(other._addrs);
84
- AbstractValue::operator=(std::move(other));
85
83
  }
86
84
  return *this;
87
85
  }
@@ -91,17 +89,6 @@ public:
91
89
  return _addrs == rhs._addrs;
92
90
  }
93
91
 
94
- bool operator==(const AddressValue &rhs) const
95
- {
96
- return _addrs == rhs._addrs;
97
- }
98
-
99
- /// Operator !=
100
- bool operator!=(const AddressValue &rhs) const
101
- {
102
- return _addrs != rhs._addrs;
103
- }
104
-
105
92
  AddrSet::const_iterator begin() const
106
93
  {
107
94
  return _addrs.cbegin();
@@ -181,19 +168,19 @@ public:
181
168
  return !v.empty();
182
169
  }
183
170
 
184
- inline bool isTop() const override
171
+ inline bool isTop() const
185
172
  {
186
- return *this == BlackHoleAddr;
173
+ return *this->begin() == BlackHoleAddr;
187
174
  }
188
175
 
189
- inline bool isBottom() const override
176
+ inline bool isBottom() const
190
177
  {
191
178
  return empty();
192
179
  }
193
180
 
194
181
  inline void setTop()
195
182
  {
196
- *this = BlackHoleAddr;
183
+ *this = AddressValue(BlackHoleAddr);
197
184
  }
198
185
 
199
186
  inline void setBottom()
@@ -201,6 +188,26 @@ public:
201
188
  _addrs.clear();
202
189
  }
203
190
 
191
+ const std::string toString() const
192
+ {
193
+ std::string str;
194
+ std::stringstream rawStr(str);
195
+ if (this->isBottom())
196
+ {
197
+ rawStr << "⊥";
198
+ }
199
+ else
200
+ {
201
+ rawStr << "[";
202
+ for (auto it = _addrs.begin(), eit = _addrs.end(); it!= eit; ++it)
203
+ {
204
+ rawStr << *it << ", ";
205
+ }
206
+ rawStr << "]";
207
+ }
208
+ return rawStr.str();
209
+ }
210
+
204
211
  /// The physical address starts with 0x7f...... + idx
205
212
  static inline u32_t getVirtualMemAddress(u32_t idx)
206
213
  {
@@ -39,7 +39,7 @@
39
39
  namespace SVF
40
40
  {
41
41
 
42
- class IntervalExeState;
42
+ class SparseAbstractState;
43
43
 
44
44
  /*!
45
45
  * Base execution state
@@ -196,7 +196,7 @@ protected:
196
196
  auto it = rhs.find(item.first);
197
197
  if (it == rhs.end())
198
198
  return false;
199
- if (item.second != it->second)
199
+ if (item.second.equals(it->second))
200
200
  {
201
201
  return false;
202
202
  }