diff --git a/libr/core/disasm.c b/libr/core/disasm.c index 11036361c328f..6f919cddbed9f 100644 --- a/libr/core/disasm.c +++ b/libr/core/disasm.c @@ -94,7 +94,8 @@ typedef struct r_disasm_state_t { int atabs; bool atabsonce; int atabsoff; - int decode; + bool decode; + ut32 decode_mask; // computed once based on display settings bool pseudo; bool sparse; bool subnames; @@ -345,7 +346,7 @@ static void ds_begin_cont(RDisasmState *ds); static void ds_print_esil_anal(RDisasmState *ds); static void ds_reflines_init(RDisasmState *ds); static void ds_align_comment(RDisasmState *ds); -static RDisasmState * ds_init(RCore *core); +static RDisasmState * ds_init(RCore *core, bool for_json); static void ds_build_op_str(RDisasmState *ds, bool print_color); static void ds_print_bytes(RDisasmState *ds); static char *ds_getstring(RDisasmState *ds, const char *str, int len, const char **prefix); @@ -663,7 +664,7 @@ static void ds_print_esil_anal_fini(RDisasmState *ds) { } } -static RDisasmState *ds_init(RCore *core) { +static RDisasmState *ds_init(RCore *core, bool for_json) { RDisasmState *ds = R_NEW0 (RDisasmState); ds->ssa = sdb_new0 (); ds->core = core; @@ -735,7 +736,7 @@ static RDisasmState *ds_init(RCore *core) { ds->asm_flags_right = r_config_get_i (core->config, "asm.flags.right"); ds->midbb = r_config_get_i (core->config, "asm.bbmiddle"); ds->midcursor = r_config_get_i (core->config, "asm.midcursor"); - ds->decode = r_config_get_i (core->config, "asm.decode"); + ds->decode = r_config_get_b (core->config, "asm.decode"); core->rasm->parse->pseudo = ds->pseudo = r_config_get_b (core->config, "asm.pseudo"); if (ds->pseudo) { ds->atabs = 0; @@ -976,6 +977,11 @@ static RDisasmState *ds_init(RCore *core) { // Prevent palette reload during disassembly to avoid UAF of cached color pointers ds->pal_batch_save = core->cons->context->pal_batch; core->cons->context->pal_batch = true; + // Compute the decode mask once based on display settings to avoid unnecessary work. + ds->decode_mask = R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_HINT | R_ARCH_OP_MASK_VAL | R_ARCH_OP_MASK_DISASM; + if (for_json || ds->use_esil || ds->show_emu || ds->show_cmt_esil || ds->show_emu_bb || (ds->asm_hints && ds->asm_hint_cdiv)) { + ds->decode_mask |= R_ARCH_OP_MASK_ESIL; + } return ds; } @@ -6617,7 +6623,7 @@ R_API int r_core_print_disasm(RCore *core, ut64 addr, ut8 *buf, int len, int cou const char *pdu_condition_opcode = NULL; // TODO: All those ds must be print flags - RDisasmState *ds = ds_init (core); + RDisasmState *ds = ds_init (core, false); ds->count_bytes = count_bytes; ds->print = p; ds->count = count? count: core->blocksize; @@ -6694,7 +6700,7 @@ R_API int r_core_print_disasm(RCore *core, ut64 addr, ut8 *buf, int len, int cou // TODO: support in-the-middle-of-instruction too r_anal_op_fini (&ds->analop); if (r_anal_op (core->anal, &ds->analop, core->addr + core->print->cur, - buf + core->print->cur, (int)(len - core->print->cur), R_ARCH_OP_MASK_ALL)) { + buf + core->print->cur, (int)(len - core->print->cur), R_ARCH_OP_MASK_BASIC | R_ARCH_OP_MASK_HINT)) { // TODO: check for ds->analop.type and ret ds->dest = ds->analop.jump; } @@ -6809,7 +6815,7 @@ R_API int r_core_print_disasm(RCore *core, ut64 addr, ut8 *buf, int len, int cou r_asm_set_pc (core->rasm, ds->at); ds_update_ref_lines (ds); r_anal_op_fini (&ds->analop); - ret = r_anal_op (core->anal, &ds->analop, ds->at, ds_bufat (ds), ds_left (ds), R_ARCH_OP_MASK_ALL); + ret = r_anal_op (core->anal, &ds->analop, ds->at, ds_bufat (ds), ds_left (ds), ds->decode_mask); if (ret < 1) { ret = ds->analop.size; inc = minopsz; @@ -6926,7 +6932,7 @@ R_API int r_core_print_disasm(RCore *core, ut64 addr, ut8 *buf, int len, int cou if (ds->analop.addr != ds->at) { // TODO : check for error r_anal_op_fini (&ds->analop); - r_anal_op (core->anal, &ds->analop, ds->at, ds_bufat (ds), ds_left (ds), R_ARCH_OP_MASK_ALL); + r_anal_op (core->anal, &ds->analop, ds->at, ds_bufat (ds), ds_left (ds), ds->decode_mask); } if (ret < 1) { r_strbuf_fini (&ds->analop.esil); @@ -7349,7 +7355,7 @@ R_API int r_core_print_disasm_instructions_with_buf(RCore *core, ut64 address, u r_reg_arena_push (core->anal->reg); - ds = ds_init (core); + ds = ds_init (core, false); if (!ds) { return 0; } @@ -7381,7 +7387,7 @@ R_API int r_core_print_disasm_instructions_with_buf(RCore *core, ut64 address, u const size_t delta = addrbytes * i; r_anal_op_init (&ds->analop); const int oret = r_anal_op (core->anal, &ds->analop, ds->at, - buf + delta, nb_bytes - delta, R_ARCH_OP_MASK_ALL); + buf + delta, nb_bytes - delta, ds->decode_mask); ret = oret; ds->oplen = ds->analop.size; if (ret > 0) { @@ -7673,7 +7679,7 @@ R_IPI int r_core_print_disasm_json_ipi(RCore *core, ut64 addr, ut8 *buf, int nb_ // i = number of bytes // j = number of instructions // k = delta from addr - ds = ds_init (core); + ds = ds_init (core, true); bool result = false; const bool be = R_ARCH_CONFIG_IS_BIG_ENDIAN (core->rasm->config); @@ -7731,7 +7737,7 @@ R_IPI int r_core_print_disasm_json_ipi(RCore *core, ut64 addr, ut8 *buf, int nb_ ds->has_description = false; r_anal_op_fini (&ds->analop); - r_anal_op (core->anal, &ds->analop, at, buf + i, nb_bytes - i, R_ARCH_OP_MASK_ALL); + r_anal_op (core->anal, &ds->analop, at, buf + i, nb_bytes - i, ds->decode_mask); if (ds->pseudo) { char *res = r_asm_parse_pseudo (core->rasm, opstr); @@ -7950,7 +7956,7 @@ R_API int r_core_print_disasm_all(RCore *core, ut64 addr, int l, int len, int mo if (l < 1) { l = len; } - RDisasmState *ds = ds_init (core); + RDisasmState *ds = ds_init (core, false); if (l > core->blocksize || addr != core->addr) { buf = malloc (l + 1); if (!buf) { @@ -8020,13 +8026,15 @@ R_API int r_core_print_disasm_all(RCore *core, ut64 addr, int l, int len, int mo if (scr_color) { RAnalOp aop; RAnalFunction *f = fcnIn (ds, ds->vat, R_ANAL_FCN_TYPE_NULL); - r_anal_op (core->anal, &aop, addr, buf + i, l - i, R_ARCH_OP_MASK_ALL); + r_anal_op_init (&aop); + r_anal_op (core->anal, &aop, addr, buf + i, l - i, R_ARCH_OP_MASK_BASIC); char *buf_asm = r_print_colorize_opcode (core->print, res? res: asmop.mnemonic, core->cons->context->pal.reg, core->cons->context->pal.num, false, f ? f->addr : 0); if (buf_asm) { r_cons_printf (core->cons, "%s%s\n", r_print_color_op_type (core->print, aop.type), buf_asm); free (buf_asm); } + r_anal_op_fini (&aop); } else { r_cons_println (core->cons, asmop.mnemonic); }