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,650 +0,0 @@
1
- //===- IntervalExeState.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
-
43
- #ifndef Z3_EXAMPLE_INTERVAL_DOMAIN_H
44
- #define Z3_EXAMPLE_INTERVAL_DOMAIN_H
45
-
46
- #include "AE/Core/ExeState.h"
47
- #include "AE/Core/IntervalValue.h"
48
- #include "Util/Z3Expr.h"
49
-
50
- #include <iomanip>
51
-
52
- namespace SVF
53
- {
54
- class IntervalESBase: public ExeState
55
- {
56
- friend class SVFIR2ItvExeState;
57
- friend class RelationSolver;
58
- public:
59
- typedef Map<u32_t, IntervalValue> VarToValMap;
60
-
61
- typedef VarToValMap LocToValMap;
62
-
63
- public:
64
- /// default constructor
65
- IntervalESBase() : ExeState(ExeState::IntervalK) {}
66
-
67
- IntervalESBase(VarToValMap &_varToValMap, LocToValMap &_locToValMap) : ExeState(ExeState::IntervalK),
68
- _varToItvVal(_varToValMap),
69
- _locToItvVal(_locToValMap) {}
70
-
71
- /// copy constructor
72
- IntervalESBase(const IntervalESBase &rhs) : ExeState(rhs), _varToItvVal(rhs.getVarToVal()),
73
- _locToItvVal(rhs.getLocToVal())
74
- {
75
-
76
- }
77
-
78
- virtual ~IntervalESBase() = default;
79
-
80
-
81
- IntervalESBase &operator=(const IntervalESBase &rhs)
82
- {
83
- if (rhs != *this)
84
- {
85
- _varToItvVal = rhs._varToItvVal;
86
- _locToItvVal = rhs._locToItvVal;
87
- ExeState::operator=(rhs);
88
- }
89
- return *this;
90
- }
91
-
92
- /// move constructor
93
- IntervalESBase(IntervalESBase &&rhs) : ExeState(std::move(rhs)),
94
- _varToItvVal(std::move(rhs._varToItvVal)),
95
- _locToItvVal(std::move(rhs._locToItvVal))
96
- {
97
-
98
- }
99
-
100
- /// operator= move constructor
101
- IntervalESBase &operator=(IntervalESBase &&rhs)
102
- {
103
- if (&rhs != this)
104
- {
105
- _varToItvVal = std::move(rhs._varToItvVal);
106
- _locToItvVal = std::move(rhs._locToItvVal);
107
- ExeState::operator=(std::move(rhs));
108
- }
109
- return *this;
110
- }
111
-
112
- /// Set all value bottom
113
- IntervalESBase bottom() const
114
- {
115
- IntervalESBase inv = *this;
116
- for (auto &item: inv._varToItvVal)
117
- {
118
- item.second.set_to_bottom();
119
- }
120
- return inv;
121
- }
122
-
123
- /// Set all value top
124
- IntervalESBase top() const
125
- {
126
- IntervalESBase inv = *this;
127
- for (auto &item: inv._varToItvVal)
128
- {
129
- item.second.set_to_top();
130
- }
131
- return inv;
132
- }
133
-
134
- /// Copy some values and return a new IntervalExeState
135
- IntervalESBase sliceState(Set<u32_t> &sl)
136
- {
137
- IntervalESBase inv;
138
- for (u32_t id: sl)
139
- {
140
- inv._varToItvVal[id] = _varToItvVal[id];
141
- }
142
- return inv;
143
- }
144
-
145
- protected:
146
-
147
- VarToValMap _varToItvVal; ///< Map a variable (symbol) to its interval value
148
- LocToValMap _locToItvVal; ///< Map a memory address to its stored interval value
149
-
150
- public:
151
-
152
- /// get memory addresses of variable
153
- Addrs &getAddrs(u32_t id) override
154
- {
155
- return _varToAddrs[id];
156
- }
157
-
158
- /// get interval value of variable
159
- inline virtual IntervalValue &operator[](u32_t varId)
160
- {
161
- return _varToItvVal[varId];
162
- }
163
-
164
- /// whether the variable is in varToAddrs table
165
- inline bool inVarToAddrsTable(u32_t id) const override
166
- {
167
- return _varToAddrs.find(id) != _varToAddrs.end();
168
- }
169
-
170
- /// whether the variable is in varToVal table
171
- inline virtual bool inVarToValTable(u32_t id) const
172
- {
173
- return _varToItvVal.find(id) != _varToItvVal.end();
174
- }
175
-
176
- /// whether the memory address stores memory addresses
177
- inline bool inLocToAddrsTable(u32_t id) const override
178
- {
179
- return _locToAddrs.find(id) != _locToAddrs.end();
180
- }
181
-
182
- /// whether the memory address stores interval value
183
- inline virtual bool inLocToValTable(u32_t id) const
184
- {
185
- return _locToItvVal.find(id) != _locToItvVal.end();
186
- }
187
-
188
- /// get var2val map
189
- const VarToValMap &getVarToVal() const
190
- {
191
- return _varToItvVal;
192
- }
193
-
194
- /// get loc2val map
195
- const LocToValMap &getLocToVal() const
196
- {
197
- return _locToItvVal;
198
- }
199
-
200
- public:
201
-
202
- /// domain widen with other, and return the widened domain
203
- IntervalESBase widening(const IntervalESBase &other);
204
-
205
- /// domain narrow with other, and return the narrowed domain
206
- IntervalESBase narrowing(const IntervalESBase &other);
207
-
208
- /// domain widen with other, important! other widen this.
209
- void widenWith(const IntervalESBase &other);
210
-
211
- /// domain join with other, important! other widen this.
212
- void joinWith(const IntervalESBase &other);
213
-
214
- /// domain narrow with other, important! other widen this.
215
- void narrowWith(const IntervalESBase &other);
216
-
217
- /// domain meet with other, important! other widen this.
218
- void meetWith(const IntervalESBase &other);
219
-
220
-
221
- /// Return int value from an expression if it is a numeral, otherwise return an approximate value
222
- inline s32_t Interval2NumValue(const IntervalValue &e) const
223
- {
224
- //TODO: return concrete value;
225
- return (s32_t) e.lb().getNumeral();
226
- }
227
-
228
- ///TODO: Create new interval value
229
- IntervalValue createIntervalValue(double lb, double ub, NodeID id)
230
- {
231
- _varToItvVal[id] = IntervalValue(lb, ub);
232
- return _varToItvVal[id];
233
- }
234
-
235
- /// Return true if map has bottom value
236
- inline bool has_bottom()
237
- {
238
- for (auto it = _varToItvVal.begin(); it != _varToItvVal.end(); ++it)
239
- {
240
- if (it->second.isBottom())
241
- {
242
- return true;
243
- }
244
- }
245
- for (auto it = _locToItvVal.begin(); it != _locToItvVal.end(); ++it)
246
- {
247
- if (it->second.isBottom())
248
- {
249
- return true;
250
- }
251
- }
252
- return false;
253
- }
254
-
255
- u32_t hash() const override;
256
-
257
- public:
258
- inline void store(u32_t addr, const IntervalValue &val)
259
- {
260
- assert(isVirtualMemAddress(addr) && "not virtual address?");
261
- if (isNullPtr(addr)) return;
262
- u32_t objId = getInternalID(addr);
263
- _locToItvVal[objId] = val;
264
- }
265
-
266
- inline virtual IntervalValue &load(u32_t addr)
267
- {
268
- assert(isVirtualMemAddress(addr) && "not virtual address?");
269
- u32_t objId = getInternalID(addr);
270
- auto it = _locToItvVal.find(objId);
271
- if(it != _locToItvVal.end())
272
- return it->second;
273
- else
274
- {
275
- return _locToItvVal[objId];
276
- }
277
- }
278
-
279
- inline virtual Addrs &loadAddrs(u32_t addr) override
280
- {
281
- assert(isVirtualMemAddress(addr) && "not virtual address?");
282
- u32_t objId = getInternalID(addr);
283
- auto it = _locToAddrs.find(objId);
284
- if(it != _locToAddrs.end())
285
- return it->second;
286
- else
287
- {
288
- return _locToAddrs[objId];
289
- }
290
- }
291
-
292
- inline virtual IntervalValue& getLocVal(u32_t id)
293
- {
294
- auto it = _locToItvVal.find(id);
295
- if(it != _locToItvVal.end())
296
- return it->second;
297
- else
298
- {
299
- return _locToItvVal[id];
300
- }
301
- }
302
-
303
- inline virtual Addrs& getLocAddrs(u32_t id)
304
- {
305
- auto it = _locToAddrs.find(id);
306
- if(it != _locToAddrs.end())
307
- return it->second;
308
- else
309
- {
310
- return _locToAddrs[id];
311
- }
312
- }
313
-
314
- /// Print values of all expressions
315
- void printExprValues(std::ostream &oss) const override;
316
-
317
- std::string toString() const override
318
- {
319
- return "";
320
- }
321
-
322
- bool equals(const IntervalESBase &other) const;
323
-
324
- static bool eqVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs)
325
- {
326
- if (lhs.size() != rhs.size()) return false;
327
- for (const auto &item: lhs)
328
- {
329
- auto it = rhs.find(item.first);
330
- if (it == rhs.end())
331
- return false;
332
- if (!item.second.equals(it->second))
333
- {
334
- return false;
335
- }
336
- }
337
- return true;
338
- }
339
-
340
-
341
- static bool lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs)
342
- {
343
- if (lhs.empty()) return !rhs.empty();
344
- for (const auto &item: lhs)
345
- {
346
- auto it = rhs.find(item.first);
347
- if (it == rhs.end()) return false;
348
- // judge from expr id
349
- if (item.second.geq(it->second)) return false;
350
- }
351
- return true;
352
- }
353
-
354
- // lhs >= rhs
355
- static bool geqVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs)
356
- {
357
- if (rhs.empty()) return true;
358
- for (const auto &item: rhs)
359
- {
360
- auto it = lhs.find(item.first);
361
- if (it == lhs.end()) return false;
362
- // judge from expr id
363
- if (!it->second.geq(item.second)) return false;
364
- }
365
- return true;
366
- }
367
-
368
- using ExeState::operator==;
369
- using ExeState::operator!=;
370
- bool operator==(const IntervalESBase &rhs) const
371
- {
372
- return ExeState::operator==(rhs) && eqVarToValMap(_varToItvVal, rhs.getVarToVal()) &&
373
- eqVarToValMap(_locToItvVal, rhs.getLocToVal());
374
- }
375
-
376
- bool operator!=(const IntervalESBase &rhs) const
377
- {
378
- return !(*this == rhs);
379
- }
380
-
381
- bool operator<(const IntervalESBase &rhs) const
382
- {
383
- return !(*this >= rhs);
384
- }
385
-
386
-
387
- bool operator>=(const IntervalESBase &rhs) const
388
- {
389
- return geqVarToValMap(_varToItvVal, rhs.getVarToVal()) && geqVarToValMap(_locToItvVal, rhs.getLocToVal());
390
- }
391
-
392
- void clear()
393
- {
394
- _locToItvVal.clear();
395
- _varToItvVal.clear();
396
- _locToAddrs.clear();
397
- _varToAddrs.clear();
398
- }
399
-
400
-
401
- protected:
402
- void printTable(const VarToValMap &table, std::ostream &oss) const;
403
-
404
- void printTable(const VarToAddrs &table, std::ostream &oss) const;
405
- };
406
-
407
- class IntervalExeState : public IntervalESBase
408
- {
409
- friend class SVFIR2ItvExeState;
410
- friend class RelationSolver;
411
-
412
- public:
413
- static IntervalExeState globalES;
414
-
415
- public:
416
- /// default constructor
417
- IntervalExeState() : IntervalESBase() {}
418
-
419
- IntervalExeState(VarToValMap &_varToValMap, LocToValMap &_locToValMap) : IntervalESBase(_varToValMap, _locToValMap) {}
420
-
421
- /// copy constructor
422
- IntervalExeState(const IntervalExeState &rhs) : IntervalESBase(rhs)
423
- {
424
-
425
- }
426
-
427
- virtual ~IntervalExeState() = default;
428
-
429
-
430
- IntervalExeState &operator=(const IntervalExeState &rhs)
431
- {
432
- IntervalESBase::operator=(rhs);
433
- return *this;
434
- }
435
-
436
- virtual void printExprValues(std::ostream &oss) const override;
437
-
438
- /// move constructor
439
- IntervalExeState(IntervalExeState &&rhs) : IntervalESBase(std::move(rhs))
440
- {
441
-
442
- }
443
-
444
- /// operator= move constructor
445
- IntervalExeState &operator=(IntervalExeState &&rhs)
446
- {
447
- IntervalESBase::operator=(std::move(rhs));
448
- return *this;
449
- }
450
-
451
- public:
452
-
453
- /// get memory addresses of variable
454
- Addrs &getAddrs(u32_t id) override
455
- {
456
- auto it = _varToAddrs.find(id);
457
- if (it != _varToAddrs.end())
458
- return it->second;
459
- else
460
- return globalES._varToAddrs[id];
461
- }
462
-
463
- /// get interval value of variable
464
- inline IntervalValue &operator[](u32_t varId) override
465
- {
466
- auto localIt = _varToItvVal.find(varId);
467
- if(localIt != _varToItvVal.end())
468
- return localIt->second;
469
- else
470
- {
471
- return globalES._varToItvVal[varId];
472
- }
473
- }
474
-
475
- /// whether the variable is in varToAddrs table
476
- inline bool inVarToAddrsTable(u32_t id) const override
477
- {
478
- return _varToAddrs.find(id) != _varToAddrs.end() ||
479
- globalES._varToAddrs.find(id) != globalES._varToAddrs.end();
480
- }
481
-
482
- /// whether the variable is in varToVal table
483
- inline bool inVarToValTable(u32_t id) const override
484
- {
485
- return _varToItvVal.find(id) != _varToItvVal.end() ||
486
- globalES._varToItvVal.find(id) != globalES._varToItvVal.end();
487
- }
488
-
489
- /// whether the memory address stores memory addresses
490
- inline bool inLocToAddrsTable(u32_t id) const override
491
- {
492
- return _locToAddrs.find(id) != _locToAddrs.end() ||
493
- globalES._locToAddrs.find(id) != globalES._locToAddrs.end();
494
- }
495
-
496
- /// whether the memory address stores interval value
497
- inline bool inLocToValTable(u32_t id) const override
498
- {
499
- return _locToItvVal.find(id) != _locToItvVal.end() ||
500
- globalES._locToItvVal.find(id) != globalES._locToItvVal.end();
501
- }
502
-
503
- inline bool inLocalLocToValTable(u32_t id) const
504
- {
505
- return _locToItvVal.find(id) != _locToItvVal.end();
506
- }
507
-
508
- inline bool inLocalLocToAddrsTable(u32_t id) const
509
- {
510
- return _locToAddrs.find(id) != _locToAddrs.end();
511
- }
512
-
513
- public:
514
-
515
- inline void cpyItvToLocal(u32_t varId)
516
- {
517
- auto localIt = _varToItvVal.find(varId);
518
- // local already have varId
519
- if (localIt != _varToItvVal.end()) return;
520
- auto globIt = globalES._varToItvVal.find(varId);
521
- if (globIt != globalES._varToItvVal.end())
522
- {
523
- _varToItvVal[varId] = globIt->second;
524
- }
525
- }
526
-
527
- /// domain widen with other, and return the widened domain
528
- IntervalExeState widening(const IntervalExeState &other);
529
-
530
- /// domain narrow with other, and return the narrowed domain
531
- IntervalExeState narrowing(const IntervalExeState &other);
532
-
533
- /// domain widen with other, important! other widen this.
534
- void widenWith(const IntervalExeState &other);
535
-
536
- /// domain join with other, important! other widen this.
537
- void joinWith(const IntervalExeState &other);
538
-
539
- /// domain narrow with other, important! other widen this.
540
- void narrowWith(const IntervalExeState &other);
541
-
542
- /// domain meet with other, important! other widen this.
543
- void meetWith(const IntervalExeState &other);
544
-
545
- u32_t hash() const override;
546
-
547
- public:
548
-
549
- inline IntervalValue &load(u32_t addr) override
550
- {
551
- assert(isVirtualMemAddress(addr) && "not virtual address?");
552
- u32_t objId = getInternalID(addr);
553
- auto it = _locToItvVal.find(objId);
554
- if(it != _locToItvVal.end())
555
- return it->second;
556
- else
557
- {
558
- auto globIt = globalES._locToItvVal.find(objId);
559
- if(globIt != globalES._locToItvVal.end())
560
- return globIt->second;
561
- else
562
- return _locToItvVal[objId];
563
- }
564
- }
565
-
566
- inline Addrs &loadAddrs(u32_t addr) override
567
- {
568
- assert(isVirtualMemAddress(addr) && "not virtual address?");
569
- u32_t objId = getInternalID(addr);
570
- auto it = _locToAddrs.find(objId);
571
- if(it != _locToAddrs.end())
572
- return it->second;
573
- else
574
- {
575
- auto globIt = globalES._locToAddrs.find(objId);
576
- if(globIt != globalES._locToAddrs.end())
577
- return globIt->second;
578
- else
579
- return _locToAddrs[objId];
580
- }
581
- }
582
-
583
- inline IntervalValue& getLocVal(u32_t id) override
584
- {
585
- auto it = _locToItvVal.find(id);
586
- if(it != _locToItvVal.end())
587
- return it->second;
588
- else
589
- {
590
- auto globIt = globalES._locToItvVal.find(id);
591
- if(globIt != globalES._locToItvVal.end())
592
- return globIt->second;
593
- else
594
- return _locToItvVal[id];
595
- }
596
- }
597
-
598
- inline Addrs& getLocAddrs(u32_t id) override
599
- {
600
- auto it = _locToAddrs.find(id);
601
- if(it != _locToAddrs.end())
602
- return it->second;
603
- else
604
- {
605
- auto globIt = globalES._locToAddrs.find(id);
606
- if(globIt != globalES._locToAddrs.end())
607
- return globIt->second;
608
- else
609
- return _locToAddrs[id];
610
- }
611
- }
612
-
613
- bool equals(const IntervalExeState &other) const;
614
-
615
- using ExeState::operator==;
616
- using ExeState::operator!=;
617
- bool operator==(const IntervalExeState &rhs) const
618
- {
619
- return ExeState::operator==(rhs) && eqVarToValMap(_varToItvVal, rhs._varToItvVal) &&
620
- eqVarToValMap(_locToItvVal, rhs._locToItvVal);
621
- }
622
-
623
- bool operator!=(const IntervalExeState &rhs) const
624
- {
625
- return !(*this == rhs);
626
- }
627
-
628
- bool operator<(const IntervalExeState &rhs) const
629
- {
630
- return !(*this >= rhs);
631
- }
632
-
633
-
634
- bool operator>=(const IntervalExeState &rhs) const
635
- {
636
- return geqVarToValMap(_varToItvVal, rhs.getVarToVal()) && geqVarToValMap(_locToItvVal, rhs._locToItvVal);
637
- }
638
- };
639
- }
640
-
641
- template<>
642
- struct std::hash<SVF::IntervalExeState>
643
- {
644
- size_t operator()(const SVF::IntervalExeState &exeState) const
645
- {
646
- return exeState.hash();
647
- }
648
- };
649
-
650
- #endif //Z3_EXAMPLE_INTERVAL_DOMAIN_H