diff --git a/libr/core/disasm.c b/libr/core/disasm.c index 8c5fe49703..ff4f240924 100644 --- a/libr/core/disasm.c +++ b/libr/core/disasm.c @@ -911,6 +911,17 @@ static void ds_highlight_word(RDisasmState * ds, char *word, char *color) { ds->opstr = asm_str? asm_str: source; } +static char *get_op_ireg (void *user, ut64 addr) { + RCore *core = (RCore *)user; + char *res = NULL; + RAnalOp *op = r_core_anal_op (core, addr, R_ANAL_OP_MASK_ESIL); + if (op && op->ireg) { + res = strdup (op->ireg); + } + r_anal_op_free (op); + return res; +} + static void ds_build_op_str(RDisasmState *ds, bool print_color) { RCore *core = ds->core; if (!ds->opstr) { @@ -925,6 +936,7 @@ static void ds_build_op_str(RDisasmState *ds, bool print_color) { ut64 at = ds->vat; RAnalFunction *f = fcnIn (ds, at, R_ANAL_FCN_TYPE_NULL); core->parser->varlist = r_anal_var_list_dynamic; + core->parser->get_op_ireg = get_op_ireg; r_parse_varsub (core->parser, f, at, ds->analop.size, ds->opstr, ds->strsub, sizeof (ds->strsub)); if (*ds->strsub) { diff --git a/libr/include/r_parse.h b/libr/include/r_parse.h index 970be9174b..b246bbf1af 100644 --- a/libr/include/r_parse.h +++ b/libr/include/r_parse.h @@ -34,6 +34,7 @@ typedef struct r_parse_t { RAnalHint *hint; // weak anal ref RList *parsers; RAnalVarList varlist; + char* (*get_op_ireg)(void *user, ut64 addr); RAnalBind analb; } RParse; diff --git a/libr/parse/p/parse_x86_pseudo.c b/libr/parse/p/parse_x86_pseudo.c index b1dd964dbf..20941ba823 100644 --- a/libr/parse/p/parse_x86_pseudo.c +++ b/libr/parse/p/parse_x86_pseudo.c @@ -300,36 +300,55 @@ static inline int issegoff (const char *w) { } #endif -static void parse_localvar (RParse *p, char *newstr, size_t newstr_len, const char *var, const char *reg, char sign, bool att) { +static void parse_localvar (RParse *p, char *newstr, size_t newstr_len, const char *var, const char *reg, char sign, char *ireg, bool att) { + RStrBuf *sb = r_strbuf_new (""); if (att) { if (p->localvar_only) { - snprintf (newstr, newstr_len - 1, "%s", var); + if (ireg) { + r_strbuf_setf (sb, "(%%%s)", ireg); + } + snprintf (newstr, newstr_len - 1, "%s%s", var, r_strbuf_get (sb)); } else { - snprintf (newstr, newstr_len - 1, "%s(%%%s)", var, reg); + if (ireg) { + r_strbuf_setf (sb, ", %%%s", ireg); + } + snprintf (newstr, newstr_len - 1, "%s(%%%s%s)", var, reg, r_strbuf_get (sb)); } } else { + if (ireg) { + r_strbuf_setf (sb, " + %s", ireg); + } if (p->localvar_only) { - snprintf (newstr, newstr_len - 1, "[%s]", var); + snprintf (newstr, newstr_len - 1, "[%s%s]", var, r_strbuf_get (sb)); } else { - snprintf (newstr, newstr_len - 1, "[%s %c %s]", reg, sign, var); + snprintf (newstr, newstr_len - 1, "[%s%s %c %s]", reg, r_strbuf_get (sb), sign, var); } } + r_strbuf_free (sb); } -static inline void mk_reg_str(const char *regname, int delta, bool sign, bool att, char *dest, int len) { +static inline void mk_reg_str(const char *regname, int delta, bool sign, bool att, char *ireg, char *dest, int len) { + RStrBuf *sb = r_strbuf_new (""); if (att) { + if (ireg) { + r_strbuf_setf (sb, ", %%%s", ireg); + } if (delta < 10) { - snprintf (dest, len - 1, "%s%d(%%%s)", sign ? "" : "-", delta, regname); + snprintf (dest, len - 1, "%s%d(%%%s%s)", sign ? "" : "-", delta, regname, r_strbuf_get (sb)); } else { - snprintf (dest, len - 1, "%s0x%x(%%%s)", sign ? "" : "-", delta, regname); + snprintf (dest, len - 1, "%s0x%x(%%%s%s)", sign ? "" : "-", delta, regname, r_strbuf_get (sb)); } } else { + if (ireg) { + r_strbuf_setf (sb, " + %s", ireg); + } if (delta < 10) { - snprintf (dest, len - 1, "[%s %c %d]", regname, sign ? '+':'-', delta); + snprintf (dest, len - 1, "[%s%s %c %d]", regname, r_strbuf_get (sb), sign ? '+':'-', delta); } else { - snprintf (dest, len - 1, "[%s %c 0x%x]", regname, sign ? '+':'-', delta); + snprintf (dest, len - 1, "[%s%s %c 0x%x]", regname, r_strbuf_get (sb), sign ? '+':'-', delta); } } + r_strbuf_free (sb); } static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *data, char *str, int len) { @@ -405,14 +424,18 @@ static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *dat if (ucase && tstr[1]) { ucase = tstr[1] >= 'A' && tstr[1] <= 'Z'; } + char *ireg = NULL; + if (p->get_op_ireg) { + ireg = p->get_op_ireg(p->user, addr); + } r_list_foreach (spargs, spiter, sparg) { // assuming delta always positive? - mk_reg_str (p->anal->reg->name[R_REG_NAME_SP], sparg->delta, true, att, oldstr, sizeof (oldstr)); + mk_reg_str (p->anal->reg->name[R_REG_NAME_SP], sparg->delta, true, att, ireg, oldstr, sizeof (oldstr)); if (ucase) { r_str_case (oldstr, true); } - parse_localvar (p, newstr, sizeof (newstr), sparg->name, p->anal->reg->name[R_REG_NAME_SP], '+', att); + parse_localvar (p, newstr, sizeof (newstr), sparg->name, p->anal->reg->name[R_REG_NAME_SP], '+', ireg, att); if (ucase) { char *plus = strchr (newstr, '+'); if (plus) { @@ -443,11 +466,11 @@ static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *dat sign = '-'; bparg->delta = -bparg->delta; } - mk_reg_str (p->anal->reg->name[R_REG_NAME_BP], bparg->delta, sign=='+', att, oldstr, sizeof (oldstr)); + mk_reg_str (p->anal->reg->name[R_REG_NAME_BP], bparg->delta, sign=='+', att, ireg, oldstr, sizeof (oldstr)); if (ucase) { r_str_case (oldstr, true); } - parse_localvar (p, newstr, sizeof (newstr), bparg->name, p->anal->reg->name[R_REG_NAME_BP], sign, att); + parse_localvar (p, newstr, sizeof (newstr), bparg->name, p->anal->reg->name[R_REG_NAME_BP], sign, ireg, att); if (ucase) { char *plus = strchr (newstr, sign); if (plus) { @@ -498,6 +521,7 @@ static bool varsub (RParse *p, RAnalFunction *f, ut64 addr, int oplen, char *dat ret = false; } free (tstr); + free (ireg); r_list_free (spargs); r_list_free (bpargs); return ret;