From 87b75910b5b8224e3eebb73c0eb22cf19a05798b Mon Sep 17 00:00:00 2001 From: Rot127 <45763064+Rot127@users.noreply.github.com> Date: Fri, 6 Dec 2024 00:10:25 +0000 Subject: [PATCH] Port remaining debug commands to RzShell (#4753) * Port `dmhb` to RzShell * Port `dmhf` to RzShell * Remove 'to' argument from rz_core_debug_continue_until(). It was never used in the whole function. Hence, whatever it was supposed to do, it didn't * Port `dcu` to RzShell * Fix tests of `dmh[bf]` commands * Port `dmi` commands to RzShell * Port `dmx` to RzShell * Remove `dta` command. Originally it limited the addresses to trace. But it was not used in any test, and the implementation was not optimal. It allowed only specific addresses (no range). Also worked on strings (not ut64 values). Also, the usefulness is limited, considering the alternative to just not tracing a certain address. * Add quiet and quietest mode to `dmi` commands. This also removes the test for `dmias`. The command was not documented and it doesn't seem to do anything special `dmia` can't do. --- librz/core/cdebug.c | 45 ++- librz/core/cio.c | 4 +- librz/core/cmd/cmd_api.c | 1 + librz/core/cmd/cmd_debug.c | 440 +++++++---------------- librz/core/cmd/cmd_linux_heap_glibc.c | 10 +- librz/core/cmd_descs/cmd_debug.yaml | 78 +++- librz/core/cmd_descs/cmd_descs.c | 145 ++++++-- librz/core/cmd_descs/cmd_descs.h | 22 +- librz/core/cmd_descs/cmd_heap_glibc.yaml | 6 +- librz/core/linux_heap_glibc.c | 38 +- librz/core/linux_heap_jemalloc.c | 28 +- librz/core/tui/visual.c | 2 +- librz/debug/trace.c | 22 -- librz/include/rz_cmd.h | 1 + librz/include/rz_core.h | 2 +- librz/include/rz_debug.h | 4 - librz/include/rz_heap_glibc.h | 9 +- test/db/archos/darwin-arm64/dbg | 8 - test/db/archos/darwin-x64/dbg | 2 - test/db/archos/linux-x64/dbg_dmi | 19 +- test/db/archos/linux-x64/dbg_step | 4 - 21 files changed, 419 insertions(+), 471 deletions(-) diff --git a/librz/core/cdebug.c b/librz/core/cdebug.c index 254a6ea297d..5be1af5778b 100644 --- a/librz/core/cdebug.c +++ b/librz/core/cdebug.c @@ -96,13 +96,24 @@ RZ_IPI void rz_core_debug_continue(RzCore *core) { } } -RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr, ut64 to) { +/** + * \brief Continue the execution of the debugged binary until \p addr. + * + * \param core The current core. + * \param addr The address to execute to. + * + * \return true On success. + * \return false Otherwise. + */ +RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr) { +#if RZ_BUILD_DEBUG + long level = 0; + ut64 prev_pc = UT64_MAX; + unsigned long steps = 0; +#endif ut64 pc; if (!strcmp(core->dbg->btalgo, "trace") && core->dbg->arch && !strcmp(core->dbg->arch, "x86") && core->dbg->bits == 4) { - unsigned long steps = 0; - long level = 0; const char *pc_name = core->dbg->reg->name[RZ_REG_NAME_PC]; - ut64 prev_pc = UT64_MAX; bool prev_call = false; bool prev_ret = false; const char *sp_name = core->dbg->reg->name[RZ_REG_NAME_SP]; @@ -127,45 +138,51 @@ RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr, ut64 to) { frame->sp = cur_sp; frame->bp = old_sp; rz_list_prepend(core->dbg->call_frames, frame); - eprintf("%ld Call from 0x%08" PFMT64x " to 0x%08" PFMT64x " ret 0x%08" PFMT32x "\n", - level, prev_pc, pc, ret_addr); - level++; + RZ_LOG_DEBUG("%ld Call from 0x%08" PFMT64x " to 0x%08" PFMT64x " ret 0x%08" PFMT32x "\n", + level++, prev_pc, pc, ret_addr); old_sp = cur_sp; prev_call = false; } else if (prev_ret) { RzDebugFrame *head = rz_list_first(core->dbg->call_frames); if (head && head->addr != pc) { - eprintf("*"); + RZ_LOG_DEBUG("*"); } else { rz_list_pop_head(core->dbg->call_frames); - eprintf("%ld", level); - level--; + RZ_LOG_DEBUG("%ld", level--); } - eprintf(" Ret from 0x%08" PFMT64x " to 0x%08" PFMT64x "\n", + RZ_LOG_DEBUG(" Ret from 0x%08" PFMT64x " to 0x%08" PFMT64x "\n", prev_pc, pc); prev_ret = false; } +#if RZ_BUILD_DEBUG if (steps % 500 == 0 || pc == addr) { - eprintf("At 0x%08" PFMT64x " after %lu steps\n", pc, steps); + RZ_LOG_DEBUG("At 0x%08" PFMT64x " after %lu steps\n", pc, steps); } +#endif if (rz_cons_is_breaked() || rz_debug_is_dead(core->dbg) || pc == addr) { break; } if (is_x86_call(core->dbg, pc)) { +#if RZ_BUILD_DEBUG prev_pc = pc; +#endif prev_call = true; } else if (is_x86_ret(core->dbg, pc)) { +#if RZ_BUILD_DEBUG prev_pc = pc; +#endif prev_ret = true; } rz_debug_step(core->dbg, 1); +#if RZ_BUILD_DEBUG steps++; +#endif } rz_core_reg_update_flags(core); rz_cons_break_pop(); return true; } - eprintf("Continue until 0x%08" PFMT64x "\n", addr); + RZ_LOG_DEBUG("Continue until 0x%08" PFMT64x "\n", addr); rz_reg_arena_swap(core->dbg->reg, true); if (rz_bp_add_sw(core->dbg->bp, addr, 0, RZ_PERM_X)) { if (rz_debug_is_dead(core->dbg)) { @@ -185,7 +202,7 @@ RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr, ut64 to) { RZ_IPI void rz_core_debug_single_step_in(RzCore *core) { if (rz_core_is_debug(core)) { if (core->print->cur_enabled) { - rz_core_debug_continue_until(core, core->offset, core->offset + core->print->cur); + rz_core_debug_continue_until(core, core->offset); core->print->cur_enabled = 0; } else { rz_core_debug_step_one(core, 1); diff --git a/librz/core/cio.c b/librz/core/cio.c index f04a421f993..7b40744d129 100644 --- a/librz/core/cio.c +++ b/librz/core/cio.c @@ -35,10 +35,10 @@ RZ_API int rz_core_setup_debugger(RzCore *r, const char *debugbackend, bool atta /* do nothing here */ } else if (!strcmp(bep, "entry")) { address = rz_num_math(r->num, "entry0"); - rz_core_debug_continue_until(r, address, address); + rz_core_debug_continue_until(r, address); } else { address = rz_num_math(r->num, bep); - rz_core_debug_continue_until(r, address, address); + rz_core_debug_continue_until(r, address); } } } diff --git a/librz/core/cmd/cmd_api.c b/librz/core/cmd/cmd_api.c index 4d3e07e2d03..47a9b0368eb 100644 --- a/librz/core/cmd/cmd_api.c +++ b/librz/core/cmd/cmd_api.c @@ -67,6 +67,7 @@ static const struct argv_modes_t { { "l", " (verbose mode)", RZ_OUTPUT_MODE_LONG }, { "J", " (verbose JSON mode)", RZ_OUTPUT_MODE_LONG_JSON }, { "t", " (table mode)", RZ_OUTPUT_MODE_TABLE }, + { "g", " (graph mode)", RZ_OUTPUT_MODE_GRAPH }, }; RZ_IPI int rz_output_mode_to_char(RzOutputMode mode) { diff --git a/librz/core/cmd/cmd_debug.c b/librz/core/cmd/cmd_debug.c index bc3bfd0d128..d1b5e6dc703 100644 --- a/librz/core/cmd/cmd_debug.c +++ b/librz/core/cmd/cmd_debug.c @@ -1,6 +1,9 @@ // SPDX-FileCopyrightText: 2009-2020 pancake // SPDX-License-Identifier: LGPL-3.0-only +#include +#include +#include #include #include #include @@ -25,25 +28,6 @@ } \ } while (0) -static const char *help_msg_dcu[] = { - "Usage:", "dcu", " Continue until address", - "dcu.", "", "Alias for dcu $$ (continue until current address", - "dcu", " address", "Continue until address", - "dcu", " [..tail]", "Continue until the range", - "dcu", " [from] [to]", "Continue until the range", - NULL -}; - -static const char *help_msg_dmi[] = { - "Usage: dmi", "", " # List/Load Symbols", - "dmi", "[j|q|*] [libname] [symname]", "List symbols of target lib", - "dmia", "[j|q|*] [libname]", "List all info of target lib", - "dmi*", "", "List symbols of target lib in rizin commands", - "dmi.", "", "List closest symbol to the current address", - "dmiv", "", "Show address of given symbol for given lib", - NULL -}; - struct dot_trace_ght { RzGraph /**/ *graph; Sdb *graphnodes; @@ -683,26 +667,17 @@ static RzDebugMap *get_closest_map(RzCore *core, ut64 addr) { return NULL; } -static RzOutputMode rad2mode(int mode) { - switch (mode) { - case RZ_MODE_PRINT: - default: - return RZ_OUTPUT_MODE_STANDARD; - case RZ_MODE_JSON: - return RZ_OUTPUT_MODE_JSON; - case RZ_MODE_SIMPLE: - return RZ_OUTPUT_MODE_QUIET; - case RZ_MODE_SIMPLEST: - return RZ_OUTPUT_MODE_QUIETEST; - case RZ_MODE_RIZINCMD: - return RZ_OUTPUT_MODE_RIZIN; - } -} - -static bool get_bin_info(RzCore *core, const char *file, ut64 baseaddr, PJ *pj, - int mode, bool symbols_only, RzCoreBinFilter *filter) { +/** + * \brief Hacky way to get the binary information of a file. + * It opens \p file into the current core->bin (backing up the previous pointer) + * and reads the information. + * Then closes it again and restores the old core-bin pointer. + */ +static bool get_bin_info(RzCore *core, const char *file, ut64 baseaddr, + RzCmdStateOutput *state, int action, RzCoreBinFilter *filter) { int fd; if ((fd = rz_io_fd_open(core->io, file, RZ_PERM_R, 0)) == -1) { + RZ_LOG_ERROR("Failed to open file: %s\n", file); return false; } RzBinOptions opt = { 0 }; @@ -715,24 +690,11 @@ static bool get_bin_info(RzCore *core, const char *file, ut64 baseaddr, PJ *pj, RzBinFile *obf = rz_bin_cur(core->bin); RzBinFile *bf = rz_bin_open_io(core->bin, &opt); if (!bf) { + RZ_LOG_ERROR("Failed to create RzBinFile for: %s\n", file); rz_io_fd_close(core->io, fd); return false; } - int action = RZ_CORE_BIN_ACC_ALL & ~RZ_CORE_BIN_ACC_INFO; - if (symbols_only || filter->name) { - action = RZ_CORE_BIN_ACC_SYMBOLS; - } else if (mode == RZ_MODE_SET || mode == RZ_MODE_RIZINCMD) { - action &= ~RZ_CORE_BIN_ACC_ENTRIES & ~RZ_CORE_BIN_ACC_MAIN & ~RZ_CORE_BIN_ACC_MAPS; - } - if (mode == RZ_MODE_SET) { - rz_core_bin_apply_info(core, core->bin->cur, action); - } else { - RzCmdStateOutput state; - rz_cmd_state_output_init(&state, rad2mode(mode)); - rz_core_bin_print(core, bf, action, filter, &state, NULL); - rz_cmd_state_output_print(&state); - rz_cmd_state_output_fini(&state); - } + rz_core_bin_print(core, bf, action, filter, state, NULL); rz_bin_file_delete(core->bin, bf); rz_bin_file_set_cur_binfile(core->bin, obf); rz_io_fd_close(core->io, fd); @@ -835,176 +797,114 @@ RZ_IPI RzCmdStatus rz_cmd_debug_dump_maps_writable_handler(RzCore *core, int arg return RZ_CMD_STATUS_OK; } -// dmi -RZ_IPI int rz_cmd_debug_dmi(void *data, const char *input) { - RzCore *core = (RzCore *)data; +static RzDebugMap *get_debug_map_from_lib_name(RzCore *core, const char *lib_name) { + ut64 addr = addroflib(core, rz_file_basename(lib_name)); + if (addr == UT64_MAX) { + RZ_LOG_ERROR("Unknown library '%s' not found\n", lib_name); + return NULL; + } + + RzDebugMap *map = get_closest_map(core, addr); + if (!map) { + RZ_LOG_ERROR("Didn't find library map at 0x%" PFMT64x "\n", addr); + return NULL; + } + return map; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_dmi_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { CMD_CHECK_DEBUG_DEAD(core); - RzDebugMap *map; - ut64 addr = core->offset; - switch (input[0]) { - case '\0': // "dmi" alias of "dmm" - { - RzCmdStateOutput state = { 0 }; - rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD); - cmd_debug_modules(core, &state); - rz_cmd_state_output_print(&state); - rz_cmd_state_output_fini(&state); + if (argc == 1) { + // Effectively an alias for 'dmm' + cmd_debug_modules(core, state); + rz_cmd_state_output_print(state); rz_cons_flush(); - break; + return RZ_CMD_STATUS_OK; } - case ' ': // "dmi " - case '*': // "dmi*" - case 'v': // "dmiv" - case 'j': // "dmij" - case 'q': // "dmiq" - case 'a': // "dmia" - { - const char *libname = NULL, *symname = NULL, *a0; - int mode; - ut64 baddr = 0LL; - char *ptr; - int i = 1; - bool symbols_only = true; - if (input[0] == 'a') { - symbols_only = false; - input++; - } - PJ *pj = NULL; - switch (input[0]) { - case 's': - mode = RZ_MODE_SET; - break; - case '*': - mode = RZ_MODE_RIZINCMD; - break; - case 'j': - mode = RZ_MODE_JSON; - pj = pj_new(); - if (!pj) { - return false; - } - break; - case 'q': - mode = input[1] == 'q' ? input++, RZ_MODE_SIMPLEST : RZ_MODE_SIMPLE; - break; - default: - mode = RZ_MODE_PRINT; - break; - } - ptr = rz_str_dup(input[0] ? rz_str_trim_head_ro(input + 1) : ""); - if (!ptr || !*ptr) { - rz_core_cmd(core, "dmm", 0); - free(ptr); - pj_free(pj); - break; - } - if (symbols_only) { - i = rz_str_word_set0(ptr); - } - switch (i) { - case 2: - symname = rz_str_word_get0(ptr, 1); - // fall through - case 1: - a0 = rz_str_word_get0(ptr, 0); - addr = rz_num_get(core->num, a0); - if (!addr || addr == UT64_MAX) { - libname = rz_str_word_get0(ptr, 0); - } - break; - } - if (libname && !addr) { - addr = addroflib(core, rz_file_basename(libname)); - if (addr == UT64_MAX) { - RZ_LOG_ERROR("core: Unknown library, or not found in dm\n"); - } - } - map = get_closest_map(core, addr); - if (map) { - RzCoreBinFilter filter; - filter.offset = UT64_MAX; - filter.name = (char *)symname; - baddr = map->addr; - if (libname) { - const char *file = map->file ? map->file : map->name; - char *newfile = NULL; - if (!rz_file_exists(file)) { - newfile = rz_file_temp("memlib"); - if (newfile) { - file = newfile; - rz_core_dump(core, file, baddr, map->size, false); - } - } - get_bin_info(core, file, baddr, pj, mode, symbols_only, &filter); - if (newfile) { - if (!rz_file_rm(newfile)) { - RZ_LOG_ERROR("core: Error when removing %s\n", newfile); - } - free(newfile); - } - } else { - RzBinFile *bf = rz_bin_cur(core->bin); - if (bf) { - rz_bin_set_baddr(core->bin, map->addr); - RzCmdStateOutput state; - rz_cmd_state_output_init(&state, rad2mode(mode)); - rz_core_bin_print(core, bf, RZ_CORE_BIN_ACC_SYMBOLS, &filter, &state, NULL); - rz_cmd_state_output_print(&state); - rz_cmd_state_output_fini(&state); - rz_bin_set_baddr(core->bin, baddr); - } - } - } - if (mode == RZ_MODE_JSON) { - rz_cons_println(pj_string(pj)); - pj_free(pj); - } - free(ptr); - } break; - case '.': // "dmi." - { - map = get_closest_map(core, addr); - if (map) { - ut64 closest_addr = UT64_MAX; - RzBinObject *o = rz_bin_cur_object(core->bin); - RzPVector *symbols = o ? (RzPVector *)rz_bin_object_get_symbols(o) : NULL; - RzBinSymbol *symbol, *closest_symbol = NULL; - void **iter; - - rz_pvector_foreach (symbols, iter) { - symbol = *iter; - if (symbol->vaddr > addr) { - if (symbol->vaddr - addr < closest_addr) { - closest_addr = symbol->vaddr - addr; - closest_symbol = symbol; - } - } else { - if (addr - symbol->vaddr < closest_addr) { - closest_addr = addr - symbol->vaddr; - closest_symbol = symbol; - } - } + const char *lib_name = argc >= 2 ? argv[1] : NULL; + const char *sym_name = argc == 3 ? argv[2] : NULL; + + RzCoreBinFilter filter = { .offset = UT64_MAX, .name = sym_name }; + int action = RZ_CORE_BIN_ACC_SYMBOLS; + + RzDebugMap *map = get_debug_map_from_lib_name(core, lib_name); + if (!map) { + RZ_LOG_ERROR("Failed to get map from %s\n", lib_name); + return RZ_CMD_STATUS_ERROR; + } + const char *file = map->file ? map->file : map->name; + if (!get_bin_info(core, file, map->addr, state, action, &filter)) { + RZ_LOG_ERROR("Failed to get binary information for map: '%s' in file: '%s'\n", map->name, file); + return RZ_CMD_STATUS_ERROR; + } + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_dmi_all_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + CMD_CHECK_DEBUG_DEAD(core); + if (argc == 1) { + cmd_debug_modules(core, state); + rz_cmd_state_output_print(state); + rz_cons_flush(); + return RZ_CMD_STATUS_OK; + } + const char *lib_name = argv[1]; + RzDebugMap *map = get_debug_map_from_lib_name(core, lib_name); + if (!map) { + RZ_LOG_ERROR("Failed to get map from %s\n", lib_name); + return RZ_CMD_STATUS_ERROR; + } + const char *file = map->file ? map->file : map->name; + RzCoreBinFilter filter = { .offset = UT64_MAX, .name = NULL }; + int action = RZ_CORE_BIN_ACC_ALL & ~RZ_CORE_BIN_ACC_INFO; + if (!get_bin_info(core, file, map->addr, state, action, &filter)) { + RZ_LOG_ERROR("Failed to get binary information for map: '%s' in file: '%s'\n", map->name, file); + return RZ_CMD_STATUS_ERROR; + } + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_dmi_closest_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + RzBinObject *obj = rz_bin_cur_object(core->bin); + if (!obj) { + RZ_LOG_ERROR("No object present.\n"); + return RZ_CMD_STATUS_ERROR; + } + const RzPVector *symbols = rz_bin_object_get_symbols(obj); + if (!symbols) { + RZ_LOG_ERROR("Failed to get symbols from object.\n"); + return RZ_CMD_STATUS_ERROR; + } + ut64 addr = core->offset; + ut64 closest_addr = UT64_MAX; + RzBinSymbol *symbol, *closest_symbol = NULL; + void **iter; + rz_pvector_foreach (symbols, iter) { + symbol = *iter; + if (symbol->vaddr > addr) { + if (symbol->vaddr - addr < closest_addr) { + closest_addr = symbol->vaddr - addr; + closest_symbol = symbol; } - RzBinFile *bf = rz_bin_cur(core->bin); - if (closest_symbol && bf) { - RzCoreBinFilter filter; - filter.offset = UT64_MAX; - filter.name = (char *)closest_symbol->name; - - rz_bin_set_baddr(core->bin, map->addr); - RzCmdStateOutput state; - rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD); - rz_core_bin_print(core, bf, RZ_CORE_BIN_ACC_SYMBOLS, &filter, &state, NULL); - rz_cmd_state_output_print(&state); - rz_cmd_state_output_fini(&state); + } else { + if (addr - symbol->vaddr < closest_addr) { + closest_addr = addr - symbol->vaddr; + closest_symbol = symbol; } } - } break; - default: - rz_core_cmd_help(core, help_msg_dmi); - break; } + if (!closest_symbol) { + RZ_LOG_ERROR("Did not found any symbol close to 0x%" PFMT64x "\n", addr); + return RZ_CMD_STATUS_ERROR; + } + RzBinFile *bf = rz_bin_cur(core->bin); + if (!bf) { + RZ_LOG_ERROR("Failed to get current binary file.\n"); + return RZ_CMD_STATUS_ERROR; + } + RzCoreBinFilter filter = { .offset = UT64_MAX, .name = closest_symbol->name }; + rz_core_bin_print(core, bf, RZ_CORE_BIN_ACC_SYMBOLS, &filter, state, NULL); return RZ_CMD_STATUS_OK; } @@ -1136,20 +1036,35 @@ RZ_IPI RzCmdStatus rz_cmd_debug_dmL_handler(RzCore *core, int argc, const char * return RZ_CMD_STATUS_OK; } -// dmx -RZ_IPI int rz_cmd_debug_heap_jemalloc(void *data, const char *input) { - RzCore *core = (RzCore *)data; +static RzCmdStatus call_map_jemalloc(RzCore *core, char type, const char *arg) { CMD_CHECK_DEBUG_DEAD(core); #if HAVE_JEMALLOC if (core->rasm->bits == 64) { - return cmd_dbg_map_jemalloc_64(core, input); + cmd_dbg_map_jemalloc_64(core, type, arg); } else { - return cmd_dbg_map_jemalloc_32(core, input); + cmd_dbg_map_jemalloc_32(core, type, arg); } + return RZ_CMD_STATUS_OK; #endif + RZ_LOG_ERROR("JEMALLOC not supported.\n"); return RZ_CMD_STATUS_ERROR; } +// "dmxa" +RZ_IPI RzCmdStatus rz_cmd_debug_heap_jemalloc_a_handler(RzCore *core, int argc, const char **argv) { + return call_map_jemalloc(core, 'a', argc == 1 ? "" : argv[1]); +} + +// "dmxb" +RZ_IPI RzCmdStatus rz_cmd_debug_heap_jemalloc_b_handler(RzCore *core, int argc, const char **argv) { + return call_map_jemalloc(core, 'b', argc == 1 ? "" : argv[1]); +} + +// "dmxc" +RZ_IPI RzCmdStatus rz_cmd_debug_heap_jemalloc_c_handler(RzCore *core, int argc, const char **argv) { + return call_map_jemalloc(core, 'c', argv[1]); +} + static void backtrace_vars(RzCore *core, RzList /**/ *frames) { RzDebugFrame *f; RzListIter *iter; @@ -1476,69 +1391,6 @@ static void debug_trace_calls(RzCore *core, ut64 from, ut64 to, ut64 final_addr) rz_cons_break_pop(); } -static bool cmd_dcu(RzCore *core, const char *input) { - const char *ptr = NULL; - ut64 from, to, pc; - bool dcu_range = false; - bool invalid = (!input[0] || !input[1] || !input[2]); - if (invalid || (input[2] != ' ' && input[2] != '.')) { - rz_core_cmd_help(core, help_msg_dcu); - return false; - } - to = UT64_MAX; - if (input[2] == '.') { - ptr = strchr(input + 3, ' '); - if (ptr) { // TODO: put '\0' in *ptr to avoid - from = rz_num_tail(core->num, core->offset, input + 2); - if (ptr[1] == '.') { - to = rz_num_tail(core->num, core->offset, ptr + 2); - } else { - to = rz_num_math(core->num, ptr + 1); - } - dcu_range = true; - } else { - from = rz_num_tail(core->num, core->offset, input + 2); - } - } else { - ptr = strchr(input + 3, ' '); - if (ptr) { // TODO: put '\0' in *ptr to avoid - from = rz_num_math(core->num, input + 3); - if (ptr[1] == '.') { - to = rz_num_tail(core->num, core->offset, ptr + 2); - } else { - to = rz_num_math(core->num, ptr + 1); - } - dcu_range = true; - } else { - from = rz_num_math(core->num, input + 3); - } - } - if (core->num->nc.errors && rz_cons_is_interactive()) { - RZ_LOG_ERROR("core: Cannot continue until unknown address '%s'\n", core->num->nc.calc_buf); - return false; - } - if (to == UT64_MAX) { - to = from; - } - if (dcu_range) { - rz_cons_break_push(NULL, NULL); - do { - if (rz_cons_is_breaked()) { - break; - } - rz_debug_step(core->dbg, 1); - rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_GPR, false); - pc = rz_debug_reg_get(core->dbg, "PC"); - RZ_LOG_WARN("core: Continue 0x%08" PFMT64x " > 0x%08" PFMT64x " < 0x%08" PFMT64x "\n", - from, pc, to); - } while (pc < from || pc > to); - rz_cons_break_pop(); - } else { - return rz_core_debug_continue_until(core, from, to); - } - return true; -} - // dsu RZ_IPI RzCmdStatus rz_cmd_debug_step_until_handler(RzCore *core, int argc, const char **argv) { rz_reg_arena_swap(core->dbg->reg, true); @@ -1656,13 +1508,6 @@ RZ_IPI RzCmdStatus rz_cmd_debug_traces_reset_handler(RzCore *core, int argc, con return RZ_CMD_STATUS_OK; } -// dta -RZ_IPI int rz_cmd_debug_trace_addr(void *data, const char *input) { - RzCore *core = (RzCore *)data; - rz_debug_trace_at(core->dbg, input); - return 0; -} - // dtc RZ_IPI RzCmdStatus rz_cmd_debug_trace_calls_handler(RzCore *core, int argc, const char **argv) { ut64 from = argc > 1 ? rz_num_math(core->num, argv[1]) : 0; @@ -2550,22 +2395,15 @@ RZ_IPI RzCmdStatus rz_cmd_debug_continue_syscall_handler(RzCore *core, int argc, } // dcu -RZ_IPI int rz_cmd_debug_continue_until(void *data, const char *input) { - RzCore *core = (RzCore *)data; +RZ_IPI RzCmdStatus rz_cmd_debug_continue_until_handler(RzCore *core, int argc, const char **argv) { CMD_CHECK_DEBUG_DEAD(core); rz_cons_break_push(rz_core_static_debug_stop, core->dbg); - if (input[0] == '?') { - rz_core_cmd_help(core, help_msg_dcu); - } else if (input[0] == '.' || input[0] == '\0') { - cmd_dcu(core, "cu $$"); - } else { - char *tmpinp = rz_str_newf("cu %s", input + 1); - cmd_dcu(core, tmpinp); - free(tmpinp); - } + ut64 addr = rz_num_math(core->num, argv[1]); + RZ_LOG_INFO("Continue until 0x%" PFMT64x "\n", addr); + bool success = rz_core_debug_continue_until(core, addr); rz_cons_break_pop(); rz_core_dbg_follow_seek_register(core); - return RZ_CMD_STATUS_OK; + return success ? RZ_CMD_STATUS_OK : RZ_CMD_STATUS_ERROR; } RZ_IPI RzCmdStatus rz_cmd_debug_handler_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { diff --git a/librz/core/cmd/cmd_linux_heap_glibc.c b/librz/core/cmd/cmd_linux_heap_glibc.c index a423368cf8a..d0269071f9b 100644 --- a/librz/core/cmd/cmd_linux_heap_glibc.c +++ b/librz/core/cmd/cmd_linux_heap_glibc.c @@ -58,14 +58,12 @@ RZ_IPI RzCmdStatus rz_cmd_heap_tcache_print_handler(RzCore *core, int argc, cons call_handler(rz_cmd_heap_tcache_print_handler, argc, argv); } -RZ_IPI int rz_cmd_heap_bins_list_print(void *data, const char *input) { - RzCore *core = (RzCore *)data; - call_handler(rz_cmd_heap_bins_list_print, input); +RZ_IPI RzCmdStatus rz_cmd_heap_bins_list_print_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) { + call_handler(rz_cmd_heap_bins_list_print_handler, argc == 1 ? "" : argv[1], mode); } -RZ_IPI int rz_cmd_heap_fastbins_print(void *data, const char *input) { - RzCore *core = (RzCore *)data; - call_handler(rz_cmd_heap_fastbins_print, input); +RZ_IPI RzCmdStatus rz_cmd_heap_fastbins_print_handler(RzCore *core, int argc, const char **argv) { + call_handler(rz_cmd_heap_fastbins_print_handler, argc == 1 ? "" : argv[1]); } RZ_IPI RzCmdStatus rz_cmd_heap_arena_bins_print_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) { diff --git a/librz/core/cmd_descs/cmd_debug.yaml b/librz/core/cmd_descs/cmd_debug.yaml index 78b72f65f09..b7baf19079e 100644 --- a/librz/core/cmd_descs/cmd_debug.yaml +++ b/librz/core/cmd_descs/cmd_debug.yaml @@ -331,7 +331,10 @@ commands: - name: dcu summary: Debug continue until cname: cmd_debug_continue_until - type: RZ_CMD_DESC_TYPE_OLDINPUT + args: + - name: address + type: RZ_CMD_ARG_TYPE_RZNUM + default_value: "$$" - name: dd summary: Debug file descriptors commands subcommands: @@ -610,10 +613,6 @@ commands: summary: Reset traces (instruction/calls) cname: cmd_debug_traces_reset args: [] - - name: dta - summary: Only trace given addresses - cname: cmd_debug_trace_addr - type: RZ_CMD_DESC_TYPE_OLDINPUT - name: dtc summary: Trace call/ret cname: cmd_debug_trace_calls @@ -852,8 +851,49 @@ commands: subcommands: cmd_heap_glibc - name: dmi summary: List/Load symbols - cname: cmd_debug_dmi - type: RZ_CMD_DESC_TYPE_OLDINPUT + subcommands: + - name: "dmi" + summary: List libraries and library symbols. + cname: cmd_debug_dmi + args: + - name: lib_name + type: RZ_CMD_ARG_TYPE_STRING + optional: true + - name: symbol_name + type: RZ_CMD_ARG_TYPE_STRING + optional: true + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_RIZIN + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_QUIET + - RZ_OUTPUT_MODE_QUIETEST + - name: "dmia" + summary: List all info of target library. + cname: cmd_debug_dmi_all + args: + - name: lib_name + type: RZ_CMD_ARG_TYPE_STRING + optional: true + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_RIZIN + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_QUIET + - RZ_OUTPUT_MODE_QUIETEST + - name: "dmi." + summary: List closest symbol to the current address. + cname: cmd_debug_dmi_closest + args: [] + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_RIZIN + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_QUIET + - RZ_OUTPUT_MODE_QUIETEST - name: dml summary: Load contents of file into current map region cname: cmd_debug_dml @@ -917,9 +957,27 @@ commands: args: [] - name: dmx summary: Jemalloc heap commands - cname: cmd_debug_heap_jemalloc - type: RZ_CMD_DESC_TYPE_OLDINPUT - args: [] + subcommands: + - name: dmxa + summary: Show all arenas created, or print arena_type structure for given arena. + cname: cmd_debug_heap_jemalloc_a + args: + - name: arena_type + type: RZ_CMD_ARG_TYPE_STRING + optional: true + - name: dmxb + summary: Show all arenas created, or print arena_type structure for given arena. + cname: cmd_debug_heap_jemalloc_b + args: + - name: arena_type + type: RZ_CMD_ARG_TYPE_STRING + optional: true + - name: dmxc + summary: Show all chunks created in all arenas, or show all chunks created for a given arena_t instanc. + cname: cmd_debug_heap_jemalloc_c + args: + - name: "*|arena_type" + type: RZ_CMD_ARG_TYPE_STRING - name: dp summary: List or attach to process or thread subcommands: diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index 731a7affc8a..4be80561e70 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -396,6 +396,7 @@ static const RzCmdDescArg cmd_debug_continue_execution_args[2]; static const RzCmdDescArg cmd_debug_continue_send_signal_args[3]; static const RzCmdDescArg cmd_debug_continue_syscall_args[2]; static const RzCmdDescArg cmd_debug_continue_traptrace_args[2]; +static const RzCmdDescArg cmd_debug_continue_until_args[2]; static const RzCmdDescArg cmd_debug_descriptor_open_args[2]; static const RzCmdDescArg cmd_debug_descriptor_close_args[2]; static const RzCmdDescArg cmd_debug_descriptor_seek_args[3]; @@ -440,11 +441,16 @@ static const RzCmdDescArg cmd_heap_fastbins_print_args[2]; static const RzCmdDescArg cmd_heap_chunks_graph_args[2]; static const RzCmdDescArg cmd_heap_info_print_args[2]; static const RzCmdDescArg cmd_main_arena_print_args[2]; +static const RzCmdDescArg cmd_debug_dmi_args[3]; +static const RzCmdDescArg cmd_debug_dmi_all_args[2]; static const RzCmdDescArg cmd_debug_dml_args[2]; static const RzCmdDescArg debug_memory_permission_args[3]; static const RzCmdDescArg cmd_debug_dmL_args[2]; static const RzCmdDescArg cmd_debug_dmS_args[3]; static const RzCmdDescArg cmd_debug_process_heap_block_args[2]; +static const RzCmdDescArg cmd_debug_heap_jemalloc_a_args[2]; +static const RzCmdDescArg cmd_debug_heap_jemalloc_b_args[2]; +static const RzCmdDescArg cmd_debug_heap_jemalloc_c_args[2]; static const RzCmdDescArg cmd_debug_pid_list_args[2]; static const RzCmdDescArg cmd_debug_pid_attach_args[2]; static const RzCmdDescArg cmd_debug_pid_detach_args[2]; @@ -8374,8 +8380,19 @@ static const RzCmdDescHelp cmd_debug_continue_traptrace_help = { .args = cmd_debug_continue_traptrace_args, }; +static const RzCmdDescArg cmd_debug_continue_until_args[] = { + { + .name = "address", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .default_value = "$$", + + }, + { 0 }, +}; static const RzCmdDescHelp cmd_debug_continue_until_help = { .summary = "Debug continue until", + .args = cmd_debug_continue_until_args, }; static const RzCmdDescHelp dd_help = { @@ -8895,10 +8912,6 @@ static const RzCmdDescHelp cmd_debug_traces_reset_help = { .args = cmd_debug_traces_reset_args, }; -static const RzCmdDescHelp cmd_debug_trace_addr_help = { - .summary = "Only trace given addresses", -}; - static const RzCmdDescArg cmd_debug_trace_calls_args[] = { { .name = "from", @@ -9306,7 +9319,7 @@ static const RzCmdDescArg cmd_heap_bins_list_print_args[] = { { 0 }, }; static const RzCmdDescHelp cmd_heap_bins_list_print_help = { - .summary = "Display double linked list for bins in an arena. Use dmhbg command for graphical representation.", + .summary = "Display double linked list for bins in an arena.", .args = cmd_heap_bins_list_print_args, }; @@ -9402,9 +9415,52 @@ static const RzCmdDescHelp cmd_heap_tcache_print_help = { .args = cmd_heap_tcache_print_args, }; -static const RzCmdDescHelp cmd_debug_dmi_help = { +static const RzCmdDescHelp dmi_help = { .summary = "List/Load symbols", }; +static const RzCmdDescArg cmd_debug_dmi_args[] = { + { + .name = "lib_name", + .type = RZ_CMD_ARG_TYPE_STRING, + .optional = true, + + }, + { + .name = "symbol_name", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_dmi_help = { + .summary = "List libraries and library symbols.", + .args = cmd_debug_dmi_args, +}; + +static const RzCmdDescArg cmd_debug_dmi_all_args[] = { + { + .name = "lib_name", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_dmi_all_help = { + .summary = "List all info of target library.", + .args = cmd_debug_dmi_all_args, +}; + +static const RzCmdDescArg cmd_debug_dmi_closest_args[] = { + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_dmi_closest_help = { + .summary = "List closest symbol to the current address.", + .args = cmd_debug_dmi_closest_args, +}; static const RzCmdDescArg cmd_debug_dml_args[] = { { @@ -9508,12 +9564,51 @@ static const RzCmdDescHelp cmd_debug_heap_block_flag_help = { .args = cmd_debug_heap_block_flag_args, }; -static const RzCmdDescArg cmd_debug_heap_jemalloc_args[] = { +static const RzCmdDescHelp dmx_help = { + .summary = "Jemalloc heap commands", +}; +static const RzCmdDescArg cmd_debug_heap_jemalloc_a_args[] = { + { + .name = "arena_type", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, { 0 }, }; -static const RzCmdDescHelp cmd_debug_heap_jemalloc_help = { - .summary = "Jemalloc heap commands", - .args = cmd_debug_heap_jemalloc_args, +static const RzCmdDescHelp cmd_debug_heap_jemalloc_a_help = { + .summary = "Show all arenas created, or print arena_type structure for given arena.", + .args = cmd_debug_heap_jemalloc_a_args, +}; + +static const RzCmdDescArg cmd_debug_heap_jemalloc_b_args[] = { + { + .name = "arena_type", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_heap_jemalloc_b_help = { + .summary = "Show all arenas created, or print arena_type structure for given arena.", + .args = cmd_debug_heap_jemalloc_b_args, +}; + +static const RzCmdDescArg cmd_debug_heap_jemalloc_c_args[] = { + { + .name = "*|arena_type", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_heap_jemalloc_c_help = { + .summary = "Show all chunks created in all arenas, or show all chunks created for a given arena_t instanc.", + .args = cmd_debug_heap_jemalloc_c_args, }; static const RzCmdDescHelp dp_help = { @@ -21149,7 +21244,7 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *cmd_debug_continue_traptrace_cd = rz_cmd_desc_argv_new(core->rcmd, dc_cd, "dct", rz_cmd_debug_continue_traptrace_handler, &cmd_debug_continue_traptrace_help); rz_warn_if_fail(cmd_debug_continue_traptrace_cd); - RzCmdDesc *cmd_debug_continue_until_cd = rz_cmd_desc_oldinput_new(core->rcmd, dc_cd, "dcu", rz_cmd_debug_continue_until, &cmd_debug_continue_until_help); + RzCmdDesc *cmd_debug_continue_until_cd = rz_cmd_desc_argv_new(core->rcmd, dc_cd, "dcu", rz_cmd_debug_continue_until_handler, &cmd_debug_continue_until_help); rz_warn_if_fail(cmd_debug_continue_until_cd); RzCmdDesc *dd_cd = rz_cmd_desc_group_new(core->rcmd, d_cd, "dd", rz_cmd_debug_descriptor_open_handler, &cmd_debug_descriptor_open_help, &dd_help); @@ -21261,9 +21356,6 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *cmd_debug_traces_reset_cd = rz_cmd_desc_argv_new(core->rcmd, dt_cd, "dt-", rz_cmd_debug_traces_reset_handler, &cmd_debug_traces_reset_help); rz_warn_if_fail(cmd_debug_traces_reset_cd); - RzCmdDesc *cmd_debug_trace_addr_cd = rz_cmd_desc_oldinput_new(core->rcmd, dt_cd, "dta", rz_cmd_debug_trace_addr, &cmd_debug_trace_addr_help); - rz_warn_if_fail(cmd_debug_trace_addr_cd); - RzCmdDesc *cmd_debug_trace_calls_cd = rz_cmd_desc_argv_new(core->rcmd, dt_cd, "dtc", rz_cmd_debug_trace_calls_handler, &cmd_debug_trace_calls_help); rz_warn_if_fail(cmd_debug_trace_calls_cd); @@ -21360,7 +21452,7 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *cmd_arena_print_cd = rz_cmd_desc_argv_new(core->rcmd, dmh_cd, "dmha", rz_cmd_arena_print_handler, &cmd_arena_print_help); rz_warn_if_fail(cmd_arena_print_cd); - RzCmdDesc *cmd_heap_bins_list_print_cd = rz_cmd_desc_oldinput_new(core->rcmd, dmh_cd, "dmhb", rz_cmd_heap_bins_list_print, &cmd_heap_bins_list_print_help); + RzCmdDesc *cmd_heap_bins_list_print_cd = rz_cmd_desc_argv_modes_new(core->rcmd, dmh_cd, "dmhb", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_GRAPH, rz_cmd_heap_bins_list_print_handler, &cmd_heap_bins_list_print_help); rz_warn_if_fail(cmd_heap_bins_list_print_cd); RzCmdDesc *cmd_heap_chunk_print_cd = rz_cmd_desc_argv_new(core->rcmd, dmh_cd, "dmhc", rz_cmd_heap_chunk_print_handler, &cmd_heap_chunk_print_help); @@ -21369,7 +21461,7 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *cmd_heap_arena_bins_print_cd = rz_cmd_desc_argv_modes_new(core->rcmd, dmh_cd, "dmhd", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_heap_arena_bins_print_handler, &cmd_heap_arena_bins_print_help); rz_warn_if_fail(cmd_heap_arena_bins_print_cd); - RzCmdDesc *cmd_heap_fastbins_print_cd = rz_cmd_desc_oldinput_new(core->rcmd, dmh_cd, "dmhf", rz_cmd_heap_fastbins_print, &cmd_heap_fastbins_print_help); + RzCmdDesc *cmd_heap_fastbins_print_cd = rz_cmd_desc_argv_new(core->rcmd, dmh_cd, "dmhf", rz_cmd_heap_fastbins_print_handler, &cmd_heap_fastbins_print_help); rz_warn_if_fail(cmd_heap_fastbins_print_cd); RzCmdDesc *cmd_heap_chunks_graph_cd = rz_cmd_desc_argv_new(core->rcmd, dmh_cd, "dmhg", rz_cmd_heap_chunks_graph_handler, &cmd_heap_chunks_graph_help); @@ -21384,8 +21476,13 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *cmd_heap_tcache_print_cd = rz_cmd_desc_argv_new(core->rcmd, dmh_cd, "dmht", rz_cmd_heap_tcache_print_handler, &cmd_heap_tcache_print_help); rz_warn_if_fail(cmd_heap_tcache_print_cd); - RzCmdDesc *cmd_debug_dmi_cd = rz_cmd_desc_oldinput_new(core->rcmd, dm_cd, "dmi", rz_cmd_debug_dmi, &cmd_debug_dmi_help); - rz_warn_if_fail(cmd_debug_dmi_cd); + RzCmdDesc *dmi_cd = rz_cmd_desc_group_state_new(core->rcmd, dm_cd, "dmi", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_QUIETEST, rz_cmd_debug_dmi_handler, &cmd_debug_dmi_help, &dmi_help); + rz_warn_if_fail(dmi_cd); + RzCmdDesc *cmd_debug_dmi_all_cd = rz_cmd_desc_argv_state_new(core->rcmd, dmi_cd, "dmia", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_QUIETEST, rz_cmd_debug_dmi_all_handler, &cmd_debug_dmi_all_help); + rz_warn_if_fail(cmd_debug_dmi_all_cd); + + RzCmdDesc *cmd_debug_dmi_closest_cd = rz_cmd_desc_argv_state_new(core->rcmd, dmi_cd, "dmi.", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_QUIETEST, rz_cmd_debug_dmi_closest_handler, &cmd_debug_dmi_closest_help); + rz_warn_if_fail(cmd_debug_dmi_closest_cd); RzCmdDesc *cmd_debug_dml_cd = rz_cmd_desc_argv_new(core->rcmd, dm_cd, "dml", rz_cmd_debug_dml_handler, &cmd_debug_dml_help); rz_warn_if_fail(cmd_debug_dml_cd); @@ -21407,8 +21504,16 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *cmd_debug_heap_block_flag_cd = rz_cmd_desc_argv_new(core->rcmd, dmw_cd, "dmwbf", rz_cmd_debug_heap_block_flag_handler, &cmd_debug_heap_block_flag_help); rz_warn_if_fail(cmd_debug_heap_block_flag_cd); - RzCmdDesc *cmd_debug_heap_jemalloc_cd = rz_cmd_desc_oldinput_new(core->rcmd, dm_cd, "dmx", rz_cmd_debug_heap_jemalloc, &cmd_debug_heap_jemalloc_help); - rz_warn_if_fail(cmd_debug_heap_jemalloc_cd); + RzCmdDesc *dmx_cd = rz_cmd_desc_group_new(core->rcmd, dm_cd, "dmx", NULL, NULL, &dmx_help); + rz_warn_if_fail(dmx_cd); + RzCmdDesc *cmd_debug_heap_jemalloc_a_cd = rz_cmd_desc_argv_new(core->rcmd, dmx_cd, "dmxa", rz_cmd_debug_heap_jemalloc_a_handler, &cmd_debug_heap_jemalloc_a_help); + rz_warn_if_fail(cmd_debug_heap_jemalloc_a_cd); + + RzCmdDesc *cmd_debug_heap_jemalloc_b_cd = rz_cmd_desc_argv_new(core->rcmd, dmx_cd, "dmxb", rz_cmd_debug_heap_jemalloc_b_handler, &cmd_debug_heap_jemalloc_b_help); + rz_warn_if_fail(cmd_debug_heap_jemalloc_b_cd); + + RzCmdDesc *cmd_debug_heap_jemalloc_c_cd = rz_cmd_desc_argv_new(core->rcmd, dmx_cd, "dmxc", rz_cmd_debug_heap_jemalloc_c_handler, &cmd_debug_heap_jemalloc_c_help); + rz_warn_if_fail(cmd_debug_heap_jemalloc_c_cd); RzCmdDesc *dp_cd = rz_cmd_desc_group_state_new(core->rcmd, d_cd, "dp", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_TABLE, rz_cmd_debug_pid_list_handler, &cmd_debug_pid_list_help, &dp_help); rz_warn_if_fail(dp_cd); diff --git a/librz/core/cmd_descs/cmd_descs.h b/librz/core/cmd_descs/cmd_descs.h index 347493ef9bb..90a0449dc30 100644 --- a/librz/core/cmd_descs/cmd_descs.h +++ b/librz/core/cmd_descs/cmd_descs.h @@ -1072,7 +1072,7 @@ RZ_IPI RzCmdStatus rz_cmd_debug_continue_syscall_handler(RzCore *core, int argc, // "dct" RZ_IPI RzCmdStatus rz_cmd_debug_continue_traptrace_handler(RzCore *core, int argc, const char **argv); // "dcu" -RZ_IPI int rz_cmd_debug_continue_until(void *data, const char *input); +RZ_IPI RzCmdStatus rz_cmd_debug_continue_until_handler(RzCore *core, int argc, const char **argv); // "dd" RZ_IPI RzCmdStatus rz_cmd_debug_descriptor_open_handler(RzCore *core, int argc, const char **argv); // "dd-" @@ -1147,8 +1147,6 @@ RZ_IPI RzCmdStatus rz_cmd_debug_trace_add_handler(RzCore *core, int argc, const RZ_IPI RzCmdStatus rz_cmd_debug_trace_add_addrs_handler(RzCore *core, int argc, const char **argv); // "dt-" RZ_IPI RzCmdStatus rz_cmd_debug_traces_reset_handler(RzCore *core, int argc, const char **argv); -// "dta" -RZ_IPI int rz_cmd_debug_trace_addr(void *data, const char *input); // "dtc" RZ_IPI RzCmdStatus rz_cmd_debug_trace_calls_handler(RzCore *core, int argc, const char **argv); // "dte" @@ -1216,13 +1214,13 @@ RZ_IPI RzCmdStatus rz_cmd_heap_chunks_print_handler(RzCore *core, int argc, cons // "dmha" RZ_IPI RzCmdStatus rz_cmd_arena_print_handler(RzCore *core, int argc, const char **argv); // "dmhb" -RZ_IPI int rz_cmd_heap_bins_list_print(void *data, const char *input); +RZ_IPI RzCmdStatus rz_cmd_heap_bins_list_print_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); // "dmhc" RZ_IPI RzCmdStatus rz_cmd_heap_chunk_print_handler(RzCore *core, int argc, const char **argv); // "dmhd" RZ_IPI RzCmdStatus rz_cmd_heap_arena_bins_print_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); // "dmhf" -RZ_IPI int rz_cmd_heap_fastbins_print(void *data, const char *input); +RZ_IPI RzCmdStatus rz_cmd_heap_fastbins_print_handler(RzCore *core, int argc, const char **argv); // "dmhg" RZ_IPI RzCmdStatus rz_cmd_heap_chunks_graph_handler(RzCore *core, int argc, const char **argv); // "dmhi" @@ -1232,7 +1230,11 @@ RZ_IPI RzCmdStatus rz_cmd_main_arena_print_handler(RzCore *core, int argc, const // "dmht" RZ_IPI RzCmdStatus rz_cmd_heap_tcache_print_handler(RzCore *core, int argc, const char **argv); // "dmi" -RZ_IPI int rz_cmd_debug_dmi(void *data, const char *input); +RZ_IPI RzCmdStatus rz_cmd_debug_dmi_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +// "dmia" +RZ_IPI RzCmdStatus rz_cmd_debug_dmi_all_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +// "dmi." +RZ_IPI RzCmdStatus rz_cmd_debug_dmi_closest_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); // "dml" RZ_IPI RzCmdStatus rz_cmd_debug_dml_handler(RzCore *core, int argc, const char **argv); // "dmp" @@ -1247,8 +1249,12 @@ RZ_IPI RzCmdStatus rz_cmd_debug_process_heaps_handler(RzCore *core, int argc, co RZ_IPI RzCmdStatus rz_cmd_debug_process_heap_block_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); // "dmwbf" RZ_IPI RzCmdStatus rz_cmd_debug_heap_block_flag_handler(RzCore *core, int argc, const char **argv); -// "dmx" -RZ_IPI int rz_cmd_debug_heap_jemalloc(void *data, const char *input); +// "dmxa" +RZ_IPI RzCmdStatus rz_cmd_debug_heap_jemalloc_a_handler(RzCore *core, int argc, const char **argv); +// "dmxb" +RZ_IPI RzCmdStatus rz_cmd_debug_heap_jemalloc_b_handler(RzCore *core, int argc, const char **argv); +// "dmxc" +RZ_IPI RzCmdStatus rz_cmd_debug_heap_jemalloc_c_handler(RzCore *core, int argc, const char **argv); // "dp" RZ_IPI RzCmdStatus rz_cmd_debug_pid_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); // "dpl" diff --git a/librz/core/cmd_descs/cmd_heap_glibc.yaml b/librz/core/cmd_descs/cmd_heap_glibc.yaml index a6c7545cd6d..7aa8ba561f0 100644 --- a/librz/core/cmd_descs/cmd_heap_glibc.yaml +++ b/librz/core/cmd_descs/cmd_heap_glibc.yaml @@ -25,8 +25,9 @@ commands: cname: cmd_heap_bins_list_print summary: > Display double linked list for bins in an arena. - Use dmhbg command for graphical representation. - type: RZ_CMD_DESC_TYPE_OLDINPUT + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_GRAPH args: - name: bin_num|bin_num:malloc_state type: RZ_CMD_ARG_TYPE_STRING @@ -50,7 +51,6 @@ commands: choices: ["small", "large", "fast", "unsorted", "tcache"] - name: dmhf cname: cmd_heap_fastbins_print - type: RZ_CMD_DESC_TYPE_OLDINPUT summary: > Display all parsed fastbins of main_arena's or a particular arena fastbinY instance diff --git a/librz/core/linux_heap_glibc.c b/librz/core/linux_heap_glibc.c index 88ed2e20804..a7c5bd37bc6 100644 --- a/librz/core/linux_heap_glibc.c +++ b/librz/core/linux_heap_glibc.c @@ -3,6 +3,7 @@ // SPDX-FileCopyrightText: 2016-2020 pancake // SPDX-License-Identifier: LGPL-3.0-only +#include #include #include #include @@ -1294,8 +1295,7 @@ static int GH(print_double_linked_list_bin)(RzCore *core, MallocState *main_aren return ret; } -static void GH(print_heap_bin)(RzCore *core, GHT m_arena, MallocState *main_arena, const char *input) { - int i, j = 2; +static void GH(print_heap_bin)(RzCore *core, GHT m_arena, MallocState *main_arena, const char *input, bool print_graph) { GHT num_bin = GHT_MAX; GHT offset; RzConsPrintablePalette *pal = &rz_cons_singleton()->context->pal; @@ -1307,30 +1307,25 @@ static void GH(print_heap_bin)(RzCore *core, GHT m_arena, MallocState *main_aren offset = 12 * SZ + sizeof(int) * 2; } - switch (input[0]) { - case '\0': // dmhb + if (!input[0]) { PRINT_YA("Bins {\n"); - for (i = 0; i < NBINS - 1; i++) { - PRINTF_YA(" Bin %03d:\n", i); + for (size_t i = 0; i < NBINS - 1; i++) { + PRINTF_YA(" Bin %03" PFMTSZu ":\n", i); GH(print_double_linked_list_bin) - (core, main_arena, m_arena, offset, i, 0); + (core, main_arena, m_arena, offset, i, print_graph); } PRINT_YA("\n}\n"); - break; - case ' ': // dmhb [bin_num] - j--; // for spaces after input - // fallthrough - case 'g': // dmhbg [bin_num] - num_bin = rz_num_get(NULL, input + j); + } else { + num_bin = rz_num_get(NULL, input); if (num_bin > NBINS - 2) { - RZ_LOG_ERROR("core: the number of bins is greater than %d\n", NBINS - 2); - break; + RZ_LOG_ERROR("The number of bins is greater than %d\n", NBINS - 2); + return; } PRINTF_YA(" Bin %03" PFMT64u ":\n", (ut64)num_bin); GH(print_double_linked_list_bin) - (core, main_arena, m_arena, offset, num_bin, j); - break; + (core, main_arena, m_arena, offset, num_bin, print_graph); } + return; } void GH(rz_heap_chunk_free)(RzHeapChunkListItem *item) { @@ -1427,8 +1422,7 @@ void GH(print_heap_fastbin)(RzCore *core, GHT m_arena, MallocState *main_arena, int global_max_fast_idx = fastbin_index(global_max_fast); int fastbin_count = fastbins_max < global_max_fast_idx ? fastbins_max : global_max_fast_idx; int bin_to_print = 0; - switch (input[0]) { - case ' ': + if (input[0]) { bin_to_print = (int)rz_num_get(NULL, input); if (bin_to_print <= 0 || bin_to_print - 1 > fastbin_count) { RZ_LOG_ERROR("core: the number of bins is greater than %d\n", fastbin_count + 1); @@ -2722,7 +2716,7 @@ RZ_IPI RzCmdStatus GH(rz_cmd_heap_tcache_print_handler)(RzCore *core, int argc, return RZ_CMD_STATUS_OK; } -RZ_IPI int GH(rz_cmd_heap_bins_list_print)(RzCore *core, const char *input) { +RZ_IPI RzCmdStatus GH(rz_cmd_heap_bins_list_print_handler)(RzCore *core, const char *input, RzOutputMode mode) { GHT m_arena = GHT_MAX, m_state = GHT_MAX; RzConsPrintablePalette *pal = &rz_cons_singleton()->context->pal; MallocState *main_arena = RZ_NEW0(MallocState); @@ -2752,7 +2746,7 @@ RZ_IPI int GH(rz_cmd_heap_bins_list_print)(RzCore *core, const char *input) { return RZ_CMD_STATUS_ERROR; } GH(print_heap_bin) - (core, m_state, main_arena, dup); + (core, m_state, main_arena, dup, mode == RZ_OUTPUT_MODE_GRAPH); } else { PRINT_RA("This address is not part of the arenas\n"); free(main_arena); @@ -2764,7 +2758,7 @@ RZ_IPI int GH(rz_cmd_heap_bins_list_print)(RzCore *core, const char *input) { return RZ_CMD_STATUS_OK; } -RZ_IPI int GH(rz_cmd_heap_fastbins_print)(void *data, const char *input) { +RZ_IPI RzCmdStatus GH(rz_cmd_heap_fastbins_print_handler)(void *data, const char *input) { RzCore *core = (RzCore *)data; GHT m_arena = GHT_MAX, m_state = GHT_MAX; RzConsPrintablePalette *pal = &rz_cons_singleton()->context->pal; diff --git a/librz/core/linux_heap_jemalloc.c b/librz/core/linux_heap_jemalloc.c index 56ed9644638..aa08bcbe51e 100644 --- a/librz/core/linux_heap_jemalloc.c +++ b/librz/core/linux_heap_jemalloc.c @@ -493,37 +493,19 @@ static void GH(jemalloc_get_runs)(RzCore *core, const char *input) { } #endif -static int GH(cmd_dbg_map_jemalloc)(RzCore *core, const char *input) { - const char *help_msg[] = { - "Usage:", "dmx", " # Jemalloc heap parsing commands", - "dmxa", "[arena_t]", "show all arenas created, or print arena_t structure for given arena", - "dmxb", "[arena_t]", "show all bins created for given arena", - "dmxc", "*|[arena_t]", "show all chunks created in all arenas, or show all chunks created for a given arena_t instance", - // "dmxr", "[arena_chunk_t]", "print all runs created for a given arena_chunk_t instance", - "dmx?", "", "Show map heap help", NULL - }; - - switch (input[0]) { - case '?': - rz_core_cmd_help(core, help_msg); - break; +static void GH(cmd_dbg_map_jemalloc)(RzCore *core, char dmx_variant, const char *arg) { + switch (dmx_variant) { case 'a': // dmxa GH(jemalloc_print_narenas) - (core, input + 1); + (core, arg); break; case 'b': // dmxb GH(jemalloc_get_bins) - (core, input + 1); + (core, arg); break; case 'c': // dmxc GH(jemalloc_get_chunks) - (core, input + 1); - break; - /* - case 'r': //dmxr - GH(jemalloc_get_runs) (core, input + 1); + (core, arg); break; - */ } - return 0; } diff --git a/librz/core/tui/visual.c b/librz/core/tui/visual.c index cdbc038cd8a..0bf6182eb0f 100644 --- a/librz/core/tui/visual.c +++ b/librz/core/tui/visual.c @@ -749,7 +749,7 @@ static int visual_nkey(RzCore *core, int ch) { ch = rz_core_cmd0(core, cmd); } else { if (core->print->cur_enabled) { - rz_core_debug_continue_until(core, core->offset, core->offset + core->print->cur); + rz_core_debug_continue_until(core, core->offset); core->print->cur_enabled = 0; } } diff --git a/librz/debug/trace.c b/librz/debug/trace.c index 2b2561c952d..571473e152b 100644 --- a/librz/debug/trace.c +++ b/librz/debug/trace.c @@ -10,7 +10,6 @@ RZ_API RzDebugTrace *rz_debug_trace_new(void) { return NULL; } t->tag = 1; // UT32_MAX; - t->addresses = NULL; t->enabled = false; t->traces = rz_list_new(); if (!t->traces) { @@ -205,12 +204,6 @@ RZ_API void rz_debug_trace_op(RzDebug *dbg, RzAnalysisOp *op) { oldpc = op->addr; } -RZ_API void rz_debug_trace_at(RzDebug *dbg, const char *str) { - // TODO: parse offsets and so use ut64 instead of strstr() - free(dbg->trace->addresses); - dbg->trace->addresses = (str && *str) ? rz_str_dup(str) : NULL; -} - RZ_API RzDebugTracepoint *rz_debug_trace_get(RzDebug *dbg, ut64 addr) { char tmpbuf[64]; int tag = dbg->trace->tag; @@ -261,25 +254,10 @@ RZ_API RZ_OWN RzList /**/ *rz_debug_traces_info(RzDebug *dbg, ut64 return info_list; } -// XXX: find better name, make it public? -static int rz_debug_trace_is_traceable(RzDebug *dbg, ut64 addr) { - if (dbg->trace->addresses) { - char addr_str[32]; - snprintf(addr_str, sizeof(addr_str), "0x%08" PFMT64x, addr); - if (!strstr(dbg->trace->addresses, addr_str)) { - return false; - } - } - return true; -} - RZ_API RzDebugTracepoint *rz_debug_trace_add(RzDebug *dbg, ut64 addr, int size) { RzDebugTracepoint *tp; char tmpbuf[64]; int tag = dbg->trace->tag; - if (!rz_debug_trace_is_traceable(dbg, addr)) { - return NULL; - } rz_analysis_trace_bb(dbg->analysis, addr); tp = RZ_NEW0(RzDebugTracepoint); if (!tp) { diff --git a/librz/include/rz_cmd.h b/librz/include/rz_cmd.h index 8e48d7859af..42cd6656164 100644 --- a/librz/include/rz_cmd.h +++ b/librz/include/rz_cmd.h @@ -91,6 +91,7 @@ typedef enum { RZ_OUTPUT_MODE_LONG_JSON = 1 << 6, RZ_OUTPUT_MODE_TABLE = 1 << 7, RZ_OUTPUT_MODE_QUIETEST = 1 << 8, + RZ_OUTPUT_MODE_GRAPH = 1 << 9, } RzOutputMode; /** diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index c087685e176..f8be249fac1 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -572,7 +572,7 @@ RZ_API void rz_core_reg_update_flags(RzCore *core); /* cdebug.c */ RZ_API bool rz_core_is_debug(RzCore *core); RZ_API bool rz_core_debug_step_one(RzCore *core, int times); -RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr, ut64 to); +RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr); RZ_API void rz_core_debug_bp_add_noreturn_func(RzCore *core); RZ_API void rz_core_debug_breakpoint_toggle(RZ_NONNULL RzCore *core, ut64 addr); diff --git a/librz/include/rz_debug.h b/librz/include/rz_debug.h index dc888ceb8ac..573f57aa2b5 100644 --- a/librz/include/rz_debug.h +++ b/librz/include/rz_debug.h @@ -222,11 +222,8 @@ typedef struct rz_debug_trace_t { RzList /**/ *traces; int count; int enabled; - // int changed; int tag; int dup; - char *addresses; - // TODO: add range here HtSP *ht; } RzDebugTrace; @@ -564,7 +561,6 @@ RZ_API void rz_debug_tracenodes_reset(RzDebug *dbg); RZ_API void rz_debug_trace_reset(RzDebug *dbg); RZ_API int rz_debug_trace_pc(RzDebug *dbg, ut64 pc); RZ_API void rz_debug_trace_op(RzDebug *dbg, RzAnalysisOp *op); -RZ_API void rz_debug_trace_at(RzDebug *dbg, const char *str); RZ_API RzDebugTracepoint *rz_debug_trace_get(RzDebug *dbg, ut64 addr); RZ_API void rz_debug_trace_print(RzDebug *dbg, RzCmdStateOutput *state, ut64 offset); RZ_API RZ_OWN RzList /**/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset); diff --git a/librz/include/rz_heap_glibc.h b/librz/include/rz_heap_glibc.h index 44418faa46a..0fe95d7f860 100644 --- a/librz/include/rz_heap_glibc.h +++ b/librz/include/rz_heap_glibc.h @@ -1,6 +1,7 @@ #ifndef RZ_HEAP_GLIBC_H #define RZ_HEAP_GLIBC_H +#include #include #include @@ -355,11 +356,11 @@ RZ_API RzList /**/ *rz_heap_chunks_list_wrapper_32(RzCore RZ_API RzList /**/ *rz_heap_arena_list_wrapper_64(RzCore *core); RZ_API RzList /**/ *rz_heap_arena_list_wrapper_32(RzCore *core); -RZ_IPI int rz_cmd_heap_fastbins_print_64(void *data, const char *input); -RZ_IPI int rz_cmd_heap_fastbins_print_32(void *data, const char *input); +RZ_IPI RzCmdStatus rz_cmd_heap_fastbins_print_handler_64(void *data, const char *input); +RZ_IPI RzCmdStatus rz_cmd_heap_fastbins_print_handler_32(void *data, const char *input); -RZ_IPI int rz_cmd_heap_bins_list_print_64(RzCore *core, const char *input); -RZ_IPI int rz_cmd_heap_bins_list_print_32(RzCore *core, const char *input); +RZ_IPI RzCmdStatus rz_cmd_heap_bins_list_print_handler_64(RzCore *core, const char *input, RzOutputMode mode); +RZ_IPI RzCmdStatus rz_cmd_heap_bins_list_print_handler_32(RzCore *core, const char *input, RzOutputMode mode); RZ_API void rz_heap_bin_free_64(RzHeapBin *bin); RZ_API void rz_heap_bin_free_32(RzHeapBin *bin); diff --git a/test/db/archos/darwin-arm64/dbg b/test/db/archos/darwin-arm64/dbg index de3de9af24c..02f65a1023b 100644 --- a/test/db/archos/darwin-arm64/dbg +++ b/test/db/archos/darwin-arm64/dbg @@ -33,12 +33,8 @@ str x8, [sp, 0x10] EOF REGEXP_FILTER_ERR=(((Continue\suntil)|(hit\sbreakpoint\sat:)|[0-9a-f][0-9a-f][0-9a-f]\n)) EXPECT_ERR=<