svf-tools 1.0.728 → 1.0.729

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.728",
3
+ "version": "1.0.729",
4
4
  "description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,446 @@
1
+ //===- ConsExeState.h ----Constant Execution State-------------------------//
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
+ // Created by jiawei and xiao on 6/1/23.
24
+ //
25
+
26
+ #ifndef SVF_CONSEXESTATE_H
27
+ #define SVF_CONSEXESTATE_H
28
+
29
+ #include "AbstractExecution/SingleAbsValue.h"
30
+ #include "AbstractExecution/ExeState.h"
31
+
32
+ namespace SVF
33
+ {
34
+
35
+ /*!
36
+ * Constant Expr Execution State
37
+ *
38
+ * Constant expr execution state support z3 symbolic value
39
+ * and gives a top value when two different constants join
40
+ *
41
+ * lattice: ⊤ may be constant
42
+ * / / | \ \ \
43
+ * true ... c0 c1 ... false constant
44
+ * \ \ \ | | |
45
+ * ⊥ not contant
46
+ */
47
+ class ConsExeState final : public ExeState
48
+ {
49
+ friend class SVFIR2ConsExeState;
50
+
51
+ public:
52
+ typedef Map<u32_t, SingleAbsValue> VarToValMap;
53
+ typedef VarToValMap LocToValMap;
54
+
55
+ static ConsExeState globalConsES;
56
+
57
+ protected:
58
+ VarToValMap _varToVal;
59
+ LocToValMap _locToVal;
60
+
61
+ public:
62
+ ConsExeState(): ExeState(ExeState::SingleValueK) {}
63
+
64
+
65
+ /// Constructor
66
+ ConsExeState(VarToValMap varToValMap, LocToValMap locToValMap) : ExeState(ExeState::SingleValueK), _varToVal(
67
+ SVFUtil::move(varToValMap)), _locToVal(SVFUtil::move(locToValMap)) {}
68
+
69
+ /// Copy Constructor
70
+ ConsExeState(const ConsExeState &rhs) : ExeState(rhs), _varToVal(rhs.getVarToVal()),
71
+ _locToVal(rhs.getLocToVal())
72
+ {
73
+
74
+ }
75
+
76
+ /// Destructor
77
+ ~ConsExeState() override
78
+ {
79
+ _varToVal.clear();
80
+ _locToVal.clear();
81
+ }
82
+
83
+ /// Copy operator
84
+ ConsExeState &operator=(const ConsExeState &rhs);
85
+
86
+ /// Move Constructor
87
+ ConsExeState(ConsExeState &&rhs) noexcept: ExeState(std::move(rhs)),
88
+ _varToVal(SVFUtil::move(rhs._varToVal)), _locToVal(SVFUtil::move(rhs._locToVal))
89
+ {
90
+
91
+ }
92
+
93
+ /// Move operator
94
+ ConsExeState &operator=(ConsExeState &&rhs) noexcept;
95
+
96
+ /// Name
97
+ static inline std::string name()
98
+ {
99
+ return "ConstantExpr";
100
+ }
101
+
102
+ /// Exposed APIs
103
+ //{%
104
+ bool operator==(const ConsExeState &rhs) const;
105
+
106
+ bool operator!=(const ConsExeState &other) const
107
+ {
108
+ return !(*this == other);
109
+ }
110
+
111
+ bool operator<(const ConsExeState &rhs) const;
112
+
113
+ u32_t hash() const override;
114
+
115
+ /// Merge rhs into this
116
+ bool joinWith(const ConsExeState &rhs);
117
+
118
+ /// Build global execution state
119
+ void buildGlobES(ConsExeState &globES, Set<u32_t> &vars);
120
+
121
+ /// Update symbolic states based on the summary/side-effect of callee
122
+ void applySummary(const ConsExeState &summary);
123
+
124
+ /// Whether state is null state (uninitialized state)
125
+ inline bool isNullState() const
126
+ {
127
+ return _varToVal.size() == 1 && eq((*_varToVal.begin()).second, -1) && _locToVal.empty();
128
+ }
129
+
130
+ /// Print values of all expressions
131
+ void printExprValues() const;
132
+
133
+ /// Print values of all expressions
134
+ void printExprValues(std::ostream &oss) const override;
135
+
136
+ std::string toString() const override;
137
+
138
+ std::string pcToString() const;
139
+
140
+ std::string varToString(u32_t varId) const;
141
+
142
+ std::string locToString(u32_t objId) const;
143
+
144
+ bool applySelect(u32_t res, u32_t cond, u32_t top, u32_t fop);
145
+
146
+ bool applyPhi(u32_t res, std::vector<u32_t> &ops);
147
+
148
+ inline bool inVarToVal(u32_t varId) const
149
+ {
150
+ return _varToVal.count(varId) || globalConsES._varToVal.count(varId);
151
+ }
152
+
153
+ inline bool inLocalLocToVal(const SingleAbsValue &loc) const
154
+ {
155
+ assert(loc.is_numeral() && "location must be numeral");
156
+ s32_t virAddr = z3Expr2NumValue(loc);
157
+ assert(isVirtualMemAddress(virAddr) && "Pointer operand is not a physical address?");
158
+ u32_t objId = getInternalID(virAddr);
159
+ assert(getInternalID(objId) == objId && "SVFVar idx overflow > 0x7f000000?");
160
+ return inLocalLocToVal(objId);
161
+ }
162
+
163
+ inline bool inLocalLocToVal(u32_t varId) const
164
+ {
165
+ return _locToVal.count(varId);
166
+ }
167
+
168
+ inline bool inLocToVal(u32_t varId) const
169
+ {
170
+ return inLocalLocToVal(varId) || globalConsES._locToVal.count(varId);
171
+ }
172
+
173
+ inline bool equalVar(u32_t lhs, u32_t rhs)
174
+ {
175
+ if (!inVarToVal(lhs) || !inVarToVal(rhs)) return false;
176
+ return eq((*this)[lhs], (*this)[rhs]);
177
+ }
178
+ //%}
179
+
180
+ virtual inline bool inVarToAddrsTable(u32_t id) const override
181
+ {
182
+ return _varToVAddrs.find(id) != _varToVAddrs.end() ||
183
+ globalConsES._varToVAddrs.find(id) != globalConsES._varToVAddrs.end();
184
+ }
185
+
186
+ virtual inline bool inLocToAddrsTable(u32_t id) const override
187
+ {
188
+ return globalConsES._locToVAddrs.find(id) != globalConsES._locToVAddrs.end() || inLocalLocToAddrsTable(id);
189
+ }
190
+
191
+ virtual inline bool inLocalLocToAddrsTable(u32_t id) const
192
+ {
193
+ return _locToVAddrs.find(id) != _locToVAddrs.end();
194
+ }
195
+
196
+ virtual VAddrs &getVAddrs(u32_t id) override
197
+ {
198
+ auto it = globalConsES._varToVAddrs.find(id);
199
+ if (it != globalConsES._varToVAddrs.end()) return it->second;
200
+ return _varToVAddrs[id];
201
+ }
202
+
203
+ virtual VAddrs &loadVAddrs(u32_t addr) override
204
+ {
205
+ assert(isVirtualMemAddress(addr) && "not virtual address?");
206
+ u32_t objId = getInternalID(addr);
207
+ auto it = _locToVAddrs.find(objId);
208
+ if (it != _locToVAddrs.end())
209
+ {
210
+ return it->second;
211
+ }
212
+ else
213
+ {
214
+ auto globIt = globalConsES._locToVAddrs.find(objId);
215
+ if (globIt != globalConsES._locToVAddrs.end())
216
+ {
217
+ return globIt->second;
218
+ }
219
+ else
220
+ {
221
+ return getVAddrs(0);
222
+ }
223
+ }
224
+ }
225
+
226
+ virtual std::string varToAddrs(u32_t varId) const override
227
+ {
228
+ std::stringstream exprName;
229
+ auto it = _varToVAddrs.find(varId);
230
+ if (it == _varToVAddrs.end())
231
+ {
232
+ auto git = globalConsES._varToVAddrs.find(varId);
233
+ if (git == globalConsES._varToVAddrs.end())
234
+ exprName << "Var not in varToAddrs!\n";
235
+ else
236
+ {
237
+ const VAddrs &vaddrs = git->second;
238
+ if (vaddrs.size() == 1)
239
+ {
240
+ exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
241
+ }
242
+ else
243
+ {
244
+ exprName << "addr: {";
245
+ for (const auto &addr: vaddrs)
246
+ {
247
+ exprName << std::dec << getInternalID(addr) << ", ";
248
+ }
249
+ exprName << "}\n";
250
+ }
251
+ }
252
+ }
253
+ else
254
+ {
255
+ const VAddrs &vaddrs = it->second;
256
+ if (vaddrs.size() == 1)
257
+ {
258
+ exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
259
+ }
260
+ else
261
+ {
262
+ exprName << "addr: {";
263
+ for (const auto &addr: vaddrs)
264
+ {
265
+ exprName << std::dec << getInternalID(addr) << ", ";
266
+ }
267
+ exprName << "}\n";
268
+ }
269
+ }
270
+ return SVFUtil::move(exprName.str());
271
+ }
272
+
273
+ virtual std::string locToAddrs(u32_t objId) const override
274
+ {
275
+ std::stringstream exprName;
276
+ auto it = _locToVAddrs.find(objId);
277
+ if (it == _locToVAddrs.end())
278
+ {
279
+ auto git = globalConsES._locToVAddrs.find(objId);
280
+ if (git == globalConsES._locToVAddrs.end())
281
+ exprName << "Obj not in locToVal!\n";
282
+ else
283
+ {
284
+ const VAddrs &vaddrs = git->second;
285
+ if (vaddrs.size() == 1)
286
+ {
287
+ exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
288
+ }
289
+ else
290
+ {
291
+ exprName << "addr: {";
292
+ for (const auto &addr: vaddrs)
293
+ {
294
+ exprName << std::dec << getInternalID(addr) << ", ";
295
+ }
296
+ exprName << "}\n";
297
+ }
298
+ }
299
+ }
300
+ else
301
+ {
302
+ const VAddrs &vaddrs = it->second;
303
+ if (vaddrs.size() == 1)
304
+ {
305
+ exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
306
+ }
307
+ else
308
+ {
309
+ exprName << "addr: {";
310
+ for (const auto &addr: vaddrs)
311
+ {
312
+ exprName << std::dec << getInternalID(addr) << ", ";
313
+ }
314
+ exprName << "}\n";
315
+ }
316
+ }
317
+ return SVFUtil::move(exprName.str());
318
+ }
319
+
320
+ /// Empty execution state with a true path constraint
321
+ static inline ConsExeState initExeState()
322
+ {
323
+ VarToValMap mp;
324
+ ConsExeState exeState(mp, SVFUtil::move(mp));
325
+ return SVFUtil::move(exeState);
326
+ }
327
+
328
+ /// Empty execution state with a null expr
329
+ static inline ConsExeState nullExeState()
330
+ {
331
+ VarToValMap mp;
332
+ ConsExeState exeState(mp, SVFUtil::move(mp));
333
+ exeState._varToVal[PAG::getPAG()->getNullPtr()] = -1;
334
+ return SVFUtil::move(exeState);
335
+ }
336
+
337
+ public:
338
+
339
+ inline const VarToValMap &getVarToVal() const
340
+ {
341
+ return _varToVal;
342
+ }
343
+
344
+ inline const LocToValMap &getLocToVal() const
345
+ {
346
+ return _locToVal;
347
+ }
348
+
349
+
350
+ s64_t getNumber(u32_t lhs);
351
+
352
+ public:
353
+
354
+
355
+ static inline SingleAbsValue getIntOneZ3Expr()
356
+ {
357
+ return getContext().int_val(1);
358
+ }
359
+
360
+ static inline SingleAbsValue getIntZeroZ3Expr()
361
+ {
362
+ return getContext().int_val(0);
363
+ }
364
+
365
+ static inline SingleAbsValue getTrueZ3Expr()
366
+ {
367
+ return getContext().bool_val(true);
368
+ }
369
+
370
+ static inline SingleAbsValue getFalseZ3Expr()
371
+ {
372
+ return getContext().bool_val(false);
373
+ }
374
+
375
+ public:
376
+ inline SingleAbsValue &operator[](u32_t varId)
377
+ {
378
+ auto it = globalConsES._varToVal.find(varId);
379
+ if (it != globalConsES._varToVal.end())
380
+ return it->second;
381
+ else
382
+ return _varToVal[varId];
383
+ }
384
+
385
+ /// Store value to location
386
+ bool store(const SingleAbsValue &loc, const SingleAbsValue &value);
387
+
388
+ /// Load value at location
389
+ SingleAbsValue load(const SingleAbsValue &loc);
390
+
391
+ /// Return int value from an expression if it is a numeral, otherwise return an approximate value
392
+ static inline s32_t z3Expr2NumValue(const SingleAbsValue &e)
393
+ {
394
+ assert(e.is_numeral() && "not numeral?");
395
+ int64_t i;
396
+ if(e.getExpr().is_numeral_i64(i))
397
+ return e.get_numeral_int64();
398
+ else
399
+ {
400
+ return e.leq(0) ? INT32_MIN : INT32_MAX;
401
+ }
402
+ }
403
+
404
+ /// Whether two var to value map is equivalent
405
+ static bool eqVarToValMap(const VarToValMap &pre, const VarToValMap &nxt);
406
+
407
+
408
+ /// Whether lhs is less than rhs
409
+ static bool lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs);
410
+
411
+
412
+ private:
413
+
414
+
415
+ static bool assign(SingleAbsValue &lhs, const SingleAbsValue &rhs);
416
+
417
+ inline bool store(u32_t objId, const SingleAbsValue &z3Expr)
418
+ {
419
+ SingleAbsValue &lhs = _locToVal[objId];
420
+ if (!eq(lhs, z3Expr.simplify()))
421
+ {
422
+ lhs = z3Expr.simplify();
423
+ return true;
424
+ }
425
+ else
426
+ return false;
427
+ }
428
+
429
+ inline SingleAbsValue load(u32_t objId);
430
+ }; // end class ConExeState
431
+
432
+ } // end namespace SVF
433
+
434
+ /// Specialized hash for ConExeState
435
+ template<>
436
+ struct std::hash<SVF::ConsExeState>
437
+ {
438
+ size_t operator()(const SVF::ConsExeState &exeState) const
439
+ {
440
+ return exeState.hash();
441
+ }
442
+ };
443
+
444
+
445
+
446
+ #endif // SVF_CONSEXESTATE_H
@@ -54,7 +54,7 @@ public:
54
54
  /// Execution state kind
55
55
  enum ExeState_TYPE
56
56
  {
57
- IntervalK, ConcreteK
57
+ IntervalK, SingleValueK
58
58
  };
59
59
  private:
60
60
  ExeState_TYPE _kind;
@@ -90,9 +90,9 @@ public:
90
90
  return *this;
91
91
  }
92
92
 
93
- bool operator==(const ExeState &rhs) const;
93
+ virtual bool operator==(const ExeState &rhs) const;
94
94
 
95
- inline bool operator!=(const ExeState &rhs) const
95
+ inline virtual bool operator!=(const ExeState &rhs) const
96
96
  {
97
97
  return !(*this == rhs);
98
98
  }
@@ -103,10 +103,10 @@ public:
103
103
  }
104
104
 
105
105
  /// Make all value join with the other
106
- void joinWith(const ExeState &other);
106
+ bool joinWith(const ExeState &other);
107
107
 
108
108
  /// Make all value meet with the other
109
- void meetWith(const ExeState &other);
109
+ bool meetWith(const ExeState &other);
110
110
 
111
111
  virtual u32_t hash() const;
112
112
 
@@ -190,6 +190,64 @@ protected:
190
190
  return true;
191
191
  }
192
192
 
193
+ public:
194
+
195
+ virtual std::string varToAddrs(u32_t varId) const
196
+ {
197
+ std::stringstream exprName;
198
+ auto it = _varToVAddrs.find(varId);
199
+ if (it == _varToVAddrs.end())
200
+ {
201
+ exprName << "Var not in varToAddrs!\n";
202
+ }
203
+ else
204
+ {
205
+ const VAddrs &vaddrs = it->second;
206
+ if (vaddrs.size() == 1)
207
+ {
208
+ exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
209
+ }
210
+ else
211
+ {
212
+ exprName << "addr: {";
213
+ for (const auto &addr: vaddrs)
214
+ {
215
+ exprName << std::dec << getInternalID(addr) << ", ";
216
+ }
217
+ exprName << "}\n";
218
+ }
219
+ }
220
+ return SVFUtil::move(exprName.str());
221
+ }
222
+
223
+ virtual std::string locToAddrs(u32_t objId) const
224
+ {
225
+ std::stringstream exprName;
226
+ auto it = _locToVAddrs.find(objId);
227
+ if (it == _locToVAddrs.end())
228
+ {
229
+ exprName << "Var not in varToAddrs!\n";
230
+ }
231
+ else
232
+ {
233
+ const VAddrs &vaddrs = it->second;
234
+ if (vaddrs.size() == 1)
235
+ {
236
+ exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
237
+ }
238
+ else
239
+ {
240
+ exprName << "addr: {";
241
+ for (const auto &addr: vaddrs)
242
+ {
243
+ exprName << std::dec << getInternalID(addr) << ", ";
244
+ }
245
+ exprName << "}\n";
246
+ }
247
+ }
248
+ return SVFUtil::move(exprName.str());
249
+ }
250
+
193
251
  public:
194
252
  static z3::context &getContext()
195
253
  {
@@ -220,4 +278,13 @@ public:
220
278
 
221
279
 
222
280
  } // end namespace SVF
281
+
282
+ template<>
283
+ struct std::hash<SVF::ExeState>
284
+ {
285
+ size_t operator()(const SVF::ExeState &es) const
286
+ {
287
+ return es.hash();
288
+ }
289
+ };
223
290
  #endif //Z3_EXAMPLE_EXESTATE_H
@@ -25,6 +25,19 @@
25
25
  * Created on: Jul 9, 2022
26
26
  * Author: Xiao Cheng, Jiawei Wang
27
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
+ * ⊥
28
41
  */
29
42
 
30
43
  #ifndef Z3_EXAMPLE_INTERVAL_DOMAIN_H