svf-tools 1.0.940 → 1.0.942
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 +1 -1
- package/svf/include/AE/Core/AbstractState.h +5 -4
- package/svf/include/AE/Core/AbstractValue.h +13 -42
- package/svf/include/AE/Core/AddressValue.h +3 -1
- package/svf/include/AE/Core/IntervalValue.h +46 -4
- package/svf/include/AE/Core/RelExeState.h +2 -0
- package/svf/include/AE/Svfexe/SVFIR2AbsState.h +11 -2
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +10 -9
- package/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp +76 -109
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.942",
|
|
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": {
|
|
@@ -224,7 +224,7 @@ public:
|
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
/// whether the memory address stores memory addresses
|
|
227
|
-
inline bool
|
|
227
|
+
inline bool inAddrToAddrsTable(u32_t id) const
|
|
228
228
|
{
|
|
229
229
|
if (_addrToAbsVal.find(id)!= _addrToAbsVal.end())
|
|
230
230
|
{
|
|
@@ -237,7 +237,7 @@ public:
|
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
/// whether the memory address stores abstract value
|
|
240
|
-
inline virtual bool
|
|
240
|
+
inline virtual bool inAddrToValTable(u32_t id) const
|
|
241
241
|
{
|
|
242
242
|
if (_addrToAbsVal.find(id) != _addrToAbsVal.end())
|
|
243
243
|
{
|
|
@@ -393,7 +393,7 @@ public:
|
|
|
393
393
|
auto it = rhs.find(item.first);
|
|
394
394
|
if (it == rhs.end()) return false;
|
|
395
395
|
// judge from expr id
|
|
396
|
-
if (item.second.getInterval().
|
|
396
|
+
if (item.second.getInterval().contain(it->second.getInterval())) return false;
|
|
397
397
|
}
|
|
398
398
|
return true;
|
|
399
399
|
}
|
|
@@ -409,7 +409,8 @@ public:
|
|
|
409
409
|
// judge from expr id
|
|
410
410
|
if (it->second.isInterval() && item.second.isInterval())
|
|
411
411
|
{
|
|
412
|
-
if (!it->second.getInterval().
|
|
412
|
+
if (!it->second.getInterval().contain(
|
|
413
|
+
item.second.getInterval()))
|
|
413
414
|
return false;
|
|
414
415
|
}
|
|
415
416
|
|
|
@@ -39,7 +39,7 @@ public:
|
|
|
39
39
|
};
|
|
40
40
|
DataType type;
|
|
41
41
|
IntervalValue interval;
|
|
42
|
-
AddressValue
|
|
42
|
+
AddressValue addrs;
|
|
43
43
|
|
|
44
44
|
AbstractValue() : type(IntervalType)
|
|
45
45
|
{
|
|
@@ -53,7 +53,7 @@ public:
|
|
|
53
53
|
interval = IntervalValue::top();
|
|
54
54
|
break;
|
|
55
55
|
case AddressType:
|
|
56
|
-
|
|
56
|
+
addrs = AddressValue();
|
|
57
57
|
break;
|
|
58
58
|
case UnknownType:
|
|
59
59
|
break;
|
|
@@ -68,7 +68,7 @@ public:
|
|
|
68
68
|
interval = other.interval;
|
|
69
69
|
break;
|
|
70
70
|
case AddressType:
|
|
71
|
-
|
|
71
|
+
addrs = other.addrs;
|
|
72
72
|
break;
|
|
73
73
|
case UnknownType:
|
|
74
74
|
break;
|
|
@@ -101,7 +101,7 @@ public:
|
|
|
101
101
|
interval = other.interval;
|
|
102
102
|
break;
|
|
103
103
|
case AddressType:
|
|
104
|
-
|
|
104
|
+
addrs = other.addrs;
|
|
105
105
|
break;
|
|
106
106
|
case UnknownType:
|
|
107
107
|
break;
|
|
@@ -118,7 +118,7 @@ public:
|
|
|
118
118
|
interval = other.interval;
|
|
119
119
|
break;
|
|
120
120
|
case AddressType:
|
|
121
|
-
|
|
121
|
+
addrs = other.addrs;
|
|
122
122
|
break;
|
|
123
123
|
case UnknownType:
|
|
124
124
|
break;
|
|
@@ -136,38 +136,13 @@ public:
|
|
|
136
136
|
AbstractValue& operator=(const AddressValue& other)
|
|
137
137
|
{
|
|
138
138
|
type = AddressType;
|
|
139
|
-
|
|
139
|
+
addrs = other;
|
|
140
140
|
return *this;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
AbstractValue operator==(const AbstractValue& other) const
|
|
144
|
-
{
|
|
145
|
-
assert(isInterval() && other.isInterval());
|
|
146
|
-
return interval == other.interval;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
AbstractValue operator==(const IntervalValue& other) const
|
|
150
|
-
{
|
|
151
|
-
assert(isInterval());
|
|
152
|
-
return interval == other;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
AbstractValue operator!=(const AbstractValue& other) const
|
|
156
|
-
{
|
|
157
|
-
assert(isInterval());
|
|
158
|
-
return interval != other.interval;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
AbstractValue operator!=(const IntervalValue& other) const
|
|
162
|
-
{
|
|
163
|
-
assert(isInterval());
|
|
164
|
-
return interval != other;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
143
|
AbstractValue(const IntervalValue& ival) : type(IntervalType), interval(ival) {}
|
|
169
144
|
|
|
170
|
-
AbstractValue(const AddressValue& addr) : type(AddressType),
|
|
145
|
+
AbstractValue(const AddressValue& addr) : type(AddressType), addrs(addr) {}
|
|
171
146
|
|
|
172
147
|
IntervalValue& getInterval()
|
|
173
148
|
{
|
|
@@ -175,26 +150,22 @@ public:
|
|
|
175
150
|
{
|
|
176
151
|
interval = IntervalValue::top();
|
|
177
152
|
}
|
|
178
|
-
assert(isInterval() && "Attempting to retrieve an AbstractValue that is not an Interval!");
|
|
179
153
|
return interval;
|
|
180
154
|
}
|
|
181
155
|
|
|
182
156
|
const IntervalValue getInterval() const
|
|
183
157
|
{
|
|
184
|
-
assert(isInterval() && "Attempting to retrieve an AbstractValue that is not an Interval!");
|
|
185
158
|
return interval;
|
|
186
159
|
}
|
|
187
160
|
|
|
188
161
|
AddressValue& getAddrs()
|
|
189
162
|
{
|
|
190
|
-
|
|
191
|
-
return addr;
|
|
163
|
+
return addrs;
|
|
192
164
|
}
|
|
193
165
|
|
|
194
166
|
const AddressValue getAddrs() const
|
|
195
167
|
{
|
|
196
|
-
|
|
197
|
-
return addr;
|
|
168
|
+
return addrs;
|
|
198
169
|
}
|
|
199
170
|
|
|
200
171
|
~AbstractValue() {};
|
|
@@ -211,7 +182,7 @@ public:
|
|
|
211
182
|
}
|
|
212
183
|
if (isAddr())
|
|
213
184
|
{
|
|
214
|
-
return
|
|
185
|
+
return addrs.equals(rhs.addrs);
|
|
215
186
|
}
|
|
216
187
|
return false;
|
|
217
188
|
}
|
|
@@ -233,7 +204,7 @@ public:
|
|
|
233
204
|
}
|
|
234
205
|
if (isAddr() && other.isAddr())
|
|
235
206
|
{
|
|
236
|
-
|
|
207
|
+
addrs.join_with(other.addrs);
|
|
237
208
|
}
|
|
238
209
|
return;
|
|
239
210
|
}
|
|
@@ -250,7 +221,7 @@ public:
|
|
|
250
221
|
}
|
|
251
222
|
if (isAddr() && other.isAddr())
|
|
252
223
|
{
|
|
253
|
-
|
|
224
|
+
addrs.meet_with(other.addrs);
|
|
254
225
|
}
|
|
255
226
|
return;
|
|
256
227
|
}
|
|
@@ -281,7 +252,7 @@ public:
|
|
|
281
252
|
}
|
|
282
253
|
else if (isAddr())
|
|
283
254
|
{
|
|
284
|
-
return
|
|
255
|
+
return addrs.toString();
|
|
285
256
|
}
|
|
286
257
|
return "";
|
|
287
258
|
}
|
|
@@ -211,13 +211,15 @@ public:
|
|
|
211
211
|
/// The physical address starts with 0x7f...... + idx
|
|
212
212
|
static inline u32_t getVirtualMemAddress(u32_t idx)
|
|
213
213
|
{
|
|
214
|
+
// 0 is the null address, should not be used as a virtual address
|
|
215
|
+
assert(idx != 0 && "idx can’t be 0 because it represents a nullptr");
|
|
214
216
|
return AddressMask + idx;
|
|
215
217
|
}
|
|
216
218
|
|
|
217
219
|
/// Check bit value of val start with 0x7F000000, filter by 0xFF000000
|
|
218
220
|
static inline bool isVirtualMemAddress(u32_t val)
|
|
219
221
|
{
|
|
220
|
-
return (val & 0xff000000) == AddressMask;
|
|
222
|
+
return (val & 0xff000000) == AddressMask && val != AddressMask + 0;
|
|
221
223
|
}
|
|
222
224
|
|
|
223
225
|
/// Return the internal index if idx is an address otherwise return the value of idx
|
|
@@ -298,8 +298,11 @@ public:
|
|
|
298
298
|
this->_ub = plus_infinity();
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
-
///
|
|
302
|
-
|
|
301
|
+
/// Determines if the current IntervalValue is fully contained within another IntervalValue.
|
|
302
|
+
/// Example: this: [2, 3], other: [1, 4] -> returns true
|
|
303
|
+
/// Note: If the current interval is 'bottom', it is considered contained within any interval.
|
|
304
|
+
/// If the other interval is 'bottom', it cannot contain any interval.
|
|
305
|
+
bool containedWithin(const IntervalValue &other) const
|
|
303
306
|
{
|
|
304
307
|
if (this->isBottom())
|
|
305
308
|
{
|
|
@@ -316,8 +319,11 @@ public:
|
|
|
316
319
|
|
|
317
320
|
}
|
|
318
321
|
|
|
319
|
-
///
|
|
320
|
-
|
|
322
|
+
/// Determines if the current IntervalValue fully contains another IntervalValue.
|
|
323
|
+
/// Example: this: [1, 4], other: [2, 3] -> returns true
|
|
324
|
+
/// Note: If the current interval is 'bottom', it is considered to contain any interval.
|
|
325
|
+
/// If the other interval is 'bottom', it cannot be contained by any interval.
|
|
326
|
+
bool contain(const IntervalValue &other) const
|
|
321
327
|
{
|
|
322
328
|
if (this->isBottom())
|
|
323
329
|
{
|
|
@@ -333,6 +339,42 @@ public:
|
|
|
333
339
|
}
|
|
334
340
|
}
|
|
335
341
|
|
|
342
|
+
/// Check the upper bound of this Interval is less than or equal to the lower bound
|
|
343
|
+
/// e.g. [1, 3] < [3, 5] return true, lhs.ub <= rhs.lb
|
|
344
|
+
bool leq(const IntervalValue &other) const
|
|
345
|
+
{
|
|
346
|
+
if (this->isBottom())
|
|
347
|
+
{
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
else if (other.isBottom())
|
|
351
|
+
{
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
else
|
|
355
|
+
{
|
|
356
|
+
return this->_ub.leq(other._lb);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/// Check the lower bound of this Interval is greater than or equal to the upper bound
|
|
361
|
+
/// e.g. [3, 5] > [1, 3] return true, lhs.lb >= rhs.ub
|
|
362
|
+
bool geq(const IntervalValue &other) const
|
|
363
|
+
{
|
|
364
|
+
if (this->isBottom())
|
|
365
|
+
{
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
else if (other.isBottom())
|
|
369
|
+
{
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
else
|
|
373
|
+
{
|
|
374
|
+
return this->_lb.geq(other._ub);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
336
378
|
|
|
337
379
|
/// Equality comparison
|
|
338
380
|
bool equals(const IntervalValue &other) const
|
|
@@ -175,6 +175,8 @@ public:
|
|
|
175
175
|
/// Check bit value of val start with 0x7F000000, filter by 0xFF000000
|
|
176
176
|
static inline bool isVirtualMemAddress(u32_t val)
|
|
177
177
|
{
|
|
178
|
+
if (val == 0)
|
|
179
|
+
assert(false && "val cannot be 0");
|
|
178
180
|
return AddressValue::isVirtualMemAddress(val);
|
|
179
181
|
}
|
|
180
182
|
|
|
@@ -109,6 +109,15 @@ public:
|
|
|
109
109
|
return globalNulladdrs;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
inline bool inVarTable(const AbstractState& es, u32_t id) const
|
|
113
|
+
{
|
|
114
|
+
return es.inVarToValTable(id) || es.inVarToAddrsTable(id);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
inline bool inAddrTable(const AbstractState& es, u32_t id) const
|
|
118
|
+
{
|
|
119
|
+
return es.inAddrToValTable(id) || es.inAddrToAddrsTable(id);
|
|
120
|
+
}
|
|
112
121
|
|
|
113
122
|
/// whether the variable is in varToVal table
|
|
114
123
|
inline bool inVarToValTable(const AbstractState& es, u32_t id) const
|
|
@@ -126,13 +135,13 @@ public:
|
|
|
126
135
|
/// whether the memory address stores a interval value
|
|
127
136
|
inline bool inLocToValTable(const AbstractState& es, u32_t id) const
|
|
128
137
|
{
|
|
129
|
-
return es.
|
|
138
|
+
return es.inAddrToValTable(id);
|
|
130
139
|
}
|
|
131
140
|
|
|
132
141
|
/// whether the memory address stores memory addresses
|
|
133
142
|
inline bool inLocToAddrsTable(const AbstractState& es, u32_t id) const
|
|
134
143
|
{
|
|
135
|
-
return es.
|
|
144
|
+
return es.inAddrToAddrsTable(id);
|
|
136
145
|
}
|
|
137
146
|
|
|
138
147
|
void handleAddr(AbstractState& es, const AddrStmt *addr);
|
|
@@ -166,6 +166,7 @@ void AbstractInterpretation::handleGlobalNode()
|
|
|
166
166
|
AbstractState as;
|
|
167
167
|
const ICFGNode* node = _icfg->getGlobalICFGNode();
|
|
168
168
|
_postAbsTrace[node] = _preAbsTrace[node];
|
|
169
|
+
_postAbsTrace[node][SymbolTableInfo::NullPtr] = AddressValue();
|
|
169
170
|
// Global Node, we just need to handle addr, load, store, copy and gep
|
|
170
171
|
for (const SVFStmt *stmt: node->getSVFStmts())
|
|
171
172
|
{
|
|
@@ -345,7 +346,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s
|
|
|
345
346
|
for (const auto &addr: addrs)
|
|
346
347
|
{
|
|
347
348
|
NodeID objId = new_es.getInternalID(addr);
|
|
348
|
-
if (new_es.
|
|
349
|
+
if (new_es.inAddrToValTable(objId))
|
|
349
350
|
{
|
|
350
351
|
new_es.load(addr).meet_with(rhs);
|
|
351
352
|
}
|
|
@@ -367,7 +368,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s
|
|
|
367
368
|
for (const auto &addr: addrs)
|
|
368
369
|
{
|
|
369
370
|
NodeID objId = new_es.getInternalID(addr);
|
|
370
|
-
if (new_es.
|
|
371
|
+
if (new_es.inAddrToValTable(objId))
|
|
371
372
|
{
|
|
372
373
|
new_es.load(addr).meet_with(
|
|
373
374
|
IntervalValue(rhs.lb() + 1, IntervalValue::plus_infinity()));
|
|
@@ -385,7 +386,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s
|
|
|
385
386
|
for (const auto &addr: addrs)
|
|
386
387
|
{
|
|
387
388
|
NodeID objId = new_es.getInternalID(addr);
|
|
388
|
-
if (new_es.
|
|
389
|
+
if (new_es.inAddrToValTable(objId))
|
|
389
390
|
{
|
|
390
391
|
new_es.load(addr).meet_with(
|
|
391
392
|
IntervalValue(rhs.lb(), IntervalValue::plus_infinity()));
|
|
@@ -404,7 +405,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s
|
|
|
404
405
|
for (const auto &addr: addrs)
|
|
405
406
|
{
|
|
406
407
|
NodeID objId = new_es.getInternalID(addr);
|
|
407
|
-
if (new_es.
|
|
408
|
+
if (new_es.inAddrToValTable(objId))
|
|
408
409
|
{
|
|
409
410
|
new_es.load(addr).meet_with(
|
|
410
411
|
IntervalValue(IntervalValue::minus_infinity(), rhs.ub() - 1));
|
|
@@ -423,7 +424,7 @@ bool AbstractInterpretation::isCmpBranchFeasible(const CmpStmt* cmpStmt, s64_t s
|
|
|
423
424
|
for (const auto &addr: addrs)
|
|
424
425
|
{
|
|
425
426
|
NodeID objId = new_es.getInternalID(addr);
|
|
426
|
-
if (new_es.
|
|
427
|
+
if (new_es.inAddrToValTable(objId))
|
|
427
428
|
{
|
|
428
429
|
new_es.load(addr).meet_with(
|
|
429
430
|
IntervalValue(IntervalValue::minus_infinity(), rhs.ub()));
|
|
@@ -475,7 +476,7 @@ bool AbstractInterpretation::isSwitchBranchFeasible(const SVFVar* var, s64_t suc
|
|
|
475
476
|
for (const auto &addr: addrs)
|
|
476
477
|
{
|
|
477
478
|
NodeID objId = new_es.getInternalID(addr);
|
|
478
|
-
if (new_es.
|
|
479
|
+
if (new_es.inAddrToValTable(objId))
|
|
479
480
|
{
|
|
480
481
|
new_es.load(addr).meet_with(switch_cond);
|
|
481
482
|
}
|
|
@@ -1591,11 +1592,11 @@ void AbstractInterpretation::handleMemcpy(AbstractState& as, const SVF::SVFValue
|
|
|
1591
1592
|
for (const auto &src: expr_src.getAddrs())
|
|
1592
1593
|
{
|
|
1593
1594
|
u32_t objId = AbstractState::getInternalID(src);
|
|
1594
|
-
if (as.
|
|
1595
|
+
if (as.inAddrToValTable(objId))
|
|
1595
1596
|
{
|
|
1596
1597
|
as.store(dst, as.load(src));
|
|
1597
1598
|
}
|
|
1598
|
-
else if (as.
|
|
1599
|
+
else if (as.inAddrToAddrsTable(objId))
|
|
1599
1600
|
{
|
|
1600
1601
|
as.store(dst, as.load(src));
|
|
1601
1602
|
}
|
|
@@ -1661,7 +1662,7 @@ void AbstractInterpretation::handleMemset(AbstractState& as, const SVF::SVFValue
|
|
|
1661
1662
|
for (const auto &addr: lhs_gep.getAddrs())
|
|
1662
1663
|
{
|
|
1663
1664
|
u32_t objId = AbstractState::getInternalID(addr);
|
|
1664
|
-
if (as.
|
|
1665
|
+
if (as.inAddrToValTable(objId))
|
|
1665
1666
|
{
|
|
1666
1667
|
AbstractValue tmp = as.load(addr);
|
|
1667
1668
|
tmp.join_with(elem);
|
|
@@ -359,17 +359,11 @@ void SVFIR2AbsState::narrowAddrs(AbstractState& es, AbstractState&lhs, const Abs
|
|
|
359
359
|
|
|
360
360
|
AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState& es, u32_t pointer, APOffset offset)
|
|
361
361
|
{
|
|
362
|
-
assert(!getAddrs(es, pointer).getAddrs().empty());
|
|
363
362
|
AbstractValue addrs = getAddrs(es, pointer);
|
|
364
363
|
AddressValue ret = AddressValue();
|
|
365
364
|
for (const auto &addr: addrs.getAddrs())
|
|
366
365
|
{
|
|
367
366
|
s64_t baseObj = getInternalID(addr);
|
|
368
|
-
if (baseObj == 0)
|
|
369
|
-
{
|
|
370
|
-
ret.insert(getVirtualMemAddress(0));
|
|
371
|
-
continue;
|
|
372
|
-
}
|
|
373
367
|
assert(SVFUtil::isa<ObjVar>(_svfir->getGNode(baseObj)) && "Fail to get the base object address!");
|
|
374
368
|
NodeID gepObj = _svfir->getGepObjVar(baseObj, offset);
|
|
375
369
|
initSVFVar(es, gepObj);
|
|
@@ -750,7 +744,6 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
750
744
|
{
|
|
751
745
|
IntervalValue resVal;
|
|
752
746
|
AbstractValue &lhs = getAddrs(es, op0), &rhs = getAddrs(es, op1);
|
|
753
|
-
assert(!lhs.getAddrs().empty() && !rhs.getAddrs().empty() && "empty address?");
|
|
754
747
|
auto predicate = cmp->getPredicate();
|
|
755
748
|
switch (predicate)
|
|
756
749
|
{
|
|
@@ -758,20 +751,17 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
758
751
|
case CmpStmt::FCMP_OEQ:
|
|
759
752
|
case CmpStmt::FCMP_UEQ:
|
|
760
753
|
{
|
|
761
|
-
if (lhs.getAddrs().
|
|
754
|
+
if (lhs.getAddrs().hasIntersect(rhs.getAddrs()))
|
|
762
755
|
{
|
|
763
|
-
resVal = IntervalValue(
|
|
756
|
+
resVal = IntervalValue(0, 1);
|
|
757
|
+
}
|
|
758
|
+
else if (lhs.getAddrs().empty() && rhs.getAddrs().empty())
|
|
759
|
+
{
|
|
760
|
+
resVal = IntervalValue(1, 1);
|
|
764
761
|
}
|
|
765
762
|
else
|
|
766
763
|
{
|
|
767
|
-
|
|
768
|
-
{
|
|
769
|
-
resVal = IntervalValue::top();
|
|
770
|
-
}
|
|
771
|
-
else
|
|
772
|
-
{
|
|
773
|
-
resVal = IntervalValue(0);
|
|
774
|
-
}
|
|
764
|
+
resVal = IntervalValue(0, 0);
|
|
775
765
|
}
|
|
776
766
|
break;
|
|
777
767
|
}
|
|
@@ -779,20 +769,17 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
779
769
|
case CmpStmt::FCMP_ONE:
|
|
780
770
|
case CmpStmt::FCMP_UNE:
|
|
781
771
|
{
|
|
782
|
-
if (lhs.getAddrs().
|
|
772
|
+
if (lhs.getAddrs().hasIntersect(rhs.getAddrs()))
|
|
783
773
|
{
|
|
784
|
-
resVal = IntervalValue(
|
|
774
|
+
resVal = IntervalValue(0, 1);
|
|
775
|
+
}
|
|
776
|
+
else if (lhs.getAddrs().empty() && rhs.getAddrs().empty())
|
|
777
|
+
{
|
|
778
|
+
resVal = IntervalValue(0, 0);
|
|
785
779
|
}
|
|
786
780
|
else
|
|
787
781
|
{
|
|
788
|
-
|
|
789
|
-
{
|
|
790
|
-
resVal = IntervalValue::top();
|
|
791
|
-
}
|
|
792
|
-
else
|
|
793
|
-
{
|
|
794
|
-
resVal = IntervalValue(1);
|
|
795
|
-
}
|
|
782
|
+
resVal = IntervalValue(1, 1);
|
|
796
783
|
}
|
|
797
784
|
break;
|
|
798
785
|
}
|
|
@@ -807,7 +794,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
807
794
|
}
|
|
808
795
|
else
|
|
809
796
|
{
|
|
810
|
-
resVal = IntervalValue
|
|
797
|
+
resVal = IntervalValue(0, 1);
|
|
811
798
|
}
|
|
812
799
|
break;
|
|
813
800
|
}
|
|
@@ -822,7 +809,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
822
809
|
}
|
|
823
810
|
else
|
|
824
811
|
{
|
|
825
|
-
resVal = IntervalValue
|
|
812
|
+
resVal = IntervalValue(0, 1);
|
|
826
813
|
}
|
|
827
814
|
break;
|
|
828
815
|
}
|
|
@@ -837,7 +824,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
837
824
|
}
|
|
838
825
|
else
|
|
839
826
|
{
|
|
840
|
-
resVal = IntervalValue
|
|
827
|
+
resVal = IntervalValue(0, 1);
|
|
841
828
|
}
|
|
842
829
|
break;
|
|
843
830
|
}
|
|
@@ -852,7 +839,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
852
839
|
}
|
|
853
840
|
else
|
|
854
841
|
{
|
|
855
|
-
resVal = IntervalValue
|
|
842
|
+
resVal = IntervalValue(0, 1);
|
|
856
843
|
}
|
|
857
844
|
break;
|
|
858
845
|
}
|
|
@@ -878,7 +865,6 @@ void SVFIR2AbsState::handleLoad(AbstractState& es, const LoadStmt *load)
|
|
|
878
865
|
if (inVarToAddrsTable(es, rhs))
|
|
879
866
|
{
|
|
880
867
|
AbstractValue &addrs = getAddrs(es, rhs);
|
|
881
|
-
assert(!addrs.getAddrs().empty());
|
|
882
868
|
AbstractValue rhsVal(AbstractValue::UnknownType); // interval::bottom Address::bottom
|
|
883
869
|
// AbstractValue absRhs
|
|
884
870
|
for (const auto &addr: addrs.getAddrs())
|
|
@@ -887,7 +873,7 @@ void SVFIR2AbsState::handleLoad(AbstractState& es, const LoadStmt *load)
|
|
|
887
873
|
// absRhs.join_with
|
|
888
874
|
// es.load()
|
|
889
875
|
u32_t objId = getInternalID(addr);
|
|
890
|
-
if (
|
|
876
|
+
if (inAddrTable(es, objId))
|
|
891
877
|
{
|
|
892
878
|
rhsVal.join_with(es.load(addr));
|
|
893
879
|
}
|
|
@@ -903,17 +889,8 @@ void SVFIR2AbsState::handleStore(AbstractState& es, const StoreStmt *store)
|
|
|
903
889
|
u32_t lhs = store->getLHSVarID();
|
|
904
890
|
if (inVarToAddrsTable(es, lhs))
|
|
905
891
|
{
|
|
906
|
-
|
|
907
|
-
assert(!getAddrs(es, lhs).getAddrs().empty());
|
|
908
|
-
AbstractValue &addrs = es[lhs];
|
|
909
|
-
for (const auto &addr: addrs.getAddrs())
|
|
892
|
+
if (inVarTable(es, rhs))
|
|
910
893
|
{
|
|
911
|
-
es.store(addr, es[rhs]);
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
if (inVarToValTable(es, rhs) || inVarToAddrsTable(es, rhs))
|
|
915
|
-
{
|
|
916
|
-
assert(!getAddrs(es, lhs).getAddrs().empty());
|
|
917
894
|
for (const auto &addr: es[lhs].getAddrs())
|
|
918
895
|
{
|
|
919
896
|
es.store(addr, es[rhs]);
|
|
@@ -926,81 +903,74 @@ void SVFIR2AbsState::handleCopy(AbstractState& es, const CopyStmt *copy)
|
|
|
926
903
|
{
|
|
927
904
|
u32_t lhs = copy->getLHSVarID();
|
|
928
905
|
u32_t rhs = copy->getRHSVarID();
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
es[lhs] = IntervalValue::top();
|
|
932
|
-
}
|
|
933
|
-
else
|
|
906
|
+
|
|
907
|
+
if (inVarToValTable(es, rhs))
|
|
934
908
|
{
|
|
935
|
-
if (
|
|
909
|
+
if (copy->getCopyKind() == CopyStmt::COPYVAL)
|
|
910
|
+
{
|
|
911
|
+
es[lhs] = es[rhs];
|
|
912
|
+
}
|
|
913
|
+
else if (copy->getCopyKind() == CopyStmt::ZEXT)
|
|
914
|
+
{
|
|
915
|
+
es[lhs] = getZExtValue(es, copy->getRHSVar());
|
|
916
|
+
}
|
|
917
|
+
else if (copy->getCopyKind() == CopyStmt::SEXT)
|
|
918
|
+
{
|
|
919
|
+
es[lhs] = getSExtValue(es, copy->getRHSVar());
|
|
920
|
+
}
|
|
921
|
+
else if (copy->getCopyKind() == CopyStmt::FPTOSI)
|
|
922
|
+
{
|
|
923
|
+
es[lhs] = getFPToSIntValue(es, copy->getRHSVar());
|
|
924
|
+
}
|
|
925
|
+
else if (copy->getCopyKind() == CopyStmt::FPTOUI)
|
|
926
|
+
{
|
|
927
|
+
es[lhs] = getFPToUIntValue(es, copy->getRHSVar());
|
|
928
|
+
}
|
|
929
|
+
else if (copy->getCopyKind() == CopyStmt::SITOFP)
|
|
930
|
+
{
|
|
931
|
+
es[lhs] = getSIntToFPValue(es, copy->getRHSVar());
|
|
932
|
+
}
|
|
933
|
+
else if (copy->getCopyKind() == CopyStmt::UITOFP)
|
|
934
|
+
{
|
|
935
|
+
es[lhs] = getUIntToFPValue(es, copy->getRHSVar());
|
|
936
|
+
}
|
|
937
|
+
else if (copy->getCopyKind() == CopyStmt::TRUNC)
|
|
936
938
|
{
|
|
937
|
-
|
|
939
|
+
es[lhs] = getTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType());
|
|
940
|
+
}
|
|
941
|
+
else if (copy->getCopyKind() == CopyStmt::FPTRUNC)
|
|
942
|
+
{
|
|
943
|
+
es[lhs] = getFPTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType());
|
|
944
|
+
}
|
|
945
|
+
else if (copy->getCopyKind() == CopyStmt::INTTOPTR)
|
|
946
|
+
{
|
|
947
|
+
//insert nullptr
|
|
948
|
+
}
|
|
949
|
+
else if (copy->getCopyKind() == CopyStmt::PTRTOINT)
|
|
950
|
+
{
|
|
951
|
+
es[lhs] = IntervalValue::top();
|
|
952
|
+
}
|
|
953
|
+
else if (copy->getCopyKind() == CopyStmt::BITCAST)
|
|
954
|
+
{
|
|
955
|
+
if (es[rhs].isAddr())
|
|
938
956
|
{
|
|
939
957
|
es[lhs] = es[rhs];
|
|
940
958
|
}
|
|
941
|
-
else if (copy->getCopyKind() == CopyStmt::ZEXT)
|
|
942
|
-
{
|
|
943
|
-
es[lhs] = getZExtValue(es, copy->getRHSVar());
|
|
944
|
-
}
|
|
945
|
-
else if (copy->getCopyKind() == CopyStmt::SEXT)
|
|
946
|
-
{
|
|
947
|
-
es[lhs] = getSExtValue(es, copy->getRHSVar());
|
|
948
|
-
}
|
|
949
|
-
else if (copy->getCopyKind() == CopyStmt::FPTOSI)
|
|
950
|
-
{
|
|
951
|
-
es[lhs] = getFPToSIntValue(es, copy->getRHSVar());
|
|
952
|
-
}
|
|
953
|
-
else if (copy->getCopyKind() == CopyStmt::FPTOUI)
|
|
954
|
-
{
|
|
955
|
-
es[lhs] = getFPToUIntValue(es, copy->getRHSVar());
|
|
956
|
-
}
|
|
957
|
-
else if (copy->getCopyKind() == CopyStmt::SITOFP)
|
|
958
|
-
{
|
|
959
|
-
es[lhs] = getSIntToFPValue(es, copy->getRHSVar());
|
|
960
|
-
}
|
|
961
|
-
else if (copy->getCopyKind() == CopyStmt::UITOFP)
|
|
962
|
-
{
|
|
963
|
-
es[lhs] = getUIntToFPValue(es, copy->getRHSVar());
|
|
964
|
-
}
|
|
965
|
-
else if (copy->getCopyKind() == CopyStmt::TRUNC)
|
|
966
|
-
{
|
|
967
|
-
es[lhs] = getTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType());
|
|
968
|
-
}
|
|
969
|
-
else if (copy->getCopyKind() == CopyStmt::FPTRUNC)
|
|
970
|
-
{
|
|
971
|
-
es[lhs] = getFPTruncValue(es, copy->getRHSVar(), copy->getLHSVar()->getType());
|
|
972
|
-
}
|
|
973
|
-
else if (copy->getCopyKind() == CopyStmt::INTTOPTR)
|
|
974
|
-
{
|
|
975
|
-
es.getAddrs(lhs).getAddrs().insert(getVirtualMemAddress(0)); //insert nullptr
|
|
976
|
-
}
|
|
977
|
-
else if (copy->getCopyKind() == CopyStmt::PTRTOINT)
|
|
978
|
-
{
|
|
979
|
-
es[lhs] = IntervalValue::top();
|
|
980
|
-
}
|
|
981
|
-
else if (copy->getCopyKind() == CopyStmt::BITCAST)
|
|
982
|
-
{
|
|
983
|
-
if (es[rhs].isAddr())
|
|
984
|
-
{
|
|
985
|
-
es[lhs] = es[rhs];
|
|
986
|
-
}
|
|
987
|
-
else
|
|
988
|
-
{
|
|
989
|
-
// do nothing
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
959
|
else
|
|
993
960
|
{
|
|
994
|
-
|
|
995
|
-
abort();
|
|
961
|
+
// do nothing
|
|
996
962
|
}
|
|
997
963
|
}
|
|
998
|
-
else
|
|
964
|
+
else
|
|
999
965
|
{
|
|
1000
|
-
assert(
|
|
1001
|
-
|
|
966
|
+
assert(false && "undefined copy kind");
|
|
967
|
+
abort();
|
|
1002
968
|
}
|
|
1003
969
|
}
|
|
970
|
+
else if (inVarToAddrsTable(es, rhs))
|
|
971
|
+
{
|
|
972
|
+
es[lhs] = es[rhs];
|
|
973
|
+
}
|
|
1004
974
|
}
|
|
1005
975
|
|
|
1006
976
|
void SVFIR2AbsState::handleGep(AbstractState& es, const GepStmt *gep)
|
|
@@ -1009,7 +979,6 @@ void SVFIR2AbsState::handleGep(AbstractState& es, const GepStmt *gep)
|
|
|
1009
979
|
u32_t lhs = gep->getLHSVarID();
|
|
1010
980
|
if (!inVarToAddrsTable(es, rhs)) return;
|
|
1011
981
|
AbstractValue &rhsVal = es[rhs];
|
|
1012
|
-
assert(!rhsVal.getAddrs().empty());
|
|
1013
982
|
IntervalValue offsetPair = getElementIndex(es, gep);
|
|
1014
983
|
if (!isVirtualMemAddress(*rhsVal.getAddrs().begin()))
|
|
1015
984
|
return;
|
|
@@ -1049,8 +1018,6 @@ void SVFIR2AbsState::handleSelect(AbstractState& es, const SelectStmt *select)
|
|
|
1049
1018
|
{
|
|
1050
1019
|
if (es[cond].getInterval().is_numeral())
|
|
1051
1020
|
{
|
|
1052
|
-
assert(!getAddrs(es, fval).getAddrs().empty());
|
|
1053
|
-
assert(!getAddrs(es, tval).getAddrs().empty());
|
|
1054
1021
|
es.getAddrs(res) = es[cond].getInterval().is_zero() ? getAddrs(es, fval) : getAddrs(es, tval);
|
|
1055
1022
|
}
|
|
1056
1023
|
}
|