linux-user: Detect and report host SIGILL, SIGFPE, SIGTRAP
These signals, when not spoofed via kill(), are always bugs. Use die_from_signal to report this sensibly. Acked-by: Helge Deller <deller@gmx.de> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
f4e1168198
commit
4a6ebc19a7
@ -796,6 +796,43 @@ void die_from_signal(siginfo_t *info)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SIGILL:
|
||||||
|
sig = "ILL";
|
||||||
|
switch (info->si_code) {
|
||||||
|
case ILL_ILLOPC:
|
||||||
|
code = "ILLOPC";
|
||||||
|
break;
|
||||||
|
case ILL_ILLOPN:
|
||||||
|
code = "ILLOPN";
|
||||||
|
break;
|
||||||
|
case ILL_ILLADR:
|
||||||
|
code = "ILLADR";
|
||||||
|
break;
|
||||||
|
case ILL_PRVOPC:
|
||||||
|
code = "PRVOPC";
|
||||||
|
break;
|
||||||
|
case ILL_PRVREG:
|
||||||
|
code = "PRVREG";
|
||||||
|
break;
|
||||||
|
case ILL_COPROC:
|
||||||
|
code = "COPROC";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SIGFPE:
|
||||||
|
sig = "FPE";
|
||||||
|
switch (info->si_code) {
|
||||||
|
case FPE_INTDIV:
|
||||||
|
code = "INTDIV";
|
||||||
|
break;
|
||||||
|
case FPE_INTOVF:
|
||||||
|
code = "INTOVF";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SIGTRAP:
|
||||||
|
sig = "TRAP";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(sigbuf, sizeof(sigbuf), "%d", info->si_signo);
|
snprintf(sigbuf, sizeof(sigbuf), "%d", info->si_signo);
|
||||||
sig = sigbuf;
|
sig = sigbuf;
|
||||||
@ -900,7 +937,8 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Non-spoofed SIGSEGV and SIGBUS are synchronous, and need special
|
* Non-spoofed SIGSEGV and SIGBUS are synchronous, and need special
|
||||||
* handling wrt signal blocking and unwinding.
|
* handling wrt signal blocking and unwinding. Non-spoofed SIGILL,
|
||||||
|
* SIGFPE, SIGTRAP are always host bugs.
|
||||||
*/
|
*/
|
||||||
if (info->si_code > 0) {
|
if (info->si_code > 0) {
|
||||||
switch (host_sig) {
|
switch (host_sig) {
|
||||||
@ -912,6 +950,10 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
|||||||
host_sigbus_handler(cpu, info, uc);
|
host_sigbus_handler(cpu, info, uc);
|
||||||
sync_sig = true;
|
sync_sig = true;
|
||||||
break;
|
break;
|
||||||
|
case SIGILL:
|
||||||
|
case SIGFPE:
|
||||||
|
case SIGTRAP:
|
||||||
|
die_from_signal(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user