diff options
author | Antonio Borneo <borneo.antonio@gmail.com> | 2020-05-22 18:55:34 +0200 |
---|---|---|
committer | Antonio Borneo <borneo.antonio@gmail.com> | 2020-06-06 18:05:29 +0100 |
commit | 6f88aa0fb3bb7a91b5327b75e8fb772ed6d3be2d (patch) | |
tree | a7845631f2138ccc7f15e4aa32719b1156fd3870 /src | |
parent | 061cae171c9d2b6015a565dcc748dd04319e08cf (diff) | |
download | riscv-openocd-6f88aa0fb3bb7a91b5327b75e8fb772ed6d3be2d.zip riscv-openocd-6f88aa0fb3bb7a91b5327b75e8fb772ed6d3be2d.tar.gz riscv-openocd-6f88aa0fb3bb7a91b5327b75e8fb772ed6d3be2d.tar.bz2 |
target/cortex_a: fix memory leak of register cache
There is no method to free the register cache, allocated in
armv4_5, so we get a memory leak.
Issue identified by valgrind.
Implement the method arm_free_reg_cache() and call it in cortex_a
deinit and to exit for error during arm_dpm_setup().
Tested on dual cortex-A stm32mp15x.
This change is inspired from similar fix in commit b01b5fe13a67
("armv7m: Fix memory leak in register caching.").
The same allocation is also used by target types "arm7tdmi",
"arm9tdmi", "arm11" and "xscale" but they all lack the deinit
method and I do not have relevant HW to test the fix. For such
reasons they are not addressed in this patch.
Change-Id: I4da1e1f12e36ec245d1f3b11a4eafcbd9a1d2e25
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/5693
Tested-by: jenkins
Diffstat (limited to 'src')
-rw-r--r-- | src/target/arm.h | 2 | ||||
-rw-r--r-- | src/target/arm_dpm.c | 1 | ||||
-rw-r--r-- | src/target/armv4_5.c | 21 | ||||
-rw-r--r-- | src/target/cortex_a.c | 1 |
4 files changed, 25 insertions, 0 deletions
diff --git a/src/target/arm.h b/src/target/arm.h index b399574..3450260 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -272,6 +272,8 @@ struct arm_reg { }; struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm); +void arm_free_reg_cache(struct arm *arm); + struct reg_cache *armv8_build_reg_cache(struct target *target); extern const struct command_registration arm_command_handlers[]; diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index 495d63e..72215f9 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -1100,6 +1100,7 @@ int arm_dpm_setup(struct arm_dpm *dpm) dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp)); if (!dpm->dbp || !dpm->dwp) { + arm_free_reg_cache(arm); free(dpm->dbp); free(dpm->dwp); return ERROR_FAIL; diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index b4581d5..58bc339 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -769,6 +769,27 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm) return cache; } +void arm_free_reg_cache(struct arm *arm) +{ + if (!arm || !arm->core_cache) + return; + + struct reg_cache *cache = arm->core_cache; + + for (unsigned int i = 0; i < cache->num_regs; i++) { + struct reg *reg = &cache->reg_list[i]; + + free(reg->feature); + free(reg->reg_data_type); + } + + free(cache->reg_list[0].arch_info); + free(cache->reg_list); + free(cache); + + arm->core_cache = NULL; +} + int arm_arch_state(struct target *target) { struct arm *arm = target_to_arm(target); diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index f71b155..f562a76 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -2959,6 +2959,7 @@ static void cortex_a_deinit_target(struct target *target) } free(cortex_a->brp_list); + arm_free_reg_cache(dpm->arm); free(dpm->dbp); free(dpm->dwp); free(target->private_config); |