10 #if defined(__NetBSD__) || defined(__FreeBSD__)
11 #include <sys/syscall.h>
12 #include <sys/param.h>
20 #include "prototypes.h"
24 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
27 struct sigaction segv_act;
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));
48 int do_int(int intnum, struct sigcontext_struct *scp)
52 case 0x10: return do_int10(scp);
55 scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment();
59 scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L;
60 return 1; /* get base mem size */
62 case 0x13: return do_int13(scp);
63 case 0x15: return do_int15(scp);
64 case 0x16: return do_int16(scp);
65 case 0x1a: return do_int1a(scp);
66 case 0x21: return do_int21(scp);
75 case 0x25: return do_int25(scp);
76 case 0x26: return do_int26(scp);
77 case 0x2a: return do_int2a(scp);
78 case 0x2f: return do_int2f(scp);
79 case 0x31: return do_int31(scp);
85 static void win_fault(int signal, struct sigcontext_struct context)
87 struct sigcontext_struct *scp = &context;
89 static void win_fault(int signal, int code, struct sigcontext *scp)
92 unsigned char * instr;
93 #if !(defined (linux) || defined (__NetBSD__))
97 /* First take care of a few preliminaries */
104 && signal != SIGTRAP)
109 /* And back up over the int3 instruction. */
110 if(signal == SIGTRAP) {
115 if((scp->sc_cs & 7) != 7)
118 #if defined(__NetBSD__) || defined(__FreeBSD__)
119 /* set_es(0x27); set_ds(0x27); */
120 if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP)
122 if(scp->sc_cs == 0x1f)
126 "Segmentation fault in Wine program (%x:%lx)."
128 scp->sc_cs, scp->sc_eip);
132 /* Now take a look at the actual instruction where the program
134 instr = (unsigned char *) SAFEMAKEPTR(scp->sc_cs, scp->sc_eip);
138 case 0xcd: /* int <XX> */
140 if (!do_int(*instr, scp)) {
141 fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
144 scp->sc_eip += 2; /* Bypass the int instruction */
147 case 0xe4: /* inb al,XX */
152 case 0xe5: /* in ax,XX */
157 case 0xe6: /* outb XX,al */
162 case 0xe7: /* out XX,ax */
167 case 0xec: /* inb al,dx */
172 case 0xed: /* in ax,dx */
177 case 0xee: /* outb dx,al */
182 case 0xef: /* out dx,ax */
187 case 0xfa: /* cli, ignored */
191 case 0xfb: /* sti, ignored */
196 fprintf(stderr, "Unexpected Windows program segfault"
197 " - opcode = %x\n", *instr);
201 /* OK, done handling the interrupt */
206 XUngrabPointer(display, CurrentTime);
207 XUngrabServer(display);
209 fprintf(stderr,"In win_fault %x:%lx\n", scp->sc_cs, scp->sc_eip);
210 #if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__)
211 wine_debug(signal, (int *)scp); /* Enter our debugger */
213 fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp);
217 fprintf(stderr," %8.8x", *dump++);
219 fprintf(stderr,"\n");
221 fprintf(stderr,"\n");
226 void init_wine_signals(void)
229 segv_act.sa_handler = (__sighandler_t) win_fault;
230 /* Point to the top of the stack, minus 4 just in case, and make
232 segv_act.sa_restorer =
233 (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
234 wine_sigaction(SIGSEGV, &segv_act, NULL);
235 wine_sigaction(SIGILL, &segv_act, NULL);
237 wine_sigaction(SIGBUS, &segv_act, NULL);
239 wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
241 #if defined(__NetBSD__) || defined(__FreeBSD__)
243 #if defined(BSD4_4) && !defined (__FreeBSD__)
244 struct sigaltstack ss;
246 if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
247 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
251 ss.ss_size = MINSIGSTKSZ;
253 if (sigaltstack(&ss, NULL) < 0) {
260 ss.ss_sp = (char *) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
262 if (sigstack(&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 static sigjmp_buf segv_jmpbuf;
297 siglongjmp(segv_jmpbuf, 1);
301 test_memory( char *p, int write )
304 struct sigaction new_act;
305 struct sigaction old_act;
307 memset(&new_act, 0, sizeof new_act);
308 new_act.sa_handler = segv_handler;
309 if (sigsetjmp( segv_jmpbuf, 1 ) == 0) {
311 if (sigaction(SIGSEGV, &new_act, &old_act) < 0)
319 wine_sigaction(SIGSEGV, &old_act, NULL);
321 sigaction(SIGSEGV, &old_act, NULL);
326 #endif /* ifndef WINELIB */