From d5936dc688bedf54848a29b7c171ef47deb2bf91 Mon Sep 17 00:00:00 2001
From: Marc Schink <openocd-dev@marcschink.de>
Date: Mon, 1 Apr 2019 13:47:17 +0200
Subject: [PATCH] target/riscv: Free registers to avoid memory leak

Tested with SiFive HiFive1 development board.

Change-Id: I96a9a528057fcf9fc54d3da46a672d2cd54c3d5f
Signed-off-by: Marc Schink <openocd-dev@marcschink.de>
Reviewed-on: http://openocd.zylin.com/4885
Tested-by: jenkins
Reviewed-by: Tim Newsome <tim@sifive.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
---
 src/target/riscv/riscv.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 3b88e3313..44da5a9e6 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -271,16 +271,8 @@ static int riscv_init_target(struct command_context *cmd_ctx,
 	return ERROR_OK;
 }
 
-static void riscv_deinit_target(struct target *target)
+static void riscv_free_registers(struct target *target)
 {
-	LOG_DEBUG("riscv_deinit_target()");
-	struct target_type *tt = get_target_type(target);
-	if (tt) {
-		tt->deinit_target(target);
-		riscv_info_t *info = (riscv_info_t *) target->arch_info;
-		free(info->reg_names);
-		free(info);
-	}
 	/* Free the shared structure use for most registers. */
 	if (target->reg_cache) {
 		if (target->reg_cache->reg_list) {
@@ -293,6 +285,21 @@ static void riscv_deinit_target(struct target *target)
 		}
 		free(target->reg_cache);
 	}
+}
+
+static void riscv_deinit_target(struct target *target)
+{
+	LOG_DEBUG("riscv_deinit_target()");
+	struct target_type *tt = get_target_type(target);
+	if (tt) {
+		tt->deinit_target(target);
+		riscv_info_t *info = (riscv_info_t *) target->arch_info;
+		free(info->reg_names);
+		free(info);
+	}
+
+	riscv_free_registers(target);
+
 	target->arch_info = NULL;
 }
 
@@ -2503,11 +2510,7 @@ int riscv_init_registers(struct target *target)
 {
 	RISCV_INFO(info);
 
-	if (target->reg_cache) {
-		if (target->reg_cache->reg_list)
-			free(target->reg_cache->reg_list);
-		free(target->reg_cache);
-	}
+	riscv_free_registers(target);
 
 	target->reg_cache = calloc(1, sizeof(*target->reg_cache));
 	target->reg_cache->name = "RISC-V Registers";
-- 
GitLab