RzIL op definition refinements (#6622)

Many IL ops such as add, sub, mul, ... share the same operand structure,
but previously in the RzILOpPure.op union there was only dedicated
members per exact opcode. So for code where multiple opcodes with
identical structure were handled, one had to either pick one of the
matching RzILOpPure.op members at random or add a large switch that was
technically unnecessary.
For such cases, we now make the structural identity explicit by
introducing shared operand structures such as RzILOpArgsBinopBV, which
can be used for all opcodes that match it.
Dedicated per-opcode typedefs and union members remain for when only a
single opcode is considered.
This commit is contained in:
Florian Märkl 2026-07-16 14:22:47 +02:00 committed by GitHub
parent 4d7ca4161a
commit a57652ccc0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 276 additions and 249 deletions

View file

@ -182,7 +182,7 @@ static void il_opdmp_bool_xor(RzILOpPure *op, PJ *pj) {
} }
static void il_opdmp_bitv(RzILOpPure *op, PJ *pj) { static void il_opdmp_bitv(RzILOpPure *op, PJ *pj) {
RzILOpArgsBv *opx = &op->op.bitv; RzILOpArgsBV *opx = &op->op.bitv;
char *num = rz_bv_as_hex_string(opx->value, false); char *num = rz_bv_as_hex_string(opx->value, false);
pj_o(pj); pj_o(pj);
pj_ks(pj, "opcode", "bitv"); pj_ks(pj, "opcode", "bitv");
@ -357,7 +357,7 @@ static void il_opdmp_fcast_sint(RzILOpPure *op, PJ *pj) {
} }
static void il_opdmp_fcast_float(RzILOpPure *op, PJ *pj) { static void il_opdmp_fcast_float(RzILOpPure *op, PJ *pj) {
RzILOpArgsFCastfloat *opx = &op->op.fcast_float; RzILOpArgsFCastUFloat *opx = &op->op.fcast_float;
pj_o(pj); pj_o(pj);
pj_ks(pj, "opcode", "fcast_float"); pj_ks(pj, "opcode", "fcast_float");
pj_ks(pj, "format", rz_il_float_stringify_format(opx->format)); pj_ks(pj, "format", rz_il_float_stringify_format(opx->format));
@ -368,7 +368,7 @@ static void il_opdmp_fcast_float(RzILOpPure *op, PJ *pj) {
} }
static void il_opdmp_fcast_sfloat(RzILOpPure *op, PJ *pj) { static void il_opdmp_fcast_sfloat(RzILOpPure *op, PJ *pj) {
RzILOpArgsFCastsfloat *opx = &op->op.fcast_sfloat; RzILOpArgsFCastSFloat *opx = &op->op.fcast_sfloat;
pj_o(pj); pj_o(pj);
pj_ks(pj, "opcode", "fcast_sfloat"); pj_ks(pj, "opcode", "fcast_sfloat");
pj_ks(pj, "format", rz_il_float_stringify_format(opx->format)); pj_ks(pj, "format", rz_il_float_stringify_format(opx->format));

View file

@ -231,7 +231,7 @@ static void il_opdmp_bool_xor(RzILOpPure *op, RzStrBuf *sb, int pad) {
} }
static void il_opdmp_bitv(RzILOpPure *op, RzStrBuf *sb, int pad) { static void il_opdmp_bitv(RzILOpPure *op, RzStrBuf *sb, int pad) {
RzILOpArgsBv *opx = &op->op.bitv; RzILOpArgsBV *opx = &op->op.bitv;
char *num = rz_bv_as_hex_string(opx->value, false); char *num = rz_bv_as_hex_string(opx->value, false);
if (pad < 0) { if (pad < 0) {
rz_strbuf_appendf(sb, "(bv %u %s)", opx->value->len, num); rz_strbuf_appendf(sb, "(bv %u %s)", opx->value->len, num);
@ -426,7 +426,7 @@ static void il_opdmp_fcast_sint(RzILOpPure *op, RzStrBuf *sb, int pad) {
} }
static void il_opdmp_fcast_float(RzILOpPure *op, RzStrBuf *sb, int pad) { static void il_opdmp_fcast_float(RzILOpPure *op, RzStrBuf *sb, int pad) {
RzILOpArgsFCastfloat *opx = &op->op.fcast_float; RzILOpArgsFCastUFloat *opx = &op->op.fcast_float;
if (pad < 0) { if (pad < 0) {
rz_strbuf_append(sb, "(fcast_float "); rz_strbuf_append(sb, "(fcast_float ");
rz_strbuf_append(sb, rz_il_float_stringify_format(opx->format)); rz_strbuf_append(sb, rz_il_float_stringify_format(opx->format));
@ -447,7 +447,7 @@ static void il_opdmp_fcast_float(RzILOpPure *op, RzStrBuf *sb, int pad) {
} }
static void il_opdmp_fcast_sfloat(RzILOpPure *op, RzStrBuf *sb, int pad) { static void il_opdmp_fcast_sfloat(RzILOpPure *op, RzStrBuf *sb, int pad) {
RzILOpArgsFCastsfloat *opx = &op->op.fcast_sfloat; RzILOpArgsFCastSFloat *opx = &op->op.fcast_sfloat;
if (pad < 0) { if (pad < 0) {
rz_strbuf_append(sb, "(fcast_sfloat "); rz_strbuf_append(sb, "(fcast_sfloat ");
rz_strbuf_append(sb, rz_il_float_stringify_format(opx->format)); rz_strbuf_append(sb, rz_il_float_stringify_format(opx->format));

View file

@ -242,7 +242,7 @@ static bool il_opdmp_bool_xor(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStr
} }
static bool il_opdmp_bitv_float(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStrBuf *sb, const char *sym) { static bool il_opdmp_bitv_float(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStrBuf *sb, const char *sym) {
const RzILOpArgsBv *opx = &op->op.bitv; const RzILOpArgsBV *opx = &op->op.bitv;
char *num = rz_bv_as_hex_string(opx->value, false); char *num = rz_bv_as_hex_string(opx->value, false);
return_false_if_fail(num); return_false_if_fail(num);
goto_if_fail(rz_strbuf_appendf(sb, "%s", num), fini); goto_if_fail(rz_strbuf_appendf(sb, "%s", num), fini);
@ -256,7 +256,7 @@ fini:
} }
static bool il_opdmp_bitv(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStrBuf *sb) { static bool il_opdmp_bitv(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStrBuf *sb) {
const RzILOpArgsBv *opx = &op->op.bitv; const RzILOpArgsBV *opx = &op->op.bitv;
char *num = rz_bv_as_hex_string(opx->value, false); char *num = rz_bv_as_hex_string(opx->value, false);
return_false_if_fail(num); return_false_if_fail(num);
// The hex value plus the width as a Unicode subscript, via the // The hex value plus the width as a Unicode subscript, via the
@ -427,7 +427,7 @@ static bool il_opdmp_fcast_sint(RzILStringifyCtx *ctx, const RzILOpPure *op, RzS
} }
static bool il_opdmp_fcast_float(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStrBuf *sb) { static bool il_opdmp_fcast_float(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStrBuf *sb) {
const RzILOpArgsFCastfloat *opx = &op->op.fcast_float; const RzILOpArgsFCastUFloat *opx = &op->op.fcast_float;
char *sym = sym_with_float_format(opx->format, UCD_FCAST_FLOAT); char *sym = sym_with_float_format(opx->format, UCD_FCAST_FLOAT);
return_false_if_fail(sym); return_false_if_fail(sym);
bool ok = rz_strbuf_append(sb, "(") && bool ok = rz_strbuf_append(sb, "(") &&
@ -440,7 +440,7 @@ static bool il_opdmp_fcast_float(RzILStringifyCtx *ctx, const RzILOpPure *op, Rz
} }
static bool il_opdmp_fcast_sfloat(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStrBuf *sb) { static bool il_opdmp_fcast_sfloat(RzILStringifyCtx *ctx, const RzILOpPure *op, RzStrBuf *sb) {
const RzILOpArgsFCastsfloat *opx = &op->op.fcast_sfloat; const RzILOpArgsFCastSFloat *opx = &op->op.fcast_sfloat;
char *sym = sym_with_float_format(opx->format, UCD_FCAST_SFLOAT); char *sym = sym_with_float_format(opx->format, UCD_FCAST_SFLOAT);
return_false_if_fail(sym); return_false_if_fail(sym);
bool ok = rz_strbuf_append(sb, "(") && bool ok = rz_strbuf_append(sb, "(") &&

View file

@ -137,7 +137,7 @@ static void il_op_graph_bool_xor(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *, N
} }
static void il_op_graph_bitv(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *, NULL *>*/ *g, RzGraphNode *from) { static void il_op_graph_bitv(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *, NULL *>*/ *g, RzGraphNode *from) {
RzILOpArgsBv *opx = &op->op.bitv; RzILOpArgsBV *opx = &op->op.bitv;
char *num = rz_bv_as_hex_string(opx->value, false); char *num = rz_bv_as_hex_string(opx->value, false);
il_op_graph_add_edge_f(g, from, "bv: %u %s", opx->value->len, num); il_op_graph_add_edge_f(g, from, "bv: %u %s", opx->value->len, num);
free(num); free(num);
@ -303,7 +303,7 @@ static void il_op_graph_fcast_sint(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *,
} }
static void il_op_graph_fcast_float(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *, NULL *>*/ *g, RzGraphNode *from) { static void il_op_graph_fcast_float(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *, NULL *>*/ *g, RzGraphNode *from) {
RzILOpArgsFCastfloat *opx = &op->op.fcast_float; RzILOpArgsFCastUFloat *opx = &op->op.fcast_float;
const char *format_str = rz_il_float_stringify_format(opx->format); const char *format_str = rz_il_float_stringify_format(opx->format);
const char *rmode_str = rz_il_float_stringify_rmode(opx->mode); const char *rmode_str = rz_il_float_stringify_rmode(opx->mode);
char *value = rz_str_newf("fcast_float: %s %s", format_str, rmode_str); char *value = rz_str_newf("fcast_float: %s %s", format_str, rmode_str);
@ -314,7 +314,7 @@ static void il_op_graph_fcast_float(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *
} }
static void il_op_graph_fcast_sfloat(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *, NULL *>*/ *g, RzGraphNode *from) { static void il_op_graph_fcast_sfloat(RzILOpPure *op, RzGraph /*<RzGraphNodeInfo *, NULL *>*/ *g, RzGraphNode *from) {
RzILOpArgsFCastsfloat *opx = &op->op.fcast_sfloat; RzILOpArgsFCastSFloat *opx = &op->op.fcast_sfloat;
const char *format_str = rz_il_float_stringify_format(opx->format); const char *format_str = rz_il_float_stringify_format(opx->format);
const char *rmode_str = rz_il_float_stringify_rmode(opx->mode); const char *rmode_str = rz_il_float_stringify_rmode(opx->mode);
char *value = rz_str_newf("fcast_sfloat: %s %s", format_str, rmode_str); char *value = rz_str_newf("fcast_sfloat: %s %s", format_str, rmode_str);

View file

@ -336,8 +336,8 @@ VALIDATOR_PURE(bitv) {
* e.g. add, sub, mul, div, ... * e.g. add, sub, mul, div, ...
*/ */
VALIDATOR_PURE(bitv_binop) { VALIDATOR_PURE(bitv_binop) {
RzILOpPure *x = op->op.add.x; // just add is fine, all ops in here use the same struct RzILOpPure *x = op->op.binop_bv.x;
RzILOpPure *y = op->op.add.y; RzILOpPure *y = op->op.binop_bv.y;
RzILSortPure sx; RzILSortPure sx;
VALIDATOR_DESCEND(x, &sx); VALIDATOR_DESCEND(x, &sx);
VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BITVECTOR, "Left operand of %s op is not a bitvector.\n", rz_il_op_pure_code_stringify(op->code)); VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BITVECTOR, "Left operand of %s op is not a bitvector.\n", rz_il_op_pure_code_stringify(op->code));
@ -396,8 +396,8 @@ VALIDATOR_PURE(inv) {
* e.g. and, or, ... * e.g. and, or, ...
*/ */
VALIDATOR_PURE(bool_binop) { VALIDATOR_PURE(bool_binop) {
RzILOpPure *x = op->op.booland.x; // just booland is fine, all ops in here use the same struct RzILOpPure *x = op->op.binop_bool.x;
RzILOpPure *y = op->op.booland.y; RzILOpPure *y = op->op.binop_bool.y;
RzILSortPure sx; RzILSortPure sx;
VALIDATOR_DESCEND(x, &sx); VALIDATOR_DESCEND(x, &sx);
VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BOOL, "Left operand of %s op is not bool.\n", rz_il_op_pure_code_stringify(op->code)); VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BOOL, "Left operand of %s op is not bool.\n", rz_il_op_pure_code_stringify(op->code));
@ -413,7 +413,7 @@ VALIDATOR_PURE(bool_binop) {
* e.g. msb, lsb * e.g. msb, lsb
*/ */
VALIDATOR_PURE(bitv_bool_unop) { VALIDATOR_PURE(bitv_bool_unop) {
RzILOpPure *x = op->op.msb.bv; // just msb is fine, all ops in here use the same struct RzILOpPure *x = op->op.unop_bv.bv;
RzILSortPure sx; RzILSortPure sx;
VALIDATOR_DESCEND(x, &sx); VALIDATOR_DESCEND(x, &sx);
VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BITVECTOR, "Operand of %s op is not a bitvector.\n", rz_il_op_pure_code_stringify(op->code)); VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BITVECTOR, "Operand of %s op is not a bitvector.\n", rz_il_op_pure_code_stringify(op->code));
@ -426,7 +426,7 @@ VALIDATOR_PURE(bitv_bool_unop) {
* e.g. bitwise negation * e.g. bitwise negation
*/ */
VALIDATOR_PURE(bitv_unop) { VALIDATOR_PURE(bitv_unop) {
RzILOpPure *x = op->op.lognot.bv; // just lognot is fine, all ops in here use the same struct RzILOpPure *x = op->op.unop_bv.bv;
RzILSortPure sx; RzILSortPure sx;
VALIDATOR_DESCEND(x, &sx); VALIDATOR_DESCEND(x, &sx);
VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BITVECTOR, "Operand of %s op is not a bitvector.\n", rz_il_op_pure_code_stringify(op->code)); VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BITVECTOR, "Operand of %s op is not a bitvector.\n", rz_il_op_pure_code_stringify(op->code));
@ -435,7 +435,7 @@ VALIDATOR_PURE(bitv_unop) {
} }
VALIDATOR_PURE(shift) { VALIDATOR_PURE(shift) {
RzILOpArgsShiftLeft *args = &op->op.shiftl; RzILOpArgsShiftLeft *args = &op->op.shift;
RzILSortPure sf; RzILSortPure sf;
VALIDATOR_DESCEND(args->fill_bit, &sf); VALIDATOR_DESCEND(args->fill_bit, &sf);
VALIDATOR_ASSERT(sf.type == RZ_IL_TYPE_PURE_BOOL, "Fill operand of %s op is not bool.\n", rz_il_op_pure_code_stringify(op->code)); VALIDATOR_ASSERT(sf.type == RZ_IL_TYPE_PURE_BOOL, "Fill operand of %s op is not bool.\n", rz_il_op_pure_code_stringify(op->code));
@ -450,7 +450,7 @@ VALIDATOR_PURE(shift) {
} }
VALIDATOR_PURE(cmp) { VALIDATOR_PURE(cmp) {
RzILOpArgsEq *args = &op->op.eq; RzILOpArgsEq *args = &op->op.binop_bv;
RzILSortPure sx; RzILSortPure sx;
VALIDATOR_DESCEND(args->x, &sx); VALIDATOR_DESCEND(args->x, &sx);
VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BITVECTOR, "Left operand of %s op is not a bitvector.\n", rz_il_op_pure_code_stringify(op->code)); VALIDATOR_ASSERT(sx.type == RZ_IL_TYPE_PURE_BITVECTOR, "Left operand of %s op is not a bitvector.\n", rz_il_op_pure_code_stringify(op->code));
@ -574,7 +574,7 @@ VALIDATOR_PURE(fcast_to_int) {
} }
VALIDATOR_PURE(icast_to_float) { VALIDATOR_PURE(icast_to_float) {
RzILOpArgsFCastfloat *args = &op->op.fcast_float; RzILOpArgsFCastUFloat *args = &op->op.fcast_float;
RzILSortPure sort; RzILSortPure sort;
VALIDATOR_DESCEND(args->bv, &sort); VALIDATOR_DESCEND(args->bv, &sort);

View file

@ -145,10 +145,10 @@ void *rz_il_handler_append(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type)
void *rz_il_handler_logical_and(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) { void *rz_il_handler_logical_and(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL); rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsAdd *op_add = &op->op.add; RzILOpArgsLogAnd *op_and = &op->op.logand;
RzBitVector *x = rz_il_evaluate_bitv(vm, op_add->x); RzBitVector *x = rz_il_evaluate_bitv(vm, op_and->x);
RzBitVector *y = rz_il_evaluate_bitv(vm, op_add->y); RzBitVector *y = rz_il_evaluate_bitv(vm, op_and->y);
RzBitVector *result = x && y ? rz_bv_and(x, y) : NULL; RzBitVector *result = x && y ? rz_bv_and(x, y) : NULL;
rz_bv_free(x); rz_bv_free(x);
rz_bv_free(y); rz_bv_free(y);
@ -160,10 +160,10 @@ void *rz_il_handler_logical_and(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *t
void *rz_il_handler_logical_or(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) { void *rz_il_handler_logical_or(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL); rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsAdd *op_add = &op->op.add; RzILOpArgsAdd *op_or = &op->op.logor;
RzBitVector *x = rz_il_evaluate_bitv(vm, op_add->x); RzBitVector *x = rz_il_evaluate_bitv(vm, op_or->x);
RzBitVector *y = rz_il_evaluate_bitv(vm, op_add->y); RzBitVector *y = rz_il_evaluate_bitv(vm, op_or->y);
RzBitVector *result = x && y ? rz_bv_or(x, y) : NULL; RzBitVector *result = x && y ? rz_bv_or(x, y) : NULL;
rz_bv_free(x); rz_bv_free(x);
rz_bv_free(y); rz_bv_free(y);
@ -175,10 +175,10 @@ void *rz_il_handler_logical_or(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *ty
void *rz_il_handler_logical_xor(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) { void *rz_il_handler_logical_xor(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL); rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsAdd *op_add = &op->op.add; RzILOpArgsAdd *op_xor = &op->op.logxor;
RzBitVector *x = rz_il_evaluate_bitv(vm, op_add->x); RzBitVector *x = rz_il_evaluate_bitv(vm, op_xor->x);
RzBitVector *y = rz_il_evaluate_bitv(vm, op_add->y); RzBitVector *y = rz_il_evaluate_bitv(vm, op_xor->y);
RzBitVector *result = x && y ? rz_bv_xor(x, y) : NULL; RzBitVector *result = x && y ? rz_bv_xor(x, y) : NULL;
rz_bv_free(x); rz_bv_free(x);
rz_bv_free(y); rz_bv_free(y);
@ -335,7 +335,7 @@ void *rz_il_handler_shiftr(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type)
void *rz_il_handler_bitv(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) { void *rz_il_handler_bitv(RzILVM *vm, RzILOpBitVector *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL); rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsBv *op_bitv = &op->op.bitv; RzILOpArgsBV *op_bitv = &op->op.bitv;
RzBitVector *bv = rz_bv_dup(op_bitv->value); RzBitVector *bv = rz_bv_dup(op_bitv->value);

View file

@ -200,7 +200,7 @@ void *rz_il_handler_fcast_sint(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
void *rz_il_handler_fcast_float(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) { void *rz_il_handler_fcast_float(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL); rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFCastfloat cast = op->op.fcast_float; RzILOpArgsFCastUFloat cast = op->op.fcast_float;
RzBitVector *bv = rz_il_evaluate_bitv(vm, cast.bv); RzBitVector *bv = rz_il_evaluate_bitv(vm, cast.bv);
RzFloatFormat format = cast.format; RzFloatFormat format = cast.format;
RzFloatRMode mode = cast.mode; RzFloatRMode mode = cast.mode;
@ -215,7 +215,7 @@ void *rz_il_handler_fcast_float(RzILVM *vm, RzILOpPure *op, RzILTypePure *type)
void *rz_il_handler_fcast_sfloat(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) { void *rz_il_handler_fcast_sfloat(RzILVM *vm, RzILOpPure *op, RzILTypePure *type) {
rz_return_val_if_fail(vm && op && type, NULL); rz_return_val_if_fail(vm && op && type, NULL);
RzILOpArgsFCastsfloat cast = op->op.fcast_sfloat; RzILOpArgsFCastSFloat cast = op->op.fcast_sfloat;
RzBitVector *bv = rz_il_evaluate_bitv(vm, cast.bv); RzBitVector *bv = rz_il_evaluate_bitv(vm, cast.bv);
RzFloatFormat format = cast.format; RzFloatFormat format = cast.format;
RzFloatRMode mode = cast.mode; RzFloatRMode mode = cast.mode;

View file

@ -30,10 +30,18 @@ extern "C" {
* o o o o o * o o o o o
* Init RzILBool Bitv Memory Effect * Init RzILBool Bitv Memory Effect
* *
* See also the references : * See also the references:
* 0. A gentle introduction to core theory http://binaryanalysisplatform.github.io/bap/api/odoc/bap-core-theory/Bap_core_theory/index.html * 0. A gentle introduction to core theory http://binaryanalysisplatform.github.io/bap/api/odoc/bap-core-theory/Bap_core_theory/index.html
* 1. http://binaryanalysisplatform.github.io/bap/api/odoc/bap-core-theory/Bap_core_theory/Theory/index.html * 1. http://binaryanalysisplatform.github.io/bap/api/odoc/bap-core-theory/Bap_core_theory/Theory/index.html
* 2. For core and array theories https://smtlib.cs.uiowa.edu/theories.shtml * 2. For core and array theories https://smtlib.cs.uiowa.edu/theories.shtml
*
* Note about the intended usage of the operand structs:
* Many operations share the same operand structure, e.g. (add x y) and (sub x y).
* The C struct for the operands of both ops will thus be RzILOpArgsBinopBV, but there are also per-op typedefs
* like `RzILOpArgsAdd` and `RzILOpArgsSub`.
* The op-specific ones can be used when the opcode is known to be exactly that to avoid type confusion mistakes,
* but when reasoning about operands of possibly different opcodes but with the same structure, the generic ones
* can be used.
*/ */
typedef struct rz_il_op_pure_t RzILOpPure; typedef struct rz_il_op_pure_t RzILOpPure;
@ -51,35 +59,25 @@ typedef struct rz_il_op_effect_t RzILOpEffect;
*/ */
typedef struct rz_il_op_args_bv_t { typedef struct rz_il_op_args_bv_t {
RzBitVector *value; ///< value of bitvector RzBitVector *value; ///< value of bitvector
} RzILOpArgsBv; } RzILOpArgsBV;
/**
* \brief op structure for `'s bitv -> bool`
* [MSB] msb x is the most significant bit of x.
* [LSB] lsb x is the least significant bit of x.
* [IS_ZERO] is_zero x holds if x is a bitvector of all zeros.
*/
struct rz_il_op_args_un_bv_b_t {
RzILOpBitVector *bv;
};
typedef struct rz_il_op_args_un_bv_b_t RzILOpArgsMsb;
typedef struct rz_il_op_args_un_bv_b_t RzILOpArgsLsb;
typedef struct rz_il_op_args_un_bv_b_t RzILOpArgsIsZero;
/** /**
* op structure for * op structure for
* `not` ('s bitv -> 's bitv) * [MSB] msb x is the most significant bit of x.
* not x is one-complement negation. * [LSB] lsb x is the least significant bit of x.
* `neg` ('s bitv -> 's bitv) * [IS_ZERO] is_zero x holds if x is a bitvector of all zeros.
* neg x is two-complement unary minus * [LOGNOT] not x is one-complement negation.
* [NEG] neg x is two-complement unary minus
*/ */
struct rz_il_op_args_bv_unop_t { typedef struct rz_il_op_args_bv_unop_t {
RzILOpBitVector *bv; ///< unary operand RzILOpBitVector *bv; ///< unary operand
}; } RzILOpArgsUnopBV;
typedef struct rz_il_op_args_bv_unop_t RzILOpArgsLogNot; typedef RzILOpArgsUnopBV RzILOpArgsMsb;
typedef struct rz_il_op_args_bv_unop_t RzILOpArgsNeg; typedef RzILOpArgsUnopBV RzILOpArgsLsb;
typedef RzILOpArgsUnopBV RzILOpArgsIsZero;
typedef RzILOpArgsUnopBV RzILOpArgsLogNot;
typedef RzILOpArgsUnopBV RzILOpArgsNeg;
/** /**
* \brief op structure for two-operand algorithm and logical operations ('s bitv -> 's bitv -> 's bitv) * \brief op structure for two-operand algorithm and logical operations ('s bitv -> 's bitv -> 's bitv)
@ -94,45 +92,35 @@ typedef struct rz_il_op_args_bv_unop_t RzILOpArgsNeg;
* [LOGAND] logand x y is a bitwise logical and of x and y. * [LOGAND] logand x y is a bitwise logical and of x and y.
* [LOGOR] logor x y is a bitwise logical or of x and y. * [LOGOR] logor x y is a bitwise logical or of x and y.
* [LOGXOR] logxor x y is a bitwise logical xor of x and y. * [LOGXOR] logxor x y is a bitwise logical xor of x and y.
*/
struct rz_il_op_args_alg_log_operations_t {
RzILOpBitVector *x; ///< left operand
RzILOpBitVector *y; ///< right operand
};
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsAdd;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsSub;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsMul;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsDiv;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsSdiv;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsMod;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsSmod;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsLogand;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsLogor;
typedef struct rz_il_op_args_alg_log_operations_t RzILOpArgsLogxor;
/**
* \brief op structure for binary comparison ops ('a bitv -> 'a bitv -> bool)
*
* [EQ] eq x y binary predicate for bitwise equality * [EQ] eq x y binary predicate for bitwise equality
* [SLE] sle x y binary predicate for singed less than or equal * [SLE] sle x y binary predicate for signed less than or equal
* [ULE] ule x y binary predicate for unsigned less than or equal * [ULE] ule x y binary predicate for unsigned less than or equal
*/ */
struct rz_il_op_args_cmp_t { typedef struct rz_il_op_args_binop_bv_t {
RzILOpBitVector *x; ///< index of operand 1 RzILOpBitVector *x; ///< left operand
RzILOpBitVector *y; ///< index of operand 2 RzILOpBitVector *y; ///< right operand
}; } RzILOpArgsBinopBV;
typedef struct rz_il_op_args_cmp_t RzILOpArgsEq; typedef RzILOpArgsBinopBV RzILOpArgsAdd;
typedef struct rz_il_op_args_cmp_t RzILOpArgsSle; typedef RzILOpArgsBinopBV RzILOpArgsSub;
typedef struct rz_il_op_args_cmp_t RzILOpArgsUle; typedef RzILOpArgsBinopBV RzILOpArgsMul;
typedef RzILOpArgsBinopBV RzILOpArgsDiv;
typedef RzILOpArgsBinopBV RzILOpArgsSdiv;
typedef RzILOpArgsBinopBV RzILOpArgsMod;
typedef RzILOpArgsBinopBV RzILOpArgsSmod;
typedef RzILOpArgsBinopBV RzILOpArgsLogAnd;
typedef RzILOpArgsBinopBV RzILOpArgsLogOr;
typedef RzILOpArgsBinopBV RzILOpArgsLogXor;
typedef RzILOpArgsBinopBV RzILOpArgsEq;
typedef RzILOpArgsBinopBV RzILOpArgsSle;
typedef RzILOpArgsBinopBV RzILOpArgsUle;
/** /**
* \brief op structure for casting bitv * \brief op structure for casting bitv
*/ */
typedef struct rz_il_op_args_cast_t { typedef struct rz_il_op_args_cast_t {
ut32 length; ///< new bits length ut32 length; ///< new bits length
RzILOpBool *fill; ///< If m = size val - length > 0 then m fill-bits are prepended to the most significant part of the vector. RzILOpBool *fill; ///< If m = length - size val > 0 then m fill-bits are prepended to the most significant part of the vector.
RzILOpBitVector *val; ///< value to cast RzILOpBitVector *val; ///< value to cast
} RzILOpArgsCast; } RzILOpArgsCast;
@ -151,14 +139,14 @@ typedef struct rz_il_op_args_append_t {
* [LSHIFT] shiftl s x m shifts x left by m bits filling with s. * [LSHIFT] shiftl s x m shifts x left by m bits filling with s.
* [RSHIFT] shiftr s x m shifts x right by m bits filling with s. * [RSHIFT] shiftr s x m shifts x right by m bits filling with s.
*/ */
struct rz_il_op_args_shift_t { typedef struct rz_il_op_args_shift_t {
RzILOpBool *fill_bit; ///< index of fill bit RzILOpBool *fill_bit; ///< index of fill bit
RzILOpBitVector *x; ///< index of operand 1 RzILOpBitVector *x; ///< index of operand 1
RzILOpBitVector *y; ///< index of operand 2 RzILOpBitVector *y; ///< index of operand 2
}; } RzILOpArgsShift;
typedef struct rz_il_op_args_shift_t RzILOpArgsShiftLeft; typedef RzILOpArgsShift RzILOpArgsShiftLeft;
typedef struct rz_il_op_args_shift_t RzILOpArgsShiftRight; typedef RzILOpArgsShift RzILOpArgsShiftRight;
/** /**
* \brief op structure for `set` ('a var -> 'a pure -> data eff) * \brief op structure for `set` ('a var -> 'a pure -> data eff)
@ -217,7 +205,7 @@ typedef struct rz_il_op_args_seq_t {
* *
* blk lbl data ctrl a labeled sequence of effects. * blk lbl data ctrl a labeled sequence of effects.
*/ */
typedef struct rzil_op_blk_t { typedef struct rz_il_op_blk_t {
const char *label; ///< name of the label, const one const char *label; ///< name of the label, const one
RzILOpEffect *data_eff; ///< index of data_eff RzILOpEffect *data_eff; ///< index of data_eff
RzILOpEffect *ctrl_eff; ///< index of ctrl_eff RzILOpEffect *ctrl_eff; ///< index of ctrl_eff
@ -228,7 +216,7 @@ typedef struct rzil_op_blk_t {
* *
* repeat c data repeats data effects till the condition c holds. * repeat c data repeats data effects till the condition c holds.
*/ */
typedef struct rzil_op_repeat_t { typedef struct rz_il_op_repeat_t {
RzILOpBool *condition; ///< index of BOOL condition RzILOpBool *condition; ///< index of BOOL condition
RzILOpEffect *data_eff; ///< index of data effect RzILOpEffect *data_eff; ///< index of data effect
} RzILOpArgsRepeat; } RzILOpArgsRepeat;
@ -266,25 +254,6 @@ typedef struct rz_il_op_args_var_t {
RzILVarKind kind; ///< set of variables to pick from RzILVarKind kind; ///< set of variables to pick from
} RzILOpArgsVar; } RzILOpArgsVar;
/**
* \brief op structure for `and`, `or` and `xor` (bool -> bool -> bool)
*
* BAP equivalent:
* val and_ : bool -> bool -> bool
* val or_ : bool -> bool -> bool
* and(x, y) is a conjunction of x and y.
* or(x, y) is a conjunction of x or y.
* xor(x, y) is a conjunction of x xor y.
*/
struct rz_il_op_args_bool_operation_t {
RzILOpBool *x; ///< left operand
RzILOpBool *y; ///< right operand
};
typedef struct rz_il_op_args_bool_operation_t RzILOpArgsBoolAnd;
typedef struct rz_il_op_args_bool_operation_t RzILOpArgsBoolOr;
typedef struct rz_il_op_args_bool_operation_t RzILOpArgsBoolXor;
/** /**
* \brief op structure for `inv` (!bool -> bool) * \brief op structure for `inv` (!bool -> bool)
* *
@ -292,11 +261,28 @@ typedef struct rz_il_op_args_bool_operation_t RzILOpArgsBoolXor;
* val inv : bool -> bool * val inv : bool -> bool
* inv(x) inverts x (also known as not operation). * inv(x) inverts x (also known as not operation).
*/ */
struct rz_il_op_args_bool_inv_t { typedef struct rz_il_op_args_bool_inv_t {
RzILOpBool *x; ///< single operand RzILOpBool *x; ///< single operand
}; } RzILOpArgsBoolInv;
typedef struct rz_il_op_args_bool_inv_t RzILOpArgsBoolInv; /**
* \brief op structure for `and`, `or` and `xor` (bool -> bool -> bool)
*
* BAP equivalent:
* val and_ : bool -> bool -> bool
* val or_ : bool -> bool -> bool
* [AND] and x y is a conjunction of x and y.
* [OR] or x y is an inclusive disjunction of x and y.
* [XOR] xor x y is an exclusive disjunction of x and y.
*/
typedef struct rz_il_op_args_binop_bool_t {
RzILOpBool *x; ///< left operand
RzILOpBool *y; ///< right operand
} RzILOpArgsBinopBool;
typedef RzILOpArgsBinopBool RzILOpArgsBoolAnd;
typedef RzILOpArgsBinopBool RzILOpArgsBoolOr;
typedef RzILOpArgsBinopBool RzILOpArgsBoolXor;
/** /**
* \brief op structure for `load` (('a, 'b) mem -> 'a bitv -> 'b bitv) * \brief op structure for `load` (('a, 'b) mem -> 'a bitv -> 'b bitv)
@ -352,88 +338,76 @@ typedef struct rz_il_op_args_float_t {
} RzILOpArgsFloat; } RzILOpArgsFloat;
/** /**
* \brief op structure for unary without rmode * \brief op structure for 'f float -> 'a
*/ * [FBITS] fbits x is a bitvector representation of the floating-point number x.
struct rz_il_op_args_float_unary_t {
RzILOpFloat *f;
};
/**
* \brief opstructure for fbits : ( 'r, 's ) format float -> 's bitv
* fbits x is a bitvector representation of the floating-point number x.
*/
typedef struct rz_il_op_args_float_unary_t RzILOpArgsFbits;
/**
* \brief op structure for 'f float -> bool
* [IS_FINITE] is_finite x holds if x represents a finite number. * [IS_FINITE] is_finite x holds if x represents a finite number.
* [IS_NAN] is_nan x holds if x represents a not-a-number (NaN). * [IS_NAN] is_nan x holds if x represents a not-a-number (NaN).
* [IS_INF] is_inf x holds if x represents an infinite number. * [IS_INF] is_inf x holds if x represents an infinite number.
* [IS_FZERO] is_fzero x holds if x represents a zero. * [IS_FZERO] is_fzero x holds if x represents a zero.
* [IS_FNEG] is_fpos x holds if x represents a positive number. * [IS_FPOS] is_fpos x holds if x represents a positive number.
* [IS_FPOS] is_fneg x hold if x represents a negative number. * [IS_FNEG] is_fneg x holds if x represents a negative number.
*/
typedef struct rz_il_op_args_float_unary_t RzILOpArgsIsFinite;
typedef struct rz_il_op_args_float_unary_t RzILOpArgsIsNan;
typedef struct rz_il_op_args_float_unary_t RzILOpArgsIsInf;
typedef struct rz_il_op_args_float_unary_t RzILOpArgsIsFzero;
typedef struct rz_il_op_args_float_unary_t RzILOpArgsIsFpos;
typedef struct rz_il_op_args_float_unary_t RzILOpArgsIsFneg;
/**
* op structure for 'f float -> float
* [FNEG] fneg x is -x * [FNEG] fneg x is -x
* [FABS] fabs x is absolute value of x (|x|) * [FABS] fabs x is absolute value of x (|x|)
* [FSUCC] fsucc x is the least floating-point number representable in (sort x) that is greater than x. * [FSUCC] fsucc x is the least floating-point number representable in (sort x) that is greater than x.
* [FPRED] fpred x is the greatest floating-point number representable in (sort x) that is less than x. * [FPRED] fpred x is the greatest floating-point number representable in (sort x) that is less than x.
*/ */
typedef struct rz_il_op_args_float_unary_t RzILOpArgsFneg; typedef struct rz_il_op_args_unop_float_t {
typedef struct rz_il_op_args_float_unary_t RzILOpArgsFabs; RzILOpFloat *f;
typedef struct rz_il_op_args_float_unary_t RzILOpArgsFsucc; } RzILOpArgsUnopFloat;
typedef struct rz_il_op_args_float_unary_t RzILOpArgsFpred;
typedef RzILOpArgsUnopFloat RzILOpArgsFbits;
typedef RzILOpArgsUnopFloat RzILOpArgsIsFinite;
typedef RzILOpArgsUnopFloat RzILOpArgsIsNan;
typedef RzILOpArgsUnopFloat RzILOpArgsIsInf;
typedef RzILOpArgsUnopFloat RzILOpArgsIsFzero;
typedef RzILOpArgsUnopFloat RzILOpArgsIsFpos;
typedef RzILOpArgsUnopFloat RzILOpArgsIsFneg;
typedef RzILOpArgsUnopFloat RzILOpArgsFneg;
typedef RzILOpArgsUnopFloat RzILOpArgsFabs;
typedef RzILOpArgsUnopFloat RzILOpArgsFsucc;
typedef RzILOpArgsUnopFloat RzILOpArgsFpred;
/** /**
* \brief op structure for cast to bv from float * \brief op structure for cast to bv from float
* [FCAST_INT] `f_cast_int s rm x` returns an integer closest to x. * [FCAST_INT] `f_cast_int s rm x` returns an integer closest to x.
* [FCAST_SINT] `f_cast_sint s rm x` returns an integer closest to x. * [FCAST_SINT] `f_cast_sint s rm x` returns an integer closest to x.
*/ */
struct rz_il_op_args_float_cast_int_t { typedef struct rz_il_op_args_float_cast_int_t {
ut32 length; ut32 length;
RzFloatRMode mode; RzFloatRMode mode;
RzILOpFloat *f; RzILOpFloat *f;
}; } RzILOpArgsFCastInt;
typedef struct rz_il_op_args_float_cast_int_t RzILOpArgsFCastint; typedef RzILOpArgsFCastInt RzILOpArgsFCastint;
typedef struct rz_il_op_args_float_cast_int_t RzILOpArgsFCastsint; typedef RzILOpArgsFCastInt RzILOpArgsFCastsint;
/** /**
* \brief for cast to float from bv * \brief for cast to float from bv
* 'f Float.t Value.sort -> rmode -> 'a bitv -> 'f float * 'f Float.t Value.sort -> rmode -> 'a bitv -> 'f float
* [FCAST_FLOAT] `cast_float s rm x` is the closest to x floating-point number of sort x. * [FCAST_FLOAT] `cast_float s rm x` is the closest to x floating-point number of sort s.
* note that : The bitvector x is interpreted as an unsigned integer in the two-complement form. * note that : The bitvector x is interpreted as an unsigned integer in the two-complement form.
* [FCAST_SFLOAT] `cast_sfloat s rm x` is the closest to x floating-point number of sort x. * [FCAST_SFLOAT] `cast_sfloat s rm x` is the closest to x floating-point number of sort s.
* note that : The bitvector x is interpreted as a signed integer in the two-complement form. * note that : The bitvector x is interpreted as a signed integer in the two-complement form.
*/ */
struct rz_il_op_args_float_cast_float_t { typedef struct rz_il_op_args_float_cast_float_t {
RzFloatFormat format; RzFloatFormat format;
RzFloatRMode mode; RzFloatRMode mode;
RzILOpBitVector *bv; RzILOpBitVector *bv;
}; } RzILOpArgsFCastFloat;
typedef struct rz_il_op_args_float_cast_float_t RzILOpArgsFCastfloat; typedef struct rz_il_op_args_float_cast_float_t RzILOpArgsFCastUFloat;
typedef struct rz_il_op_args_float_cast_float_t RzILOpArgsFCastsfloat; typedef struct rz_il_op_args_float_cast_float_t RzILOpArgsFCastSFloat;
/** /**
* \brief convert between different float format * \brief convert between different float format
* 'f Float.t Value.sort -> rmode -> _ float -> 'f float * 'f Float.t Value.sort -> rmode -> _ float -> 'f float
* [FCONVERT] `fconvert f r x` is the closest to x floating number in format f. * [FCONVERT] `fconvert f r x` is the closest to x floating number in format f.
*/ */
struct rz_il_op_args_float_fconvert_t { typedef struct rz_il_op_args_float_fconvert_t {
RzFloatFormat format; RzFloatFormat format;
RzFloatRMode mode; RzFloatRMode mode;
RzILOpFloat *f; RzILOpFloat *f;
}; } RzILOpArgsFconvert;
typedef struct rz_il_op_args_float_fconvert_t RzILOpArgsFconvert;
/** /**
* \brief op structure of requal * \brief op structure of requal
@ -447,7 +421,7 @@ typedef struct rz_il_op_args_float_requal_t {
/** /**
* \brief op structure of binary op without rmode * \brief op structure of binary op without rmode
* ('float -> 'flaat -> bool) * ('f float -> 'f float -> bool)
* forder x y holds if floating-point number x is less than y. * forder x y holds if floating-point number x is less than y.
*/ */
typedef struct rz_il_op_args_float_binop_t { typedef struct rz_il_op_args_float_binop_t {
@ -462,13 +436,14 @@ typedef struct rz_il_op_args_float_binop_t {
* [FSQRT] fsqrt m x returns the closest floating-point number to r, where r is such number that r*r is equal to x. * [FSQRT] fsqrt m x returns the closest floating-point number to r, where r is such number that r*r is equal to x.
* [FRSQRT] reverse sqrt, rsqrt m x is the closest floating-point number to 1 / sqrt x. * [FRSQRT] reverse sqrt, rsqrt m x is the closest floating-point number to 1 / sqrt x.
*/ */
struct rz_il_op_args_float_alg_unop_t { typedef struct rz_il_op_args_float_alg_unop_t {
RzFloatRMode rmode; RzFloatRMode rmode;
RzILOpFloat *f; RzILOpFloat *f;
}; } RzILOpArgsFloatAlgUnop;
typedef struct rz_il_op_args_float_alg_unop_t RzILOpArgsFround;
typedef struct rz_il_op_args_float_alg_unop_t RzILOpArgsFsqrt; typedef RzILOpArgsFloatAlgUnop RzILOpArgsFround;
typedef struct rz_il_op_args_float_alg_unop_t RzILOpArgsFrsqrt; typedef RzILOpArgsFloatAlgUnop RzILOpArgsFsqrt;
typedef RzILOpArgsFloatAlgUnop RzILOpArgsFrsqrt;
typedef struct rz_il_op_args_float_expect_t { typedef struct rz_il_op_args_float_expect_t {
RzFloatException e; RzFloatException e;
@ -480,45 +455,45 @@ typedef struct rz_il_op_args_float_expect_t {
* rmode -> 'f float -> 'f float -> 'f float * rmode -> 'f float -> 'f float -> 'f float
* [FADD] * [FADD]
*/ */
struct rz_il_op_args_float_alg_binop_t { typedef struct rz_il_op_args_float_alg_binop_t {
RzFloatRMode rmode; RzFloatRMode rmode;
RzILOpFloat *x; RzILOpFloat *x;
RzILOpFloat *y; RzILOpFloat *y;
}; } RzILOpArgsFloatAlgBinop;
typedef struct rz_il_op_args_float_alg_binop_t RzILOpArgsFadd; typedef RzILOpArgsFloatAlgBinop RzILOpArgsFadd;
typedef struct rz_il_op_args_float_alg_binop_t RzILOpArgsFsub; typedef RzILOpArgsFloatAlgBinop RzILOpArgsFsub;
typedef struct rz_il_op_args_float_alg_binop_t RzILOpArgsFmul; typedef RzILOpArgsFloatAlgBinop RzILOpArgsFmul;
typedef struct rz_il_op_args_float_alg_binop_t RzILOpArgsFdiv; typedef RzILOpArgsFloatAlgBinop RzILOpArgsFdiv;
typedef struct rz_il_op_args_float_alg_binop_t RzILOpArgsFmod; typedef RzILOpArgsFloatAlgBinop RzILOpArgsFmod;
typedef struct rz_il_op_args_float_alg_binop_t RzILOpArgsFhypot; typedef RzILOpArgsFloatAlgBinop RzILOpArgsFhypot;
typedef struct rz_il_op_args_float_alg_binop_t RzILOpArgsFpow; typedef RzILOpArgsFloatAlgBinop RzILOpArgsFpow;
/** /**
* \brief op structure of ternary op in float * \brief op structure of ternary op in float
* rmode -> 'f float -> 'f float -> 'f float -> 'f float * rmode -> 'f float -> 'f float -> 'f float -> 'f float
*/ */
struct rz_il_op_args_float_alg_terop_t { typedef struct rz_il_op_args_float_alg_terop_t {
RzFloatRMode rmode; RzFloatRMode rmode;
RzILOpFloat *x; RzILOpFloat *x;
RzILOpFloat *y; RzILOpFloat *y;
RzILOpFloat *z; RzILOpFloat *z;
}; } RzILOpArgsFloatAlgTernop;
typedef struct rz_il_op_args_float_alg_terop_t RzILOpArgsFmad; typedef RzILOpArgsFloatAlgTernop RzILOpArgsFmad;
/** /**
* \brief op structure for some float binary op requiring `int` * \brief op structure for some float binary op requiring `int`
* rmode -> 'f float -> 'a bitv -> 'f float * rmode -> 'f float -> 'a bitv -> 'f float
*/ */
struct rz_il_op_args_float_alg_hybrid_binop_t { typedef struct rz_il_op_args_float_alg_hybrid_binop_t {
RzFloatRMode rmode; RzFloatRMode rmode;
RzILOpFloat *f; RzILOpFloat *f;
RzILOpBitVector *n; RzILOpBitVector *n;
}; } RzILOpArgsFloatAlgHybridBinop;
typedef struct rz_il_op_args_float_alg_hybrid_binop_t RzILOpArgsFrootn; typedef RzILOpArgsFloatAlgHybridBinop RzILOpArgsFrootn;
typedef struct rz_il_op_args_float_alg_hybrid_binop_t RzILOpArgsFpown; typedef RzILOpArgsFloatAlgHybridBinop RzILOpArgsFpown;
typedef struct rz_il_op_args_float_alg_hybrid_binop_t RzILOpArgsFcompound; typedef RzILOpArgsFloatAlgHybridBinop RzILOpArgsFcompound;
///////////////////////////// /////////////////////////////
// Opcodes of type 'a pure // // Opcodes of type 'a pure //
@ -618,76 +593,129 @@ typedef enum {
struct rz_il_op_pure_t { struct rz_il_op_pure_t {
RzILOpPureCode code; RzILOpPureCode code;
union { union {
RzILOpArgsIte ite; //////////
RzILOpArgsVar var; // Init //
RzILOpArgsLet let; RzILOpArgsVar var; ///< RZ_IL_OP_VAR
RzILOpArgsIte ite; ///< RZ_IL_OP_ITE
RzILOpArgsLet let; ///< RZ_IL_OP_LET
RzILOpArgsBoolAnd booland; struct {
RzILOpArgsBoolOr boolor; RzILOpPure *x;
RzILOpArgsBoolXor boolxor; RzILOpPure *y;
RzILOpArgsBoolInv boolinv; } binop; ///< any op that uses binop_bool or binop_bv
struct {
RzILOpPure *x;
} unop; ///< RZ_IL_OP_INV or any other op that uses unop_bv
RzILOpArgsBv bitv; //////////
RzILOpArgsMsb msb; // Bool //
RzILOpArgsLsb lsb; RzILOpArgsBoolInv boolinv; ///< RZ_IL_OP_INV
RzILOpArgsIsZero is_zero;
RzILOpArgsEq eq;
RzILOpArgsUle ule;
RzILOpArgsSle sle;
RzILOpArgsCast cast;
RzILOpArgsNeg neg;
RzILOpArgsLogNot lognot;
RzILOpArgsAdd add;
RzILOpArgsSub sub;
RzILOpArgsMul mul;
RzILOpArgsDiv div;
RzILOpArgsSdiv sdiv;
RzILOpArgsSmod smod;
RzILOpArgsMod mod;
RzILOpArgsLogand logand;
RzILOpArgsLogor logor;
RzILOpArgsLogxor logxor;
RzILOpArgsShiftLeft shiftl;
RzILOpArgsShiftRight shiftr;
RzILOpArgsAppend append;
RzILOpArgsLoad load; RzILOpArgsBinopBool binop_bool; ///< RZ_IL_OP_AND, RZ_IL_OP_OR, RZ_IL_OP_XOR
RzILOpArgsLoadW loadw; RzILOpArgsBoolAnd booland; ///< RZ_IL_OP_AND
RzILOpArgsBoolOr boolor; ///< RZ_IL_OP_OR
RzILOpArgsBoolXor boolxor; ///< RZ_IL_OP_XOR
RzILOpArgsFloat float_; ///////////////
RzILOpArgsFbits fbits; // Bitvector //
RzILOpArgsIsFinite is_finite; RzILOpArgsBV bitv; ///< RZ_IL_OP_BITV
RzILOpArgsIsNan is_nan;
RzILOpArgsIsInf is_inf; RzILOpArgsUnopBV unop_bv; ///< RZ_IL_OP_MSB, RZ_IL_OP_LSB, RZ_IL_OP_IS_ZERO, RZ_IL_OP_NEG, RZ_IL_OP_LOGNOT
RzILOpArgsIsFzero is_fzero; RzILOpArgsMsb msb; ///< RZ_IL_OP_MSB
RzILOpArgsIsFneg is_fneg; RzILOpArgsLsb lsb; ///< RZ_IL_OP_LSB
RzILOpArgsIsFpos is_fpos; RzILOpArgsIsZero is_zero; ///< RZ_IL_OP_IS_ZERO
RzILOpArgsFneg fneg; RzILOpArgsNeg neg; ///< RZ_IL_OP_NEG
RzILOpArgsFabs fabs; RzILOpArgsLogNot lognot; ///< RZ_IL_OP_LOGNOT
RzILOpArgsFCastint fcast_int;
RzILOpArgsFCastsint fcast_sint; /**
RzILOpArgsFCastfloat fcast_float; * RZ_IL_OP_EQ, RZ_IL_OP_ULE, RZ_IL_OP_SLE, RZ_IL_OP_ADD, RZ_IL_OP_SUB, RZ_IL_OP_MUL,
RzILOpArgsFCastsfloat fcast_sfloat; * RZ_IL_OP_DIV, RZ_IL_OP_SDIV, RZ_IL_OP_SMOD, RZ_IL_OP_MOD, RZ_IL_OP_LOGAND,
RzILOpArgsFconvert fconvert; * RZ_IL_OP_LOGOR, RZ_IL_OP_LOGXOR
RzILOpArgsFrequal frequal; */
RzILOpArgsFsucc fsucc; RzILOpArgsBinopBV binop_bv;
RzILOpArgsFpred fpred; RzILOpArgsEq eq; ///< RZ_IL_OP_EQ
RzILOpArgsForder forder; RzILOpArgsUle ule; ///< RZ_IL_OP_ULE
RzILOpArgsFround fround; RzILOpArgsSle sle; ///< RZ_IL_OP_SLE
RzILOpArgsFsqrt fsqrt; RzILOpArgsAdd add; ///< RZ_IL_OP_ADD
RzILOpArgsFrsqrt frsqrt; RzILOpArgsSub sub; ///< RZ_IL_OP_SUB
RzILOpArgsFexcept fexcept; RzILOpArgsMul mul; ///< RZ_IL_OP_MUL
RzILOpArgsFadd fadd; RzILOpArgsDiv div; ///< RZ_IL_OP_DIV
RzILOpArgsFsub fsub; RzILOpArgsSdiv sdiv; ///< RZ_IL_OP_SDIV
RzILOpArgsFmul fmul; RzILOpArgsSmod smod; ///< RZ_IL_OP_SMOD
RzILOpArgsFdiv fdiv; RzILOpArgsMod mod; ///< RZ_IL_OP_MOD
RzILOpArgsFmod fmod; RzILOpArgsLogAnd logand; ///< RZ_IL_OP_LOGAND
RzILOpArgsFmad fmad; RzILOpArgsLogOr logor; ///< RZ_IL_OP_LOGOR
RzILOpArgsFpow fpow; RzILOpArgsLogXor logxor; ///< RZ_IL_OP_LOGXOR
RzILOpArgsFpown fpown;
RzILOpArgsFrootn frootn; RzILOpArgsShift shift; ///< RZ_IL_OP_SHIFTL, RZ_IL_OP_SHIFTR
RzILOpArgsFcompound fcompound; RzILOpArgsShiftLeft shiftl; ///< RZ_IL_OP_SHIFTL
RzILOpArgsFhypot fhypot; RzILOpArgsShiftRight shiftr; ///< RZ_IL_OP_SHIFTR
RzILOpArgsCast cast; ///< RZ_IL_OP_CAST
RzILOpArgsAppend append; ///< RZ_IL_OP_APPEND
////////////
// Memory //
RzILOpArgsLoad load; ///< RZ_IL_OP_LOAD
RzILOpArgsLoadW loadw; ///< RZ_IL_OP_LOADW
///////////
// Float //
RzILOpArgsFloat float_; ///< RZ_IL_OP_FLOAT
/**
* RZ_IL_OP_FBITS, RZ_IL_OP_IS_FINITE, RZ_IL_OP_IS_NAN, RZ_IL_OP_IS_INF, RZ_IL_OP_IS_FZERO
* RZ_IL_OP_IS_FNEG, RZ_IL_OP_IS_FPOS, RZ_IL_OP_FNEG, RZ_IL_OP_FABS, RZ_IL_OP_FSUCC,
* RZ_IL_OP_FPRED
*/
RzILOpArgsUnopFloat unop_float;
RzILOpArgsFbits fbits; ///< RZ_IL_OP_FBITS
RzILOpArgsIsFinite is_finite; ///< RZ_IL_OP_IS_FINITE
RzILOpArgsIsNan is_nan; ///< RZ_IL_OP_IS_NAN
RzILOpArgsIsInf is_inf; ///< RZ_IL_OP_IS_INF
RzILOpArgsIsFzero is_fzero; ///< RZ_IL_OP_IS_FZERO
RzILOpArgsIsFneg is_fneg; ///< RZ_IL_OP_IS_FNEG
RzILOpArgsIsFpos is_fpos; ///< RZ_IL_OP_IS_FPOS
RzILOpArgsFneg fneg; ///< RZ_IL_OP_FNEG
RzILOpArgsFabs fabs; ///< RZ_IL_OP_FABS
RzILOpArgsFsucc fsucc; ///< RZ_IL_OP_FSUCC
RzILOpArgsFpred fpred; ///< RZ_IL_OP_FPRED
RzILOpArgsFCastint fcast_int; ///< RZ_IL_OP_FCAST_INT
RzILOpArgsFCastsint fcast_sint; ///< RZ_IL_OP_FCAST_SINT
RzILOpArgsFCastUFloat fcast_float; ///< RZ_IL_OP_FCAST_FLOAT
RzILOpArgsFCastSFloat fcast_sfloat; ///< RZ_IL_OP_FCAST_SFLOAT
RzILOpArgsFconvert fconvert; ///< RZ_IL_OP_FCONVERT
RzILOpArgsFrequal frequal; ///< RZ_IL_OP_FREQUAL
RzILOpArgsForder forder; ///< RZ_IL_OP_FORDER
RzILOpArgsFround fround; ///< RZ_IL_OP_FROUND
RzILOpArgsFsqrt fsqrt; ///< RZ_IL_OP_FSQRT
RzILOpArgsFrsqrt frsqrt; ///< RZ_IL_OP_FRSQRT
/**
* RZ_IL_OP_FADD, RZ_IL_OP_FSUB, RZ_IL_OP_FMUL, RZ_IL_OP_FDIV, RZ_IL_OP_FMOD,
* RZ_IL_OP_FHYPOT, RZ_IL_OP_FPOW
*/
RzILOpArgsFloatAlgBinop binop_float_alg;
RzILOpArgsFadd fadd; ///< RZ_IL_OP_FADD
RzILOpArgsFsub fsub; ///< RZ_IL_OP_FSUB
RzILOpArgsFmul fmul; ///< RZ_IL_OP_FMUL
RzILOpArgsFdiv fdiv; ///< RZ_IL_OP_FDIV
RzILOpArgsFmod fmod; ///< RZ_IL_OP_FMOD
RzILOpArgsFhypot fhypot; ///< RZ_IL_OP_FHYPOT
RzILOpArgsFpow fpow; ///< RZ_IL_OP_FPOW
RzILOpArgsFmad fmad; ///< RZ_IL_OP_FMAD
RzILOpArgsFloatAlgHybridBinop binop_float_alg_hybrid; ///< RZ_IL_OP_FROOTN, RZ_IL_OP_FPOWN, RZ_IL_OP_FCOMPOUND
RzILOpArgsFrootn frootn; ///< RZ_IL_OP_FROOTN
RzILOpArgsFpown fpown; ///< RZ_IL_OP_FPOWN
RzILOpArgsFcompound fcompound; ///< RZ_IL_OP_FCOMPOUND
RzILOpArgsFexcept fexcept; ///< RZ_IL_OP_FEXCEPT
} op; } op;
}; };
@ -710,7 +738,6 @@ RZ_API RZ_OWN RzILOpBool *rz_il_op_new_bool_inv(RZ_NONNULL RzILOpBool *x);
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv(RZ_NONNULL RzBitVector *value); RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv(RZ_NONNULL RzBitVector *value);
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv_from_ut64(ut32 length, ut64 number); RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv_from_ut64(ut32 length, ut64 number);
RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv_from_st64(ut32 length, st64 number); RZ_API RZ_OWN RzILOpBitVector *rz_il_op_new_bitv_from_st64(ut32 length, st64 number);
RZ_API RZ_OWN RzILOpBool *rz_il_op_new_bitv_max(ut32 length);
RZ_API RZ_OWN RzILOpBool *rz_il_op_new_msb(RZ_NONNULL RzILOpPure *val); RZ_API RZ_OWN RzILOpBool *rz_il_op_new_msb(RZ_NONNULL RzILOpPure *val);
RZ_API RZ_OWN RzILOpBool *rz_il_op_new_lsb(RZ_NONNULL RzILOpPure *val); RZ_API RZ_OWN RzILOpBool *rz_il_op_new_lsb(RZ_NONNULL RzILOpPure *val);
RZ_API RZ_OWN RzILOpBool *rz_il_op_new_is_zero(RZ_NONNULL RzILOpPure *bv); RZ_API RZ_OWN RzILOpBool *rz_il_op_new_is_zero(RZ_NONNULL RzILOpPure *bv);