libwine: Make addresses above 0x82000000 available on FreeBSD.

Tijl Coosemans tijl at coosemans.org
Mon Sep 20 16:20:00 CDT 2010


On Monday 20 September 2010 15:10:58 Alexandre Julliard wrote:
> Tijl Coosemans <tijl at coosemans.org> writes:
>> With this patch it is possible that a .dll.so is loaded beyond the
>> 2GiB limit, but this does not seem to be a problem in practice. All
>> mmap calls from within Wine and thus all .dll stay below 2GiB and core
>> .dll.so such as ntdll, kernel32, user32,... are also loaded below 2GiB
>> because they are loaded early and are placed in the 32MiB mentioned
>> above. Also note that a .dll.so is only loaded above 2GiB when needed,
>> i.e. the program wouldn't have worked at all without this patch. It is
>> preferred that Wine at least makes an attempt at running the program
>> and therefore loosens the restriction on the use of addresses above
>> 2GiB, especially since it seems to work so far.
>
> It would be better to fix this properly. If there's no way to convince
> FreeBSD's mmap to use all available space, you'll have to move the
> loader down to make some room.

I've attached a patch that takes a different approach. I still need to
test it more extensively, but is this patch acceptable in principle?

It adds an mmap symbol to the loader thereby overriding the libc symbol.
This captures all calls to libc mmap and allows modifying the address
argument if needed. It doesn't capture cases that call the kernel
syscall directly, so shared libraries for instance are all still loaded
in the narrow address space close to the 2GiB boundary. This patch also
increases that space to 48MiB. It might work, but needs more testing.
-------------- next part --------------
diff --git a/libs/wine/mmap.c b/libs/wine/mmap.c
index b400189..296ffa9 100644
--- a/libs/wine/mmap.c
+++ b/libs/wine/mmap.c
@@ -200,11 +200,6 @@ void *wine_anon_mmap( void *start, size_t size, int prot, int flags )
 
     if (!(flags & MAP_FIXED))
     {
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-        /* Even FreeBSD 5.3 does not properly support NULL here. */
-        if( start == NULL ) start = (void *)0x110000;
-#endif
-
 #ifdef MAP_TRYFIXED
         /* If available, this will attempt a fixed mapping in-kernel */
         flags |= MAP_TRYFIXED;
diff --git a/loader/main.c b/loader/main.c
index 628a0fa..2b731a2 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -164,14 +164,30 @@ static int pre_exec(void)
     return 1;
 }
 
-#elif defined(__FreeBSD__) && defined(__i386__)
+#elif (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && defined(__i386__)
+
+#include <dlfcn.h>
+
+static void *_mmap_init( void *addr, size_t len, int prot, int flags, int fd, off_t offset );
+static void *( *_mmap )( void *addr, size_t len, int prot, int flags, int fd, off_t offset ) = _mmap_init;
+
+static void *_mmap_init( void *addr, size_t len, int prot, int flags, int fd, off_t offset ) {
+    _mmap = ( void *( * )( void *, size_t, int, int, int, off_t )) dlsym( RTLD_NEXT, "mmap" );
+    return( _mmap( addr, len, prot, flags, fd, offset ));
+}
+
+void *mmap( void *addr, size_t len, int prot, int flags, int fd, off_t offset ) {
+    if ((flags & MAP_FIXED) == 0 && addr == NULL )
+        addr = (void *)0x110000;
+    return( _mmap( addr, len, prot, flags, fd, offset ));
+}
 
 static int pre_exec(void)
 {
     struct rlimit rl;
 
-    rl.rlim_cur = 0x02000000;
-    rl.rlim_max = 0x02000000;
+    rl.rlim_cur = 0x01000000;
+    rl.rlim_max = 0x01000000;
     setrlimit( RLIMIT_DATA, &rl );
     return 1;
 }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 228 bytes
Desc: This is a digitally signed message part.
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20100920/c2f12b81/attachment.pgp>


More information about the wine-devel mailing list