diff --git a/libr/core/disasm.c b/libr/core/disasm.c index b560588775291..e8aef1fdf5e2d 100644 --- a/libr/core/disasm.c +++ b/libr/core/disasm.c @@ -1133,11 +1133,12 @@ static void ds_show_refs(RDisasmState *ds) { static void ds_show_xrefs(RDisasmState *ds) { RAnalRef *refi; - RListIter *iter; + RListIter *iter, *it; RCore *core = ds->core; bool demangle = r_config_get_i (core->config, "bin.demangle"); const char *lang = demangle ? r_config_get (core->config, "bin.lang") : NULL; char *name, *tmp; + ut64 addr; int count = 0; if (!ds->show_xrefs || !ds->show_comments) { return; @@ -1182,15 +1183,36 @@ static void ds_show_xrefs(RDisasmState *ds) { return; } + RList *addrs = r_list_new (); + RAnalFunction *fun, *next_fun; + RFlagItem *f, *next_f; r_list_foreach (xrefs, iter, refi) { if (refi->at == ds->at) { - RAnalFunction *fun = fcnIn (ds, refi->addr, -1); //r_anal_get_fcn_in (core->anal, refi->addr, -1); + fun = fcnIn (ds, refi->addr, -1); if (fun) { + if (iter != xrefs->tail) { + ut64 next_addr = ((RAnalRef *)(iter->n->data))->addr; + next_fun = r_anal_get_fcn_in (core->anal, next_addr, -1); + if (next_fun && next_fun->addr == fun->addr) { + r_list_append (addrs, refi->addr); + continue; + } + } name = strdup (fun->name); + r_list_append (addrs, refi->addr); } else { - RFlagItem *f = r_flag_get_at (core->flags, refi->addr, true); + f = r_flag_get_at (core->flags, refi->addr, true); if (f) { - name = r_str_newf ("%s + %d", f->name, refi->addr - f->offset); + if (iter != xrefs->tail) { + ut64 next_addr = ((RAnalRef *)(iter->n->data))->addr; + next_f = r_flag_get_at (core->flags, next_addr, true); + if (next_f && f->offset == next_f->offset) { + r_list_append (addrs, refi->addr - f->offset); + continue; + } + } + name = strdup (f->name); + r_list_append (addrs, refi->addr - f->offset); } else { name = strdup ("unk"); } @@ -1204,10 +1226,16 @@ static void ds_show_xrefs(RDisasmState *ds) { } ds_begin_json_line (ds); ds_pre_xrefs (ds, false); - ds_comment (ds, false, "%s; %s XREF from 0x%08"PFMT64x" (%s)%s", - COLOR (ds, pal_comment), r_anal_xrefs_type_tostring (refi->type), - refi->addr, name, COLOR_RESET (ds)); + char* plural = r_list_length (addrs) > 1 ? "S" : ""; + char* plus = fun ? "" : "+"; + ds_comment (ds, false, "%s; %s XREF%s from %s (", + COLOR (ds, pal_comment), r_anal_xrefs_type_tostring (refi->type), plural, name); + r_list_foreach (addrs, it, addr) { + ds_comment (ds, false, "%s%s0x%"PFMT64x, it == addrs->head ? "" : ", ", plus, addr); + } + ds_comment (ds, false, ")%s", COLOR_RESET (ds)); ds_newline (ds); + r_list_purge (addrs); R_FREE (name); } else { eprintf ("Corrupted database?\n");