1 static char rcsid[]="$Id: sunexception.c,v 1.4 1996/07/09 19:41:47 paul Exp $";
2
3 /*
4 * This file contains two functions, both of which are entry points:
5 * - exception - handles all SunOS signals that don't have
6 * special-purpose handlers.
7 * - do_dump - called from panic to dump relevant informatiomn
8 *
9 * A SunOS signal is either passed on to the currently executing smx
10 * process (SIGSEGV, etc), completely ignored (eg. SIGINT) or can cause
11 * smx Minix to shutdown (SIGTERM). If a signal in the first category
12 * occurs within the kernel or one of the servers, then this is regarded
13 * as a fatal error, and smx is shutdown after displaying some debugging
14 * information.
15 */
16
17 #include "kernel.h"
18 #include "proc.h"
19 #include <sun/syscall.h>
20 #include <sun/signal.h>
21
22 #include <signal.h>
23
24 /*
25 * Given a SunOS signal number, this table is used to determine what to do
26 * that signal. If the entry is a '', or if there is no entry, then the
27 * signal is ignored. Otherwise, the entry contains a MINIX signal number
28 * that the SunOS signal number should be translated to. The SunOS IO,
29 * ALRM and USR1 signals have special handlers because smx uses those
30 * signals for its own purposes), so exception() is not called to handle
31 * those signals.
32 */
33 int signum[] = {
34 0, /* Signal 0---no such SunOS signal */
35 0, /* SO_SIGHUP */
36 0, /* SO_SIGINT */
37 0, /* SO_SIGQUIT */
38 SIGILL, /* SO_SIGILL */
39 SIGTRAP, /* SO_SIGTRAP */
40 SIGABRT, /* SO_SIGABRT */
41 0, /* SO_SIGEMT */
42 SIGFPE, /* SO_SIGFPE */
43 SIGKILL, /* SO_SIGKILL */
44 SIGSEGV, /* SO_SIGBUS */
45 SIGSEGV, /* SO_SIGSEGV */
46 SIGSEGV, /* SO_SIGSYS */
47 };
48
49 #define SIGNUMSIZE (sizeof(signum) / sizeof(signum[0]))
50
51 /*
52 * Function: exception
53 * Parameters: sig - SunOS signal that has occurred
54 * siginf - extra information on that signal
55 * scp - saved context of the interrupted smx process.
56 *
57 * This function is called by the lower level SunOS signal handler.
58 * The SunOS signal is either passed on, ignored or causes a shutdown.
59 */
60 void exception(int sig, void *siginf, struct stackframe_s *scp)
61 {
62 int mx_sig;
63 unsigned *sinf = siginf;
64
65 if (sig == SO_SIGTERM) {
66 printf("\nMinix terminated\n");
67 SunOS(SYS_exit, 0);
68 }
69
70 /* ignore some signals */
71 if (sig >= SIGNUMSIZE || (mx_sig = signum[sig]) == 0) {
72 printf("Ignoring sig %d\n", sig);
73 return;
74 }
75
76
77 /*
78 * if an smx user process was executing, send it the appropriate
79 * smx signal. We check that the pc at which the signal arose
80 * was within the text segment of the current process, and that
81 * the current process was a user proces. If the "signalling" pc
82 * was outside the text segment of the running process then either
83 * the pc was in layer 1 kernel code, or something has gone badly wrong,
84 * so we abort smx in this situation.
85 */
86 if (scp->pc >= proc_ptr->p_map[T].mem_vir << CLICK_SHIFT &&
87 scp->pc <= (proc_ptr->p_map[T].mem_vir + proc_ptr->p_map[T].mem_len)
88 << CLICK_SHIFT && isuserp(proc_ptr)) {
89
90 /*
91 * First we need to check whether we have got a segmentation violation
92 * which really indicates that stack growth is needed. This is assumed
93 * if the address referenced lies between the data segment and the
94 * stack segment.
95 */
96 if (sig == SO_SIGSEGV &&
97 sinf[3] < proc_ptr->p_map[S].mem_vir << CLICK_SHIFT &&
98 sinf[3] > (proc_ptr->p_map[D].mem_vir + proc_ptr->p_map[D].mem_len)
99 << CLICK_SHIFT) {
100 cause_sig(proc_number(proc_ptr), SIGSTKFLT);
101 return;
102 }
103
104 /*
105 * Send a signal to an smx process. The print statement provides
106 * useful debugging info---comment it out if don't want to see
107 * that info any more.
108 */
109 printf("SunOS sig %d in %d (%s, sp 0x%x) accessing 0x%x at 0x%x\n",
110 sig, proc_number(proc_ptr), proc_ptr->p_name, scp->sp, sinf[3], scp->pc);
111 cause_sig(proc_number(proc_ptr), mx_sig);
112 return;
113 }
114
115 /*
116 * An "error" signal within the kernel, MM or FS causes a shutdown
117 */
118 printf("\nSunOS signal number %d received within kernel\n", sig);
119 printf("PC = 0x%x, accessing 0x%x, task = %d\n",
120 proc_ptr->p_reg.pc, sinf[3], proc_number(proc_ptr));
121 panic("Signal within kernel", NO_NUM);
122 }
123
124
125 /*
126 * Function: do_dump
127 *
128 * Display debugging information. This is called from within panic.
129 */
130 PUBLIC void do_dump()
131 {
132 printf("\nSP = %x PSW = %x", proc_ptr->p_reg.sp, proc_ptr->p_reg.psw);
133 printf("\n\n");
134 p_dmp();
135 map_dmp();
136 }
137
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.