Re: MemoryLayoutOverride

Gavriel State <[email protected]>
Newsgroups gmane.comp.emulators.winex.devel
Message-ID <[email protected]>
Alex Lange wrote:
> I've been playing a bit with winex cvs today, but compared to the binaries, 
> "MemoryLayoutOverride" seems to be ignored in this version. Is it still 
> somehow possible to set this, or is this feature only available with the 
> binaries?

Yes, that's correct - MemoryLayoutOverride is only in the binaries due
to the fact that it's kind of an ugly hack.  It's only really needed in
Medal of Honor due to a bug in their code.

It's been posted to the list before, but here's the patch again.

Take care,
  -Gav

-- 
Gavriel State
Co-CEO & CTO
TransGaming Technologies Inc.
[email protected]
http://www.transgaming.com

Let the games begin!
memory_layout_override.diff (text/plain, 4.2 KB)
Index: port/port.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/port/port.c,v
retrieving revision 1.1
diff -u -r1.1 port.c
--- port/port.c	22 Mar 2004 14:46:55 -0000	1.1
+++ port/port.c	25 Mar 2004 18:32:03 -0000
@@ -514,6 +514,32 @@
 }
 #endif
 
+/* This function returns the address that mmap should use for any
+ * allocation where start is passed as NULL. */
+void *__memory_layout_override = NULL;
+static void *get_anon_mmap_null_address(size_t size)
+{
+    static int got_override = 0;
+    static void *low_alloc_ptr = NULL;
+    void * current_low_alloc_ptr;
+
+    if (!got_override)
+    {
+        if (__memory_layout_override)
+	{
+            low_alloc_ptr = __memory_layout_override;
+            got_override = 1;
+        }
+    }
+
+    current_low_alloc_ptr = low_alloc_ptr;
+
+    if (low_alloc_ptr)
+        low_alloc_ptr += size;
+    
+    return current_low_alloc_ptr;
+}
+
 /***********************************************************************
  *		wine_anon_mmap
  *
@@ -550,6 +576,9 @@
         return start;
 #endif
 
+    if ((start == NULL) && !(flags & MAP_FIXED))
+       start = get_anon_mmap_null_address(size);
+
     return mmap( start, size, prot, flags, fdzero, 0 );
 }
 
Index: scheduler/process.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/scheduler/process.c,v
retrieving revision 1.28
diff -u -r1.28 process.c
--- scheduler/process.c	16 Mar 2004 20:16:04 -0000	1.28
+++ scheduler/process.c	25 Mar 2004 18:32:03 -0000
@@ -141,6 +141,57 @@
 typedef WORD (WINAPI *pUserSignalProc)( UINT, DWORD, DWORD, HMODULE16 );
 
 /***********************************************************************
+ * get_config_key
+ *
+ * Get a config key from either the app-specific or the default config
+ */
+inline static DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
+                                    char *buffer, DWORD size )
+{
+    if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, buffer, &size )) return 0;
+    return RegQueryValueExA( defkey, name, 0, NULL, buffer, &size );
+}
+
+/***********************************************************************
+ * setup_memory_layout_override
+ *
+ * Check for the memory layout override setting, and set the override global 
+ */
+extern void *__memory_layout_override;
+static void setup_memory_layout_override(char *appname)
+{
+    char buffer[MAX_PATH+16] = "";
+    HKEY hkey, appkey = 0;
+    HKEY tmpkey;
+    char *p;
+
+    /* Check for the reg keys */
+    if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\memory", 0, NULL,
+                         REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL )) {
+      ERR("Cannot create config registry key\n");
+      return;
+    }
+
+   /* open the app-specific key */
+    if ((p = strrchr( appname, '/' ))) appname = p + 1;
+    if ((p = strrchr( appname, '\\' ))) appname = p + 1;
+    strcpy( buffer, appname );
+    strcat( buffer, "\\memory" );
+    if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\AppDefaults", &tmpkey ))
+    {
+        if (RegOpenKeyA( tmpkey, buffer, &appkey )) appkey = 0;
+        RegCloseKey( tmpkey );
+    }
+
+    if (!get_config_key( hkey, appkey, "MemoryLayoutOverride", buffer, sizeof(buffer) ))
+        __memory_layout_override = (void*)strtoul(buffer, NULL, 16 );
+
+    if (appkey) RegCloseKey( appkey );
+    RegCloseKey( hkey );
+}
+
+
+/***********************************************************************
  *           PROCESS_CallUserSignalProc
  *
  * FIXME:  Some of the signals aren't sent correctly!
@@ -377,6 +428,11 @@
         if (!GetLongPathNameA( full_argv0, main_exe_name, sizeof(main_exe_name) ))
             lstrcpynA( main_exe_name, full_argv0, sizeof(main_exe_name) );
     }
+    /* If the exe has a memory layout override set, we find it here and set the 
+     * override global variable.  This way, we will get windows-like memory layout for
+     * app-allocated anonymous zero-address memory maps, but not for anything that
+     * wine tried to allocate previously */
+    setup_memory_layout_override(main_exe_name);
 
     if (main_file)
     {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.