diff options
author | Bharata B Rao <bharata@linux.vnet.ibm.com> | 2014-09-26 14:37:38 +0530 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2014-11-04 23:26:12 +0100 |
commit | 81f194dd69756677cc36ff0827bf970f0f048914 (patch) | |
tree | 5f1f0ab25c0d0fa00fdaf29484e53154630c96e7 /target-ppc/translate_init.c | |
parent | 54ff58bb10acd6938b43dd3504ece4a7f4eb3fa1 (diff) |
target-ppc: Fix an invalid free in opcode table handling code.
Opcode table has direct, indirect and double indirect handlers, but
ppc_cpu_unrealizefn() frees direct handlers which are never allocated
and never frees double indirect handlers.
Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/translate_init.c')
-rw-r--r-- | target-ppc/translate_init.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 3ff68ae9ad..20d58c01db 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -9132,11 +9132,24 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp) { PowerPCCPU *cpu = POWERPC_CPU(dev); CPUPPCState *env = &cpu->env; - int i; + opc_handler_t **table; + int i, j; for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { - if (env->opcodes[i] != &invalid_handler) { - g_free(env->opcodes[i]); + if (env->opcodes[i] == &invalid_handler) { + continue; + } + if (is_indirect_opcode(env->opcodes[i])) { + table = ind_table(env->opcodes[i]); + for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { + if (table[j] != &invalid_handler && + is_indirect_opcode(table[j])) { + g_free((opc_handler_t *)((uintptr_t)table[j] & + ~PPC_INDIRECT)); + } + } + g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] & + ~PPC_INDIRECT)); } } } |