10 #if defined(__NetBSD__) || defined(__FreeBSD__)
11 #include <sys/syscall.h>
12 #include <sys/param.h>
19 #include "prototypes.h"
23 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
26 struct sigaction segv_act;
29 extern void ___sig_restore();
30 extern void ___masksig_restore();
32 /* Similar to the sigaction function in libc, except it leaves alone the
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));
47 int do_int(int intnum, struct sigcontext_struct *scp)
51 case 0x10: return do_int10(scp);
54 scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment();
58 scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L;
59 return 1; /* get base mem size */
61 case 0x13: return do_int13(scp);
62 case 0x15: return do_int15(scp);
63 case 0x16: return do_int16(scp);
64 case 0x1a: return do_int1a(scp);
65 case 0x21: return do_int21(scp);
74 case 0x25: return do_int25(scp);
75 case 0x26: return do_int26(scp);
76 case 0x2a: return do_int2a(scp);
77 case 0x2f: return do_int2f(scp);
78 case 0x31: return do_int31(scp);
81 printf("int%02x: Unimplemented!\n", intnum);
88 static void win_fault(int signal, struct sigcontext_struct context)
90 struct sigcontext_struct *scp = &context;
92 static void win_fault(int signal, int code, struct sigcontext *scp)
95 unsigned char * instr;
96 #if !(defined (linux) || defined (__NetBSD__))
100 /* First take care of a few preliminaries */
108 && signal != SIGTRAP)
113 /* And back up over the int3 instruction. */
114 if(signal == SIGTRAP) {
120 /* set_es(0x1f); set_ds(0x1f); */
121 if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP)
125 /* set_es(0x27); set_ds(0x27); */
126 if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP)
129 if (scp->sc_cs == WINE_CODE_SELECTOR)
132 "Segmentation fault in Wine program (%x:%lx)."
134 scp->sc_cs, scp->sc_eip);
138 /* Now take a look at the actual instruction where the program
140 instr = (unsigned char *) PTR_SEG_OFF_TO_LIN(scp->sc_cs, scp->sc_eip);
144 case 0xcd: /* int <XX> */
146 if (!do_int(*instr, scp)) {
147 fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
150 scp->sc_eip += 2; /* Bypass the int instruction */
153 case 0xe4: /* inb al,XX */
158 case 0xe5: /* in ax,XX */
163 case 0xe6: /* outb XX,al */
168 case 0xe7: /* out XX,ax */
173 case 0xec: /* inb al,dx */
178 case 0xed: /* in ax,dx */
183 case 0xee: /* outb dx,al */
188 case 0xef: /* out dx,ax */
193 case 0xfa: /* cli, ignored */
197 case 0xfb: /* sti, ignored */
202 fprintf(stderr, "Unexpected Windows program segfault"
203 " - opcode = %x\n", *instr);
207 /* OK, done handling the interrupt */
212 XUngrabPointer(display, CurrentTime);
213 XUngrabServer(display);
215 fprintf(stderr,"In win_fault %x:%lx\n", scp->sc_cs, scp->sc_eip);
216 #if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__)
217 wine_debug(signal, (int *)scp); /* Enter our debugger */
219 fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp);
223 fprintf(stderr," %8.8x", *dump++);
225 fprintf(stderr,"\n");
227 fprintf(stderr,"\n");
232 void init_wine_signals(void)
235 segv_act.sa_handler = (__sighandler_t) win_fault;
236 /* Point to the top of the stack, minus 4 just in case, and make
238 segv_act.sa_restorer =
239 (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
240 wine_sigaction(SIGSEGV, &segv_act, NULL);
241 wine_sigaction(SIGILL, &segv_act, NULL);
242 wine_sigaction(SIGFPE, &segv_act, NULL);
244 wine_sigaction(SIGBUS, &segv_act, NULL);
246 wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
248 #if defined(__NetBSD__) || defined(__FreeBSD__)
250 struct sigaltstack ss;
252 #if !defined (__FreeBSD__)
253 if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
255 if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
257 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
261 ss.ss_size = MINSIGSTKSZ;
263 if (sigaltstack(&ss, NULL) < 0) {
267 sigemptyset(&sig_mask);
268 segv_act.sa_handler = (void (*)) win_fault;
269 segv_act.sa_flags = SA_ONSTACK;
270 segv_act.sa_mask = sig_mask;
271 if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
272 perror("sigaction: SIGBUS");
275 segv_act.sa_handler = (void (*)) win_fault;
276 segv_act.sa_flags = SA_ONSTACK;
277 segv_act.sa_mask = sig_mask;
278 if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
279 perror("sigaction: SIGSEGV");
282 segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
283 segv_act.sa_flags = SA_ONSTACK;
284 segv_act.sa_mask = sig_mask;
285 if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
286 perror("sigaction: SIGTRAP");
292 #endif /* ifndef WINELIB */