-
Notifications
You must be signed in to change notification settings - Fork 1
/
smt_convert.hpp
83 lines (72 loc) · 2.55 KB
/
smt_convert.hpp
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
/*
* Copyright (c) 2023 by Hex-Rays, [email protected]
* ALL RIGHTS RESERVED.
*
* gooMBA plugin for Hex-Rays Decompiler.
*
*/
#pragma once
#include "z3++_no_warn.h"
#include "mcode_emu.hpp"
//-------------------------------------------------------------------------
class z3_converter_t
{
char namebuf[12];
int next_free_varnum = 0;
const char *build_new_varname()
{
qsnprintf(namebuf, sizeof(namebuf), "y%d", next_free_varnum++);
return namebuf;
}
public:
z3::context context;
z3::expr_vector input_vars;
// the next integer we can use to generate a z3 variable name
std::map<mop_t, z3::expr> assigned_vars;
z3_converter_t() : input_vars(context) { namebuf[0] = '\0'; }
virtual ~z3_converter_t() {}
// create_new_z3_var is called when var_to_expr fails to find an assigned_var in the cache
virtual z3::expr create_new_z3_var(const mop_t &mop);
z3::expr var_to_expr(const mop_t &mop); // for terminal mops, i.e. stack vars, registers, global vars
z3::expr mop_to_expr(const mop_t &mop);
z3::expr minsn_to_expr(const minsn_t &insn);
//-------------------------------------------------------------------------
z3::expr bool_to_bv(z3::expr boolean, uint bitsz)
{
return z3::ite(boolean, context.bv_val(1, bitsz), context.bv_val(0, bitsz));
}
//-------------------------------------------------------------------------
z3::expr bv_zext_to_len(z3::expr bv, uint target_bitsz)
{
uint orig_bitsz = bv.get_sort().bv_size();
if ( target_bitsz == orig_bitsz )
return bv; // no need to extend
return z3::zext(bv, target_bitsz - orig_bitsz);
}
//-------------------------------------------------------------------------
z3::expr bv_sext_to_len(z3::expr bv, uint target_bitsz)
{
uint orig_bitsz = bv.get_sort().bv_size();
if ( target_bitsz == orig_bitsz )
return bv; // no need to extend
return z3::sext(bv, target_bitsz - orig_bitsz);
}
//-------------------------------------------------------------------------
z3::expr bv_resize_to_len(z3::expr bv, uint target_bitsz, bool sext)
{
uint orig_bitsz = bv.get_sort().bv_size();
if ( target_bitsz == orig_bitsz )
return bv;
if ( target_bitsz < orig_bitsz )
return bv.extract(target_bitsz - 1, 0);
else
return sext
? bv_sext_to_len(bv, target_bitsz)
: bv_zext_to_len(bv, target_bitsz);
}
//-------------------------------------------------------------------------
z3::expr mcode_val_to_expr(mcode_val_t v)
{
return context.bv_val(uint64_t(v.val), v.size * 8);
}
};