svf-tools 1.0.941 → 1.0.943
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 +2 -2
- package/svf/include/AE/Core/AbstractValue.h +13 -42
- package/svf/include/AE/Core/AddressValue.h +3 -1
- package/svf/include/AE/Core/RelExeState.h +2 -0
- package/svf/include/AE/Svfexe/SVFIR2AbsState.h +12 -5
- package/svf/lib/AE/Svfexe/AbstractInterpretation.cpp +10 -9
- package/svf/lib/AE/Svfexe/SVFIR2AbsState.cpp +186 -241
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svf-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.943",
|
|
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
|
{
|
|
@@ -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
|
|
@@ -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
|
|
|
@@ -96,10 +96,8 @@ public:
|
|
|
96
96
|
|
|
97
97
|
|
|
98
98
|
/// Init ObjVar
|
|
99
|
-
void initObjVar(AbstractState&
|
|
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
|
{
|
|
@@ -109,6 +107,15 @@ public:
|
|
|
109
107
|
return globalNulladdrs;
|
|
110
108
|
}
|
|
111
109
|
|
|
110
|
+
inline bool inVarTable(const AbstractState& es, u32_t id) const
|
|
111
|
+
{
|
|
112
|
+
return es.inVarToValTable(id) || es.inVarToAddrsTable(id);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
inline bool inAddrTable(const AbstractState& es, u32_t id) const
|
|
116
|
+
{
|
|
117
|
+
return es.inAddrToValTable(id) || es.inAddrToAddrsTable(id);
|
|
118
|
+
}
|
|
112
119
|
|
|
113
120
|
/// whether the variable is in varToVal table
|
|
114
121
|
inline bool inVarToValTable(const AbstractState& es, u32_t id) const
|
|
@@ -126,13 +133,13 @@ public:
|
|
|
126
133
|
/// whether the memory address stores a interval value
|
|
127
134
|
inline bool inLocToValTable(const AbstractState& es, u32_t id) const
|
|
128
135
|
{
|
|
129
|
-
return es.
|
|
136
|
+
return es.inAddrToValTable(id);
|
|
130
137
|
}
|
|
131
138
|
|
|
132
139
|
/// whether the memory address stores memory addresses
|
|
133
140
|
inline bool inLocToAddrsTable(const AbstractState& es, u32_t id) const
|
|
134
141
|
{
|
|
135
|
-
return es.
|
|
142
|
+
return es.inAddrToAddrsTable(id);
|
|
136
143
|
}
|
|
137
144
|
|
|
138
145
|
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);
|
|
@@ -108,35 +108,35 @@ AbstractValue SVFIR2AbsState::getRangeLimitFromType(const SVFType* type)
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
AbstractValue SVFIR2AbsState::getZExtValue(const AbstractState&
|
|
111
|
+
AbstractValue SVFIR2AbsState::getZExtValue(const AbstractState& as, const SVFVar* var)
|
|
112
112
|
{
|
|
113
113
|
const SVFType* type = var->getType();
|
|
114
114
|
if (SVFUtil::isa<SVFIntegerType>(type))
|
|
115
115
|
{
|
|
116
116
|
u32_t bits = type->getByteSize() * 8;
|
|
117
|
-
if (
|
|
117
|
+
if (as[var->getId()].getInterval().is_numeral())
|
|
118
118
|
{
|
|
119
119
|
if (bits == 8)
|
|
120
120
|
{
|
|
121
|
-
int8_t signed_i8_value =
|
|
121
|
+
int8_t signed_i8_value = as[var->getId()].getInterval().getIntNumeral();
|
|
122
122
|
u32_t unsigned_value = static_cast<uint8_t>(signed_i8_value);
|
|
123
123
|
return IntervalValue(unsigned_value, unsigned_value);
|
|
124
124
|
}
|
|
125
125
|
else if (bits == 16)
|
|
126
126
|
{
|
|
127
|
-
s16_t signed_i16_value =
|
|
127
|
+
s16_t signed_i16_value = as[var->getId()].getInterval().getIntNumeral();
|
|
128
128
|
u32_t unsigned_value = static_cast<u16_t>(signed_i16_value);
|
|
129
129
|
return IntervalValue(unsigned_value, unsigned_value);
|
|
130
130
|
}
|
|
131
131
|
else if (bits == 32)
|
|
132
132
|
{
|
|
133
|
-
s32_t signed_i32_value =
|
|
133
|
+
s32_t signed_i32_value = as[var->getId()].getInterval().getIntNumeral();
|
|
134
134
|
u32_t unsigned_value = static_cast<u32_t>(signed_i32_value);
|
|
135
135
|
return IntervalValue(unsigned_value, unsigned_value);
|
|
136
136
|
}
|
|
137
137
|
else if (bits == 64)
|
|
138
138
|
{
|
|
139
|
-
s64_t signed_i64_value =
|
|
139
|
+
s64_t signed_i64_value = as[var->getId()].getInterval().getIntNumeral();
|
|
140
140
|
return IntervalValue((s64_t)signed_i64_value, (s64_t)signed_i64_value);
|
|
141
141
|
// we only support i64 at most
|
|
142
142
|
}
|
|
@@ -153,18 +153,18 @@ AbstractValue SVFIR2AbsState::getZExtValue(const AbstractState& es, const SVFVar
|
|
|
153
153
|
return IntervalValue::top(); // TODO: may have better solution
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
AbstractValue SVFIR2AbsState::getSExtValue(const AbstractState&
|
|
156
|
+
AbstractValue SVFIR2AbsState::getSExtValue(const AbstractState& as, const SVFVar* var)
|
|
157
157
|
{
|
|
158
|
-
return
|
|
158
|
+
return as[var->getId()].getInterval();
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
AbstractValue SVFIR2AbsState::getFPToSIntValue(const AbstractState&
|
|
161
|
+
AbstractValue SVFIR2AbsState::getFPToSIntValue(const AbstractState& as, const SVF::SVFVar* var)
|
|
162
162
|
{
|
|
163
|
-
if (
|
|
163
|
+
if (as[var->getId()].getInterval().is_real())
|
|
164
164
|
{
|
|
165
165
|
// get the float value of ub and lb
|
|
166
|
-
double float_lb =
|
|
167
|
-
double float_ub =
|
|
166
|
+
double float_lb = as[var->getId()].getInterval().lb().getRealNumeral();
|
|
167
|
+
double float_ub = as[var->getId()].getInterval().ub().getRealNumeral();
|
|
168
168
|
// get the int value of ub and lb
|
|
169
169
|
s64_t int_lb = static_cast<s64_t>(float_lb);
|
|
170
170
|
s64_t int_ub = static_cast<s64_t>(float_ub);
|
|
@@ -172,17 +172,17 @@ AbstractValue SVFIR2AbsState::getFPToSIntValue(const AbstractState& es, const SV
|
|
|
172
172
|
}
|
|
173
173
|
else
|
|
174
174
|
{
|
|
175
|
-
return getSExtValue(
|
|
175
|
+
return getSExtValue(as, var);
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
AbstractValue SVFIR2AbsState::getFPToUIntValue(const AbstractState&
|
|
179
|
+
AbstractValue SVFIR2AbsState::getFPToUIntValue(const AbstractState& as, const SVF::SVFVar* var)
|
|
180
180
|
{
|
|
181
|
-
if (
|
|
181
|
+
if (as[var->getId()].getInterval().is_real())
|
|
182
182
|
{
|
|
183
183
|
// get the float value of ub and lb
|
|
184
|
-
double float_lb =
|
|
185
|
-
double float_ub =
|
|
184
|
+
double float_lb = as[var->getId()].getInterval().lb().getRealNumeral();
|
|
185
|
+
double float_ub = as[var->getId()].getInterval().ub().getRealNumeral();
|
|
186
186
|
// get the int value of ub and lb
|
|
187
187
|
u64_t int_lb = static_cast<u64_t>(float_lb);
|
|
188
188
|
u64_t int_ub = static_cast<u64_t>(float_ub);
|
|
@@ -190,37 +190,37 @@ AbstractValue SVFIR2AbsState::getFPToUIntValue(const AbstractState& es, const SV
|
|
|
190
190
|
}
|
|
191
191
|
else
|
|
192
192
|
{
|
|
193
|
-
return getZExtValue(
|
|
193
|
+
return getZExtValue(as, var);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
AbstractValue SVFIR2AbsState::getSIntToFPValue(const AbstractState&
|
|
197
|
+
AbstractValue SVFIR2AbsState::getSIntToFPValue(const AbstractState& as, const SVF::SVFVar* var)
|
|
198
198
|
{
|
|
199
199
|
// get the sint value of ub and lb
|
|
200
|
-
s64_t sint_lb =
|
|
201
|
-
s64_t sint_ub =
|
|
200
|
+
s64_t sint_lb = as[var->getId()].getInterval().lb().getIntNumeral();
|
|
201
|
+
s64_t sint_ub = as[var->getId()].getInterval().ub().getIntNumeral();
|
|
202
202
|
// get the float value of ub and lb
|
|
203
203
|
double float_lb = static_cast<double>(sint_lb);
|
|
204
204
|
double float_ub = static_cast<double>(sint_ub);
|
|
205
205
|
return IntervalValue(float_lb, float_ub);
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
AbstractValue SVFIR2AbsState::getUIntToFPValue(const AbstractState&
|
|
208
|
+
AbstractValue SVFIR2AbsState::getUIntToFPValue(const AbstractState& as, const SVF::SVFVar* var)
|
|
209
209
|
{
|
|
210
210
|
// get the uint value of ub and lb
|
|
211
|
-
u64_t uint_lb =
|
|
212
|
-
u64_t uint_ub =
|
|
211
|
+
u64_t uint_lb = as[var->getId()].getInterval().lb().getIntNumeral();
|
|
212
|
+
u64_t uint_ub = as[var->getId()].getInterval().ub().getIntNumeral();
|
|
213
213
|
// get the float value of ub and lb
|
|
214
214
|
double float_lb = static_cast<double>(uint_lb);
|
|
215
215
|
double float_ub = static_cast<double>(uint_ub);
|
|
216
216
|
return IntervalValue(float_lb, float_ub);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
AbstractValue SVFIR2AbsState::getTruncValue(const AbstractState&
|
|
219
|
+
AbstractValue SVFIR2AbsState::getTruncValue(const AbstractState& as, const SVF::SVFVar* var, const SVFType* dstType)
|
|
220
220
|
{
|
|
221
221
|
// get the value of ub and lb
|
|
222
|
-
s64_t int_lb =
|
|
223
|
-
s64_t int_ub =
|
|
222
|
+
s64_t int_lb = as[var->getId()].getInterval().lb().getIntNumeral();
|
|
223
|
+
s64_t int_ub = as[var->getId()].getInterval().ub().getIntNumeral();
|
|
224
224
|
// get dst type
|
|
225
225
|
u32_t dst_bits = dstType->getByteSize() * 8;
|
|
226
226
|
if (dst_bits == 8)
|
|
@@ -265,13 +265,13 @@ AbstractValue SVFIR2AbsState::getTruncValue(const AbstractState& es, const SVF::
|
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
AbstractValue SVFIR2AbsState::getFPTruncValue(const AbstractState&
|
|
268
|
+
AbstractValue SVFIR2AbsState::getFPTruncValue(const AbstractState& as, const SVF::SVFVar* var, const SVFType* dstType)
|
|
269
269
|
{
|
|
270
270
|
// TODO: now we do not really handle fptrunc
|
|
271
|
-
return
|
|
271
|
+
return as[var->getId()].getInterval();
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
void SVFIR2AbsState::widenAddrs(AbstractState&
|
|
274
|
+
void SVFIR2AbsState::widenAddrs(AbstractState& as, AbstractState&lhs, const AbstractState&rhs)
|
|
275
275
|
{
|
|
276
276
|
for (const auto &rhsItem: rhs._varToAbsVal)
|
|
277
277
|
{
|
|
@@ -286,7 +286,7 @@ void SVFIR2AbsState::widenAddrs(AbstractState& es, AbstractState&lhs, const Abst
|
|
|
286
286
|
{
|
|
287
287
|
for (s32_t i = 0; i < (s32_t) Options::MaxFieldLimit(); i++)
|
|
288
288
|
{
|
|
289
|
-
lhsIter->second.join_with(getGepObjAddress(
|
|
289
|
+
lhsIter->second.join_with(getGepObjAddress(as, getInternalID(addr), i));
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
292
|
}
|
|
@@ -308,7 +308,7 @@ void SVFIR2AbsState::widenAddrs(AbstractState& es, AbstractState&lhs, const Abst
|
|
|
308
308
|
i++)
|
|
309
309
|
{
|
|
310
310
|
lhsIter->second.join_with(
|
|
311
|
-
getGepObjAddress(
|
|
311
|
+
getGepObjAddress(as, getInternalID(addr), i));
|
|
312
312
|
}
|
|
313
313
|
}
|
|
314
314
|
}
|
|
@@ -317,7 +317,7 @@ void SVFIR2AbsState::widenAddrs(AbstractState& es, AbstractState&lhs, const Abst
|
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
void SVFIR2AbsState::narrowAddrs(AbstractState&
|
|
320
|
+
void SVFIR2AbsState::narrowAddrs(AbstractState& as, AbstractState&lhs, const AbstractState&rhs)
|
|
321
321
|
{
|
|
322
322
|
for (const auto &rhsItem: rhs._varToAbsVal)
|
|
323
323
|
{
|
|
@@ -357,23 +357,17 @@ void SVFIR2AbsState::narrowAddrs(AbstractState& es, AbstractState&lhs, const Abs
|
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
-
AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState&
|
|
360
|
+
AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState& as, u32_t pointer, APOffset offset)
|
|
361
361
|
{
|
|
362
|
-
|
|
363
|
-
AbstractValue addrs = getAddrs(es, pointer);
|
|
362
|
+
AbstractValue addrs = getAddrs(as, 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
|
-
|
|
376
|
-
ret.insert(getVirtualMemAddress(gepObj));
|
|
369
|
+
as[gepObj] = AddressValue(AbstractState::getVirtualMemAddress(gepObj));
|
|
370
|
+
ret.insert(AbstractState::getVirtualMemAddress(gepObj));
|
|
377
371
|
}
|
|
378
372
|
return ret;
|
|
379
373
|
}
|
|
@@ -400,7 +394,7 @@ AbstractValue SVFIR2AbsState::getGepObjAddress(AbstractState& es, u32_t pointer,
|
|
|
400
394
|
* Therefore the final byteoffset is [8+4*var1.lb(), 8+4*var1.ub()]
|
|
401
395
|
*
|
|
402
396
|
*/
|
|
403
|
-
IntervalValue SVFIR2AbsState::getByteOffset(const AbstractState&
|
|
397
|
+
IntervalValue SVFIR2AbsState::getByteOffset(const AbstractState& as, const GepStmt *gep)
|
|
404
398
|
{
|
|
405
399
|
if (gep->isConstantOffset())
|
|
406
400
|
return IntervalValue((s64_t)gep->accumulateConstantByteOffset());
|
|
@@ -431,7 +425,7 @@ IntervalValue SVFIR2AbsState::getByteOffset(const AbstractState& es, const GepSt
|
|
|
431
425
|
else
|
|
432
426
|
{
|
|
433
427
|
u32_t idx = _svfir->getValueNode(idxOperandVar->getValue());
|
|
434
|
-
IntervalValue idxVal =
|
|
428
|
+
IntervalValue idxVal = as[idx].getInterval();
|
|
435
429
|
if (idxVal.isBottom())
|
|
436
430
|
res = res + IntervalValue(0, 0);
|
|
437
431
|
else
|
|
@@ -470,7 +464,7 @@ IntervalValue SVFIR2AbsState::getByteOffset(const AbstractState& es, const GepSt
|
|
|
470
464
|
*
|
|
471
465
|
* @return A pair of APOffset values representing the offset range.
|
|
472
466
|
*/
|
|
473
|
-
IntervalValue SVFIR2AbsState::getElementIndex(const AbstractState&
|
|
467
|
+
IntervalValue SVFIR2AbsState::getElementIndex(const AbstractState& as, const GepStmt *gep)
|
|
474
468
|
{
|
|
475
469
|
if (gep->isConstantOffset())
|
|
476
470
|
return IntervalValue((s64_t)gep->accumulateConstantOffset());
|
|
@@ -490,7 +484,7 @@ IntervalValue SVFIR2AbsState::getElementIndex(const AbstractState& es, const Gep
|
|
|
490
484
|
idxLb = idxUb = constInt->getSExtValue();
|
|
491
485
|
else
|
|
492
486
|
{
|
|
493
|
-
IntervalValue idxItv =
|
|
487
|
+
IntervalValue idxItv = as[_svfir->getValueNode(value)].getInterval();
|
|
494
488
|
if (idxItv.isBottom())
|
|
495
489
|
idxLb = idxUb = 0;
|
|
496
490
|
else
|
|
@@ -540,81 +534,59 @@ IntervalValue SVFIR2AbsState::getElementIndex(const AbstractState& es, const Gep
|
|
|
540
534
|
}
|
|
541
535
|
|
|
542
536
|
|
|
543
|
-
|
|
544
|
-
* Init Z3Expr for ObjVar
|
|
545
|
-
* @param objVar
|
|
546
|
-
* @param valExprIdToCondValPairMap
|
|
547
|
-
*/
|
|
548
|
-
void SVFIR2AbsState::initObjVar(AbstractState& es, const ObjVar *objVar, u32_t varId)
|
|
537
|
+
void SVFIR2AbsState::initObjVar(AbstractState& as, const ObjVar* var)
|
|
549
538
|
{
|
|
550
|
-
|
|
551
|
-
if (
|
|
539
|
+
NodeID varId = var->getId();
|
|
540
|
+
if (var->hasValue())
|
|
552
541
|
{
|
|
553
|
-
const MemObj *obj =
|
|
542
|
+
const MemObj *obj = var->getMemObj();
|
|
554
543
|
/// constant data
|
|
555
544
|
if (obj->isConstDataOrConstGlobal() || obj->isConstantArray() || obj->isConstantStruct())
|
|
556
545
|
{
|
|
557
546
|
if (const SVFConstantInt *consInt = SVFUtil::dyn_cast<SVFConstantInt>(obj->getValue()))
|
|
558
547
|
{
|
|
559
548
|
s64_t numeral = consInt->getSExtValue();
|
|
560
|
-
|
|
549
|
+
as[varId] = IntervalValue(numeral, numeral);
|
|
561
550
|
}
|
|
562
551
|
else if (const SVFConstantFP* consFP = SVFUtil::dyn_cast<SVFConstantFP>(obj->getValue()))
|
|
563
|
-
|
|
552
|
+
as[varId] = IntervalValue(consFP->getFPValue(), consFP->getFPValue());
|
|
564
553
|
else if (SVFUtil::isa<SVFConstantNullPtr>(obj->getValue()))
|
|
565
|
-
|
|
554
|
+
as[varId] = IntervalValue(0, 0);
|
|
566
555
|
else if (SVFUtil::isa<SVFGlobalValue>(obj->getValue()))
|
|
567
556
|
{
|
|
568
|
-
|
|
557
|
+
as[varId] = AddressValue(getVirtualMemAddress(varId));
|
|
569
558
|
}
|
|
570
559
|
|
|
571
560
|
else if (obj->isConstantArray() || obj->isConstantStruct())
|
|
572
|
-
|
|
561
|
+
as[varId] = IntervalValue::top();
|
|
573
562
|
else
|
|
574
|
-
|
|
563
|
+
as[varId] = IntervalValue::top();
|
|
575
564
|
}
|
|
576
565
|
else
|
|
577
|
-
|
|
566
|
+
as[varId] = AddressValue(getVirtualMemAddress(varId));
|
|
578
567
|
}
|
|
579
568
|
else
|
|
580
|
-
|
|
569
|
+
as[varId] = AddressValue(getVirtualMemAddress(varId));
|
|
581
570
|
}
|
|
582
571
|
|
|
583
|
-
void SVFIR2AbsState::initSVFVar(AbstractState& es, u32_t varId)
|
|
584
|
-
{
|
|
585
|
-
if (inVarToValTable(es, varId) || es.inVarToAddrsTable(varId)) return;
|
|
586
|
-
SVFIR *svfir = PAG::getPAG();
|
|
587
|
-
SVFVar *svfVar = svfir->getGNode(varId);
|
|
588
|
-
// write objvar into cache instead of exestate
|
|
589
|
-
if (const ObjVar *objVar = dyn_cast<ObjVar>(svfVar))
|
|
590
|
-
{
|
|
591
|
-
initObjVar(es, objVar, varId);
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
else
|
|
595
|
-
{
|
|
596
|
-
assert(false && "not an obj var?");
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
572
|
|
|
600
|
-
|
|
601
|
-
void SVFIR2AbsState::handleAddr(AbstractState& es, const AddrStmt *addr)
|
|
573
|
+
void SVFIR2AbsState::handleAddr(AbstractState& as, const AddrStmt *addr)
|
|
602
574
|
{
|
|
603
|
-
|
|
604
|
-
if (inVarToValTable(
|
|
575
|
+
initObjVar(as, SVFUtil::cast<ObjVar>(addr->getRHSVar()));
|
|
576
|
+
if (inVarToValTable(as, addr->getRHSVarID()))
|
|
605
577
|
{
|
|
606
578
|
// if addr RHS is integerType(i8 i32 etc), value should be limited.
|
|
607
579
|
if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy)
|
|
608
580
|
{
|
|
609
|
-
|
|
581
|
+
as[addr->getRHSVarID()].meet_with(getRangeLimitFromType(addr->getRHSVar()->getType()));
|
|
610
582
|
}
|
|
611
|
-
|
|
583
|
+
as[addr->getLHSVarID()] = as[addr->getRHSVarID()];
|
|
612
584
|
|
|
613
585
|
}
|
|
614
|
-
else if (inVarToAddrsTable(
|
|
586
|
+
else if (inVarToAddrsTable(as, addr->getRHSVarID()))
|
|
615
587
|
{
|
|
616
|
-
|
|
617
|
-
|
|
588
|
+
as[addr->getLHSVarID()] =
|
|
589
|
+
as[addr->getRHSVarID()];
|
|
618
590
|
}
|
|
619
591
|
else
|
|
620
592
|
{
|
|
@@ -623,16 +595,16 @@ void SVFIR2AbsState::handleAddr(AbstractState& es, const AddrStmt *addr)
|
|
|
623
595
|
}
|
|
624
596
|
|
|
625
597
|
|
|
626
|
-
void SVFIR2AbsState::handleBinary(AbstractState&
|
|
598
|
+
void SVFIR2AbsState::handleBinary(AbstractState& as, const BinaryOPStmt *binary)
|
|
627
599
|
{
|
|
628
600
|
u32_t op0 = binary->getOpVarID(0);
|
|
629
601
|
u32_t op1 = binary->getOpVarID(1);
|
|
630
602
|
u32_t res = binary->getResID();
|
|
631
|
-
if (!inVarToValTable(
|
|
632
|
-
if (!inVarToValTable(
|
|
633
|
-
if (inVarToValTable(
|
|
603
|
+
if (!inVarToValTable(as, op0)) as[op0] = IntervalValue::top();
|
|
604
|
+
if (!inVarToValTable(as, op1)) as[op1] = IntervalValue::top();
|
|
605
|
+
if (inVarToValTable(as, op0) && inVarToValTable(as, op1))
|
|
634
606
|
{
|
|
635
|
-
IntervalValue &lhs =
|
|
607
|
+
IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval();
|
|
636
608
|
IntervalValue resVal;
|
|
637
609
|
switch (binary->getOpcode())
|
|
638
610
|
{
|
|
@@ -681,19 +653,19 @@ void SVFIR2AbsState::handleBinary(AbstractState& es, const BinaryOPStmt *binary)
|
|
|
681
653
|
assert(false && "undefined binary: ");
|
|
682
654
|
}
|
|
683
655
|
}
|
|
684
|
-
|
|
656
|
+
as[res] = resVal;
|
|
685
657
|
}
|
|
686
658
|
}
|
|
687
659
|
|
|
688
|
-
void SVFIR2AbsState::handleCmp(AbstractState&
|
|
660
|
+
void SVFIR2AbsState::handleCmp(AbstractState& as, const CmpStmt *cmp)
|
|
689
661
|
{
|
|
690
662
|
u32_t op0 = cmp->getOpVarID(0);
|
|
691
663
|
u32_t op1 = cmp->getOpVarID(1);
|
|
692
664
|
u32_t res = cmp->getResID();
|
|
693
|
-
if (inVarToValTable(
|
|
665
|
+
if (inVarToValTable(as, op0) && inVarToValTable(as, op1))
|
|
694
666
|
{
|
|
695
667
|
IntervalValue resVal;
|
|
696
|
-
IntervalValue &lhs =
|
|
668
|
+
IntervalValue &lhs = as[op0].getInterval(), &rhs = as[op1].getInterval();
|
|
697
669
|
//AbstractValue
|
|
698
670
|
auto predicate = cmp->getPredicate();
|
|
699
671
|
switch (predicate)
|
|
@@ -744,13 +716,12 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
744
716
|
assert(false && "undefined compare: ");
|
|
745
717
|
}
|
|
746
718
|
}
|
|
747
|
-
|
|
719
|
+
as[res] = resVal;
|
|
748
720
|
}
|
|
749
|
-
else if (inVarToAddrsTable(
|
|
721
|
+
else if (inVarToAddrsTable(as, op0) && inVarToAddrsTable(as, op1))
|
|
750
722
|
{
|
|
751
723
|
IntervalValue resVal;
|
|
752
|
-
AbstractValue &lhs = getAddrs(
|
|
753
|
-
assert(!lhs.getAddrs().empty() && !rhs.getAddrs().empty() && "empty address?");
|
|
724
|
+
AbstractValue &lhs = getAddrs(as, op0), &rhs = getAddrs(as, op1);
|
|
754
725
|
auto predicate = cmp->getPredicate();
|
|
755
726
|
switch (predicate)
|
|
756
727
|
{
|
|
@@ -758,20 +729,17 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
758
729
|
case CmpStmt::FCMP_OEQ:
|
|
759
730
|
case CmpStmt::FCMP_UEQ:
|
|
760
731
|
{
|
|
761
|
-
if (lhs.getAddrs().
|
|
732
|
+
if (lhs.getAddrs().hasIntersect(rhs.getAddrs()))
|
|
733
|
+
{
|
|
734
|
+
resVal = IntervalValue(0, 1);
|
|
735
|
+
}
|
|
736
|
+
else if (lhs.getAddrs().empty() && rhs.getAddrs().empty())
|
|
762
737
|
{
|
|
763
|
-
resVal = IntervalValue(
|
|
738
|
+
resVal = IntervalValue(1, 1);
|
|
764
739
|
}
|
|
765
740
|
else
|
|
766
741
|
{
|
|
767
|
-
|
|
768
|
-
{
|
|
769
|
-
resVal = IntervalValue::top();
|
|
770
|
-
}
|
|
771
|
-
else
|
|
772
|
-
{
|
|
773
|
-
resVal = IntervalValue(0);
|
|
774
|
-
}
|
|
742
|
+
resVal = IntervalValue(0, 0);
|
|
775
743
|
}
|
|
776
744
|
break;
|
|
777
745
|
}
|
|
@@ -779,20 +747,17 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
779
747
|
case CmpStmt::FCMP_ONE:
|
|
780
748
|
case CmpStmt::FCMP_UNE:
|
|
781
749
|
{
|
|
782
|
-
if (lhs.getAddrs().
|
|
750
|
+
if (lhs.getAddrs().hasIntersect(rhs.getAddrs()))
|
|
783
751
|
{
|
|
784
|
-
resVal = IntervalValue(
|
|
752
|
+
resVal = IntervalValue(0, 1);
|
|
753
|
+
}
|
|
754
|
+
else if (lhs.getAddrs().empty() && rhs.getAddrs().empty())
|
|
755
|
+
{
|
|
756
|
+
resVal = IntervalValue(0, 0);
|
|
785
757
|
}
|
|
786
758
|
else
|
|
787
759
|
{
|
|
788
|
-
|
|
789
|
-
{
|
|
790
|
-
resVal = IntervalValue::top();
|
|
791
|
-
}
|
|
792
|
-
else
|
|
793
|
-
{
|
|
794
|
-
resVal = IntervalValue(1);
|
|
795
|
-
}
|
|
760
|
+
resVal = IntervalValue(1, 1);
|
|
796
761
|
}
|
|
797
762
|
break;
|
|
798
763
|
}
|
|
@@ -807,7 +772,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
807
772
|
}
|
|
808
773
|
else
|
|
809
774
|
{
|
|
810
|
-
resVal = IntervalValue
|
|
775
|
+
resVal = IntervalValue(0, 1);
|
|
811
776
|
}
|
|
812
777
|
break;
|
|
813
778
|
}
|
|
@@ -822,7 +787,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
822
787
|
}
|
|
823
788
|
else
|
|
824
789
|
{
|
|
825
|
-
resVal = IntervalValue
|
|
790
|
+
resVal = IntervalValue(0, 1);
|
|
826
791
|
}
|
|
827
792
|
break;
|
|
828
793
|
}
|
|
@@ -837,7 +802,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
837
802
|
}
|
|
838
803
|
else
|
|
839
804
|
{
|
|
840
|
-
resVal = IntervalValue
|
|
805
|
+
resVal = IntervalValue(0, 1);
|
|
841
806
|
}
|
|
842
807
|
break;
|
|
843
808
|
}
|
|
@@ -852,7 +817,7 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
852
817
|
}
|
|
853
818
|
else
|
|
854
819
|
{
|
|
855
|
-
resVal = IntervalValue
|
|
820
|
+
resVal = IntervalValue(0, 1);
|
|
856
821
|
}
|
|
857
822
|
break;
|
|
858
823
|
}
|
|
@@ -867,150 +832,132 @@ void SVFIR2AbsState::handleCmp(AbstractState& es, const CmpStmt *cmp)
|
|
|
867
832
|
assert(false && "undefined compare: ");
|
|
868
833
|
}
|
|
869
834
|
}
|
|
870
|
-
|
|
835
|
+
as[res] = resVal;
|
|
871
836
|
}
|
|
872
837
|
}
|
|
873
838
|
|
|
874
|
-
void SVFIR2AbsState::handleLoad(AbstractState&
|
|
839
|
+
void SVFIR2AbsState::handleLoad(AbstractState& as, const LoadStmt *load)
|
|
875
840
|
{
|
|
876
841
|
u32_t rhs = load->getRHSVarID();
|
|
877
842
|
u32_t lhs = load->getLHSVarID();
|
|
878
|
-
if (inVarToAddrsTable(
|
|
843
|
+
if (inVarToAddrsTable(as, rhs))
|
|
879
844
|
{
|
|
880
|
-
AbstractValue &addrs = getAddrs(
|
|
881
|
-
assert(!addrs.getAddrs().empty());
|
|
845
|
+
AbstractValue &addrs = getAddrs(as, rhs);
|
|
882
846
|
AbstractValue rhsVal(AbstractValue::UnknownType); // interval::bottom Address::bottom
|
|
883
847
|
// AbstractValue absRhs
|
|
884
848
|
for (const auto &addr: addrs.getAddrs())
|
|
885
849
|
{
|
|
886
850
|
// inLocToAbsVal()
|
|
887
851
|
// absRhs.join_with
|
|
888
|
-
//
|
|
852
|
+
// as.load()
|
|
889
853
|
u32_t objId = getInternalID(addr);
|
|
890
|
-
if (
|
|
854
|
+
if (inAddrTable(as, objId))
|
|
891
855
|
{
|
|
892
|
-
rhsVal.join_with(
|
|
856
|
+
rhsVal.join_with(as.load(addr));
|
|
893
857
|
}
|
|
894
858
|
}
|
|
895
859
|
if (!rhsVal.isUnknown())
|
|
896
|
-
|
|
860
|
+
as[lhs] = rhsVal;
|
|
897
861
|
}
|
|
898
862
|
}
|
|
899
863
|
|
|
900
|
-
void SVFIR2AbsState::handleStore(AbstractState&
|
|
864
|
+
void SVFIR2AbsState::handleStore(AbstractState& as, const StoreStmt *store)
|
|
901
865
|
{
|
|
902
866
|
u32_t rhs = store->getRHSVarID();
|
|
903
867
|
u32_t lhs = store->getLHSVarID();
|
|
904
|
-
if (inVarToAddrsTable(
|
|
868
|
+
if (inVarToAddrsTable(as, lhs))
|
|
905
869
|
{
|
|
906
|
-
|
|
907
|
-
assert(!getAddrs(es, lhs).getAddrs().empty());
|
|
908
|
-
AbstractValue &addrs = es[lhs];
|
|
909
|
-
for (const auto &addr: addrs.getAddrs())
|
|
870
|
+
if (inVarTable(as, rhs))
|
|
910
871
|
{
|
|
911
|
-
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
if (inVarToValTable(es, rhs) || inVarToAddrsTable(es, rhs))
|
|
915
|
-
{
|
|
916
|
-
assert(!getAddrs(es, lhs).getAddrs().empty());
|
|
917
|
-
for (const auto &addr: es[lhs].getAddrs())
|
|
872
|
+
for (const auto &addr: as[lhs].getAddrs())
|
|
918
873
|
{
|
|
919
|
-
|
|
874
|
+
as.store(addr, as[rhs]);
|
|
920
875
|
}
|
|
921
876
|
}
|
|
922
877
|
}
|
|
923
878
|
}
|
|
924
879
|
|
|
925
|
-
void SVFIR2AbsState::handleCopy(AbstractState&
|
|
880
|
+
void SVFIR2AbsState::handleCopy(AbstractState& as, const CopyStmt *copy)
|
|
926
881
|
{
|
|
927
882
|
u32_t lhs = copy->getLHSVarID();
|
|
928
883
|
u32_t rhs = copy->getRHSVarID();
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
es[lhs] = IntervalValue::top();
|
|
932
|
-
}
|
|
933
|
-
else
|
|
884
|
+
|
|
885
|
+
if (inVarToValTable(as, rhs))
|
|
934
886
|
{
|
|
935
|
-
if (
|
|
887
|
+
if (copy->getCopyKind() == CopyStmt::COPYVAL)
|
|
936
888
|
{
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
889
|
+
as[lhs] = as[rhs];
|
|
890
|
+
}
|
|
891
|
+
else if (copy->getCopyKind() == CopyStmt::ZEXT)
|
|
892
|
+
{
|
|
893
|
+
as[lhs] = getZExtValue(as, copy->getRHSVar());
|
|
894
|
+
}
|
|
895
|
+
else if (copy->getCopyKind() == CopyStmt::SEXT)
|
|
896
|
+
{
|
|
897
|
+
as[lhs] = getSExtValue(as, copy->getRHSVar());
|
|
898
|
+
}
|
|
899
|
+
else if (copy->getCopyKind() == CopyStmt::FPTOSI)
|
|
900
|
+
{
|
|
901
|
+
as[lhs] = getFPToSIntValue(as, copy->getRHSVar());
|
|
902
|
+
}
|
|
903
|
+
else if (copy->getCopyKind() == CopyStmt::FPTOUI)
|
|
904
|
+
{
|
|
905
|
+
as[lhs] = getFPToUIntValue(as, copy->getRHSVar());
|
|
906
|
+
}
|
|
907
|
+
else if (copy->getCopyKind() == CopyStmt::SITOFP)
|
|
908
|
+
{
|
|
909
|
+
as[lhs] = getSIntToFPValue(as, copy->getRHSVar());
|
|
910
|
+
}
|
|
911
|
+
else if (copy->getCopyKind() == CopyStmt::UITOFP)
|
|
912
|
+
{
|
|
913
|
+
as[lhs] = getUIntToFPValue(as, copy->getRHSVar());
|
|
914
|
+
}
|
|
915
|
+
else if (copy->getCopyKind() == CopyStmt::TRUNC)
|
|
916
|
+
{
|
|
917
|
+
as[lhs] = getTruncValue(as, copy->getRHSVar(), copy->getLHSVar()->getType());
|
|
918
|
+
}
|
|
919
|
+
else if (copy->getCopyKind() == CopyStmt::FPTRUNC)
|
|
920
|
+
{
|
|
921
|
+
as[lhs] = getFPTruncValue(as, copy->getRHSVar(), copy->getLHSVar()->getType());
|
|
922
|
+
}
|
|
923
|
+
else if (copy->getCopyKind() == CopyStmt::INTTOPTR)
|
|
924
|
+
{
|
|
925
|
+
//insert nullptr
|
|
926
|
+
}
|
|
927
|
+
else if (copy->getCopyKind() == CopyStmt::PTRTOINT)
|
|
928
|
+
{
|
|
929
|
+
as[lhs] = IntervalValue::top();
|
|
930
|
+
}
|
|
931
|
+
else if (copy->getCopyKind() == CopyStmt::BITCAST)
|
|
932
|
+
{
|
|
933
|
+
if (as[rhs].isAddr())
|
|
982
934
|
{
|
|
983
|
-
|
|
984
|
-
{
|
|
985
|
-
es[lhs] = es[rhs];
|
|
986
|
-
}
|
|
987
|
-
else
|
|
988
|
-
{
|
|
989
|
-
// do nothing
|
|
990
|
-
}
|
|
935
|
+
as[lhs] = as[rhs];
|
|
991
936
|
}
|
|
992
937
|
else
|
|
993
938
|
{
|
|
994
|
-
|
|
995
|
-
abort();
|
|
939
|
+
// do nothing
|
|
996
940
|
}
|
|
997
941
|
}
|
|
998
|
-
else
|
|
942
|
+
else
|
|
999
943
|
{
|
|
1000
|
-
assert(
|
|
1001
|
-
|
|
944
|
+
assert(false && "undefined copy kind");
|
|
945
|
+
abort();
|
|
1002
946
|
}
|
|
1003
947
|
}
|
|
948
|
+
else if (inVarToAddrsTable(as, rhs))
|
|
949
|
+
{
|
|
950
|
+
as[lhs] = as[rhs];
|
|
951
|
+
}
|
|
1004
952
|
}
|
|
1005
953
|
|
|
1006
|
-
void SVFIR2AbsState::handleGep(AbstractState&
|
|
954
|
+
void SVFIR2AbsState::handleGep(AbstractState& as, const GepStmt *gep)
|
|
1007
955
|
{
|
|
1008
956
|
u32_t rhs = gep->getRHSVarID();
|
|
1009
957
|
u32_t lhs = gep->getLHSVarID();
|
|
1010
|
-
if (!inVarToAddrsTable(
|
|
1011
|
-
AbstractValue &rhsVal =
|
|
1012
|
-
|
|
1013
|
-
IntervalValue offsetPair = getElementIndex(es, gep);
|
|
958
|
+
if (!inVarToAddrsTable(as, rhs)) return;
|
|
959
|
+
AbstractValue &rhsVal = as[rhs];
|
|
960
|
+
IntervalValue offsetPair = getElementIndex(as, gep);
|
|
1014
961
|
if (!isVirtualMemAddress(*rhsVal.getAddrs().begin()))
|
|
1015
962
|
return;
|
|
1016
963
|
else
|
|
@@ -1021,42 +968,40 @@ void SVFIR2AbsState::handleGep(AbstractState& es, const GepStmt *gep)
|
|
|
1021
968
|
APOffset ub = offsetPair.ub().getIntNumeral() < Options::MaxFieldLimit()?
|
|
1022
969
|
offsetPair.ub().getIntNumeral(): Options::MaxFieldLimit();
|
|
1023
970
|
for (APOffset i = lb; i <= ub; i++)
|
|
1024
|
-
gepAddrs.join_with(getGepObjAddress(
|
|
971
|
+
gepAddrs.join_with(getGepObjAddress(as, rhs, i));
|
|
1025
972
|
if (!rhsVal.isUnknown())
|
|
1026
|
-
|
|
973
|
+
as[lhs] = gepAddrs;
|
|
1027
974
|
return;
|
|
1028
975
|
}
|
|
1029
976
|
}
|
|
1030
977
|
|
|
1031
|
-
void SVFIR2AbsState::handleSelect(AbstractState&
|
|
978
|
+
void SVFIR2AbsState::handleSelect(AbstractState& as, const SelectStmt *select)
|
|
1032
979
|
{
|
|
1033
980
|
u32_t res = select->getResID();
|
|
1034
981
|
u32_t tval = select->getTrueValue()->getId();
|
|
1035
982
|
u32_t fval = select->getFalseValue()->getId();
|
|
1036
983
|
u32_t cond = select->getCondition()->getId();
|
|
1037
|
-
if (inVarToValTable(
|
|
984
|
+
if (inVarToValTable(as, tval) && inVarToValTable(as, fval) && inVarToValTable(as, cond))
|
|
1038
985
|
{
|
|
1039
|
-
if (
|
|
986
|
+
if (as[cond].getInterval().is_numeral())
|
|
1040
987
|
{
|
|
1041
|
-
|
|
988
|
+
as[res] = as[cond].getInterval().is_zero() ? as[fval] : as[tval];
|
|
1042
989
|
}
|
|
1043
990
|
else
|
|
1044
991
|
{
|
|
1045
|
-
|
|
992
|
+
as[res] = as[cond];
|
|
1046
993
|
}
|
|
1047
994
|
}
|
|
1048
|
-
else if (inVarToAddrsTable(
|
|
995
|
+
else if (inVarToAddrsTable(as, tval) && inVarToAddrsTable(as, fval) && inVarToValTable(as, cond))
|
|
1049
996
|
{
|
|
1050
|
-
if (
|
|
997
|
+
if (as[cond].getInterval().is_numeral())
|
|
1051
998
|
{
|
|
1052
|
-
|
|
1053
|
-
assert(!getAddrs(es, tval).getAddrs().empty());
|
|
1054
|
-
es.getAddrs(res) = es[cond].getInterval().is_zero() ? getAddrs(es, fval) : getAddrs(es, tval);
|
|
999
|
+
as.getAddrs(res) = as[cond].getInterval().is_zero() ? getAddrs(as, fval) : getAddrs(as, tval);
|
|
1055
1000
|
}
|
|
1056
1001
|
}
|
|
1057
1002
|
}
|
|
1058
1003
|
|
|
1059
|
-
void SVFIR2AbsState::handlePhi(AbstractState&
|
|
1004
|
+
void SVFIR2AbsState::handlePhi(AbstractState& as, const PhiStmt *phi)
|
|
1060
1005
|
{
|
|
1061
1006
|
u32_t res = phi->getResID();
|
|
1062
1007
|
AbstractValue rhs(AbstractValue::UnknownType);
|
|
@@ -1064,32 +1009,32 @@ void SVFIR2AbsState::handlePhi(AbstractState& es, const PhiStmt *phi)
|
|
|
1064
1009
|
{
|
|
1065
1010
|
NodeID curId = phi->getOpVarID(i);
|
|
1066
1011
|
|
|
1067
|
-
if (inVarToValTable(
|
|
1012
|
+
if (inVarToValTable(as, curId) || inVarToAddrsTable(as, curId))
|
|
1068
1013
|
{
|
|
1069
|
-
rhs.join_with(
|
|
1014
|
+
rhs.join_with(as[curId]);
|
|
1070
1015
|
}
|
|
1071
1016
|
}
|
|
1072
1017
|
if (!rhs.isUnknown())
|
|
1073
|
-
|
|
1018
|
+
as[res] = rhs;
|
|
1074
1019
|
}
|
|
1075
1020
|
|
|
1076
1021
|
|
|
1077
|
-
void SVFIR2AbsState::handleCall(AbstractState&
|
|
1022
|
+
void SVFIR2AbsState::handleCall(AbstractState& as, const CallPE *callPE)
|
|
1078
1023
|
{
|
|
1079
1024
|
NodeID lhs = callPE->getLHSVarID();
|
|
1080
1025
|
NodeID rhs = callPE->getRHSVarID();
|
|
1081
|
-
if (inVarToValTable(
|
|
1026
|
+
if (inVarToValTable(as, rhs) || inVarToAddrsTable(as, rhs))
|
|
1082
1027
|
{
|
|
1083
|
-
|
|
1028
|
+
as[lhs] = as[rhs];
|
|
1084
1029
|
}
|
|
1085
1030
|
}
|
|
1086
1031
|
|
|
1087
|
-
void SVFIR2AbsState::handleRet(AbstractState&
|
|
1032
|
+
void SVFIR2AbsState::handleRet(AbstractState& as, const RetPE *retPE)
|
|
1088
1033
|
{
|
|
1089
1034
|
NodeID lhs = retPE->getLHSVarID();
|
|
1090
1035
|
NodeID rhs = retPE->getRHSVarID();
|
|
1091
|
-
if (inVarToValTable(
|
|
1036
|
+
if (inVarToValTable(as, rhs) || inVarToAddrsTable(as, rhs))
|
|
1092
1037
|
{
|
|
1093
|
-
|
|
1038
|
+
as[lhs] = as[rhs];
|
|
1094
1039
|
}
|
|
1095
1040
|
}
|