I am trying to translate Z3::expr
into a bit representation of a number in order to find out how many bits 1
the number contains and if the number of bits 1
is even, then I raise the flag.
I wrote the implementation below, but it doesn't work the way I need.
static inline bool calculate_parity(z3::context& z3c, z3::expr** even_bits, z3::expr** dst)
{
z3::expr num = z3c.bv_val(42, 64); // 42 in 64-bit binary representation
for (int i = 31; i >= 0; i--) {
z3::expr bit = num.extract(i, i);
std::cout << bit << " ";
}
std::cout << std::endl;
return true;
}
The implementation of the task can be compared with raising the pf
flag in the x86_64 assembler.
Something like this:
static inline void translate_add(z3::context& z3c, x8664_ctx& old_state, x8664_ctx& new_state, ZydisDisassembledInstruction ins)
{
if (ins.info.operand_count_visible == 2)
{
auto& op1 = ins.operands[0];
auto& op2 = ins.operands[1];
z3::expr e1 = **Z3SystemTranslateFuncs::get_val_expr(z3c, old_state, op1);
z3::expr e2 = **Z3SystemTranslateFuncs::get_val_expr(z3c, old_state, op2);
z3::expr** dst = Z3SystemTranslateFuncs::get_val_expr(z3c, new_state, op1);
*dst = new z3::expr(z3c, e1 + e2);
new_state.zf = new z3::expr(**dst == 0);
new_state.of = new z3::expr(((e1 ^ e2) & 0x7FFFFFFF) == 0 && ((e1 ^ **dst) & 0x7FFFFFFF) != 0);
new_state.cf = new z3::expr((e1 + e2).simplify() < e1.simplify());
***new_state.pf = new z3::expr(z3c.bool_val(Z3SystemTranslateFuncs::calculate_parity(z3c, dst, dst)));***
new_state.sf = new z3::expr(**dst < 0);
z3::expr bit3 = (e1 + e2).extract(3, 3);
z3::expr bit4 = (e1 + e2).extract(4, 4);
new_state.af = new z3::expr((bit3 ^ bit4) != 0);
}
else
throw std::exception("bad operand count in translate_add function");
}