Implement ar, and dr, commands to list registers in table format ##cons
This commit is contained in:
parent
1d42b95e78
commit
84436bfaad
|
@ -620,6 +620,7 @@ static const char *help_msg_ar[] = {
|
||||||
"Usage: ar", "", "# Analysis Registers",
|
"Usage: ar", "", "# Analysis Registers",
|
||||||
"ar", "", "Show 'gpr' registers",
|
"ar", "", "Show 'gpr' registers",
|
||||||
"ar.", ">$snapshot", "Show r2 commands to set register values to the current state",
|
"ar.", ">$snapshot", "Show r2 commands to set register values to the current state",
|
||||||
|
"ar,", "", "Show registers in table format (see dr,)",
|
||||||
".ar*", "", "Import register values as flags",
|
".ar*", "", "Import register values as flags",
|
||||||
".ar-", "", "Unflag all registers",
|
".ar-", "", "Unflag all registers",
|
||||||
"ar0", "", "Reset register arenas to 0",
|
"ar0", "", "Reset register arenas to 0",
|
||||||
|
@ -4005,6 +4006,9 @@ void cmd_anal_reg(RCore *core, const char *str) {
|
||||||
pj_free (pj);
|
pj_free (pj);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case ',': // "ar,"
|
||||||
|
__tableRegList (core, core->anal->reg, str + 1);
|
||||||
|
break;
|
||||||
case '0': // "ar0"
|
case '0': // "ar0"
|
||||||
r_reg_arena_zero (core->anal->reg);
|
r_reg_arena_zero (core->anal->reg);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -328,6 +328,7 @@ static const char *help_msg_dr[] = {
|
||||||
"dr", "", "Show 'gpr' registers",
|
"dr", "", "Show 'gpr' registers",
|
||||||
"dr", " <register>=<val>", "Set register value",
|
"dr", " <register>=<val>", "Set register value",
|
||||||
"dr.", " >$snapshot", "Capture current register values in r2 alias file",
|
"dr.", " >$snapshot", "Capture current register values in r2 alias file",
|
||||||
|
"dr,", " [table-query]", "Enumerate registers in table format",
|
||||||
"dr8", "[1|2|4|8] [type]", "Display hexdump of gpr arena (WIP)",
|
"dr8", "[1|2|4|8] [type]", "Display hexdump of gpr arena (WIP)",
|
||||||
"dr=", "", "Show registers in columns",
|
"dr=", "", "Show registers in columns",
|
||||||
"dr?", "<register>", "Show value of given register",
|
"dr?", "<register>", "Show value of given register",
|
||||||
|
@ -2347,6 +2348,58 @@ static void cmd_debug_reg_print_packed_reg(RCore *core, RRegItem *item, char exp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *__table_format_string(RTable *t, int fmt) {
|
||||||
|
switch (fmt) {
|
||||||
|
case 'j': return r_table_tojson (t);
|
||||||
|
case 's': return r_table_tostring (t);
|
||||||
|
}
|
||||||
|
return r_table_tofancystring (t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __tableRegList (RCore *core, RReg *reg, const char *str) {
|
||||||
|
int i;
|
||||||
|
RRegItem *e;
|
||||||
|
RTable *t = r_core_table (core);
|
||||||
|
RTableColumnType *typeString = r_table_type ("string");
|
||||||
|
RTableColumnType *typeNumber = r_table_type ("number");
|
||||||
|
RTableColumnType *typeBoolean = r_table_type ("boolean");
|
||||||
|
r_table_add_column (t, typeNumber, "offset", 0);
|
||||||
|
r_table_add_column (t, typeNumber, "size", 0);
|
||||||
|
r_table_add_column (t, typeNumber, "psize", 0);
|
||||||
|
r_table_add_column (t, typeNumber, "index", 0);
|
||||||
|
r_table_add_column (t, typeNumber, "arena", 0);
|
||||||
|
r_table_add_column (t, typeBoolean, "float", 0);
|
||||||
|
r_table_add_column (t, typeString, "name", 0);
|
||||||
|
r_table_add_column (t, typeString, "flags", 0);
|
||||||
|
r_table_add_column (t, typeString, "comment", 0);
|
||||||
|
for (i = 0; i < R_REG_TYPE_LAST; i++) {
|
||||||
|
RList *list = r_reg_get_list (reg, i);
|
||||||
|
RListIter *iter;
|
||||||
|
r_list_foreach (list, iter, e) {
|
||||||
|
// sdb_fmt is not thread safe
|
||||||
|
r_table_add_row (t,
|
||||||
|
sdb_fmt ("%d", e->offset),
|
||||||
|
sdb_fmt ("%d", e->size),
|
||||||
|
sdb_fmt ("%d", e->packed_size),
|
||||||
|
sdb_fmt ("%d", e->index),
|
||||||
|
sdb_fmt ("%d", e->arena),
|
||||||
|
r_str_bool (e->is_float),
|
||||||
|
e->name? e->name: "",
|
||||||
|
e->flags? e->flags: "",
|
||||||
|
e->comment? e->comment: "",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char fmt = *str++;
|
||||||
|
const char *q = str;
|
||||||
|
if (r_table_query (t, q)) {
|
||||||
|
char *s = __table_format_string (t, fmt);
|
||||||
|
r_cons_printf ("%s\n", s);
|
||||||
|
free (s);
|
||||||
|
}
|
||||||
|
r_table_free (t);
|
||||||
|
}
|
||||||
|
|
||||||
static void cmd_debug_reg(RCore *core, const char *str) {
|
static void cmd_debug_reg(RCore *core, const char *str) {
|
||||||
char *arg;
|
char *arg;
|
||||||
|
@ -2922,6 +2975,13 @@ static void cmd_debug_reg(RCore *core, const char *str) {
|
||||||
r_debug_reg_list (core->dbg, R_REG_TYPE_GPR, bits, 0, use_color); // xxx detect which one is current usage
|
r_debug_reg_list (core->dbg, R_REG_TYPE_GPR, bits, 0, use_color); // xxx detect which one is current usage
|
||||||
r_reg_arena_swap (core->dbg->reg, false);
|
r_reg_arena_swap (core->dbg->reg, false);
|
||||||
break;
|
break;
|
||||||
|
case ',': // "dr,"
|
||||||
|
if (r_debug_reg_sync (core->dbg, R_REG_TYPE_GPR, false)) {
|
||||||
|
__tableRegList (core, core->dbg->reg, str + 1);
|
||||||
|
} else {
|
||||||
|
eprintf ("cannot retrieve registers from pid %d\n", core->dbg->pid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case '=': // "dr="
|
case '=': // "dr="
|
||||||
{
|
{
|
||||||
int pcbits2, pcbits = grab_bits (core, str + 1, &pcbits2);
|
int pcbits2, pcbits = grab_bits (core, str + 1, &pcbits2);
|
||||||
|
|
|
@ -427,7 +427,7 @@ typedef struct {
|
||||||
|
|
||||||
static bool __tableItemCallback(RFlagItem *flag, void *user) {
|
static bool __tableItemCallback(RFlagItem *flag, void *user) {
|
||||||
FlagTableData *ftd = user;
|
FlagTableData *ftd = user;
|
||||||
if (flag->name && *flag->name) {
|
if (!R_STR_ISEMPTY (flag->name)) {
|
||||||
RTable *t = ftd->t;
|
RTable *t = ftd->t;
|
||||||
const char *spaceName = (flag->space && flag->space->name)? flag->space->name: "";
|
const char *spaceName = (flag->space && flag->space->name)? flag->space->name: "";
|
||||||
const char *addr = sdb_fmt ("0x%08"PFMT64x, flag->offset);
|
const char *addr = sdb_fmt ("0x%08"PFMT64x, flag->offset);
|
||||||
|
|
|
@ -743,7 +743,7 @@ static bool __fcnstrValidField(char *field, int i) {
|
||||||
return !(is_ret && is_args && is_arg && is_arg_number);
|
return !(is_ret && is_args && is_arg && is_arg_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *types_list_to_fcnstr(RList *types) {
|
static char *__types_list_to_fcnstr(RList *types) {
|
||||||
char *type_kv = NULL, *k = NULL, *v = NULL;
|
char *type_kv = NULL, *k = NULL, *v = NULL;
|
||||||
char *field = NULL, *name = NULL, *rettype = NULL;
|
char *field = NULL, *name = NULL, *rettype = NULL;
|
||||||
char *arg = NULL, *ret = NULL;
|
char *arg = NULL, *ret = NULL;
|
||||||
|
@ -796,11 +796,9 @@ static const char *types_list_to_fcnstr(RList *types) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_list_length (args) > 0) {
|
ret = (r_list_length (args) > 0)
|
||||||
ret = r_str_newf ("%s%s);", ret, (char *)r_list_get_top (args));
|
? r_str_newf ("%s%s);", ret, (char *)r_list_get_top (args))
|
||||||
} else {
|
: r_str_newf ("%s);", ret);
|
||||||
ret = r_str_newf ("%s);", ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
r_list_free (args);
|
r_list_free (args);
|
||||||
free (rettype);
|
free (rettype);
|
||||||
|
@ -813,7 +811,7 @@ static void addFlag(RCore *core, RSignItem *it, ut64 addr, int size, int count,
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
|
|
||||||
if (it->types) {
|
if (it->types) {
|
||||||
char *fcnstr = types_list_to_fcnstr (it->types);
|
char *fcnstr = __types_list_to_fcnstr (it->types);
|
||||||
char *fcnstr_copy = strdup (fcnstr);
|
char *fcnstr_copy = strdup (fcnstr);
|
||||||
fcn = r_anal_get_fcn_in (core->anal, it->addr, 0);
|
fcn = r_anal_get_fcn_in (core->anal, it->addr, 0);
|
||||||
if (fcn) {
|
if (fcn) {
|
||||||
|
|
Loading…
Reference in New Issue