target/arm926ejs: fix memory leaks
authorAntonio Borneo <borneo.antonio@gmail.com>
Sun, 14 Jun 2020 21:18:21 +0000 (23:18 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Wed, 8 Jul 2020 21:07:38 +0000 (22:07 +0100)
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 <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/5698
Tested-by: jenkins
src/target/arm7_9_common.c
src/target/arm7_9_common.h
src/target/arm926ejs.c
src/target/arm_jtag.c
src/target/arm_jtag.h
src/target/embeddedice.c
src/target/embeddedice.h

index 6a7bf9da58e62aea786c6e828a32e41930b05b37..28fefc5aab74fea942b680dcd55c9e31151e065f 100644 (file)
@@ -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)
 {
index 811f9c593e959c1e135b0c91afc72029dad4c147..4961212bb880620a86b2deba7528d973038ffc7c 100644 (file)
@@ -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,
index ac30485b8e9b5496f181857ebd4958882d653fb1..95a4f7ca0611264685aae743e1d50e6f098cf99b 100644 (file)
@@ -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,
index 49aca3487b6448133a44424432cbd2686a96f8eb..f9605acb16a562b1013eb514fb0d0228f69d358c 100644 (file)
@@ -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);
+}
index bb92abb84ba33d1faa4a49823eb0a7c8038418a1..bf5b837486cb8960159f4b2cf4402896f3799ef2 100644 (file)
@@ -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)
index 61ee8bbd92f0d5e63128043f1eaf23c4604db57d..7c53c45c57fac9bee752145fa09d149f2653a186 100644 (file)
@@ -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.
  */
index 39902fb3ec920add7511768ceed9f22a7b618e22..4b5c816a6b34c4849c5053e8a72fbaf3d6ac7d70 100644 (file)
@@ -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);