[PATCH 2/2] dbghelp: handle the case where loader isn't what WINELOADER reports
Eric Pouech
eric.pouech at gmail.com
Thu Sep 2 04:08:27 CDT 2021
use case, in a WoW setup:
wine programs/winedbg/winedbg.exe.so notepad.exe
where both winedbg and notepad are 64bit exec:s
in this case, dbghelp (loaded from winedbg) reads '<...>/wine' from WINELOADER
windows env block inside notepad
(but the unix env block is correctly set to wine64 by the tweak in
ntdll/unix/loader.c)
as a consequence dbghelp doesn't get the ELF information (it tries to read 32bit
ELF entities, and fails); hence misses all the loaded ELF libraries
winedbg's command 'info share' only reports the PE modules
note: the 'dual' case
wine64 programs/winedbg/winedbg.exe.so c:\\windows\\syswow64\\notepad.exe
where winedbg is a 64bit exec and notepad a 32bit
shows the same failures
workaround this in dbghelp by tweaking the value of WINELOADER whether
the debuggee is 32 or 64bit
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
---
dlls/dbghelp/elf_module.c | 10 ++++++++--
dlls/dbghelp/macho_module.c | 10 +++++++++-
dlls/dbghelp/module.c | 28 +++++++++++++++++++++++++---
3 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index d1a4454e043..1cbd14aafb9 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -1752,10 +1752,16 @@ static const struct loader_ops elf_loader_ops =
BOOL elf_read_wine_loader_dbg_info(struct process* pcs, ULONG_PTR addr)
{
struct elf_info elf_info;
- BOOL ret;
+ BOOL ret = FALSE;
+ const WCHAR* loader;
elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
- ret = elf_search_and_load_file(pcs, get_wine_loader_name(pcs), addr, 0, &elf_info);
+ loader = get_wine_loader_name(pcs);
+ if (loader)
+ {
+ ret = elf_search_and_load_file(pcs, loader, addr, 0, &elf_info);
+ HeapFree(GetProcessHeap(), 0, (void*)loader);
+ }
if (!ret || !elf_info.dbg_hdr_addr) return FALSE;
TRACE("Found ELF debug header %#lx\n", elf_info.dbg_hdr_addr);
diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c
index 602f7e45c14..144e0c666fc 100644
--- a/dlls/dbghelp/macho_module.c
+++ b/dlls/dbghelp/macho_module.c
@@ -1885,7 +1885,15 @@ static BOOL macho_search_loader(struct process* pcs, struct macho_info* macho_in
}
}
- if (!ret) ret = macho_search_and_load_file(pcs, get_wine_loader_name(pcs), 0, macho_info);
+ if (!ret)
+ {
+ const WCHAR* loader = get_wine_loader_name(pcs);
+ if (loader)
+ {
+ ret = macho_search_and_load_file(pcs, loader, 0, macho_info);
+ HeapFree(GetProcessHeap(), 0, (void*)loader);
+ }
+ }
return ret;
}
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index c278a627d37..709744bd7ea 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -140,10 +140,32 @@ void module_set_module(struct module* module, const WCHAR* name)
/* Returned string must be freed by caller */
const WCHAR *get_wine_loader_name(struct process *pcs)
{
- const WCHAR *name = process_getenv(pcs, L"WINELOADER");
+ const WCHAR *name;
+ WCHAR* altname;
+ unsigned len;
+
+ name = process_getenv(pcs, L"WINELOADER");
if (!name) name = pcs->is_64bit ? L"wine64" : L"wine";
- TRACE("returning %s\n", debugstr_w(name));
- return name;
+ len = lstrlenW(name);
+
+ /* WINELOADER isn't properly updated in Wow64 process calling inside Windows env block
+ * (it's updated in ELF env block though)
+ * So do the adaptation ourselves.
+ */
+ altname = HeapAlloc(GetProcessHeap(), 0, (len + 2 + 1) * sizeof(WCHAR));
+ if (altname)
+ {
+ memcpy(altname, name, len * sizeof(WCHAR));
+ if (pcs->is_64bit && len >= 2 && memcmp(name + len - 2, L"64", 2 * sizeof(WCHAR)) != 0)
+ lstrcpyW(altname + len, L"64");
+ else if (!pcs->is_64bit && len >= 2 && !memcmp(name + len - 2, L"64", 2 * sizeof(WCHAR)))
+ altname[len - 2] = '\0';
+ else
+ altname[len] = '\0';
+ }
+
+ TRACE("returning %s\n", debugstr_w(altname));
+ return altname;
}
static const char* get_module_type(enum module_type type, BOOL virtual)
More information about the wine-devel
mailing list