From b9d5e1d92707f04c258784eb52c3f92f65abc708 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 18 Dec 2018 05:09:47 -0500 Subject: [PATCH] target/arm: Free name string in ARMCPRegInfo hashtable entries' When we add a new entry to the ARMCPRegInfo hash table in add_cpreg_to_hashtable(), we allocate memory for tehe ARMCPRegInfo struct itself, and we also g_strdup() the name string. So the hashtable's value destructor function must free the name string as well as the struct. Spotted by clang's leak sanitizer. The leak here is a small one-off leak at startup, because we don't support CPU hotplug, and so the only time when we destroy hash table entries is for the case where ARM_CP_OVERRIDE means we register a wildcard entry and then override it later. Backports commit ac87e5072e2cbfcf8e80caac7ef43ceb6914c7af from qemu --- qemu/target/arm/cpu.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 8e9f97db..31f98123 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -505,6 +505,20 @@ static inline void unset_feature(CPUARMState *env, int feature) #define ARM_CPUS_PER_CLUSTER 8 +static void cpreg_hashtable_data_destroy(gpointer data) +{ + /* + * Destroy function for cpu->cp_regs hashtable data entries. + * We must free the name string because it was g_strdup()ed in + * add_cpreg_to_hashtable(). It's OK to cast away the 'const' + * from r->name because we know we definitely allocated it. + */ + ARMCPRegInfo *r = data; + + g_free((void *)r->name); + g_free(r); +} + static void arm_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) { CPUState *cs = CPU(obj); @@ -514,7 +528,7 @@ static void arm_cpu_initfn(struct uc_struct *uc, Object *obj, void *opaque) cs->env_ptr = &cpu->env; cpu_exec_init(cs, &error_abort, opaque); cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, - g_free, g_free); + g_free, cpreg_hashtable_data_destroy); QLIST_INIT(&cpu->pre_el_change_hooks); QLIST_INIT(&cpu->el_change_hooks);