-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathZ3Mgr.h
146 lines (115 loc) · 4.03 KB
/
Z3Mgr.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//===- Z3Mgr.h -- Z3 manager for software verification ------------------//
//
// SVF: Static Value-Flow Analysis
//
// Copyright (C) <2013-2022> <Yulei Sui>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//===----------------------------------------------------------------------===//
/*
* Z3 manager for software verification
*
* Created on: Feb 19, 2024
*/
#ifndef SOFTWARE_SECURITY_ANALYSIS_Z3MGR_H
#define SOFTWARE_SECURITY_ANALYSIS_Z3MGR_H
#include "z3++.h"
namespace SVF {
#ifdef DEBUGINFO
# define DBOP(X) X;
#else
# define DBOP(X)
#endif
#define AddressMask 0x7f000000
#define FlippedAddressMask (AddressMask ^ 0xffffffff)
typedef unsigned u32_t;
typedef signed s32_t;
/// Z3 manager interface
class Z3Mgr {
public:
/// Constructor
Z3Mgr(u32_t numOfMapElems)
: solver(ctx)
, varID2ExprMap(ctx)
, lastSlot(numOfMapElems) {
resetZ3ExprMap();
}
inline void resetZ3ExprMap() {
varID2ExprMap.resize(lastSlot + 1);
z3::expr loc2ValMap = ctx.constant("loc2ValMap", ctx.array_sort(ctx.int_sort(), ctx.int_sort()));
updateZ3Expr(lastSlot, loc2ValMap);
}
/// Store and Select for Loc2ValMap, i.e., store and load
z3::expr storeValue(const z3::expr loc, const z3::expr value);
z3::expr loadValue(const z3::expr loc);
/// The physical address starts with 0x7f...... + idx
inline u32_t getVirtualMemAddress(u32_t idx) const {
return AddressMask + idx;
}
inline bool isVirtualMemAddress(u32_t val) {
return (val > 0 && (val & AddressMask) == AddressMask);
// return ((val & AddressMask) > 0);
}
inline bool isVirtualMemAddress(z3::expr e) {
z3::expr val = getEvalExpr(e);
if (val.is_numeral()) {
return isVirtualMemAddress(z3Expr2NumValue(val));
}
else {
return false;
}
}
/// Return the internal index if idx is an address otherwise return the value of idx
inline u32_t getInternalID(u32_t idx) const {
return (idx & FlippedAddressMask);
}
/// Return Z3 expression based on SVFVar ID
inline z3::expr getZ3Expr(u32_t idx) const {
assert(getInternalID(idx) == idx && "SVFVar idx overflow > 0x7f000000?");
assert(varID2ExprMap.size() >= idx + 1 && "idx out of bound for map access, increase map size!");
return varID2ExprMap[getInternalID(idx)];
}
/// Update expression when assignments
inline void updateZ3Expr(u32_t idx, z3::expr target) {
assert(varID2ExprMap.size() >= idx + 1 && "idx out of bound for map access, increase map size!");
varID2ExprMap.set(getInternalID(idx), target);
}
/// Return int value from an expression if it is a numeral, otherwise return an approximate value
s32_t z3Expr2NumValue(z3::expr e);
/// It checks if the constraints added to the Z3 solver are satisfiable.
/// If they are, it retrieves the model that satisfies these constraints
/// and evaluates the given complex expression e within this model, returning the evaluated result
z3::expr getEvalExpr(z3::expr e);
/// Print all expressions' values after evaluation
void printExprValues();
void printZ3Exprs();
inline z3::solver& getSolver() {
return solver;
}
inline z3::context& getCtx() {
return ctx;
}
inline void clearVarID2ExprMap() {
while (!varID2ExprMap.empty())
varID2ExprMap.pop_back();
resetZ3ExprMap();
}
protected:
z3::context ctx;
z3::solver solver;
private:
z3::expr_vector varID2ExprMap;
u32_t lastSlot;
};
} // namespace SVF
#endif // SOFTWARE_SECURITY_ANALYSIS_Z3MGR_H