From c719e68907cdea1b1dadb4e99d135474ee7b9c04 Mon Sep 17 00:00:00 2001 From: winesync Date: Fri, 11 Sep 2020 13:06:43 +0200 Subject: [PATCH] [WINESYNC] dbghelp: Read the r_debug and link_map structs corresponding to the target's architecture. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard wine commit id 99e818154a803c8cfd2478b9db3b455fc9adef30 by Zebediah Figura --- dll/win32/dbghelp/elf_module.c | 110 +++++++++++++++++++++++++-------- sdk/tools/winesync/dbghelp.cfg | 2 +- 2 files changed, 85 insertions(+), 27 deletions(-) diff --git a/dll/win32/dbghelp/elf_module.c b/dll/win32/dbghelp/elf_module.c index c43d10812c3..32ce3455db0 100644 --- a/dll/win32/dbghelp/elf_module.c +++ b/dll/win32/dbghelp/elf_module.c @@ -78,6 +78,15 @@ struct r_debug }; #endif /* HAVE_STRUCT_R_DEBUG */ +struct r_debug32 +{ + int r_version; + DWORD r_map; + Elf32_Addr r_brk; + int r_state; + Elf32_Addr r_ldbase; +}; + #ifndef HAVE_STRUCT_LINK_MAP struct link_map { @@ -88,6 +97,14 @@ struct link_map }; #endif /* HAVE_STRUCT_LINK_MAP */ +struct link_map32 +{ + Elf32_Addr l_addr; + DWORD l_name; + DWORD l_ld; + DWORD l_next, l_prev; +}; + WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); struct elf_info @@ -1648,36 +1665,77 @@ static BOOL elf_enum_modules_internal(const struct process* pcs, const WCHAR* main_name, enum_elf_modules_cb cb, void* user) { - struct r_debug dbg_hdr; - void* lm_addr; - struct link_map lm; - char bufstr[256]; - WCHAR bufstrW[MAX_PATH]; + WCHAR bufstrW[MAX_PATH]; + char bufstr[256]; + void *lm_addr; - if (!pcs->dbg_hdr_addr || - !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr, - &dbg_hdr, sizeof(dbg_hdr), NULL)) - return FALSE; - - /* Now walk the linked list. In all known ELF implementations, - * the dynamic loader maintains this linked list for us. In some - * cases the first entry doesn't appear with a name, in other cases it - * does. - */ - for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next) + if (pcs->is_64bit) { - if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL)) - return FALSE; + struct r_debug dbg_hdr; + struct link_map lm; - if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */ - lm.l_name != NULL && - ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL)) + if (!pcs->dbg_hdr_addr || + !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr, + &dbg_hdr, sizeof(dbg_hdr), NULL)) + return FALSE; + + /* Now walk the linked list. In all known ELF implementations, + * the dynamic loader maintains this linked list for us. In some + * cases the first entry doesn't appear with a name, in other cases it + * does. + */ + for (lm_addr = (void*)dbg_hdr.r_map; lm_addr; lm_addr = (void*)lm.l_next) { - bufstr[sizeof(bufstr) - 1] = '\0'; - MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, sizeof(bufstrW) / sizeof(WCHAR)); - if (main_name && !bufstrW[0]) strcpyW(bufstrW, main_name); - if (!cb(bufstrW, (unsigned long)lm.l_addr, (unsigned long)lm.l_ld, FALSE, user)) break; - } + if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL)) + return FALSE; + + if (lm.l_prev != NULL && /* skip first entry, normally debuggee itself */ + lm.l_name != NULL && + ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL)) + { + bufstr[sizeof(bufstr) - 1] = '\0'; + MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, + sizeof(bufstrW) / sizeof(WCHAR)); + if (main_name && !bufstrW[0]) strcpyW(bufstrW, main_name); + if (!cb(bufstrW, (unsigned long)lm.l_addr, (unsigned long)lm.l_ld, FALSE, user)) + break; + } + } + } + else + { + struct r_debug32 dbg_hdr; + struct link_map32 lm; + + if (!pcs->dbg_hdr_addr || + !ReadProcessMemory(pcs->handle, (void*)pcs->dbg_hdr_addr, + &dbg_hdr, sizeof(dbg_hdr), NULL)) + return FALSE; + + /* Now walk the linked list. In all known ELF implementations, + * the dynamic loader maintains this linked list for us. In some + * cases the first entry doesn't appear with a name, in other cases it + * does. + */ + for (lm_addr = (void *)(DWORD_PTR)dbg_hdr.r_map; lm_addr; + lm_addr = (void *)(DWORD_PTR)lm.l_next) + { + if (!ReadProcessMemory(pcs->handle, lm_addr, &lm, sizeof(lm), NULL)) + return FALSE; + + if (lm.l_prev && /* skip first entry, normally debuggee itself */ + lm.l_name && + ReadProcessMemory(pcs->handle, (void *)(DWORD_PTR)lm.l_name, + bufstr, sizeof(bufstr), NULL)) + { + bufstr[sizeof(bufstr) - 1] = '\0'; + MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, + sizeof(bufstrW) / sizeof(WCHAR)); + if (main_name && !bufstrW[0]) strcpyW(bufstrW, main_name); + if (!cb(bufstrW, (unsigned long)lm.l_addr, (unsigned long)lm.l_ld, FALSE, user)) + break; + } + } } #ifdef AT_SYSINFO_EHDR diff --git a/sdk/tools/winesync/dbghelp.cfg b/sdk/tools/winesync/dbghelp.cfg index 7069689f26f..0014cc129c2 100644 --- a/sdk/tools/winesync/dbghelp.cfg +++ b/sdk/tools/winesync/dbghelp.cfg @@ -3,4 +3,4 @@ directories: files: include/dbghelp.h: sdk/include/psdk/dbghelp.h tags: - wine: 7e4fd17d5b62e888fd6a3a452dc3ee22dfb74ccd + wine: 99e818154a803c8cfd2478b9db3b455fc9adef30