diff --git a/librz/il/il_routines.c b/librz/il/il_routines.c index f78d68b07ed..3e745cb32bb 100644 --- a/librz/il/il_routines.c +++ b/librz/il/il_routines.c @@ -49,6 +49,27 @@ RZ_API RZ_OWN RzILOpBitVector *rz_il_extract64(RZ_BORROW RzILOpBitVector *value, return op_AND_6; } +/** + * \brief Extracts \p length bits from \p start from \p value and returns them as S32. The extracted value is sign extended. + * + * Performed operation: (((st32) (value << 0x20 - length - start)) >> 0x20 - length); + * + * \param value The value to extract the bits from. It must be a bitvector of size 32. + * \param start The start index of the bits to extract. Passed bitvector must be 32bits in size. + * \param length Number of bits to extract. Passed bitvector must be 32bits in size. + * + * \return A 32bit wide sign extended bitvector with the extracted value. + */ +RZ_API RZ_OWN RzILOpBitVector *rz_il_sextract32(RZ_BORROW RzILOpBitVector *value, RZ_BORROW RzILOpBitVector *start, RZ_BORROW RzILOpBitVector *length) { + rz_return_val_if_fail(value && start && length, NULL); + RzILOpPure *op_SUB_1 = rz_il_op_new_sub(rz_il_op_new_bitv_from_st64(32, 0x20), length); + RzILOpPure *op_SUB_2 = rz_il_op_new_sub(op_SUB_1, start); + RzILOpPure *op_LSHIFT_3 = rz_il_op_new_shiftl(rz_il_op_new_b0(), value, op_SUB_2); + RzILOpPure *op_SUB_6 = rz_il_op_new_sub(rz_il_op_new_bitv_from_st64(32, 0x20), rz_il_op_pure_dup(length)); + RzILOpPure *op_RSHIFT_7 = rz_il_op_new_shiftr_arith(rz_il_op_new_cast(32, rz_il_op_new_b0(), op_LSHIFT_3), op_SUB_6); + return op_RSHIFT_7; +} + /** * \brief Extracts \p length bits from \p start from \p value and returns them as S64. The extracted value is sign extended. * @@ -169,7 +190,7 @@ RZ_API RZ_OWN RzILOpBitVector *rz_il_bswap32(RZ_BORROW RzILOpBitVector *t) { } /** - * \brief Performes a byte swap of \p t. + * \brief Performs a byte swap of \p t. * * Perfomed operation: * ((t & 0xff) << 0x38) @@ -211,3 +232,15 @@ RZ_API RZ_OWN RzILOpBitVector *rz_il_bswap64(RZ_BORROW RzILOpBitVector *t) { RzILOpPure *op_OR_38 = rz_il_op_new_log_or(op_OR_33, op_RSHIFT_37); return op_OR_38; } + +/** + * \brief [NE] not eq x y binary predicate for bitwise equality + */ +RZ_API RZ_OWN RzILOpBool *rz_il_op_new_ne(RZ_NONNULL RzILOpPure *x, RZ_NONNULL RzILOpPure *y) { + rz_return_val_if_fail(x && y, NULL); + RzILOpBool *result = rz_il_op_new_eq(x, y); + if (!result) { + return NULL; + } + return rz_il_op_new_bool_inv(result); +} diff --git a/librz/il/il_validate.c b/librz/il/il_validate.c index 1ea28a9c043..f191a0dabfa 100644 --- a/librz/il/il_validate.c +++ b/librz/il/il_validate.c @@ -279,6 +279,7 @@ typedef bool (*ValidatePureFn)(VALIDATOR_PURE_ARGS); #define VALIDATOR_ASSERT(condition, ...) \ do { \ if (!(condition)) { \ + rz_warn_if_reached(); \ rz_strbuf_appendf(report_builder, __VA_ARGS__); \ return false; \ } \ diff --git a/librz/include/rz_il/rz_il_opbuilder_begin.h b/librz/include/rz_il/rz_il_opbuilder_begin.h index 2d0944f984c..fac91223df0 100644 --- a/librz/include/rz_il/rz_il_opbuilder_begin.h +++ b/librz/include/rz_il/rz_il_opbuilder_begin.h @@ -179,11 +179,13 @@ #define EXTRACT32(value, start, length) rz_il_extract32(value, start, length) #define EXTRACT64(value, start, length) rz_il_extract64(value, start, length) +#define SEXTRACT32(value, start, length) rz_il_sextract32(value, start, length) #define SEXTRACT64(value, start, length) rz_il_sextract64(value, start, length) #define DEPOSIT32(value, start, length, fieldval) rz_il_deposit32(value, start, length, fieldval) #define DEPOSIT64(value, start, length, fieldval) rz_il_deposit64(value, start, length, fieldval) #define BSWAP16(t) rz_il_bswap16(t) #define BSWAP32(t) rz_il_bswap32(t) #define BSWAP64(t) rz_il_bswap64(t) +#define NE(x, y) rz_il_op_new_ne(x, y) #endif diff --git a/librz/include/rz_il/rz_il_opbuilder_end.h b/librz/include/rz_il/rz_il_opbuilder_end.h index c6fe9f62547..1241793e8d8 100644 --- a/librz/include/rz_il/rz_il_opbuilder_end.h +++ b/librz/include/rz_il/rz_il_opbuilder_end.h @@ -138,11 +138,13 @@ #undef EXTRACT32 #undef EXTRACT64 +#undef SEXTRACT32 #undef SEXTRACT64 #undef DEPOSIT32 #undef DEPOSIT64 #undef BSWAP16 #undef BSWAP32 #undef BSWAP64 +#undef NE #undef RZ_IL_OPBUILDER_BEGIN_H diff --git a/librz/include/rz_il/rz_il_opcodes.h b/librz/include/rz_il/rz_il_opcodes.h index e5ec47995d4..e5c86c2bb29 100644 --- a/librz/include/rz_il/rz_il_opcodes.h +++ b/librz/include/rz_il/rz_il_opcodes.h @@ -772,12 +772,14 @@ RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fcompound(RzFloatRMode rmode, RZ_NONNULL RZ_API RZ_OWN RzILOpBitVector *rz_il_extract32(RZ_BORROW RzILOpBitVector *value, RZ_BORROW RzILOpBitVector *start, RZ_BORROW RzILOpBitVector *length); RZ_API RZ_OWN RzILOpBitVector *rz_il_extract64(RZ_BORROW RzILOpBitVector *value, RZ_BORROW RzILOpBitVector *start, RZ_BORROW RzILOpBitVector *length); +RZ_API RZ_OWN RzILOpBitVector *rz_il_sextract32(RZ_BORROW RzILOpBitVector *value, RZ_BORROW RzILOpBitVector *start, RZ_BORROW RzILOpBitVector *length); RZ_API RZ_OWN RzILOpBitVector *rz_il_sextract64(RZ_BORROW RzILOpBitVector *value, RZ_BORROW RzILOpBitVector *start, RZ_BORROW RzILOpBitVector *length); RZ_API RZ_OWN RzILOpBitVector *rz_il_deposit64(RZ_BORROW RzILOpBitVector *value, RZ_BORROW RzILOpBitVector *start, RZ_BORROW RzILOpBitVector *length, RZ_BORROW RzILOpBitVector *fieldval); RZ_API RZ_OWN RzILOpBitVector *rz_il_deposit32(RZ_BORROW RzILOpBitVector *value, RZ_BORROW RzILOpBitVector *start, RZ_BORROW RzILOpBitVector *length, RZ_BORROW RzILOpBitVector *fieldval); RZ_API RZ_OWN RzILOpBitVector *rz_il_bswap16(RZ_BORROW RzILOpBitVector *t); RZ_API RZ_OWN RzILOpBitVector *rz_il_bswap32(RZ_BORROW RzILOpBitVector *t); RZ_API RZ_OWN RzILOpBitVector *rz_il_bswap64(RZ_BORROW RzILOpBitVector *t); +RZ_API RZ_OWN RzILOpBool *rz_il_op_new_ne(RZ_NONNULL RzILOpPure *x, RZ_NONNULL RzILOpPure *y); /////////////////////////////// // Opcodes of type 'a effect //