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