svf-lib 1.0.1561 → 1.0.1563
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/SVF-osx/Release-build/svf/libSvfCore.a +0 -0
- package/SVF-osx/Release-build/svf-llvm/libSvfLLVM.a +0 -0
- package/SVF-osx/svf/include/AbstractExecution/ConsExeState.h +446 -0
- package/SVF-osx/svf/include/AbstractExecution/ExeState.h +72 -5
- package/SVF-osx/svf/include/AbstractExecution/IntervalExeState.h +13 -0
- package/SVF-osx/svf/include/AbstractExecution/SVFIR2ConsExeState.h +149 -0
- package/SVF-osx/svf/include/AbstractExecution/SymState.h +221 -0
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
//===- ConsExeState.h ----Constant Execution State-------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2022> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU Affero General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
//
|
|
23
|
+
// Created by jiawei and xiao on 6/1/23.
|
|
24
|
+
//
|
|
25
|
+
|
|
26
|
+
#ifndef SVF_CONSEXESTATE_H
|
|
27
|
+
#define SVF_CONSEXESTATE_H
|
|
28
|
+
|
|
29
|
+
#include "AbstractExecution/SingleAbsValue.h"
|
|
30
|
+
#include "AbstractExecution/ExeState.h"
|
|
31
|
+
|
|
32
|
+
namespace SVF
|
|
33
|
+
{
|
|
34
|
+
|
|
35
|
+
/*!
|
|
36
|
+
* Constant Expr Execution State
|
|
37
|
+
*
|
|
38
|
+
* Constant expr execution state support z3 symbolic value
|
|
39
|
+
* and gives a top value when two different constants join
|
|
40
|
+
*
|
|
41
|
+
* lattice: ⊤ may be constant
|
|
42
|
+
* / / | \ \ \
|
|
43
|
+
* true ... c0 c1 ... false constant
|
|
44
|
+
* \ \ \ | | |
|
|
45
|
+
* ⊥ not contant
|
|
46
|
+
*/
|
|
47
|
+
class ConsExeState final : public ExeState
|
|
48
|
+
{
|
|
49
|
+
friend class SVFIR2ConsExeState;
|
|
50
|
+
|
|
51
|
+
public:
|
|
52
|
+
typedef Map<u32_t, SingleAbsValue> VarToValMap;
|
|
53
|
+
typedef VarToValMap LocToValMap;
|
|
54
|
+
|
|
55
|
+
static ConsExeState globalConsES;
|
|
56
|
+
|
|
57
|
+
protected:
|
|
58
|
+
VarToValMap _varToVal;
|
|
59
|
+
LocToValMap _locToVal;
|
|
60
|
+
|
|
61
|
+
public:
|
|
62
|
+
ConsExeState(): ExeState(ExeState::SingleValueK) {}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
/// Constructor
|
|
66
|
+
ConsExeState(VarToValMap varToValMap, LocToValMap locToValMap) : ExeState(ExeState::SingleValueK), _varToVal(
|
|
67
|
+
SVFUtil::move(varToValMap)), _locToVal(SVFUtil::move(locToValMap)) {}
|
|
68
|
+
|
|
69
|
+
/// Copy Constructor
|
|
70
|
+
ConsExeState(const ConsExeState &rhs) : ExeState(rhs), _varToVal(rhs.getVarToVal()),
|
|
71
|
+
_locToVal(rhs.getLocToVal())
|
|
72
|
+
{
|
|
73
|
+
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// Destructor
|
|
77
|
+
~ConsExeState() override
|
|
78
|
+
{
|
|
79
|
+
_varToVal.clear();
|
|
80
|
+
_locToVal.clear();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/// Copy operator
|
|
84
|
+
ConsExeState &operator=(const ConsExeState &rhs);
|
|
85
|
+
|
|
86
|
+
/// Move Constructor
|
|
87
|
+
ConsExeState(ConsExeState &&rhs) noexcept: ExeState(std::move(rhs)),
|
|
88
|
+
_varToVal(SVFUtil::move(rhs._varToVal)), _locToVal(SVFUtil::move(rhs._locToVal))
|
|
89
|
+
{
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// Move operator
|
|
94
|
+
ConsExeState &operator=(ConsExeState &&rhs) noexcept;
|
|
95
|
+
|
|
96
|
+
/// Name
|
|
97
|
+
static inline std::string name()
|
|
98
|
+
{
|
|
99
|
+
return "ConstantExpr";
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/// Exposed APIs
|
|
103
|
+
//{%
|
|
104
|
+
bool operator==(const ConsExeState &rhs) const;
|
|
105
|
+
|
|
106
|
+
bool operator!=(const ConsExeState &other) const
|
|
107
|
+
{
|
|
108
|
+
return !(*this == other);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
bool operator<(const ConsExeState &rhs) const;
|
|
112
|
+
|
|
113
|
+
u32_t hash() const override;
|
|
114
|
+
|
|
115
|
+
/// Merge rhs into this
|
|
116
|
+
bool joinWith(const ConsExeState &rhs);
|
|
117
|
+
|
|
118
|
+
/// Build global execution state
|
|
119
|
+
void buildGlobES(ConsExeState &globES, Set<u32_t> &vars);
|
|
120
|
+
|
|
121
|
+
/// Update symbolic states based on the summary/side-effect of callee
|
|
122
|
+
void applySummary(const ConsExeState &summary);
|
|
123
|
+
|
|
124
|
+
/// Whether state is null state (uninitialized state)
|
|
125
|
+
inline bool isNullState() const
|
|
126
|
+
{
|
|
127
|
+
return _varToVal.size() == 1 && eq((*_varToVal.begin()).second, -1) && _locToVal.empty();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// Print values of all expressions
|
|
131
|
+
void printExprValues() const;
|
|
132
|
+
|
|
133
|
+
/// Print values of all expressions
|
|
134
|
+
void printExprValues(std::ostream &oss) const override;
|
|
135
|
+
|
|
136
|
+
std::string toString() const override;
|
|
137
|
+
|
|
138
|
+
std::string pcToString() const;
|
|
139
|
+
|
|
140
|
+
std::string varToString(u32_t varId) const;
|
|
141
|
+
|
|
142
|
+
std::string locToString(u32_t objId) const;
|
|
143
|
+
|
|
144
|
+
bool applySelect(u32_t res, u32_t cond, u32_t top, u32_t fop);
|
|
145
|
+
|
|
146
|
+
bool applyPhi(u32_t res, std::vector<u32_t> &ops);
|
|
147
|
+
|
|
148
|
+
inline bool inVarToVal(u32_t varId) const
|
|
149
|
+
{
|
|
150
|
+
return _varToVal.count(varId) || globalConsES._varToVal.count(varId);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
inline bool inLocalLocToVal(const SingleAbsValue &loc) const
|
|
154
|
+
{
|
|
155
|
+
assert(loc.is_numeral() && "location must be numeral");
|
|
156
|
+
s32_t virAddr = z3Expr2NumValue(loc);
|
|
157
|
+
assert(isVirtualMemAddress(virAddr) && "Pointer operand is not a physical address?");
|
|
158
|
+
u32_t objId = getInternalID(virAddr);
|
|
159
|
+
assert(getInternalID(objId) == objId && "SVFVar idx overflow > 0x7f000000?");
|
|
160
|
+
return inLocalLocToVal(objId);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
inline bool inLocalLocToVal(u32_t varId) const
|
|
164
|
+
{
|
|
165
|
+
return _locToVal.count(varId);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
inline bool inLocToVal(u32_t varId) const
|
|
169
|
+
{
|
|
170
|
+
return inLocalLocToVal(varId) || globalConsES._locToVal.count(varId);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
inline bool equalVar(u32_t lhs, u32_t rhs)
|
|
174
|
+
{
|
|
175
|
+
if (!inVarToVal(lhs) || !inVarToVal(rhs)) return false;
|
|
176
|
+
return eq((*this)[lhs], (*this)[rhs]);
|
|
177
|
+
}
|
|
178
|
+
//%}
|
|
179
|
+
|
|
180
|
+
virtual inline bool inVarToAddrsTable(u32_t id) const override
|
|
181
|
+
{
|
|
182
|
+
return _varToVAddrs.find(id) != _varToVAddrs.end() ||
|
|
183
|
+
globalConsES._varToVAddrs.find(id) != globalConsES._varToVAddrs.end();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
virtual inline bool inLocToAddrsTable(u32_t id) const override
|
|
187
|
+
{
|
|
188
|
+
return globalConsES._locToVAddrs.find(id) != globalConsES._locToVAddrs.end() || inLocalLocToAddrsTable(id);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
virtual inline bool inLocalLocToAddrsTable(u32_t id) const
|
|
192
|
+
{
|
|
193
|
+
return _locToVAddrs.find(id) != _locToVAddrs.end();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
virtual VAddrs &getVAddrs(u32_t id) override
|
|
197
|
+
{
|
|
198
|
+
auto it = globalConsES._varToVAddrs.find(id);
|
|
199
|
+
if (it != globalConsES._varToVAddrs.end()) return it->second;
|
|
200
|
+
return _varToVAddrs[id];
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
virtual VAddrs &loadVAddrs(u32_t addr) override
|
|
204
|
+
{
|
|
205
|
+
assert(isVirtualMemAddress(addr) && "not virtual address?");
|
|
206
|
+
u32_t objId = getInternalID(addr);
|
|
207
|
+
auto it = _locToVAddrs.find(objId);
|
|
208
|
+
if (it != _locToVAddrs.end())
|
|
209
|
+
{
|
|
210
|
+
return it->second;
|
|
211
|
+
}
|
|
212
|
+
else
|
|
213
|
+
{
|
|
214
|
+
auto globIt = globalConsES._locToVAddrs.find(objId);
|
|
215
|
+
if (globIt != globalConsES._locToVAddrs.end())
|
|
216
|
+
{
|
|
217
|
+
return globIt->second;
|
|
218
|
+
}
|
|
219
|
+
else
|
|
220
|
+
{
|
|
221
|
+
return getVAddrs(0);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
virtual std::string varToAddrs(u32_t varId) const override
|
|
227
|
+
{
|
|
228
|
+
std::stringstream exprName;
|
|
229
|
+
auto it = _varToVAddrs.find(varId);
|
|
230
|
+
if (it == _varToVAddrs.end())
|
|
231
|
+
{
|
|
232
|
+
auto git = globalConsES._varToVAddrs.find(varId);
|
|
233
|
+
if (git == globalConsES._varToVAddrs.end())
|
|
234
|
+
exprName << "Var not in varToAddrs!\n";
|
|
235
|
+
else
|
|
236
|
+
{
|
|
237
|
+
const VAddrs &vaddrs = git->second;
|
|
238
|
+
if (vaddrs.size() == 1)
|
|
239
|
+
{
|
|
240
|
+
exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
|
|
241
|
+
}
|
|
242
|
+
else
|
|
243
|
+
{
|
|
244
|
+
exprName << "addr: {";
|
|
245
|
+
for (const auto &addr: vaddrs)
|
|
246
|
+
{
|
|
247
|
+
exprName << std::dec << getInternalID(addr) << ", ";
|
|
248
|
+
}
|
|
249
|
+
exprName << "}\n";
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else
|
|
254
|
+
{
|
|
255
|
+
const VAddrs &vaddrs = it->second;
|
|
256
|
+
if (vaddrs.size() == 1)
|
|
257
|
+
{
|
|
258
|
+
exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
|
|
259
|
+
}
|
|
260
|
+
else
|
|
261
|
+
{
|
|
262
|
+
exprName << "addr: {";
|
|
263
|
+
for (const auto &addr: vaddrs)
|
|
264
|
+
{
|
|
265
|
+
exprName << std::dec << getInternalID(addr) << ", ";
|
|
266
|
+
}
|
|
267
|
+
exprName << "}\n";
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return SVFUtil::move(exprName.str());
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
virtual std::string locToAddrs(u32_t objId) const override
|
|
274
|
+
{
|
|
275
|
+
std::stringstream exprName;
|
|
276
|
+
auto it = _locToVAddrs.find(objId);
|
|
277
|
+
if (it == _locToVAddrs.end())
|
|
278
|
+
{
|
|
279
|
+
auto git = globalConsES._locToVAddrs.find(objId);
|
|
280
|
+
if (git == globalConsES._locToVAddrs.end())
|
|
281
|
+
exprName << "Obj not in locToVal!\n";
|
|
282
|
+
else
|
|
283
|
+
{
|
|
284
|
+
const VAddrs &vaddrs = git->second;
|
|
285
|
+
if (vaddrs.size() == 1)
|
|
286
|
+
{
|
|
287
|
+
exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
|
|
288
|
+
}
|
|
289
|
+
else
|
|
290
|
+
{
|
|
291
|
+
exprName << "addr: {";
|
|
292
|
+
for (const auto &addr: vaddrs)
|
|
293
|
+
{
|
|
294
|
+
exprName << std::dec << getInternalID(addr) << ", ";
|
|
295
|
+
}
|
|
296
|
+
exprName << "}\n";
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else
|
|
301
|
+
{
|
|
302
|
+
const VAddrs &vaddrs = it->second;
|
|
303
|
+
if (vaddrs.size() == 1)
|
|
304
|
+
{
|
|
305
|
+
exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
|
|
306
|
+
}
|
|
307
|
+
else
|
|
308
|
+
{
|
|
309
|
+
exprName << "addr: {";
|
|
310
|
+
for (const auto &addr: vaddrs)
|
|
311
|
+
{
|
|
312
|
+
exprName << std::dec << getInternalID(addr) << ", ";
|
|
313
|
+
}
|
|
314
|
+
exprName << "}\n";
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return SVFUtil::move(exprName.str());
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/// Empty execution state with a true path constraint
|
|
321
|
+
static inline ConsExeState initExeState()
|
|
322
|
+
{
|
|
323
|
+
VarToValMap mp;
|
|
324
|
+
ConsExeState exeState(mp, SVFUtil::move(mp));
|
|
325
|
+
return SVFUtil::move(exeState);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/// Empty execution state with a null expr
|
|
329
|
+
static inline ConsExeState nullExeState()
|
|
330
|
+
{
|
|
331
|
+
VarToValMap mp;
|
|
332
|
+
ConsExeState exeState(mp, SVFUtil::move(mp));
|
|
333
|
+
exeState._varToVal[PAG::getPAG()->getNullPtr()] = -1;
|
|
334
|
+
return SVFUtil::move(exeState);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
public:
|
|
338
|
+
|
|
339
|
+
inline const VarToValMap &getVarToVal() const
|
|
340
|
+
{
|
|
341
|
+
return _varToVal;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
inline const LocToValMap &getLocToVal() const
|
|
345
|
+
{
|
|
346
|
+
return _locToVal;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
s64_t getNumber(u32_t lhs);
|
|
351
|
+
|
|
352
|
+
public:
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
static inline SingleAbsValue getIntOneZ3Expr()
|
|
356
|
+
{
|
|
357
|
+
return getContext().int_val(1);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
static inline SingleAbsValue getIntZeroZ3Expr()
|
|
361
|
+
{
|
|
362
|
+
return getContext().int_val(0);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
static inline SingleAbsValue getTrueZ3Expr()
|
|
366
|
+
{
|
|
367
|
+
return getContext().bool_val(true);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
static inline SingleAbsValue getFalseZ3Expr()
|
|
371
|
+
{
|
|
372
|
+
return getContext().bool_val(false);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
public:
|
|
376
|
+
inline SingleAbsValue &operator[](u32_t varId)
|
|
377
|
+
{
|
|
378
|
+
auto it = globalConsES._varToVal.find(varId);
|
|
379
|
+
if (it != globalConsES._varToVal.end())
|
|
380
|
+
return it->second;
|
|
381
|
+
else
|
|
382
|
+
return _varToVal[varId];
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/// Store value to location
|
|
386
|
+
bool store(const SingleAbsValue &loc, const SingleAbsValue &value);
|
|
387
|
+
|
|
388
|
+
/// Load value at location
|
|
389
|
+
SingleAbsValue load(const SingleAbsValue &loc);
|
|
390
|
+
|
|
391
|
+
/// Return int value from an expression if it is a numeral, otherwise return an approximate value
|
|
392
|
+
static inline s32_t z3Expr2NumValue(const SingleAbsValue &e)
|
|
393
|
+
{
|
|
394
|
+
assert(e.is_numeral() && "not numeral?");
|
|
395
|
+
int64_t i;
|
|
396
|
+
if(e.getExpr().is_numeral_i64(i))
|
|
397
|
+
return e.get_numeral_int64();
|
|
398
|
+
else
|
|
399
|
+
{
|
|
400
|
+
return e.leq(0) ? INT32_MIN : INT32_MAX;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/// Whether two var to value map is equivalent
|
|
405
|
+
static bool eqVarToValMap(const VarToValMap &pre, const VarToValMap &nxt);
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
/// Whether lhs is less than rhs
|
|
409
|
+
static bool lessThanVarToValMap(const VarToValMap &lhs, const VarToValMap &rhs);
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
private:
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
static bool assign(SingleAbsValue &lhs, const SingleAbsValue &rhs);
|
|
416
|
+
|
|
417
|
+
inline bool store(u32_t objId, const SingleAbsValue &z3Expr)
|
|
418
|
+
{
|
|
419
|
+
SingleAbsValue &lhs = _locToVal[objId];
|
|
420
|
+
if (!eq(lhs, z3Expr.simplify()))
|
|
421
|
+
{
|
|
422
|
+
lhs = z3Expr.simplify();
|
|
423
|
+
return true;
|
|
424
|
+
}
|
|
425
|
+
else
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
inline SingleAbsValue load(u32_t objId);
|
|
430
|
+
}; // end class ConExeState
|
|
431
|
+
|
|
432
|
+
} // end namespace SVF
|
|
433
|
+
|
|
434
|
+
/// Specialized hash for ConExeState
|
|
435
|
+
template<>
|
|
436
|
+
struct std::hash<SVF::ConsExeState>
|
|
437
|
+
{
|
|
438
|
+
size_t operator()(const SVF::ConsExeState &exeState) const
|
|
439
|
+
{
|
|
440
|
+
return exeState.hash();
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
#endif // SVF_CONSEXESTATE_H
|
|
@@ -54,7 +54,7 @@ public:
|
|
|
54
54
|
/// Execution state kind
|
|
55
55
|
enum ExeState_TYPE
|
|
56
56
|
{
|
|
57
|
-
IntervalK,
|
|
57
|
+
IntervalK, SingleValueK
|
|
58
58
|
};
|
|
59
59
|
private:
|
|
60
60
|
ExeState_TYPE _kind;
|
|
@@ -90,9 +90,9 @@ public:
|
|
|
90
90
|
return *this;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
bool operator==(const ExeState &rhs) const;
|
|
93
|
+
virtual bool operator==(const ExeState &rhs) const;
|
|
94
94
|
|
|
95
|
-
inline bool operator!=(const ExeState &rhs) const
|
|
95
|
+
inline virtual bool operator!=(const ExeState &rhs) const
|
|
96
96
|
{
|
|
97
97
|
return !(*this == rhs);
|
|
98
98
|
}
|
|
@@ -103,10 +103,10 @@ public:
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/// Make all value join with the other
|
|
106
|
-
|
|
106
|
+
bool joinWith(const ExeState &other);
|
|
107
107
|
|
|
108
108
|
/// Make all value meet with the other
|
|
109
|
-
|
|
109
|
+
bool meetWith(const ExeState &other);
|
|
110
110
|
|
|
111
111
|
virtual u32_t hash() const;
|
|
112
112
|
|
|
@@ -190,6 +190,64 @@ protected:
|
|
|
190
190
|
return true;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
public:
|
|
194
|
+
|
|
195
|
+
virtual std::string varToAddrs(u32_t varId) const
|
|
196
|
+
{
|
|
197
|
+
std::stringstream exprName;
|
|
198
|
+
auto it = _varToVAddrs.find(varId);
|
|
199
|
+
if (it == _varToVAddrs.end())
|
|
200
|
+
{
|
|
201
|
+
exprName << "Var not in varToAddrs!\n";
|
|
202
|
+
}
|
|
203
|
+
else
|
|
204
|
+
{
|
|
205
|
+
const VAddrs &vaddrs = it->second;
|
|
206
|
+
if (vaddrs.size() == 1)
|
|
207
|
+
{
|
|
208
|
+
exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
|
|
209
|
+
}
|
|
210
|
+
else
|
|
211
|
+
{
|
|
212
|
+
exprName << "addr: {";
|
|
213
|
+
for (const auto &addr: vaddrs)
|
|
214
|
+
{
|
|
215
|
+
exprName << std::dec << getInternalID(addr) << ", ";
|
|
216
|
+
}
|
|
217
|
+
exprName << "}\n";
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return SVFUtil::move(exprName.str());
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
virtual std::string locToAddrs(u32_t objId) const
|
|
224
|
+
{
|
|
225
|
+
std::stringstream exprName;
|
|
226
|
+
auto it = _locToVAddrs.find(objId);
|
|
227
|
+
if (it == _locToVAddrs.end())
|
|
228
|
+
{
|
|
229
|
+
exprName << "Var not in varToAddrs!\n";
|
|
230
|
+
}
|
|
231
|
+
else
|
|
232
|
+
{
|
|
233
|
+
const VAddrs &vaddrs = it->second;
|
|
234
|
+
if (vaddrs.size() == 1)
|
|
235
|
+
{
|
|
236
|
+
exprName << "addr: {" << std::dec << getInternalID(*vaddrs.begin()) << "}\n";
|
|
237
|
+
}
|
|
238
|
+
else
|
|
239
|
+
{
|
|
240
|
+
exprName << "addr: {";
|
|
241
|
+
for (const auto &addr: vaddrs)
|
|
242
|
+
{
|
|
243
|
+
exprName << std::dec << getInternalID(addr) << ", ";
|
|
244
|
+
}
|
|
245
|
+
exprName << "}\n";
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return SVFUtil::move(exprName.str());
|
|
249
|
+
}
|
|
250
|
+
|
|
193
251
|
public:
|
|
194
252
|
static z3::context &getContext()
|
|
195
253
|
{
|
|
@@ -220,4 +278,13 @@ public:
|
|
|
220
278
|
|
|
221
279
|
|
|
222
280
|
} // end namespace SVF
|
|
281
|
+
|
|
282
|
+
template<>
|
|
283
|
+
struct std::hash<SVF::ExeState>
|
|
284
|
+
{
|
|
285
|
+
size_t operator()(const SVF::ExeState &es) const
|
|
286
|
+
{
|
|
287
|
+
return es.hash();
|
|
288
|
+
}
|
|
289
|
+
};
|
|
223
290
|
#endif //Z3_EXAMPLE_EXESTATE_H
|
|
@@ -25,6 +25,19 @@
|
|
|
25
25
|
* Created on: Jul 9, 2022
|
|
26
26
|
* Author: Xiao Cheng, Jiawei Wang
|
|
27
27
|
*
|
|
28
|
+
* [-oo,+oo]
|
|
29
|
+
* / / \ \
|
|
30
|
+
* [-oo,1] ... [-oo,10] ... [-1,+oo] ... [0,+oo]
|
|
31
|
+
* \ \ / /
|
|
32
|
+
* \ [-1,10] /
|
|
33
|
+
* \ / \ /
|
|
34
|
+
* ... [-1,1] ... [0,10] ...
|
|
35
|
+
* \ | \ / \ /
|
|
36
|
+
* ... [-1,0] [0,1] ... [1,9] ...
|
|
37
|
+
* \ | \ | \ /
|
|
38
|
+
* ... [-1,-1] [0,0] [1,1] ...
|
|
39
|
+
* \ \ \ / /
|
|
40
|
+
* ⊥
|
|
28
41
|
*/
|
|
29
42
|
|
|
30
43
|
#ifndef Z3_EXAMPLE_INTERVAL_DOMAIN_H
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
//===- SVFIR2ConsExeState.h ----SVFIR2ConsExeState-------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2022> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU Affero General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
//
|
|
24
|
+
// Created by jiawei and xiao on 6/1/23.
|
|
25
|
+
//
|
|
26
|
+
|
|
27
|
+
#ifndef SVF_SVFIR2CONSEXESTATE_H
|
|
28
|
+
#define SVF_SVFIR2CONSEXESTATE_H
|
|
29
|
+
|
|
30
|
+
#include "AbstractExecution/ConsExeState.h"
|
|
31
|
+
#include "SVFIR/SVFIR.h"
|
|
32
|
+
|
|
33
|
+
namespace SVF
|
|
34
|
+
{
|
|
35
|
+
class SVFIR2ConsExeState
|
|
36
|
+
{
|
|
37
|
+
public:
|
|
38
|
+
typedef ExeState::VAddrs VAddrs;
|
|
39
|
+
|
|
40
|
+
SVFIR2ConsExeState() = default;
|
|
41
|
+
|
|
42
|
+
void setEs(ConsExeState *es)
|
|
43
|
+
{
|
|
44
|
+
_es = es;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
ConsExeState *getEs()
|
|
48
|
+
{
|
|
49
|
+
return _es;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
virtual ~SVFIR2ConsExeState();
|
|
53
|
+
|
|
54
|
+
/// Translator for llvm ir
|
|
55
|
+
//{%
|
|
56
|
+
/// https://llvm.org/docs/LangRef.html#alloca-instruction
|
|
57
|
+
void translateAddr(const AddrStmt *addr);
|
|
58
|
+
|
|
59
|
+
/// https://llvm.org/docs/LangRef.html#binary-operations
|
|
60
|
+
void translateBinary(const BinaryOPStmt *binary);
|
|
61
|
+
|
|
62
|
+
/// https://llvm.org/docs/LangRef.html#icmp-instruction
|
|
63
|
+
void translateCmp(const CmpStmt *cmp);
|
|
64
|
+
|
|
65
|
+
/// https://llvm.org/docs/LangRef.html#load-instruction
|
|
66
|
+
void translateLoad(const LoadStmt *load);
|
|
67
|
+
|
|
68
|
+
/// https://llvm.org/docs/LangRef.html#store-instruction
|
|
69
|
+
void translateStore(const StoreStmt *store);
|
|
70
|
+
|
|
71
|
+
/// https://llvm.org/docs/LangRef.html#conversion-operations
|
|
72
|
+
void translateCopy(const CopyStmt *copy);
|
|
73
|
+
|
|
74
|
+
/// https://llvm.org/docs/LangRef.html#call-instruction
|
|
75
|
+
void translateCall(const CallPE *callPE);
|
|
76
|
+
|
|
77
|
+
void translateRet(const RetPE *retPE);
|
|
78
|
+
|
|
79
|
+
/// https://llvm.org/docs/LangRef.html#getelementptr-instruction
|
|
80
|
+
void translateGep(const GepStmt *gep, bool isGlobal);
|
|
81
|
+
|
|
82
|
+
/// https://llvm.org/docs/LangRef.html#select-instruction
|
|
83
|
+
void translateSelect(const SelectStmt *select);
|
|
84
|
+
|
|
85
|
+
/// https://llvm.org/docs/LangRef.html#i-phi
|
|
86
|
+
void translatePhi(const PhiStmt *phi);
|
|
87
|
+
|
|
88
|
+
//%}
|
|
89
|
+
//%}
|
|
90
|
+
|
|
91
|
+
/// Return the expr of gep object given a base and offset
|
|
92
|
+
VAddrs getGepObjAddress(u32_t base, u32_t offset);
|
|
93
|
+
|
|
94
|
+
/// Return the offset expression of a GepStmt
|
|
95
|
+
std::pair<s32_t, s32_t> getGepOffset(const GepStmt *gep);
|
|
96
|
+
|
|
97
|
+
/// Init ConZ3Expr for ObjVar
|
|
98
|
+
void initObjVar(const ObjVar *objVar, u32_t varId);
|
|
99
|
+
|
|
100
|
+
void initValVar(const ValVar *objVar, u32_t varId);
|
|
101
|
+
|
|
102
|
+
void initSVFVar(u32_t varId);
|
|
103
|
+
|
|
104
|
+
void moveToGlobal();
|
|
105
|
+
|
|
106
|
+
/// The physical address starts with 0x7f...... + idx
|
|
107
|
+
static inline u32_t getVirtualMemAddress(u32_t idx)
|
|
108
|
+
{
|
|
109
|
+
return ExeState::getVirtualMemAddress(idx);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/// Check bit value of val start with 0x7F000000, filter by 0xFF000000
|
|
113
|
+
static inline bool isVirtualMemAddress(u32_t val)
|
|
114
|
+
{
|
|
115
|
+
return ExeState::isVirtualMemAddress(val);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/// Return the internal index if idx is an address otherwise return the value of idx
|
|
119
|
+
static inline u32_t getInternalID(u32_t idx)
|
|
120
|
+
{
|
|
121
|
+
return ExeState::getInternalID(idx);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
inline bool inVarToValTable(u32_t id) const
|
|
125
|
+
{
|
|
126
|
+
return _es->inVarToVal(id);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
inline bool inLocToValTable(u32_t id) const
|
|
130
|
+
{
|
|
131
|
+
return _es->inLocToVal(id);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
inline bool inVarToAddrsTable(u32_t id) const
|
|
135
|
+
{
|
|
136
|
+
return _es->inVarToAddrsTable(id);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
inline bool inLocToAddrsTable(u32_t id) const
|
|
140
|
+
{
|
|
141
|
+
return _es->inLocToAddrsTable(id);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
protected:
|
|
145
|
+
ConsExeState *_es{nullptr};
|
|
146
|
+
}; // end class SVFIR2ConsExeState
|
|
147
|
+
} // end namespace SVF
|
|
148
|
+
|
|
149
|
+
#endif // SVF_SVFIR2CONSEXESTATE_H
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
//===- SymState.h ----Symbolic State-------------------------//
|
|
2
|
+
//
|
|
3
|
+
// SVF: Static Value-Flow Analysis
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) <2013-2022> <Yulei Sui>
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
// This program is free software: you can redistribute it and/or modify
|
|
9
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
10
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
// (at your option) any later version.
|
|
12
|
+
|
|
13
|
+
// This program is distributed in the hope that it will be useful,
|
|
14
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
// GNU Affero General Public License for more details.
|
|
17
|
+
|
|
18
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
19
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
//
|
|
21
|
+
//===----------------------------------------------------------------------===//
|
|
22
|
+
|
|
23
|
+
//
|
|
24
|
+
// Created by jiawei and xiao on 6/1/23.
|
|
25
|
+
//
|
|
26
|
+
|
|
27
|
+
#ifndef SVF_SYMSTATE_H
|
|
28
|
+
#define SVF_SYMSTATE_H
|
|
29
|
+
|
|
30
|
+
#include "AbstractExecution/ConsExeState.h"
|
|
31
|
+
|
|
32
|
+
namespace SVF
|
|
33
|
+
{
|
|
34
|
+
/*!
|
|
35
|
+
* Symbolic state
|
|
36
|
+
*
|
|
37
|
+
* Execution State + Type State
|
|
38
|
+
*/
|
|
39
|
+
class SymState
|
|
40
|
+
{
|
|
41
|
+
|
|
42
|
+
public:
|
|
43
|
+
typedef std::string TypeState;
|
|
44
|
+
typedef std::vector<u32_t> KeyNodes;
|
|
45
|
+
typedef Set<KeyNodes> KeyNodesSet;
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
ConsExeState _exeState; ///< Execution state: values of variables
|
|
49
|
+
TypeState _typeState; ///< Type state: FSM node
|
|
50
|
+
|
|
51
|
+
private:
|
|
52
|
+
/// Only for bug report
|
|
53
|
+
KeyNodesSet _keyNodesSet; ///< The nodes where abstract state changes
|
|
54
|
+
Z3Expr _branchCondition; ///< The branches current state passes
|
|
55
|
+
|
|
56
|
+
public:
|
|
57
|
+
/// Constructor
|
|
58
|
+
SymState() : _exeState(ConsExeState::nullExeState()), _typeState("") {}
|
|
59
|
+
|
|
60
|
+
/// Constructor
|
|
61
|
+
SymState(ConsExeState _es, TypeState _as);
|
|
62
|
+
|
|
63
|
+
/// Desstructor
|
|
64
|
+
virtual ~SymState() = default;
|
|
65
|
+
|
|
66
|
+
/// Copy Constructor
|
|
67
|
+
SymState(const SymState &rhs) : _exeState(rhs._exeState), _typeState(rhs._typeState), _keyNodesSet(rhs._keyNodesSet),
|
|
68
|
+
_branchCondition(rhs._branchCondition)
|
|
69
|
+
{
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// Operator=
|
|
74
|
+
SymState &operator=(const SymState &rhs)
|
|
75
|
+
{
|
|
76
|
+
if (*this != rhs)
|
|
77
|
+
{
|
|
78
|
+
_typeState = rhs._typeState;
|
|
79
|
+
_exeState = rhs._exeState;
|
|
80
|
+
_keyNodesSet = rhs._keyNodesSet;
|
|
81
|
+
_branchCondition = rhs._branchCondition;
|
|
82
|
+
}
|
|
83
|
+
return *this;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
/// Move Constructor
|
|
88
|
+
SymState(SymState &&rhs) noexcept: _exeState(SVFUtil::move(rhs._exeState)),
|
|
89
|
+
_typeState(SVFUtil::move(rhs._typeState)),
|
|
90
|
+
_keyNodesSet(SVFUtil::move(rhs._keyNodesSet)),
|
|
91
|
+
_branchCondition(rhs._branchCondition)
|
|
92
|
+
{
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/// Move operator=
|
|
97
|
+
SymState &operator=(SymState &&rhs) noexcept
|
|
98
|
+
{
|
|
99
|
+
if (this != &rhs)
|
|
100
|
+
{
|
|
101
|
+
_typeState = SVFUtil::move(rhs._typeState);
|
|
102
|
+
_exeState = SVFUtil::move(rhs._exeState);
|
|
103
|
+
_keyNodesSet = SVFUtil::move(rhs._keyNodesSet);
|
|
104
|
+
_branchCondition = rhs._branchCondition;
|
|
105
|
+
}
|
|
106
|
+
return *this;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const KeyNodesSet &getKeyNodesSet() const
|
|
110
|
+
{
|
|
111
|
+
return _keyNodesSet;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
void insertKeyNode(NodeID id)
|
|
116
|
+
{
|
|
117
|
+
if (_keyNodesSet.empty())
|
|
118
|
+
{
|
|
119
|
+
_keyNodesSet.insert(KeyNodes{id});
|
|
120
|
+
}
|
|
121
|
+
else
|
|
122
|
+
{
|
|
123
|
+
for (const auto &df: _keyNodesSet)
|
|
124
|
+
{
|
|
125
|
+
const_cast<KeyNodes &>(df).push_back(id);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void setKeyNodesSet(KeyNodesSet ns)
|
|
131
|
+
{
|
|
132
|
+
_keyNodesSet = SVFUtil::move(ns);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
void clearKeyNodesSet()
|
|
136
|
+
{
|
|
137
|
+
_keyNodesSet.clear();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
inline const Z3Expr &getBranchCondition() const
|
|
141
|
+
{
|
|
142
|
+
return _branchCondition;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
inline void setBranchCondition(const Z3Expr &br)
|
|
146
|
+
{
|
|
147
|
+
_branchCondition = br;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const TypeState &getAbstractState() const
|
|
151
|
+
{
|
|
152
|
+
return _typeState;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
TypeState &getAbstractState()
|
|
156
|
+
{
|
|
157
|
+
return _typeState;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
void setAbsState(const TypeState &absState)
|
|
161
|
+
{
|
|
162
|
+
_typeState = absState;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const ConsExeState &getExecutionState() const
|
|
166
|
+
{
|
|
167
|
+
return _exeState;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
ConsExeState &getExecutionState()
|
|
171
|
+
{
|
|
172
|
+
return _exeState;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/// Overloading Operator==
|
|
176
|
+
inline bool operator==(const SymState &rhs) const
|
|
177
|
+
{
|
|
178
|
+
return _typeState == rhs.getAbstractState() && _exeState == rhs.getExecutionState();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/// Overloading Operator!=
|
|
182
|
+
inline bool operator!=(const SymState &rhs) const
|
|
183
|
+
{
|
|
184
|
+
return !(*this == rhs);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/// Overloading Operator==
|
|
188
|
+
inline bool operator<(const SymState &rhs) const
|
|
189
|
+
{
|
|
190
|
+
if (_typeState != rhs.getAbstractState())
|
|
191
|
+
return _typeState < rhs.getAbstractState();
|
|
192
|
+
if (_exeState != rhs.getExecutionState())
|
|
193
|
+
return _exeState < rhs.getExecutionState();
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
inline bool isNullSymState() const
|
|
198
|
+
{
|
|
199
|
+
return getExecutionState().isNullState() && getAbstractState().empty();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
} // end namespace SVF
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
/// Specialise hash for SymState
|
|
209
|
+
template<>
|
|
210
|
+
struct std::hash<SVF::SymState>
|
|
211
|
+
{
|
|
212
|
+
size_t operator()(const SVF::SymState &symState) const
|
|
213
|
+
{
|
|
214
|
+
|
|
215
|
+
SVF::Hash<std::pair<SVF::SymState::TypeState, SVF::ConsExeState>> pairH;
|
|
216
|
+
|
|
217
|
+
return pairH(make_pair(symState.getAbstractState(), symState.getExecutionState()));
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
#endif // SVF_SYMSTATE_H
|