From fc380e06914683a0d64d8c62c10c22433fc37b4a Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Thu, 16 Sep 2021 11:09:45 +0200 Subject: [PATCH] dbghelp: Separate alternate debug file lookup functions. Split in two different (and disjoint) the functions for checking that an alternate debug file matches the expected one - the first based on crc - the second based on GNU build-id Signed-off-by: Eric Pouech Signed-off-by: Alexandre Julliard --- dlls/dbghelp/module.c | 107 +++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 44 deletions(-) diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index cda12f4c350..c71e016b824 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -467,8 +467,40 @@ static BOOL module_is_container_loaded(const struct process* pcs, return FALSE; } -static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc) +static BOOL image_check_debug_link_crc(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc) { + DWORD read_bytes; + HANDLE handle; + WCHAR *path; + WORD magic; + DWORD crc; + BOOL ret; + + path = get_dos_file_name(file); + handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + heap_free(path); + if (handle == INVALID_HANDLE_VALUE) return FALSE; + + crc = calc_crc32(handle); + if (crc != link_crc) + { + WARN("Bad CRC for file %s (got %08x while expecting %08x)\n", debugstr_w(file), crc, link_crc); + CloseHandle(handle); + return FALSE; + } + + SetFilePointer(handle, 0, 0, FILE_BEGIN); + if (ReadFile(handle, &magic, sizeof(magic), &read_bytes, NULL) && magic == IMAGE_DOS_SIGNATURE) + ret = pe_map_file(handle, fmap, DMT_PE); + else + ret = elf_map_handle(handle, fmap); + CloseHandle(handle); + return ret; +} + +static BOOL image_check_debug_link_gnu_id(const WCHAR* file, struct image_file_map* fmap, const BYTE* id, unsigned idlen) +{ + struct image_section_map buildid_sect; DWORD read_bytes; HANDLE handle; WCHAR *path; @@ -480,24 +512,33 @@ static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fma heap_free(path); if (handle == INVALID_HANDLE_VALUE) return FALSE; - if (link_crc) - { - DWORD crc = calc_crc32(handle); - if (crc != link_crc) - { - WARN("Bad CRC for file %s (got %08x while expecting %08x)\n", debugstr_w(file), crc, link_crc); - CloseHandle(handle); - return FALSE; - } - } + TRACE("Located debug information file at %s\n", debugstr_w(file)); - SetFilePointer(handle, 0, 0, FILE_BEGIN); if (ReadFile(handle, &magic, sizeof(magic), &read_bytes, NULL) && magic == IMAGE_DOS_SIGNATURE) ret = pe_map_file(handle, fmap, DMT_PE); else ret = elf_map_handle(handle, fmap); CloseHandle(handle); - return ret; + + if (ret && image_find_section(fmap, ".note.gnu.build-id", &buildid_sect)) + { + const UINT32* note; + + note = (const UINT32*)image_map_section(&buildid_sect); + if (note != IMAGE_NO_MAP) + { + /* the usual ELF note structure: name-size desc-size type */ + if (note[2] == NOTE_GNU_BUILD_ID) + { + if (note[1] == idlen && !memcmp(note + 3 + ((note[0] + 3) >> 2), id, idlen)) + return TRUE; + WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(file)); + } + } + image_unmap_section(&buildid_sect); + image_unmap_file(fmap); + } + return FALSE; } /****************************************************************** @@ -548,12 +589,12 @@ static BOOL image_locate_debug_link(const struct module* module, struct image_fi /* testing execdir/filename */ MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len); - if (image_check_debug_link(p, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(p, fmap_link, crc)) goto found; /* testing execdir/.debug/filename */ memcpy(slash, dotDebugW, sizeof(dotDebugW)); MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash + ARRAY_SIZE(dotDebugW), filename_len); - if (image_check_debug_link(p, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(p, fmap_link, crc)) goto found; if (module->real_path) { @@ -562,7 +603,7 @@ static BOOL image_locate_debug_link(const struct module* module, struct image_fi if ((slash2 = wcsrchr(slash, '/'))) slash = slash2 + 1; if ((slash2 = wcsrchr(slash, '\\'))) slash = slash2 + 1; MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len); - if (image_check_debug_link(p, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(p, fmap_link, crc)) goto found; } /* testing globaldebugdir/execdir/filename */ @@ -570,10 +611,10 @@ static BOOL image_locate_debug_link(const struct module* module, struct image_fi memcpy(p, globalDebugDirW, globalDebugDirLen * sizeof(WCHAR)); slash += globalDebugDirLen; MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len); - if (image_check_debug_link(p, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(p, fmap_link, crc)) goto found; /* finally testing filename */ - if (image_check_debug_link(slash, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(slash, fmap_link, crc)) goto found; WARN("Couldn't locate or map %s\n", filename); @@ -632,33 +673,11 @@ static BOOL image_locate_build_id_target(struct image_file_map* fmap, const BYTE memcpy(z, dotDebug0W, sizeof(dotDebug0W)); TRACE("checking %s\n", wine_dbgstr_w(p)); - if (image_check_debug_link(p, fmap_link, 0)) + if (image_check_debug_link_gnu_id(p, fmap_link, idend - idlen, idlen)) { - struct image_section_map buildid_sect; - if (image_find_section(fmap_link, ".note.gnu.build-id", &buildid_sect)) - { - const UINT32* note; - - note = (const UINT32*)image_map_section(&buildid_sect); - if (note != IMAGE_NO_MAP) - { - /* the usual ELF note structure: name-size desc-size type */ - if (note[2] == NOTE_GNU_BUILD_ID) - { - if (note[1] == idlen && - !memcmp(note + 3 + ((note[0] + 3) >> 2), idend - idlen, idlen)) - { - TRACE("Located debug information file at %s\n", debugstr_w(p)); - HeapFree(GetProcessHeap(), 0, p); - fmap->alternate = fmap_link; - return TRUE; - } - WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(p)); - } - } - image_unmap_section(&buildid_sect); - } - image_unmap_file(fmap_link); + HeapFree(GetProcessHeap(), 0, p); + fmap->alternate = fmap_link; + return TRUE; } TRACE("not found\n");