Add division overflow macros in r_types ##util (#17856)
This commit is contained in:
parent
8a319a2b09
commit
7b171b9961
3 changed files with 22 additions and 14 deletions
|
|
@ -1540,18 +1540,6 @@ static bool esil_mod(RzAnalEsil *esil) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool detect_fpu_div_exception(ut64 a, ut64 b) {
|
||||
// division by zero
|
||||
if (b == UT64_MIN) {
|
||||
return true;
|
||||
}
|
||||
// undefined result (0x80000 / -1) cant be represented
|
||||
if (a == UT64_GT0 && b == UT64_MAX) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool esil_signed_mod(RzAnalEsil *esil) {
|
||||
bool ret = false;
|
||||
st64 s, d;
|
||||
|
|
@ -1559,7 +1547,7 @@ static bool esil_signed_mod(RzAnalEsil *esil) {
|
|||
char *src = rz_anal_esil_pop (esil);
|
||||
if (src && rz_anal_esil_get_parm (esil, src, (ut64 *)&s)) {
|
||||
if (dst && rz_anal_esil_get_parm (esil, dst, (ut64 *)&d)) {
|
||||
if (detect_fpu_div_exception (d, s)) {
|
||||
if (ST64_DIV_OVFCHK (d, s)) {
|
||||
if (esil->verbose > 0) {
|
||||
eprintf ("0x%08"PFMT64x" esil_mod: Division by zero!\n", esil->address);
|
||||
}
|
||||
|
|
@ -1638,7 +1626,7 @@ static bool esil_signed_div(RzAnalEsil *esil) {
|
|||
char *src = rz_anal_esil_pop (esil);
|
||||
if (src && rz_anal_esil_get_parm (esil, src, (ut64 *)&s)) {
|
||||
if (dst && rz_anal_esil_get_parm (esil, dst, (ut64 *)&d)) {
|
||||
if (detect_fpu_div_exception (d, s)) {
|
||||
if (ST64_DIV_OVFCHK (d, s)) {
|
||||
ERR ("esil_div: Division by zero!");
|
||||
esil->trap = RZ_ANAL_TRAP_DIVBYZERO;
|
||||
esil->trap_code = 0;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ typedef struct _utX {
|
|||
#undef UT64_MIN
|
||||
#undef UT32_MAX
|
||||
#undef UT32_MIN
|
||||
#undef UT16_MIN
|
||||
#undef UT8_MIN
|
||||
#define ST64_MAX ((st64)0x7FFFFFFFFFFFFFFFULL)
|
||||
#define ST64_MIN ((st64)(-ST64_MAX-1))
|
||||
#define UT64_MAX 0xFFFFFFFFFFFFFFFFULL
|
||||
|
|
@ -80,6 +82,7 @@ typedef struct _utX {
|
|||
#define UT64_16U 0xFFFFFFFFFFFF0000ULL
|
||||
#define UT64_8U 0xFFFFFFFFFFFFFF00ULL
|
||||
#define UT32_MIN 0U
|
||||
#define UT16_MIN 0U
|
||||
#define UT32_GT0 0x80000000U
|
||||
#define UT32_LT0 0x7FFFFFFFU
|
||||
#define ST32_MAX 0x7FFFFFFF
|
||||
|
|
|
|||
|
|
@ -47,6 +47,23 @@ static inline bool overflow_name(type_base a, type_base b) { \
|
|||
return a && b < type_max / a; \
|
||||
}
|
||||
|
||||
#define SIGNED_DIV_OVERFLOW_CHECK(overflow_name, type_base, type_mid, type_max) \
|
||||
static inline bool overflow_name(type_base a, type_base b) { \
|
||||
return (!b || (a == type_mid && b == type_max)); \
|
||||
}
|
||||
#define UNSIGNED_DIV_OVERFLOW_CHECK(overflow_name, type_base, type_min, type_max) \
|
||||
static inline bool overflow_name(type_base a, type_base b) { \
|
||||
return !b; \
|
||||
}
|
||||
|
||||
SIGNED_DIV_OVERFLOW_CHECK(ST8_DIV_OVFCHK, ut8, UT8_GT0, UT8_MAX)
|
||||
SIGNED_DIV_OVERFLOW_CHECK(ST16_DIV_OVFCHK, ut16, UT16_GT0, UT16_MAX)
|
||||
SIGNED_DIV_OVERFLOW_CHECK(ST32_DIV_OVFCHK, ut32, UT32_GT0, UT32_MAX)
|
||||
SIGNED_DIV_OVERFLOW_CHECK(ST64_DIV_OVFCHK, ut64, UT64_GT0, UT64_MAX)
|
||||
UNSIGNED_DIV_OVERFLOW_CHECK(UT8_DIV_OVFCHK, ut8, UT8_MIN, UT8_MAX)
|
||||
UNSIGNED_DIV_OVERFLOW_CHECK(UT16_DIV_OVFCHK, ut16, UT16_MIN, UT16_MAX)
|
||||
UNSIGNED_DIV_OVERFLOW_CHECK(UT32_DIV_OVFCHK, ut32, UT32_MIN, UT32_MAX)
|
||||
UNSIGNED_DIV_OVERFLOW_CHECK(UT64_DIV_OVFCHK, ut64, UT64_MIN, UT64_MAX)
|
||||
// TODO: Windows doesn't have ssize_t, and we don't need this check yet
|
||||
// SIGNED_MUL_OVERFLOW_CHECK(SSZT_MUL_OVFCHK, ssize_t, SSZT_MIN, SSZT_MAX)
|
||||
SIGNED_MUL_OVERFLOW_CHECK(ST8_MUL_OVFCHK, st8, ST8_MIN, ST8_MAX)
|
||||
|
|
|
|||
Loading…
Reference in a new issue