Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Aug 2004 02:11:27 -0400
From:      Brian Fundakowski Feldman <green@freebsd.org>
To:        Anish Mistry <mistry.7@osu.edu>
Cc:        freebsd-current@freebsd.org
Subject:   Re: FreeBSD and wine mmap
Message-ID:  <20040829061127.GG1047@green.homeunix.org>
In-Reply-To: <20040829045911.GF1047@green.homeunix.org>
References:  <200407271731.12282.mistry.7@osu.edu> <200408041828.26762.mistry.7@osu.edu> <20040804223937.GA99521@freebsd3.cimlogic.com.au> <200408101353.22714.mistry.7@osu.edu> <20040829045911.GF1047@green.homeunix.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Aug 29, 2004 at 12:59:11AM -0400, Brian Fundakowski Feldman wrote:
> On Tue, Aug 10, 2004 at 01:53:14PM -0400, Anish Mistry wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> > 
> > On Wednesday 04 August 2004 06:39 pm, you wrote:
> > > On Wed, Aug 04, 2004 at 06:28:02PM -0400, Anish Mistry wrote:
> > > > Ok, so we need something like vm_map_findspace(), but for process address
> > > > mapping?  ie. pmap_findspace() that will return an address to a large
> > > > enough free chunk?
> > >
> > > That's a good start, just to get something to work with. How this fits in
> > > with the vm code and whether it is ultimately suitable in the long run is
> > > probably up to Alan Cox. For now, just get something that (a) doesn't break
> > > anything else; and (b) lets Wine behave the way it needs to.
> > >
> > > AFAIK, there are still pthread issues with Wine, but those can't be
> > > addressed until the mmap issue has a work-around.
> > I've got a small patch that gets by the initial problem about not being to 
> > mmap the memory for the libraries, but the addresses that are mmap'ed seem to 
> > seem to overlap with memory that the current pthread implementation want to 
> > mmap for the "red zone" when wine tries to create a thread.  It can't mmap 
> > the "red zone" addresses since all those address mapping where gobbled up 
> > before the thread launched.
> > I'll try to figure out a way to maybe leave a space for the "red zone" and see 
> > if that works.
> > Someone who actually knows what they are doing should probably take a look.
> 
> The red pages are implemented by leaving the memory space unallocated;
> I don't like that one bit -- this will cause those spaces to be allocated
> but given no protection, which should provide the crash feature that the
> guard pages are there for, but be less bogus (and it doesn't use more
> "memory," but it will use a few more vm_map_entrys.
> 
> Index: lib/libpthread/thread/thr_stack.c
> ===================================================================
> RCS file: /usr/ncvs/src/lib/libpthread/thread/thr_stack.c,v
> retrieving revision 1.8
> diff -u -r1.8 thr_stack.c
> --- lib/libpthread/thread/thr_stack.c	14 Sep 2003 22:39:44 -0000	1.8
> +++ lib/libpthread/thread/thr_stack.c	29 Aug 2004 04:50:28 -0000
> @@ -214,6 +214,17 @@
>  		     stacksize, PROT_READ | PROT_WRITE, MAP_STACK,
>  		     -1, 0)) == MAP_FAILED)
>  			attr->stackaddr_attr = NULL;
> +		if (attr->stackaddr_attr != NULL) {
> +			void *red;
> +
> +			red = mmap((char *)attr->stackaddr_attr + stacksize,
> +			    _thr_guard_default, PROT_NONE,
> +			    MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0);
> +			if (red == MAP_FAILED) {
> +				(void)munmap(attr->stackaddr_attr, stacksize);
> +				attr->stackaddr_attr = NULL;
> +			}
> +		}
>  	}
>  	if (attr->stackaddr_attr != NULL)
>  		return (0);
> 

BTW, I think you could also use something like this instead of giving
the kernel questionable mmap(2) policy.  I haven't compiled/tested
this one due to lack of a breaking WINE application (but the
libpthread change I know seems to work fine.)

--- map_object.c	Sun Aug 29 02:02:54 2004
+++ map_object.c.new	Sun Aug 29 02:09:22 2004
@@ -152,6 +152,16 @@
 
     mapbase = mmap(base_addr, mapsize, convert_prot(segs[0]->p_flags),
       convert_flags(segs[0]->p_flags), fd, base_offset);
+    /*
+     * If the entire area above the ELF data space is already allocated,
+     * go ahead and try the area before the text (and everything else);
+     * skip the first 1024 pages to not allocate any values "near" NULL
+     * thus hiding NULL pointer errors.
+     */
+    if (mapbase == (caddr_t) -1 && base_addr == NULL)
+        mapbase = mmap(getpagesize() << 10, mapsize,
+	  convert_prot(segs[0]->p_flags), convert_flags(segs[0]->p_flags),
+	  fd, base_offset);
     if (mapbase == (caddr_t) -1) {
 	_rtld_error("%s: mmap of entire address space failed: %s",
 	  path, strerror(errno));


-- 
Brian Fundakowski Feldman                           \'[ FreeBSD ]''''''''''\
  <> green@FreeBSD.org                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\



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