mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-06 21:39:38 +00:00
Fix #13880: Add dt= ##print
This commit is contained in:
parent
a7e1918225
commit
6896064553
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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?
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user