Skip to content

Commit

Permalink
Start integrating new esil stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
condret committed Dec 2, 2024
1 parent c938df9 commit 3938d9a
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 21 deletions.
151 changes: 132 additions & 19 deletions libr/esil/esil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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 " <W ", addr);
int i;
Expand All @@ -576,11 +644,17 @@ R_API bool r_esil_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) {
ret = esil->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) {
Expand Down Expand Up @@ -726,7 +800,7 @@ static bool get_parm_size(REsil *esil, const char *str, ut64 *num, int *size) {
}
return true;
case R_ESIL_PARM_REG:
return r_esil_reg_read (esil, str, num, size);
return r_esil_reg_read (esil, str, num, (ut32 *)size);
default:
R_LOG_DEBUG ("Invalid esil arg to find parm size (%s)", str);
esil->parse_stop = 1;
Expand All @@ -738,17 +812,36 @@ R_API int r_esil_get_parm(REsil *esil, const char *str, ut64 *num) {
return get_parm_size (esil, str, num, NULL);
}

R_API bool r_esil_reg_write(REsil *esil, const char *dst, ut64 num) {
R_API bool r_esil_reg_write(REsil *esil, const char *dst, ut64 val) {
R_RETURN_VAL_IF_FAIL (esil && dst, false);
#if USE_NEW_ESIL
ut64 old;
if (R_UNLIKELY (!r_esil_reg_read_silent (esil, dst, &old, NULL))) {
return r_esil_reg_write_silent (esil, dst, val);
}
if (R_UNLIKELY (!r_esil_reg_write_silent (esil, dst, val))) {
return false;
}
ut32 i;
if (!r_id_storage_get_lowest (&esil->voyeur[R_ESIL_VOYEUR_REG_WRITE], &i)) {
return true;
}
do {
REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_REG_WRITE], i);
voy->reg_write (voy->user, dst, old, val);
} while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_REG_WRITE], &i));
return true;
#else
bool ret = false;
R_LOG_DEBUG ("%s=0x%" PFMT64x, dst, num);
R_LOG_DEBUG ("%s=0x%" PFMT64x, dst, val);
if (esil->cb.hook_reg_write) {
ret = esil->cb.hook_reg_write (esil, dst, &num);
ret = esil->cb.hook_reg_write (esil, dst, &val);
}
if (!ret && esil->cb.reg_write) {
ret = esil->cb.reg_write (esil, dst, num);
ret = esil->cb.reg_write (esil, dst, val);
}
return ret;
#endif
}

R_API bool r_esil_reg_write_silent(REsil *esil, const char *name, ut64 num) {
Expand All @@ -759,29 +852,45 @@ R_API bool r_esil_reg_write_silent(REsil *esil, const char *name, ut64 num) {
R_API bool r_esil_reg_read_nocallback(REsil *esil, const char *regname, ut64 *num, int *size) {
void *old_hook_reg_read = (void *) esil->cb.hook_reg_read;
esil->cb.hook_reg_read = NULL;
bool ret = r_esil_reg_read (esil, regname, num, size);
bool ret = r_esil_reg_read (esil, regname, num, (ut32 *)size);
esil->cb.hook_reg_read = old_hook_reg_read;
return ret;
}

R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *num, int *size) {
R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *val, ut32 *size) {
#if USE_NEW_ESIL
R_RETURN_VAL_IF_FAIL (esil && regname && val, false);
if (R_UNLIKELY (!r_esil_reg_read_silent (esil, regname, val, size))) {
return false;
}
ut32 i;
if (!r_id_storage_get_lowest (&esil->voyeur[R_ESIL_VOYEUR_REG_READ], &i)) {
return true;
}
do {
REsilVoyeur *voy = r_id_storage_get (&esil->voyeur[R_ESIL_VOYEUR_REG_READ], i);
voy->reg_read (voy->user, regname, *val);
} while (r_id_storage_get_next (&esil->voyeur[R_ESIL_VOYEUR_REG_READ], &i));
return true;
#else
R_RETURN_VAL_IF_FAIL (esil && regname, false);
bool ret = false;
ut64 localnum = 0LL; // XXX why is this necessary?
if (!num) {
num = &localnum;
if (!val) {
val = &localnum;
}
*num = 0LL;
*val = 0LL;
if (size) {
*size = esil->anal->config->bits;
}
if (esil->cb.hook_reg_read) {
ret = esil->cb.hook_reg_read (esil, regname, num, size);
ret = esil->cb.hook_reg_read (esil, regname, val, (st32 *)size);
}
if (!ret && esil->cb.reg_read) {
ret = esil->cb.reg_read (esil, regname, num, size);
ret = esil->cb.reg_read (esil, regname, val, (st32 *)size);
}
return ret;
#endif
}

R_API bool r_esil_reg_read_silent(REsil *esil, const char *name, ut64 *val, ut32 *size) {
Expand Down Expand Up @@ -1069,7 +1178,11 @@ static bool esil_eq(REsil *esil) {
}
free (newreg);
free (src2);
#if USE_NEW_ESIL
} else if (src && dst && r_esil_reg_read_silent (esil, dst, &num, NULL)) {
#else
} else if (src && dst && r_esil_reg_read_nocallback (esil, dst, &num, NULL)) {
#endif
if (r_esil_get_parm (esil, src, &num2)) {
ret = r_esil_reg_write (esil, dst, num2);
esil->cur = num2;
Expand Down
6 changes: 4 additions & 2 deletions libr/include/r_esil.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -307,9 +309,9 @@ R_API bool r_esil_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len);
R_API bool r_esil_mem_read_silent(REsil *esil, ut64 addr, ut8 *buf, int len);
R_API bool r_esil_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len);
R_API bool r_esil_mem_write_silent(REsil *esil, ut64 addr, const ut8 *buf, int len);
R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *num, int *size);
R_API bool r_esil_reg_read(REsil *esil, const char *regname, ut64 *val, ut32 *size);
R_API bool r_esil_reg_read_silent(REsil *esil, const char *name, ut64 *val, ut32 *size);
R_API bool r_esil_reg_write(REsil *esil, const char *name, ut64 num);
R_API bool r_esil_reg_write(REsil *esil, const char *name, ut64 val);
R_API bool r_esil_reg_write_silent(REsil *esil, const char *dst, ut64 val);
R_API bool r_esil_pushnum(REsil *esil, ut64 num);
R_API bool r_esil_push(REsil *esil, const char *str);
Expand Down

0 comments on commit 3938d9a

Please sign in to comment.