Release 951105
[wine/multimedia.git] / loader / signal.c
blob8a31b8d1716c41b8afcb3f9c8d2e9ffba4907edf
1 #ifndef WINELIB
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <signal.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <time.h>
8 #include <setjmp.h>
10 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__)
11 #include <sys/syscall.h>
12 #include <sys/param.h>
13 #else
14 #include <syscall.h>
15 #endif
17 #include "debugger.h"
18 #include "miscemu.h"
19 #include "registers.h"
20 #include "win.h"
21 #include "xmalloc.h"
23 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
24 char * cstack[4096];
25 #endif
26 struct sigaction segv_act;
27 struct sigaction usr2_act;
29 #ifdef linux
30 extern void ___sig_restore();
31 extern void ___masksig_restore();
33 /* Similar to the sigaction function in libc, except it leaves alone the
34 restorer field */
36 static int
37 wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
39 __asm__("int $0x80":"=a" (sig)
40 :"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
41 if (sig>=0)
42 return 0;
43 errno = -sig;
44 return -1;
46 #endif
49 #if defined(linux) || defined(__svr4__)
50 static void win_fault(int signal, struct sigcontext_struct context_struct)
52 struct sigcontext_struct *context = &context_struct;
53 #else
54 static void win_fault(int signal, int code, struct sigcontext *context)
56 #endif
57 if (signal != SIGTRAP)
59 if (CS_reg(context) == WINE_CODE_SELECTOR)
61 fprintf(stderr, "Segmentation fault in Wine program (%04x:%08lx)."
62 " Please debug.\n",
63 CS_reg(context), EIP_reg(context) );
65 else if (INSTR_EmulateInstruction( context )) return;
66 fprintf( stderr,"In win_fault %x:%lx\n",
67 CS_reg(context), EIP_reg(context) );
69 XUngrabPointer(display, CurrentTime);
70 XUngrabServer(display);
71 XFlush(display);
72 wine_debug( signal, context ); /* Enter our debugger */
75 void init_wine_signals(void)
77 extern void stop_wait(int a);
78 #ifdef linux
79 segv_act.sa_handler = (__sighandler_t) win_fault;
80 /* Point to the top of the stack, minus 4 just in case, and make
81 it aligned */
82 segv_act.sa_restorer =
83 (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
84 /* Point to the top of the stack, minus 4 just in case, and make
85 it aligned */
86 wine_sigaction(SIGSEGV, &segv_act, NULL);
87 wine_sigaction(SIGILL, &segv_act, NULL);
88 wine_sigaction(SIGFPE, &segv_act, NULL);
89 #ifdef SIGBUS
90 wine_sigaction(SIGBUS, &segv_act, NULL);
91 #endif
92 wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
93 #ifdef CONFIG_IPC
94 usr2_act.sa_restorer= segv_act.sa_restorer;
95 usr2_act.sa_handler = (__sighandler_t) stop_wait;
96 wine_sigaction(SIGUSR2, &usr2_act, NULL);
97 #endif /* CONFIG_IPC */
98 #endif /* linux */
99 #if defined(__NetBSD__) || defined(__FreeBSD__)
100 sigset_t sig_mask;
101 struct sigaltstack ss;
103 #if !defined (__FreeBSD__)
104 ss.ss_base = xmalloc (MINSIGSTKSZ);
105 #else
106 ss.ss_sp = xmalloc (MINSIGSTKSZ);
107 #endif
108 ss.ss_size = MINSIGSTKSZ;
109 ss.ss_flags = 0;
110 if (sigaltstack(&ss, NULL) < 0) {
111 perror("sigstack");
112 exit(1);
114 sigemptyset(&sig_mask);
115 segv_act.sa_handler = (void (*)) win_fault;
116 segv_act.sa_flags = SA_ONSTACK;
117 segv_act.sa_mask = sig_mask;
118 if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
119 perror("sigaction: SIGBUS");
120 exit(1);
122 segv_act.sa_handler = (void (*)) win_fault;
123 segv_act.sa_flags = SA_ONSTACK;
124 segv_act.sa_mask = sig_mask;
125 if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
126 perror("sigaction: SIGSEGV");
127 exit(1);
129 segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
130 segv_act.sa_flags = SA_ONSTACK;
131 segv_act.sa_mask = sig_mask;
132 if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
133 perror("sigaction: SIGTRAP");
134 exit(1);
136 #ifdef CONFIG_IPC
137 usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
138 usr2_act.sa_flags = SA_ONSTACK;
139 usr2_act.sa_mask = sig_mask;
140 if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
141 perror("sigaction: SIGUSR2");
142 exit(1);
144 #endif /* CONFIG_IPC */
145 #endif /* __FreeBSD__ || __NetBSD__ */
148 #endif /* ifndef WINELIB */