Sun Apr 2 18:31:12 1995 Alexandre Julliard (julliard@sunsite.unc.edu) * [Configure] [if1632/Imakefile] Removed new build and short names options. * [if1632/*.c] [tools/build.c] Implemented compiled call-back functions for better performance; all the relay code is now done in assembly code generated by the build program. Relay code is no longer dependent on being loaded below 64K. * [loader/resource.c] Fixed memory leak in LoadString(). A fix will also be needed for other resources. * [memory/global.c] Implemented global heap arenas, so we can store informations about global blocks, like lock counts or owner handle. Implemented FarGetOwner() and FarSetOwner(). Implemented global heap TOOLHELP functions. * [memory/selector.c] Bug fix: it was not possible to re-use a free selector. Sun Apr 2 01:34:52 1995 Constantine Sapuntzakis (csapuntz@mit.edu) * [controls/listbox.c] Major work on listbox code - Many bugs fixed (still many bugs) - More messages supported - Code simplified Fri Mar 31 03:27:16 EST 1995 William Magro (wmagro@tc.cornell.edu) * [controls/edit.c] Lots of bug fixes related to diappearing text, lost carets, highlighting, segmentation faults, occurance of random characters, insertion of characters over selection, misplaced caret location, display corruption, end of line behavior, etc. * [controls/widgets.c] EDIT class doesn't want to use CS_PARENTDC flag. Thu Mar 30 20:58:25 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [loader/selector.c] FixupFunctionPrologs() should also handle multiple data modules. (this bug only became visible because MakeProcInstance() was fixed in 950319) * [misc/dosfs.c] Simplified DOS_SimplifyPath. Small fix to DOS_opendir to reuse an entry if an open directory is opened again, to prevent "too many open directories" messages. Thu Mar 30 12:05:05 1995 Martin von Loewis <loewis@informatik.hu-berlin.de> * [if1632/compobj.spec][include/compobj.h][misc/compobj.c] CoDisconnectObject: new stub function * [include/msdos.h] fix DOSVERSION * [loader/ne_image.c] NE_FixupSegment: Be more generous on additive fixups * [if1632/user.spec][misc/network.c] Add more WNet* stubs Wed Mar 29 11:47:22 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [controls/listbox.c] DlgDirList(): send segptr instead of linear pointer in message to static control * [controls/menu.c] Tried to implement ownerdrawn menuitems. Doesn't work. * [if1632/gdi.spec] [include/windows.h] [objects/font.c] Provide a stub for GetRasterizerCaps() * [loader/selector.c] Pass end address instead of length to LocalInit() in CreateSelectors() * [memory/local.c] LocalInit(): If there's already a local heap in the segment, do nothing and return TRUE * [objects/linedda.c] Replaced buggy LineDDA() with a Bresenham algorithm. Should work now. * [windows/cursor.c] LoadCursor()/CreateCursor(): Cleaned up the mess. Needs some more work still. Tue Mar 21 17:54:43 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [if1632/relay.c] [if1632/callback.c] [include/dlls.h] [if1632/winprocs.spec] [if1632/winprocs.c] [include/winprocs.h] [controls/widgets.c] [misc/shell.c] [misc/commdlg.c] [windows/nonclient.c] [misc/message.c] Added a new builtin DLL that provides 16 bit entry points for all the Def*Procs (DefDlgProc, ButtonProc etc.). OWL programs work again. * [misc/shell.c] RegOpenKey()/RegCreateKey() bugs fixed. * [loader/ne_image.c] Skipping the initialization of a DLL when CS == 0 was broken.
290 lines
6.9 KiB
C
290 lines
6.9 KiB
C
#ifndef WINELIB
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
#include <setjmp.h>
|
|
|
|
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
|
#include <sys/syscall.h>
|
|
#include <sys/param.h>
|
|
#else
|
|
#include <syscall.h>
|
|
#endif
|
|
|
|
#include "wine.h"
|
|
#include "dos_fs.h"
|
|
#include "prototypes.h"
|
|
#include "miscemu.h"
|
|
#include "win.h"
|
|
|
|
#if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
|
|
char * cstack[4096];
|
|
#endif
|
|
struct sigaction segv_act;
|
|
|
|
#ifdef linux
|
|
extern void ___sig_restore();
|
|
extern void ___masksig_restore();
|
|
|
|
/* Similar to the sigaction function in libc, except it leaves alone the
|
|
restorer field */
|
|
|
|
static int
|
|
wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
|
|
{
|
|
__asm__("int $0x80":"=a" (sig)
|
|
:"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
|
|
if (sig>=0)
|
|
return 0;
|
|
errno = -sig;
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
int do_int(int intnum, struct sigcontext_struct *scp)
|
|
{
|
|
switch(intnum)
|
|
{
|
|
case 0x10: return do_int10(scp);
|
|
|
|
case 0x11:
|
|
scp->sc_eax = (scp->sc_eax & 0xffff0000L) | DOS_GetEquipment();
|
|
return 1;
|
|
|
|
case 0x12:
|
|
scp->sc_eax = (scp->sc_eax & 0xffff0000L) | 640L;
|
|
return 1; /* get base mem size */
|
|
|
|
case 0x13: return do_int13(scp);
|
|
case 0x15: return do_int15(scp);
|
|
case 0x16: return do_int16(scp);
|
|
case 0x1a: return do_int1a(scp);
|
|
case 0x21: return do_int21(scp);
|
|
|
|
case 0x22:
|
|
scp->sc_eax = 0x1234;
|
|
scp->sc_ebx = 0x5678;
|
|
scp->sc_ecx = 0x9abc;
|
|
scp->sc_edx = 0xdef0;
|
|
return 1;
|
|
|
|
case 0x25: return do_int25(scp);
|
|
case 0x26: return do_int26(scp);
|
|
case 0x2a: return do_int2a(scp);
|
|
case 0x2f: return do_int2f(scp);
|
|
case 0x31: return do_int31(scp);
|
|
|
|
default:
|
|
printf("int%02x: Unimplemented!\n", intnum);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#ifdef linux
|
|
static void win_fault(int signal, struct sigcontext_struct context)
|
|
{
|
|
struct sigcontext_struct *scp = &context;
|
|
#else
|
|
static void win_fault(int signal, int code, struct sigcontext *scp)
|
|
{
|
|
#endif
|
|
unsigned char * instr;
|
|
#if !(defined (linux) || defined (__NetBSD__))
|
|
int i, *dump;
|
|
#endif
|
|
|
|
/* First take care of a few preliminaries */
|
|
#ifdef linux
|
|
if(signal != SIGSEGV
|
|
&& signal != SIGILL
|
|
&& signal != SIGFPE
|
|
#ifdef SIGBUS
|
|
&& signal != SIGBUS
|
|
#endif
|
|
&& signal != SIGTRAP)
|
|
{
|
|
exit(1);
|
|
}
|
|
|
|
/* And back up over the int3 instruction. */
|
|
if(signal == SIGTRAP) {
|
|
scp->sc_eip--;
|
|
goto oops;
|
|
};
|
|
|
|
if((scp->sc_cs & 7) != 7)
|
|
{
|
|
#endif
|
|
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
|
/* set_es(0x27); set_ds(0x27); */
|
|
if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP)
|
|
exit(1);
|
|
if(scp->sc_cs == 0x1f)
|
|
{
|
|
#endif
|
|
fprintf(stderr,
|
|
"Segmentation fault in Wine program (%x:%lx)."
|
|
" Please debug\n",
|
|
scp->sc_cs, scp->sc_eip);
|
|
goto oops;
|
|
};
|
|
|
|
/* Now take a look at the actual instruction where the program
|
|
bombed */
|
|
instr = (unsigned char *) PTR_SEG_OFF_TO_LIN(scp->sc_cs, scp->sc_eip);
|
|
|
|
switch(*instr)
|
|
{
|
|
case 0xcd: /* int <XX> */
|
|
instr++;
|
|
if (!do_int(*instr, scp)) {
|
|
fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
|
|
goto oops;
|
|
}
|
|
scp->sc_eip += 2; /* Bypass the int instruction */
|
|
break;
|
|
|
|
case 0xe4: /* inb al,XX */
|
|
inportb_abs(scp);
|
|
scp->sc_eip += 2;
|
|
break;
|
|
|
|
case 0xe5: /* in ax,XX */
|
|
inport_abs(scp);
|
|
scp->sc_eip += 2;
|
|
break;
|
|
|
|
case 0xe6: /* outb XX,al */
|
|
outportb_abs(scp);
|
|
scp->sc_eip += 2;
|
|
break;
|
|
|
|
case 0xe7: /* out XX,ax */
|
|
outport_abs(scp);
|
|
scp->sc_eip += 2;
|
|
break;
|
|
|
|
case 0xec: /* inb al,dx */
|
|
inportb(scp);
|
|
scp->sc_eip++;
|
|
break;
|
|
|
|
case 0xed: /* in ax,dx */
|
|
inport(scp);
|
|
scp->sc_eip++;
|
|
break;
|
|
|
|
case 0xee: /* outb dx,al */
|
|
outportb(scp);
|
|
scp->sc_eip++;
|
|
break;
|
|
|
|
case 0xef: /* out dx,ax */
|
|
outport(scp);
|
|
scp->sc_eip++;
|
|
break;
|
|
|
|
case 0xfa: /* cli, ignored */
|
|
scp->sc_eip++;
|
|
break;
|
|
|
|
case 0xfb: /* sti, ignored */
|
|
scp->sc_eip++;
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "Unexpected Windows program segfault"
|
|
" - opcode = %x\n", *instr);
|
|
goto oops;
|
|
}
|
|
|
|
/* OK, done handling the interrupt */
|
|
|
|
return;
|
|
|
|
oops:
|
|
XUngrabPointer(display, CurrentTime);
|
|
XUngrabServer(display);
|
|
XFlush(display);
|
|
fprintf(stderr,"In win_fault %x:%lx\n", scp->sc_cs, scp->sc_eip);
|
|
#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__)
|
|
wine_debug(signal, (int *)scp); /* Enter our debugger */
|
|
#else
|
|
fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp);
|
|
dump = (int*) scp;
|
|
for(i=0; i<22; i++)
|
|
{
|
|
fprintf(stderr," %8.8x", *dump++);
|
|
if ((i % 8) == 7)
|
|
fprintf(stderr,"\n");
|
|
}
|
|
fprintf(stderr,"\n");
|
|
exit(1);
|
|
#endif
|
|
}
|
|
|
|
void init_wine_signals(void)
|
|
{
|
|
#ifdef linux
|
|
segv_act.sa_handler = (__sighandler_t) win_fault;
|
|
/* Point to the top of the stack, minus 4 just in case, and make
|
|
it aligned */
|
|
segv_act.sa_restorer =
|
|
(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
|
|
wine_sigaction(SIGSEGV, &segv_act, NULL);
|
|
wine_sigaction(SIGILL, &segv_act, NULL);
|
|
wine_sigaction(SIGFPE, &segv_act, NULL);
|
|
#ifdef SIGBUS
|
|
wine_sigaction(SIGBUS, &segv_act, NULL);
|
|
#endif
|
|
wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
|
|
#endif
|
|
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
|
sigset_t sig_mask;
|
|
struct sigaltstack ss;
|
|
|
|
#if !defined (__FreeBSD__)
|
|
if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
|
|
#else
|
|
if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
|
|
#endif
|
|
fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
|
|
MINSIGSTKSZ);
|
|
exit(1);
|
|
}
|
|
ss.ss_size = MINSIGSTKSZ;
|
|
ss.ss_flags = 0;
|
|
if (sigaltstack(&ss, NULL) < 0) {
|
|
perror("sigstack");
|
|
exit(1);
|
|
}
|
|
sigemptyset(&sig_mask);
|
|
segv_act.sa_handler = (void (*)) win_fault;
|
|
segv_act.sa_flags = SA_ONSTACK;
|
|
segv_act.sa_mask = sig_mask;
|
|
if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
|
|
perror("sigaction: SIGBUS");
|
|
exit(1);
|
|
}
|
|
segv_act.sa_handler = (void (*)) win_fault;
|
|
segv_act.sa_flags = SA_ONSTACK;
|
|
segv_act.sa_mask = sig_mask;
|
|
if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
|
|
perror("sigaction: SIGSEGV");
|
|
exit(1);
|
|
}
|
|
segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
|
|
segv_act.sa_flags = SA_ONSTACK;
|
|
segv_act.sa_mask = sig_mask;
|
|
if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
|
|
perror("sigaction: SIGTRAP");
|
|
exit(1);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#endif /* ifndef WINELIB */
|