7 #include <sys/syscall.h>
14 #include <linux/sched.h>
15 #include <asm/system.h>
21 struct sigaction segv_act
;
24 extern void ___sig_restore();
25 extern void ___masksig_restore();
28 /* Similar to the sigaction function in libc, except it leaves alone the
32 wine_sigaction(int sig
,struct sigaction
* new, struct sigaction
* old
)
34 __asm__("int $0x80":"=a" (sig
)
35 :"0" (SYS_sigaction
),"b" (sig
),"c" (new),"d" (old
));
43 static void win_fault(int signal
, struct sigcontext_struct context
){
44 struct sigcontext_struct
*scp
= &context
;
46 static void win_fault(int signal
, int code
, struct sigcontext
*scp
){
48 unsigned char * instr
;
53 /* First take care of a few preliminaries */
55 if(signal
!= SIGSEGV
) exit(1);
56 if((scp
->sc_cs
& 7) != 7){
59 /* set_es(0x27); set_ds(0x27); */
60 if(signal
!= SIGBUS
) exit(1);
61 if(scp
->sc_cs
== 0x1f){
64 "Segmentation fault in Wine program (%x:%x)."
66 scp
->sc_cs
, scp
->sc_eip
);
70 /* Now take a look at the actual instruction where the program
72 instr
= (char *) SAFEMAKEPTR(scp
->sc_cs
, scp
->sc_eip
);
76 "Unexpected Windows program segfault"
77 " - opcode = %x\n", *instr
);
89 if(!do_int21(scp
)) goto oops
;
92 scp
->sc_eax
= (scp
->sc_eax
& 0xffff0000L
) | DOS_GetEquipment();
95 scp
->sc_eax
= (scp
->sc_eax
& 0xffff0000L
) | 640L;
96 break; /* get base mem size */
98 if(!do_int1A(scp
)) goto oops
;
101 fprintf(stderr
,"Unexpected Windows interrupt %x\n", intno
);
105 /* OK, done handling the interrupt */
107 scp
->sc_eip
+= 2; /* Bypass the int instruction */
110 fprintf(stderr
,"In win_fault %x:%x\n", scp
->sc_cs
, scp
->sc_eip
);
112 wine_debug(scp
); /* Enter our debugger */
114 fprintf(stderr
,"Stack: %x:%x\n", scp
->sc_ss
, scp
->sc_esp
);
118 fprintf(stderr
," %8.8x", *dump
++);
120 fprintf(stderr
,"\n");
122 fprintf(stderr
,"\n");
130 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
131 /* Point to the top of the stack, minus 4 just in case, and make
133 segv_act
.sa_restorer
=
134 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
135 wine_sigaction(SIGSEGV
, &segv_act
, NULL
);
141 ss
.ss_sp
= (char *) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
143 if (sigstack(&ss
, NULL
) < 0) {
147 sigemptyset(&sig_mask
);
148 segv_act
.sa_handler
= (__sighandler_t
) win_fault
;
149 segv_act
.sa_flags
= SA_ONSTACK
;
150 segv_act
.sa_mask
= sig_mask
;
151 if (sigaction(SIGBUS
, &segv_act
, NULL
) < 0) {