Unscramble Register Printing and Flags Logic (#1920)

* Added rz_analysis_get_address_bits() instead of arch-specific hacks in core
* flags are only set for address-sized registers
* dr/ar show registers of any size by default, but hiding registers that are entirely
  covered by others
This commit is contained in:
Florian Märkl 2021-11-17 11:44:14 +01:00 committed by GitHub
parent fd8d84b475
commit 289536cc04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 205 additions and 209 deletions

View file

@ -308,6 +308,21 @@ RZ_API bool rz_analysis_set_bits(RzAnalysis *analysis, int bits) {
return false;
}
/**
* \brief The actual size of an address in bits.
*
* This may differ from analysis.bits in some cases such as arm thumb
* being identified as bits=16, but still using 32-bit addresses,
* or "8-bit" architectures like 6502 which still use 16-bit addresses.
*/
RZ_API int rz_analysis_get_address_bits(RzAnalysis *analysis) {
if (!analysis->cur || !analysis->cur->address_bits) {
return analysis->bits;
}
int r = analysis->cur->address_bits(analysis, analysis->bits);
return r > 0 ? r : analysis->bits;
}
RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu) {
free(analysis->cpu);
analysis->cpu = cpu ? strdup(cpu) : NULL;

View file

@ -950,12 +950,17 @@ static int esil_6502_fini(RzAnalysisEsil *esil) {
return true;
}
static int address_bits(RzAnalysis *analysis, int bits) {
return 16;
}
RzAnalysisPlugin rz_analysis_plugin_6502 = {
.name = "6502",
.desc = "6502/NES analysis plugin",
.license = "LGPL3",
.arch = "6502",
.bits = 8,
.address_bits = address_bits,
.op = &_6502_op,
.set_reg_profile = &set_reg_profile,
.esil = true,

View file

@ -194,12 +194,17 @@ static bool set_reg_profile(RzAnalysis *analysis) {
return rz_reg_set_profile_string(analysis->reg, p);
}
static int address_bits(RzAnalysis *analysis, int bits) {
return 16;
}
RzAnalysisPlugin rz_analysis_plugin_6502_cs = {
.name = "6502.cs",
.desc = "Capstone mos65xx analysis plugin",
.license = "LGPL3",
.arch = "6502",
.bits = 8,
.address_bits = address_bits,
.op = &analop,
.set_reg_profile = &set_reg_profile,
};

View file

@ -4507,6 +4507,11 @@ static RzList *analysis_preludes(RzAnalysis *analysis) {
return l;
}
static int address_bits(RzAnalysis *analysis, int bits) {
// thumb still has 32bit addrs, all other cases use the default behavior (-1)
return bits == 16 ? 32 : -1;
}
static bool init(void **user) {
ArmCSContext *ctx = RZ_NEW0(ArmCSContext);
if (!ctx) {
@ -4542,6 +4547,7 @@ RzAnalysisPlugin rz_analysis_plugin_arm_cs = {
.analysis_mask = analysis_mask,
.preludes = analysis_preludes,
.bits = 16 | 32 | 64,
.address_bits = address_bits,
.op = &analop,
.init = &init,
.fini = &fini,

View file

@ -473,6 +473,11 @@ static int archinfo(RzAnalysis *analysis, int q) {
return 4; // XXX
}
static int address_bits(RzAnalysis *analysis, int bits) {
// thumb still has 32bit addrs, all other cases use the default behavior (-1)
return bits == 16 ? 32 : -1;
}
RzAnalysisPlugin rz_analysis_plugin_arm_gnu = {
.name = "arm.gnu",
.arch = "arm",
@ -480,6 +485,7 @@ RzAnalysisPlugin rz_analysis_plugin_arm_gnu = {
.bits = 16 | 32 | 64,
.desc = "ARM code analysis plugin",
.archinfo = archinfo,
.address_bits = address_bits,
.op = &arm_op,
.set_reg_profile = set_reg_profile,
};

View file

@ -2090,6 +2090,10 @@ static ut8 *analysis_mask_avr(RzAnalysis *analysis, int size, const ut8 *data, u
return ret;
}
static int address_bits(RzAnalysis *analysis, int bits) {
return bits == 8 ? 16 : -1;
}
RzAnalysisPlugin rz_analysis_plugin_avr = {
.name = "avr",
.desc = "AVR code analysis plugin",
@ -2098,6 +2102,7 @@ RzAnalysisPlugin rz_analysis_plugin_avr = {
.esil = true,
.archinfo = archinfo,
.bits = 8 | 16, // 24 big regs conflicts
.address_bits = address_bits,
.op = &avr_op,
.set_reg_profile = &set_reg_profile,
.esil_init = esil_avr_init,

View file

@ -55,11 +55,11 @@ RZ_API bool rz_core_debug_step_one(RzCore *core, int times) {
rz_debug_trace_pc(core->dbg, pc);
if (!rz_debug_step(core->dbg, times)) {
eprintf("Step failed\n");
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
core->break_loop = true;
return false;
}
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
} else {
int i = 0;
do {
@ -79,7 +79,7 @@ RZ_IPI void rz_core_debug_continue(RzCore *core) {
core->dbg->continue_all_threads = true;
#endif
rz_debug_continue(core->dbg);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_cons_break_pop();
rz_core_dbg_follow_seek_register(core);
} else {
@ -153,7 +153,7 @@ RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr, ut64 to) {
rz_debug_step(core->dbg, 1);
steps++;
}
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_cons_break_pop();
return true;
}
@ -164,7 +164,7 @@ RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr, ut64 to) {
eprintf("Cannot continue, run ood?\n");
} else {
rz_debug_continue(core->dbg);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
}
rz_bp_del(core->dbg->bp, addr);
} else {
@ -190,31 +190,19 @@ static void regs_to_flags(RzCore *core, int size) {
}
}
static int get_regs_bits(RzCore *core) {
// Copied from cmd_analysis.c:__analysis_reg_list
int bits = core->analysis->bits;
if (!strcmp(core->analysis->cur->arch, "arm") && bits == 16) {
/* workaround for thumb */
bits = 32;
} else if ((!strcmp(core->analysis->cur->arch, "6502") && bits == 8) || (!strcmp(core->analysis->cur->arch, "avr") && bits == 8)) {
/* workaround for 6502 and avr*/
regs_to_flags(core, 16);
}
return bits;
}
RZ_IPI void rz_core_regs2flags(RzCore *core) {
rz_flag_space_push(core->flags, RZ_FLAGS_FS_REGISTERS);
int size = get_regs_bits(core);
int size = rz_analysis_get_address_bits(core->analysis);
regs_to_flags(core, size);
rz_flag_space_pop(core->flags);
}
RZ_IPI void rz_core_debug_regs2flags(RzCore *core, int bits) {
/// update or create flags for all registers where it makes sense (regs that have the same size as an address)
RZ_IPI void rz_core_debug_regs2flags(RzCore *core) {
if (core->bin->is_debugger) {
if (rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_GPR, false)) {
rz_flag_space_push(core->flags, RZ_FLAGS_FS_REGISTERS);
int size = bits <= 0 ? get_regs_bits(core) : bits;
int size = rz_analysis_get_address_bits(core->analysis);
regs_to_flags(core, size);
rz_flag_space_pop(core->flags);
}
@ -224,7 +212,6 @@ RZ_IPI void rz_core_debug_regs2flags(RzCore *core, int bits) {
}
RZ_IPI bool rz_core_debug_reg_set(RzCore *core, const char *regname, ut64 val, const char *strval) {
int bits = (core->dbg->bits & RZ_SYS_BITS_64) ? 64 : 32;
RzRegItem *r = rz_reg_get(core->dbg->reg, regname, -1);
if (!r) {
int role = rz_reg_get_name_idx(regname);
@ -251,19 +238,71 @@ RZ_IPI bool rz_core_debug_reg_set(RzCore *core, const char *regname, ut64 val, c
rz_reg_set_value(core->dbg->reg, r, val);
}
rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_ANY, true);
rz_core_debug_regs2flags(core, bits);
rz_core_debug_regs2flags(core);
return true;
}
RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, PJ *pj, int rad, const char *use_color) {
static bool foreach_reg_cb(RzIntervalNode *node, void *user) {
RzRegItem *from_list = user;
RzRegItem *from_tree = node->data;
if (from_list == from_tree) {
return true;
}
// Check if from_list is covered entirely by from_tree, but is also smaller than it.
// We already know that
// from_tree->offset <= from_list->offset < from_tree->offset + from_tree->size
if (from_list->offset + from_list->size > from_tree->offset + from_tree->size) {
// from_list expands beyond from_tree, so it's not covered
return true;
}
if (from_list->offset + from_list->size == from_tree->offset + from_tree->size) {
// they end at the same position, so it is covered entirely, but is it also smaller?
if (from_list->offset == from_tree->offset) {
// nope
return true;
}
}
// from_list ends before from_tree, so it is covered and smaller
return false;
}
/// Filter out all registers that are smaller than but covered entirely by some other register
static RZ_OWN RzList *regs_filter_covered(RZ_BORROW const RzList /* <RzRegItem> */ *regs) {
RzList *ret = rz_list_new();
if (!ret) {
return NULL;
}
RzIntervalTree t;
rz_interval_tree_init(&t, NULL);
RzRegItem *item;
RzListIter *it;
rz_list_foreach (regs, it, item) {
if (item->offset < 0 || item->size <= 0) {
continue;
}
rz_interval_tree_insert(&t, item->offset, item->offset + item->size - 1, item);
}
rz_list_foreach (regs, it, item) {
if (item->offset < 0 || item->size <= 0) {
rz_list_push(ret, item);
continue;
}
if (!rz_interval_tree_all_in(&t, item->offset, true, foreach_reg_cb, item)) {
// foreach_reg_cb break-ed so it found a cover
continue;
}
rz_list_push(ret, item);
}
rz_interval_tree_fini(&t);
return ret;
}
RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, bool skip_covered, PJ *pj, int rad, const char *use_color) {
RzDebug *dbg = core->dbg;
int delta, cols, n = 0;
const char *fmt, *fmt2, *kwhites;
RzPrint *pr = NULL;
int colwidth = 20;
RzListIter *iter;
RzRegItem *item;
const RzList *head;
ut64 diff;
char strvalue[256];
bool isJson = (rad == 'j' || rad == 'J');
@ -303,13 +342,22 @@ RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, PJ *pj, int
int itmidx = -1;
dbg->creg = NULL;
head = rz_reg_get_list(dbg->reg, type);
const RzList *head = rz_reg_get_list(dbg->reg, type);
if (!head) {
return false;
}
if (rad == 1 || rad == '*') {
rz_cons_printf("fs+%s\n", RZ_FLAGS_FS_REGISTERS);
}
RzList *filtered_list = NULL;
if (skip_covered) {
filtered_list = regs_filter_covered(head);
if (filtered_list) {
head = filtered_list;
}
}
RzListIter *iter;
RzRegItem *item;
rz_list_foreach (head, iter, item) {
ut64 value;
utX valueBig;
@ -456,6 +504,7 @@ RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, PJ *pj, int
rz_cons_printf("fs-\n");
}
beach:
rz_list_free(filtered_list);
if (isJson) {
pj_end(pj);
} else if (n > 0 && (rad == 2 || rad == '=') && ((n % cols))) {
@ -558,13 +607,13 @@ RZ_IPI void rz_core_debug_single_step_over(RzCore *core) {
rz_cons_break_push(rz_core_static_debug_stop, core->dbg);
rz_reg_arena_swap(core->dbg->reg, true);
rz_debug_continue_until_optype(core->dbg, RZ_ANALYSIS_OP_TYPE_RET, 1);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_cons_break_pop();
rz_core_dbg_follow_seek_register(core);
core->print->cur_enabled = 0;
} else {
rz_core_cmd(core, "dso", 0);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
}
} else {
rz_core_analysis_esil_step_over(core);
@ -694,7 +743,7 @@ RZ_IPI void rz_core_debug_print_status(RzCore *core) {
const char *use_color = core->cons->context->pal.creg
? core->cons->context->pal.creg
: Color_BWHITE;
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, core->dbg->bits, NULL, 3, use_color);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, core->dbg->bits, true, NULL, 3, use_color);
ut64 old_address = core->offset;
rz_core_seek(core, rz_debug_reg_get(core->dbg, "PC"), true);
rz_core_print_disasm_instructions(core, 0, 1);

View file

@ -430,7 +430,7 @@ RZ_API int rz_core_file_reopen(RzCore *core, const char *args, int perm, int loa
rz_core_seek(core, origoff, true);
if (isdebug) {
rz_core_cmd0(core, ".dm*");
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_core_seek_to_register(core, "PC", false);
} else {
loadGP(core);

View file

@ -375,7 +375,6 @@ RZ_IPI void rz_core_analysis_esil_emulate_bb(RzCore *core) {
}
RZ_IPI int rz_core_analysis_set_reg(RzCore *core, const char *regname, ut64 val) {
int bits = (core->analysis->bits & RZ_SYS_BITS_64) ? 64 : 32;
RzRegItem *r = rz_reg_get(core->dbg->reg, regname, -1);
if (!r) {
int role = rz_reg_get_name_idx(regname);
@ -392,7 +391,7 @@ RZ_IPI int rz_core_analysis_set_reg(RzCore *core, const char *regname, ut64 val)
}
rz_reg_set_value(core->dbg->reg, r, val);
rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_ANY, true);
rz_core_debug_regs2flags(core, bits);
rz_core_debug_regs2flags(core);
return 0;
}

View file

@ -25,7 +25,7 @@ RZ_API int rz_core_setup_debugger(RzCore *r, const char *debugbackend, bool atta
}
//this makes to attach twice showing warnings in the output
//we get "resource busy" so it seems isn't an issue
rz_core_debug_regs2flags(r, 0);
rz_core_debug_regs2flags(r);
/* honor dbg.bep */
{
const char *bep = rz_config_get(r->config, "dbg.bep");

View file

@ -1629,7 +1629,7 @@ static int rz_core_cmd_subst(RzCore *core, char *cmd) {
// XXX: do not flush here, we need rz_cons_push () and rz_cons_pop()
rz_cons_flush();
// XXX: we must import register flags in C
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
(void)rz_core_cmd0(core, cr);
}
free(cr);

View file

@ -3408,8 +3408,10 @@ RZ_IPI int rz_cmd_analysis_fcn(void *data, const char *input) {
return true;
}
// size: 0: bits; -1: any; >0: exact size
static void __analysis_reg_list(RzCore *core, int type, int bits, char mode) {
/**
* \param bits if > 0, show only regs with this bit size, otherwise all
*/
static void print_reg_list(RzCore *core, int type, int bits, bool skip_covered, char mode) {
PJ *pj = NULL;
if (mode == 'i') {
rz_core_debug_ri(core, core->analysis->reg, 0);
@ -3431,53 +3433,11 @@ static void __analysis_reg_list(RzCore *core, int type, int bits, char mode) {
} else {
use_color = NULL;
}
if (bits < 0) {
// TODO Change the `size` argument of rz_core_debug_reg_list to use -1 for any and 0 for analysis->bits
bits = 0;
} else if (!bits) {
bits = core->analysis->bits;
}
int mode2 = mode;
if (core->analysis) {
core->dbg->reg = core->analysis->reg;
if (core->analysis->cur && core->analysis->cur->arch) {
/* workaround for thumb */
if (!strcmp(core->analysis->cur->arch, "arm") && bits == 16) {
bits = 32;
}
/* workaround for 6502 and avr*/
if ((!strcmp(core->analysis->cur->arch, "6502") && bits == 8) || (!strcmp(core->analysis->cur->arch, "avr") && bits == 8)) {
if (mode == 'j') {
mode2 = 'J';
pj_o(pj);
}
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, 16, pj, mode2, use_color); // XXX detect which one is current usage
}
}
}
if (mode == '=') {
int pcbits = 0;
const char *pcname = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_PC);
if (pcname) {
RzRegItem *reg = rz_reg_get(core->analysis->reg, pcname, 0);
if (reg && bits != reg->size) {
pcbits = reg->size;
}
if (pcbits) {
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, NULL, mode, use_color); // XXX detect which one is current usage
}
}
}
rz_core_debug_reg_list(core, type, bits, pj, mode2, use_color);
rz_core_debug_reg_list(core, type, bits, skip_covered, pj, mode, use_color);
if (mode == 'j') {
if (mode2 == 'J') {
pj_end(pj);
}
rz_cons_println(pj_string(pj));
pj_free(pj);
}
core->dbg->reg = hack;
}
@ -3494,7 +3454,7 @@ void cmd_analysis_reg(RzCore *core, const char *str) {
return;
}
int size = 0, i, type = RZ_REG_TYPE_GPR;
int i, type = RZ_REG_TYPE_GPR;
int bits = (core->analysis->bits & RZ_SYS_BITS_64) ? 64 : 32;
int use_colors = rz_config_get_i(core->config, "scr.color");
const char *use_color;
@ -3746,15 +3706,16 @@ void cmd_analysis_reg(RzCore *core, const char *str) {
}
break;
case 'd': // "ard"
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, NULL, 3, use_color); // XXX detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, false, NULL, 3, use_color); // XXX detect which one is current usage
break;
case 'o': // "aro"
rz_reg_arena_swap(core->dbg->reg, false);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, NULL, 0, use_color); // XXX detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, false, NULL, 0, use_color); // XXX detect which one is current usage
rz_reg_arena_swap(core->dbg->reg, false);
break;
case '=': // "ar="
{
int size = 0;
char *p = NULL;
char *bits = NULL;
if (str[1]) {
@ -3787,7 +3748,7 @@ void cmd_analysis_reg(RzCore *core, const char *str) {
}
}
}
__analysis_reg_list(core, type, size, str[0]);
print_reg_list(core, type, size, !size, str[0]);
if (!rz_list_empty(core->dbg->q_regs)) {
rz_list_free(core->dbg->q_regs);
}
@ -3801,7 +3762,7 @@ void cmd_analysis_reg(RzCore *core, const char *str) {
case 'j': // "arj"
case 'i': // "ari"
case '\0': // "ar"
__analysis_reg_list(core, type, size, str[0]);
print_reg_list(core, type, 0, true, str[0]);
break;
case ' ': { // "ar "
arg = strchr(str + 1, '=');
@ -3825,12 +3786,12 @@ void cmd_analysis_reg(RzCore *core, const char *str) {
if (j - i + 1 <= sizeof name) {
rz_str_ncpy(name, str + i, j - i + 1);
if (IS_DIGIT(name[0])) { // e.g. ar 32
__analysis_reg_list(core, RZ_REG_TYPE_GPR, atoi(name), '\0');
print_reg_list(core, RZ_REG_TYPE_GPR, atoi(name), false, '\0');
} else if (showreg(core, name) > 0) { // e.g. ar rax
} else { // e.g. ar gpr ; ar all
type = rz_reg_type_by_name(name);
// TODO differentiate ALL and illegal register types and print error message for the latter
__analysis_reg_list(core, type, -1, '\0');
print_reg_list(core, type, 0, true, '\0');
}
}
i = j;

View file

@ -602,7 +602,7 @@ static int step_until(RzCore *core, ut64 addr) {
off = rz_debug_reg_get(core->dbg, "PC");
// check breakpoint here
} while (off != addr);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_cons_break_pop();
return true;
}
@ -691,7 +691,7 @@ static bool step_until_inst(RzCore *core, const char *instr, bool regex) {
}
}
}
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_cons_break_pop();
return true;
}
@ -776,7 +776,7 @@ static int step_until_optype(RzCore *core, RzList *optypes_list) {
}
cleanup_after_push:
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_cons_break_pop();
end:
return res;
@ -814,7 +814,7 @@ static int step_until_flag(RzCore *core, const char *instr) {
}
}
beach:
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_cons_break_pop();
return true;
}
@ -834,7 +834,7 @@ static int step_until_eof(RzCore *core) {
break;
}
} while (off <= now);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
rz_cons_break_pop();
return true;
}
@ -867,7 +867,7 @@ static int step_line(RzCore *core, int times) {
if (find_meta) {
continue;
}
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
eprintf("Cannot retrieve dwarf info at 0x%08" PFMT64x "\n", off);
return false;
}
@ -877,7 +877,7 @@ static int step_line(RzCore *core, int times) {
tmp_ptr = rz_file_slurp_line(file2, line2, 0);
eprintf("--> %s\n", tmp_ptr);
free(tmp_ptr);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
return true;
}
@ -2080,7 +2080,7 @@ static void cmd_debug_reg(RzCore *core, const char *str) {
}
} break;
case '-': // "dr-"
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, NULL, '-', 0);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, false, NULL, '-', 0);
break;
case '?': // "dr?"
if (str[1]) {
@ -2458,10 +2458,10 @@ static void cmd_debug_reg(RzCore *core, const char *str) {
} else { // drm # no arg
if (str[1] == 'y') { // drmy
rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_YMM, false);
rz_core_debug_reg_list(core, RZ_REG_TYPE_YMM, 256, NULL, 0, 0);
rz_core_debug_reg_list(core, RZ_REG_TYPE_YMM, 256, false, NULL, 0, 0);
} else { // drm
rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_XMM, false);
rz_core_debug_reg_list(core, RZ_REG_TYPE_XMM, 128, NULL, 0, 0);
rz_core_debug_reg_list(core, RZ_REG_TYPE_XMM, 128, false, NULL, 0, 0);
}
}
//rz_debug_drx_list (core->dbg);
@ -2557,11 +2557,11 @@ static void cmd_debug_reg(RzCore *core, const char *str) {
}
type = rz_reg_type_by_name(str + 2);
rz_debug_reg_sync(core->dbg, type, false);
rz_core_debug_reg_list(core, type, size, NULL, rad, use_color);
rz_core_debug_reg_list(core, type, size, false, NULL, rad, use_color);
} else {
if (type != RZ_REG_TYPE_LAST) {
rz_debug_reg_sync(core->dbg, type, false);
rz_core_debug_reg_list(core, type, size, NULL, rad, use_color);
rz_core_debug_reg_list(core, type, size, false, NULL, rad, use_color);
} else {
eprintf("cmd_debug_reg: unknown type\n");
}
@ -2586,11 +2586,11 @@ static void cmd_debug_reg(RzCore *core, const char *str) {
free(foo);
} break;
case 'd': // "drd"
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, NULL, 3, use_color); // xxx detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, false, NULL, 3, use_color); // xxx detect which one is current usage
break;
case 'o': // "dro"
rz_reg_arena_swap(core->dbg->reg, false);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, NULL, 0, use_color); // xxx detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, false, NULL, 0, use_color); // xxx detect which one is current usage
rz_reg_arena_swap(core->dbg->reg, false);
break;
case ',': // "dr,"
@ -2606,37 +2606,37 @@ static void cmd_debug_reg(RzCore *core, const char *str) {
if (rz_config_get_b(core->config, "cfg.debug")) {
if (rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_GPR, false)) {
if (pcbits && pcbits != bits) {
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, NULL, '=', use_color); // xxx detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, false, NULL, '=', use_color); // xxx detect which one is current usage
}
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, NULL, '=', use_color); // xxx detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, false, NULL, '=', use_color); // xxx detect which one is current usage
if (pcbits2) {
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits2, NULL, '=', use_color); // xxx detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits2, false, NULL, '=', use_color); // xxx detect which one is current usage
}
} //else eprintf ("cannot retrieve registers from pid %d\n", core->dbg->pid);
} else {
RzReg *orig = core->dbg->reg;
core->dbg->reg = core->analysis->reg;
if (pcbits && pcbits != bits)
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, NULL, '=', use_color); // xxx detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, NULL, '=', use_color); // xxx detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, false, NULL, '=', use_color); // xxx detect which one is current usage
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, bits, false, NULL, '=', use_color); // xxx detect which one is current usage
core->dbg->reg = orig;
}
} break;
case '.':
if (rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_GPR, false)) {
int pcbits2, pcbits = grab_bits(core, str + 1, &pcbits2);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, NULL, '.', use_color);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, false, NULL, '.', use_color);
if (pcbits2) {
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits2, NULL, '.', use_color);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits2, false, NULL, '.', use_color);
}
}
break;
case '*': // "dr*"
if (rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_GPR, false)) {
int pcbits2, pcbits = grab_bits(core, str + 1, &pcbits2);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, NULL, '*', use_color);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, false, NULL, '*', use_color);
if (pcbits2) {
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits2, NULL, '*', use_color);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits2, false, NULL, '*', use_color);
}
rz_flag_space_pop(core->flags);
}
@ -2657,22 +2657,14 @@ static void cmd_debug_reg(RzCore *core, const char *str) {
case 'j': // "drj"
case '\0': // "dr"
if (rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_GPR, false)) {
int pcbits = core->analysis->bits;
const char *pcname = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_PC);
RzRegItem *reg = rz_reg_get(core->analysis->reg, pcname, 0);
if (reg) {
if (core->rasm->bits != reg->size) {
pcbits = reg->size;
}
}
if (str[0] == 'j') {
PJ *pj = pj_new();
if (!pj) {
return;
}
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, pj, 'j', use_color);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, 0, true, pj, 'j', use_color);
} else {
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, pcbits, NULL, 0, use_color);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, 0, true, NULL, 0, use_color);
}
} else {
eprintf("cannot retrieve registers from pid %d\n", core->dbg->pid);
@ -2695,7 +2687,7 @@ static void cmd_debug_reg(RzCore *core, const char *str) {
size = atoi(str + 1);
if (size) {
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, size, NULL, str[0], use_color);
rz_core_debug_reg_list(core, RZ_REG_TYPE_GPR, size, false, NULL, str[0], use_color);
} else {
char *comma = strchr(str + 1, ',');
if (comma) {
@ -3498,7 +3490,7 @@ RZ_IPI int rz_cmd_debug_step(void *data, const char *input) {
core->break_loop = true;
break;
}
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
n++;
} while (!rz_num_conditional(core->num, input + 2));
rz_cons_break_pop();
@ -3562,7 +3554,7 @@ RZ_IPI int rz_cmd_debug_step(void *data, const char *input) {
}
rz_debug_step(core->dbg, 1);
}
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
break;
case 's': // "dss"
{
@ -3585,7 +3577,7 @@ RZ_IPI int rz_cmd_debug_step(void *data, const char *input) {
}
rz_debug_reg_set(core->dbg, "PC", addr);
rz_reg_setv(core->analysis->reg, "PC", addr);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
if (bpi) {
(void)rz_debug_bp_add(core->dbg, addr, hwbp, false, 0, NULL, 0);
}
@ -3605,7 +3597,7 @@ RZ_IPI int rz_cmd_debug_step(void *data, const char *input) {
if (bpi) {
(void)rz_debug_bp_add(core->dbg, addr, hwbp, false, 0, NULL, 0);
}
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
} else {
for (i = 0; i < times; i++) {
rz_core_analysis_esil_step_over(core);
@ -3620,7 +3612,7 @@ RZ_IPI int rz_cmd_debug_step(void *data, const char *input) {
} else if (rz_debug_step_back(core->dbg, times) < 0) {
eprintf("Error: stepping back failed\n");
} else {
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
}
} else {
if (!rz_core_esil_step_back(core)) {

View file

@ -118,8 +118,8 @@ RZ_IPI RzCmdStatus rz_core_binldr_plugin_print(const RzBinLdrPlugin *ld, RzCmdSt
/* cdebug.c */
RZ_IPI bool rz_core_debug_reg_set(RzCore *core, const char *regname, ut64 val, const char *strval);
RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, PJ *pj, int rad, const char *use_color);
RZ_IPI void rz_core_debug_regs2flags(RzCore *core, int bits);
RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, bool skip_covered, PJ *pj, int rad, const char *use_color);
RZ_IPI void rz_core_debug_regs2flags(RzCore *core);
RZ_IPI void rz_core_regs2flags(RzCore *core);
RZ_IPI void rz_core_debug_single_step_in(RzCore *core);
RZ_IPI void rz_core_debug_single_step_over(RzCore *core);

View file

@ -3970,7 +3970,7 @@ void __print_disassembly_cb(void *user, void *p) {
core->offset = panel->model->addr;
rz_core_seek(core, panel->model->addr, true);
if (rz_config_get_b(core->config, "cfg.debug")) {
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
}
cmdstr = __handle_cmd_str_cache(core, panel, false);
core->offset = o_offset;
@ -4794,7 +4794,7 @@ void __do_panels_refreshOneShot(RzCore *core) {
void __panel_single_step_in(RzCore *core) {
if (rz_config_get_b(core->config, "cfg.debug")) {
rz_core_debug_step_one(core, 1);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
} else {
rz_core_esil_step(core, UT64_MAX, NULL, NULL, false);
rz_core_regs2flags(core);
@ -4806,7 +4806,7 @@ void __panel_single_step_over(RzCore *core) {
rz_config_set_b(core->config, "io.cache", false);
if (rz_config_get_b(core->config, "cfg.debug")) {
rz_core_cmd(core, "dso", 0);
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
} else {
rz_core_analysis_esil_step_over(core);
}

View file

@ -769,7 +769,7 @@ RZ_API int rz_core_visual_prompt(RzCore *core) {
rz_cons_flush();
ret = true;
if (rz_config_get_b(core->config, "cfg.debug")) {
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
}
} else {
ret = false;
@ -4016,7 +4016,7 @@ RZ_API int rz_core_visual(RzCore *core, const char *input) {
rz_core_seek(core, scrseek, true);
}
if (debug) {
rz_core_debug_regs2flags(core, 0);
rz_core_debug_regs2flags(core);
}
core->print->vflush = !skip;
visual_refresh(core);

View file

@ -1221,6 +1221,12 @@ typedef struct rz_analysis_plugin_t {
ut8 *(*analysis_mask)(RzAnalysis *analysis, int size, const ut8 *data, ut64 at);
RzList *(*preludes)(RzAnalysis *analysis);
/**
* The actual bit-size of an address for given analysis.bits.
* If unimplemented or returns <= 0, analysis.bits will be used as-is.
*/
int (*address_bits)(RzAnalysis *analysis, int bits);
// legacy rz_analysis_functions
RzAnalysisOpCallback op;
@ -1460,6 +1466,7 @@ RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const
RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp);
RZ_API void rz_analysis_remove_import(RzAnalysis *analysis, const char *imp);
RZ_API void rz_analysis_purge_imports(RzAnalysis *analysis);
RZ_API int rz_analysis_get_address_bits(RzAnalysis *analysis);
/* op.c */
RZ_API const char *rz_analysis_stackop_tostring(int s);

View file

@ -203,6 +203,7 @@ lr = 0x00000000
ctr = 0x00000000
msr = 0x00000000
pc = 0x10000320
cr = 0x00000000
xer = 0x00000000
mq = 0x00000000
fpscr = 0x00000000
@ -218,22 +219,14 @@ hid3 = 0x00000000
hid4 = 0x00000000
hid5 = 0x00000000
hid6 = 0x00000000
ibat0l = 0x00000000
ibat1l = 0x00000000
ibat2l = 0x00000000
ibat3l = 0x00000000
ibat0u = 0x00000000
ibat1u = 0x00000000
ibat2u = 0x00000000
ibat3u = 0x00000000
dbat0l = 0x00000000
dbat1l = 0x00000000
dbat2l = 0x00000000
dbat3l = 0x00000000
dbat0u = 0x00000000
dbat1u = 0x00000000
dbat2u = 0x00000000
dbat3u = 0x00000000
ibat0 = 0x00000000
ibat1 = 0x00000000
ibat2 = 0x00000000
ibat3 = 0x00000000
dbat0 = 0x00000000
dbat1 = 0x00000000
dbat2 = 0x00000000
dbat3 = 0x00000000
mask = 0x00000000
EOF
RUN
@ -283,6 +276,7 @@ lr = 0x00000000
ctr = 0x00000000
msr = 0x00000000
pc = 0x10000420
cr = 0x00000000
xer = 0x00000000
mq = 0x00000000
fpscr = 0x00000000
@ -298,22 +292,14 @@ hid3 = 0x00000000
hid4 = 0x00000000
hid5 = 0x00000000
hid6 = 0x00000000
ibat0l = 0x00000000
ibat1l = 0x00000000
ibat2l = 0x00000000
ibat3l = 0x00000000
ibat0u = 0x00000000
ibat1u = 0x00000000
ibat2u = 0x00000000
ibat3u = 0x00000000
dbat0l = 0x00000000
dbat1l = 0x00000000
dbat2l = 0x00000000
dbat3l = 0x00000000
dbat0u = 0x00000000
dbat1u = 0x00000000
dbat2u = 0x00000000
dbat3u = 0x00000000
ibat0 = 0x00000000
ibat1 = 0x00000000
ibat2 = 0x00000000
ibat3 = 0x00000000
dbat0 = 0x00000000
dbat1 = 0x00000000
dbat2 = 0x00000000
dbat3 = 0x00000000
mask = 0x00000000
EOF
RUN

View file

@ -746,52 +746,11 @@ EXPECT=<<EOF
0x00000000 2 x
0x00000000 2 z
0x00000000 2 pch
0x00000000 1 r0
0x00000000 1 r1
0x00000000 1 r2
0x00000000 1 r3
0x00000000 1 r4
0x00000000 1 r5
0x00000000 1 r6
0x00000000 1 r7
0x00000000 1 r8
0x00000000 1 r9
0x00000000 1 r10
0x00000000 1 r11
0x00000000 1 r12
0x00000000 1 r13
0x00000000 1 r14
0x00000000 1 r15
0x00000000 1 r16
0x00000000 1 r17
0x00000000 1 r18
0x00000000 1 r19
0x00000000 1 r20
0x00000000 1 r21
0x00000000 1 r22
0x00000000 1 r23
0x00000000 1 r24
0x00000000 1 r25
0x00000000 1 r26
0x00000000 1 r27
0x00000000 1 r28
0x00000000 1 r30
0x00000000 1 r31
0x00000000 1 spl
0x00000000 1 sreg
0x00000000 1 rampx
0x00000000 1 rampy
0x00000000 1 rampz
0x00000000 1 rampd
0x00000000 1 eind
0x00000000 1 spmcsr
0x00000037 1 SPMCSR
0x0000003d 1 SPL
0x0000003e 1 SPH
0x0000003f 1 SREG
0x00000066 4 aav.0x00000066
0x00000080 1 r29
0x00000080 1 sph
0x00000158 13478 entry0
0x00000158 2 pcl
0x000001ba 188 fcn.000001ba

View file

@ -22,7 +22,7 @@ RUN
NAME=AVR: des encrypt
FILE=malloc://1024
CMDS=<<EOF
(regs ;ar 8~:6..22) # show regs r0-r15
(regs ;ar 8~:0..16) # show regs r0-r15
e asm.arch=avr
wx 0b941b942b943b944b945b946b947b948b949b94ab94bb94cb94db94eb94fb94
ar r0 = 0x41
@ -357,7 +357,7 @@ RUN
NAME=AVR: des decrypt
FILE=malloc://1024
CMDS=<<EOF
(regs ;ar 8~:6..22) # show regs r0-r15
(regs ;ar 8~:0..16) # show regs r0-r15
e asm.arch=avr
wx 58940b941b942b943b944b945b946b947b948b949b94ab94bb94cb94db94eb94fb94
ar r0 = 0xf5

View file

@ -200,6 +200,7 @@ CMDS=<<EOF
dr
EOF
EXPECT=<<EOF
wzr = 0x00000000
x0 = 0x00000000
x1 = 0x7ff5eb5ed8
x2 = 0x7ff5eb5ee8