Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions libr/core/disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand Down
Loading