patch-2.3.41 linux/arch/sparc/kernel/signal.c
Next file: linux/arch/sparc/kernel/smp.c
Previous file: linux/arch/sparc/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 134
- Date:
Fri Jan 21 18:22:54 2000
- Orig file:
v2.3.40/linux/arch/sparc/kernel/signal.c
- Orig date:
Tue Jan 4 13:57:16 2000
diff -u --recursive --new-file v2.3.40/linux/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.99 1999/12/27 06:08:32 anton Exp $
+/* $Id: signal.c,v 1.101 2000/01/21 11:38:38 jj Exp $
* linux/arch/sparc/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -424,12 +424,15 @@
}
static inline void
-setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
- struct pt_regs *regs, int signr, sigset_t *oldset)
+setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
{
struct signal_sframe *sframep;
struct sigcontext *sc;
int window = 0, err;
+ unsigned long pc = regs->pc;
+ unsigned long npc = regs->npc;
+ void *sig_address;
+ int sig_code;
synchronize_user_stack();
sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
@@ -474,18 +477,63 @@
sizeof(struct reg_window));
current->thread.w_saved = 0; /* So process is allowed to execute. */
+
err |= __put_user(signr, &sframep->sig_num);
- if(signr == SIGSEGV ||
- signr == SIGILL ||
- signr == SIGFPE ||
- signr == SIGBUS ||
- signr == SIGEMT) {
- err |= __put_user(current->thread.sig_desc, &sframep->sig_code);
- err |= __put_user(current->thread.sig_address, &sframep->sig_address);
- } else {
- err |= __put_user(0, &sframep->sig_code);
- err |= __put_user(0, &sframep->sig_address);
+ sig_address = NULL;
+ sig_code = 0;
+ if (SI_FROMKERNEL (info) && (info->si_code & __SI_MASK) == __SI_FAULT) {
+ sig_address = info->si_addr;
+ switch (signr) {
+ case SIGSEGV:
+ switch (info->si_code) {
+ case SEGV_MAPERR: sig_code = SUBSIG_NOMAPPING; break;
+ default: sig_code = SUBSIG_PROTECTION; break;
+ }
+ break;
+ case SIGILL:
+ switch (info->si_code) {
+ case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
+ case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
+ case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break;
+ default: sig_code = SUBSIG_STACK; break;
+ }
+ break;
+ case SIGFPE:
+ switch (info->si_code) {
+ case FPE_INTDIV: sig_code = SUBSIG_IDIVZERO; break;
+ case FPE_INTOVF: sig_code = SUBSIG_FPINTOVFL; break;
+ case FPE_FLTDIV: sig_code = SUBSIG_FPDIVZERO; break;
+ case FPE_FLTOVF: sig_code = SUBSIG_FPOVFLOW; break;
+ case FPE_FLTUND: sig_code = SUBSIG_FPUNFLOW; break;
+ case FPE_FLTRES: sig_code = SUBSIG_FPINEXACT; break;
+ case FPE_FLTINV: sig_code = SUBSIG_FPOPERROR; break;
+ default: sig_code = SUBSIG_FPERROR; break;
+ }
+ break;
+ case SIGBUS:
+ switch (info->si_code) {
+ case BUS_ADRALN: sig_code = SUBSIG_ALIGNMENT; break;
+ case BUS_ADRERR: sig_code = SUBSIG_MISCERROR; break;
+ default: sig_code = SUBSIG_BUSTIMEOUT; break;
+ }
+ break;
+ case SIGEMT:
+ switch (info->si_code) {
+ case EMT_TAGOVF: sig_code = SUBSIG_TAG; break;
+ }
+ break;
+ case SIGSYS:
+ if (info->si_code == (__SI_FAULT|0x100)) {
+ /* See sys_sunos.c */
+ sig_code = info->si_trapno;
+ break;
+ }
+ default:
+ sig_address = NULL;
+ }
}
+ err |= __put_user((long)sig_address, &sframep->sig_address);
+ err |= __put_user(sig_code, &sframep->sig_code);
err |= __put_user(sc, &sframep->sig_scptr);
if (err)
goto sigsegv;
@@ -791,8 +839,7 @@
/* Setup the signal information. Solaris expects a bunch of
* information to be passed to the signal handler, we don't provide
- * that much currently, should use those that David already
- * is providing with thread.sig_desc
+ * that much currently, should use siginfo.
*/
err |= __put_user(signr, &si->siginfo.signo);
err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
@@ -977,7 +1024,7 @@
else if (current->thread.new_signal)
new_setup_frame (ka, regs, signr, oldset);
else
- setup_frame(&ka->sa, regs->pc, regs->npc, regs, signr, oldset);
+ setup_frame(&ka->sa, regs, signr, oldset, info);
}
if(ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
@@ -1074,7 +1121,16 @@
struct k_sigaction *ka;
siginfo_t info;
+ /*
+ * XXX Disable svr4 signal handling until solaris emulation works.
+ * It is buggy - Anton
+ */
+#define SVR4_SIGNAL_BROKEN 1
+#ifdef SVR4_SIGNAL_BROKEN
+ int svr4_signal = 0;
+#else
int svr4_signal = current->personality == PER_SVR4;
+#endif
if (!oldset)
oldset = ¤t->blocked;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)