Release 960114
[wine/gsoc-2012-control.git] / loader / signal.c
blob1968046833d29b42d623b0e8a3efba3b65c38c17
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
25 struct sigaction segv_act;
26 struct sigaction usr2_act;
28 #ifdef linux
29 extern void ___sig_restore();
30 extern void ___masksig_restore();
32 /* Similar to the sigaction function in libc, except it leaves alone the
33 restorer field */
35 static int
36 wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
38 __asm__("int $0x80":"=a" (sig)
39 :"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
40 if (sig>=0)
41 return 0;
42 errno = -sig;
43 return -1;
45 #endif
48 #if defined(linux)
49 static void win_fault(int signal, struct sigcontext_struct context_struct)
51 struct sigcontext_struct *context = &context_struct;
52 #elif defined(__svr4__)
53 static void win_fault(int signal, void *siginfo, ucontext_t *context)
55 #else
56 static void win_fault(int signal, int code, struct sigcontext *context)
58 #endif
59 if (signal != SIGTRAP)
61 if (CS_reg(context) == WINE_CODE_SELECTOR)
63 fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
64 " Please debug\n",
65 CS_reg(context), EIP_reg(context) );
67 else if (INSTR_EmulateInstruction( context )) return;
68 fprintf( stderr,"In win_fault %x:%lx\n",
69 CS_reg(context), EIP_reg(context) );
71 XUngrabPointer(display, CurrentTime);
72 XUngrabServer(display);
73 XFlush(display);
74 wine_debug( signal, context ); /* Enter our debugger */
77 void init_wine_signals(void)
79 extern void stop_wait(int a);
80 #ifdef linux
81 segv_act.sa_handler = (__sighandler_t) win_fault;
82 /* Point to the top of the stack, minus 4 just in case, and make
83 it aligned */
84 segv_act.sa_restorer =
85 (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
86 /* Point to the top of the stack, minus 4 just in case, and make
87 it aligned */
88 wine_sigaction(SIGSEGV, &segv_act, NULL);
89 wine_sigaction(SIGILL, &segv_act, NULL);
90 wine_sigaction(SIGFPE, &segv_act, NULL);
91 #ifdef SIGBUS
92 wine_sigaction(SIGBUS, &segv_act, NULL);
93 #endif
94 wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
95 #ifdef CONFIG_IPC
96 usr2_act.sa_restorer= segv_act.sa_restorer;
97 usr2_act.sa_handler = (__sighandler_t) stop_wait;
98 wine_sigaction(SIGUSR2, &usr2_act, NULL);
99 #endif /* CONFIG_IPC */
100 #endif /* linux */
101 #if defined(__NetBSD__) || defined(__FreeBSD__)
102 sigset_t sig_mask;
103 struct sigaltstack ss;
105 #if !defined (__FreeBSD__)
106 if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
107 #else
108 if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
109 #endif
110 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
111 MINSIGSTKSZ);
112 exit(1);
114 ss.ss_size = MINSIGSTKSZ;
115 ss.ss_flags = 0;
116 if (sigaltstack(&ss, NULL) < 0) {
117 perror("sigstack");
118 exit(1);
120 sigemptyset(&sig_mask);
121 segv_act.sa_handler = (void (*)) win_fault;
122 segv_act.sa_flags = SA_ONSTACK;
123 segv_act.sa_mask = sig_mask;
124 if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
125 perror("sigaction: SIGBUS");
126 exit(1);
128 segv_act.sa_handler = (void (*)) win_fault;
129 segv_act.sa_flags = SA_ONSTACK;
130 segv_act.sa_mask = sig_mask;
131 if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
132 perror("sigaction: SIGSEGV");
133 exit(1);
135 segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
136 segv_act.sa_flags = SA_ONSTACK;
137 segv_act.sa_mask = sig_mask;
138 if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
139 perror("sigaction: SIGTRAP");
140 exit(1);
142 #ifdef CONFIG_IPC
143 usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
144 usr2_act.sa_flags = SA_ONSTACK;
145 usr2_act.sa_mask = sig_mask;
146 if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
147 perror("sigaction: SIGUSR2");
148 exit(1);
150 #endif /* CONFIG_IPC */
151 #endif /* __FreeBSD__ || __NetBSD__ */
152 #if defined (__svr4__)
153 sigset_t sig_mask;
154 struct sigaltstack ss;
156 if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
157 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
158 SIGSTKSZ);
159 exit(1);
161 ss.ss_size = SIGSTKSZ;
162 ss.ss_flags = 0;
163 if (sigaltstack(&ss, NULL) < 0) {
164 perror("sigstack");
165 exit(1);
167 sigemptyset(&sig_mask);
168 segv_act.sa_handler = (void (*)) win_fault;
169 segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
170 segv_act.sa_mask = sig_mask;
171 if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
172 perror("sigaction: SIGBUS");
173 exit(1);
175 segv_act.sa_handler = (void (*)) win_fault;
176 segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
177 segv_act.sa_mask = sig_mask;
178 if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
179 perror("sigaction: SIGSEGV");
180 exit(1);
184 segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
185 segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
186 segv_act.sa_mask = sig_mask;
187 if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
188 perror("sigaction: SIGTRAP");
189 exit(1);
191 #ifdef CONFIG_IPC
192 usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
193 usr2_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
194 usr2_act.sa_mask = sig_mask;
195 if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
196 perror("sigaction: SIGUSR2");
197 exit(1);
199 #endif /* CONFIG_IPC */
201 #endif /* __svr4__ */
204 #endif /* ifndef WINELIB */