target/xscale: fix memory leak of register cache
authorAntonio Borneo <borneo.antonio@gmail.com>
Mon, 25 May 2020 08:43:53 +0000 (10:43 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sun, 26 Jul 2020 19:12:34 +0000 (20:12 +0100)
There is no method to free the register cache, allocated in
xscale_build_reg_cache(), so we get a memory leak.
Issue identified by tracking all calls to arm_build_reg_cache().

Implement the method xscale_deinit_target() that in turn calls the
new xscale_free_reg_cache().
Fix leak of struct xscale.

NOT TESTED on a real xscale target.
Tested on a arm926ejs (SPEAr320) by hacking the target type and
pretending it is a xscale:
sed -i s/arm926ejs/xscale/ tcl/target/spear3xx.cfg

Change-Id: Ibb2104c42411b76f4bb77c2fa387d1b85a3d2d5d
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/5695
Tested-by: jenkins
src/target/xscale.c

index edab4f9fc72bb50e7c54560b15a43d1e9c13594b..1bca96d73e9004d060225a61cbe711dd38458c6f 100644 (file)
@@ -2903,6 +2903,21 @@ static void xscale_build_reg_cache(struct target *target)
        xscale->reg_cache = (*cache_p);
 }
 
+static void xscale_free_reg_cache(struct target *target)
+{
+       struct xscale_common *xscale = target_to_xscale(target);
+       struct reg_cache *cache = xscale->reg_cache;
+
+       for (unsigned int i = 0; i < ARRAY_SIZE(xscale_reg_arch_info); i++)
+               free(cache->reg_list[i].value);
+
+       free(cache->reg_list[0].arch_info);
+       free(cache->reg_list);
+       free(cache);
+
+       arm_free_reg_cache(&xscale->arm);
+}
+
 static int xscale_init_target(struct command_context *cmd_ctx,
        struct target *target)
 {
@@ -2910,6 +2925,14 @@ static int xscale_init_target(struct command_context *cmd_ctx,
        return ERROR_OK;
 }
 
+static void xscale_deinit_target(struct target *target)
+{
+       struct xscale_common *xscale = target_to_xscale(target);
+
+       xscale_free_reg_cache(target);
+       free(xscale);
+}
+
 static int xscale_init_arch_info(struct target *target,
        struct xscale_common *xscale, struct jtag_tap *tap)
 {
@@ -3725,6 +3748,7 @@ struct target_type xscale_target = {
        .commands = xscale_command_handlers,
        .target_create = xscale_target_create,
        .init_target = xscale_init_target,
+       .deinit_target = xscale_deinit_target,
 
        .virt2phys = xscale_virt2phys,
        .mmu = xscale_mmu