Eric Pouech : dbghelp: Fix conversion of dwarf's basic types into dbghelp's basic types.

Alexandre Julliard julliard at winehq.org
Fri May 13 15:45:13 CDT 2022


Module: wine
Branch: master
Commit: d94f4747e877b87400d4cb0d11d1c09139ad2c87
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d94f4747e877b87400d4cb0d11d1c09139ad2c87

Author: Eric Pouech <eric.pouech at gmail.com>
Date:   Tue May 10 17:11:08 2022 +0200

dbghelp: Fix conversion of dwarf's basic types into dbghelp's basic types.

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dbghelp/dwarf.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 19c0da933d3..5c0f34d4bf5 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -213,6 +213,7 @@ typedef struct dwarf2_parse_context_s
     dwarf2_cuhead_t             head;
     enum unit_status            status;
     dwarf2_traverse_context_t   traverse_DIE;
+    unsigned                    language;
 } dwarf2_parse_context_t;
 
 /* stored in the dbghelp's module internal structure for later reuse */
@@ -1450,16 +1451,43 @@ static struct vector* dwarf2_get_di_children(dwarf2_debug_info_t* di)
     return NULL;
 }
 
+/* reconstruct whether integer is long (contains 'long' only once) */
+static BOOL is_long(const char* name)
+{
+    /* we assume name is made only of basic C keywords:
+     *    int long short unsigned signed void float double char _Bool _Complex
+     */
+    const char* p = strstr(name, "long");
+    return p && strstr(p + 4, "long") == NULL;
+}
+
+static BOOL is_c_language(dwarf2_parse_context_t* unit_ctx)
+{
+    return unit_ctx->language == DW_LANG_C ||
+        unit_ctx->language == DW_LANG_C89 ||
+        unit_ctx->language == DW_LANG_C99;
+}
+
+static BOOL is_cpp_language(dwarf2_parse_context_t* unit_ctx)
+{
+    return unit_ctx->language == DW_LANG_C_plus_plus;
+}
+
 static struct symt* dwarf2_parse_base_type(dwarf2_debug_info_t* di)
 {
     struct attribute name;
     struct attribute size;
     struct attribute encoding;
     enum BasicType bt;
+    BOOL c_language, cpp_language;
+
     if (di->symt) return di->symt;
 
     TRACE("%s\n", dwarf2_debug_di(di));
 
+    c_language = is_c_language(di->unit_ctx);
+    cpp_language = is_cpp_language(di->unit_ctx);
+
     if (!dwarf2_find_attribute(di, DW_AT_name, &name))
         name.u.string = NULL;
     if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = 0;
@@ -1472,10 +1500,19 @@ static struct symt* dwarf2_parse_base_type(dwarf2_debug_info_t* di)
     case DW_ATE_boolean:        bt = btBool; break;
     case DW_ATE_complex_float:  bt = btComplex; break;
     case DW_ATE_float:          bt = btFloat; break;
-    case DW_ATE_signed:         bt = btInt; break;
-    case DW_ATE_unsigned:       bt = btUInt; break;
-    case DW_ATE_signed_char:    bt = btChar; break;
-    case DW_ATE_unsigned_char:  bt = btChar; break;
+    case DW_ATE_signed:         bt = ((c_language || cpp_language) && is_long(name.u.string)) ? btLong : btInt; break;
+    case DW_ATE_unsigned:
+        if ((c_language || cpp_language) && is_long(name.u.string)) bt = btULong;
+        else if (cpp_language && !strcmp(name.u.string, "wchar_t")) bt = btWChar;
+        else if (cpp_language && !strcmp(name.u.string, "char8_t")) bt = btChar8;
+        else if (cpp_language && !strcmp(name.u.string, "char16_t")) bt = btChar16;
+        else if (cpp_language && !strcmp(name.u.string, "char32_t")) bt = btChar32;
+        else bt = btUInt;
+        break;
+    /* on Windows, in C, char == signed char, but not in C++ */
+    case DW_ATE_signed_char:    bt = (cpp_language && !strcmp(name.u.string, "signed char")) ? btInt : btChar; break;
+    case DW_ATE_unsigned_char:  bt = btUInt; break;
+    case DW_ATE_UTF:            bt = (size.u.uvalue == 1) ? btChar8 : (size.u.uvalue == 2 ? btChar16 : btChar32); break;
     default:                    bt = btNoType; break;
     }
     di->symt = &symt_get_basic(bt, size.u.uvalue)->symt;
@@ -1497,7 +1534,15 @@ static struct symt* dwarf2_parse_typedef(dwarf2_debug_info_t* di)
     ref_type = dwarf2_lookup_type(di);
 
     if (name.u.string)
+    {
+        /* Note: The MS C compiler has tweaks for WCHAR support.
+         *       Even if WCHAR is a typedef to wchar_t, wchar_t is emitted as btUInt/2 (it's defined as
+         *          unsigned short, so far so good), while WCHAR is emitted as btWChar/2).
+         */
+        if ((is_c_language(di->unit_ctx) || is_cpp_language(di->unit_ctx)) && !strcmp(name.u.string, "WCHAR"))
+            ref_type = &symt_get_basic(btWChar, 2)->symt;
         di->symt = &symt_new_typedef(di->unit_ctx->module_ctx->module, ref_type, name.u.string)->symt;
+    }
     if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n");
     return di->symt;
 }
@@ -2917,6 +2962,7 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx)
             unsigned int                i;
             struct attribute            stmt_list, low_pc;
             struct attribute            comp_dir;
+            struct attribute            language;
 
             if (!dwarf2_find_attribute(di, DW_AT_name, &name))
                 name.u.string = NULL;
@@ -2927,6 +2973,12 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx)
 
             if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc))
                 low_pc.u.uvalue = 0;
+
+            if (!dwarf2_find_attribute(di, DW_AT_language, &language))
+                language.u.uvalue = DW_LANG_C;
+
+            ctx->language = language.u.uvalue;
+
             ctx->compiland = symt_new_compiland(ctx->module_ctx->module, ctx->module_ctx->load_offset + low_pc.u.uvalue,
                                                 source_new(ctx->module_ctx->module, comp_dir.u.string, name.u.string));
             dwarf2_cache_cuhead(ctx->module_ctx->module->format_info[DFI_DWARF]->u.dwarf2_info, ctx->compiland, &ctx->head);




More information about the wine-cvs mailing list