https://git.reactos.org/?p=reactos.git;a=commitdiff;h=be0572902a33f8740e8dd2...
commit be0572902a33f8740e8dd2ccfff9f94f87ce6e82 Author: winesync ros-dev@reactos.org AuthorDate: Fri Sep 11 19:12:15 2020 +0200 Commit: Jérôme Gardou jerome.gardou@reactos.org CommitDate: Wed Sep 16 10:36:00 2020 +0200
[WINESYNC] dbghelp: Use debuggee environment variables in search_dll_path.
This fixes searching wow32 binaries, where debuggee search path is different than debugger's.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
wine commit id 2b0977fc711e1faadfef69e3a46c2d1848b4826b by Jacek Caban jacek@codeweavers.com --- dll/win32/dbghelp/dbghelp.c | 83 +++++++++++++++++++++++++++++++++---- dll/win32/dbghelp/dbghelp_private.h | 5 ++- dll/win32/dbghelp/elf_module.c | 2 +- dll/win32/dbghelp/macho_module.c | 2 +- dll/win32/dbghelp/path.c | 18 ++++---- dll/win32/dbghelp/pe_module.c | 2 +- sdk/tools/winesync/dbghelp.cfg | 2 +- 7 files changed, 93 insertions(+), 21 deletions(-)
diff --git a/dll/win32/dbghelp/dbghelp.c b/dll/win32/dbghelp/dbghelp.c index 83c3a0ec10f..5a4f55f5470 100644 --- a/dll/win32/dbghelp/dbghelp.c +++ b/dll/win32/dbghelp/dbghelp.c @@ -284,6 +284,23 @@ static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOI return TRUE; }
+const WCHAR *process_getenv(const struct process *process, const WCHAR *name) +{ + size_t name_len; + const WCHAR *iter; + + if (!process->environment) return NULL; + name_len = lstrlenW(name); + + for (iter = process->environment; *iter; iter += lstrlenW(iter) + 1) + { + if (!wcsnicmp(iter, name, name_len) && iter[name_len] == '=') + return iter + name_len + 1; + } + + return NULL; +} + /****************************************************************** * check_live_target * @@ -291,7 +308,7 @@ static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOI static BOOL check_live_target(struct process* pcs) { PROCESS_BASIC_INFORMATION pbi; - ULONG_PTR base = 0; + ULONG_PTR base = 0, env = 0;
if (!GetProcessId(pcs->handle)) return FALSE; if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE; @@ -302,18 +319,67 @@ static BOOL check_live_target(struct process* pcs)
if (!pcs->is_64bit) { - PEB32 *peb32 = (PEB32 *)pbi.PebBaseAddress; - DWORD base32 = 0; - ReadProcessMemory(pcs->handle, &peb32->Reserved[0], &base32, sizeof(base32), NULL); - base = base32; + DWORD env32; + PEB32 peb32; + C_ASSERT(sizeof(void*) != 4 || FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment) == 0x48); + if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb32, sizeof(peb32), NULL)) return FALSE; + base = peb32.Reserved[0]; + if (read_process_memory(pcs, peb32.ProcessParameters + 0x48, &env32, sizeof(env32))) env = env32; } - else ReadProcessMemory(pcs->handle, &pbi.PebBaseAddress->Reserved[0], &base, sizeof(base), NULL); -#ifndef __REACTOS__ + else + { + PEB peb; + if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb, sizeof(peb), NULL)) return FALSE; + base = peb.Reserved[0]; + ReadProcessMemory(pcs->handle, &peb.ProcessParameters->Environment, &env, sizeof(env), NULL); + } + +#ifdef __REACTOS__ /* Wine store their loader base address in peb.reserved[0] and load its symbol from there. - * ReactOS does not care about it */ + * ReactOS does not care about it, we are just happy if we managed to read the value */ + base = 1; +#endif + + /* read debuggee environment block */ + if (env) + { + size_t buf_size = 0, i, last_null = -1; + WCHAR *buf = NULL; + + do + { + size_t read_size = sysinfo.dwAllocationGranularity - (env & (sysinfo.dwAllocationGranularity - 1)); + if (buf) + { + WCHAR *new_buf; + if (!(new_buf = realloc(buf, buf_size + read_size))) break; + buf = new_buf; + } + else if(!(buf = malloc(read_size))) break; + + if (!read_process_memory(pcs, env, (char*)buf + buf_size, read_size)) break; + for (i = buf_size / sizeof(WCHAR); i < (buf_size + read_size) / sizeof(WCHAR); i++) + { + if (buf[i]) continue; + if (last_null + 1 == i) + { + pcs->environment = realloc(buf, (i + 1) * sizeof(WCHAR)); + buf = NULL; + break; + } + last_null = i; + } + env += read_size; + buf_size += read_size; + } + while (buf); + free(buf); + } + if (!base) return FALSE;
TRACE("got debug info address %#lx from PEB %p\n", base, pbi.PebBaseAddress); +#ifndef __REACTOS__ return elf_read_wine_loader_dbg_info(pcs, base) || macho_read_wine_loader_dbg_info(pcs, base); #else return TRUE; @@ -476,6 +542,7 @@ BOOL WINAPI SymCleanup(HANDLE hProcess) while ((*ppcs)->lmodules) module_remove(*ppcs, (*ppcs)->lmodules);
HeapFree(GetProcessHeap(), 0, (*ppcs)->search_path); + free((*ppcs)->environment); next = (*ppcs)->next; HeapFree(GetProcessHeap(), 0, *ppcs); *ppcs = next; diff --git a/dll/win32/dbghelp/dbghelp_private.h b/dll/win32/dbghelp/dbghelp_private.h index 6faf8b8eb55..434e157c28f 100644 --- a/dll/win32/dbghelp/dbghelp_private.h +++ b/dll/win32/dbghelp/dbghelp_private.h @@ -430,6 +430,7 @@ struct process HANDLE handle; const struct loader_ops* loader; WCHAR* search_path; + WCHAR* environment;
PSYMBOL_REGISTERED_CALLBACK64 reg_cb; PSYMBOL_REGISTERED_CALLBACK reg_cb32; @@ -632,6 +633,7 @@ extern BOOL pcs_callback(const struct process* pcs, ULONG action, void* extern void* fetch_buffer(struct process* pcs, unsigned size) DECLSPEC_HIDDEN; extern const char* wine_dbgstr_addr(const ADDRESS64* addr) DECLSPEC_HIDDEN; extern struct cpu* cpu_find(DWORD) DECLSPEC_HIDDEN; +extern const WCHAR *process_getenv(const struct process *process, const WCHAR *name); extern DWORD calc_crc32(HANDLE handle) DECLSPEC_HIDDEN;
#ifndef __REACTOS__ @@ -703,7 +705,8 @@ extern BOOL path_find_symbol_file(const struct process* pcs, const struc PCSTR full_path, enum module_type type, const GUID* guid, DWORD dw1, DWORD dw2, WCHAR *buffer, BOOL* is_unmatched) DECLSPEC_HIDDEN; extern WCHAR *get_dos_file_name(const WCHAR *filename) DECLSPEC_HIDDEN; -extern BOOL search_dll_path(const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param) DECLSPEC_HIDDEN; +extern BOOL search_dll_path(const struct process* process, const WCHAR *name, + BOOL (*match)(void*, HANDLE, const WCHAR*), void *param) DECLSPEC_HIDDEN; extern BOOL search_unix_path(const WCHAR *name, const char *path, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param) DECLSPEC_HIDDEN; extern const WCHAR* file_name(const WCHAR* str) DECLSPEC_HIDDEN; extern const char* file_nameA(const char* str) DECLSPEC_HIDDEN; diff --git a/dll/win32/dbghelp/elf_module.c b/dll/win32/dbghelp/elf_module.c index 5f92432d0e8..ab2a693ecaf 100644 --- a/dll/win32/dbghelp/elf_module.c +++ b/dll/win32/dbghelp/elf_module.c @@ -1436,7 +1436,7 @@ static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename, load_elf.elf_info = elf_info;
ret = search_unix_path(filename, getenv("LD_LIBRARY_PATH"), elf_load_file_cb, &load_elf) - || search_dll_path(filename, elf_load_file_cb, &load_elf); + || search_dll_path(pcs, filename, elf_load_file_cb, &load_elf); }
return ret; diff --git a/dll/win32/dbghelp/macho_module.c b/dll/win32/dbghelp/macho_module.c index 51119593770..05549571c5e 100644 --- a/dll/win32/dbghelp/macho_module.c +++ b/dll/win32/dbghelp/macho_module.c @@ -1588,7 +1588,7 @@ static BOOL macho_search_and_load_file(struct process* pcs, const WCHAR* filenam ret = search_unix_path(p, fallback, macho_load_file_cb, &load_params); } if (!ret && p == filename) - ret = search_dll_path(filename, macho_load_file_cb, &load_params); + ret = search_dll_path(pcs, filename, macho_load_file_cb, &load_params);
return ret; } diff --git a/dll/win32/dbghelp/path.c b/dll/win32/dbghelp/path.c index d4e04ff1f40..87eeb93ae6d 100644 --- a/dll/win32/dbghelp/path.c +++ b/dll/win32/dbghelp/path.c @@ -692,19 +692,17 @@ WCHAR *get_dos_file_name(const WCHAR *filename) }
#ifndef __REACTOS__ -BOOL search_dll_path(const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param) +BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param) { + const WCHAR *env; size_t len, i; HANDLE file; WCHAR *buf; BOOL ret;
- static const WCHAR winebuilddirW[] = {'W','I','N','E','B','U','I','L','D','D','I','R',0}; - static const WCHAR winedlldirW[] = {'W','I','N','E','D','L','L','D','I','R','%','u',0}; - name = file_name(name);
- if ((len = GetEnvironmentVariableW(winebuilddirW, NULL, 0))) + if ((env = process_getenv(process, L"WINEBUILDDIR"))) { WCHAR *p, *end; const WCHAR dllsW[] = { '\','d','l','l','s','\' }; @@ -713,8 +711,11 @@ BOOL search_dll_path(const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR const WCHAR dot_exeW[] = {'.','e','x','e',0}; const WCHAR dot_soW[] = {'.','s','o',0};
+ + len = lstrlenW(env); if (!(buf = heap_alloc((len + 8 + 3 * lstrlenW(name)) * sizeof(WCHAR)))) return FALSE; - end = buf + GetEnvironmentVariableW(winebuilddirW, buf, len); + wcscpy(buf, env); + end = buf + len;
memcpy(end, dllsW, sizeof(dllsW)); lstrcpyW(end + ARRAY_SIZE(dllsW), name); @@ -753,8 +754,9 @@ BOOL search_dll_path(const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR for (i = 0;; i++) { WCHAR env_name[64]; - swprintf(env_name, ARRAY_SIZE(env_name), winedlldirW, i); - if (!(len = GetEnvironmentVariableW(env_name, NULL, 0))) break; + swprintf(env_name, ARRAY_SIZE(env_name), L"WINEDLLDIR%u", i); + if (!(env = process_getenv(process, env_name))) return FALSE; + len = lstrlenW(env); if (!(buf = heap_alloc((len + lstrlenW(name) + 2) * sizeof(WCHAR)))) return FALSE;
len = GetEnvironmentVariableW(env_name, buf, len); diff --git a/dll/win32/dbghelp/pe_module.c b/dll/win32/dbghelp/pe_module.c index 9ea60ecade4..193876263ac 100644 --- a/dll/win32/dbghelp/pe_module.c +++ b/dll/win32/dbghelp/pe_module.c @@ -823,7 +823,7 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name, { #ifndef __REACTOS__ struct builtin_search builtin = { NULL }; - if (modfmt->u.pe_info->fmap.u.pe.builtin && search_dll_path(loaded_name, search_builtin_pe, &builtin)) + if (modfmt->u.pe_info->fmap.u.pe.builtin && search_dll_path(pcs, loaded_name, search_builtin_pe, &builtin)) { TRACE("reloaded %s from %s\n", debugstr_w(loaded_name), debugstr_w(builtin.path)); image_unmap_file(&modfmt->u.pe_info->fmap); diff --git a/sdk/tools/winesync/dbghelp.cfg b/sdk/tools/winesync/dbghelp.cfg index d728bdefbc4..e8df9235796 100644 --- a/sdk/tools/winesync/dbghelp.cfg +++ b/sdk/tools/winesync/dbghelp.cfg @@ -4,4 +4,4 @@ files: include/dbghelp.h: sdk/include/psdk/dbghelp.h include/wine/mscvpdb.h: sdk/include/reactos/wine/mscvpdb.h tags: - wine: 341feeb10eddd3d139c4c206a43db80d0671ff3b + wine: 2b0977fc711e1faadfef69e3a46c2d1848b4826b