10 #if defined(__NetBSD__) || defined(__FreeBSD__)
11 #include <sys/syscall.h>
12 #include <sys/param.h>
19 #include "prototypes.h"
21 #include "registers.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
*context
)
52 case 0x10: return do_int10(context
);
55 AX
= DOS_GetEquipment();
60 return 1; /* get base mem size */
62 case 0x13: return do_int13(context
);
63 case 0x15: return do_int15(context
);
64 case 0x16: return do_int16(context
);
65 case 0x1a: return do_int1a(context
);
66 case 0x21: return do_int21(context
);
75 case 0x25: return do_int25(context
);
76 case 0x26: return do_int26(context
);
77 case 0x2a: return do_int2a(context
);
78 case 0x2f: return do_int2f(context
);
79 case 0x31: return do_int31(context
);
80 case 0x5c: return do_int5c(context
);
83 fprintf(stderr
,"int%02x: Unimplemented!\n", intnum
);
90 static void win_fault(int signal
, struct sigcontext_struct context_struct
)
92 struct sigcontext_struct
*context
= &context_struct
;
94 static void win_fault(int signal
, int code
, struct sigcontext
*context
)
97 unsigned char * instr
;
99 #if !(defined (linux) || defined (__NetBSD__))
103 /* First take care of a few preliminaries */
111 && signal
!= SIGTRAP
)
116 /* And back up over the int3 instruction. */
117 if(signal
== SIGTRAP
) {
123 /* set_es(0x1f); set_ds(0x1f); */
124 if(signal
!= SIGBUS
&& signal
!= SIGSEGV
&& signal
!= SIGTRAP
)
128 /* set_es(0x27); set_ds(0x27); */
129 if(signal
!= SIGBUS
&& signal
!= SIGSEGV
&& signal
!= SIGTRAP
)
132 if (CS
== WINE_CODE_SELECTOR
)
135 "Segmentation fault in Wine program (%x:%lx)."
136 " Please debug\n", CS
, EIP
);
140 /* Now take a look at the actual instruction where the program
142 instr
= (unsigned char *) PTR_SEG_OFF_TO_LIN( CS
, EIP
);
146 case 0xcd: /* int <XX> */
148 if (!do_int(*instr
, context
)) {
149 fprintf(stderr
,"Unexpected Windows interrupt %x\n", *instr
);
152 EIP
+= 2; /* Bypass the int instruction */
155 case 0xcf: /* iret */
156 stack
= (WORD
*)PTR_SEG_OFF_TO_LIN( SS
, SP
);
160 SP
+= 6; /* Pop the return address and flags */
163 case 0xe4: /* inb al,XX */
164 inportb_abs(context
);
168 case 0xe5: /* in ax,XX */
173 case 0xe6: /* outb XX,al */
174 outportb_abs(context
);
178 case 0xe7: /* out XX,ax */
179 outport_abs(context
);
183 case 0xec: /* inb al,dx */
188 case 0xed: /* in ax,dx */
193 case 0xee: /* outb dx,al */
198 case 0xef: /* out dx,ax */
203 case 0xfa: /* cli, ignored */
207 case 0xfb: /* sti, ignored */
212 fprintf(stderr
, "Unexpected Windows program segfault"
213 " - opcode = %x\n", *instr
);
217 /* OK, done handling the interrupt */
222 XUngrabPointer(display
, CurrentTime
);
223 XUngrabServer(display
);
225 fprintf(stderr
,"In win_fault %x:%lx\n", CS
, EIP
);
226 #if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__)
227 wine_debug(signal
, (int *)context
); /* Enter our debugger */
229 fprintf(stderr
,"Stack: %x:%x\n", SS
, ESP
);
230 dump
= (int*) context
;
233 fprintf(stderr
," %8.8x", *dump
++);
235 fprintf(stderr
,"\n");
237 fprintf(stderr
,"\n");
242 void init_wine_signals(void)
245 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
246 /* Point to the top of the stack, minus 4 just in case, and make
248 segv_act
.sa_restorer
=
249 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
250 wine_sigaction(SIGSEGV
, &segv_act
, NULL
);
251 wine_sigaction(SIGILL
, &segv_act
, NULL
);
252 wine_sigaction(SIGFPE
, &segv_act
, NULL
);
254 wine_sigaction(SIGBUS
, &segv_act
, NULL
);
256 wine_sigaction(SIGTRAP
, &segv_act
, NULL
); /* For breakpoints */
258 #if defined(__NetBSD__) || defined(__FreeBSD__)
260 struct sigaltstack ss
;
262 #if !defined (__FreeBSD__)
263 if ((ss
.ss_base
= malloc(MINSIGSTKSZ
)) == NULL
) {
265 if ((ss
.ss_sp
= malloc(MINSIGSTKSZ
)) == NULL
) {
267 fprintf(stderr
, "Unable to allocate signal stack (%d bytes)\n",
271 ss
.ss_size
= MINSIGSTKSZ
;
273 if (sigaltstack(&ss
, NULL
) < 0) {
277 sigemptyset(&sig_mask
);
278 segv_act
.sa_handler
= (void (*)) win_fault
;
279 segv_act
.sa_flags
= SA_ONSTACK
;
280 segv_act
.sa_mask
= sig_mask
;
281 if (sigaction(SIGBUS
, &segv_act
, NULL
) < 0) {
282 perror("sigaction: SIGBUS");
285 segv_act
.sa_handler
= (void (*)) win_fault
;
286 segv_act
.sa_flags
= SA_ONSTACK
;
287 segv_act
.sa_mask
= sig_mask
;
288 if (sigaction(SIGSEGV
, &segv_act
, NULL
) < 0) {
289 perror("sigaction: SIGSEGV");
292 segv_act
.sa_handler
= (void (*)) win_fault
; /* For breakpoints */
293 segv_act
.sa_flags
= SA_ONSTACK
;
294 segv_act
.sa_mask
= sig_mask
;
295 if (sigaction(SIGTRAP
, &segv_act
, NULL
) < 0) {
296 perror("sigaction: SIGTRAP");
302 #endif /* ifndef WINELIB */