* [Qemu-devel] [PATCH 2/6] linux-user: Pass si_type information to queue_signal() explicitly
2016-07-28 15:44 [Qemu-devel] [PATCH 0/6] linux-user: Handle SEGV on signal entry/exit correctly Peter Maydell
2016-07-28 15:44 ` [Qemu-devel] [PATCH 1/6] linux-user: Recheck for pending synchronous signals too Peter Maydell
@ 2016-07-28 15:44 ` Peter Maydell
2016-07-28 15:44 ` [Qemu-devel] [PATCH 3/6] linux-user: SIGSEGV on signal entry need not be fatal Peter Maydell
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2016-07-28 15:44 UTC (permalink / raw)
To: qemu-devel; +Cc: patches, Riku Voipio
Instead of assuming in queue_signal() that all callers are passing
a siginfo structure which uses the _sifields._sigfault part of the
union (and thus a si_type of QEMU_SI_FAULT), make callers pass
the si_type they require in as an argument.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
linux-user/main.c | 124 +++++++++++++++++++++++++--------------------------
linux-user/qemu.h | 3 +-
linux-user/signal.c | 10 ++---
linux-user/syscall.c | 6 ++-
4 files changed, 71 insertions(+), 72 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index 462e820..de26d4a 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -339,7 +339,7 @@ void cpu_loop(CPUX86State *env)
info.si_errno = 0;
info.si_code = TARGET_SI_KERNEL;
info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP0D_GPF:
/* XXX: potential problem if ABI32 */
@@ -353,7 +353,7 @@ void cpu_loop(CPUX86State *env)
info.si_errno = 0;
info.si_code = TARGET_SI_KERNEL;
info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP0E_PAGE:
@@ -364,7 +364,7 @@ void cpu_loop(CPUX86State *env)
else
info.si_code = TARGET_SEGV_ACCERR;
info._sifields._sigfault._addr = env->cr[2];
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP00_DIVZ:
#ifndef TARGET_X86_64
@@ -378,7 +378,7 @@ void cpu_loop(CPUX86State *env)
info.si_errno = 0;
info.si_code = TARGET_FPE_INTDIV;
info._sifields._sigfault._addr = env->eip;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP01_DB:
@@ -398,7 +398,7 @@ void cpu_loop(CPUX86State *env)
info.si_code = TARGET_SI_KERNEL;
info._sifields._sigfault._addr = 0;
}
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP04_INTO:
@@ -413,7 +413,7 @@ void cpu_loop(CPUX86State *env)
info.si_errno = 0;
info.si_code = TARGET_SI_KERNEL;
info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP06_ILLOP:
@@ -421,7 +421,7 @@ void cpu_loop(CPUX86State *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPN;
info._sifields._sigfault._addr = env->eip;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
@@ -436,7 +436,7 @@ void cpu_loop(CPUX86State *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -576,7 +576,7 @@ segv:
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->exception.vaddress;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
/* Handle a jump to the kernel code page. */
@@ -755,7 +755,7 @@ void cpu_loop(CPUARMState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPN;
info._sifields._sigfault._addr = env->regs[15];
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
} else if (rc < 0) { /* FP exception */
int arm_fpe=0;
@@ -786,7 +786,7 @@ void cpu_loop(CPUARMState *env)
if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
info._sifields._sigfault._addr = env->regs[15];
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
} else {
env->regs[15] += 4;
}
@@ -907,7 +907,7 @@ void cpu_loop(CPUARMState *env)
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = addr;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_DEBUG:
@@ -921,7 +921,7 @@ void cpu_loop(CPUARMState *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -1099,7 +1099,7 @@ void cpu_loop(CPUARMState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPN;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_STREX:
if (!do_strex_a64(env)) {
@@ -1113,7 +1113,7 @@ void cpu_loop(CPUARMState *env)
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->exception.vaddress;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_DEBUG:
case EXCP_BKPT:
@@ -1122,7 +1122,7 @@ void cpu_loop(CPUARMState *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_SEMIHOST:
@@ -1202,7 +1202,7 @@ void cpu_loop(CPUUniCore32State *env)
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
@@ -1216,7 +1216,7 @@ void cpu_loop(CPUUniCore32State *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -1431,7 +1431,7 @@ void cpu_loop (CPUSPARCState *env)
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->mmuregs[4];
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
#else
@@ -1452,7 +1452,7 @@ void cpu_loop (CPUSPARCState *env)
info._sifields._sigfault._addr = env->dmmuregs[4];
else
info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
#ifndef TARGET_ABI32
@@ -1475,7 +1475,7 @@ void cpu_loop (CPUSPARCState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPC;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_DEBUG:
@@ -1488,7 +1488,7 @@ void cpu_loop (CPUSPARCState *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -1680,7 +1680,7 @@ void cpu_loop(CPUPPCState *env)
break;
}
info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case POWERPC_EXCP_ISI: /* Instruction storage exception */
EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" TARGET_FMT_lx
@@ -1708,7 +1708,7 @@ void cpu_loop(CPUPPCState *env)
break;
}
info._sifields._sigfault._addr = env->nip - 4;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case POWERPC_EXCP_EXTERNAL: /* External input */
cpu_abort(cs, "External interrupt while in user mode. "
@@ -1721,7 +1721,7 @@ void cpu_loop(CPUPPCState *env)
info.si_errno = 0;
info.si_code = TARGET_BUS_ADRALN;
info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case POWERPC_EXCP_PROGRAM: /* Program exception */
case POWERPC_EXCP_HV_EMU: /* HV emulation */
@@ -1815,7 +1815,7 @@ void cpu_loop(CPUPPCState *env)
break;
}
info._sifields._sigfault._addr = env->nip - 4;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
EXCP_DUMP(env, "No floating point allowed\n");
@@ -1823,7 +1823,7 @@ void cpu_loop(CPUPPCState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_COPROC;
info._sifields._sigfault._addr = env->nip - 4;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case POWERPC_EXCP_SYSCALL: /* System call exception */
cpu_abort(cs, "Syscall exception while in user mode. "
@@ -1835,7 +1835,7 @@ void cpu_loop(CPUPPCState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_COPROC;
info._sifields._sigfault._addr = env->nip - 4;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case POWERPC_EXCP_DECR: /* Decrementer exception */
cpu_abort(cs, "Decrementer interrupt while in user mode. "
@@ -1863,7 +1863,7 @@ void cpu_loop(CPUPPCState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_COPROC;
info._sifields._sigfault._addr = env->nip - 4;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");
@@ -1927,7 +1927,7 @@ void cpu_loop(CPUPPCState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_COPROC;
info._sifields._sigfault._addr = env->nip - 4;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
cpu_abort(cs, "Programmable interval timer interrupt "
@@ -2021,7 +2021,7 @@ void cpu_loop(CPUPPCState *env)
info.si_errno = 0;
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->nip;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_DEBUG:
@@ -2033,7 +2033,7 @@ void cpu_loop(CPUPPCState *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -2467,13 +2467,13 @@ static int do_break(CPUMIPSState *env, target_siginfo_t *info,
info->si_signo = TARGET_SIGFPE;
info->si_errno = 0;
info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;
- queue_signal(env, info->si_signo, &*info);
+ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
ret = 0;
break;
default:
info->si_signo = TARGET_SIGTRAP;
info->si_errno = 0;
- queue_signal(env, info->si_signo, &*info);
+ queue_signal(env, info->si_signo, QEMU_SI_FAULT, &*info);
ret = 0;
break;
}
@@ -2571,14 +2571,14 @@ done_syscall:
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->CP0_BadVAddr;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_CpU:
case EXCP_RI:
info.si_signo = TARGET_SIGILL;
info.si_errno = 0;
info.si_code = 0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
@@ -2593,7 +2593,7 @@ done_syscall:
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -2603,14 +2603,14 @@ done_syscall:
info.si_errno = 0;
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->active_tc.PC;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_DSPDIS:
info.si_signo = TARGET_SIGILL;
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPC;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
/* The code below was inspired by the MIPS Linux kernel trap
* handling code in arch/mips/kernel/traps.c.
@@ -2861,7 +2861,7 @@ void cpu_loop(CPUSH4State *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -2871,7 +2871,7 @@ void cpu_loop(CPUSH4State *env)
info.si_errno = 0;
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->tea;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
default:
@@ -2903,7 +2903,7 @@ void cpu_loop(CPUCRISState *env)
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->pregs[PR_EDA];
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_INTERRUPT:
@@ -2935,7 +2935,7 @@ void cpu_loop(CPUCRISState *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -2968,7 +2968,7 @@ void cpu_loop(CPUMBState *env)
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_INTERRUPT:
@@ -3017,7 +3017,7 @@ void cpu_loop(CPUMBState *env)
info.si_errno = 0;
info.si_code = TARGET_FPE_FLTDIV;
info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case ESR_EC_FPU:
info.si_signo = TARGET_SIGFPE;
@@ -3029,7 +3029,7 @@ void cpu_loop(CPUMBState *env)
info.si_code = TARGET_FPE_FLTDIV;
}
info._sifields._sigfault._addr = 0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
default:
printf ("Unhandled hw-exception: 0x%x\n",
@@ -3049,7 +3049,7 @@ void cpu_loop(CPUMBState *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -3103,7 +3103,7 @@ void cpu_loop(CPUM68KState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPN;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_TRAP0:
{
@@ -3137,7 +3137,7 @@ void cpu_loop(CPUM68KState *env)
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->mmu.ar;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_DEBUG:
@@ -3150,7 +3150,7 @@ void cpu_loop(CPUM68KState *env)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
}
break;
@@ -3206,7 +3206,7 @@ static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
info.si_errno = 0;
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = addr;
- queue_signal(env, TARGET_SIGSEGV, &info);
+ queue_signal(env, TARGET_SIGSEGV, QEMU_SI_FAULT, &info);
}
void cpu_loop(CPUAlphaState *env)
@@ -3248,7 +3248,7 @@ void cpu_loop(CPUAlphaState *env)
info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
info._sifields._sigfault._addr = env->trap_arg0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_UNALIGN:
env->lock_addr = -1;
@@ -3256,7 +3256,7 @@ void cpu_loop(CPUAlphaState *env)
info.si_errno = 0;
info.si_code = TARGET_BUS_ADRALN;
info._sifields._sigfault._addr = env->trap_arg0;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_OPCDEC:
do_sigill:
@@ -3265,7 +3265,7 @@ void cpu_loop(CPUAlphaState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPC;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_ARITH:
env->lock_addr = -1;
@@ -3273,7 +3273,7 @@ void cpu_loop(CPUAlphaState *env)
info.si_errno = 0;
info.si_code = TARGET_FPE_FLTINV;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case EXCP_FEN:
/* No-op. Linux simply re-enables the FPU. */
@@ -3287,7 +3287,7 @@ void cpu_loop(CPUAlphaState *env)
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case 0x81:
/* BUGCHK */
@@ -3295,7 +3295,7 @@ void cpu_loop(CPUAlphaState *env)
info.si_errno = 0;
info.si_code = 0;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
case 0x83:
/* CALLSYS */
@@ -3367,7 +3367,7 @@ void cpu_loop(CPUAlphaState *env)
}
info.si_errno = 0;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
default:
goto do_sigill;
@@ -3379,7 +3379,7 @@ void cpu_loop(CPUAlphaState *env)
env->lock_addr = -1;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
break;
case EXCP_STL_C:
@@ -3513,7 +3513,7 @@ void cpu_loop(CPUS390XState *env)
info.si_errno = 0;
info.si_code = n;
info._sifields._sigfault._addr = addr;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
default:
@@ -3537,7 +3537,7 @@ static void gen_sigill_reg(CPUTLGState *env)
info.si_errno = 0;
info.si_code = TARGET_ILL_PRVREG;
info._sifields._sigfault._addr = env->pc;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
static void do_signal(CPUTLGState *env, int signo, int sigcode)
@@ -3561,7 +3561,7 @@ static void do_signal(CPUTLGState *env, int signo, int sigcode)
}
info.si_code = sigcode;
- queue_signal(env, info.si_signo, &info);
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
}
static void gen_sigsegv_maperr(CPUTLGState *env, target_ulong addr)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 18cb200..112e7d7 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -377,7 +377,8 @@ extern int do_strace;
/* signal.c */
void process_pending_signals(CPUArchState *cpu_env);
void signal_init(void);
-int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info);
+int queue_signal(CPUArchState *env, int sig, int si_type,
+ target_siginfo_t *info);
void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info);
void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo);
int target_to_host_signal(int sig);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 87871ce..aa052e2 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -569,19 +569,15 @@ static void QEMU_NORETURN force_sig(int target_sig)
/* queue a signal so that it will be send to the virtual CPU as soon
as possible */
-int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
+int queue_signal(CPUArchState *env, int sig, int si_type,
+ target_siginfo_t *info)
{
CPUState *cpu = ENV_GET_CPU(env);
TaskState *ts = cpu->opaque;
trace_user_queue_signal(env, sig);
- /* Currently all callers define siginfo structures which
- * use the _sifields._sigfault union member, so we can
- * set the type here. If that changes we should push this
- * out so the si_type is passed in by callers.
- */
- info->si_code = deposit32(info->si_code, 16, 16, QEMU_SI_FAULT);
+ info->si_code = deposit32(info->si_code, 16, 16, si_type);
ts->sync_signal.info = *info;
ts->sync_signal.pending = sig;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0e98593..17ecd10 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -10422,7 +10422,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
info.si_code = si_code;
info._sifields._sigfault._addr
= ((CPUArchState *)cpu_env)->pc;
- queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
+ queue_signal((CPUArchState *)cpu_env, info.si_signo,
+ QEMU_SI_FAULT, &info);
}
}
break;
@@ -11519,7 +11520,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
info.si_errno = 0;
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = arg6;
- queue_signal((CPUArchState *)cpu_env, info.si_signo, &info);
+ queue_signal((CPUArchState *)cpu_env, info.si_signo,
+ QEMU_SI_FAULT, &info);
ret = 0xdeadbeef;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 3/6] linux-user: SIGSEGV on signal entry need not be fatal
2016-07-28 15:44 [Qemu-devel] [PATCH 0/6] linux-user: Handle SEGV on signal entry/exit correctly Peter Maydell
2016-07-28 15:44 ` [Qemu-devel] [PATCH 1/6] linux-user: Recheck for pending synchronous signals too Peter Maydell
2016-07-28 15:44 ` [Qemu-devel] [PATCH 2/6] linux-user: Pass si_type information to queue_signal() explicitly Peter Maydell
@ 2016-07-28 15:44 ` Peter Maydell
2016-07-28 15:44 ` [Qemu-devel] [PATCH 4/6] linux-user: ARM: Give SIGSEGV if signal frame setup fails Peter Maydell
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2016-07-28 15:44 UTC (permalink / raw)
To: qemu-devel; +Cc: patches, Riku Voipio
A failed write to memory trying to set up the signal frame
should trigger a SIGSEGV, but this need not be fatal: the
guest has a chance to catch it. Implement this via a force_sigsegv()
function with the same behaviour as the kernel function of that
name: make sure that we don't try to re-take a failed SIGSEGV,
and force a synchronous signal.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
linux-user/signal.c | 87 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 49 insertions(+), 38 deletions(-)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index aa052e2..d87c551 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -512,6 +512,33 @@ void signal_init(void)
}
}
+#if !((defined(TARGET_ARM) && !defined(TARGET_AARCH64)) || \
+ defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
+
+/* Force a SIGSEGV if we couldn't write to memory trying to set
+ * up the signal frame. oldsig is the signal we were trying to handle
+ * at the point of failure.
+ */
+static void force_sigsegv(int oldsig)
+{
+ CPUState *cpu = thread_cpu;
+ CPUArchState *env = cpu->env_ptr;
+ target_siginfo_t info;
+
+ if (oldsig == SIGSEGV) {
+ /* Make sure we don't try to deliver the signal again; this will
+ * end up with handle_pending_signal() calling force_sig().
+ */
+ sigact_table[oldsig - 1]._sa_handler = TARGET_SIG_DFL;
+ }
+ info.si_signo = TARGET_SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = TARGET_SI_KERNEL;
+ info._sifields._kill._pid = 0;
+ info._sifields._kill._uid = 0;
+ queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
+}
+#endif
/* abort execution with signal */
static void QEMU_NORETURN force_sig(int target_sig)
@@ -1011,10 +1038,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- if (sig == TARGET_SIGSEGV) {
- ka->_sa_handler = TARGET_SIG_DFL;
- }
- force_sig(TARGET_SIGSEGV /* , current */);
+ force_sigsegv(sig);
}
/* compare linux/arch/i386/kernel/signal.c:setup_rt_frame() */
@@ -1084,10 +1108,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- if (sig == TARGET_SIGSEGV) {
- ka->_sa_handler = TARGET_SIG_DFL;
- }
- force_sig(TARGET_SIGSEGV /* , current */);
+ force_sigsegv(sig);
}
static int
@@ -1416,7 +1437,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
give_sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(usig);
}
static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -2441,7 +2462,7 @@ sigill_and_return:
#endif
sigsegv:
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -3033,7 +3054,7 @@ static void setup_frame(int sig, struct target_sigaction * ka,
return;
give_sigsegv:
- force_sig(TARGET_SIGSEGV/*, current*/);
+ force_sigsegv(sig);
}
long do_sigreturn(CPUMIPSState *regs)
@@ -3142,7 +3163,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
give_sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- force_sig(TARGET_SIGSEGV/*, current*/);
+ force_sigsegv(sig);
}
long do_rt_sigreturn(CPUMIPSState *env)
@@ -3345,7 +3366,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
give_sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -3405,7 +3426,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
give_sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
long do_sigreturn(CPUSH4State *regs)
@@ -3652,7 +3673,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
unlock_user_struct(frame, frame_addr, 1);
return;
badframe:
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -3822,7 +3843,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
unlock_user_struct(frame, frame_addr, 1);
return;
badframe:
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -4061,10 +4082,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
give_sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- if (sig == TARGET_SIGSEGV) {
- ka->_sa_handler = TARGET_SIG_DFL;
- }
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
long do_sigreturn(CPUOpenRISCState *env)
@@ -4245,7 +4263,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -4300,7 +4318,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
static int
@@ -4811,7 +4829,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
static void setup_rt_frame(int sig, struct target_sigaction *ka,
@@ -4906,7 +4924,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
@@ -5155,7 +5173,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
static inline int target_rt_setup_ucontext(struct target_ucontext *uc,
@@ -5294,7 +5312,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
give_sigsegv:
unlock_user_struct(frame, frame_addr, 1);
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
}
long do_sigreturn(CPUM68KState *env)
@@ -5501,10 +5519,8 @@ static void setup_frame(int sig, struct target_sigaction *ka,
if (err) {
give_sigsegv:
- if (sig == TARGET_SIGSEGV) {
- ka->_sa_handler = TARGET_SIG_DFL;
- }
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
+ return;
}
env->ir[IR_RA] = r26;
@@ -5558,10 +5574,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
if (err) {
give_sigsegv:
- if (sig == TARGET_SIGSEGV) {
- ka->_sa_handler = TARGET_SIG_DFL;
- }
- force_sig(TARGET_SIGSEGV);
+ force_sigsegv(sig);
+ return;
}
env->ir[IR_RA] = r26;
@@ -5758,10 +5772,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
return;
give_sigsegv:
- if (sig == TARGET_SIGSEGV) {
- ka->_sa_handler = TARGET_SIG_DFL;
- }
- force_sig(TARGET_SIGSEGV /* , current */);
+ force_sigsegv(sig);
}
long do_rt_sigreturn(CPUTLGState *env)
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH 5/6] linux-user: SIGSEGV from sigreturn need not be fatal
2016-07-28 15:44 [Qemu-devel] [PATCH 0/6] linux-user: Handle SEGV on signal entry/exit correctly Peter Maydell
` (3 preceding siblings ...)
2016-07-28 15:44 ` [Qemu-devel] [PATCH 4/6] linux-user: ARM: Give SIGSEGV if signal frame setup fails Peter Maydell
@ 2016-07-28 15:44 ` Peter Maydell
2016-07-28 15:44 ` [Qemu-devel] [PATCH 6/6] linux-user: Implement force_sigsegv() via force_sig() Peter Maydell
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2016-07-28 15:44 UTC (permalink / raw)
To: qemu-devel; +Cc: patches, Riku Voipio
If the sigreturn syscall fails to read memory then this causes a
SIGSEGV, but this is not necessarily a fatal signal -- the guest
process can catch it.
We don't implement this correctly because the behaviour of QEMU's
force_sig() function has drifted away from the kernel function of the
same name -- ours now does "always do a guest core dump and abort
execution", whereas the kernel version simply forces the guest to
take a signal, which may or may not eventually cause a core dump.
Rename our force_sig() to dump_core_and_abort(), and provide a
force_sig() which acts more like the kernel version as the sigreturn
implementations expect it to. Since force_sig() now returns, we must
update all the callsites to return -TARGET_QEMU_ESIGRETURN so that
the main loop doesn't change the guest registers before the signal
handler is invoked.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
linux-user/signal.c | 81 +++++++++++++++++++++++++++++++++++------------------
1 file changed, 54 insertions(+), 27 deletions(-)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index cec6410..cadb989 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -512,6 +512,27 @@ void signal_init(void)
}
}
+#if !defined(TARGET_OPENRISC) && !defined(TARGET_UNICORE32) && \
+ !defined(TARGET_X86_64)
+/* Force a synchronously taken signal. The kernel force_sig() function
+ * also forces the signal to "not blocked, not ignored", but for QEMU
+ * that work is done in process_pending_signals().
+ */
+static void force_sig(int sig)
+{
+ CPUState *cpu = thread_cpu;
+ CPUArchState *env = cpu->env_ptr;
+ target_siginfo_t info;
+
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = TARGET_SI_KERNEL;
+ info._sifields._kill._pid = 0;
+ info._sifields._kill._uid = 0;
+ queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
+}
+#endif
+
#if !(defined(TARGET_X86_64) || defined(TARGET_UNICORE32))
/* Force a SIGSEGV if we couldn't write to memory trying to set
@@ -526,7 +547,7 @@ static void force_sigsegv(int oldsig)
if (oldsig == SIGSEGV) {
/* Make sure we don't try to deliver the signal again; this will
- * end up with handle_pending_signal() calling force_sig().
+ * end up with handle_pending_signal() calling dump_core_and_abort().
*/
sigact_table[oldsig - 1]._sa_handler = TARGET_SIG_DFL;
}
@@ -540,7 +561,7 @@ static void force_sigsegv(int oldsig)
#endif
/* abort execution with signal */
-static void QEMU_NORETURN force_sig(int target_sig)
+static void QEMU_NORETURN dump_core_and_abort(int target_sig)
{
CPUState *cpu = thread_cpu;
CPUArchState *env = cpu->env_ptr;
@@ -1181,7 +1202,7 @@ long do_sigreturn(CPUX86State *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUX86State *env)
@@ -1212,7 +1233,7 @@ long do_rt_sigreturn(CPUX86State *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
#elif defined(TARGET_AARCH64)
@@ -1482,7 +1503,7 @@ long do_rt_sigreturn(CPUARMState *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_sigreturn(CPUARMState *env)
@@ -2004,8 +2025,8 @@ static long do_sigreturn_v1(CPUARMState *env)
return -TARGET_QEMU_ESIGRETURN;
badframe:
- force_sig(TARGET_SIGSEGV /* , current */);
- return 0;
+ force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
@@ -2131,8 +2152,8 @@ static long do_sigreturn_v2(CPUARMState *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
- force_sig(TARGET_SIGSEGV /* , current */);
- return 0;
+ force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_sigreturn(CPUARMState *env)
@@ -2185,8 +2206,8 @@ static long do_rt_sigreturn_v1(CPUARMState *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
- force_sig(TARGET_SIGSEGV /* , current */);
- return 0;
+ force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
static long do_rt_sigreturn_v2(CPUARMState *env)
@@ -2218,8 +2239,8 @@ static long do_rt_sigreturn_v2(CPUARMState *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
- force_sig(TARGET_SIGSEGV /* , current */);
- return 0;
+ force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUARMState *env)
@@ -2553,6 +2574,7 @@ long do_sigreturn(CPUSPARCState *env)
segv_and_exit:
unlock_user_struct(sf, sf_addr, 0);
force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUSPARCState *env)
@@ -3110,8 +3132,8 @@ long do_sigreturn(CPUMIPSState *regs)
return -TARGET_QEMU_ESIGRETURN;
badframe:
- force_sig(TARGET_SIGSEGV/*, current*/);
- return 0;
+ force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
# endif /* O32 */
@@ -3207,8 +3229,8 @@ long do_rt_sigreturn(CPUMIPSState *env)
return -TARGET_QEMU_ESIGRETURN;
badframe:
- force_sig(TARGET_SIGSEGV/*, current*/);
- return 0;
+ force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
#elif defined(TARGET_SH4)
@@ -3474,7 +3496,7 @@ long do_sigreturn(CPUSH4State *regs)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUSH4State *regs)
@@ -3506,7 +3528,7 @@ long do_rt_sigreturn(CPUSH4State *regs)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
#elif defined(TARGET_MICROBLAZE)
@@ -3725,6 +3747,7 @@ long do_sigreturn(CPUMBState *env)
return -TARGET_QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUMBState *env)
@@ -3892,6 +3915,7 @@ long do_sigreturn(CPUCRISState *env)
return -TARGET_QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUCRISState *env)
@@ -4383,7 +4407,7 @@ long do_sigreturn(CPUS390XState *env)
badframe:
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUS390XState *env)
@@ -4414,7 +4438,7 @@ long do_rt_sigreturn(CPUS390XState *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
#elif defined(TARGET_PPC)
@@ -4973,7 +4997,7 @@ sigsegv:
unlock_user_struct(sr, sr_addr, 1);
unlock_user_struct(sc, sc_addr, 1);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
/* See arch/powerpc/kernel/signal_32.c. */
@@ -5028,7 +5052,7 @@ long do_rt_sigreturn(CPUPPCState *env)
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
#elif defined(TARGET_M68K)
@@ -5358,7 +5382,7 @@ long do_sigreturn(CPUM68KState *env)
badframe:
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUM68KState *env)
@@ -5391,7 +5415,7 @@ long do_rt_sigreturn(CPUM68KState *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return 0;
+ return -TARGET_QEMU_ESIGRETURN;
}
#elif defined(TARGET_ALPHA)
@@ -5620,6 +5644,7 @@ long do_sigreturn(CPUAlphaState *env)
badframe:
force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUAlphaState *env)
@@ -5649,6 +5674,7 @@ long do_rt_sigreturn(CPUAlphaState *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
#elif defined(TARGET_TILEGX)
@@ -5813,6 +5839,7 @@ long do_rt_sigreturn(CPUTLGState *env)
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
}
#else
@@ -5879,12 +5906,12 @@ static void handle_pending_signal(CPUArchState *cpu_env, int sig,
sig != TARGET_SIGURG &&
sig != TARGET_SIGWINCH &&
sig != TARGET_SIGCONT) {
- force_sig(sig);
+ dump_core_and_abort(sig);
}
} else if (handler == TARGET_SIG_IGN) {
/* ignore sig */
} else if (handler == TARGET_SIG_ERR) {
- force_sig(sig);
+ dump_core_and_abort(sig);
} else {
/* compute the blocked signals during the handler execution */
sigset_t *blocked_set;
--
1.9.1
^ permalink raw reply related [flat|nested] 9+ messages in thread