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)
{