Eric Pouech : dbghelp: Detect collision by looking at module's base address in SymLoadModuleEx().
Alexandre Julliard
julliard at winehq.org
Tue Nov 16 16:32:28 CST 2021
Module: wine
Branch: master
Commit: 1465c7de2a533ea6bda9b939c54f969dac29f2bb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=1465c7de2a533ea6bda9b939c54f969dac29f2bb
Author: Eric Pouech <eric.pouech at gmail.com>
Date: Tue Nov 16 17:47:43 2021 +0100
dbghelp: Detect collision by looking at module's base address in SymLoadModuleEx().
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dbghelp/module.c | 73 +++++++++++++++++++++++++++------------------------
1 file changed, 38 insertions(+), 35 deletions(-)
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 5c439dd1d3c..64d4e3113d5 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -900,7 +900,8 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
PMODLOAD_DATA Data, DWORD Flags)
{
struct process* pcs;
- struct module* module = NULL;
+ struct module* module = NULL;
+ struct module* altmodule;
TRACE("(%p %p %s %s %s %08x %p %08x)\n",
hProcess, hFile, debugstr_w(wImageName), debugstr_w(wModuleName),
@@ -912,16 +913,6 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
if (!(pcs = process_find_by_handle(hProcess))) return 0;
- if (Flags & SLMFLAG_VIRTUAL)
- {
- if (!wImageName) return 0;
- module = module_new(pcs, wImageName, DMT_PE, TRUE, BaseOfDll, SizeOfDll, 0, 0, IMAGE_FILE_MACHINE_UNKNOWN);
- if (!module) return 0;
- if (wModuleName) module_set_module(module, wModuleName);
- module->module.SymType = SymVirtual;
-
- return module->module.BaseOfImage;
- }
if (Flags & ~(SLMFLAG_VIRTUAL))
FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName));
@@ -930,31 +921,18 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
/* this is a Wine extension to the API just to redo the synchronisation */
if (!wImageName && !hFile) return 0;
- /* check if the module is already loaded, or if it's a builtin PE module with
- * an containing ELF module
- */
- if (wImageName)
+ if (Flags & SLMFLAG_VIRTUAL)
{
- module = module_is_already_loaded(pcs, wImageName);
- if (module)
- {
- if (module->module.BaseOfImage == BaseOfDll)
- SetLastError(ERROR_SUCCESS);
- else
- {
- /* native allows to load the same module at different addresses
- * we don't support this for now
- */
- SetLastError(ERROR_INVALID_PARAMETER);
- FIXME("Reloading %s at different base address isn't supported\n", debugstr_w(module->modulename));
- }
- return 0;
- }
- if (!module && module_is_container_loaded(pcs, wImageName, BaseOfDll))
- {
- /* force the loading of DLL as builtin */
- module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
- }
+ if (!wImageName) return 0;
+ module = module_new(pcs, wImageName, DMT_PE, TRUE, BaseOfDll, SizeOfDll, 0, 0, IMAGE_FILE_MACHINE_UNKNOWN);
+ if (!module) return 0;
+ module->module.SymType = SymVirtual;
+ }
+ /* check if it's a builtin PE module with a containing ELF module */
+ else if (wImageName && module_is_container_loaded(pcs, wImageName, BaseOfDll))
+ {
+ /* force the loading of DLL as builtin */
+ module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
}
if (!module)
{
@@ -978,6 +956,31 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
module_set_module(module, wModuleName);
if (wImageName)
lstrcpynW(module->module.ImageName, wImageName, ARRAY_SIZE(module->module.ImageName));
+
+ for (altmodule = pcs->lmodules; altmodule; altmodule = altmodule->next)
+ {
+ if (altmodule != module && altmodule->type == module->type &&
+ module->module.BaseOfImage >= altmodule->module.BaseOfImage &&
+ module->module.BaseOfImage < altmodule->module.BaseOfImage + altmodule->module.ImageSize)
+ break;
+ }
+ if (altmodule)
+ {
+ /* we have a conflict as the new module cannot be found by its base address
+ * we need to get rid of one on the two modules
+ */
+ /* loading same module at same address... don't change anything */
+ if (module->module.BaseOfImage == altmodule->module.BaseOfImage)
+ {
+ module_remove(pcs, module);
+ SetLastError(ERROR_SUCCESS);
+ return 0;
+ }
+ module_remove(pcs, module);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
if ((dbghelp_options & SYMOPT_DEFERRED_LOADS) == 0)
module_load_debug(module);
return module->module.BaseOfImage;
More information about the wine-cvs
mailing list