Fix #13880: Add dt= ##print

This commit is contained in:
dodococo 2019-04-28 23:00:15 +05:30 committed by radare
parent a7e1918225
commit 6896064553
5 changed files with 143 additions and 9 deletions

View File

@ -304,6 +304,7 @@ static const char *help_msg_afb[] = {
".afbr-*", "", "Remove breakpoint on every return address of the function",
"afb", " [addr]", "list basic blocks of function",
"afb.", " [addr]", "show info of current basic block",
"afb=", "", "display ascii-art bars for basic block regions",
"afb+", " fcn_at bbat bbsz [jump] [fail] ([type] ([diff]))", "add basic block by hand",
"afbr", "", "Show addresses of instructions which leave the function",
"afbi", "", "print current basic block information",
@ -352,6 +353,7 @@ static const char *help_msg_afl[] = {
"Usage:", "afl", " List all functions",
"afl", "", "list functions",
"afl+", "", "display sum all function sizes",
"afl=", "", "display ascii-art bars with function ranges",
"aflc", "", "count of functions",
"aflj", "", "list functions in json",
"afll", "", "list functions in verbose mode",

View File

@ -421,6 +421,7 @@ static const char *help_msg_dt[] = {
"dt*", "", "List all traced opcode offsets",
"dt+"," [addr] [times]", "Add trace for address N times",
"dt-", "", "Reset traces (instruction/calls)",
"dt=", "", "Show ascii-art color bars with the debug trace ranges",
"dta", " 0x804020 ...", "Only trace given addresses",
"dtc[?][addr]|([from] [to] [addr])", "", "Trace call/ret",
"dtd", "[qi] [nth-start]", "List all traced disassembled (quiet, instructions)",
@ -4473,13 +4474,16 @@ static int cmd_debug(void *data, const char *input) {
// TODO: define ranges? to display only some traces, allow to scroll on this disasm? ~.. ?
switch (input[1]) {
case '\0': // "dt"
r_debug_trace_list (core->dbg, 0);
r_debug_trace_list (core->dbg, 0, core->offset);
break;
case '=': // "dt="
r_debug_trace_list (core->dbg, '=', core->offset);
break;
case 'q': // "dtq"
r_debug_trace_list (core->dbg, 'q');
r_debug_trace_list (core->dbg, 'q', core->offset);
break;
case '*': // "dt*"
r_debug_trace_list (core->dbg, 1);
r_debug_trace_list (core->dbg, 1, core->offset);
break;
case ' ': // "dt [addr]"
if ((t = r_debug_trace_get (core->dbg,

View File

@ -854,12 +854,12 @@ static const char *radare_argv[] = {
"aer", "aets?", "aets", "aets+", "aes", "aesp", "aesb", "aeso", "aesou", "aess", "aesu", "aesue", "aetr", "aex",
"af?", "af", "afr", "af+", "af-",
"afa", "afan",
"afb?", "afb", "afb.", "afb+", "afbb", "afbr", "afbi", "afbj", "afbe", "afB", "afbc",
"afb?", "afb", "afb.", "afb+", "afbb", "afbr", "afbi", "afbj", "afbe", "afB", "afbc", "afb=",
"afB", "afC", "afCl", "afCc", "afc?", "afc", "afc=", "afcr", "afcrj", "afca", "afcf", "afcfj",
"afck", "afcl", "afco", "afcR",
"afd", "aff", "afF", "afi",
"afl?", "afl", "afl+", "aflc", "aflj", "afll", "afllj", "aflm", "aflq", "aflqj", "afls",
"afm", "afM", "afn?", "afn", "afna", "afns", "afnsj",
"afm", "afM", "afn?", "afn", "afna", "afns", "afnsj", "afl=",
"afo", "afs", "afS", "aft?", "aft", "afu",
"afv?", "afv", "afvr?", "afvr", "afvr*", "afvrj", "afvr-", "afvrg", "afvrs",
"afvb?", "afvb", "afvbj", "afvb-", "afvbg", "afvbs",
@ -915,7 +915,7 @@ static const char *radare_argv[] = {
"dr?", "dr", "drps", "drpj", "drr", "drrj", "drs", "drs+", "drs-", "drt", "drt*", "drtj", "drw", "drx", "drx-",
".dr*", ".dr-",
"ds?", "ds", "dsb", "dsf", "dsi", "dsl", "dso", "dsp", "dss", "dsu", "dsui", "dsuo", "dsue", "dsuf",
"dt?", "dt", "dt%", "dt*", "dt+", "dt-", "dtD", "dta", "dtc", "dtd", "dte", "dte-*", "dtei", "dtek",
"dt?", "dt", "dt%", "dt*", "dt+", "dt-", "dt=", "dtD", "dta", "dtc", "dtd", "dte", "dte-*", "dtei", "dtek",
"dtg", "dtg*", "dtgi",
"dtr",
"dts?", "dts", "dts+", "dts-", "dtsf", "dtst", "dtsC", "dtt",

View File

@ -1,7 +1,6 @@
/* radare - LGPL - Copyright 2008-2016 - pancake */
#include <r_debug.h>
#define R_DEBUG_SDB_TRACES 1
// DO IT WITH SDB
@ -98,9 +97,119 @@ R_API RDebugTracepoint *r_debug_trace_get (RDebug *dbg, ut64 addr) {
return NULL;
}
R_API void r_debug_trace_list (RDebug *dbg, int mode) {
typedef struct {
char *name;
RInterval pitv;
RInterval vitv;
int perm;
char *extra;
} ListInfo;
static int cmpaddr (const void *_a, const void *_b) {
const ListInfo *a = _a, *b = _b;
return (r_itv_begin (a->pitv) > r_itv_begin (b->pitv))? 1:
(r_itv_begin (a->pitv) < r_itv_begin (b->pitv))? -1: 0;
}
// Copy from visual to avoid circular dependency
void visual_list(RDebug *dbg, RList *list, ut64 seek, ut64 len, int width, int use_color) {
ut64 mul, min = -1, max = -1;
RListIter *iter;
ListInfo *info;
int j, i;
RIO *io = dbg->iob.io;
width -= 80;
if (width < 1) {
width = 30;
}
r_list_foreach (list, iter, info) {
if (min == -1 || info->pitv.addr < min) {
min = info->pitv.addr;
}
if (max == -1 || info->pitv.addr + info->pitv.size > max) {
max = info->pitv.addr + info->pitv.size;
}
}
mul = (max - min) / width;
if (min != -1 && mul > 0) {
const char * color = "", *color_end = "";
i = 0;
r_list_foreach (list, iter, info) {
if (use_color && info->perm != -1) {
color_end = Color_RESET;
if ((info->perm & R_PERM_X) && (info->perm & R_PERM_W)) { // exec & write bits
color = r_cons_singleton ()->context->pal.graph_trufae;
} else if ((info->perm & R_PERM_X)) { // exec bit
color = r_cons_singleton ()->context->pal.graph_true;
} else if ((info->perm & R_PERM_W)) { // write bit
color = r_cons_singleton ()->context->pal.graph_false;
} else {
color = "";
color_end = "";
}
} else {
color = "";
color_end = "";
}
if (io->va) {
io->cb_printf ("%05d%c %s0x%08"PFMT64x"%s |", i,
r_itv_contain (info->vitv, seek) ? '*' : ' ',
color, info->vitv.addr, color_end);
} else {
io->cb_printf ("%05d%c %s0x%08"PFMT64x"%s |", i,
r_itv_contain (info->pitv, seek) ? '*' : ' ',
color, info->pitv.addr, color_end);
}
for (j = 0; j < width; j++) {
ut64 pos = min + j * mul;
ut64 npos = min + (j + 1) * mul;
if (info->pitv.addr < npos && (info->pitv.addr + info->pitv.size) > pos) {
io->cb_printf ("#");
} else {
io->cb_printf ("-");
}
}
if (io->va) {
io->cb_printf ("| %s0x%08"PFMT64x"%s %s %6s %s\n",
color, r_itv_end (info->vitv), color_end,
(info->perm != -1)? r_str_rwx_i (info->perm) : " ",
(info->extra)?info->extra : " ",
(info->name)?info->name : " ");
} else {
io->cb_printf ("| %s0x%08"PFMT64x"%s %s %6s %s\n",
color, r_itv_end (info->pitv), color_end,
(info->perm != -1)? r_str_rwx_i (info->perm) : " ",
(info->extra)?info->extra : " ",
(info->name)?info->name : "");
}
i++;
}
/* current seek */
if (i > 0 && len != 0) {
if (seek == UT64_MAX) {
seek = 0;
}
io->cb_printf ("=> 0x%08"PFMT64x" |", seek);
for (j = 0; j < width; j++) {
io->cb_printf (
((j * mul) + min >= seek &&
(j * mul) + min <= seek+len)
?"^" : "-");
}
io->cb_printf ("| 0x%08"PFMT64x"\n", seek+len);
}
}
}
R_API void r_debug_trace_list (RDebug *dbg, int mode, ut64 offset) {
int tag = dbg->trace->tag;
RListIter *iter;
bool flag = false;
RList *info_list = r_list_new ();
if (!info_list && mode == '=') {
return;
}
RDebugTracepoint *trace;
r_list_foreach (dbg->trace->traces, iter, trace) {
if (!trace->tag || (tag & trace->tag)) {
@ -108,6 +217,19 @@ R_API void r_debug_trace_list (RDebug *dbg, int mode) {
case 'q':
dbg->cb_printf ("0x%"PFMT64x"\n", trace->addr);
break;
case '=': {
ListInfo *info = R_NEW0 (ListInfo);
if (!info) {
return;
}
info->pitv = (RInterval) {trace->addr, trace->size};
info->vitv = info->pitv;
info->perm = -1;
info->name = r_str_newf ("%d", trace->times);
info->extra = r_str_newf ("%d", trace->count);
r_list_append (info_list, info);
flag = true;
} break;
case 1:
case '*':
dbg->cb_printf ("dt+ 0x%"PFMT64x" %d\n", trace->addr, trace->times);
@ -119,6 +241,12 @@ R_API void r_debug_trace_list (RDebug *dbg, int mode) {
}
}
}
if (flag) {
r_list_sort (info_list, cmpaddr);
visual_list (dbg, info_list, offset, 1,
r_cons_get_size (NULL), false);
r_list_free (info_list);
}
}
// XXX: find better name, make it public?

View File

@ -544,7 +544,7 @@ R_API void r_debug_trace_reset(RDebug *dbg);
R_API int r_debug_trace_pc(RDebug *dbg, ut64 pc);
R_API void r_debug_trace_at(RDebug *dbg, const char *str);
R_API RDebugTracepoint *r_debug_trace_get(RDebug *dbg, ut64 addr);
R_API void r_debug_trace_list(RDebug *dbg, int mode);
R_API void r_debug_trace_list(RDebug *dbg, int mode, ut64 offset);
R_API RDebugTracepoint *r_debug_trace_add(RDebug *dbg, ut64 addr, int size);
R_API RDebugTrace *r_debug_trace_new(void);
R_API void r_debug_trace_free(RDebugTrace *dbg);