Eric Pouech : dbghelp: Added support for locating a .dwz file (GNU extension) attached to a debug file.
Alexandre Julliard
julliard at winehq.org
Thu Sep 16 15:34:31 CDT 2021
Module: wine
Branch: master
Commit: e5dbf5f74e4ec6a3a61007afe09c34df42d7ecf7
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e5dbf5f74e4ec6a3a61007afe09c34df42d7ecf7
Author: Eric Pouech <eric.pouech at gmail.com>
Date: Thu Sep 16 11:09:51 2021 +0200
dbghelp: Added support for locating a .dwz file (GNU extension) attached to a debug file.
A DWZ file contains additional Dwarf debug information, and can be shared
across several debug info files.
Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dbghelp/image_private.h | 1 +
dlls/dbghelp/module.c | 100 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 101 insertions(+)
diff --git a/dlls/dbghelp/image_private.h b/dlls/dbghelp/image_private.h
index 83442ffb9e1..964e974e49d 100644
--- a/dlls/dbghelp/image_private.h
+++ b/dlls/dbghelp/image_private.h
@@ -194,6 +194,7 @@ struct macho64_nlist
};
BOOL image_check_alternate(struct image_file_map* fmap, const struct module* module) DECLSPEC_HIDDEN;
+struct image_file_map* image_load_debugaltlink(struct image_file_map* fmap, struct module* module) DECLSPEC_HIDDEN;
BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) DECLSPEC_HIDDEN;
BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_type mt) DECLSPEC_HIDDEN;
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index c71e016b824..826306cfb38 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -629,6 +629,106 @@ found:
return TRUE;
}
+/******************************************************************
+ * image_load_debugaltlink
+ *
+ * Handle a (potential) .gnu_debugaltlink section and the link to
+ * (another) alternate debug file.
+ * Return an heap-allocated image_file_map when the section .gnu_debugaltlink is present,
+ * and a matching debug file has been located.
+ */
+struct image_file_map* image_load_debugaltlink(struct image_file_map* fmap, struct module* module)
+{
+ struct image_section_map debugaltlink_sect;
+ const char* data;
+ struct image_file_map* fmap_link = NULL;
+ BOOL ret = FALSE;
+
+ for (; fmap; fmap = fmap->alternate)
+ {
+ if (image_find_section(fmap, ".gnu_debugaltlink", &debugaltlink_sect)) break;
+ }
+ if (!fmap)
+ {
+ TRACE("No .gnu_debugaltlink section found for %s\n", debugstr_w(module->modulename));
+ return NULL;
+ }
+
+ data = image_map_section(&debugaltlink_sect);
+ if (data != IMAGE_NO_MAP)
+ {
+ unsigned sect_len;
+ const BYTE* id;
+ /* The content of the section is:
+ * + a \0 terminated string
+ * + followed by the build-id
+ * We try loading the dwz_alternate, either as absolute path, or relative to the embedded build-id
+ */
+ sect_len = image_get_map_size(&debugaltlink_sect);
+ id = memchr(data, '\0', sect_len);
+ if (id)
+ {
+ id++;
+ fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link));
+ if (fmap_link)
+ {
+ unsigned filename_len = MultiByteToWideChar(CP_UNIXCP, 0, data, -1, NULL, 0);
+ /* Trying absolute path */
+ WCHAR* dst = HeapAlloc(GetProcessHeap(), 0, filename_len * sizeof(WCHAR));
+ if (dst)
+ {
+ MultiByteToWideChar(CP_UNIXCP, 0, data, -1, dst, filename_len);
+ ret = image_check_debug_link_gnu_id(dst, fmap_link, id, data + sect_len - (const char*)id);
+ HeapFree(GetProcessHeap(), 0, dst);
+ }
+ /* Trying relative path to build-id directory */
+ if (!ret)
+ {
+ static const WCHAR globalDebugDirW[] =
+ {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/','.','b','u','i','l','d','-','i','d','/'};
+ dst = HeapAlloc(GetProcessHeap(), 0, sizeof(globalDebugDirW) + (3 + filename_len) * sizeof(WCHAR));
+ if (dst)
+ {
+ WCHAR* p;
+
+ /* SIGH....
+ * some relative links are relative to /usr/lib/debug/.build-id, some others are from the directory
+ * where the alternate file is...
+ * so try both
+ */
+ p = memcpy(dst, globalDebugDirW, sizeof(globalDebugDirW));
+ p += ARRAY_SIZE(globalDebugDirW);
+ MultiByteToWideChar(CP_UNIXCP, 0, data, -1, p, filename_len);
+ ret = image_check_debug_link_gnu_id(dst, fmap_link, id, data + sect_len - (const char*)id);
+ if (!ret)
+ {
+ p = dst + ARRAY_SIZE(globalDebugDirW);
+ if ((const char*)id < data + sect_len)
+ {
+ *p++ = "0123456789abcdef"[*id >> 4 ];
+ *p++ = "0123456789abcdef"[*id & 0x0F];
+ }
+ *p++ = '/';
+ MultiByteToWideChar(CP_UNIXCP, 0, data, -1, p, filename_len);
+ ret = image_check_debug_link_gnu_id(dst, fmap_link, id, data + sect_len - (const char*)id);
+ }
+ HeapFree(GetProcessHeap(), 0, dst);
+ }
+ }
+ if (!ret)
+ {
+ HeapFree(GetProcessHeap(), 0, fmap_link);
+ WARN("Couldn't find a match for .gnu_debugaltlink section %s for %s\n", data, debugstr_w(module->modulename));
+ fmap_link = NULL;
+ }
+ }
+ }
+ }
+ image_unmap_section(&debugaltlink_sect);
+ if (fmap_link) TRACE("Found match .gnu_debugaltlink section for %s\n", debugstr_w(module->modulename));
+ return fmap_link;
+}
+
/******************************************************************
* image_locate_build_id_target
*
More information about the wine-cvs
mailing list