From 996f6b83b7a9551b05df2ca979bd960a609481f3 Mon Sep 17 00:00:00 2001 From: condret Date: Mon, 2 Dec 2024 01:43:16 +0100 Subject: [PATCH] Start integrating new esil stuff --- libr/esil/esil.c | 88 +++++++++++++++++++++++++++++++++++++++---- libr/include/r_esil.h | 2 + 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 33394060f7322..02d6f59c04576 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -387,7 +387,7 @@ static ut8 esil_internal_sizeof_reg(REsil *esil, const char *r) { static bool alignCheck(REsil *esil, ut64 addr) { // r_anal_archinfo (esil->anal, R_ARCH_INFO_DATA_ALIGN); - const unsigned int da = esil->data_align; + const ut32 da = esil->data_align; return !(da > 0 && addr % da); } @@ -457,17 +457,36 @@ static bool internal_esil_mem_read_no_null(REsil *esil, ut64 addr, ut8 *buf, int } R_API bool r_esil_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len) { - R_RETURN_VAL_IF_FAIL (buf && esil, 0); - bool ret = false; +#if USE_NEW_ESIL + R_RETURN_VAL_IF_FAIL (buf && esil && esil->mem_if.mem_read, false); + addr &= esil->addrmask; +#else + R_RETURN_VAL_IF_FAIL (buf && esil, false); addr &= esil->addrmask; + bool ret = false; if (esil->cb.hook_mem_read) { ret = esil->cb.hook_mem_read (esil, addr, buf, len); } +#endif if (!alignCheck (esil, addr)) { esil->trap = R_ANAL_TRAP_READ_ERR; esil->trap_code = addr; return false; } +#if USE_NEW_ESIL + if (R_UNLIKELY (!r_esil_mem_read_silent (esil, addr, buf, len))) { + return false; + } + ut32 i; + if (!r_id_storage_get_lowest (&esil->voyeur[R_ESIL_VOYEUR_MEM_READ], &i)) { + return true; + } + do { + REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_MEM_READ], i); + voy->mem_read (voy->user, addr, buf, len); + } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_MEM_READ], &i)); + return true; +#else if (!ret && esil->cb.mem_read) { if (ret = esil->cb.mem_read (esil, addr, buf, len), (!ret && esil->iotrap)) { esil->trap = R_ANAL_TRAP_READ_ERR; @@ -483,11 +502,17 @@ R_API bool r_esil_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len) { eprintf ("\n"); } return ret; +#endif } R_API bool r_esil_mem_read_silent(REsil *esil, ut64 addr, ut8 *buf, int len) { - R_RETURN_VAL_IF_FAIL (buf && esil->mem_if.mem_read, false); - return esil->mem_if.mem_read (esil->mem_if.mem, addr & esil->addrmask, buf, len); + R_RETURN_VAL_IF_FAIL (buf && esil && esil->mem_if.mem_read, false); + if (R_LIKELY (esil->mem_if.mem_read (esil->mem_if.mem, addr & esil->addrmask, buf, len))) { + return true; + } + esil->trap = R_ANAL_TRAP_READ_ERR; + esil->trap_code = addr; + return false; } static bool internal_esil_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) { @@ -558,9 +583,52 @@ static bool internal_esil_mem_write_no_null(REsil *esil, ut64 addr, const ut8 *b } R_API bool r_esil_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) { +#if USE_NEW_ESIL + R_RETURN_VAL_IF_FAIL (esil && buf && esil->mem_if.mem_write, false); + addr &= esil->addrmask; + union { + ut8 buf[16]; + ut8 *ptr; + } o; + ut32 i; + if (R_LIKELY (len < 17)) { + memset (o.buf, 0xff, len); + if (R_UNLIKELY (!r_esil_mem_read_silent (esil, addr, o.buf, len))) { + esil->trap = R_ANAL_TRAP_NONE; + } + if (R_UNLIKELY (!r_esil_mem_write_silent (esil, addr, buf, len))) { + return false; + } + if (!r_id_storage_get_lowest (&esil->voyeur[R_ESIL_VOYEUR_MEM_WRITE], &i)) { + return true; + } + do { + REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_OP_TYPE_MEM_WRITE], i); + voy->mem_write (voy->user, addr, o.buf, buf, len); + } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_OP_TYPE_MEM_WRITE], &i)); + return true; + } + o.ptr = R_NEWS (ut8, len); + if (R_UNLIKELY (!o.ptr)) { + return r_esil_mem_write_silent (esil, addr, buf, len); + } + memset (o.ptr, 0xff, len); + if (R_UNLIKELY (!r_esil_mem_read_silent (esil, addr, o.ptr, len))) { + esil->trap = R_ANAL_TRAP_NONE; + } + if (R_UNLIKELY (!r_esil_mem_write_silent (esil, addr, buf, len))) { + return false; + } + do { + REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_OP_TYPE_MEM_WRITE], i); + voy->mem_write (voy->user, addr, o.ptr, buf, len); + } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_OP_TYPE_MEM_WRITE], &i)); + free (o.ptr); + return true; +#else R_RETURN_VAL_IF_FAIL (esil && buf, false); - bool ret = false; addr &= esil->addrmask; + bool ret = false; IFDBG { eprintf ("0x%08" PFMT64x " cb.mem_write (esil, addr, buf, len); } return ret; +#endif } R_API bool r_esil_mem_write_silent(REsil *esil, ut64 addr, const ut8 *buf, int len) { R_RETURN_VAL_IF_FAIL (esil && buf && esil->mem_if.mem_write, false); - return esil->mem_if.mem_write (esil->mem_if.mem, addr & esil->addrmask, buf, len); + if (R_LIKELY (esil->mem_if.mem_write (esil->mem_if.mem, addr & esil->addrmask, buf, len))) { + return true; + } + esil->trap = R_ANAL_TRAP_WRITE_ERR; + esil->trap_code = addr; + return false; } static bool internal_esil_reg_read(REsil *esil, const char *regname, ut64 *num, int *size) { diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index 7103fbdfc24e9..69987cc0d4ddc 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -11,6 +11,8 @@ extern "C" { #endif +#define USE_NEW_ESIL 0 + #define esilprintf(op, fmt, ...) r_strbuf_setf (&op->esil, fmt, ##__VA_ARGS__) // only flags that affect control flow enum {