Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Sep 1999 00:57:39 +0200 (MET DST)
From:      Juergen Lock <nox@jelal.kn-bremen.de>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   ports/13670: update emulators/wine for the release
Message-ID:  <199909092257.AAA18464@saturn.kn-bremen.de>

next in thread | raw e-mail | index | archive | help

>Number:         13670
>Category:       ports
>Synopsis:       update emulators/wine for the release
>Confidential:   no
>Severity:       non-critical
>Priority:       high
>Responsible:    freebsd-ports
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Sep  9 16:10:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Juergen Lock
>Release:        FreeBSD 3.3-RC i386
>Organization:
me?  organized?
>Environment:

	3.3-RC i386, xpm-3.4k

>Description:

	Here's an update of the wine port to 990815.  It includes
	fixes for the recently found signal handling bugs on FreeBSD
	and kernel patch files for 3.3 for the changes that didn't
	make it in in time for the code freeze.  With those applied
	it should now finally run everything it does on linux...
	
	(As it turns out i will be here the entire day on friday so
	you can mail me should there be any problems with this.
	I still want to have another look at the sigtrap patch,
	maybe i'll send a new one should i get something working.)

>How-To-Repeat:

	n/a

>Fix:
	
Changed files:
Makefile, files/md5, patches/patch-ad, pkg/PLIST

New files:
files/README.patch, files/patch-3.3-sys-ldtshare,
files/patch-3.3-sys-sigtrap, patches/patch-ba, pkg/MESSAGE

Removed files:
patches/patch-am, patches/patch-an, patches/patch-aw,
patches/patch-ay

Index: Makefile
===================================================================
RCS file: /home/cvs/cvs/ports/emulators/wine/Makefile,v
retrieving revision 1.73
diff -u -u -r1.73 Makefile
--- Makefile	1999/08/31 06:43:57	1.73
+++ Makefile	1999/09/09 21:55:03
@@ -1,14 +1,14 @@
 # New ports collection makefile for:    wine
-# Version required:     980517
+# Version required:     990815
 # Date created:         Sa   9 Nov 1996 00:52:22 MET
 # Whom:			se
 #
 # $FreeBSD: ports/emulators/wine/Makefile,v 1.73 1999/08/31 06:43:57 mharo Exp $
 #
 
-DATE=		990426
+DATE=		990815
 DISTNAME=	Wine-${DATE}
-PKGNAME=	wine-99.04.26
+PKGNAME=	wine-99.08.15
 CATEGORIES=	emulators
 MASTER_SITES=	${MASTER_SITE_SUNSITE}
 MASTER_SITE_SUBDIR=	ALPHA/wine/development
@@ -22,6 +22,8 @@
 MAN1=		wine.1
 ONLY_FOR_ARCHS=	i386
 
+CFLAGS+=	-g
+
 pre-configure:
 	@${ECHO} "WINE_INI_GLOBAL \"${PREFIX}/etc/wine.conf\"" \
 		>> ${WRKSRC}/autoconf.h
@@ -34,7 +36,14 @@
 	-@${MKDIR} ${PREFIX}/etc 2>/dev/null
 	[ -f ${PREFIX}/etc/wine.conf ] \
 		|| ${CP} ${WRKSRC}/wine.ini ${PREFIX}/etc/wine.conf
-	${CP} ${WRKSRC}/wine.sym ${PREFIX}/etc
-	${CP} ${WRKSRC}/documentation/wine.man ${PREFIX}/man/man1/wine.1
+	${INSTALL_DATA} ${WRKSRC}/wine.sym ${PREFIX}/etc
+	${INSTALL_DATA} ${WRKSRC}/documentation/wine.man ${PREFIX}/man/man1/wine.1
+	-@${MKDIR} ${PREFIX}/share/wine 2>/dev/null
+	${INSTALL_DATA} ${FILESDIR}/README.patch \
+		${FILESDIR}/patch-3.3-sys-ldtshare \
+		${FILESDIR}/patch-3.3-sys-sigtrap \
+		${PREFIX}/share/wine
+	${ECHO}
+	@${SED} s+!!PREFIX!!+${PREFIX}+g <${PKGMESSAGE}
 
 .include <bsd.port.mk>
Index: files/md5
===================================================================
RCS file: /home/cvs/cvs/ports/emulators/wine/files/md5,v
retrieving revision 1.46
diff -u -u -r1.46 md5
--- md5	1999/05/03 22:36:11	1.46
+++ md5	1999/09/08 21:59:31
@@ -1 +1 @@
-MD5 (Wine-990426.tar.gz) = ddc5561393b7fedb02b933889658eb7f
+MD5 (Wine-990815.tar.gz) = d3b8b2eb3c55e5bc27b0419ebd2de4e1
Index: patches/patch-ad
===================================================================
RCS file: /home/cvs/cvs/ports/emulators/wine/patches/patch-ad,v
retrieving revision 1.5
diff -u -u -r1.5 patch-ad
--- patch-ad	1996/08/13 16:35:27	1.5
+++ patch-ad	1999/09/08 22:06:47
@@ -1,40 +1,27 @@
-*** wine.ini.orig	Wed Jul 17 22:00:24 1996
---- wine.ini	Mon Aug 12 19:51:38 1996
-***************
-*** 35,39 ****
-  Temp=e:\
-  Path=c:\windows;c:\windows\system;e:\;e:\test;f:\
-! SymbolTableFile=./wine.sym
-  
-  [options]
---- 35,39 ----
-  Temp=e:\
-  Path=c:\windows;c:\windows\system;e:\;e:\test;f:\
-! SymbolTableFile=/usr/local/etc/wine.sym
-  
-  [options]
-***************
-*** 54,64 ****
-  
-  [serialports]
-! Com1=/dev/cua0
-! Com2=/dev/cua1
-  Com3=/dev/modem,38400
-  Com4=/dev/modem
-  
-  [parallelports]
-! Lpt1=/dev/lp0
-  
-  [spy]
---- 54,64 ----
-  
-  [serialports]
-! Com1=/dev/ttyd0
-! Com2=/dev/ttyd1
-  Com3=/dev/modem,38400
-  Com4=/dev/modem
-  
-  [parallelports]
-! Lpt1=/dev/lpt0
-  
-  [spy]
+Index: wine.ini
+@@ -52,7 +52,7 @@
+ System=c:\windows\system
+ Temp=e:\
+ Path=c:\windows;c:\windows\system;e:\;e:\test;f:\
+-SymbolTableFile=./wine.sym
++SymbolTableFile=/usr/local/etc/wine.sym
+ 
+ # <wineconf>
+ 
+@@ -105,13 +105,13 @@
+ Default = -adobe-times-
+ 
+ [serialports]
+-Com1=/dev/ttyS0
+-Com2=/dev/ttyS1
++Com1=/dev/ttyd0
++Com2=/dev/ttyd1
+ Com3=/dev/modem,38400
+ Com4=/dev/modem
+ 
+ [parallelports]
+-Lpt1=/dev/lp0
++Lpt1=/dev/lpt0
+ 
+ [spooler]
+ LPT1:=|lpr
Index: pkg/PLIST
===================================================================
RCS file: /home/cvs/cvs/ports/emulators/wine/pkg/PLIST,v
retrieving revision 1.3
diff -u -u -r1.3 PLIST
--- PLIST	1998/08/17 09:43:16	1.3
+++ PLIST	1999/09/09 20:58:35
@@ -1,3 +1,6 @@
 bin/wine
 etc/wine.conf
 etc/wine.sym
+share/wine/README.patch
+share/wine/patch-3.3-sys-ldtshare
+share/wine/patch-3.3-sys-sigtrap
--- /dev/null	Thu Sep  9 23:47:15 1999
+++ files/README.patch	Thu Sep  9 23:29:03 1999
@@ -0,0 +1,39 @@
+Here are two patches for FreeBSD's kernel that are necessary for wine
+(well not strictly _necessary_ but without them parts of it won't work.)
+They unfortunately didn't make it into the base distribution in time
+for the 3.3 release...
+
+patch-3.3-sys-ldtshare:
+make kernel threads (rfork(), which wine uses) share one LDT instead of
+each having its own.  this fixes the same problem that wine also had on
+linux kernels before 2.2.
+
+patch-3.3-sys-sigtrap:
+stop wine's SIGTRAP handler from being called in the sigreturn syscall,
+causing problems for wine's internal debugger.  (it would still
+correctly show a crash backtrace but all commands that use single-
+stepping failed.)  (late note:  as Bruce points out on -emulation
+this is not the `right' fix for this but i want to get this port update
+out first in time for the freeze before i try his suggestion...)
+
+Apply as follows:
+
+	(cd /usr/src/sys && patch ) <patch-3.3-sys-ldtshare
+	(cd /usr/src/sys && patch ) <patch-3.3-sys-sigtrap
+
+then build a new kernel. (don't forget to include the options USER_LDT,
+SYSVSHM, SYSVSEM, and SYSVMSG, wine needs these.)
+
+-current users:
+someone of you :) needs to implement a runtime check in wine for the
+FreeBSD version and based on that use/set the sc_gs and sc_fs values
+in the sigcontext struct in signal handlers for versions >= 4.0.
+(yes you could also simply define FS_sig and GS_sig in wine's
+include/sig_context.h and be done with it but the resulting wine
+would only work on 4.0 and Alexandre (wine maintainer) didn't like
+that idea...)
+
+A LDT patch for -current is at http://www.freebsd.org/~luoqi
+(not included since i don't know if it still applies), the sigtrap
+patch looks like it could also apply to -current but i haven't tried.
+(and if not, i guess the `real' fix will be committed soon anyway.)
--- /dev/null	Thu Sep  9 23:47:27 1999
+++ files/patch-3.3-sys-ldtshare	Thu Sep  9 19:28:21 1999
@@ -0,0 +1,656 @@
+Index: alpha/alpha/vm_machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/alpha/alpha/vm_machdep.c,v
+retrieving revision 1.7.2.2
+diff -u -u -r1.7.2.2 vm_machdep.c
+--- vm_machdep.c	1999/08/29 15:56:38	1.7.2.2
++++ vm_machdep.c	1999/09/04 20:32:00
+@@ -114,11 +114,15 @@
+  * ready to run and return to user mode.
+  */
+ void
+-cpu_fork(p1, p2)
++cpu_fork(p1, p2, flags)
+ 	register struct proc *p1, *p2;
++	int flags;
+ {
+ 	struct user *up = p2->p_addr;
+ 	int i;
++
++	if ((flags & RFPROC) == 0)
++		return;
+ 
+ 	p2->p_md.md_tf = p1->p_md.md_tf;
+ 	p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
+Index: i386/i386/genassym.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/genassym.c,v
+retrieving revision 1.62.2.2
+diff -u -u -r1.62.2.2 genassym.c
+--- genassym.c	1999/08/29 16:05:40	1.62.2.2
++++ genassym.c	1999/09/04 20:35:59
+@@ -125,7 +125,9 @@
+ 	printf("#define\tPCB_EBX %#x\n", OS(pcb, pcb_ebx));
+ 	printf("#define\tPCB_EIP %#x\n", OS(pcb, pcb_eip));
+ 	printf("#define\tTSS_ESP0 %#x\n", OS(i386tss, tss_esp0));
++#ifdef USER_LDT
+ 	printf("#define\tPCB_USERLDT %#x\n", OS(pcb, pcb_ldt));
++#endif
+ 	printf("#define\tPCB_FS %#x\n", OS(pcb, pcb_fs));
+ 	printf("#define\tPCB_GS %#x\n", OS(pcb, pcb_gs));
+ #ifdef VM86
+Index: i386/i386/machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/machdep.c,v
+retrieving revision 1.322.2.8
+diff -u -u -r1.322.2.8 machdep.c
+--- machdep.c	1999/08/29 16:05:43	1.322.2.8
++++ machdep.c	1999/09/04 20:36:02
+@@ -817,15 +827,7 @@
+ 
+ #ifdef USER_LDT
+ 	/* was i386_user_cleanup() in NetBSD */
+-	if (pcb->pcb_ldt) {
+-		if (pcb == curpcb) {
+-			lldt(_default_ldt);
+-			currentldt = _default_ldt;
+-		}
+-		kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
+-			pcb->pcb_ldt_len * sizeof(union descriptor));
+-		pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
+- 	}
++	user_ldt_free(pcb);
+ #endif
+   
+ 	bzero((char *)regs, sizeof(struct trapframe));
+Index: i386/i386/sys_machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/sys_machdep.c,v
+retrieving revision 1.38.2.1
+diff -u -u -r1.38.2.1 sys_machdep.c
+--- sys_machdep.c	1999/08/29 16:05:55	1.38.2.1
++++ sys_machdep.c	1999/09/04 20:36:09
+@@ -41,6 +41,7 @@
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/sysproto.h>
++#include <sys/malloc.h>
+ #include <sys/proc.h>
+ 
+ #include <vm/vm.h>
+@@ -65,7 +66,6 @@
+ 
+ 
+ #ifdef USER_LDT
+-void set_user_ldt	__P((struct pcb *pcb));
+ static int i386_get_ldt	__P((struct proc *, char *));
+ static int i386_set_ldt	__P((struct proc *, char *));
+ #endif
+@@ -259,13 +259,72 @@
+ void
+ set_user_ldt(struct pcb *pcb)
+ {
+-	gdt_segs[GUSERLDT_SEL].ssd_base = (unsigned)pcb->pcb_ldt;
+-	gdt_segs[GUSERLDT_SEL].ssd_limit = (pcb->pcb_ldt_len * sizeof(union descriptor)) - 1;
+-	ssdtosd(&gdt_segs[GUSERLDT_SEL], &gdt[GUSERLDT_SEL].sd);
++	struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
++#ifdef SMP
++	gdt[cpuid * NGDT + GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
++#else
++	gdt[GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
++#endif
+ 	lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
+ 	currentldt = GSEL(GUSERLDT_SEL, SEL_KPL);
+ }
+ 
++struct pcb_ldt *
++user_ldt_alloc(struct pcb *pcb, int len)
++{
++	struct pcb_ldt *pcb_ldt, *new_ldt;
++
++	MALLOC(new_ldt, struct pcb_ldt *, sizeof(struct pcb_ldt),
++		M_SUBPROC, M_WAITOK);
++	if (new_ldt == NULL)
++		return NULL;
++
++	new_ldt->ldt_len = len = NEW_MAX_LD(len);
++	new_ldt->ldt_base = (caddr_t)kmem_alloc(kernel_map,
++		len * sizeof(union descriptor));
++	if (new_ldt->ldt_base == NULL) {
++		FREE(new_ldt, M_SUBPROC);
++		return NULL;
++	}
++	new_ldt->ldt_refcnt = 1;
++	new_ldt->ldt_active = 0;
++
++	gdt_segs[GUSERLDT_SEL].ssd_base = (unsigned)new_ldt->ldt_base;
++	gdt_segs[GUSERLDT_SEL].ssd_limit = len * sizeof(union descriptor) - 1;
++	ssdtosd(&gdt_segs[GUSERLDT_SEL], &new_ldt->ldt_sd);
++
++	if ((pcb_ldt = pcb->pcb_ldt)) {
++		if (len > pcb_ldt->ldt_len)
++			len = pcb_ldt->ldt_len;
++		bcopy(pcb_ldt->ldt_base, new_ldt->ldt_base,
++			len * sizeof(union descriptor));
++	} else {
++		bcopy(ldt, new_ldt->ldt_base, sizeof(ldt));
++	}
++	return new_ldt;
++}
++
++void
++user_ldt_free(struct pcb *pcb)
++{
++	struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
++
++	if (pcb_ldt == NULL)
++		return;
++
++	if (pcb == curpcb) {
++		lldt(_default_ldt);
++		currentldt = _default_ldt;
++	}
++
++	if (--pcb_ldt->ldt_refcnt == 0) {
++		kmem_free(kernel_map, (vm_offset_t)pcb_ldt->ldt_base,
++			pcb_ldt->ldt_len * sizeof(union descriptor));
++		FREE(pcb_ldt, M_SUBPROC);
++	}
++	pcb->pcb_ldt = NULL;
++}
++
+ struct i386_get_ldt_args {
+ 	int start;
+ 	union descriptor *desc;
+@@ -279,6 +338,7 @@
+ {
+ 	int error = 0;
+ 	struct pcb *pcb = &p->p_addr->u_pcb;
++	struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
+ 	int nldt, num;
+ 	union descriptor *lp;
+ 	int s;
+@@ -299,10 +359,10 @@
+ 
+ 	s = splhigh();
+ 
+-	if (pcb->pcb_ldt) {
+-		nldt = pcb->pcb_ldt_len;
++	if (pcb_ldt) {
++		nldt = pcb_ldt->ldt_len;
+ 		num = min(uap->num, nldt);
+-		lp = &((union descriptor *)(pcb->pcb_ldt))[uap->start];
++		lp = &((union descriptor *)(pcb_ldt->ldt_base))[uap->start];
+ 	} else {
+ 		nldt = sizeof(ldt)/sizeof(ldt[0]);
+ 		num = min(uap->num, nldt);
+@@ -335,6 +395,7 @@
+ 	int error = 0, i, n;
+  	int largest_ld;
+ 	struct pcb *pcb = &p->p_addr->u_pcb;
++	struct pcb_ldt *pcb_ldt = pcb->pcb_ldt;
+ 	int s;
+ 	struct i386_set_ldt_args ua, *uap;
+ 
+@@ -348,36 +409,37 @@
+ 	    uap->start, uap->num, (void *)uap->desc);
+ #endif
+ 
+- 	/* verify range of descriptors to modify */
+- 	if ((uap->start < 0) || (uap->start >= MAX_LD) || (uap->num < 0) ||
+- 		(uap->num > MAX_LD))
+- 	{
++	/* verify range of descriptors to modify */
++	if ((uap->start < 0) || (uap->start >= MAX_LD) || (uap->num < 0) ||
++		(uap->num > MAX_LD))
++	{
++		return(EINVAL);
++	}
++	largest_ld = uap->start + uap->num - 1;
++	if (largest_ld >= MAX_LD)
+  		return(EINVAL);
+- 	}
+- 	largest_ld = uap->start + uap->num - 1;
+- 	if (largest_ld >= MAX_LD)
+-  		return(EINVAL);
+-  
+-  	/* allocate user ldt */
+- 	if (!pcb->pcb_ldt || (largest_ld >= pcb->pcb_ldt_len)) {
+- 		union descriptor *new_ldt = (union descriptor *)kmem_alloc(
+- 			kernel_map, SIZE_FROM_LARGEST_LD(largest_ld));
+- 		if (new_ldt == NULL) {
+- 			return ENOMEM;
+- 		}
+- 		if (pcb->pcb_ldt) {
+- 			bcopy(pcb->pcb_ldt, new_ldt, pcb->pcb_ldt_len
+- 				* sizeof(union descriptor));
+- 			kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
+- 				pcb->pcb_ldt_len * sizeof(union descriptor));
+- 		} else {
+- 			bcopy(ldt, new_ldt, sizeof(ldt));
+- 		}
+-  		pcb->pcb_ldt = (caddr_t)new_ldt;
+- 		pcb->pcb_ldt_len = NEW_MAX_LD(largest_ld);
+- 		if (pcb == curpcb)
+- 		    set_user_ldt(pcb);
+-  	}
++ 
++ 	/* allocate user ldt */
++	if (!pcb_ldt || (largest_ld >= pcb_ldt->ldt_len)) {
++		struct pcb_ldt *new_ldt = user_ldt_alloc(pcb, largest_ld);
++		if (new_ldt == NULL) {
++			return ENOMEM;
++		}
++	        if (pcb_ldt) {
++	                pcb_ldt->ldt_sd = new_ldt->ldt_sd;
++#ifdef SMP
++		/* signal other cpus to reload ldt */
++#endif
++			kmem_free(kernel_map, (vm_offset_t)pcb_ldt->ldt_base,
++				pcb_ldt->ldt_len * sizeof(union descriptor));
++			pcb_ldt->ldt_base = new_ldt->ldt_base;
++			pcb_ldt->ldt_len = new_ldt->ldt_len;
++			FREE(new_ldt, M_SUBPROC);
++	        } else
++			pcb->pcb_ldt = pcb_ldt = new_ldt;
++		if (pcb == curpcb)
++			set_user_ldt(pcb);
++	}
+ 
+ 	/* Check descriptors for access violations */
+ 	for (i = 0, n = uap->start; i < uap->num; i++, n++) {
+@@ -388,70 +450,70 @@
+ 			return(error);
+ 
+ 		switch (desc.sd.sd_type) {
+- 		case SDT_SYSNULL:	/* system null */ 
+- 			desc.sd.sd_p = 0;
+-  			break;
+- 		case SDT_SYS286TSS: /* system 286 TSS available */
+- 		case SDT_SYSLDT:    /* system local descriptor table */
+- 		case SDT_SYS286BSY: /* system 286 TSS busy */
+- 		case SDT_SYSTASKGT: /* system task gate */
+- 		case SDT_SYS286IGT: /* system 286 interrupt gate */
+- 		case SDT_SYS286TGT: /* system 286 trap gate */
+- 		case SDT_SYSNULL2:  /* undefined by Intel */ 
+- 		case SDT_SYS386TSS: /* system 386 TSS available */
+- 		case SDT_SYSNULL3:  /* undefined by Intel */
+- 		case SDT_SYS386BSY: /* system 386 TSS busy */
+- 		case SDT_SYSNULL4:  /* undefined by Intel */ 
+- 		case SDT_SYS386IGT: /* system 386 interrupt gate */
+- 		case SDT_SYS386TGT: /* system 386 trap gate */
+- 		case SDT_SYS286CGT: /* system 286 call gate */ 
+- 		case SDT_SYS386CGT: /* system 386 call gate */
+- 			/* I can't think of any reason to allow a user proc
+- 			 * to create a segment of these types.  They are
+- 			 * for OS use only.
+- 			 */
+-     	    	    	return EACCES;
+- 
+- 		/* memory segment types */
+- 		case SDT_MEMEC:   /* memory execute only conforming */
+- 		case SDT_MEMEAC:  /* memory execute only accessed conforming */
+- 		case SDT_MEMERC:  /* memory execute read conforming */
+- 		case SDT_MEMERAC: /* memory execute read accessed conforming */
+-                         /* Must be "present" if executable and conforming. */
+-                         if (desc.sd.sd_p == 0)
+-                                 return (EACCES);
++		case SDT_SYSNULL:	/* system null */ 
++			desc.sd.sd_p = 0;
+  			break;
+- 		case SDT_MEMRO:   /* memory read only */
+- 		case SDT_MEMROA:  /* memory read only accessed */
+- 		case SDT_MEMRW:   /* memory read write */
+- 		case SDT_MEMRWA:  /* memory read write accessed */
+- 		case SDT_MEMROD:  /* memory read only expand dwn limit */
+- 		case SDT_MEMRODA: /* memory read only expand dwn lim accessed */
+- 		case SDT_MEMRWD:  /* memory read write expand dwn limit */  
+- 		case SDT_MEMRWDA: /* memory read write expand dwn lim acessed */
+- 		case SDT_MEME:    /* memory execute only */ 
+- 		case SDT_MEMEA:   /* memory execute only accessed */
+- 		case SDT_MEMER:   /* memory execute read */
+- 		case SDT_MEMERA:  /* memory execute read accessed */
++		case SDT_SYS286TSS: /* system 286 TSS available */
++		case SDT_SYSLDT:    /* system local descriptor table */
++		case SDT_SYS286BSY: /* system 286 TSS busy */
++		case SDT_SYSTASKGT: /* system task gate */
++		case SDT_SYS286IGT: /* system 286 interrupt gate */
++		case SDT_SYS286TGT: /* system 286 trap gate */
++		case SDT_SYSNULL2:  /* undefined by Intel */ 
++		case SDT_SYS386TSS: /* system 386 TSS available */
++		case SDT_SYSNULL3:  /* undefined by Intel */
++		case SDT_SYS386BSY: /* system 386 TSS busy */
++		case SDT_SYSNULL4:  /* undefined by Intel */ 
++		case SDT_SYS386IGT: /* system 386 interrupt gate */
++		case SDT_SYS386TGT: /* system 386 trap gate */
++		case SDT_SYS286CGT: /* system 286 call gate */ 
++		case SDT_SYS386CGT: /* system 386 call gate */
++			/* I can't think of any reason to allow a user proc
++			 * to create a segment of these types.  They are
++			 * for OS use only.
++			 */
++    	    	    	return EACCES;
++
++		/* memory segment types */
++		case SDT_MEMEC:   /* memory execute only conforming */
++		case SDT_MEMEAC:  /* memory execute only accessed conforming */
++		case SDT_MEMERC:  /* memory execute read conforming */
++		case SDT_MEMERAC: /* memory execute read accessed conforming */
++			/* Must be "present" if executable and conforming. */
++			if (desc.sd.sd_p == 0)
++				return (EACCES);
++			break;
++		case SDT_MEMRO:   /* memory read only */
++		case SDT_MEMROA:  /* memory read only accessed */
++		case SDT_MEMRW:   /* memory read write */
++		case SDT_MEMRWA:  /* memory read write accessed */
++		case SDT_MEMROD:  /* memory read only expand dwn limit */
++		case SDT_MEMRODA: /* memory read only expand dwn lim accessed */
++		case SDT_MEMRWD:  /* memory read write expand dwn limit */  
++		case SDT_MEMRWDA: /* memory read write expand dwn lim acessed */
++		case SDT_MEME:    /* memory execute only */ 
++		case SDT_MEMEA:   /* memory execute only accessed */
++		case SDT_MEMER:   /* memory execute read */
++		case SDT_MEMERA:  /* memory execute read accessed */
+ 			break;
+ 		default:
+ 			return(EINVAL);
+ 			/*NOTREACHED*/
+ 		}
+  
+- 		/* Only user (ring-3) descriptors may be present. */
+- 		if ((desc.sd.sd_p != 0) && (desc.sd.sd_dpl != SEL_UPL))
+- 			return (EACCES);
++		/* Only user (ring-3) descriptors may be present. */
++		if ((desc.sd.sd_p != 0) && (desc.sd.sd_dpl != SEL_UPL))
++			return (EACCES);
+ 	}
+ 
+ 	s = splhigh();
+ 
+ 	/* Fill in range */
+- 	error = copyin(uap->desc, 
+- 		 &((union descriptor *)(pcb->pcb_ldt))[uap->start],
+- 		uap->num * sizeof(union descriptor));
+- 	if (!error)
+-  		p->p_retval[0] = uap->start;
++	error = copyin(uap->desc, 
++		 &((union descriptor *)(pcb_ldt->ldt_base))[uap->start],
++		uap->num * sizeof(union descriptor));
++	if (!error)
++ 		p->p_retval[0] = uap->start;
+ 
+ 	splx(s);
+ 	return(error);
+Index: i386/i386/vm_machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/vm_machdep.c,v
+retrieving revision 1.115.2.1
+diff -u -u -r1.115.2.1 vm_machdep.c
+--- vm_machdep.c	1999/08/29 16:05:58	1.115.2.1
++++ vm_machdep.c	1999/09/04 20:36:15
+@@ -57,6 +57,7 @@
+ #include <sys/vmmeter.h>
+ #include <sys/kernel.h>
+ #include <sys/sysctl.h>
++#include <sys/unistd.h>
+ 
+ #include <machine/clock.h>
+ #include <machine/cpu.h>
+@@ -68,6 +69,9 @@
+ #include <machine/pcb_ext.h>
+ #include <machine/vm86.h>
+ #endif
++#ifdef USER_LDT
++#include <machine/pcb_ext.h>
++#endif
+ 
+ #include <vm/vm.h>
+ #include <vm/vm_param.h>
+@@ -113,10 +117,29 @@
+  * ready to run and return to user mode.
+  */
+ void
+-cpu_fork(p1, p2)
++cpu_fork(p1, p2, flags)
+ 	register struct proc *p1, *p2;
++	int flags;
+ {
+-	struct pcb *pcb2 = &p2->p_addr->u_pcb;
++	struct pcb *pcb2;
++ 
++	if ((flags & RFPROC) == 0) {
++#ifdef USER_LDT
++		if ((flags & RFMEM) == 0) {
++			/* unshare user LDT */
++			struct pcb *pcb1 = &p1->p_addr->u_pcb;
++			struct pcb_ldt *pcb_ldt = pcb1->pcb_ldt;
++			if (pcb_ldt && pcb_ldt->ldt_refcnt > 1) {
++				pcb_ldt = user_ldt_alloc(pcb1,pcb_ldt->ldt_len);
++				user_ldt_free(pcb1);
++				pcb1->pcb_ldt = pcb_ldt;
++				if (pcb1 == curpcb)
++					set_user_ldt(pcb1);
++			}
++		}
++#endif
++	        return;
++	}
+ 
+ #if NNPX > 0
+ 	/* Ensure that p1's pcb is up to date. */
+@@ -126,6 +149,7 @@
+ 
+ 	/* Copy p1's pcb. */
+ 	p2->p_addr->u_pcb = p1->p_addr->u_pcb;
++	pcb2 = &p2->p_addr->u_pcb;
+ 
+ 	/*
+ 	 * Create a new fresh stack for the new process.
+@@ -153,7 +177,6 @@
+ 	pcb2->pcb_eip = (int)fork_trampoline;
+ 	/*
+ 	 * pcb2->pcb_ldt:	duplicated below, if necessary.
+-	 * pcb2->pcb_ldt_len:	cloned above.
+ 	 * pcb2->pcb_savefpu:	cloned above.
+ 	 * pcb2->pcb_flags:	cloned above (always 0 here?).
+ 	 * pcb2->pcb_onfault:	cloned above (always NULL here?).
+@@ -172,12 +195,12 @@
+ #ifdef USER_LDT
+         /* Copy the LDT, if necessary. */
+         if (pcb2->pcb_ldt != 0) {
+-                union descriptor *new_ldt;
+-                size_t len = pcb2->pcb_ldt_len * sizeof(union descriptor);
+-
+-                new_ldt = (union descriptor *)kmem_alloc(kernel_map, len);
+-                bcopy(pcb2->pcb_ldt, new_ldt, len);
+-                pcb2->pcb_ldt = (caddr_t)new_ldt;
++		if (flags & RFMEM) {
++			pcb2->pcb_ldt->ldt_refcnt++;
++		} else {
++			pcb2->pcb_ldt = user_ldt_alloc(pcb2,
++				pcb2->pcb_ldt->ldt_len);
++		}
+         }
+ #endif
+ 
+@@ -235,15 +258,7 @@
+ 	}
+ #endif
+ #ifdef USER_LDT
+-	if (pcb->pcb_ldt != 0) {
+-		if (pcb == curpcb) {
+-			lldt(_default_ldt);
+-			currentldt = _default_ldt;
+-		}
+-		kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
+-			pcb->pcb_ldt_len * sizeof(union descriptor));
+-		pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
+-	}
++	user_ldt_free(pcb);
+ #endif
+ 	cnt.v_swtch++;
+ 	cpu_switch(p);
+Index: i386/include/pcb.h
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/include/pcb.h,v
+retrieving revision 1.26.2.1
+diff -u -u -r1.26.2.1 pcb.h
+--- pcb.h	1999/08/29 16:06:43	1.26.2.1
++++ pcb.h	1999/09/04 20:36:29
+@@ -53,8 +53,11 @@
+ 	int	pcb_esp;
+ 	int	pcb_ebx;
+ 	int	pcb_eip;
+-	caddr_t	pcb_ldt;		/* per process (user) LDT */
+-	int	pcb_ldt_len;		/* number of LDT entries */
++#ifdef USER_LDT
++	struct  pcb_ldt *pcb_ldt;       /* per process (user) LDT */
++#else
++	struct  pcb_ldt *pcb_ldt_dontuse;
++#endif
+ 	struct	save87	pcb_savefpu;	/* floating point state for 287/387 */
+ 	u_char	pcb_flags;
+ #define	FP_SOFTFP	0x01	/* process using software fltng pnt emulator */
+@@ -71,7 +74,7 @@
+ #else
+ 	struct	pcb_ext	*pcb_ext_dontuse;
+ #endif
+-	u_long	__pcb_spare[1];	/* adjust to avoid core dump size changes */
++	u_long	__pcb_spare[2];	/* adjust to avoid core dump size changes */
+ };
+ 
+ /*
+Index: i386/include/pcb_ext.h
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/include/pcb_ext.h,v
+retrieving revision 1.1.2.1
+diff -u -u -r1.1.2.1 pcb_ext.h
+--- pcb_ext.h	1999/08/29 16:06:44	1.1.2.1
++++ pcb_ext.h	1999/09/04 20:36:29
+@@ -43,4 +43,22 @@
+ 	struct	vm86_kernel ext_vm86;	/* vm86 area */
+ };
+ 
++struct pcb_ldt {
++	caddr_t ldt_base;
++	int     ldt_len;
++	int     ldt_refcnt;
++	u_long  ldt_active;
++	struct  segment_descriptor ldt_sd;
++};
++
++#ifdef KERNEL
++
++#ifdef USER_LDT
++void set_user_ldt __P((struct pcb *));
++struct pcb_ldt *user_ldt_alloc __P((struct pcb *, int));
++void user_ldt_free __P((struct pcb *));
++#endif
++
++#endif
++
+ #endif /* _I386_PCB_EXT_H_ */
+Index: kern/kern_fork.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/kern/kern_fork.c,v
+retrieving revision 1.54.2.4
+diff -u -u -r1.54.2.4 kern_fork.c
+--- kern_fork.c	1999/08/29 16:25:59	1.54.2.4
++++ kern_fork.c	1999/09/04 20:38:06
+@@ -162,16 +162,7 @@
+ 	 */
+ 	if ((flags & RFPROC) == 0) {
+ 
+-		/*
+-		 * Divorce the memory, if it is shared, essentially
+-		 * this changes shared memory amongst threads, into
+-		 * COW locally.
+-		 */
+-		if ((flags & RFMEM) == 0) {
+-			if (p1->p_vmspace->vm_refcnt > 1) {
+-				vmspace_unshare(p1);
+-			}
+-		}
++		vm_fork(p1, 0, flags);
+ 
+ 		/*
+ 		 * Close all file descriptors.
+Index: pc98/i386/machdep.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/pc98/i386/machdep.c,v
+retrieving revision 1.105.2.7
+diff -u -u -r1.105.2.7 machdep.c
+--- machdep.c	1999/08/29 16:31:03	1.105.2.7
++++ machdep.c	1999/09/04 20:41:41
+@@ -830,15 +830,7 @@
+ 
+ #ifdef USER_LDT
+ 	/* was i386_user_cleanup() in NetBSD */
+-	if (pcb->pcb_ldt) {
+-		if (pcb == curpcb) {
+-			lldt(_default_ldt);
+-			currentldt = _default_ldt;
+-		}
+-		kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
+-			pcb->pcb_ldt_len * sizeof(union descriptor));
+-		pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
+- 	}
++	user_ldt_free(pcb);
+ #endif
+   
+ 	bzero((char *)regs, sizeof(struct trapframe));
+Index: sys/proc.h
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/sys/proc.h,v
+retrieving revision 1.66.2.5
+diff -u -u -r1.66.2.5 proc.h
+--- proc.h	1999/08/29 16:32:36	1.66.2.5
++++ proc.h	1999/09/04 20:42:43
+@@ -375,7 +375,7 @@
+ 
+ void	cpu_exit __P((struct proc *)) __dead2;
+ void	exit1 __P((struct proc *, int)) __dead2;
+-void	cpu_fork __P((struct proc *, struct proc *));
++void	cpu_fork __P((struct proc *, struct proc *, int));
+ int	fork1 __P((struct proc *, int));
+ int	trace_req __P((struct proc *));
+ void	cpu_wait __P((struct proc *));
+Index: vm/vm_glue.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/vm/vm_glue.c,v
+retrieving revision 1.80.2.3
+diff -u -u -r1.80.2.3 vm_glue.c
+--- vm_glue.c	1999/08/29 16:33:31	1.80.2.3
++++ vm_glue.c	1999/09/04 20:43:01
+@@ -208,6 +208,21 @@
+ {
+ 	register struct user *up;
+ 
++	if ((flags & RFPROC) == 0) {
++		/*
++		 * Divorce the memory, if it is shared, essentially
++		 * this changes shared memory amongst threads, into
++		 * COW locally.
++		 */
++		if ((flags & RFMEM) == 0) {
++			if (p1->p_vmspace->vm_refcnt > 1) {
++				vmspace_unshare(p1);
++			}
++		}
++		cpu_fork(p1, p2, flags);
++		return;
++	}
++
+ 	if (flags & RFMEM) {
+ 		p2->p_vmspace = p1->p_vmspace;
+ 		p1->p_vmspace->vm_refcnt++;
+@@ -259,7 +274,7 @@
+ 	 * cpu_fork will copy and update the pcb, set up the kernel stack,
+ 	 * and make the child ready to run.
+ 	 */
+-	cpu_fork(p1, p2);
++	cpu_fork(p1, p2, flags);
+ }
+ 
+ /*
--- /dev/null	Thu Sep  9 23:47:27 1999
+++ files/patch-3.3-sys-sigtrap	Thu Sep  9 19:18:29 1999
@@ -0,0 +1,31 @@
+Index: i386/i386/trap.c
+===================================================================
+RCS file: /home/cvs/cvs/src/sys/i386/i386/trap.c,v
+retrieving revision 1.133.2.1
+diff -u -u -r1.133.2.1 trap.c
+--- trap.c	1999/08/29 16:05:56	1.133.2.1
++++ trap.c	1999/09/09 17:17:40
+@@ -57,6 +57,7 @@
+ #include <sys/signalvar.h>
+ #include <sys/syscall.h>
+ #include <sys/sysent.h>
++#include <sys/sysproto.h>
+ #include <sys/uio.h>
+ #include <sys/vmmeter.h>
+ #ifdef KTRACE
+@@ -1135,10 +1179,13 @@
+ 		break;
+ 	}
+ 
+-	if ((frame.tf_eflags & PSL_T) && !(frame.tf_eflags & PSL_VM)) {
++	if ((frame.tf_eflags & PSL_T) && !(frame.tf_eflags & PSL_VM) &&
++	    *callp->sy_call != sigreturn) {
+ 		/* Traced syscall. */
+ 		frame.tf_eflags &= ~PSL_T;
+-		trapsignal(p, SIGTRAP, 0);
++		/* tell the signal handler this is a trace trap */
++		frame.tf_trapno = T_TRCTRAP;
++		trapsignal(p, SIGTRAP, T_TRCTRAP);
+ 	}
+ 
+ 	userret(p, &frame, sticks);
--- /dev/null	Thu Sep  9 23:47:43 1999
+++ patches/patch-ba	Thu Sep  9 00:43:10 1999
@@ -0,0 +1,214 @@
+Index: Make.rules.in
+===================================================================
+RCS file: /home/wine/wine/Make.rules.in,v
+retrieving revision 1.17
+diff -u -u -r1.17 Make.rules.in
+--- Make.rules.in	1999/08/15 12:45:53	1.17
++++ Make.rules.in	1999/09/06 21:13:32
+@@ -21,7 +21,7 @@
+ CC        = @CC@
+ CPP       = @CPP@
+ CFLAGS    = @CFLAGS@
+-OPTIONS   = @OPTIONS@ -D_REENTRANT
++OPTIONS   = @OPTIONS@ -D_REENTRANT -D_THREAD_SAFE
+ X_CFLAGS  = @X_CFLAGS@
+ X_LIBS    = @X_LIBS@
+ XLIB      = @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
+@@ -81,7 +81,7 @@
+ 
+ # Implicit rules
+ 
+-.SUFFIXES:
++#.SUFFIXES:
+ .SUFFIXES: .rc .res .spec .spec.c .spec.o .glue.c $(SUFFIXES)
+ 
+ .c.o:
+Index: dlls/ntdll/exception.c
+===================================================================
+RCS file: /home/wine/wine/dlls/ntdll/exception.c,v
+retrieving revision 1.11
+diff -u -u -r1.11 exception.c
+--- dlls/ntdll/exception.c	1999/09/03 12:46:38	1.11
++++ dlls/ntdll/exception.c	1999/09/06 21:13:48
+@@ -31,6 +31,34 @@
+ # define GET_IP(context) ((LPVOID)0)
+ #endif  /* __i386__ */
+ 
++#ifdef __FreeBSD__
++/* translate BSD's sigcontext sc_trapno for TRAP_sig */
++int xlatebsdtrapno(int t)
++{
++    switch (t)
++    {
++	case T_PRIVINFLT: return 6;
++	case T_BPTFLT:	return 3;
++	case T_ARITHTRAP: return 16;
++	case T_PROTFLT:	return 13;
++	case T_TRCTRAP:	return 1;
++	case T_PAGEFLT:	return 14;
++	case T_ALIGNFLT: return 17;
++	case T_DIVIDE:	return 0;
++	case T_NMI:	return 2;
++	case T_OFLOW:	return 4;
++	case T_BOUND:	return 5;
++	case T_DNA:	return 7;
++	case T_FPOPFLT:	return 9;
++	case T_TSSFLT:	return 10;
++	case T_SEGNPFLT: return 11;
++	case T_STKFLT:	return 12;
++	case T_RESERVED: return 15;
++	default:	return 18;
++    }
++}
++#endif
++
+ /* Default hook for built-in debugger */
+ static DWORD default_hook( EXCEPTION_RECORD *rec, CONTEXT *ctx, BOOL first )
+ {
+@@ -524,7 +524,7 @@
+     }
+ #else  /* TRAP_sig */
+-# ifdef __i386
+-    if (INSTR_EmulateInstruction( &context )) return;
++# ifdef __i386__
++    if (INSTR_EmulateInstruction( &context )) goto restore;
+ # endif
+     rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;  /* generic error */
+ #endif  /* TRAP_sig */
+Index: include/sig_context.h
+===================================================================
+RCS file: /home/wine/wine/include/sig_context.h,v
+retrieving revision 1.15
+diff -u -u -r1.15 sig_context.h
+--- include/sig_context.h	1999/09/05 16:26:12	1.15
++++ include/sig_context.h	1999/09/06 21:13:49
+@@ -171,6 +171,8 @@
+ #define EFL_sig(context)     ((context)->sc_efl)
+ /* FreeBSD, see i386/i386/traps.c::trap_pfault va->err kludge  */
+ #define CR2_sig(context)     ((context)->sc_err)
++int xlatebsdtrapno(int t);
++#define TRAP_sig(context)    ((long)xlatebsdtrapno((context)->sc_trapno))
+ #endif                      
+ 
+ 
+Index: loader/signal.c
+===================================================================
+RCS file: /home/wine/wine/loader/signal.c,v
+retrieving revision 1.16
+diff -u -u -r1.16 signal.c
+--- loader/signal.c	1999/08/01 14:54:16	1.16
++++ loader/signal.c	1999/09/06 21:13:51
+@@ -84,11 +84,7 @@
+ }
+ #endif /* linux && __i386__ */
+ 
+-/* Signal stack */
+ 
+-static char SIGNAL_Stack[16384];
+-
+-
+ /**********************************************************************
+  *		SIGNAL_SetHandler
+  */
+@@ -98,6 +94,9 @@
+ 
+ #if defined(linux) && defined(__i386__)
+ 
++    /* Signal stack */
++    static char SIGNAL_Stack[16384];
++
+     struct kernel_sigaction sig_act;
+     sig_act.sa_handler = func;
+     sig_act.sa_flags   = SA_RESTART | SA_NOMASK;
+@@ -140,18 +139,6 @@
+  */
+ BOOL SIGNAL_Init(void)
+ {
+-#ifdef HAVE_WORKING_SIGALTSTACK
+-    struct sigaltstack ss;
+-    ss.ss_sp    = SIGNAL_Stack;
+-    ss.ss_size  = sizeof(SIGNAL_Stack);
+-    ss.ss_flags = 0;
+-    if (sigaltstack(&ss, NULL) < 0)
+-    {
+-        perror("sigaltstack");
+-	/* fall through on error and try it differently */
+-    }
+-#endif  /* HAVE_SIGALTSTACK */
+-    
+     /* ignore SIGPIPE so that WINSOCK can get a EPIPE error instead  */
+     signal (SIGPIPE, SIG_IGN);
+     /* automatic child reaping to avoid zombies */
+Index: scheduler/sysdeps.c
+===================================================================
+RCS file: /home/wine/wine/scheduler/sysdeps.c,v
+retrieving revision 1.15
+diff -u -u -r1.15 sysdeps.c
+--- scheduler/sysdeps.c	1999/09/03 16:45:44	1.15
++++ scheduler/sysdeps.c	1999/09/03 23:46:50
+@@ -112,6 +112,9 @@
+  */
+ void SYSDEPS_SetCurThread( TEB *teb )
+ {
++#ifdef HAVE_WORKING_SIGALTSTACK
++    struct sigaltstack ss;
++#endif  /* HAVE_SIGALTSTACK */
+ #ifdef __i386__
+     /* On the i386, the current thread is in the %fs register */
+     SET_FS( teb->teb_sel );
+@@ -119,6 +122,17 @@
+     /* FIXME: only works if there is no preemptive task-switching going on... */
+     pCurrentTeb = teb;
+ #endif  /* __i386__ */
++#ifdef HAVE_WORKING_SIGALTSTACK
++    if ((ss.ss_sp = teb->signal_stack)) {
++	ss.ss_size  = SIGNAL_STACK_SIZE;
++	ss.ss_flags = 0;
++	if (sigaltstack(&ss, NULL) < 0)
++	{
++	    perror("SYSDEPS_SetCurThread sigaltstack");
++	    /* fall through on error and try it differently */
++	}
++    }
++#endif  /* HAVE_SIGALTSTACK */
+     init_done = 1;  /* now we can use threading routines */
+ }
+ 
+Index: scheduler/thread.c
+===================================================================
+RCS file: /home/wine/wine/scheduler/thread.c,v
+retrieving revision 1.43
+diff -u -u -r1.43 thread.c
+--- scheduler/thread.c	1999/07/31 14:41:45	1.43
++++ scheduler/thread.c	1999/09/06 21:13:55
+@@ -193,6 +193,8 @@
+ 
+     if (CLIENT_InitThread()) return NULL;
+     if (!THREAD_InitTEB( &initial_teb, 0, TRUE, NULL )) return NULL;
++    /* call this again so it can set the signal stack (allocated by THREAD_InitTEB) */
++    SYSDEPS_SetCurThread( &initial_teb );
+     return &initial_teb;
+ }
+ 
+
+Index: include/sig_context.h
+===================================================================
+RCS file: /home/wine/wine/include/sig_context.h,v
+retrieving revision 1.14
+diff -u -u -r1.14 sig_context.h
+--- include/sig_context.h	1999/08/01 12:51:56	1.14
++++ include/sig_context.h	1999/09/03 23:46:37
+@@ -244,7 +244,12 @@
+          if (!fs) fs = SYSLEVEL_EmergencyTeb;                         \
+          SET_FS(fs);                           } while (0)
+ #else
+-#define HANDLER_INIT() /* nothing */
++#define HANDLER_INIT() \
++    do { int fs; GET_FS(fs); fs &= 0xffff;                      \
++         if (!IS_SELECTOR_SYSTEM(CS_sig(HANDLER_CONTEXT)))      \
++             fs = SYSLEVEL_Win16CurrentTeb;                     \
++         if (!fs) fs = SYSLEVEL_EmergencyTeb;                   \
++         SET_FS(fs);                          } while (0)
+ #endif
+ 
+ #else /* __i386__ */
--- /dev/null	Thu Sep  9 23:47:43 1999
+++ pkg/MESSAGE	Thu Sep  9 23:27:58 1999
@@ -0,0 +1,4 @@
+In order to use wine you need to build and install a new kernel with
+options USER_LDT, SYSVSHM, SYSVSEM, and SYSVMSG.  Before you do that
+you might want to apply the patches in /usr/local/share/wine to your
+kernel sources, see the README.patch there.

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199909092257.AAA18464>