11 #include <sys/timeb.h>
13 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__)
14 #include <sys/syscall.h>
15 #include <sys/param.h>
22 #include "registers.h"
25 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
30 extern void ___sig_restore();
31 extern void ___masksig_restore();
33 /* Similar to the sigaction function in libc, except it leaves alone the
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
));
49 /**********************************************************************
55 static void wine_timer(int signal
, struct sigcontext_struct context_struct
)
57 #elif defined(__svr4__)
58 static void wine_timer(int signal
, void *siginfo
, ucontext_t
*context
)
61 static void wine_timer(int signal
, int code
, struct sigcontext
*context
)
64 /* Should do real-time timers here */
70 /**********************************************************************
76 static void win_fault(int signal
, struct sigcontext_struct context_struct
)
78 struct sigcontext_struct
*context
= &context_struct
;
79 #elif defined(__svr4__)
80 static void win_fault(int signal
, void *siginfo
, ucontext_t
*context
)
83 static void win_fault(int signal
, int code
, struct sigcontext
*context
)
86 if (signal
== SIGTRAP
)
88 /* If SIGTRAP not caused by breakpoint or single step
89 don't jump into the debugger */
90 if (!(EFL_reg(context
) & STEP_FLAG
))
93 addr
.seg
= CS_reg(context
);
94 addr
.off
= EIP_reg(context
) - 1;
95 if (DEBUG_FindBreakpoint(&addr
) == -1) return;
98 else if (signal
!= SIGHUP
)
100 if (CS_reg(context
) == WINE_CODE_SELECTOR
)
102 fprintf(stderr
, "Segmentation fault in Wine program (%x:%lx)."
104 CS_reg(context
), EIP_reg(context
) );
108 if (INSTR_EmulateInstruction( context
)) return;
109 fprintf( stderr
, "Segmentation fault in Windows program %x:%lx.\n",
110 CS_reg(context
), EIP_reg(context
) );
114 XUngrabPointer(display
, CurrentTime
);
115 XUngrabServer(display
);
117 wine_debug( signal
, context
); /* Enter our debugger */
121 /**********************************************************************
124 static void SIGNAL_SetHandler( int sig
, void (*func
)() )
127 struct sigaction sig_act
;
130 sig_act
.sa_handler
= func
;
131 sig_act
.sa_flags
= SA_RESTART
;
132 /* Point to the top of the stack, minus 4 just in case, and make
134 sig_act
.sa_restorer
=
135 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
136 ret
= wine_sigaction( sig
, &sig_act
, NULL
);
139 #if defined(__NetBSD__) || defined(__FreeBSD__)
141 sigemptyset(&sig_mask
);
142 sig_act
.sa_handler
= func
;
143 sig_act
.sa_flags
= SA_ONSTACK
;
144 sig_act
.sa_mask
= sig_mask
;
145 ret
= sigaction( sig
, &sig_act
, NULL
);
146 #endif /* __FreeBSD__ || __NetBSD__ */
148 #if defined (__svr4__)
150 sigemptyset(&sig_mask
);
151 sig_act
.sa_handler
= func
;
152 sig_act
.sa_flags
= SA_ONSTACK
| SA_SIGINFO
;
153 sig_act
.sa_mask
= sig_mask
;
154 ret
= sigaction( sig
, &sig_act
, NULL
);
155 #endif /* __svr4__ */
159 perror( "sigaction" );
164 extern void stop_wait(int a
);
167 /**********************************************************************
170 void init_wine_signals(void)
172 #if defined(__NetBSD__) || defined(__FreeBSD__)
173 struct sigaltstack ss
;
175 #if !defined (__FreeBSD__)
176 if ((ss
.ss_base
= malloc(MINSIGSTKSZ
)) == NULL
) {
178 if ((ss
.ss_sp
= malloc(MINSIGSTKSZ
)) == NULL
) {
180 fprintf(stderr
, "Unable to allocate signal stack (%d bytes)\n",
184 ss
.ss_size
= MINSIGSTKSZ
;
186 if (sigaltstack(&ss
, NULL
) < 0) {
190 #endif /* __FreeBSD__ || __NetBSD__ */
192 #if defined (__svr4__)
193 struct sigaltstack ss
;
195 if ((ss
.ss_sp
= malloc(SIGSTKSZ
) ) == NULL
) {
196 fprintf(stderr
, "Unable to allocate signal stack (%d bytes)\n",
200 ss
.ss_size
= SIGSTKSZ
;
202 if (sigaltstack(&ss
, NULL
) < 0) {
206 #endif /* __svr4__ */
208 SIGNAL_SetHandler( SIGALRM
, (void (*)())wine_timer
);
209 SIGNAL_SetHandler( SIGSEGV
, (void (*)())win_fault
);
210 SIGNAL_SetHandler( SIGILL
, (void (*)())win_fault
);
211 SIGNAL_SetHandler( SIGFPE
, (void (*)())win_fault
);
212 SIGNAL_SetHandler( SIGTRAP
, (void (*)())win_fault
); /* For debugger */
213 SIGNAL_SetHandler( SIGHUP
, (void (*)())win_fault
); /* For forced break */
215 SIGNAL_SetHandler( SIGBUS
, (void (*)())win_fault
);
218 SIGNAL_SetHandler( SIGUSR2
, (void (*)())stop_wait
); /* For IPC */
220 SIGNAL_StartBIOSTimer();
224 /**********************************************************************
227 * Start the BIOS tick timer.
229 void SIGNAL_StartBIOSTimer(void)
231 struct itimerval vt_timer
;
233 vt_timer
.it_interval
.tv_sec
= 0;
234 vt_timer
.it_interval
.tv_usec
= 54929;
235 vt_timer
.it_value
= vt_timer
.it_interval
;
237 setitimer(ITIMER_REAL
, &vt_timer
, NULL
);
240 #endif /* ifndef WINELIB */