diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 8f0c13cfc1d79..10a5455cfb7a6 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -14,7 +14,6 @@ #include #include -#define ESIL_MACRO 0 // TODO: replace esil->verbose with R_LOG_DEBUG #define IFDBG if (esil->verbose > 1) @@ -209,46 +208,48 @@ R_API REsil *r_esil_new_simple(ut32 addrsize, void *reg, void *iob) { return r_esil_new_ex (4096, false, addrsize, &simple_reg_if, &simple_mem_if); } -R_API st32 r_esil_add_voyeur(REsil *esil, void *user, void *vfn, REsilVoyeurType vt) { - R_RETURN_VAL_IF_FAIL (esil && vfn, -1); +R_API ut32 r_esil_add_voyeur(REsil *esil, void *user, void *vfn, REsilVoyeurType vt) { + R_RETURN_VAL_IF_FAIL (esil && vfn, R_ESIL_VOYEUR_ERR); switch (vt) { case R_ESIL_VOYEUR_REG_READ: case R_ESIL_VOYEUR_REG_WRITE: case R_ESIL_VOYEUR_MEM_READ: case R_ESIL_VOYEUR_MEM_WRITE: + case R_ESIL_VOYEUR_OP: break; default: r_warn_if_reached (); - return -1; + return R_ESIL_VOYEUR_ERR; } REsilVoyeur *voyeur = R_NEW (REsilVoyeur); if (!voyeur) { - return -1; + return R_ESIL_VOYEUR_ERR; } ut32 id; if (!r_id_storage_add (&esil->voyeur[vt], voyeur, &id)) { free (voyeur); - return -1; + return R_ESIL_VOYEUR_ERR; } voyeur->user = user; voyeur->vfn = vfn; - return (st32)(id | (vt << 29)); + return id | (vt << VOYEUR_SHIFT_LEFT); } -R_API void r_esil_del_voyeur(REsil *esil, st32 vid) { +R_API void r_esil_del_voyeur(REsil *esil, ut32 vid) { R_RETURN_IF_FAIL (esil); - const ut32 vt = (vid & (0x7 << 29)) >> 29; + const ut32 vt = (vid & VOYEUR_TYPE_MASK) >> VOYEUR_SHIFT_LEFT; switch (vt) { case R_ESIL_VOYEUR_REG_READ: case R_ESIL_VOYEUR_REG_WRITE: case R_ESIL_VOYEUR_MEM_READ: case R_ESIL_VOYEUR_MEM_WRITE: + case R_ESIL_VOYEUR_OP: break; default: r_warn_if_reached (); return; } - const ut32 id = vid & ~(0x7 << 29); + const ut32 id = vid & ~VOYEUR_TYPE_MASK; free (r_id_storage_take (&esil->voyeur[vt], id)); } @@ -3758,11 +3759,21 @@ static bool runword(REsil *esil, const char *word) { op = r_esil_get_op (esil, word); if (op) { // run action +#if USE_NEW_ESIL + ut32 i; + if (r_id_storage_get_lowest (&esil->voyeur[R_ESIL_VOYEUR_OP], &i)) { + do { + REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_OP], i); + voy->op (voy->user, word); + } while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_OP], &i)); + } +#else if (esil->cb.hook_command) { if (esil->cb.hook_command (esil, word)) { return 1; // XXX cannot return != 1 } } +#endif esil->current_opstr = strdup (word); // so this is basically just sharing what's the // operation with the operation useful for wrappers diff --git a/libr/include/r_esil.h b/libr/include/r_esil.h index eeb7a6c1a97d6..c801506e1e155 100644 --- a/libr/include/r_esil.h +++ b/libr/include/r_esil.h @@ -165,6 +165,7 @@ typedef void (*REsilVoyeurRegRead)(void *user, const char *name, ut64 val); typedef void (*REsilVoyeurRegWrite)(void *user, const char *name, ut64 old, ut64 val); typedef void (*REsilVoyeurMemRead)(void *user, ut64 addr, const ut8 *buf, int len); typedef void (*REsilVoyeurMemWrite)(void *user, ut64 addr, const ut8 *old, const ut8 *buf, int len); +typedef void (*REsilVoyeurOp)(void *user, const char *op); typedef struct r_esil_voyeur_t { void *user; @@ -173,6 +174,7 @@ typedef struct r_esil_voyeur_t { REsilVoyeurRegWrite reg_write; REsilVoyeurMemRead mem_read; REsilVoyeurMemWrite mem_write; + REsilVoyeurOp op; void *vfn; }; } REsilVoyeur; @@ -182,10 +184,16 @@ typedef enum { R_ESIL_VOYEUR_REG_WRITE, R_ESIL_VOYEUR_MEM_READ, R_ESIL_VOYEUR_MEM_WRITE, + R_ESIL_VOYEUR_OP, R_ESIL_VOYEUR_LAST, + R_ESIL_VOYEUR_HIGH_MASK = 0x7, + R_ESIL_VOYEUR_ERR = UT32_MAX, } REsilVoyeurType; -#define MAX_VOYEURS (UT32_MAX ^ (0x7 << 29)) +#define VOYEUR_TYPE_BITS 3 +#define VOYEUR_SHIFT_LEFT ((sizeof (ut32) << 3) - VOYEUR_TYPE_BITS) +#define VOYEUR_TYPE_MASK (R_ESIL_VOYEUR_HIGH_MASK << VOYEUR_SHIFT_LEFT) +#define MAX_VOYEURS (UT32_MAX ^ VOYEUR_TYPE_MASK) typedef struct r_esil_options_t { int nowrite; @@ -292,8 +300,8 @@ R_API REsil *r_esil_new_ex(int stacksize, bool iotrap, ut32 addrsize, //this should replace existing r_esil_new R_API REsil *r_esil_new_simple(ut32 addrsize, void *reg, void *iob); //R_API REsil *r_esil_new_simple(ut32 addrsize, struct r_reg_t *reg, struct r_io_bind_t *iob); -R_API st32 r_esil_add_voyeur(REsil *esil, void *user, void *vfn, REsilVoyeurType vt); -R_API void r_esil_del_voyeur(REsil *esil, st32 vid); +R_API ut32 r_esil_add_voyeur(REsil *esil, void *user, void *vfn, REsilVoyeurType vt); +R_API void r_esil_del_voyeur(REsil *esil, ut32 vid); R_API void r_esil_reset(REsil *esil); R_API void r_esil_set_pc(REsil *esil, ut64 addr); R_API bool r_esil_setup(REsil *esil, struct r_anal_t *anal, bool romem, bool stats, bool nonull);