svf-tools 1.0.942 → 1.0.944

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.942",
3
+ "version": "1.0.944",
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": {
@@ -183,20 +183,6 @@ public:
183
183
  return _varToAbsVal.at(varId);
184
184
  }
185
185
 
186
- /// get memory addresses of variable
187
- AbstractValue &getAddrs(u32_t id)
188
- {
189
- if (_varToAbsVal.find(id)!= _varToAbsVal.end())
190
- {
191
- return _varToAbsVal[id];
192
- }
193
- else
194
- {
195
- _varToAbsVal[id] = AddressValue();
196
- return _varToAbsVal[id];
197
- }
198
- }
199
-
200
186
  /// whether the variable is in varToAddrs table
201
187
  inline bool inVarToAddrsTable(u32_t id) const
202
188
  {
@@ -289,31 +275,6 @@ public:
289
275
  return (s32_t) e.lb().getNumeral();
290
276
  }
291
277
 
292
- /// Return true if map has bottom value
293
- inline bool has_bottom()
294
- {
295
- for (auto it = _varToAbsVal.begin(); it != _varToAbsVal.end(); ++it)
296
- {
297
- if (it->second.isInterval())
298
- {
299
- if (it->second.getInterval().isBottom())
300
- {
301
- return true;
302
- }
303
- }
304
- }
305
- for (auto it = _addrToAbsVal.begin(); it != _addrToAbsVal.end(); ++it)
306
- {
307
- if (it->second.isInterval())
308
- {
309
- if (it->second.getInterval().isBottom())
310
- {
311
- return true;
312
- }
313
- }
314
- }
315
- return false;
316
- }
317
278
 
318
279
  u32_t hash() const;
319
280
 
@@ -330,14 +291,8 @@ public:
330
291
  {
331
292
  assert(isVirtualMemAddress(addr) && "not virtual address?");
332
293
  u32_t objId = getInternalID(addr);
333
- auto it = _addrToAbsVal.find(objId);
334
- if(it != _addrToAbsVal.end())
335
- return it->second;
336
- else
337
- {
338
- _addrToAbsVal[objId] = IntervalValue::top();
339
- return _addrToAbsVal[objId];
340
- }
294
+ return _addrToAbsVal[objId];
295
+
341
296
  }
342
297
 
343
298
 
@@ -351,6 +306,7 @@ public:
351
306
 
352
307
  bool equals(const AbstractState&other) const;
353
308
 
309
+
354
310
  static bool eqVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs)
355
311
  {
356
312
  if (lhs.size() != rhs.size()) return false;
@@ -359,32 +315,15 @@ public:
359
315
  auto it = rhs.find(item.first);
360
316
  if (it == rhs.end())
361
317
  return false;
362
- if (item.second.getType() == it->second.getType())
363
- {
364
- if (item.second.isInterval())
365
- {
366
- if (!item.second.getInterval().equals(it->second.getInterval()))
367
- {
368
- return false;
369
- }
370
- }
371
- else if (item.second.isAddr())
372
- {
373
- if (!item.second.getAddrs().equals(it->second.getAddrs()))
374
- {
375
- return false;
376
- }
377
- }
378
- }
318
+ if (!item.second.equals(it->second))
319
+ return false;
379
320
  else
380
321
  {
381
- return false;
382
322
  }
383
323
  }
384
324
  return true;
385
325
  }
386
326
 
387
-
388
327
  static bool lessThanVarToValMap(const VarToAbsValMap&lhs, const VarToAbsValMap&rhs)
389
328
  {
390
329
  if (lhs.empty()) return !rhs.empty();
@@ -407,12 +346,9 @@ public:
407
346
  auto it = lhs.find(item.first);
408
347
  if (it == lhs.end()) return false;
409
348
  // judge from expr id
410
- if (it->second.isInterval() && item.second.isInterval())
411
- {
412
- if (!it->second.getInterval().contain(
413
- item.second.getInterval()))
414
- return false;
415
- }
349
+ if (!it->second.getInterval().contain(
350
+ item.second.getInterval()))
351
+ return false;
416
352
 
417
353
  }
418
354
  return true;
@@ -22,6 +22,7 @@
22
22
 
23
23
  #include "AE/Core/IntervalValue.h"
24
24
  #include "AE/Core/AddressValue.h"
25
+ #include "Util/SVFUtil.h"
25
26
 
26
27
  namespace SVF
27
28
  {
@@ -30,126 +31,71 @@ class AbstractValue
30
31
  {
31
32
 
32
33
  public:
33
-
34
- enum DataType
35
- {
36
- IntervalType,
37
- AddressType,
38
- UnknownType,
39
- };
40
- DataType type;
41
34
  IntervalValue interval;
42
35
  AddressValue addrs;
43
36
 
44
- AbstractValue() : type(IntervalType)
45
- {
46
- interval = IntervalValue::top();
47
- }
48
- AbstractValue(DataType type) : type(type)
37
+ AbstractValue()
49
38
  {
50
- switch (type)
51
- {
52
- case IntervalType:
53
- interval = IntervalValue::top();
54
- break;
55
- case AddressType:
56
- addrs = AddressValue();
57
- break;
58
- case UnknownType:
59
- break;
60
- }
39
+ interval = IntervalValue::bottom();
40
+ addrs = AddressValue();
61
41
  }
62
42
 
63
- AbstractValue(const AbstractValue& other): type(other.type)
43
+ AbstractValue(const AbstractValue& other)
64
44
  {
65
- switch (type)
66
- {
67
- case IntervalType:
68
- interval = other.interval;
69
- break;
70
- case AddressType:
71
- addrs = other.addrs;
72
- break;
73
- case UnknownType:
74
- break;
75
- }
45
+ interval = other.interval;
46
+ addrs = other.addrs;
76
47
  }
77
48
 
78
49
  inline bool isInterval() const
79
50
  {
80
- return type == IntervalType;
51
+ return !interval.isBottom();
81
52
  }
82
53
  inline bool isAddr() const
83
54
  {
84
- return type == AddressType;
85
- }
86
- inline bool isUnknown() const
87
- {
88
- return type == UnknownType;
55
+ return !addrs.isBottom();
89
56
  }
90
57
 
91
- inline DataType getType() const
58
+ AbstractValue(AbstractValue &&other)
92
59
  {
93
- return type;
60
+ interval = SVFUtil::move(other.interval);
61
+ addrs = SVFUtil::move(other.addrs);
94
62
  }
95
63
 
96
- AbstractValue(AbstractValue &&other) : type(other.type)
64
+ // operator overload, supporting both interval and address
65
+ AbstractValue& operator=(const AbstractValue& other)
97
66
  {
98
- switch (type)
99
- {
100
- case IntervalType:
101
- interval = other.interval;
102
- break;
103
- case AddressType:
104
- addrs = other.addrs;
105
- break;
106
- case UnknownType:
107
- break;
108
- }
67
+ interval = other.interval;
68
+ addrs = other.addrs;
69
+ return *this;
109
70
  }
110
71
 
111
- // operator overload, supporting both interval and address
112
- AbstractValue& operator=(const AbstractValue& other)
72
+ AbstractValue& operator=(const AbstractValue&& other)
113
73
  {
114
- type = other.type;
115
- switch (type)
116
- {
117
- case IntervalType:
118
- interval = other.interval;
119
- break;
120
- case AddressType:
121
- addrs = other.addrs;
122
- break;
123
- case UnknownType:
124
- break;
125
- }
74
+ interval = SVFUtil::move(other.interval);
75
+ addrs = SVFUtil::move(other.addrs);
126
76
  return *this;
127
77
  }
128
78
 
129
79
  AbstractValue& operator=(const IntervalValue& other)
130
80
  {
131
- type = IntervalType;
132
81
  interval = other;
82
+ addrs = AddressValue();
133
83
  return *this;
134
84
  }
135
85
 
136
86
  AbstractValue& operator=(const AddressValue& other)
137
87
  {
138
- type = AddressType;
139
88
  addrs = other;
89
+ interval = IntervalValue::bottom();
140
90
  return *this;
141
91
  }
142
92
 
143
- AbstractValue(const IntervalValue& ival) : type(IntervalType), interval(ival) {}
93
+ AbstractValue(const IntervalValue& ival) : interval(ival), addrs(AddressValue()) {}
144
94
 
145
- AbstractValue(const AddressValue& addr) : type(AddressType), addrs(addr) {}
95
+ AbstractValue(const AddressValue& addr) : interval(IntervalValue::bottom()), addrs(addr) {}
146
96
 
147
97
  IntervalValue& getInterval()
148
98
  {
149
- if (isUnknown())
150
- {
151
- interval = IntervalValue::top();
152
- }
153
99
  return interval;
154
100
  }
155
101
 
@@ -172,90 +118,36 @@ public:
172
118
 
173
119
  bool equals(const AbstractValue &rhs) const
174
120
  {
175
- if (type != rhs.type)
176
- {
177
- return false;
178
- }
179
- if (isInterval())
180
- {
181
- return interval.equals(rhs.interval);
182
- }
183
- if (isAddr())
184
- {
185
- return addrs.equals(rhs.addrs);
186
- }
187
- return false;
121
+ return interval.equals(rhs.interval) && addrs.equals(rhs.addrs);
188
122
  }
189
123
 
190
124
  void join_with(const AbstractValue &other)
191
125
  {
192
- if (isUnknown())
193
- {
194
- *this = other;
195
- return;
196
- }
197
- else if (type != other.type)
198
- {
199
- return;
200
- }
201
- if (isInterval() && other.isInterval())
202
- {
203
- interval.join_with(other.interval);
204
- }
205
- if (isAddr() && other.isAddr())
206
- {
207
- addrs.join_with(other.addrs);
208
- }
209
- return;
126
+ interval.join_with(other.interval);
127
+ addrs.join_with(other.addrs);
210
128
  }
211
129
 
212
130
  void meet_with(const AbstractValue &other)
213
131
  {
214
- if (type != other.type)
215
- {
216
- return;
217
- }
218
- if (isInterval() && other.isInterval())
219
- {
220
- interval.meet_with(other.interval);
221
- }
222
- if (isAddr() && other.isAddr())
223
- {
224
- addrs.meet_with(other.addrs);
225
- }
226
- return;
132
+ interval.meet_with(other.interval);
133
+ addrs.meet_with(other.addrs);
227
134
  }
228
135
 
229
136
  void widen_with(const AbstractValue &other)
230
137
  {
231
- // widen_with only in interval
232
- if (isInterval() && other.isInterval())
233
- {
234
- interval.widen_with(other.interval);
235
- }
138
+ interval.widen_with(other.interval);
139
+ // TODO: widen Addrs
236
140
  }
237
141
 
238
142
  void narrow_with(const AbstractValue &other)
239
143
  {
240
- // narrow_with only in interval
241
- if (isInterval() && other.isInterval())
242
- {
243
- interval.narrow_with(other.interval);
244
- }
144
+ interval.narrow_with(other.interval);
145
+ // TODO: narrow Addrs
245
146
  }
246
147
 
247
148
  std::string toString() const
248
149
  {
249
- if (isInterval())
250
- {
251
- return interval.toString();
252
- }
253
- else if (isAddr())
254
- {
255
- return addrs.toString();
256
- }
257
- return "";
150
+ return "<" + interval.toString() + ", " + addrs.toString() + ">";
258
151
  }
259
-
260
152
  };
261
153
  }
@@ -62,19 +62,19 @@ public:
62
62
  void narrowAddrs(AbstractState& es, AbstractState&lhs, const AbstractState&rhs);
63
63
 
64
64
  /// Return the field address given a pointer points to a struct object and an offset
65
- AbstractValue getGepObjAddress(AbstractState& es, u32_t pointer, APOffset offset);
65
+ AddressValue getGepObjAddress(AbstractState& es, u32_t pointer, APOffset offset);
66
66
 
67
67
  /// Return the value range of Integer SVF Type, e.g. unsigned i8 Type->[0, 255], signed i8 Type->[-128, 127]
68
- AbstractValue getRangeLimitFromType(const SVFType* type);
68
+ IntervalValue getRangeLimitFromType(const SVFType* type);
69
69
 
70
- AbstractValue getZExtValue(const AbstractState& es, const SVFVar* var);
71
- AbstractValue getSExtValue(const AbstractState& es, const SVFVar* var);
72
- AbstractValue getFPToSIntValue(const AbstractState& es, const SVFVar* var);
73
- AbstractValue getFPToUIntValue(const AbstractState& es, const SVFVar* var);
74
- AbstractValue getSIntToFPValue(const AbstractState& es, const SVFVar* var);
75
- AbstractValue getUIntToFPValue(const AbstractState& es, const SVFVar* var);
76
- AbstractValue getTruncValue(const AbstractState& es, const SVFVar* var, const SVFType* dstType);
77
- AbstractValue getFPTruncValue(const AbstractState& es, const SVFVar* var, const SVFType* dstType);
70
+ IntervalValue getZExtValue(const AbstractState& es, const SVFVar* var);
71
+ IntervalValue getSExtValue(const AbstractState& es, const SVFVar* var);
72
+ IntervalValue getFPToSIntValue(const AbstractState& es, const SVFVar* var);
73
+ IntervalValue getFPToUIntValue(const AbstractState& es, const SVFVar* var);
74
+ IntervalValue getSIntToFPValue(const AbstractState& es, const SVFVar* var);
75
+ IntervalValue getUIntToFPValue(const AbstractState& es, const SVFVar* var);
76
+ IntervalValue getTruncValue(const AbstractState& es, const SVFVar* var, const SVFType* dstType);
77
+ IntervalValue getFPTruncValue(const AbstractState& es, const SVFVar* var, const SVFType* dstType);
78
78
 
79
79
  /// Return the byte offset expression of a GepStmt
80
80
  /// elemBytesize is the element byte size of an static alloc or heap alloc array
@@ -96,15 +96,13 @@ public:
96
96
 
97
97
 
98
98
  /// Init ObjVar
99
- void initObjVar(AbstractState& es, const ObjVar *objVar, u32_t varId);
99
+ void initObjVar(AbstractState& as, const ObjVar* var);
100
100
 
101
- /// Init SVFVar
102
- void initSVFVar(AbstractState& es, u32_t varId);
103
101
 
104
102
  inline AbstractValue &getAddrs(AbstractState& es, u32_t id)
105
103
  {
106
104
  if (inVarToAddrsTable(es, id))
107
- return es.getAddrs(id);
105
+ return es[id];
108
106
  else
109
107
  return globalNulladdrs;
110
108
  }
@@ -125,18 +125,7 @@ void AbstractState::joinWith(const AbstractState& other)
125
125
  auto oit = _varToAbsVal.find(key);
126
126
  if (oit != _varToAbsVal.end())
127
127
  {
128
- if (oit->second.isInterval() && it->second.isInterval())
129
- {
130
- oit->second.getInterval().join_with(it->second.getInterval());
131
- }
132
- else if (oit->second.isAddr() && it->second.isAddr())
133
- {
134
- oit->second.getAddrs().join_with(it->second.getAddrs());
135
- }
136
- else
137
- {
138
- // do nothing
139
- }
128
+ oit->second.join_with(it->second);
140
129
  }
141
130
  else
142
131
  {
@@ -149,18 +138,7 @@ void AbstractState::joinWith(const AbstractState& other)
149
138
  auto oit = _addrToAbsVal.find(key);
150
139
  if (oit != _addrToAbsVal.end())
151
140
  {
152
- if (oit->second.isInterval() && it->second.isInterval())
153
- {
154
- oit->second.getInterval().join_with(it->second.getInterval());
155
- }
156
- else if (oit->second.isAddr() && it->second.isAddr())
157
- {
158
- oit->second.getAddrs().join_with(it->second.getAddrs());
159
- }
160
- else
161
- {
162
- // do nothing
163
- }
141
+ oit->second.join_with(it->second);
164
142
  }
165
143
  else
166
144
  {
@@ -199,18 +177,7 @@ void AbstractState::meetWith(const AbstractState& other)
199
177
  auto oit = _varToAbsVal.find(key);
200
178
  if (oit != _varToAbsVal.end())
201
179
  {
202
- if (oit->second.isInterval() && it->second.isInterval())
203
- {
204
- oit->second.getInterval().meet_with(it->second.getInterval());
205
- }
206
- else if (oit->second.isAddr() && it->second.isAddr())
207
- {
208
- oit->second.getAddrs().meet_with(it->second.getAddrs());
209
- }
210
- else
211
- {
212
- // do nothing
213
- }
180
+ oit->second.meet_with(it->second);
214
181
  }
215
182
  }
216
183
  for (auto it = other._addrToAbsVal.begin(); it != other._addrToAbsVal.end(); ++it)
@@ -219,18 +186,7 @@ void AbstractState::meetWith(const AbstractState& other)
219
186
  auto oit = _addrToAbsVal.find(key);
220
187
  if (oit != _addrToAbsVal.end())
221
188
  {
222
- if (oit->second.isInterval() && it->second.isInterval())
223
- {
224
- oit->second.getInterval().meet_with(it->second.getInterval());
225
- }
226
- else if (oit->second.isAddr() && it->second.isAddr())
227
- {
228
- oit->second.getAddrs().meet_with(it->second.getAddrs());
229
- }
230
- else
231
- {
232
- // do nothing
233
- }
189
+ oit->second.meet_with(it->second);
234
190
  }
235
191
  }
236
192
  }
@@ -255,15 +211,6 @@ void AbstractState::printTable(const VarToAbsValMap&table, std::ostream &oss) co
255
211
  for (const auto &item: ordered)
256
212
  {
257
213
  oss << "Var" << std::to_string(item);
258
- if (table.at(item).isInterval())
259
- {
260
- IntervalValue sim = table.at(item).getInterval();
261
- oss << "\t Value: " << std::dec << sim << "\n";
262
- }
263
- else if (table.at(item).isAddr())
264
- {
265
- AbstractValue sim = table.at(item);
266
- oss << "\t Value: " << sim.getAddrs().toString() << "\n";
267
- }
214
+ oss << "\t Value: " << table.at(item).toString() << "\n";
268
215
  }
269
216
  }
@@ -331,7 +331,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s
331
331
  // change interval range according to the compare predicate
332
332
  AddressValue addrs;
333
333
  if(load_op0 && new_es.inVarToAddrsTable(load_op0->getRHSVarID()))
334
- addrs = new_es.getAddrs(load_op0->getRHSVarID()).getAddrs();
334
+ addrs = new_es[load_op0->getRHSVarID()].getAddrs();
335
335
 
336
336
  IntervalValue &lhs = new_es[op0].getInterval(), &rhs = new_es[op1].getInterval();
337
337
  switch (predicate)
@@ -472,7 +472,7 @@ bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t suc
472
472
  {
473
473
  if (new_es.inVarToAddrsTable(load->getRHSVarID()))
474
474
  {
475
- AddressValue &addrs = new_es.getAddrs(load->getRHSVarID()).getAddrs();
475
+ AddressValue &addrs = new_es[load->getRHSVarID()].getAddrs();
476
476
  for (const auto &addr: addrs)
477
477
  {
478
478
  NodeID objId = new_es.getInternalID(addr);
@@ -930,7 +930,7 @@ void AbstractInterpretation::SkipRecursiveCall(const CallICFGNode *callNode)
930
930
  {
931
931
  if (!rhsVar->isPointer() && !rhsVar->isConstDataOrAggDataButNotNullPtr())
932
932
  {
933
- const AbstractValue &addrs = as.getAddrs(lhs);
933
+ const AbstractValue &addrs = as[lhs];
934
934
  for (const auto &addr: addrs.getAddrs())
935
935
  {
936
936
  as.store(addr, IntervalValue::top());
@@ -1147,13 +1147,11 @@ std::string AbstractInterpretation::strRead(AbstractState& as, const SVFValue* r
1147
1147
  if (!as.inVarToAddrsTable(_svfir->getValueNode(rhs))) continue;
1148
1148
  AbstractValue expr0 =
1149
1149
  _svfir2AbsState->getGepObjAddress(as, _svfir->getValueNode(rhs), index);
1150
- AbstractValue val(AbstractValue::UnknownType);
1150
+ AbstractValue val;
1151
1151
  for (const auto &addr: expr0.getAddrs())
1152
1152
  {
1153
1153
  val.join_with(as.load(addr));
1154
1154
  }
1155
- if (val.isUnknown())
1156
- return str0;
1157
1155
  if (!val.getInterval().is_numeral())
1158
1156
  {
1159
1157
  break;
@@ -1464,15 +1462,11 @@ IntervalValue AbstractInterpretation::getStrlen(AbstractState& as, const SVF::SV
1464
1462
  {
1465
1463
  AbstractValue expr0 =
1466
1464
  _svfir2AbsState->getGepObjAddress(as, dstid, index);
1467
- AbstractValue val(AbstractValue::UnknownType);
1465
+ AbstractValue val;
1468
1466
  for (const auto &addr: expr0.getAddrs())
1469
1467
  {
1470
1468
  val.join_with(as.load(addr));
1471
1469
  }
1472
- if (val.isUnknown())
1473
- {
1474
- return IntervalValue((s64_t)0, (s64_t)Options::MaxFieldLimit());
1475
- }
1476
1470
  if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
1477
1471
  {
1478
1472
  break;