Eric Pouech : winedbg: Introduce struct data_model to describe the various models for base types.

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


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

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

winedbg: Introduce struct data_model to describe the various models for base types.

Detect data model to be used with current debuggee
PE & ELF 32 bit => ILP32
PE 64 bit       => LP64
ELF 64 bit      => LLP64

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

---

 programs/winedbg/debugger.h |   7 ++
 programs/winedbg/types.c    | 176 +++++++++++++++++++++++++++++++++++---------
 2 files changed, 150 insertions(+), 33 deletions(-)

diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 293de4c0aa5..de6c8b3e438 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -544,6 +544,13 @@ static inline void* dbg_heap_realloc(void* buffer, size_t size)
         HeapAlloc(GetProcessHeap(), 0, size);
 }
 
+struct data_model
+{
+    unsigned            base_type;
+    unsigned            size;
+    const WCHAR*        name;
+};
+
 extern struct dbg_internal_var          dbg_internal_vars[];
 
 #define  DBG_IVARNAME(_var)	dbg_internal_var_##_var
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index 50d1f1b8353..f4ee5a011d5 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -714,47 +714,157 @@ BOOL types_print_type(const struct dbg_type* type, BOOL details)
     return TRUE;
 }
 
+static const struct data_model ilp32_data_model[] = {
+    {btVoid,     0, L"void"},
+    {btChar,     1, L"char"},
+    {btWChar,    2, L"wchar_t"},
+    {btInt,      1, L"signed char"},
+    {btInt,      2, L"short int"},
+    {btInt,      4, L"int"},
+    {btInt,      8, L"__int64"},
+    {btUInt,     1, L"unsigned char"},
+    {btUInt,     2, L"unsigned short int"},
+    {btUInt,     4, L"unsigned int"},
+    {btUInt,     8, L"unsigned __int64"},
+    {btFloat,    4, L"float"},
+    {btFloat,    8, L"double"},
+    {btFloat,   10, L"long double"},
+    {btBool,     1, L"bool"},
+    {btLong,     4, L"long"},
+    {btLong,     8, L"long long"},
+    {btULong,    4, L"unsigned long"},
+    {btULong,    8, L"unsigned long long"},
+    {btHresult,  4, L"char32_t"},
+    {btChar16,   2, L"char16_t"},
+    {btChar32,   4, L"char32_t"},
+    {btChar8,    1, L"char8_t"},
+    {0,          0, NULL}
+};
+
+static const struct data_model llp64_data_model[] = {
+    {btVoid,     0, L"void"},
+    {btChar,     1, L"char"},
+    {btWChar,    2, L"wchar_t"},
+    {btInt,      1, L"signed char"},
+    {btInt,      2, L"short int"},
+    {btInt,      4, L"int"},
+    {btInt,      8, L"__int64"},
+    {btInt,     16, L"__int128"},
+    {btUInt,     1, L"unsigned char"},
+    {btUInt,     2, L"unsigned short int"},
+    {btUInt,     4, L"unsigned int"},
+    {btUInt,     8, L"unsigned __int64"},
+    {btUInt,    16, L"unsigned __int128"},
+    {btFloat,    4, L"float"},
+    {btFloat,    8, L"double"},
+    {btFloat,   10, L"long double"},
+    {btBool,     1, L"bool"},
+    {btLong,     4, L"long"},
+    {btLong,     8, L"long long"},
+    {btULong,    4, L"unsigned long"},
+    {btULong,    8, L"unsigned long long"},
+    {btHresult,  4, L"char32_t"},
+    {btChar16,   2, L"char16_t"},
+    {btChar32,   4, L"char32_t"},
+    {btChar8,    1, L"char8_t"},
+    {0,          0, NULL}
+};
+
+static const struct data_model lp64_data_model[] = {
+    {btVoid,     0, L"void"},
+    {btChar,     1, L"char"},
+    {btWChar,    2, L"wchar_t"},
+    {btInt,      1, L"signed char"},
+    {btInt,      2, L"short int"},
+    {btInt,      4, L"int"},
+    {btInt,      8, L"__int64"},
+    {btInt,     16, L"__int128"},
+    {btUInt,     1, L"unsigned char"},
+    {btUInt,     2, L"unsigned short int"},
+    {btUInt,     4, L"unsigned int"},
+    {btUInt,     8, L"unsigned __int64"},
+    {btUInt,    16, L"unsigned __int128"},
+    {btFloat,    4, L"float"},
+    {btFloat,    8, L"double"},
+    {btFloat,   10, L"long double"},
+    {btBool,     1, L"bool"},
+    {btLong,     4, L"int"}, /* to print at least for such a regular Windows' type */
+    {btLong,     8, L"long"}, /* we can't discriminate 'long' from 'long long' */
+    {btULong,    4, L"unsigned int"}, /* to print at least for such a regular Windows' type */
+    {btULong,    8, L"unsigned long"}, /* we can't discriminate 'unsigned long' from 'unsigned long long' */
+    {btHresult,  4, L"char32_t"},
+    {btChar16,   2, L"char16_t"},
+    {btChar32,   4, L"char32_t"},
+    {btChar8,    1, L"char8_t"},
+    {0,          0, NULL}
+};
+
+static const struct data_model* get_data_model(DWORD modaddr)
+{
+    const struct data_model *model;
+
+    if (ADDRSIZE == 4) model = ilp32_data_model;
+    else
+    {
+        IMAGEHLP_MODULEW64 mi;
+        DWORD opt = SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, TRUE);
+
+        mi.SizeOfStruct = sizeof(mi);
+        if (SymGetModuleInfoW64(dbg_curr_process->handle, modaddr, &mi) &&
+            (wcsstr(mi.ModuleName, L".so") || wcsstr(mi.ModuleName, L"<")))
+            model = lp64_data_model;
+        else
+            model = llp64_data_model;
+        SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, opt);
+    }
+    return model;
+}
+
 /* helper to typecast pInfo to its expected type (_t) */
 #define X(_t) (*((_t*)pInfo))
 
-BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
+static BOOL lookup_base_type_in_data_model(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
 {
-    if (type->id == dbg_itype_none) return FALSE;
-    if (type->module != 0)
+    DWORD tag, bt;
+    DWORD64 len;
+    const WCHAR* name = NULL;
+    WCHAR tmp[64];
+    const struct data_model* model;
+
+    if (ti != TI_GET_SYMNAME ||
+        !SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_SYMTAG, &tag) ||
+        tag != SymTagBaseType ||
+        !SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_BASETYPE, &bt) ||
+        !SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_LENGTH, &len) ||
+        len != (DWORD)len) return FALSE;
+
+    model = get_data_model(type->module);
+    for (; model->name; model++)
     {
-        DWORD ret, tag, bt;
-        ret = SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
-        if (!ret &&
-            ti == TI_GET_SYMNAME &&
-            SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_SYMTAG, &tag) &&
-            tag == SymTagBaseType &&
-            SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_BASETYPE, &bt))
+        if (bt == model->base_type && model->size == len)
         {
-            const WCHAR* name = NULL;
-
-            switch (bt)
-            {
-            case btVoid:        name = L"void"; break;
-            case btChar:        name = L"char"; break;
-            case btWChar:       name = L"WCHAR"; break;
-            case btInt:         name = L"int"; break;
-            case btUInt:        name = L"unsigned int"; break;
-            case btFloat:       name = L"float"; break;
-            case btBool:        name = L"bool"; break;
-            case btLong:        name = L"long int"; break;
-            case btULong:       name = L"unsigned long int"; break;
-            case btComplex:     name = L"complex"; break;
-            default:            WINE_FIXME("Unsupported basic type %lu\n", bt); return FALSE;
-            }
-            X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name) + 1) * sizeof(WCHAR));
-            if (X(WCHAR*))
-            {
-                lstrcpyW(X(WCHAR*), name);
-                ret = TRUE;
-            }
+            name = model->name;
+            break;
         }
-        return ret;
     }
+    if (!name) /* synthetize name */
+    {
+        WINE_FIXME("Unsupported basic type %lu %I64u\n", bt, len);
+        swprintf(tmp, ARRAY_SIZE(tmp), L"bt[%lu,%u]", bt, len);
+        name = tmp;
+    }
+    X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name) + 1) * sizeof(WCHAR));
+    if (X(WCHAR*))
+        lstrcpyW(X(WCHAR*), name);
+    return TRUE;
+}
+
+BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
+{
+    if (type->id == dbg_itype_none) return FALSE;
+    if (type->module != 0)
+        return lookup_base_type_in_data_model(type, ti, pInfo) ||
+            SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
 
     assert(type->id >= dbg_itype_first);
 




More information about the wine-cvs mailing list