mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-07 02:23:58 +00:00
anal->esil can't be null now, improve default initialization ##esil
* Fix anal.gp initialization with esil traps * Adapt tests to use aeim when needed * Improve pde initialization with r2 -c * Requires 2nd round review, added comments
This commit is contained in:
parent
4e44a218b6
commit
dcfc36ede5
@ -120,7 +120,8 @@ R_API RAnal *r_anal_new(void) {
|
|||||||
anal->sdb_classes_attrs = sdb_ns (anal->sdb_classes, "attrs", 1);
|
anal->sdb_classes_attrs = sdb_ns (anal->sdb_classes, "attrs", 1);
|
||||||
anal->zign_path = strdup ("");
|
anal->zign_path = strdup ("");
|
||||||
anal->cb_printf = (PrintfCallback) printf;
|
anal->cb_printf = (PrintfCallback) printf;
|
||||||
anal->esil = NULL; // nul on purpose, otherwise many analysisi fail O_O
|
anal->esil = r_esil_new (4096, 0, 1);
|
||||||
|
anal->esil->anal = anal;
|
||||||
(void)r_anal_pin_init (anal);
|
(void)r_anal_pin_init (anal);
|
||||||
(void)r_anal_xrefs_init (anal);
|
(void)r_anal_xrefs_init (anal);
|
||||||
anal->diff_thbb = R_ANAL_THRESHOLDBB;
|
anal->diff_thbb = R_ANAL_THRESHOLDBB;
|
||||||
|
@ -72,7 +72,7 @@ R_API char *r_bin_filter_name(RBinFile *bf, HtPU *db, ut64 vaddr, char *name) {
|
|||||||
resname = p;
|
resname = p;
|
||||||
}
|
}
|
||||||
// two symbols at different addresses and same name wtf
|
// two symbols at different addresses and same name wtf
|
||||||
R_LOG_DEBUG ("Found duplicated symbol '%s'", name);
|
R_LOG_DEBUG ("Found duplicated symbol '%s'", resname);
|
||||||
}
|
}
|
||||||
return resname;
|
return resname;
|
||||||
}
|
}
|
||||||
|
@ -785,7 +785,8 @@ R_API RList *r_bin_get_strings(RBin *bin) {
|
|||||||
return o ? o->strings : NULL;
|
return o ? o->strings : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_bin_is_string(RBin *bin, ut64 va) {
|
// XXX R2_590 this is super slow - remove this function because is used 1 time and from core and we can use rflags for this
|
||||||
|
R_API bool r_bin_is_string(RBin *bin, ut64 va) {
|
||||||
RBinString *string;
|
RBinString *string;
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
RList *list = r_bin_get_strings (bin);
|
RList *list = r_bin_get_strings (bin);
|
||||||
|
@ -5,9 +5,7 @@
|
|||||||
#define LOOP_MAX 10
|
#define LOOP_MAX 10
|
||||||
|
|
||||||
static bool anal_emul_init(RCore *core, RConfigHold *hc, RDebugTrace **dt, REsilTrace **et) {
|
static bool anal_emul_init(RCore *core, RConfigHold *hc, RDebugTrace **dt, REsilTrace **et) {
|
||||||
if (!core->anal->esil) {
|
r_return_val_if_fail (core && core->anal && core->anal->esil, false);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*dt = core->dbg->trace;
|
*dt = core->dbg->trace;
|
||||||
*et = core->anal->esil->trace;
|
*et = core->anal->esil->trace;
|
||||||
core->dbg->trace = r_debug_trace_new ();
|
core->dbg->trace = r_debug_trace_new ();
|
||||||
@ -456,55 +454,6 @@ static int bb_cmpaddr(const void *_a, const void *_b) {
|
|||||||
return a->addr > b->addr ? 1 : (a->addr < b->addr ? -1 : 0);
|
return a->addr > b->addr ? 1 : (a->addr < b->addr ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SLOW_STEP 1
|
|
||||||
static bool fast_step(RCore *core, RAnalOp *aop) {
|
|
||||||
#if SLOW_STEP
|
|
||||||
return r_core_esil_step (core, UT64_MAX, NULL, NULL, false);
|
|
||||||
#else
|
|
||||||
REsil *esil = core->anal->esil;
|
|
||||||
const char *e = R_STRBUF_SAFEGET (&aop->esil);
|
|
||||||
if (R_STR_ISEMPTY (e)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!esil) {
|
|
||||||
r_core_cmd_call (core, "aei");
|
|
||||||
// addr = initializeEsil (core);
|
|
||||||
esil = core->anal->esil;
|
|
||||||
if (!esil) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
esil->trap = 0;
|
|
||||||
//eprintf ("PC=0x%"PFMT64x"\n", (ut64)addr);
|
|
||||||
}
|
|
||||||
// const char *name = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
|
||||||
// ut64 addr = r_reg_getv (core->anal->reg, name);
|
|
||||||
int ret = (aop->type == R_ANAL_OP_TYPE_ILL) ? -1: aop->size;
|
|
||||||
// TODO: sometimes this is dupe
|
|
||||||
// if type is JMP then we execute the next N instructions
|
|
||||||
// update the esil pointer because RAnal.op() can change it
|
|
||||||
esil = core->anal->esil;
|
|
||||||
if (aop->size < 1 || ret < 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// r_esil_parse (esil, e);
|
|
||||||
#if 1
|
|
||||||
RReg *reg = core->dbg->reg;
|
|
||||||
core->dbg->reg = core->anal->reg;
|
|
||||||
r_esil_set_pc (esil, aop->addr);
|
|
||||||
r_debug_trace_op (core->dbg, aop); // calls esil.parse() internally
|
|
||||||
core->dbg->reg = reg;
|
|
||||||
#else
|
|
||||||
r_debug_trace_op (core->dbg, aop); // calls esil.parse() internally
|
|
||||||
#endif
|
|
||||||
// select next instruction
|
|
||||||
const char *pcname = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
|
||||||
r_reg_setv (core->anal->reg, pcname, aop->addr + aop->size);
|
|
||||||
r_esil_stack_free (esil);
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) {
|
R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) {
|
||||||
const int op_tions = R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_VAL | R_ARCH_OP_MASK_ESIL | R_ARCH_OP_MASK_HINT;
|
const int op_tions = R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_VAL | R_ARCH_OP_MASK_ESIL | R_ARCH_OP_MASK_HINT;
|
||||||
RAnalBlock *bb;
|
RAnalBlock *bb;
|
||||||
@ -514,11 +463,6 @@ R_API void r_core_anal_type_match(RCore *core, RAnalFunction *fcn) {
|
|||||||
|
|
||||||
r_return_if_fail (core && core->anal && fcn);
|
r_return_if_fail (core && core->anal && fcn);
|
||||||
|
|
||||||
if (!core->anal->esil) {
|
|
||||||
R_LOG_WARN ("Please run aeim");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RAnal *anal = core->anal;
|
RAnal *anal = core->anal;
|
||||||
Sdb *TDB = anal->sdb_types;
|
Sdb *TDB = anal->sdb_types;
|
||||||
bool chk_constraint = r_config_get_b (core->config, "anal.types.constraint");
|
bool chk_constraint = r_config_get_b (core->config, "anal.types.constraint");
|
||||||
@ -629,7 +573,7 @@ repeat:
|
|||||||
// just analyze statically the instruction if its a call, dont emulate it
|
// just analyze statically the instruction if its a call, dont emulate it
|
||||||
r_reg_setv (core->dbg->reg, pc, addr + ret);
|
r_reg_setv (core->dbg->reg, pc, addr + ret);
|
||||||
} else {
|
} else {
|
||||||
fast_step (core, &aop);
|
r_core_esil_step (core, UT64_MAX, NULL, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybe the basic block is gone after the step...
|
// maybe the basic block is gone after the step...
|
||||||
|
@ -3685,20 +3685,11 @@ static bool anal_block_cb(RAnalBlock *bb, BlockRecurseCtx *ctx) {
|
|||||||
if (r_cons_is_breaked ()) {
|
if (r_cons_is_breaked ()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
RAnalOp *hop = r_core_anal_op (core, opaddr, mask);
|
|
||||||
if (!hop) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
memcpy (&op, hop, sizeof (RAnalOp));
|
|
||||||
free (hop);
|
|
||||||
#else
|
|
||||||
pos = (opaddr - bb->addr);
|
pos = (opaddr - bb->addr);
|
||||||
if (r_anal_op (core->anal, &op, opaddr, buf + pos, bb->size - pos, mask) < 1) {
|
if (r_anal_op (core->anal, &op, opaddr, buf + pos, bb->size - pos, mask) < 1) {
|
||||||
r_anal_op_fini (&op);
|
r_anal_op_fini (&op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
r_anal_extract_rarg (core->anal, &op, fcn, reg_set, &ctx->count);
|
r_anal_extract_rarg (core->anal, &op, fcn, reg_set, &ctx->count);
|
||||||
if (!ctx->argonly) {
|
if (!ctx->argonly) {
|
||||||
if (op.stackop == R_ANAL_STACK_INC) {
|
if (op.stackop == R_ANAL_STACK_INC) {
|
||||||
@ -5241,7 +5232,7 @@ static bool esilbreak_reg_write(REsil *esil, const char *name, ut64 *val) {
|
|||||||
switch (op->type) {
|
switch (op->type) {
|
||||||
case R_ANAL_OP_TYPE_UCALL: // BLX
|
case R_ANAL_OP_TYPE_UCALL: // BLX
|
||||||
case R_ANAL_OP_TYPE_UJMP: // BX
|
case R_ANAL_OP_TYPE_UJMP: // BX
|
||||||
// maybe UJMP/UCALL is enough here
|
// R2_590 - maybe UJMP/UCALL is enough here
|
||||||
if (!(*val & 1)) {
|
if (!(*val & 1)) {
|
||||||
r_anal_hint_set_bits (anal, *val, 32);
|
r_anal_hint_set_bits (anal, *val, 32);
|
||||||
} else {
|
} else {
|
||||||
@ -5570,16 +5561,7 @@ R_API void r_core_anal_esil(RCore *core, const char *str /* len */, const char *
|
|||||||
}
|
}
|
||||||
esilbreak_last_read = UT64_MAX;
|
esilbreak_last_read = UT64_MAX;
|
||||||
r_io_read_at (core->io, start, buf, iend + 1);
|
r_io_read_at (core->io, start, buf, iend + 1);
|
||||||
if (!ESIL) {
|
// maybe r_core_cmd_call (core, "aeim");
|
||||||
r_core_cmd_call (core, "aei");
|
|
||||||
ESIL = core->anal->esil;
|
|
||||||
if (!ESIL) {
|
|
||||||
R_LOG_ERROR ("ESIL is not initialized");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r_core_cmd_call (core, "aeim");
|
|
||||||
ESIL = core->anal->esil;
|
|
||||||
}
|
|
||||||
const char *kspname = r_reg_get_name (core->anal->reg, R_REG_NAME_SP);
|
const char *kspname = r_reg_get_name (core->anal->reg, R_REG_NAME_SP);
|
||||||
if (R_STR_ISEMPTY (kspname)) {
|
if (R_STR_ISEMPTY (kspname)) {
|
||||||
R_LOG_ERROR ("No =SP defined in the reg profile");
|
R_LOG_ERROR ("No =SP defined in the reg profile");
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* radare - LGPL - Copyright 2009-2022 - pancake */
|
/* radare - LGPL - Copyright 2009-2023 - pancake */
|
||||||
|
|
||||||
#define R_LOG_ORIGIN "cfile"
|
#define R_LOG_ORIGIN "cfile"
|
||||||
#include <r_core.h>
|
#include <r_core.h>
|
||||||
@ -34,14 +34,18 @@ static bool its_a_mips(RCore *core) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void loadGP(RCore *core) {
|
static void loadGP(RCore *core) {
|
||||||
|
// R2R db/cmd/cmd_eval
|
||||||
if (its_a_mips (core)) {
|
if (its_a_mips (core)) {
|
||||||
ut64 e0 = r_num_math (core->num, "entry0");
|
ut64 e0 = r_num_math (core->num, "entry0");
|
||||||
ut64 gp = r_num_math (core->num, "loc._gp");
|
ut64 gp = r_num_math (core->num, "loc._gp");
|
||||||
if ((!gp || gp == UT64_MAX) && (e0 && e0 != UT64_MAX)) {
|
if ((!gp || gp == UT64_MAX) && (e0 && e0 != UT64_MAX)) {
|
||||||
r_config_set (core->config, "anal.roregs", "zero");
|
r_core_cmd0 (core, "aeim; s entry0;dr PC=entry0");
|
||||||
r_core_cmd0 (core, "10aes@entry0");
|
r_config_set (core->config, "anal.roregs", "zero"); // gp is writable here
|
||||||
r_config_set (core->config, "anal.roregs", "zero,gp");
|
r_core_cmd0 (core, "10aes");
|
||||||
gp = r_reg_getv (core->anal->reg, "gp");
|
gp = r_reg_getv (core->anal->reg, "gp");
|
||||||
|
r_core_cmd0 (core, "dr0;aeim");
|
||||||
|
r_reg_setv (core->anal->reg, "gp", gp);
|
||||||
|
r_config_set (core->config, "anal.roregs", "zero,gp");
|
||||||
}
|
}
|
||||||
R_LOG_DEBUG ("[mips] gp: 0x%08"PFMT64x, gp);
|
R_LOG_DEBUG ("[mips] gp: 0x%08"PFMT64x, gp);
|
||||||
r_config_set_i (core->config, "anal.gp", gp);
|
r_config_set_i (core->config, "anal.gp", gp);
|
||||||
@ -867,6 +871,7 @@ R_API RIODesc *r_core_file_open_many(RCore *r, const char *file, int perm, ut64
|
|||||||
const int pillow = 0x4000;
|
const int pillow = 0x4000;
|
||||||
loadaddr += sz + rest + pillow;
|
loadaddr += sz + rest + pillow;
|
||||||
}
|
}
|
||||||
|
r_esil_setup (r->anal->esil, r->anal, 0, 0, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return first;
|
return first;
|
||||||
@ -921,6 +926,7 @@ R_API RIODesc *r_core_file_open(RCore *r, const char *file, int flags, ut64 load
|
|||||||
|
|
||||||
r_io_use_fd (r->io, fd->fd);
|
r_io_use_fd (r->io, fd->fd);
|
||||||
|
|
||||||
|
r_esil_setup (r->anal->esil, r->anal, 0, 0, false);
|
||||||
if (r_config_get_b (r->config, "cfg.debug")) {
|
if (r_config_get_b (r->config, "cfg.debug")) {
|
||||||
bool swstep = true;
|
bool swstep = true;
|
||||||
if (r->dbg->current && r->dbg->current->plugin.canstep) {
|
if (r->dbg->current && r->dbg->current->plugin.canstep) {
|
||||||
|
@ -2205,15 +2205,21 @@ static void cmd_syscall_do(RCore *core, st64 n, ut64 addr) {
|
|||||||
|
|
||||||
static inline REsil *esil_new_setup(RCore *core) {
|
static inline REsil *esil_new_setup(RCore *core) {
|
||||||
int stacksize = r_config_get_i (core->config, "esil.stack.depth");
|
int stacksize = r_config_get_i (core->config, "esil.stack.depth");
|
||||||
int iotrap = r_config_get_i (core->config, "esil.iotrap");
|
bool iotrap = r_config_get_b (core->config, "esil.iotrap");
|
||||||
unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size");
|
unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size");
|
||||||
REsil *esil = r_esil_new (stacksize, iotrap, addrsize);
|
REsil *esil = r_esil_new (stacksize, iotrap, addrsize);
|
||||||
if (esil) {
|
if (esil) {
|
||||||
int romem = r_config_get_i (core->config, "esil.romem");
|
esil->anal = core->anal;
|
||||||
int stats = r_config_get_i (core->config, "esil.stats");
|
r_io_bind (core->io, &(core->anal->iob));
|
||||||
|
bool romem = r_config_get_b (core->config, "esil.romem");
|
||||||
|
bool stats = r_config_get_b (core->config, "esil.stats");
|
||||||
bool nonull = r_config_get_b (core->config, "esil.nonull");
|
bool nonull = r_config_get_b (core->config, "esil.nonull");
|
||||||
r_esil_setup (esil, core->anal, romem, stats, nonull);
|
r_esil_setup (esil, core->anal, romem, stats, nonull);
|
||||||
esil->verbose = r_config_get_i (core->config, "esil.verbose");
|
esil->verbose = r_config_get_i (core->config, "esil.verbose");
|
||||||
|
esil->cmd = r_core_esil_cmd;
|
||||||
|
const char *et = r_config_get (core->config, "cmd.esil.trap");
|
||||||
|
esil->cmd_trap = R_STR_ISNOTEMPTY (et)? strdup (et): NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
return esil;
|
return esil;
|
||||||
}
|
}
|
||||||
@ -2275,14 +2281,17 @@ static void core_anal_bytes(RCore *core, const ut8 *buf, int len, int nops, int
|
|||||||
ut64 addr;
|
ut64 addr;
|
||||||
PJ *pj = NULL;
|
PJ *pj = NULL;
|
||||||
int totalsize = 0;
|
int totalsize = 0;
|
||||||
#if 0
|
#if 1
|
||||||
REsil *esil = r_esil_new (256, 0, 0);
|
REsil *esil = r_esil_new (256, 0, 0);
|
||||||
r_esil_setup (esil, core->anal, false, false, false);
|
r_esil_setup (esil, core->anal, false, false, false);
|
||||||
esil->user = &ec;
|
esil->user = &core;
|
||||||
esil->cb.mem_read = mr;
|
esil->cb.mem_read = mr;
|
||||||
esil->cb.mem_write = mw;
|
esil->cb.mem_write = mw;
|
||||||
#else
|
#else
|
||||||
REsil *esil = NULL;
|
REsil *esil = core->anal->esil;
|
||||||
|
//esil->user = &ec;
|
||||||
|
esil->cb.mem_read = mr;
|
||||||
|
esil->cb.mem_write = mw;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Variables required for setting up ESIL to REIL conversion
|
// Variables required for setting up ESIL to REIL conversion
|
||||||
@ -2542,21 +2551,14 @@ static void core_anal_bytes(RCore *core, const ut8 *buf, int len, int nops, int
|
|||||||
pj_end (pj);
|
pj_end (pj);
|
||||||
} else if (fmt == 'r') {
|
} else if (fmt == 'r') {
|
||||||
if (R_STR_ISNOTEMPTY (esilstr)) {
|
if (R_STR_ISNOTEMPTY (esilstr)) {
|
||||||
if (core->anal->esil) {
|
|
||||||
if (use_color) {
|
if (use_color) {
|
||||||
r_cons_printf ("%s0x%" PFMT64x Color_RESET " %s\n", color, core->offset + idx, esilstr);
|
r_cons_printf ("%s0x%" PFMT64x Color_RESET " %s\n", color, core->offset + idx, esilstr);
|
||||||
} else {
|
} else {
|
||||||
r_cons_printf ("0x%" PFMT64x " %s\n", core->offset + idx, esilstr);
|
r_cons_printf ("0x%" PFMT64x " %s\n", core->offset + idx, esilstr);
|
||||||
}
|
}
|
||||||
esil = core->anal->esil;
|
r_esil_parse (core->anal->esil, esilstr);
|
||||||
r_esil_parse (esil, esilstr);
|
r_esil_dumpstack (core->anal->esil);
|
||||||
r_esil_dumpstack (esil);
|
r_esil_stack_free (core->anal->esil);
|
||||||
r_esil_stack_free (esil);
|
|
||||||
esil = NULL;
|
|
||||||
} else {
|
|
||||||
R_LOG_ERROR ("ESIL is not initialized. Run `aei`");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// ignored/skipped eprintf ("No esil for '%s'\n", op.mnemonic);
|
// ignored/skipped eprintf ("No esil for '%s'\n", op.mnemonic);
|
||||||
}
|
}
|
||||||
@ -5907,50 +5909,6 @@ void cmd_anal_reg(RCore *core, const char *str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ut64 initializeEsil(RCore *core) {
|
|
||||||
int exectrap = r_config_get_i (core->config, "esil.exectrap");
|
|
||||||
REsil *esil = esil_new_setup (core);
|
|
||||||
if (esil) {
|
|
||||||
r_esil_free (core->anal->esil);
|
|
||||||
core->anal->esil = esil;
|
|
||||||
} else {
|
|
||||||
return UT64_MAX;
|
|
||||||
}
|
|
||||||
ut64 addr;
|
|
||||||
esil->cmd = r_core_esil_cmd;
|
|
||||||
{
|
|
||||||
const char *cmd_esil_step = r_config_get (core->config, "cmd.esil.step");
|
|
||||||
if (cmd_esil_step && *cmd_esil_step) {
|
|
||||||
esil->cmd_step = strdup (cmd_esil_step);
|
|
||||||
}
|
|
||||||
const char *cmd_esil_step_out = r_config_get (core->config, "cmd.esil.stepout");
|
|
||||||
if (cmd_esil_step_out && *cmd_esil_step_out) {
|
|
||||||
esil->cmd_step_out = strdup (cmd_esil_step_out);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const char *s = r_config_get (core->config, "cmd.esil.intr");
|
|
||||||
if (s) {
|
|
||||||
char *my = strdup (s);
|
|
||||||
if (my) {
|
|
||||||
r_config_set (core->config, "cmd.esil.intr", my);
|
|
||||||
free (my);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
esil->exectrap = exectrap;
|
|
||||||
const RList *entries = r_bin_get_entries (core->bin);
|
|
||||||
if (entries && !r_list_empty (entries)) {
|
|
||||||
RBinAddr *entry = (RBinAddr *)r_list_get_n (entries, 0);
|
|
||||||
RBinInfo *info = r_bin_get_info (core->bin);
|
|
||||||
addr = info->has_va? entry->vaddr: entry->paddr;
|
|
||||||
} else {
|
|
||||||
addr = core->offset;
|
|
||||||
}
|
|
||||||
// set memory read only
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver) {
|
R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver) {
|
||||||
#define return_tail(x) { tail_return_value = x; goto tail_return; }
|
#define return_tail(x) { tail_return_value = x; goto tail_return; }
|
||||||
int tail_return_value = 0;
|
int tail_return_value = 0;
|
||||||
@ -5958,13 +5916,13 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
ut8 code[32];
|
ut8 code[32];
|
||||||
RAnalOp op = {0};
|
RAnalOp op = {0};
|
||||||
REsil *esil = core->anal->esil;
|
REsil *esil = core->anal->esil;
|
||||||
|
// esil->trap = 0;
|
||||||
const char *_pcname = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
const char *_pcname = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
||||||
if (R_STR_ISEMPTY (_pcname)) {
|
if (R_STR_ISEMPTY (_pcname)) {
|
||||||
R_LOG_ERROR ("Cannot find =PC in current reg profile");
|
R_LOG_ERROR ("Cannot find =PC in current reg profile");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
char *pcname = strdup (_pcname);
|
char *pcname = strdup (_pcname);
|
||||||
ut64 addr = r_reg_getv (core->anal->reg, pcname);
|
|
||||||
const bool r2wars = r_config_get_b (core->config, "cfg.r2wars");
|
const bool r2wars = r_config_get_b (core->config, "cfg.r2wars");
|
||||||
const bool breakoninvalid = r_config_get_b (core->config, "esil.breakoninvalid");
|
const bool breakoninvalid = r_config_get_b (core->config, "esil.breakoninvalid");
|
||||||
const int esiltimeout = r_config_get_i (core->config, "esil.timeout");
|
const int esiltimeout = r_config_get_i (core->config, "esil.timeout");
|
||||||
@ -5974,13 +5932,27 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
startTime = r_time_now_mono ();
|
startTime = r_time_now_mono ();
|
||||||
}
|
}
|
||||||
r_cons_break_push (NULL, NULL);
|
r_cons_break_push (NULL, NULL);
|
||||||
|
ut64 addr = -1;
|
||||||
|
ut64 oaddr = -1;
|
||||||
|
int minopsz = r_arch_info (core->anal->arch, R_ARCH_INFO_MIN_OP_SIZE);
|
||||||
|
ut64 naddr = addr + minopsz;
|
||||||
|
bool notfirst = false;
|
||||||
for (; true; r_anal_op_fini (&op)) {
|
for (; true; r_anal_op_fini (&op)) {
|
||||||
|
esil->trap = 0;
|
||||||
|
oaddr = addr;
|
||||||
|
addr = r_reg_getv (core->anal->reg, "PC");
|
||||||
|
if (notfirst && addr == oaddr) {
|
||||||
|
r_reg_setv (core->anal->reg, "PC", naddr);
|
||||||
|
addr = naddr;
|
||||||
|
} else {
|
||||||
|
notfirst = true;
|
||||||
|
}
|
||||||
R_LOG_DEBUG ("esil step at 0x%08"PFMT64x, addr);
|
R_LOG_DEBUG ("esil step at 0x%08"PFMT64x, addr);
|
||||||
if (r_cons_is_breaked ()) {
|
if (r_cons_is_breaked ()) {
|
||||||
R_LOG_INFO ("[+] ESIL emulation interrupted at 0x%08" PFMT64x, addr);
|
R_LOG_INFO ("[+] ESIL emulation interrupted at 0x%08" PFMT64x, addr);
|
||||||
return_tail (0);
|
return_tail (0);
|
||||||
}
|
}
|
||||||
//Break if we have exceeded esil.timeout
|
// Break if we have exceeded esil.timeout
|
||||||
if (esiltimeout > 0) {
|
if (esiltimeout > 0) {
|
||||||
ut64 elapsedTime = r_time_now_mono () - startTime;
|
ut64 elapsedTime = r_time_now_mono () - startTime;
|
||||||
elapsedTime >>= 20;
|
elapsedTime >>= 20;
|
||||||
@ -5989,34 +5961,17 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
return_tail (0);
|
return_tail (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!esil) {
|
|
||||||
addr = initializeEsil (core);
|
|
||||||
esil = core->anal->esil;
|
|
||||||
if (!esil) {
|
|
||||||
return_tail (0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
esil->trap = 0;
|
|
||||||
addr = r_reg_getv (core->anal->reg, pcname);
|
|
||||||
}
|
|
||||||
if (prev_addr) {
|
if (prev_addr) {
|
||||||
*prev_addr = addr;
|
*prev_addr = addr;
|
||||||
}
|
}
|
||||||
if (esil->exectrap) {
|
const int perm = esil->exectrap ? R_PERM_X: 0;
|
||||||
if (!r_io_is_valid_offset (core->io, addr, R_PERM_X)) {
|
if (!r_io_is_valid_offset (core->io, addr, perm)) {
|
||||||
esil->trap = R_ANAL_TRAP_EXEC_ERR;
|
esil->trap = R_ANAL_TRAP_EXEC_ERR;
|
||||||
esil->trap_code = addr;
|
esil->trap_code = addr;
|
||||||
R_LOG_INFO ("[ESIL] Trap, trying to execute on non-executable memory");
|
R_LOG_INFO ("[ESIL] Trap, trying to execute on non-executable memory");
|
||||||
return_tail (1);
|
return_tail (1);
|
||||||
}
|
}
|
||||||
} else {
|
// eprintf ("addr %llx\n", addr);
|
||||||
if (!r_io_is_valid_offset (core->io, addr, 0)) {
|
|
||||||
esil->trap = R_ANAL_TRAP_EXEC_ERR;
|
|
||||||
esil->trap_code = addr;
|
|
||||||
R_LOG_INFO ("[ESIL] Trap, trying to execute on non-executable memory");
|
|
||||||
return_tail (1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_asm_set_pc (core->rasm, addr);
|
r_asm_set_pc (core->rasm, addr);
|
||||||
// run esil pin command here
|
// run esil pin command here
|
||||||
const char *pincmd = r_anal_pin_call (core->anal, addr);
|
const char *pincmd = r_anal_pin_call (core->anal, addr);
|
||||||
@ -6024,14 +5979,14 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
r_core_cmd0 (core, pincmd);
|
r_core_cmd0 (core, pincmd);
|
||||||
ut64 pc = r_reg_getv (core->anal->reg, pcname);
|
ut64 pc = r_reg_getv (core->anal->reg, pcname);
|
||||||
if (addr != pc) {
|
if (addr != pc) {
|
||||||
eprintf ("pincmd fail\n");
|
R_LOG_ERROR ("pincmd fail");
|
||||||
return_tail (1);
|
return_tail (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int dataAlign = r_anal_archinfo (esil->anal, R_ANAL_ARCHINFO_DATA_ALIGN);
|
int dataAlign = r_anal_archinfo (esil->anal, R_ANAL_ARCHINFO_DATA_ALIGN);
|
||||||
if (dataAlign > 1) {
|
if (dataAlign > 1) {
|
||||||
if (addr % dataAlign) {
|
if (addr % dataAlign) {
|
||||||
if (esil->cmd && esil->cmd_trap) {
|
if (esil->cmd && R_STR_ISNOTEMPTY (esil->cmd_trap)) {
|
||||||
esil->cmd (esil, esil->cmd_trap, addr, R_ANAL_TRAP_UNALIGNED);
|
esil->cmd (esil, esil->cmd_trap, addr, R_ANAL_TRAP_UNALIGNED);
|
||||||
}
|
}
|
||||||
if (breakoninvalid) {
|
if (breakoninvalid) {
|
||||||
@ -6043,19 +5998,23 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
(void) r_io_read_at (core->io, addr, code, sizeof (code));
|
(void) r_io_read_at (core->io, addr, code, sizeof (code));
|
||||||
// TODO: sometimes this is dupe
|
// TODO: sometimes this is dupe
|
||||||
ret = r_anal_op (core->anal, &op, addr, code, sizeof (code), R_ARCH_OP_MASK_ESIL | R_ARCH_OP_MASK_HINT);
|
ret = r_anal_op (core->anal, &op, addr, code, sizeof (code), R_ARCH_OP_MASK_ESIL | R_ARCH_OP_MASK_HINT);
|
||||||
|
naddr = addr + op.size;
|
||||||
// if type is JMP then we execute the next N instructions
|
// if type is JMP then we execute the next N instructions
|
||||||
// update the esil pointer because RAnal.op() can change it
|
// update the esil pointer because RAnal.op() can change it
|
||||||
esil = core->anal->esil;
|
esil = core->anal->esil;
|
||||||
if (op.size < 1 || ret < 1) {
|
if (op.size < 1 || ret < 1) {
|
||||||
if (esil->cmd && esil->cmd_trap) {
|
// eprintf ("esil trap\n");
|
||||||
|
if (esil->cmd && R_STR_ISNOTEMPTY (esil->cmd_trap)) {
|
||||||
esil->cmd (esil, esil->cmd_trap, addr, R_ANAL_TRAP_INVALID);
|
esil->cmd (esil, esil->cmd_trap, addr, R_ANAL_TRAP_INVALID);
|
||||||
}
|
}
|
||||||
if (breakoninvalid) {
|
if (breakoninvalid) {
|
||||||
R_LOG_INFO ("Stopped execution in an invalid instruction (see e??esil.breakoninvalid)");
|
R_LOG_INFO ("Stopped execution in an invalid instruction (see e??esil.breakoninvalid)");
|
||||||
return_tail (0);
|
return_tail (0);
|
||||||
}
|
}
|
||||||
|
if (op.size < 1) {
|
||||||
op.size = 1; // avoid inverted stepping
|
op.size = 1; // avoid inverted stepping
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (stepOver) {
|
if (stepOver) {
|
||||||
switch (op.type) {
|
switch (op.type) {
|
||||||
case R_ANAL_OP_TYPE_SWI:
|
case R_ANAL_OP_TYPE_SWI:
|
||||||
@ -6074,7 +6033,6 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
r_reg_setv (core->anal->reg, pcname, op.addr + op.size);
|
r_reg_setv (core->anal->reg, pcname, op.addr + op.size);
|
||||||
r_reg_setv (core->dbg->reg, pcname, op.addr + op.size);
|
r_reg_setv (core->dbg->reg, pcname, op.addr + op.size);
|
||||||
}
|
}
|
||||||
eprintf ("blaaa\n");
|
|
||||||
return_tail (1);
|
return_tail (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6107,7 +6065,8 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
} else if (R_STR_ISNOTEMPTY (e)) {
|
} else if (R_STR_ISNOTEMPTY (e)) {
|
||||||
r_esil_parse (esil, e);
|
r_esil_parse (esil, e);
|
||||||
if (esil->trap) {
|
if (esil->trap) {
|
||||||
R_LOG_WARN ("ESIL TRAP ON %s at 0x%08"PFMT64x, e,addr );
|
R_LOG_WARN ("ESIL TRAP %d/%d ON %s at 0x%08"PFMT64x,
|
||||||
|
esil->trap, esil->trap_code, e, addr);
|
||||||
if (r_config_get_b (core->config, "esil.exectrap")) {
|
if (r_config_get_b (core->config, "esil.exectrap")) {
|
||||||
R_LOG_INFO ("ESIL TRAP ignored");
|
R_LOG_INFO ("ESIL TRAP ignored");
|
||||||
esil->trap = false;
|
esil->trap = false;
|
||||||
@ -6119,6 +6078,7 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
core->anal->cur->esil_post_loop (esil, &op);
|
core->anal->cur->esil_post_loop (esil, &op);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// warn if esil stack is not empty
|
||||||
r_esil_stack_free (esil);
|
r_esil_stack_free (esil);
|
||||||
}
|
}
|
||||||
bool isNextFall = false;
|
bool isNextFall = false;
|
||||||
@ -6137,7 +6097,7 @@ R_API int r_core_esil_step(RCore *core, ut64 until_addr, const char *until_expr,
|
|||||||
// only support 1 slot for now
|
// only support 1 slot for now
|
||||||
if (op.delay && !isNextFall) {
|
if (op.delay && !isNextFall) {
|
||||||
ut8 code2[32];
|
ut8 code2[32];
|
||||||
ut64 naddr = addr + op.size;
|
// ut64 naddr = addr + op.size;
|
||||||
RAnalOp op2 = {0};
|
RAnalOp op2 = {0};
|
||||||
// emulate only 1 instruction
|
// emulate only 1 instruction
|
||||||
r_esil_set_pc (esil, naddr);
|
r_esil_set_pc (esil, naddr);
|
||||||
@ -6225,12 +6185,14 @@ tail_return:
|
|||||||
|
|
||||||
R_API bool r_core_esil_step_back(RCore *core) {
|
R_API bool r_core_esil_step_back(RCore *core) {
|
||||||
r_return_val_if_fail (core && core->anal, false);
|
r_return_val_if_fail (core && core->anal, false);
|
||||||
|
#if 0
|
||||||
if (!core->anal->esil || !core->anal->esil->trace) {
|
if (!core->anal->esil || !core->anal->esil->trace) {
|
||||||
R_LOG_INFO ("Run `aeim` to initialize the esil VM and enable e dbg.trace=true");
|
R_LOG_INFO ("Run `aeim` to initialize the esil VM and enable e dbg.trace=true");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
REsil *esil = core->anal->esil;
|
REsil *esil = core->anal->esil;
|
||||||
if (esil->trace->idx > 0) {
|
if (esil && esil->trace->idx > 0) {
|
||||||
r_esil_trace_restore (esil, esil->trace->idx - 1);
|
r_esil_trace_restore (esil, esil->trace->idx - 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -6440,28 +6402,14 @@ static void cmd_esil_mem(RCore *core, const char *input) {
|
|||||||
RFlagItem *fi;
|
RFlagItem *fi;
|
||||||
char uri[32];
|
char uri[32];
|
||||||
char nomalloc[256];
|
char nomalloc[256];
|
||||||
if (!esil) {
|
|
||||||
esil = esil_new_setup (core);
|
|
||||||
if (!esil) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r_esil_free (core->anal->esil);
|
|
||||||
core->anal->esil = esil;
|
|
||||||
{
|
|
||||||
const char *s = r_config_get (core->config, "cmd.esil.intr");
|
|
||||||
if (s) {
|
|
||||||
char *my = strdup (s);
|
|
||||||
if (my) {
|
|
||||||
r_config_set (core->config, "cmd.esil.intr", my);
|
|
||||||
free (my);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (*input == '?') {
|
if (*input == '?') {
|
||||||
r_core_cmd_help (core, help_msg_aeim);
|
r_core_cmd_help (core, help_msg_aeim);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (r_config_get_b (core->config, "cfg.debug")) {
|
||||||
|
R_LOG_WARN ("When cfg.debug is set, I refuse to create a fake stack");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (input[0] == 'p') {
|
if (input[0] == 'p') {
|
||||||
fi = r_flag_get (core->flags, "aeim.stack");
|
fi = r_flag_get (core->flags, "aeim.stack");
|
||||||
@ -6519,7 +6467,7 @@ static void cmd_esil_mem(RCore *core, const char *input) {
|
|||||||
name = r_str_newf ("mem.0x%" PFMT64x "_0x%x", addr, size);
|
name = r_str_newf ("mem.0x%" PFMT64x "_0x%x", addr, size);
|
||||||
}
|
}
|
||||||
if (*input == '-') {
|
if (*input == '-') {
|
||||||
if (esil->stack_fd > 2) { //0, 1, 2 are reserved for stdio/stderr
|
if (esil->stack_fd > 2) { // 0, 1, 2 are reserved for stdio/stderr
|
||||||
r_io_fd_close (core->io, esil->stack_fd);
|
r_io_fd_close (core->io, esil->stack_fd);
|
||||||
// no need to kill the maps, r_io_map_cleanup does that for us in the close
|
// no need to kill the maps, r_io_map_cleanup does that for us in the close
|
||||||
esil->stack_fd = 0;
|
esil->stack_fd = 0;
|
||||||
@ -6577,37 +6525,6 @@ static void cmd_esil_mem(RCore *core, const char *input) {
|
|||||||
r_core_seek (core, curoff, false);
|
r_core_seek (core, curoff, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static ut64 opc = UT64_MAX;
|
|
||||||
static ut8 *regstate = NULL;
|
|
||||||
|
|
||||||
static void esil_init(RCore *core) {
|
|
||||||
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
|
||||||
int nonull = r_config_get_i (core->config, "esil.nonull");
|
|
||||||
opc = r_reg_getv (core->anal->reg, pc);
|
|
||||||
if (!opc || opc==UT64_MAX) {
|
|
||||||
opc = core->offset;
|
|
||||||
}
|
|
||||||
if (!core->anal->esil) {
|
|
||||||
core->anal->esil = esil_new_from_core (core);
|
|
||||||
if (!core->anal->esil) {
|
|
||||||
R_FREE (regstate);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r_esil_setup (core->anal->esil, core->anal, 0, 0, nonull);
|
|
||||||
}
|
|
||||||
free (regstate);
|
|
||||||
regstate = r_reg_arena_peek (core->anal->reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void esil_fini(RCore *core) {
|
|
||||||
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
|
||||||
r_reg_arena_poke (core->anal->reg, regstate);
|
|
||||||
r_reg_setv (core->anal->reg, pc, opc);
|
|
||||||
R_FREE (regstate);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
RList *regs;
|
RList *regs;
|
||||||
RList *regread;
|
RList *regread;
|
||||||
@ -6986,27 +6903,30 @@ static bool cmd_aea(RCore* core, int mode, ut64 addr, int length) {
|
|||||||
static void cmd_aespc(RCore *core, ut64 addr, ut64 until_addr, int ninstr) {
|
static void cmd_aespc(RCore *core, ut64 addr, ut64 until_addr, int ninstr) {
|
||||||
REsil *esil = core->anal->esil;
|
REsil *esil = core->anal->esil;
|
||||||
int i, j = 0;
|
int i, j = 0;
|
||||||
ut8 *buf;
|
|
||||||
RAnalOp aop = {0};
|
RAnalOp aop = {0};
|
||||||
int ret , bsize = R_MAX (4096, core->blocksize);
|
int ret , bsize = R_MAX (4096, core->blocksize);
|
||||||
const int mininstrsz = r_anal_archinfo (core->anal, R_ANAL_ARCHINFO_MIN_OP_SIZE);
|
const int mininstrsz = r_anal_archinfo (core->anal, R_ANAL_ARCHINFO_MIN_OP_SIZE);
|
||||||
const int minopcode = R_MAX (1, mininstrsz);
|
const int minopcode = R_MAX (1, mininstrsz);
|
||||||
const char *pc = r_reg_get_name (core->dbg->reg, R_REG_NAME_PC);
|
const char *pc = r_reg_get_name (core->dbg->reg, R_REG_NAME_PC);
|
||||||
|
|
||||||
|
#if 0
|
||||||
// eprintf (" aesB %llx %llx %d\n", addr, until_addr, off); // 0x%08llx %d %s\n", aop.addr, ret, aop.mnemonic);
|
// eprintf (" aesB %llx %llx %d\n", addr, until_addr, off); // 0x%08llx %d %s\n", aop.addr, ret, aop.mnemonic);
|
||||||
if (!esil) {
|
if (!esil) {
|
||||||
R_LOG_DEBUG ("cmd_espc: creating new esil instance");
|
R_LOG_DEBUG ("cmd_espc: creating new esil instance");
|
||||||
core->anal->esil = esil = esil_new_setup (core);
|
esil = esil_new_setup (core);
|
||||||
if (!esil) {
|
if (!esil) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
r_esil_free (core->anal->esil);
|
||||||
|
core->anal->esil = esil;
|
||||||
}
|
}
|
||||||
buf = malloc (bsize);
|
#endif
|
||||||
|
ut8 *buf = malloc (bsize);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
R_LOG_ERROR ("Cannot allocate %d byte(s)", bsize);
|
R_LOG_ERROR ("Cannot allocate %d byte(s)", bsize);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (addr == -1) {
|
if (addr == UT64_MAX) {
|
||||||
addr = r_reg_getv (core->dbg->reg, pc);
|
addr = r_reg_getv (core->dbg->reg, pc);
|
||||||
}
|
}
|
||||||
ut64 cursp = r_reg_getv (core->dbg->reg, "SP");
|
ut64 cursp = r_reg_getv (core->dbg->reg, "SP");
|
||||||
@ -7223,9 +7143,13 @@ static bool regwrite_hook(REsil *esil, const char *name, ut64 *val) {
|
|||||||
static void __anal_esil_function(RCore *core, ut64 addr) {
|
static void __anal_esil_function(RCore *core, ut64 addr) {
|
||||||
RListIter *iter;
|
RListIter *iter;
|
||||||
RAnalBlock *bb;
|
RAnalBlock *bb;
|
||||||
|
#if 0
|
||||||
if (!core->anal->esil) {
|
if (!core->anal->esil) {
|
||||||
r_core_cmd_call (core, "aei");
|
r_core_cmd_call (core, "aei");
|
||||||
r_core_cmd_call (core, "aeim");
|
}
|
||||||
|
#endif
|
||||||
|
if (!sdb_const_get (core->sdb, "aeim.fd", 0)) {
|
||||||
|
r_core_cmd_call (core, "aeim"); // should be set by default imho
|
||||||
}
|
}
|
||||||
void *u = core->anal->esil->user;
|
void *u = core->anal->esil->user;
|
||||||
core->anal->esil->user = core;
|
core->anal->esil->user = core;
|
||||||
@ -7557,32 +7481,26 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) {
|
|||||||
// 'aer' is an alias for 'ar'
|
// 'aer' is an alias for 'ar'
|
||||||
cmd_anal_reg (core, input + 1);
|
cmd_anal_reg (core, input + 1);
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*': // "aeq"
|
||||||
// XXX: this is wip, not working atm
|
// XXX: this is wip, not working atm
|
||||||
if (core->anal->esil) {
|
|
||||||
r_cons_printf ("trap: %d\n", core->anal->esil->trap);
|
r_cons_printf ("trap: %d\n", core->anal->esil->trap);
|
||||||
r_cons_printf ("trap-code: %d\n", core->anal->esil->trap_code);
|
r_cons_printf ("trap-code: %d\n", core->anal->esil->trap_code);
|
||||||
} else {
|
|
||||||
R_LOG_WARN ("esil vm is not initialized. Please run `aei`");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
case 'q':
|
case 'q': // "aeq"
|
||||||
//r_esil_eval (core->anal, input + 1);
|
|
||||||
if (!esil) {
|
|
||||||
core->anal->esil = esil = esil_new_setup (core);
|
|
||||||
if (!esil) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_esil_set_pc (esil, core->offset);
|
r_esil_set_pc (esil, core->offset);
|
||||||
r_esil_parse (esil, input + 1);
|
r_esil_parse (esil, r_str_trim_head_ro (input + 1));
|
||||||
if (verbose && *input != 'q') {
|
if (verbose && *input != 'q') {
|
||||||
r_esil_dumpstack (esil);
|
r_esil_dumpstack (esil);
|
||||||
}
|
}
|
||||||
r_esil_stack_free (esil);
|
r_esil_stack_free (esil);
|
||||||
break;
|
break;
|
||||||
case 's': // "aes" "aeso" "aesu" "aesue"
|
case 's': // "aes" "aeso" "aesu" "aesue"
|
||||||
|
#if 0
|
||||||
|
r_core_cmd0 (core, "ae `aoe@r:PC`");
|
||||||
|
r_core_cmd0 (core, ".ar*");
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
// aes -> single step
|
// aes -> single step
|
||||||
// aesb -> single step back
|
// aesb -> single step back
|
||||||
// aeso -> single step over
|
// aeso -> single step over
|
||||||
@ -7852,20 +7770,14 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) {
|
|||||||
cmd_esil_mem (core, "?");
|
cmd_esil_mem (core, "?");
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
if (esil) {
|
r_esil_reset (esil);
|
||||||
sdb_reset (esil->stats);
|
|
||||||
}
|
|
||||||
r_esil_free (esil);
|
|
||||||
core->anal->esil = NULL;
|
|
||||||
break;
|
break;
|
||||||
case 0: // "aei"
|
case 0: // "aei"
|
||||||
r_esil_free (esil);
|
esil = esil_new_setup (core);
|
||||||
esil = core->anal->esil = esil_new_setup (core);
|
if (esil) {
|
||||||
if (!esil) {
|
r_esil_free (core->anal->esil);
|
||||||
return;
|
core->anal->esil = esil;
|
||||||
}
|
r_esil_reset (esil);
|
||||||
// reinitialize
|
|
||||||
{
|
|
||||||
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
|
||||||
if (pc && r_reg_getv (core->anal->reg, pc) == 0LL) {
|
if (pc && r_reg_getv (core->anal->reg, pc) == 0LL) {
|
||||||
reg_name_roll_set (core, "PC", core->offset);
|
reg_name_roll_set (core, "PC", core->offset);
|
||||||
@ -7979,10 +7891,12 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) {
|
|||||||
case 's': // "aets"
|
case 's': // "aets"
|
||||||
switch (input[2]) {
|
switch (input[2]) {
|
||||||
case '+': // "aets+"
|
case '+': // "aets+"
|
||||||
|
#if 0
|
||||||
if (!esil) {
|
if (!esil) {
|
||||||
R_LOG_ERROR ("ESIL is not initialized. Use `aeim` first");
|
R_LOG_ERROR ("ESIL is not initialized. Use `aeim` first");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (esil->trace) {
|
if (esil->trace) {
|
||||||
R_LOG_INFO ("ESIL trace already started");
|
R_LOG_INFO ("ESIL trace already started");
|
||||||
break;
|
break;
|
||||||
@ -12667,6 +12581,7 @@ static int cmd_anal_all(RCore *core, const char *input) {
|
|||||||
if (input[2] == '?') {
|
if (input[2] == '?') {
|
||||||
r_core_cmd_help_match (core, help_msg_aae, "aaef", true);
|
r_core_cmd_help_match (core, help_msg_aae, "aaef", true);
|
||||||
} else {
|
} else {
|
||||||
|
r_core_cmd0 (core, "aeim");
|
||||||
RListIter *it;
|
RListIter *it;
|
||||||
RAnalFunction *fcn;
|
RAnalFunction *fcn;
|
||||||
ut64 cur_seek = core->offset;
|
ut64 cur_seek = core->offset;
|
||||||
@ -12694,6 +12609,7 @@ static int cmd_anal_all(RCore *core, const char *input) {
|
|||||||
*addr = 0;
|
*addr = 0;
|
||||||
addr = (char *)r_str_trim_head_ro (addr + 1);
|
addr = (char *)r_str_trim_head_ro (addr + 1);
|
||||||
}
|
}
|
||||||
|
r_core_cmd0 (core, "aeim");
|
||||||
r_core_anal_esil (core, len, addr);
|
r_core_anal_esil (core, len, addr);
|
||||||
free (arg);
|
free (arg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -353,6 +353,7 @@ static RCoreHelpMessage help_msg_dr = {
|
|||||||
"dr", " <register>=<val>", "set register value",
|
"dr", " <register>=<val>", "set register value",
|
||||||
"dr.", " >$snapshot", "capture current register values in r2 alias file",
|
"dr.", " >$snapshot", "capture current register values in r2 alias file",
|
||||||
"dr,", " [table-query]", "enumerate registers in table format",
|
"dr,", " [table-query]", "enumerate registers in table format",
|
||||||
|
"dr0", "", "zero-fill the register arena, reset their state",
|
||||||
"dr8", "[1|2|4|8] [type]", "display hexdump of gpr arena (WIP)",
|
"dr8", "[1|2|4|8] [type]", "display hexdump of gpr arena (WIP)",
|
||||||
"dr=", "", "show registers in columns",
|
"dr=", "", "show registers in columns",
|
||||||
"dr?", "<register>", "show value of given register",
|
"dr?", "<register>", "show value of given register",
|
||||||
|
@ -4964,6 +4964,7 @@ static void ds_print_esil_anal_init(RDisasmState *ds) {
|
|||||||
if (!pc) {
|
if (!pc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
r_esil_setup (core->anal->esil, core->anal, 0, 0, 1);
|
||||||
ds->esil_old_pc = r_reg_getv (core->anal->reg, pc);
|
ds->esil_old_pc = r_reg_getv (core->anal->reg, pc);
|
||||||
if (!ds->esil_old_pc || ds->esil_old_pc == UT64_MAX) {
|
if (!ds->esil_old_pc || ds->esil_old_pc == UT64_MAX) {
|
||||||
ds->esil_old_pc = core->offset;
|
ds->esil_old_pc = core->offset;
|
||||||
@ -4972,17 +4973,6 @@ static void ds_print_esil_anal_init(RDisasmState *ds) {
|
|||||||
// XXX. stackptr not computed without asm.emu, when its not required
|
// XXX. stackptr not computed without asm.emu, when its not required
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!core->anal->esil) {
|
|
||||||
int iotrap = r_config_get_i (core->config, "esil.iotrap");
|
|
||||||
int esd = r_config_get_i (core->config, "esil.stack.depth");
|
|
||||||
unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size");
|
|
||||||
|
|
||||||
if (!(core->anal->esil = r_esil_new (esd, iotrap, addrsize))) {
|
|
||||||
R_FREE (ds->esil_regstate);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r_esil_setup (core->anal->esil, core->anal, 0, 0, 1);
|
|
||||||
}
|
|
||||||
core->anal->esil->user = ds;
|
core->anal->esil->user = ds;
|
||||||
free (ds->esil_regstate);
|
free (ds->esil_regstate);
|
||||||
R_FREE (core->anal->last_disasm_reg);
|
R_FREE (core->anal->last_disasm_reg);
|
||||||
@ -7344,6 +7334,7 @@ static bool read_ahead(RIO *io, ut8 **buf, size_t *buf_sz, ut64 address, size_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_core_disasm_pde(RCore *core, int nb_opcodes, int mode) {
|
R_API int r_core_disasm_pde(RCore *core, int nb_opcodes, int mode) {
|
||||||
|
// R2R db/cmd/cmd_pde
|
||||||
if (nb_opcodes < 1) {
|
if (nb_opcodes < 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -7360,14 +7351,8 @@ R_API int r_core_disasm_pde(RCore *core, int nb_opcodes, int mode) {
|
|||||||
}
|
}
|
||||||
pj_a (pj);
|
pj_a (pj);
|
||||||
}
|
}
|
||||||
if (!core->anal->esil) {
|
// R2_590 - maybe here r_core_cmd_call (core, "aeim");
|
||||||
r_core_cmd_call (core, "aei");
|
|
||||||
if (!r_config_get_b (core->config, "cfg.debug")) {
|
|
||||||
r_core_cmd_call (core, "aeim");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
REsil *esil = core->anal->esil;
|
REsil *esil = core->anal->esil;
|
||||||
r_reg_arena_push (reg);
|
|
||||||
RConfigHold *chold = r_config_hold_new (core->config);
|
RConfigHold *chold = r_config_hold_new (core->config);
|
||||||
r_config_hold (chold, "io.cache", "asm.lines", NULL);
|
r_config_hold (chold, "io.cache", "asm.lines", NULL);
|
||||||
r_config_set_b (core->config, "io.cache", true);
|
r_config_set_b (core->config, "io.cache", true);
|
||||||
@ -7381,7 +7366,19 @@ R_API int r_core_disasm_pde(RCore *core, int nb_opcodes, int mode) {
|
|||||||
size_t buf_sz = 0x100, block_sz = 0, block_instr = 0;
|
size_t buf_sz = 0x100, block_sz = 0, block_instr = 0;
|
||||||
ut64 block_start = r_reg_get_value (reg, pc);
|
ut64 block_start = r_reg_get_value (reg, pc);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
const ut64 op_addr = r_reg_get_value (reg, pc);
|
||||||
ut8 *buf = malloc (buf_sz);
|
ut8 *buf = malloc (buf_sz);
|
||||||
|
if (op_addr == 0) {
|
||||||
|
const RList *entries = r_bin_get_entries (core->bin);
|
||||||
|
if (entries && !r_list_empty (entries)) {
|
||||||
|
RBinAddr *entry = (RBinAddr *)r_list_get_n (entries, 0);
|
||||||
|
RBinInfo *info = r_bin_get_info (core->bin);
|
||||||
|
block_start = info->has_va? entry->vaddr: entry->paddr;
|
||||||
|
r_reg_set_value (reg, pc, block_start);
|
||||||
|
r_core_cmd0 (core, ".dr*");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r_reg_arena_push (reg);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,9 @@ R_API REsil *r_esil_new(int stacksize, int iotrap, unsigned int addrsize) {
|
|||||||
r_esil_plugins_init (esil);
|
r_esil_plugins_init (esil);
|
||||||
esil->addrmask = genmask (addrsize - 1);
|
esil->addrmask = genmask (addrsize - 1);
|
||||||
esil->trace = r_esil_trace_new (esil);
|
esil->trace = r_esil_trace_new (esil);
|
||||||
|
int stats = 1;
|
||||||
|
r_esil_stats (esil, stats);
|
||||||
|
r_esil_setup_ops (esil);
|
||||||
return esil;
|
return esil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,22 +152,11 @@ R_API void r_esil_del_op(REsil *esil, const char *op) {
|
|||||||
|
|
||||||
static bool r_esil_fire_trap(REsil *esil, int trap_type, int trap_code) {
|
static bool r_esil_fire_trap(REsil *esil, int trap_type, int trap_code) {
|
||||||
r_return_val_if_fail (esil, false);
|
r_return_val_if_fail (esil, false);
|
||||||
if (esil->cmd) {
|
if (esil->cmd && R_STR_ISNOTEMPTY (esil->cmd_trap)) {
|
||||||
if (esil->cmd (esil, esil->cmd_trap, trap_type, trap_code)) {
|
if (esil->cmd (esil, esil->cmd_trap, trap_type, trap_code)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
/// XXX
|
|
||||||
if (esil->anal) {
|
|
||||||
RAnalPlugin *ap = esil->anal->cur;
|
|
||||||
if (ap && ap->esil_trap) {
|
|
||||||
if (ap->esil_trap (esil, trap_type, trap_code)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if 0
|
#if 0
|
||||||
REsilTrapCB icb;
|
REsilTrapCB icb;
|
||||||
icb = (REsilTrapCB)sdb_ptr_get (esil->traps, i, 0);
|
icb = (REsilTrapCB)sdb_ptr_get (esil->traps, i, 0);
|
||||||
@ -190,7 +182,7 @@ R_API void r_esil_free(REsil *esil) {
|
|||||||
RArchPluginEsilCallback esil_cb = R_UNWRAP3 (as, plugin, esilcb);
|
RArchPluginEsilCallback esil_cb = R_UNWRAP3 (as, plugin, esilcb);
|
||||||
if (esil_cb) {
|
if (esil_cb) {
|
||||||
if (!esil_cb (as, R_ARCH_ESIL_FINI)) {
|
if (!esil_cb (as, R_ARCH_ESIL_FINI)) {
|
||||||
R_LOG_WARN ("Failed to properly cleanup esil for arch plugin");
|
R_LOG_DEBUG ("Failed to properly cleanup esil for arch plugin");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3989,7 +3981,7 @@ R_API void r_esil_setup_ops(REsil *esil) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* register callbacks using this anal module. */
|
/* register callbacks using this anal module. */
|
||||||
R_API bool r_esil_setup(REsil *esil, RAnal *anal, int romem, int stats, int nonull) {
|
R_API bool r_esil_setup(REsil *esil, RAnal *anal, bool romem, bool stats, bool nonull) {
|
||||||
r_return_val_if_fail (esil, false);
|
r_return_val_if_fail (esil, false);
|
||||||
//esil->debug = 0;
|
//esil->debug = 0;
|
||||||
esil->anal = anal;
|
esil->anal = anal;
|
||||||
@ -4026,9 +4018,10 @@ R_API bool r_esil_setup(REsil *esil, RAnal *anal, int romem, int stats, int nonu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
#if 0
|
}
|
||||||
// ESIL from arch
|
|
||||||
return (anal->cur && anal->cur->esil_init)
|
R_API void r_esil_reset(REsil *esil) {
|
||||||
? anal->cur->esil_init (esil): true;
|
esil->trap = 0;
|
||||||
#endif
|
r_return_if_fail (esil);
|
||||||
|
sdb_reset (esil->stats);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ static bool hook_NOP_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API void r_esil_mem_ro(REsil *esil, int mem_readonly) {
|
R_API void r_esil_mem_ro(REsil *esil, bool mem_readonly) {
|
||||||
if (mem_readonly) {
|
if (mem_readonly) {
|
||||||
esil->cb.hook_mem_write = hook_NOP_mem_write;
|
esil->cb.hook_mem_write = hook_NOP_mem_write;
|
||||||
} else {
|
} else {
|
||||||
@ -46,7 +46,7 @@ R_API void r_esil_mem_ro(REsil *esil, int mem_readonly) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API void r_esil_stats(REsil *esil, int enable) {
|
R_API void r_esil_stats(REsil *esil, bool enable) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (esil->stats) {
|
if (esil->stats) {
|
||||||
sdb_reset (esil->stats);
|
sdb_reset (esil->stats);
|
||||||
|
@ -757,7 +757,7 @@ R_API RList *r_bin_file_get_trycatch(RBinFile *bf);
|
|||||||
R_API RList *r_bin_get_symbols(RBin *bin);
|
R_API RList *r_bin_get_symbols(RBin *bin);
|
||||||
R_API RVecRBinSymbol *r_bin_get_symbols_vec(RBin *bin);
|
R_API RVecRBinSymbol *r_bin_get_symbols_vec(RBin *bin);
|
||||||
R_API RList *r_bin_reset_strings(RBin *bin);
|
R_API RList *r_bin_reset_strings(RBin *bin);
|
||||||
R_API int r_bin_is_string(RBin *bin, ut64 va);
|
R_API bool r_bin_is_string(RBin *bin, ut64 va);
|
||||||
R_API int r_bin_is_big_endian(RBin *bin);
|
R_API int r_bin_is_big_endian(RBin *bin);
|
||||||
R_API int r_bin_is_static(RBin *bin);
|
R_API int r_bin_is_static(RBin *bin);
|
||||||
R_API ut64 r_bin_get_vaddr(RBin *bin, ut64 paddr, ut64 vaddr);
|
R_API ut64 r_bin_get_vaddr(RBin *bin, ut64 paddr, ut64 vaddr);
|
||||||
|
@ -274,8 +274,9 @@ typedef struct r_esil_active_plugin_t {
|
|||||||
} REsilActivePlugin;
|
} REsilActivePlugin;
|
||||||
|
|
||||||
R_API REsil *r_esil_new(int stacksize, int iotrap, unsigned int addrsize);
|
R_API REsil *r_esil_new(int stacksize, int iotrap, unsigned int addrsize);
|
||||||
|
R_API void r_esil_reset(REsil *esil);
|
||||||
R_API void r_esil_set_pc(REsil *esil, ut64 addr);
|
R_API void r_esil_set_pc(REsil *esil, ut64 addr);
|
||||||
R_API bool r_esil_setup(REsil *esil, struct r_anal_t *anal, int romem, int stats, int nonull);
|
R_API bool r_esil_setup(REsil *esil, struct r_anal_t *anal, bool romem, bool stats, bool nonull);
|
||||||
R_API void r_esil_setup_macros(REsil *esil);
|
R_API void r_esil_setup_macros(REsil *esil);
|
||||||
R_API void r_esil_setup_ops(REsil *esil);
|
R_API void r_esil_setup_ops(REsil *esil);
|
||||||
R_API void r_esil_free(REsil *esil);
|
R_API void r_esil_free(REsil *esil);
|
||||||
@ -330,8 +331,8 @@ R_API bool r_esil_plugin_remove(REsil *esil, REsilPlugin *plugin);
|
|||||||
R_API bool r_esil_plugin_activate(REsil *esil, const char *name);
|
R_API bool r_esil_plugin_activate(REsil *esil, const char *name);
|
||||||
R_API void r_esil_plugin_deactivate(REsil *esil, const char *name);
|
R_API void r_esil_plugin_deactivate(REsil *esil, const char *name);
|
||||||
|
|
||||||
R_API void r_esil_mem_ro(REsil *esil, int mem_readonly);
|
R_API void r_esil_mem_ro(REsil *esil, bool mem_readonly);
|
||||||
R_API void r_esil_stats(REsil *esil, int enable);
|
R_API void r_esil_stats(REsil *esil, bool enable);
|
||||||
|
|
||||||
/* trace */
|
/* trace */
|
||||||
R_API REsilTrace *r_esil_trace_new(REsil *esil);
|
R_API REsilTrace *r_esil_trace_new(REsil *esil);
|
||||||
|
@ -4,7 +4,6 @@ const ioqjsPlugin = {
|
|||||||
desc: "Simple io plugin in javascript",
|
desc: "Simple io plugin in javascript",
|
||||||
license: "MIT",
|
license: "MIT",
|
||||||
check: function (uri, perm) {
|
check: function (uri, perm) {
|
||||||
console.log("CHECK.JS");
|
|
||||||
return uri.startsWith("qjs://");
|
return uri.startsWith("qjs://");
|
||||||
},
|
},
|
||||||
open: function (uri, perm) {
|
open: function (uri, perm) {
|
||||||
|
@ -940,6 +940,8 @@ pd 9 @ main
|
|||||||
EOF
|
EOF
|
||||||
EXPECT=<<EOF
|
EXPECT=<<EOF
|
||||||
;-- main:
|
;-- main:
|
||||||
|
;-- pc:
|
||||||
|
;-- r15:
|
||||||
0x0000050c 80b5 push {r7, lr}
|
0x0000050c 80b5 push {r7, lr}
|
||||||
0x0000050e 00af add r7, sp, 0
|
0x0000050e 00af add r7, sp, 0
|
||||||
0x00000510 034b ldr r3, [0x00000520] ; [0x520:4]=94
|
0x00000510 034b ldr r3, [0x00000520] ; [0x520:4]=94
|
||||||
|
@ -331,6 +331,7 @@ RUN
|
|||||||
NAME=ppc-update-suffix-esil
|
NAME=ppc-update-suffix-esil
|
||||||
FILE=bins/elf/a6ppc.out
|
FILE=bins/elf/a6ppc.out
|
||||||
CMDS=<<EOF
|
CMDS=<<EOF
|
||||||
|
aeim
|
||||||
40ds
|
40ds
|
||||||
dr?r3
|
dr?r3
|
||||||
dr?r4
|
dr?r4
|
||||||
@ -339,9 +340,9 @@ dr?r3
|
|||||||
dr?r4
|
dr?r4
|
||||||
EOF
|
EOF
|
||||||
EXPECT=<<EOF
|
EXPECT=<<EOF
|
||||||
0xffffffbf
|
0x00177fbf
|
||||||
0x10000107
|
0x10000107
|
||||||
0xffffffc1
|
0x00177fc1
|
||||||
0x1000010a
|
0x1000010a
|
||||||
EOF
|
EOF
|
||||||
RUN
|
RUN
|
||||||
|
@ -452,6 +452,7 @@ CMDS=<<EOF
|
|||||||
e asm.flags=false
|
e asm.flags=false
|
||||||
e asm.comments=false
|
e asm.comments=false
|
||||||
e anal.vars.stackname = true
|
e anal.vars.stackname = true
|
||||||
|
aeim
|
||||||
wx 80b483b000af78600b467b8013467b707b78002b03d07a887b689a6103e07b881a047b689a6100bf0c37bd465df8047b7047
|
wx 80b483b000af78600b467b8013467b707b78002b03d07a887b689a6103e07b881a047b689a6100bf0c37bd465df8047b7047
|
||||||
af
|
af
|
||||||
aaef
|
aaef
|
||||||
|
10
test/db/esil/cmd
Normal file
10
test/db/esil/cmd
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
NAME=cmd.esil.trap
|
||||||
|
FILE=-
|
||||||
|
CMDS=<<EOF
|
||||||
|
e cmd.esil.trap=?e hello world
|
||||||
|
ae 2,1,TRAP
|
||||||
|
EOF
|
||||||
|
EXPECT=<<EOF
|
||||||
|
hello world 1 2
|
||||||
|
EOF
|
||||||
|
RUN
|
@ -1748,6 +1748,7 @@ CMDS=<<EOF
|
|||||||
e io.va=true
|
e io.va=true
|
||||||
e asm.arch=mips
|
e asm.arch=mips
|
||||||
e asm.bits=32
|
e asm.bits=32
|
||||||
|
aeim
|
||||||
ar > /dev/null
|
ar > /dev/null
|
||||||
ar v0=8
|
ar v0=8
|
||||||
ar a0=0x00400b48
|
ar a0=0x00400b48
|
||||||
|
Loading…
Reference in New Issue
Block a user