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 b01b5fe13a
("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
This commit is contained in:
parent
061cae171c
commit
6f88aa0fb3
|
@ -272,6 +272,8 @@ struct arm_reg {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm);
|
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);
|
struct reg_cache *armv8_build_reg_cache(struct target *target);
|
||||||
|
|
||||||
extern const struct command_registration arm_command_handlers[];
|
extern const struct command_registration arm_command_handlers[];
|
||||||
|
|
|
@ -1100,6 +1100,7 @@ int arm_dpm_setup(struct arm_dpm *dpm)
|
||||||
dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp));
|
dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp));
|
||||||
|
|
||||||
if (!dpm->dbp || !dpm->dwp) {
|
if (!dpm->dbp || !dpm->dwp) {
|
||||||
|
arm_free_reg_cache(arm);
|
||||||
free(dpm->dbp);
|
free(dpm->dbp);
|
||||||
free(dpm->dwp);
|
free(dpm->dwp);
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
|
|
@ -769,6 +769,27 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)
|
||||||
return cache;
|
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)
|
int arm_arch_state(struct target *target)
|
||||||
{
|
{
|
||||||
struct arm *arm = target_to_arm(target);
|
struct arm *arm = target_to_arm(target);
|
||||||
|
|
|
@ -2959,6 +2959,7 @@ static void cortex_a_deinit_target(struct target *target)
|
||||||
}
|
}
|
||||||
|
|
||||||
free(cortex_a->brp_list);
|
free(cortex_a->brp_list);
|
||||||
|
arm_free_reg_cache(dpm->arm);
|
||||||
free(dpm->dbp);
|
free(dpm->dbp);
|
||||||
free(dpm->dwp);
|
free(dpm->dwp);
|
||||||
free(target->private_config);
|
free(target->private_config);
|
||||||
|
|
Loading…
Reference in New Issue