aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBharata B Rao <bharata@linux.vnet.ibm.com>2014-09-26 14:37:38 +0530
committerAlexander Graf <agraf@suse.de>2014-11-04 23:26:12 +0100
commit81f194dd69756677cc36ff0827bf970f0f048914 (patch)
tree5f1f0ab25c0d0fa00fdaf29484e53154630c96e7
parent54ff58bb10acd6938b43dd3504ece4a7f4eb3fa1 (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>
-rw-r--r--target-ppc/translate_init.c19
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));
}
}
}