From 4f7e0e177fc7ba709a388641757408177b0b1ec1 Mon Sep 17 00:00:00 2001 From: Peiwei Hu Date: Wed, 20 Dec 2023 19:46:44 +0800 Subject: [PATCH] Remove the dependency of core->block in pi/pI (#4023) --- librz/core/cmd/cmd_print.c | 12 ++++- librz/core/cmd_descs/cmd_descs.c | 4 +- librz/core/cmd_descs/cmd_print.yaml | 4 +- librz/core/core_private.h | 2 +- librz/core/disasm.c | 81 ++++++++++++++++++++++------- librz/core/meson.build | 1 - test/db/analysis/tms320.c64x_32 | 14 +++-- test/db/analysis/v850 | 3 +- test/db/cmd/cmd_foreach | 4 +- test/db/cmd/cmd_open | 2 +- test/db/cmd/cmd_pi | 31 ++++++++++- 11 files changed, 121 insertions(+), 37 deletions(-) diff --git a/librz/core/cmd/cmd_print.c b/librz/core/cmd/cmd_print.c index fb71d5fa52d..35d142732a3 100644 --- a/librz/core/cmd/cmd_print.c +++ b/librz/core/cmd/cmd_print.c @@ -2826,7 +2826,11 @@ RZ_IPI RzCmdStatus rz_assembly_of_hex_alias_handler(RzCore *core, int argc, cons } RZ_IPI RzCmdStatus rz_print_instructions_handler(RzCore *core, int argc, const char **argv) { - ut64 len = argc > 1 ? rz_num_math(core->num, argv[1]) : core->blocksize; + if (argc <= 1) { + RZ_LOG_ERROR("Invalid arguments\n"); + return RZ_CMD_STATUS_ERROR; + } + ut64 len = rz_num_math(core->num, argv[1]); rz_core_print_disasm_instructions(core, len, 0); return RZ_CMD_STATUS_OK; } @@ -5067,7 +5071,11 @@ RZ_IPI RzCmdStatus rz_print_key_mosaic_handler(RzCore *core, int argc, const cha } RZ_IPI RzCmdStatus rz_print_instr_handler(RzCore *core, int argc, const char **argv) { - ut64 N = argc > 1 ? rz_num_math(core->num, argv[1]) : core->blocksize; + if (argc <= 1) { + RZ_LOG_ERROR("Invalid arguments\n"); + return RZ_CMD_STATUS_ERROR; + } + ut64 N = rz_num_math(core->num, argv[1]); if (N == 0) { return RZ_CMD_STATUS_ERROR; } diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index 4558d945d17..ffa81ce09fc 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -13432,7 +13432,7 @@ static const RzCmdDescArg print_instr_args[] = { { 0 }, }; static const RzCmdDescHelp print_instr_help = { - .summary = "Print instructions/bytes", + .summary = "Disassemble and print instructions", .args = print_instr_args, }; @@ -13550,7 +13550,7 @@ static const RzCmdDescArg print_instructions_args[] = { { 0 }, }; static const RzCmdDescHelp print_instructions_help = { - .summary = "Print instructions/bytes", + .summary = "Disassemble and print bytes", .args = print_instructions_args, }; diff --git a/librz/core/cmd_descs/cmd_print.yaml b/librz/core/cmd_descs/cmd_print.yaml index e8b4418a01a..5bde9b20fce 100644 --- a/librz/core/cmd_descs/cmd_print.yaml +++ b/librz/core/cmd_descs/cmd_print.yaml @@ -546,7 +546,7 @@ commands: summary: Print instructions subcommands: - name: pi - summary: Print instructions/bytes + summary: Disassemble and print instructions cname: print_instr args: - name: N @@ -626,7 +626,7 @@ commands: summary: Print instructions subcommands: - name: pI - summary: Print instructions/bytes + summary: Disassemble and print bytes cname: print_instructions args: - name: N diff --git a/librz/core/core_private.h b/librz/core/core_private.h index 666d83d4bad..2b185f03abc 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -152,7 +152,7 @@ RZ_IPI void rz_core_flag_range_print(RzFlag *f, RzCmdStateOutput *state, ut64 ra /* cdisasm.c */ RZ_IPI bool rz_disasm_check_end(int nb_opcodes, int i_opcodes, int nb_bytes, int i_bytes); RZ_IPI void rz_core_asm_bb_middle(RZ_NONNULL RzCore *core, ut64 at, RZ_INOUT RZ_NONNULL int *oplen, RZ_NONNULL int *ret); -RZ_IPI bool rz_core_handle_backwards_disasm(RZ_NONNULL RzCore *core, +RZ_DEPRECATE RZ_IPI bool rz_core_handle_backwards_disasm(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_INOUT int *pn_opcodes, RZ_NONNULL RZ_INOUT int *pn_bytes); /* cprint.c */ diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 2ae40e7bd19..378af3e5a6d 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -5640,8 +5640,8 @@ RZ_API int rz_core_print_disasm_instructions_with_buf(RzCore *core, ut64 address RzDisasmState *ds = NULL; int i, j, ret, len = 0; char *tmpopstr; - const ut64 old_offset = core->offset; bool hasanalysis = false; + bool alloc_buf = !buf; const size_t addrbytes = buf ? 1 : core->io->addrbytes; int skip_bytes_flag = 0, skip_bytes_bb = 0; @@ -5656,16 +5656,21 @@ RZ_API int rz_core_print_disasm_instructions_with_buf(RzCore *core, ut64 address ds->len = nb_opcodes * 8; if (!buf) { - rz_core_seek(core, address, true); - buf = core->block; + buf = malloc(RZ_ABS(nb_bytes) + 1); + if (!buf) { + RZ_LOG_ERROR("Fail to alloc memory."); + return 0; + } + if (rz_io_nread_at(core->io, address, buf, RZ_ABS(nb_bytes) + 1) == -1) { + RZ_LOG_ERROR("Fail to read from 0x%" PFMT64x ".", address); + free(buf); + return 0; + } } - core->offset = address; - rz_cons_break_push(NULL, NULL); // build ranges to map addr with bits j = 0; -toro: for (i = 0; rz_disasm_check_end(nb_opcodes, j, nb_bytes, addrbytes * i); i += ret, j++) { ds->at = address + i; ds->vat = rz_core_pava(core, ds->at); @@ -5785,20 +5790,18 @@ RZ_API int rz_core_print_disasm_instructions_with_buf(RzCore *core, ut64 address ds->hint = NULL; } } - if (buf == core->block && nb_opcodes > 0 && j < nb_opcodes) { - rz_core_seek(core, core->offset + i, true); - goto toro; - } rz_cons_break_pop(); ds_free(ds); - core->offset = old_offset; rz_reg_arena_pop(core->analysis->reg); - + if (alloc_buf) { + free(buf); + } return len; } /** - * \brief Converting negative numbers n_opcodes and n_opcodes + * \brief (DEPRECATED, consider rz_core_backward_offset) + * Converting negative numbers n_opcodes and n_opcodes * to positive numbers n_opcodes and n_opcodes * and seek the appropriate offset * \param core RzCore reference @@ -5806,7 +5809,7 @@ RZ_API int rz_core_print_disasm_instructions_with_buf(RzCore *core, ut64 address * \param pn_bytes Pointer to n_bytes * \return success */ -RZ_IPI bool rz_core_handle_backwards_disasm(RZ_NONNULL RzCore *core, +RZ_DEPRECATE RZ_IPI bool rz_core_handle_backwards_disasm(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_INOUT int *pn_opcodes, RZ_NONNULL RZ_INOUT int *pn_bytes) { rz_return_val_if_fail(core && pn_opcodes && pn_bytes, false); @@ -5849,18 +5852,60 @@ RZ_IPI bool rz_core_handle_backwards_disasm(RZ_NONNULL RzCore *core, return true; } +/** + * \brief Calculate the offset while \p pn_opcodes and \p pn_bytes + * are negative, and \p pn_opcodes and \p pn_bytes will be + * converted to positive numbers. + * \param core RzCore reference + * \prarm pn_opcodes Pointer to n_opcodes + * \param pn_bytes Pointer to n_bytes + * \return calculated offset + */ +RZ_IPI ut64 rz_core_backward_offset(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_INOUT int *pn_opcodes, RZ_NONNULL RZ_INOUT int *pn_bytes) { + rz_return_val_if_fail(core && pn_opcodes && pn_bytes, false); + + if (*pn_opcodes >= 0 && *pn_bytes >= 0) { + return core->offset; + } + + ut64 opcode_offset = core->offset; + if (*pn_opcodes < 0) { + *pn_opcodes = -*pn_opcodes; + if (!rz_core_prevop_addr(core, core->offset, *pn_opcodes, &opcode_offset)) { + opcode_offset = rz_core_prevop_addr_force(core, core->offset, *pn_opcodes); + } + } + + ut64 byte_offset = core->offset; + if (*pn_bytes < 0) { + *pn_bytes = RZ_MIN(RZ_ABS(*pn_bytes), RZ_CORE_MAX_DISASM); + byte_offset = core->offset - *pn_bytes; + } + + return RZ_MIN(opcode_offset, byte_offset); +} + /* Disassemble either `nb_opcodes` instructions, or * `nb_bytes` bytes; both can be negative. * Set to 0 the parameter you don't use */ +#define MAX_OPSIZE 16 +#define MIN_OPSIZE 1 RZ_API int rz_core_print_disasm_instructions(RzCore *core, int nb_bytes, int nb_opcodes) { - const ut64 ocore_offset = core->offset; int ret = -1; - if (rz_core_handle_backwards_disasm(core, &nb_opcodes, &nb_bytes)) { - ret = rz_core_print_disasm_instructions_with_buf(core, core->offset, NULL, nb_bytes, nb_opcodes); + // handler negative parameters + ut64 offset = rz_core_backward_offset(core, &nb_opcodes, &nb_bytes); + // set the parameter equaling to 0 to a value that won't affect another parameter + if (nb_bytes == 0 && nb_opcodes != 0) { + nb_bytes = MAX_OPSIZE * RZ_ABS(nb_opcodes) + 1; } - rz_core_seek(core, ocore_offset, true); + if (nb_bytes != 0 && nb_opcodes == 0) { + nb_opcodes = nb_bytes / MIN_OPSIZE + 1; + } + ret = rz_core_print_disasm_instructions_with_buf(core, offset, NULL, nb_bytes, nb_opcodes); return ret; } +#undef MIN_OPSIZE +#undef MAX_OPSIZE RZ_API int rz_core_print_disasm_json(RzCore *core, ut64 addr, ut8 *buf, int nb_bytes, int nb_opcodes, PJ *pj) { ut64 old_offset = core->offset; diff --git a/librz/core/meson.build b/librz/core/meson.build index f7fa3581c76..45ce7b68104 100644 --- a/librz/core/meson.build +++ b/librz/core/meson.build @@ -211,4 +211,3 @@ modules += { 'rz_core': { ], 'plugins': [core_plugins] }} - diff --git a/test/db/analysis/tms320.c64x_32 b/test/db/analysis/tms320.c64x_32 index fd98407f01d..f1d3b00b06f 100644 --- a/test/db/analysis/tms320.c64x_32 +++ b/test/db/analysis/tms320.c64x_32 @@ -49,7 +49,7 @@ CMDS=< 0x1000011e8 ------------------------------ 0x1000012e8 +=> 0x1000011e8 ------------------------------ 0x1000012e8 EOF RUN diff --git a/test/db/cmd/cmd_pi b/test/db/cmd/cmd_pi index d07e5efb0cc..e42027b8fbf 100644 --- a/test/db/cmd/cmd_pi +++ b/test/db/cmd/cmd_pi @@ -16,4 +16,33 @@ CMDS=e scr.color=1 ; pi 1 EXPECT=<