From 87e369b9a7c5d7d6c5a1f1408d0f44cb3a57e33c Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Mon, 10 Oct 2022 22:10:48 +0800 Subject: [PATCH] Convert `de` commands to the rzshell (#3083) --- librz/core/cesil.c | 34 ++++++ librz/core/cmd/cmd_debug.c | 162 +++++++++------------------- librz/core/cmd_descs/cmd_debug.yaml | 61 +++++++++++ librz/core/cmd_descs/cmd_descs.c | 113 +++++++++++++++++++ librz/core/cmd_descs/cmd_descs.h | 6 ++ librz/core/core_private.h | 1 + librz/debug/desil.c | 41 +++---- librz/include/rz_debug.h | 8 +- 8 files changed, 289 insertions(+), 137 deletions(-) diff --git a/librz/core/cesil.c b/librz/core/cesil.c index 3b67e41e7ec..6daabb83691 100644 --- a/librz/core/cesil.c +++ b/librz/core/cesil.c @@ -326,3 +326,37 @@ RZ_API bool rz_core_esil_dumpstack(RzAnalysisEsil *esil) { } return true; } + +RZ_IPI void rz_core_debug_esil_watch_print(RzDebug *dbg, RzCmdStateOutput *state) { + RzDebugEsilWatchpoint *ew; + RzListIter *iter; + RzList *watchpoints = rz_debug_esil_watch_list(dbg); + rz_cmd_state_output_array_start(state); + rz_cmd_state_output_set_columnsf(state, "sss", "permissions", "kind", "expression"); + rz_list_foreach (watchpoints, iter, ew) { + switch (state->mode) { + case RZ_OUTPUT_MODE_JSON: + pj_o(state->d.pj); + pj_ks(state->d.pj, "permissions", rz_str_rwx_i(ew->rwx)); + pj_ks(state->d.pj, "kind", ew->dev == 'r' ? "reg" : "mem"); + pj_ks(state->d.pj, "expression", ew->expr); + pj_end(state->d.pj); + break; + case RZ_OUTPUT_MODE_TABLE: + rz_table_add_rowf(state->d.t, "sss", + rz_str_rwx_i(ew->rwx), ew->dev == 'r' ? "reg" : "mem", + ew->expr); + break; + case RZ_OUTPUT_MODE_STANDARD: + rz_cons_printf("%s %c %s\n", rz_str_rwx_i(ew->rwx), ew->dev, ew->expr); + break; + case RZ_OUTPUT_MODE_RIZIN: + rz_cons_printf("de %s %c %s\n", rz_str_rwx_i(ew->rwx), ew->dev, ew->expr); + break; + default: + rz_warn_if_reached(); + break; + } + } + rz_cmd_state_output_array_end(state); +} diff --git a/librz/core/cmd/cmd_debug.c b/librz/core/cmd/cmd_debug.c index b475cf337e4..9dbbc2ded2c 100644 --- a/librz/core/cmd/cmd_debug.c +++ b/librz/core/cmd/cmd_debug.c @@ -68,24 +68,6 @@ static const char *help_msg_dcu[] = { NULL }; -static const char *help_msg_de[] = { - "Usage:", "de", "[-sc] [perm] [rm] [expr]", - "de", "", "List esil watchpoints", - "de-*", "", "Delete all esil watchpoints", - "de", " [perm] [rm] [addr|reg|from..to]", "Stop on condition", - "dec", "", "Continue execution until matching expression", - "des", "[?] [N]", "Step-in N instructions with esildebug", - "desu", " [addr]", "Esildebug until specific address", - NULL -}; - -static const char *help_msg_des[] = { - "Usage:", "des", "[u] [arg]", - "des", " [N]", "step-in N instructions with esildebug", - "desu", " [addr]", "esildebug until specific address", - NULL -}; - static const char *help_msg_dk[] = { "Usage: dk", "", "Signal commands", "dk", "", "List all signal handlers of child process", @@ -1542,95 +1524,6 @@ static void debug_trace_calls(RzCore *core, ut64 from, ut64 to, ut64 final_addr) rz_cons_break_pop(); } -static void rz_core_debug_esil(RzCore *core, const char *input) { - switch (input[0]) { - case '\0': // "de" - // list - rz_debug_esil_watch_list(core->dbg); - break; - case ' ': // "de " - { - char *line = strdup(input + 1); - char *p, *q; - int done = 0; - int perm = 0, dev = 0; - p = strchr(line, ' '); - if (p) { - *p++ = 0; - if (strchr(line, 'r')) - perm |= RZ_PERM_R; - if (strchr(line, 'w')) - perm |= RZ_PERM_W; - if (strchr(line, 'x')) - perm |= RZ_PERM_X; - q = strchr(p, ' '); - if (q) { - *q++ = 0; - dev = p[0]; - if (q) { - rz_debug_esil_watch(core->dbg, perm, dev, q); - done = 1; - } - } - } - if (!done) { - const char *help_de_msg[] = { - "Usage:", "de", " [perm] [reg|mem] [expr]", - NULL - }; - rz_core_cmd_help(core, help_de_msg); - } - free(line); - } break; - case '-': // "de-" - rz_debug_esil_watch_reset(core->dbg); - break; - case 'c': // "dec" - if (rz_debug_esil_watch_empty(core->dbg)) { - RZ_LOG_ERROR("core: Error: no esil watchpoints defined\n"); - } else { - rz_core_analysis_esil_reinit(core); - rz_debug_esil_prestep(core->dbg, rz_config_get_i(core->config, "esil.prestep")); - rz_debug_esil_continue(core->dbg); - } - break; - case 's': // "des" - if (input[1] == 'u' && input[2] == ' ') { // "desu" - ut64 addr, naddr, fin = rz_num_math(core->num, input + 2); - rz_core_analysis_esil_reinit(core); - addr = rz_debug_reg_get(core->dbg, "PC"); - while (addr != fin) { - rz_debug_esil_prestep(core->dbg, rz_config_get_i(core->config, "esil.prestep")); - rz_debug_esil_step(core->dbg, 1); - naddr = rz_debug_reg_get(core->dbg, "PC"); - if (naddr == addr) { - RZ_LOG_WARN("core: Detected loophole\n"); - break; - } - addr = naddr; - } - } else if (input[1] == '?' || !input[1]) { - rz_core_cmd_help(core, help_msg_des); - } else { - rz_core_analysis_esil_reinit(core); - rz_debug_esil_prestep(core->dbg, rz_config_get_i(core->config, "esil.prestep")); - // continue - rz_debug_esil_step(core->dbg, rz_num_math(core->num, input + 1)); - } - break; - case '?': // "de?" - default: { - rz_core_cmd_help(core, help_msg_de); - // TODO #7967 help refactor: move to detail - rz_cons_printf("Examples:\n" - " de r r rip # stop when reads rip\n" - " de rw m ADDR # stop when read or write in ADDR\n" - " de w r rdx # stop when rdx register is modified\n" - " de x m FROM..TO # stop when rip in range\n"); - } break; - } -} - static void rz_core_debug_kill(RzCore *core, const char *input) { if (!input || *input == '?') { if (input && input[1]) { @@ -2044,9 +1937,6 @@ RZ_IPI int rz_cmd_debug(void *data, const char *input) { int follow = 0; switch (input[0]) { - case 'e': // "de" - rz_core_debug_esil(core, input + 1); - break; case 'k': // "dk" rz_core_debug_kill(core, input + 1); break; @@ -3415,3 +3305,55 @@ RZ_IPI RzCmdStatus rz_cmd_debug_window_identify_handler(RzCore *core, int argc, return RZ_CMD_STATUS_ERROR; #endif } + +RZ_IPI RzCmdStatus rz_cmd_debug_esil_add_handler(RzCore *core, int argc, const char **argv) { + int perm = rz_str_rwx(argv[1]); + int kind = (int)argv[2][0]; + rz_debug_esil_watch(core->dbg, perm, kind, argv[3]); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_esil_remove_handler(RzCore *core, int argc, const char **argv) { + rz_debug_esil_watch_reset(core->dbg); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_esil_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + rz_core_debug_esil_watch_print(core->dbg, state); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_esil_continue_handler(RzCore *core, int argc, const char **argv) { + if (rz_debug_esil_watch_empty(core->dbg)) { + RZ_LOG_ERROR("core: Error: no esil watchpoints defined\n"); + return RZ_CMD_STATUS_ERROR; + } + rz_core_analysis_esil_reinit(core); + rz_debug_esil_prestep(core->dbg, rz_config_get_b(core->config, "esil.prestep")); + rz_debug_esil_continue(core->dbg); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_esil_step_handler(RzCore *core, int argc, const char **argv) { + rz_core_analysis_esil_reinit(core); + rz_debug_esil_prestep(core->dbg, rz_config_get_b(core->config, "esil.prestep")); + rz_debug_esil_step(core->dbg, rz_num_math(core->num, argv[1])); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_esil_step_until_handler(RzCore *core, int argc, const char **argv) { + ut64 fin = rz_num_math(core->num, argv[1]); + rz_core_analysis_esil_reinit(core); + ut64 addr = rz_debug_reg_get(core->dbg, "PC"); + while (addr != fin) { + rz_debug_esil_prestep(core->dbg, rz_config_get_b(core->config, "esil.prestep")); + rz_debug_esil_step(core->dbg, 1); + ut64 naddr = rz_debug_reg_get(core->dbg, "PC"); + if (naddr == addr) { + RZ_LOG_WARN("core: Detected loophole\n"); + break; + } + addr = naddr; + } + return RZ_CMD_STATUS_OK; +} diff --git a/librz/core/cmd_descs/cmd_debug.yaml b/librz/core/cmd_descs/cmd_debug.yaml index 71a6f1725b8..61971e8f531 100644 --- a/librz/core/cmd_descs/cmd_debug.yaml +++ b/librz/core/cmd_descs/cmd_debug.yaml @@ -373,6 +373,67 @@ commands: type: RZ_CMD_ARG_TYPE_NUM - name: len type: RZ_CMD_ARG_TYPE_NUM + - name: de + summary: Manage ESIL watchpoints + subcommands: + - name: de + summary: Add ESIL watchpoint + cname: cmd_debug_esil_add + args: + - name: perm + type: RZ_CMD_ARG_TYPE_STRING + - name: kind + type: RZ_CMD_ARG_TYPE_CHOICES + choices: + - reg + - mem + - name: expression + type: RZ_CMD_ARG_TYPE_STRING + details: + - name: Examples + entries: + - text: de + arg_str: "r reg rip" + comment: Stop when reads RIP register + - text: de + arg_str: "rw mem ADDR" + comment: Stop when read or write in ADDR + - text: de + arg_str: "w r rdx" + comment: Stop when rdx register is modified + - text: de + arg_str: "x m FROM..TO" + comment: Stop when rip in range + - name: de-* + summary: Remove all ESIL watchpoints + cname: cmd_debug_esil_remove + args: [] + - name: del + summary: List all ESIL watchpoints + cname: cmd_debug_esil_list + args: [] + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_TABLE + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_RIZIN + - name: dec + summary: Continue execution until matching expression + cname: cmd_debug_esil_continue + args: [] + - name: des + summary: Step-in instructions with ESIL + cname: cmd_debug_esil_step + args: + - name: N + type: RZ_CMD_ARG_TYPE_NUM + - name: desu + summary: Step until specified
+ cname: cmd_debug_esil_step_until + args: + - name:
+ type: RZ_CMD_ARG_TYPE_RZNUM - name: dg summary: Generate core dump file cname: cmd_debug_core_dump_generate diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index bc4bfbf7170..71086a9768b 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -39,6 +39,7 @@ static const RzCmdDescDetail cw_details[2]; static const RzCmdDescDetail cmd_debug_list_bp_details[2]; static const RzCmdDescDetail cmd_debug_add_cond_bp_details[2]; static const RzCmdDescDetail cmd_debug_add_watchpoint_details[2]; +static const RzCmdDescDetail cmd_debug_esil_add_details[2]; static const RzCmdDescDetail debug_reg_cond_details[4]; static const RzCmdDescDetail dr_details[2]; static const RzCmdDescDetail cmd_debug_inject_opcode_details[2]; @@ -321,6 +322,9 @@ static const RzCmdDescArg cmd_debug_descriptor_seek_args[3]; static const RzCmdDescArg cmd_debug_descriptor_dup_args[3]; static const RzCmdDescArg cmd_debug_descriptor_read_args[4]; static const RzCmdDescArg cmd_debug_descriptor_write_args[4]; +static const RzCmdDescArg cmd_debug_esil_add_args[4]; +static const RzCmdDescArg cmd_debug_esil_step_args[2]; +static const RzCmdDescArg cmd_debug_esil_step_until_args[2]; static const RzCmdDescArg cmd_debug_core_dump_generate_args[2]; static const RzCmdDescArg cmd_debug_process_profile_args[2]; static const RzCmdDescArg cmd_debug_step_args[2]; @@ -7120,6 +7124,98 @@ static const RzCmdDescHelp cmd_debug_descriptor_write_help = { .args = cmd_debug_descriptor_write_args, }; +static const RzCmdDescHelp de_help = { + .summary = "Manage ESIL watchpoints", +}; +static const RzCmdDescDetailEntry cmd_debug_esil_add_Examples_detail_entries[] = { + { .text = "de", .arg_str = "r reg rip", .comment = "Stop when reads RIP register" }, + { .text = "de", .arg_str = "rw mem ADDR", .comment = "Stop when read or write in ADDR" }, + { .text = "de", .arg_str = "w r rdx", .comment = "Stop when rdx register is modified" }, + { .text = "de", .arg_str = "x m FROM..TO", .comment = "Stop when rip in range" }, + { 0 }, +}; +static const RzCmdDescDetail cmd_debug_esil_add_details[] = { + { .name = "Examples", .entries = cmd_debug_esil_add_Examples_detail_entries }, + { 0 }, +}; +static const char *cmd_debug_esil_add_kind_choices[] = { "reg", "mem", NULL }; +static const RzCmdDescArg cmd_debug_esil_add_args[] = { + { + .name = "perm", + .type = RZ_CMD_ARG_TYPE_STRING, + + }, + { + .name = "kind", + .type = RZ_CMD_ARG_TYPE_CHOICES, + .choices.choices = cmd_debug_esil_add_kind_choices, + + }, + { + .name = "expression", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_esil_add_help = { + .summary = "Add ESIL watchpoint", + .details = cmd_debug_esil_add_details, + .args = cmd_debug_esil_add_args, +}; + +static const RzCmdDescArg cmd_debug_esil_remove_args[] = { + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_esil_remove_help = { + .summary = "Remove all ESIL watchpoints", + .args = cmd_debug_esil_remove_args, +}; + +static const RzCmdDescArg cmd_debug_esil_list_args[] = { + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_esil_list_help = { + .summary = "List all ESIL watchpoints", + .args = cmd_debug_esil_list_args, +}; + +static const RzCmdDescArg cmd_debug_esil_continue_args[] = { + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_esil_continue_help = { + .summary = "Continue execution until matching expression", + .args = cmd_debug_esil_continue_args, +}; + +static const RzCmdDescArg cmd_debug_esil_step_args[] = { + { + .name = "N", + .type = RZ_CMD_ARG_TYPE_NUM, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_esil_step_help = { + .summary = "Step-in instructions with ESIL", + .args = cmd_debug_esil_step_args, +}; + +static const RzCmdDescArg cmd_debug_esil_step_until_args[] = { + { + .name = "
", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_esil_step_until_help = { + .summary = "Step until specified
", + .args = cmd_debug_esil_step_until_args, +}; + static const RzCmdDescArg cmd_debug_core_dump_generate_args[] = { { .name = "filename", @@ -16969,6 +17065,23 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *cmd_debug_descriptor_write_cd = rz_cmd_desc_argv_new(core->rcmd, dd_cd, "ddw", rz_cmd_debug_descriptor_write_handler, &cmd_debug_descriptor_write_help); rz_warn_if_fail(cmd_debug_descriptor_write_cd); + RzCmdDesc *de_cd = rz_cmd_desc_group_new(core->rcmd, cmd_debug_cd, "de", rz_cmd_debug_esil_add_handler, &cmd_debug_esil_add_help, &de_help); + rz_warn_if_fail(de_cd); + RzCmdDesc *cmd_debug_esil_remove_cd = rz_cmd_desc_argv_new(core->rcmd, de_cd, "de-*", rz_cmd_debug_esil_remove_handler, &cmd_debug_esil_remove_help); + rz_warn_if_fail(cmd_debug_esil_remove_cd); + + RzCmdDesc *cmd_debug_esil_list_cd = rz_cmd_desc_argv_state_new(core->rcmd, de_cd, "del", RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_TABLE | RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN, rz_cmd_debug_esil_list_handler, &cmd_debug_esil_list_help); + rz_warn_if_fail(cmd_debug_esil_list_cd); + + RzCmdDesc *cmd_debug_esil_continue_cd = rz_cmd_desc_argv_new(core->rcmd, de_cd, "dec", rz_cmd_debug_esil_continue_handler, &cmd_debug_esil_continue_help); + rz_warn_if_fail(cmd_debug_esil_continue_cd); + + RzCmdDesc *cmd_debug_esil_step_cd = rz_cmd_desc_argv_new(core->rcmd, de_cd, "des", rz_cmd_debug_esil_step_handler, &cmd_debug_esil_step_help); + rz_warn_if_fail(cmd_debug_esil_step_cd); + + RzCmdDesc *cmd_debug_esil_step_until_cd = rz_cmd_desc_argv_new(core->rcmd, de_cd, "desu", rz_cmd_debug_esil_step_until_handler, &cmd_debug_esil_step_until_help); + rz_warn_if_fail(cmd_debug_esil_step_until_cd); + RzCmdDesc *cmd_debug_core_dump_generate_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_debug_cd, "dg", rz_cmd_debug_core_dump_generate_handler, &cmd_debug_core_dump_generate_help); rz_warn_if_fail(cmd_debug_core_dump_generate_cd); diff --git a/librz/core/cmd_descs/cmd_descs.h b/librz/core/cmd_descs/cmd_descs.h index 7888b770e7a..2d4e053ba59 100644 --- a/librz/core/cmd_descs/cmd_descs.h +++ b/librz/core/cmd_descs/cmd_descs.h @@ -482,6 +482,12 @@ RZ_IPI RzCmdStatus rz_cmd_debug_descriptor_seek_handler(RzCore *core, int argc, RZ_IPI RzCmdStatus rz_cmd_debug_descriptor_dup_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_cmd_debug_descriptor_read_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_cmd_debug_descriptor_write_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_esil_add_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_esil_remove_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_esil_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_cmd_debug_esil_continue_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_esil_step_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_esil_step_until_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_cmd_debug_core_dump_generate_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_cmd_debug_process_profile_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_cmd_debug_process_profile_edit_handler(RzCore *core, int argc, const char **argv); diff --git a/librz/core/core_private.h b/librz/core/core_private.h index be45f1a17eb..8fac43ea83e 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -23,6 +23,7 @@ RZ_IPI void rz_core_analysis_esil_references_all_functions(RzCore *core); RZ_IPI void rz_core_analysis_esil_emulate(RzCore *core, ut64 addr, ut64 until_addr, int off); RZ_IPI void rz_core_analysis_esil_emulate_bb(RzCore *core); RZ_IPI void rz_core_analysis_esil_default(RzCore *core); +RZ_IPI void rz_core_debug_esil_watch_print(RzDebug *dbg, RzCmdStateOutput *state); RZ_IPI void rz_core_analysis_il_reinit(RzCore *core); RZ_IPI bool rz_core_analysis_il_vm_set(RzCore *core, const char *var_name, ut64 value); diff --git a/librz/debug/desil.c b/librz/debug/desil.c index 31ef9052880..d56a765436c 100644 --- a/librz/debug/desil.c +++ b/librz/debug/desil.c @@ -3,8 +3,8 @@ #include -#if 0 - /* debugesil performs step into + esil conditionals */ +/* + debugesil performs step into + esil conditionals ESIL conditionals can be used to detect when a specific address is accessed, or a register. Those esil conditionals must be evaluated every iteration to ensure the register values are updated. Think @@ -15,16 +15,9 @@ de rw reg eax de-* -#expression can be a number or a range(if..is found) -#The <=, >=, ==, <, > comparisons are also supported - -#endif - -typedef struct { - int rwx; - int dev; - char *expr; -} EsilBreak; + expression can be a number or a range(if..is found) + The <=, >=, ==, <, > comparisons are also supported +*/ // TODO: Kill those globals RzDebug *dbg = NULL; @@ -69,7 +62,7 @@ static int exprmatch(RzDebug *dbg, ut64 addr, const char *expr) { } static int esilbreak_check_pc(RzDebug *dbg, ut64 pc) { - EsilBreak *ew; + RzDebugEsilWatchpoint *ew; RzListIter *iter; if (!pc) { pc = rz_debug_reg_get(dbg, dbg->reg->name[RZ_REG_NAME_PC]); @@ -85,7 +78,7 @@ static int esilbreak_check_pc(RzDebug *dbg, ut64 pc) { } static int esilbreak_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len) { - EsilBreak *ew; + RzDebugEsilWatchpoint *ew; RzListIter *iter; eprintf(Color_GREEN "MEM READ 0x%" PFMT64x "\n" Color_RESET, addr); rz_list_foreach (EWPS, iter, ew) { @@ -100,7 +93,7 @@ static int esilbreak_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len } static int esilbreak_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) { - EsilBreak *ew; + RzDebugEsilWatchpoint *ew; RzListIter *iter; eprintf(Color_RED "MEM WRTE 0x%" PFMT64x "\n" Color_RESET, addr); rz_list_foreach (EWPS, iter, ew) { @@ -115,7 +108,7 @@ static int esilbreak_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, } static int esilbreak_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size) { - EsilBreak *ew; + RzDebugEsilWatchpoint *ew; RzListIter *iter; if (regname[0] >= '0' && regname[0] <= '9') { // eprintf (Color_CYAN"IMM READ %s\n"Color_RESET, regname); @@ -191,7 +184,7 @@ static int exprmatchreg(RzDebug *dbg, const char *regname, const char *expr) { } static int esilbreak_reg_write(RzAnalysisEsil *esil, const char *regname, ut64 *num) { - EsilBreak *ew; + RzDebugEsilWatchpoint *ew; RzListIter *iter; if (regname[0] >= '0' && regname[0] <= '9') { // this should never happen @@ -286,7 +279,7 @@ RZ_API ut64 rz_debug_esil_step(RzDebug *dbg, ut32 count) { break; } if (has_match) { - eprintf("EsilBreak match at 0x%08" PFMT64x "\n", opc); + eprintf("RzDebugEsilWatchpoint match at 0x%08" PFMT64x "\n", opc); break; } if (count > 0) { @@ -305,7 +298,7 @@ RZ_API ut64 rz_debug_esil_continue(RzDebug *dbg) { return rz_debug_esil_step(dbg, UT32_MAX); } -static void ewps_free(EsilBreak *ew) { +static void ewps_free(RzDebugEsilWatchpoint *ew) { RZ_FREE(ew->expr); free(ew); } @@ -322,7 +315,7 @@ RZ_API void rz_debug_esil_watch(RzDebug *dbg, int rwx, int dev, const char *expr } EWPS->free = (RzListFree)ewps_free; } - EsilBreak *ew = RZ_NEW0(EsilBreak); + RzDebugEsilWatchpoint *ew = RZ_NEW0(RzDebugEsilWatchpoint); if (!ew) { RZ_FREE(EWPS); return; @@ -338,10 +331,6 @@ RZ_API void rz_debug_esil_watch_reset(RzDebug *dbg) { EWPS = NULL; } -RZ_API void rz_debug_esil_watch_list(RzDebug *dbg) { - EsilBreak *ew; - RzListIter *iter; - rz_list_foreach (EWPS, iter, ew) { - dbg->cb_printf("de %s %c %s\n", rz_str_rwx_i(ew->rwx), ew->dev, ew->expr); - } +RZ_API RZ_BORROW RzList /**/ *rz_debug_esil_watch_list(RzDebug *dbg) { + return EWPS; } diff --git a/librz/include/rz_debug.h b/librz/include/rz_debug.h index 0e56d462465..7e2ff4c5624 100644 --- a/librz/include/rz_debug.h +++ b/librz/include/rz_debug.h @@ -424,6 +424,12 @@ typedef struct rz_backtrace_t { char *flagdesc2; } RzBacktrace; +typedef struct rz_debug_esil_watchpoint_t { + int rwx; + int dev; + char *expr; +} RzDebugEsilWatchpoint; + #ifdef RZ_API RZ_API RZ_OWN RzDebug *rz_debug_new(RZ_BORROW RZ_NONNULL RzBreakpointContext *bp_ctx); RZ_API RzDebug *rz_debug_free(RzDebug *dbg); @@ -562,7 +568,7 @@ RZ_API ut64 rz_debug_esil_step(RzDebug *dbg, ut32 count); RZ_API ut64 rz_debug_esil_continue(RzDebug *dbg); RZ_API void rz_debug_esil_watch(RzDebug *dbg, int rwx, int dev, const char *expr); RZ_API void rz_debug_esil_watch_reset(RzDebug *dbg); -RZ_API void rz_debug_esil_watch_list(RzDebug *dbg); +RZ_API RZ_BORROW RzList /**/ *rz_debug_esil_watch_list(RzDebug *dbg); RZ_API int rz_debug_esil_watch_empty(RzDebug *dbg); RZ_API void rz_debug_esil_prestep(RzDebug *d, int p);