Fix for programs that store VirtualQueryEx results in signed integers (eg. The Borland Linker)

Troy Rollo wine at troy.rollo.name
Tue Mar 2 21:47:02 CST 2004


ChangeLog:
    Add work-around for programs that store the size from a
    VirtualQueryEx in a signed integer. This makes the Borland
    linker work. Also add comments describing how the address
    space is laid out on various versions of Windows in case
    it becomes necessary at a later time to more closely emulate
    the Windows behaviour.



-------------- next part --------------
Index: dlls/kernel/process.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/process.c,v
retrieving revision 1.46
diff -u -r1.46 process.c
--- dlls/kernel/process.c	20 Feb 2004 20:19:24 -0000	1.46
+++ dlls/kernel/process.c	3 Mar 2004 03:44:32 -0000
@@ -323,6 +323,48 @@
                     debugstr_w(name), nt->OptionalHeader.AddressOfEntryPoint );
     }
 
+   
+    /* We need to prevent the existence of a block of memory (allocated
+     * or unallocated) that exceeds 0x80000000 in size, to deal with broken
+     * programs that call VirtualQueryEx and then store the size of the block
+     * in a signed integer.
+     */
+    VirtualAlloc((LPVOID) 0x7ffff000, 0x1000, MEM_RESERVE, 0);
+
+    /* In an ideal world we would limit the address space here to what is available
+     * on Windows:
+     *
+     * Win95 series:		0x00020000-0xbfffffff
+     * NT series, 2GB mode:	0x00020000-0x7ffeffff
+     * NT series, 3GB mode:	0x00020000-0xbffeffff
+     *
+     * When NT running in 3GB mode encounters an executable that does not have the
+     * IMAGE_FILE_LARGE_ADDRESS_AWARE bit set in the file header characteristics, it
+     * reserves 0x80000000-0xbffeffff with VirtualAlloc and MEM_RESERVED.
+     *
+     * The problem with emulating this is that on Linux the top of the stack is at
+     * 0xbfffffff and below, so reserving even the balance of this range would
+     * artificially limit stack growth. We could move the stack, but it's too late
+     * to do that here because there will be pointers to things on the stack
+     * that will be affected - moving the stack would need to be done in main() in
+     * loader/main.c, which would then be responsible for moving it back (this would
+     * be done with mremap and subsequent adjustment to the stack pointer).
+     *
+     * If the stack were to be moved, it might end up at 0x00130000, expanding down,
+     * as it does on NT. This would require moving the wine-* executable to a higher
+     * address, as it currently loads at 0x00110000, and its first malloc takes its
+     * address space usage past 0x00130000.
+     *
+     * This is all possible - wine-* could be linked so as to load higher in memory,
+     * and main in loader/main.c could move the stack using mremap. This would
+     * enable a more faithful reproduction of Windows' behaviour, provided a harmless
+     * location could be found for the wine-* executable.
+     *
+     * If this were to be done, the ADDRESS_SPACE_LIMIT constant in
+     * dlls/ntdll/virtual.c might be more appropriately given as the end of the
+     * address space on the emulated operating system (requiring a variable).
+     */
+
     drive_type = GetDriveTypeW( name );
     /* don't keep the file handle open on removable media */
     if (drive_type == DRIVE_REMOVABLE || drive_type == DRIVE_CDROM)


More information about the wine-patches mailing list