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 <eric.pouech@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Eric Pouech 2021-09-16 11:09:45 +02:00 committed by Alexandre Julliard
parent c58d9cf744
commit fc380e0691
1 changed files with 63 additions and 44 deletions

View File

@ -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 <name> <desc> */
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 <name> <desc> */
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");