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
));
46 static void win_fault(int signal
, struct sigcontext_struct context
)
48 struct sigcontext_struct
*scp
= &context
;
50 static void win_fault(int signal
, int code
, struct sigcontext
*scp
)
53 unsigned char * instr
;
57 /* First take care of a few preliminaries */
59 if(signal
!= SIGSEGV
&& signal
!= SIGTRAP
)
62 /* And back up over the int3 instruction. */
63 if(signal
== SIGTRAP
) {
68 if((scp
->sc_cs
& 7) != 7)
71 #if defined(__NetBSD__) || defined(__FreeBSD__)
72 /* set_es(0x27); set_ds(0x27); */
75 if(scp
->sc_cs
== 0x1f)
79 "Segmentation fault in Wine program (%x:%x)."
81 scp
->sc_cs
, scp
->sc_eip
);
85 /* Now take a look at the actual instruction where the program
87 instr
= (unsigned char *) SAFEMAKEPTR(scp
->sc_cs
, scp
->sc_eip
);
91 case 0xcd: /* int <XX> */
101 scp
->sc_eax
= (scp
->sc_eax
& 0xffff0000L
) | DOS_GetEquipment();
105 scp
->sc_eax
= (scp
->sc_eax
& 0xffff0000L
) | 640L;
106 break; /* get base mem size */
119 scp
->sc_eax
= 0x1234;
120 scp
->sc_ebx
= 0x5678;
121 scp
->sc_ecx
= 0x9abc;
122 scp
->sc_edx
= 0xdef0;
136 fprintf(stderr
,"Unexpected Windows interrupt %x\n", *instr
);
139 scp
->sc_eip
+= 2; /* Bypass the int instruction */
142 case 0xec: /* inb al,dx */
147 case 0xed: /* in ax,dx */
152 case 0xee: /* outb dx,al */
157 case 0xef: /* out dx,ax */
163 fprintf(stderr
, "Unexpected Windows program segfault"
164 " - opcode = %x\n", *instr
);
168 /* OK, done handling the interrupt */
173 XUngrabPointer(display
, CurrentTime
);
174 XUngrabServer(display
);
176 fprintf(stderr
,"In win_fault %x:%x\n", scp
->sc_cs
, scp
->sc_eip
);
178 wine_debug(signal
, scp
); /* Enter our debugger */
180 fprintf(stderr
,"Stack: %x:%x\n", scp
->sc_ss
, scp
->sc_esp
);
184 fprintf(stderr
," %8.8x", *dump
++);
186 fprintf(stderr
,"\n");
188 fprintf(stderr
,"\n");
193 int init_wine_signals(void)
196 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
197 /* Point to the top of the stack, minus 4 just in case, and make
199 segv_act
.sa_restorer
=
200 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
201 wine_sigaction(SIGSEGV
, &segv_act
, NULL
);
202 wine_sigaction(SIGTRAP
, &segv_act
, NULL
); /* For breakpoints */
204 #if defined(__NetBSD__) || defined(__FreeBSD__)
208 ss
.ss_sp
= (char *) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
210 if (sigstack(&ss
, NULL
) < 0) {
214 sigemptyset(&sig_mask
);
215 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
216 segv_act
.sa_flags
= SA_ONSTACK
;
217 segv_act
.sa_mask
= sig_mask
;
218 if (sigaction(SIGBUS
, &segv_act
, NULL
) < 0) {
225 #endif /* ifndef WINELIB */