8 #if defined(__NetBSD__) || defined(__FreeBSD__)
9 #include <sys/syscall.h>
14 #include <linux/sched.h>
15 #include <asm/system.h>
20 #include "prototypes.h"
24 struct sigaction segv_act
;
27 extern void ___sig_restore();
28 extern void ___masksig_restore();
31 /* Similar to the sigaction function in libc, except it leaves alone the
35 wine_sigaction(int sig
,struct sigaction
* new, struct sigaction
* old
)
37 __asm__("int $0x80":"=a" (sig
)
38 :"0" (SYS_sigaction
),"b" (sig
),"c" (new),"d" (old
));
45 int do_int(int intnum
, struct sigcontext_struct
*scp
)
49 case 0x10: return do_int10(scp
);
52 scp
->sc_eax
= (scp
->sc_eax
& 0xffff0000L
) | DOS_GetEquipment();
56 scp
->sc_eax
= (scp
->sc_eax
& 0xffff0000L
) | 640L;
57 return 1; /* get base mem size */
59 case 0x15: return do_int15(scp
);
60 case 0x16: return do_int16(scp
);
61 case 0x1A: return do_int1A(scp
);
62 case 0x21: return do_int21(scp
);
71 case 0x25: return do_int25(scp
);
72 case 0x26: return do_int26(scp
);
73 case 0x2f: return do_int2f(scp
);
74 case 0x31: return do_int31(scp
);
80 static void win_fault(int signal
, struct sigcontext_struct context
)
82 struct sigcontext_struct
*scp
= &context
;
84 static void win_fault(int signal
, int code
, struct sigcontext
*scp
)
87 unsigned char * instr
;
91 /* First take care of a few preliminaries */
93 if(signal
!= SIGSEGV
&& signal
!= SIGTRAP
)
96 /* And back up over the int3 instruction. */
97 if(signal
== SIGTRAP
) {
102 if((scp
->sc_cs
& 7) != 7)
105 #if defined(__NetBSD__) || defined(__FreeBSD__)
106 /* set_es(0x27); set_ds(0x27); */
109 if(scp
->sc_cs
== 0x1f)
113 "Segmentation fault in Wine program (%x:%x)."
115 scp
->sc_cs
, scp
->sc_eip
);
119 /* Now take a look at the actual instruction where the program
121 instr
= (unsigned char *) SAFEMAKEPTR(scp
->sc_cs
, scp
->sc_eip
);
125 case 0xcd: /* int <XX> */
127 if (!do_int(*instr
, scp
)) {
128 fprintf(stderr
,"Unexpected Windows interrupt %x\n", *instr
);
131 scp
->sc_eip
+= 2; /* Bypass the int instruction */
134 case 0xec: /* inb al,dx */
139 case 0xed: /* in ax,dx */
144 case 0xee: /* outb dx,al */
149 case 0xef: /* out dx,ax */
155 fprintf(stderr
, "Unexpected Windows program segfault"
156 " - opcode = %x\n", *instr
);
160 /* OK, done handling the interrupt */
165 XUngrabPointer(display
, CurrentTime
);
166 XUngrabServer(display
);
168 fprintf(stderr
,"In win_fault %x:%x\n", scp
->sc_cs
, scp
->sc_eip
);
170 wine_debug(signal
, scp
); /* Enter our debugger */
172 fprintf(stderr
,"Stack: %x:%x\n", scp
->sc_ss
, scp
->sc_esp
);
176 fprintf(stderr
," %8.8x", *dump
++);
178 fprintf(stderr
,"\n");
180 fprintf(stderr
,"\n");
185 int init_wine_signals(void)
188 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
189 /* Point to the top of the stack, minus 4 just in case, and make
191 segv_act
.sa_restorer
=
192 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
193 wine_sigaction(SIGSEGV
, &segv_act
, NULL
);
194 wine_sigaction(SIGTRAP
, &segv_act
, NULL
); /* For breakpoints */
196 #if defined(__NetBSD__) || defined(__FreeBSD__)
200 ss
.ss_sp
= (char *) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
202 if (sigstack(&ss
, NULL
) < 0) {
206 sigemptyset(&sig_mask
);
207 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
208 segv_act
.sa_flags
= SA_ONSTACK
;
209 segv_act
.sa_mask
= sig_mask
;
210 if (sigaction(SIGBUS
, &segv_act
, NULL
) < 0) {
217 #endif /* ifndef WINELIB */