Release 960314
[wine.git] / loader / signal.c
blob3bd175f7247694a3d9498eb5ce6eec6e6fb56101
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"
22 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
23 char * cstack[4096];
24 #endif
26 #ifdef linux
27 extern void ___sig_restore();
28 extern void ___masksig_restore();
30 /* Similar to the sigaction function in libc, except it leaves alone the
31 restorer field */
33 static int
34 wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
36 __asm__("int $0x80":"=a" (sig)
37 :"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
38 if (sig>=0)
39 return 0;
40 errno = -sig;
41 return -1;
43 #endif
46 #if defined(linux)
47 static void win_fault(int signal, struct sigcontext_struct context_struct)
49 struct sigcontext_struct *context = &context_struct;
50 #elif defined(__svr4__)
51 static void win_fault(int signal, void *siginfo, ucontext_t *context)
53 #else
54 static void win_fault(int signal, int code, struct sigcontext *context)
56 #endif
57 if (signal == SIGTRAP)
59 /* If SIGTRAP not caused by breakpoint or single step
60 don't jump into the debugger */
61 if (!(EFL_reg(context) & STEP_FLAG))
63 DBG_ADDR addr;
64 addr.seg = CS_reg(context);
65 addr.off = EIP_reg(context) - 1;
66 if (DEBUG_FindBreakpoint(&addr) == -1) return;
69 else if (signal != SIGHUP)
71 if (CS_reg(context) == WINE_CODE_SELECTOR)
73 fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
74 " Please debug.\n",
75 CS_reg(context), EIP_reg(context) );
77 else
79 if (INSTR_EmulateInstruction( context )) return;
80 fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n",
81 CS_reg(context), EIP_reg(context) );
85 XUngrabPointer(display, CurrentTime);
86 XUngrabServer(display);
87 XFlush(display);
88 wine_debug( signal, context ); /* Enter our debugger */
92 /**********************************************************************
93 * SIGNAL_SetHandler
95 static void SIGNAL_SetHandler( int sig, void (*func)() )
97 int ret;
98 struct sigaction sig_act;
100 #ifdef linux
101 sig_act.sa_handler = func;
102 /* Point to the top of the stack, minus 4 just in case, and make
103 it aligned */
104 sig_act.sa_restorer =
105 (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
106 ret = wine_sigaction( sig, &sig_act, NULL );
107 #endif /* linux */
109 #if defined(__NetBSD__) || defined(__FreeBSD__)
110 sig_act.sa_handler = func;
111 sig_act.sa_flags = SA_ONSTACK;
112 sig_act.sa_mask = sig_mask;
113 ret = sigaction( sig, &sig_act, NULL );
114 #endif /* __FreeBSD__ || __NetBSD__ */
116 #if defined (__svr4__)
117 sig_act.sa_handler = func;
118 sig_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
119 sig_act.sa_mask = sig_mask;
120 ret = sigaction( sig, &sig_act, NULL );
121 #endif /* __svr4__ */
123 if (ret < 0)
125 perror( "sigaction" );
126 exit(1);
131 /**********************************************************************
132 * init_wine_signals
134 void init_wine_signals(void)
136 extern void stop_wait(int a);
138 #if defined(__NetBSD__) || defined(__FreeBSD__)
139 sigset_t sig_mask;
140 struct sigaltstack ss;
142 #if !defined (__FreeBSD__)
143 if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
144 #else
145 if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
146 #endif
147 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
148 MINSIGSTKSZ);
149 exit(1);
151 ss.ss_size = MINSIGSTKSZ;
152 ss.ss_flags = 0;
153 if (sigaltstack(&ss, NULL) < 0) {
154 perror("sigstack");
155 exit(1);
157 sigemptyset(&sig_mask);
158 #endif /* __FreeBSD__ || __NetBSD__ */
160 #if defined (__svr4__)
161 sigset_t sig_mask;
162 struct sigaltstack ss;
164 if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
165 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
166 SIGSTKSZ);
167 exit(1);
169 ss.ss_size = SIGSTKSZ;
170 ss.ss_flags = 0;
171 if (sigaltstack(&ss, NULL) < 0) {
172 perror("sigstack");
173 exit(1);
175 sigemptyset(&sig_mask);
176 #endif /* __svr4__ */
178 SIGNAL_SetHandler( SIGSEGV, (void (*)())win_fault );
179 SIGNAL_SetHandler( SIGILL, (void (*)())win_fault );
180 SIGNAL_SetHandler( SIGFPE, (void (*)())win_fault );
181 SIGNAL_SetHandler( SIGTRAP, (void (*)())win_fault ); /* For debugger */
182 SIGNAL_SetHandler( SIGHUP, (void (*)())win_fault ); /* For forced break */
183 #ifdef SIGBUS
184 SIGNAL_SetHandler( SIGBUS, (void (*)())win_fault );
185 #endif
186 #ifdef CONFIG_IPC
187 SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait ); /* For IPC */
188 #endif
191 #endif /* ifndef WINELIB */