From 09076d10dd553dc63f08e74aedb1b6aa030857f9 Mon Sep 17 00:00:00 2001 From: Matthias Welwarsky Date: Mon, 26 Mar 2018 09:45:46 +0200 Subject: [PATCH] armv8: valgrind memleak fixes Various fixes for memory leaks, adds a target cleanup for aarch64 and ARM CTI objects. Change-Id: I2267f0894df655fdf73d70c11ed03df0b8f8d07d Signed-off-by: Matthias Welwarsky Reviewed-on: http://openocd.zylin.com/4478 Tested-by: jenkins Reviewed-by: Matthias Welwarsky Reviewed-by: Tomas Vanek --- src/jtag/core.c | 2 -- src/openocd.c | 4 ++++ src/target/aarch64.c | 15 +++++++++++++++ src/target/arm_cti.c | 12 ++++++++++++ src/target/arm_cti.h | 2 +- src/target/armv8.c | 46 ++++++++++++++++++++++++++++++++++++++------ src/target/armv8.h | 2 ++ 7 files changed, 74 insertions(+), 9 deletions(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 4522321a..5d9b8101 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1494,8 +1494,6 @@ int adapter_quit(void) t = n; } - dap_cleanup_all(); - return ERROR_OK; } diff --git a/src/openocd.c b/src/openocd.c index 902528d0..f084dd45 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -359,6 +359,10 @@ int openocd_main(int argc, char *argv[]) unregister_all_commands(cmd_ctx, NULL); + /* free all DAP and CTI objects */ + dap_cleanup_all(); + arm_cti_cleanup_all(); + adapter_quit(); /* Shutdown commandline interface */ diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 4641a3fd..cd835027 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2386,6 +2386,20 @@ static int aarch64_target_create(struct target *target, Jim_Interp *interp) return aarch64_init_arch_info(target, aarch64, pc->adiv5_config.dap); } +static void aarch64_deinit_target(struct target *target) +{ + struct aarch64_common *aarch64 = target_to_aarch64(target); + struct armv8_common *armv8 = &aarch64->armv8_common; + struct arm_dpm *dpm = &armv8->dpm; + + armv8_free_reg_cache(target); + free(aarch64->brp_list); + free(dpm->dbp); + free(dpm->dwp); + free(target->private_config); + free(aarch64); +} + static int aarch64_mmu(struct target *target, int *enabled) { if (target->state != TARGET_HALTED) { @@ -2658,6 +2672,7 @@ struct target_type aarch64_target = { .target_create = aarch64_target_create, .target_jim_configure = aarch64_jim_configure, .init_target = aarch64_init_target, + .deinit_target = aarch64_deinit_target, .examine = aarch64_examine, .read_phys_memory = aarch64_read_phys_memory, diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index 547b9615..0d117e76 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -219,6 +219,18 @@ static int cti_find_reg_offset(const char *name) return -1; } +int arm_cti_cleanup_all(void) +{ + struct arm_cti_object *obj, *tmp; + + list_for_each_entry_safe(obj, tmp, &all_cti, lh) { + free(obj->name); + free(obj); + } + + return ERROR_OK; +} + COMMAND_HANDLER(handle_cti_dump) { struct arm_cti_object *obj = CMD_DATA; diff --git a/src/target/arm_cti.h b/src/target/arm_cti.h index 181f0644..7c4f7ebe 100644 --- a/src/target/arm_cti.h +++ b/src/target/arm_cti.h @@ -73,7 +73,7 @@ extern int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *va extern int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel); extern int arm_cti_set_channel(struct arm_cti *self, uint32_t channel); extern int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel); - +extern int arm_cti_cleanup_all(void); extern int cti_register_commands(struct command_context *cmd_ctx); #endif /* OPENOCD_TARGET_ARM_CTI_H */ diff --git a/src/target/armv8.c b/src/target/armv8.c index 3321dd60..82b2b249 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -1547,15 +1547,14 @@ struct reg_cache *armv8_build_reg_cache(struct target *target) } else LOG_ERROR("unable to allocate feature list"); - if (armv8_regs[i].data_type == NULL) { - reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type)); - if (reg_list[i].reg_data_type) + reg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type)); + if (reg_list[i].reg_data_type) { + if (armv8_regs[i].data_type == NULL) reg_list[i].reg_data_type->type = armv8_regs[i].type; else - LOG_ERROR("unable to allocate reg type list"); + *reg_list[i].reg_data_type = *armv8_regs[i].data_type; } else - reg_list[i].reg_data_type = armv8_regs[i].data_type; - + LOG_ERROR("unable to allocate reg type list"); } arm->cpsr = reg_list + ARMV8_xPSR; @@ -1608,6 +1607,41 @@ struct reg *armv8_reg_current(struct arm *arm, unsigned regnum) return r; } +static void armv8_free_cache(struct reg_cache *cache, bool regs32) +{ + struct reg *reg; + unsigned int i; + + if (!cache) + return; + + for (i = 0; i < cache->num_regs; i++) { + reg = &cache->reg_list[i]; + + free(reg->feature); + free(reg->reg_data_type); + } + + if (!regs32) + free(cache->reg_list[0].arch_info); + free(cache->reg_list); + free(cache); +} + +void armv8_free_reg_cache(struct target *target) +{ + struct armv8_common *armv8 = target_to_armv8(target); + struct arm *arm = &armv8->arm; + struct reg_cache *cache = NULL, *cache32 = NULL; + + cache = arm->core_cache; + if (cache != NULL) + cache32 = cache->next; + armv8_free_cache(cache32, true); + armv8_free_cache(cache, false); + arm->core_cache = NULL; +} + const struct command_registration armv8_command_handlers[] = { COMMAND_REGISTRATION_DONE }; diff --git a/src/target/armv8.h b/src/target/armv8.h index 6525d260..b3464622 100644 --- a/src/target/armv8.h +++ b/src/target/armv8.h @@ -318,6 +318,8 @@ static inline unsigned int armv8_curel_from_core_mode(enum arm_mode core_mode) void armv8_select_reg_access(struct armv8_common *armv8, bool is_aarch64); int armv8_set_dbgreg_bits(struct armv8_common *armv8, unsigned int reg, unsigned long mask, unsigned long value); +extern void armv8_free_reg_cache(struct target *target); + extern const struct command_registration armv8_command_handlers[]; #endif /* OPENOCD_TARGET_ARMV8_H */ -- 2.39.5