From b91a44905c7b57cfa79b4b9870d4e60904173899 Mon Sep 17 00:00:00 2001 From: Rot127 <45763064+Rot127@users.noreply.github.com> Date: Mon, 25 Nov 2024 12:25:56 +0000 Subject: [PATCH 1/4] librz/arch/ppc: fix leaks of Capstone handle (#4737) --- librz/arch/p/analysis/analysis_ppc_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librz/arch/p/analysis/analysis_ppc_cs.c b/librz/arch/p/analysis/analysis_ppc_cs.c index 056f226f836..4952c15464a 100644 --- a/librz/arch/p/analysis/analysis_ppc_cs.c +++ b/librz/arch/p/analysis/analysis_ppc_cs.c @@ -1744,7 +1744,6 @@ static int analyze_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf rz_strbuf_fini(&op->esil); } cs_free(insn, n); - // cs_close (&handle); } return op->size; } @@ -1780,6 +1779,7 @@ static RzAnalysisILConfig *il_config(RzAnalysis *analysis) { static bool ppc_fini(void *user) { PPCContext *ctx = (PPCContext *)user; + cs_close(&ctx->handle); if (ctx) { RZ_FREE(ctx); } From 9051d00b25b8671212eacad8edd8bad13f84f122 Mon Sep 17 00:00:00 2001 From: Khairul Azhar Kasmiran Date: Mon, 25 Nov 2024 21:10:20 +0800 Subject: [PATCH 2/4] rz-test: Set default test dir to '.' (#4741) --- binrz/rz-test/rz-test.c | 97 ++--------------------------------------- 1 file changed, 3 insertions(+), 94 deletions(-) diff --git a/binrz/rz-test/rz-test.c b/binrz/rz-test/rz-test.c index 7e29efafc03..179c48b4e3c 100644 --- a/binrz/rz-test/rz-test.c +++ b/binrz/rz-test/rz-test.c @@ -19,6 +19,7 @@ #define RIZIN_CMD_DEFAULT "rizin" #define RZ_ASM_CMD_DEFAULT "rz-asm" #define JSON_TEST_FILE_DEFAULT "bins/elf/crackme0x00b" +#define TEST_DIR_DEFAULT "." #define TIMEOUT_DEFAULT 960 #define STRV(x) #x @@ -78,7 +79,7 @@ static int help(bool verbose) { "-r", "[rizin]", "Path to rizin executable (default is " RIZIN_CMD_DEFAULT ")", "-m", "[rz-asm]", "Path to rz-asm executable (default is " RZ_ASM_CMD_DEFAULT ")", "-f", "[file]", "File to use for JSON tests (default is " JSON_TEST_FILE_DEFAULT ")", - "-C", "[dir]", "Chdir before running rz-test (default follows executable symlink + test/new)", + "-C", "[dir]", "Chdir before running rz-test (default is '" TEST_DIR_DEFAULT "')", "-t", "[seconds]", "Timeout per test (default is " TIMEOUT_DEFAULT_STR " seconds)", "-o", "[file]", "Output test run information in JSON format to file", "-e", "[dir]", "Exclude a particular directory while testing (this option can appear many times)", @@ -106,95 +107,10 @@ static int help(bool verbose) { return 1; } -static bool rz_test_chdir(const char *argv0) { -#if __UNIX__ - if (rz_file_is_directory("db")) { - return true; - } - char src_path[PATH_MAX]; - char *rz_test_path = rz_file_path(argv0); - bool found = false; - - ssize_t linklen = readlink(rz_test_path, src_path, sizeof(src_path) - 1); - if (linklen != -1) { - src_path[linklen] = '\0'; - char *p = strstr(src_path, RZ_SYS_DIR "binrz" RZ_SYS_DIR "rz-test" RZ_SYS_DIR "rz-test"); - if (p) { - *p = 0; - strcat(src_path, RZ_SYS_DIR "test" RZ_SYS_DIR); - if (rz_file_is_directory(src_path)) { - if (chdir(src_path) != -1) { - eprintf("Running from %s\n", src_path); - found = true; - } else { - eprintf("Cannot find '%s' directory\n", src_path); - } - } - } - } else { - eprintf("Cannot follow the link %s\n", src_path); - } - free(rz_test_path); - return found; -#else - return false; -#endif -} - static bool rz_test_test_run_unit(void) { return rz_sys_system("make -C unit all run") == 0; } -static bool rz_test_chdir_fromtest(const char *test_path) { - if (!test_path || *test_path == '@') { - test_path = ""; - } - char *abs_test_path = rz_file_abspath(test_path); - if (!rz_file_is_directory(abs_test_path)) { - char *last_slash = (char *)rz_str_lchr(abs_test_path, RZ_SYS_DIR[0]); - if (last_slash) { - *last_slash = 0; - } - } - if (chdir(abs_test_path) == -1) { - free(abs_test_path); - return false; - } - free(abs_test_path); - bool found = false; - char *cwd = NULL; - char *old_cwd = NULL; - while (true) { - cwd = rz_sys_getdir(); - if (old_cwd && !strcmp(old_cwd, cwd)) { - break; - } - if (rz_file_is_directory("test")) { - rz_sys_chdir("test"); - if (rz_file_is_directory("db")) { - found = true; - eprintf("Running from %s\n", cwd); - break; - } - rz_sys_chdir(".."); - } - if (rz_file_is_directory("db")) { - found = true; - eprintf("Running from %s\n", cwd); - break; - } - free(old_cwd); - old_cwd = cwd; - cwd = NULL; - if (chdir("..") == -1) { - break; - } - } - free(old_cwd); - free(cwd); - return found; -} - static bool log_mode = false; int rz_test_main(int argc, const char **argv) { @@ -338,14 +254,7 @@ int rz_test_main(int argc, const char **argv) { goto beach; } } else { - bool dir_found = (opt.ind < argc && argv[opt.ind][0] != '.') - ? rz_test_chdir_fromtest(argv[opt.ind]) - : rz_test_chdir(argv[0]); - if (!dir_found) { - eprintf("Cannot find db/ directory related to the given test.\n"); - ret = -1; - goto beach; - } + rz_test_dir = TEST_DIR_DEFAULT; } if (fuzz_dir) { From c84078d5c739429364e0007283b33eb08e8a80c5 Mon Sep 17 00:00:00 2001 From: rajRishi22 Date: Mon, 25 Nov 2024 20:29:57 +0530 Subject: [PATCH 3/4] Formatted code using clang-format-16 --- librz/util/bitvector.c | 105 ++++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 21 deletions(-) diff --git a/librz/util/bitvector.c b/librz/util/bitvector.c index b9ba66fec29..95dfcbc4952 100644 --- a/librz/util/bitvector.c +++ b/librz/util/bitvector.c @@ -4,6 +4,7 @@ #include "rz_util.h" #include #include +#include #define NELEM(N, ELEMPER) ((N + (ELEMPER)-1) / (ELEMPER)) #define BV_ELEM_SIZE 8U @@ -209,26 +210,63 @@ RZ_API ut32 rz_bv_copy(RZ_NONNULL const RzBitVector *src, RZ_NONNULL RzBitVector * \param nbit ut32, control the size of copy (in bits) * \return copied_size ut32, Actual copied size */ + RZ_API ut32 rz_bv_copy_nbits(RZ_NONNULL const RzBitVector *src, ut32 src_start_pos, RZ_NONNULL RzBitVector *dst, ut32 dst_start_pos, ut32 nbit) { - rz_return_val_if_fail(src && dst, 0); + rz_return_val_if_fail(src && dst, 0); - ut32 max_nbit = RZ_MIN((src->len - src_start_pos), - (dst->len - dst_start_pos)); + // Determine the chunk size (word size) dynamically + const ut32 chunk_size = sizeof(unsigned long) * CHAR_BIT; // Word size in bits + ut32 max_nbit = RZ_MIN((src->len - src_start_pos), (dst->len - dst_start_pos)); - // prevent overflow - if (max_nbit < nbit) { - return 0; - } + if (max_nbit < nbit) { + return 0; + } - // normal case here - for (ut32 i = 0; i < nbit; ++i) { - bool c = rz_bv_get(src, src_start_pos + i); - rz_bv_set(dst, dst_start_pos + i, c); - } + ut32 bits_copied = 0; + + // Handle unaligned prefix + while ((src_start_pos % chunk_size != 0 || dst_start_pos % chunk_size != 0) && nbit > 0) { + bool bit = rz_bv_get(src, src_start_pos++); + rz_bv_set(dst, dst_start_pos++, bit); + --nbit; + ++bits_copied; + } + + // Process aligned chunks + while (nbit >= chunk_size) { + // Get chunks from the source and destination + unsigned long src_chunk = rz_bv_get_chunk(src, src_start_pos / chunk_size); + unsigned long dst_chunk = rz_bv_get_chunk(dst, dst_start_pos / chunk_size); - return nbit; + // Create a mask for the bits to copy + unsigned long mask = (1UL << chunk_size) - 1; + if (nbit < chunk_size) { + mask = (1UL << nbit) - 1; + } + + // Merge chunks using the optimized approach + unsigned long result = dst_chunk ^ ((dst_chunk ^ src_chunk) & mask); + rz_bv_set_chunk(dst, dst_start_pos / chunk_size, result); + + src_start_pos += chunk_size; + dst_start_pos += chunk_size; + nbit -= chunk_size; + bits_copied += chunk_size; + } + + // Handle remaining unaligned suffix bits + while (nbit > 0) { + bool bit = rz_bv_get(src, src_start_pos++); + rz_bv_set(dst, dst_start_pos++, bit); + --nbit; + ++bits_copied; + } + + return bits_copied; } + + /** * Return a new bitvector prepended with bv with n zero bits * \param bv RzBitVector, pointer to bitvector instance @@ -1480,18 +1518,43 @@ RZ_API ut64 rz_bv_to_ut64(RZ_NONNULL const RzBitVector *x) { * \return return true if success, else return false */ RZ_API bool rz_bv_set_range(RZ_NONNULL RzBitVector *bv, ut32 pos_start, ut32 pos_end, bool b) { - rz_return_val_if_fail(bv, false); - if (pos_start > bv->len - 1 || pos_end > bv->len - 1) { - return false; - } + rz_return_val_if_fail(bv, false); - for (ut32 i = pos_start; i <= pos_end; ++i) { - rz_bv_set(bv, i, b); - } + if (pos_start > bv->len - 1 || pos_end > bv->len - 1 || pos_start > pos_end) { + return false; + } - return true; + // Determine the chunk size dynamically + const ut32 chunk_size = sizeof(unsigned long) * CHAR_BIT; + + // Handle unaligned prefix bits + while (pos_start < pos_end && pos_start % chunk_size != 0) { + rz_bv_set(bv, pos_start++, b); + } + + // Process aligned chunks + if (pos_start < pos_end) { + ut32 chunk_start = pos_start / chunk_size; + ut32 chunk_end = pos_end / chunk_size; + + unsigned long fill_value = b ? ~0UL : 0UL; + + for (ut32 i = chunk_start; i < chunk_end; ++i) { + rz_bv_set_chunk(bv, i, fill_value); + } + + pos_start = chunk_end * chunk_size; + } + + // Handle remaining unaligned suffix bits + while (pos_start <= pos_end) { + rz_bv_set(bv, pos_start++, b); + } + + return true; } + /** * check if bitvector's bits are all set to bit 1 * \param x RzBitVector From cde2cfff27ff284de3514723ea513a9eb1b3ce23 Mon Sep 17 00:00:00 2001 From: rajRishi22 Date: Mon, 25 Nov 2024 23:34:04 +0530 Subject: [PATCH 4/4] Resolved issues from 1st review --- librz/util/bitvector.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/librz/util/bitvector.c b/librz/util/bitvector.c index 95dfcbc4952..a78bbfed1a3 100644 --- a/librz/util/bitvector.c +++ b/librz/util/bitvector.c @@ -2,12 +2,15 @@ // SPDX-License-Identifier: LGPL-3.0-only #include "rz_util.h" +#include #include #include -#include + #define NELEM(N, ELEMPER) ((N + (ELEMPER)-1) / (ELEMPER)) #define BV_ELEM_SIZE 8U +#define SIZE_OF_UNSIGNED_LONG (sizeof(unsigned long)) + // optimization for reversing 8 bits which uses 32 bits // https://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits @@ -215,22 +218,23 @@ RZ_API ut32 rz_bv_copy_nbits(RZ_NONNULL const RzBitVector *src, ut32 src_start_p rz_return_val_if_fail(src && dst, 0); // Determine the chunk size (word size) dynamically - const ut32 chunk_size = sizeof(unsigned long) * CHAR_BIT; // Word size in bits + const ut32 chunk_size = SIZE_OF_UNSIGNED_LONG * CHAR_BIT; // Word size in bits ut32 max_nbit = RZ_MIN((src->len - src_start_pos), (dst->len - dst_start_pos)); if (max_nbit < nbit) { return 0; } - ut32 bits_copied = 0; + ut32 nbit_original = nbit; // Handle unaligned prefix - while ((src_start_pos % chunk_size != 0 || dst_start_pos % chunk_size != 0) && nbit > 0) { + if(src_start_pos % chunk_size != 0 || dst_start_pos % chunk_size != 0){ + while (nbit > 0) { bool bit = rz_bv_get(src, src_start_pos++); rz_bv_set(dst, dst_start_pos++, bit); --nbit; - ++bits_copied; } + } // Process aligned chunks while (nbit >= chunk_size) { @@ -239,7 +243,7 @@ RZ_API ut32 rz_bv_copy_nbits(RZ_NONNULL const RzBitVector *src, ut32 src_start_p unsigned long dst_chunk = rz_bv_get_chunk(dst, dst_start_pos / chunk_size); // Create a mask for the bits to copy - unsigned long mask = (1UL << chunk_size) - 1; + unsigned long mask = UINT32_MAX; if (nbit < chunk_size) { mask = (1UL << nbit) - 1; } @@ -251,7 +255,6 @@ RZ_API ut32 rz_bv_copy_nbits(RZ_NONNULL const RzBitVector *src, ut32 src_start_p src_start_pos += chunk_size; dst_start_pos += chunk_size; nbit -= chunk_size; - bits_copied += chunk_size; } // Handle remaining unaligned suffix bits @@ -259,10 +262,9 @@ RZ_API ut32 rz_bv_copy_nbits(RZ_NONNULL const RzBitVector *src, ut32 src_start_p bool bit = rz_bv_get(src, src_start_pos++); rz_bv_set(dst, dst_start_pos++, bit); --nbit; - ++bits_copied; } - return bits_copied; + return nbit_original; } @@ -1525,7 +1527,7 @@ RZ_API bool rz_bv_set_range(RZ_NONNULL RzBitVector *bv, ut32 pos_start, ut32 pos } // Determine the chunk size dynamically - const ut32 chunk_size = sizeof(unsigned long) * CHAR_BIT; + const ut32 chunk_size = SIZE_OF_UNSIGNED_LONG * CHAR_BIT; // Handle unaligned prefix bits while (pos_start < pos_end && pos_start % chunk_size != 0) {