Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fold switch cases pointing to the same instruction #10497

Merged
merged 4 commits into from Jun 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions libr/anal/fcn.c
Expand Up @@ -442,8 +442,8 @@ static void queue_case(RAnal *anal, ut64 switch_addr, ut64 case_addr, ut64 id, u
// "CCu case %d: @ 0x%"PFMT64x "\n",
// id, case_addr);
anal->cmdtail = r_str_appendf (anal->cmdtail,
"f case.%d.0x%"PFMT64x " 1 @ 0x%08"PFMT64x "\n",
id, case_addr, case_addr);
"f case.0x%"PFMT64x ".%d 1 @ 0x%08"PFMT64x "\n",
switch_addr, id, case_addr);
}

static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut64 ip, ut64 jmptbl_loc, ut64 jmptbl_off, ut64 sz, ut64 jmptbl_size, ut64 default_case, int ret0) {
Expand Down
43 changes: 39 additions & 4 deletions libr/core/disasm.c
Expand Up @@ -1848,6 +1848,9 @@ static void ds_show_flags(RDisasmState *ds) {
}
RCore *core = ds->core;
// f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
char addr[64];
ut64 switch_addr;
int case_start = -1, case_prev = 0, case_current = 0;
f = fcnIn (ds, ds->at, R_ANAL_FCN_TYPE_NULL);
flaglist = r_flag_get_list (core->flags, ds->at);
RList *uniqlist = r_list_uniq (flaglist, flagCmp);
Expand All @@ -1856,6 +1859,22 @@ static void ds_show_flags(RDisasmState *ds) {
// do not show flags that have the same name as the function
continue;
}
if (!strncmp (flag->name, "case.", 5)) {
sscanf (flag->name + 5, "%63[^.].%d", addr, &case_current);
ut64 saddr = r_num_math (core->num, addr);
if (case_start == -1) {
switch_addr = saddr;
case_prev = case_current;
case_start = case_current;
if (iter != uniqlist->tail) {
continue;
}
}
if (case_current == case_prev + 1 && switch_addr == saddr) {
case_prev = case_current;
continue;
}
}
ds_begin_json_line (ds);
if (ds->show_flgoff) {
ds_beginline (ds);
Expand All @@ -1881,10 +1900,26 @@ static void ds_show_flags(RDisasmState *ds) {
}
}
if (ds->asm_demangle && flag->realname) {
const char *lang = r_config_get (core->config, "bin.lang");
char *name = r_bin_demangle (core->bin->cur, lang, flag->realname, flag->offset);
r_cons_printf ("%s:", name? name: flag->realname);
R_FREE (name);
if (!strncmp (flag->name, "case.", 5)) {
if (!strncmp (flag->name + 5, "default", 7)) {
r_cons_printf ("%s:", flag->name);
} else if (case_prev != case_start) {
r_cons_printf ("cases %d...%d (%s):", case_start, case_prev, addr);
if (iter != uniqlist->head) {
iter = iter->p;
}
case_start = case_current;
} else {
r_cons_printf ("case %d (%s):", case_prev, addr);
case_start = -1;
}
case_prev = case_current;
} else {
const char *lang = r_config_get (core->config, "bin.lang");
char *name = r_bin_demangle (core->bin->cur, lang, flag->realname, flag->offset);
r_cons_printf ("%s:", name? name: flag->realname);
R_FREE (name);
}
} else {
r_cons_printf ("%s:", flag->name);
}
Expand Down