From: Antonio Borneo Date: Sun, 14 Jun 2020 21:18:21 +0000 (+0200) Subject: target/arm926ejs: fix memory leaks X-Git-Tag: v0.11.0-rc1~212 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=f29d157882a756e562d224dd128eea1bbe3e3813 target/arm926ejs: fix memory leaks The memory leaks detected and fixed are: - arm register cache; - EmbeddedICE register cache; - arm_jtag_reset_callback internal data; - struct arm926ejs_common. Issue identified with valgrind. Tested on SPEAr320 based on arm926ejs. Change-Id: If2bed02c516051ce4d0eb29b204a3f3337fe5d6a Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5698 Tested-by: jenkins --- diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 6a7bf9da58..28fefc5aab 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2682,6 +2682,15 @@ int arm7_9_examine(struct target *target) return retval; } +void arm7_9_deinit(struct target *target) +{ + struct arm7_9_common *arm7_9 = target_to_arm7_9(target); + + if (target_was_examined(target)) + embeddedice_free_reg_cache(arm7_9->eice_cache); + + arm_jtag_close_connection(&arm7_9->jtag_info); +} int arm7_9_check_reset(struct target *target) { diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h index 811f9c593e..4961212bb8 100644 --- a/src/target/arm7_9_common.h +++ b/src/target/arm7_9_common.h @@ -186,6 +186,7 @@ int arm7_9_execute_sys_speed(struct target *target); int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9); int arm7_9_examine(struct target *target); +void arm7_9_deinit(struct target *target); int arm7_9_check_reset(struct target *target); int arm7_9_endianness_callback(jtag_callback_data_t pu8_in, diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index ac30485b8e..95a4f7ca06 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -723,6 +723,16 @@ static int arm926ejs_target_create(struct target *target, Jim_Interp *interp) return arm926ejs_init_arch_info(target, arm926ejs, target->tap); } +void arm926ejs_deinit_target(struct target *target) +{ + struct arm *arm = target_to_arm(target); + struct arm926ejs_common *arm926ejs = target_to_arm926(target); + + arm7_9_deinit(target); + arm_free_reg_cache(arm); + free(arm926ejs); +} + COMMAND_HANDLER(arm926ejs_handle_cache_info_command) { int retval; @@ -823,6 +833,7 @@ struct target_type arm926ejs_target = { .commands = arm926ejs_command_handlers, .target_create = arm926ejs_target_create, .init_target = arm9tdmi_init_target, + .deinit_target = arm926ejs_deinit_target, .examine = arm7_9_examine, .check_reset = arm7_9_check_reset, .virt2phys = arm926ejs_virt2phys, diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c index 49aca3487b..f9605acb16 100644 --- a/src/target/arm_jtag.c +++ b/src/target/arm_jtag.c @@ -92,3 +92,8 @@ int arm_jtag_setup_connection(struct arm_jtag *jtag_info) return jtag_register_event_callback(arm_jtag_reset_callback, jtag_info); } + +int arm_jtag_close_connection(struct arm_jtag *jtag_info) +{ + return jtag_unregister_event_callback(arm_jtag_reset_callback, jtag_info); +} diff --git a/src/target/arm_jtag.h b/src/target/arm_jtag.h index bb92abb84b..bf5b837486 100644 --- a/src/target/arm_jtag.h +++ b/src/target/arm_jtag.h @@ -61,6 +61,7 @@ static inline int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_c } int arm_jtag_setup_connection(struct arm_jtag *jtag_info); +int arm_jtag_close_connection(struct arm_jtag *jtag_info); /* use this as a static so we can inline it in -O3 and refer to it via a pointer */ static inline void arm7flip32(jtag_callback_data_t arg) diff --git a/src/target/embeddedice.c b/src/target/embeddedice.c index 61ee8bbd92..7c53c45c57 100644 --- a/src/target/embeddedice.c +++ b/src/target/embeddedice.c @@ -303,6 +303,22 @@ struct reg_cache *embeddedice_build_reg_cache(struct target *target, return reg_cache; } +/** + * Free all memory allocated for EmbeddedICE register cache + */ +void embeddedice_free_reg_cache(struct reg_cache *reg_cache) +{ + if (!reg_cache) + return; + + for (unsigned int i = 0; i < reg_cache->num_regs; i++) + free(reg_cache->reg_list[i].value); + + free(reg_cache->reg_list[0].arch_info); + free(reg_cache->reg_list); + free(reg_cache); +} + /** * Initialize EmbeddedICE module, if needed. */ diff --git a/src/target/embeddedice.h b/src/target/embeddedice.h index 39902fb3ec..4b5c816a6b 100644 --- a/src/target/embeddedice.h +++ b/src/target/embeddedice.h @@ -88,6 +88,7 @@ struct embeddedice_reg { struct reg_cache *embeddedice_build_reg_cache(struct target *target, struct arm7_9_common *arm7_9); +void embeddedice_free_reg_cache(struct reg_cache *reg_cache); int embeddedice_setup(struct target *target);