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"
23 struct sigaction segv_act
;
26 extern void ___sig_restore();
27 extern void ___masksig_restore();
30 /* Similar to the sigaction function in libc, except it leaves alone the
34 wine_sigaction(int sig
,struct sigaction
* new, struct sigaction
* old
)
36 __asm__("int $0x80":"=a" (sig
)
37 :"0" (SYS_sigaction
),"b" (sig
),"c" (new),"d" (old
));
45 static void win_fault(int signal
, struct sigcontext_struct context
)
47 struct sigcontext_struct
*scp
= &context
;
49 static void win_fault(int signal
, int code
, struct sigcontext
*scp
)
52 unsigned char * instr
;
56 /* First take care of a few preliminaries */
60 if((scp
->sc_cs
& 7) != 7)
63 #if defined(__NetBSD__) || defined(__FreeBSD__)
64 /* set_es(0x27); set_ds(0x27); */
67 if(scp
->sc_cs
== 0x1f)
71 "Segmentation fault in Wine program (%x:%x)."
73 scp
->sc_cs
, scp
->sc_eip
);
77 /* Now take a look at the actual instruction where the program
79 instr
= (unsigned char *) SAFEMAKEPTR(scp
->sc_cs
, scp
->sc_eip
);
83 case 0xcd: /* int <XX> */
93 scp
->sc_eax
= (scp
->sc_eax
& 0xffff0000L
) | DOS_GetEquipment();
97 scp
->sc_eax
= (scp
->sc_eax
& 0xffff0000L
) | 640L;
98 break; /* get base mem size */
111 scp
->sc_eax
= 0x1234;
112 scp
->sc_ebx
= 0x5678;
113 scp
->sc_ecx
= 0x9abc;
114 scp
->sc_edx
= 0xdef0;
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 fprintf(stderr
,"In win_fault %x:%x\n", scp
->sc_cs
, scp
->sc_eip
);
167 wine_debug(scp
); /* Enter our debugger */
169 fprintf(stderr
,"Stack: %x:%x\n", scp
->sc_ss
, scp
->sc_esp
);
173 fprintf(stderr
," %8.8x", *dump
++);
175 fprintf(stderr
,"\n");
177 fprintf(stderr
,"\n");
182 int init_wine_signals(void)
185 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
186 /* Point to the top of the stack, minus 4 just in case, and make
188 segv_act
.sa_restorer
=
189 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
190 wine_sigaction(SIGSEGV
, &segv_act
, NULL
);
192 #if defined(__NetBSD__) || defined(__FreeBSD__)
196 ss
.ss_sp
= (char *) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
198 if (sigstack(&ss
, NULL
) < 0) {
202 sigemptyset(&sig_mask
);
203 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
204 segv_act
.sa_flags
= SA_ONSTACK
;
205 segv_act
.sa_mask
= sig_mask
;
206 if (sigaction(SIGBUS
, &segv_act
, NULL
) < 0) {
213 #endif /* ifndef WINELIB */