[PATCH 19/19] dbghelp: added support for custom symbols

Eric Pouech eric.pouech at gmail.com
Wed Oct 6 03:02:31 CDT 2021


Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 dlls/dbghelp/dbghelp_private.h |   12 +++++
 dlls/dbghelp/module.c          |    1 
 dlls/dbghelp/symbol.c          |  106 +++++++++++++++++++++++++++++++---------
 dlls/dbghelp/type.c            |   12 +++++
 4 files changed, 107 insertions(+), 24 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 474e76d52b6..14c4336e205 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -256,6 +256,14 @@ struct symt_thunk
     THUNK_ORDINAL               ordinal;        /* FIXME: doesn't seem to be accessible */
 };
 
+struct symt_custom
+{
+    struct symt                 symt;
+    struct hash_table_elt       hash_elt;
+    DWORD64                     address;
+    DWORD                       size;
+};
+
 /* class tree */
 struct symt_array
 {
@@ -382,6 +390,7 @@ struct module
 
     /* symbols & symbol tables */
     struct vector               vsymt;
+    struct vector               vcustom_symt;
     int                         sortlist_valid;
     unsigned                    num_sorttab;    /* number of symbols with addresses */
     unsigned                    num_symbols;
@@ -791,6 +800,9 @@ extern struct symt_hierarchy_point*
                                    const char* name, ULONG_PTR address) DECLSPEC_HIDDEN;
 extern struct symt* symt_index2ptr(struct module* module, DWORD id) DECLSPEC_HIDDEN;
 extern DWORD        symt_ptr2index(struct module* module, const struct symt* sym) DECLSPEC_HIDDEN;
+extern struct symt_custom*
+                    symt_new_custom(struct module* module, const char* name,
+                                    DWORD64 addr, DWORD size) DECLSPEC_HIDDEN;
 
 /* type.c */
 extern void         symt_init_basic(struct module* module) DECLSPEC_HIDDEN;
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 826306cfb38..254bbb297d7 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -243,6 +243,7 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
     module->num_symbols       = 0;
 
     vector_init(&module->vsymt, sizeof(struct symt*), 128);
+    vector_init(&module->vcustom_symt, sizeof(struct symt*), 16);
     /* FIXME: this seems a bit too high (on a per module basis)
      * need some statistics about this
      */
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index 091ea173305..ffb0e53fdeb 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -64,35 +64,68 @@ int __cdecl symt_cmp_addr(const void* p1, const void* p2)
     return cmp_addr(a1, a2);
 }
 
+#define BASE_CUSTOM_SYMT 0x80000000
+
+/* dbghelp exposes the internal symbols/types with DWORD indexes.
+ * - custom symbols are always stored with index starting at BASE_CUSTOM_SYMT
+ * - for all the others (non custom) symbols:
+ *   + on 32bit machine, index is set to the actual adress of symt
+ *   + on 64bit machine, we have a dedicated array to store symt exposed to caller
+ *     index is the index in this array of the symbol
+ */
 DWORD             symt_ptr2index(struct module* module, const struct symt* sym)
 {
-#ifdef _WIN64
+    struct vector* vector;
+    DWORD offset;
     const struct symt** c;
-    int                 len = vector_length(&module->vsymt), i;
+    int len, i;
 
+    if (!sym) return 0;
+    if (sym->tag == SymTagCustom)
+    {
+        vector = &module->vcustom_symt;
+        offset = BASE_CUSTOM_SYMT;
+    }
+    else
+    {
+#ifdef _WIN64
+        vector = &module->vsymt;
+        offset = 1;
+#else
+        return (DWORD)sym;
+#endif
+    }
+    len = vector_length(vector);
     /* FIXME: this is inefficient */
     for (i = 0; i < len; i++)
     {
-        if (*(struct symt**)vector_at(&module->vsymt, i) == sym)
-            return i + 1;
+        if (*(struct symt**)vector_at(vector, i) == sym)
+            return i + offset;
     }
     /* not found */
-    c = vector_add(&module->vsymt, &module->pool);
+    c = vector_add(vector, &module->pool);
     if (c) *c = sym;
-    return len + 1;
-#else
-    return (DWORD)sym;
-#endif
+    return len + offset;
 }
 
 struct symt*      symt_index2ptr(struct module* module, DWORD id)
 {
+    struct vector* vector;
+    if (id >= BASE_CUSTOM_SYMT)
+    {
+        id -= BASE_CUSTOM_SYMT;
+        vector = &module->vcustom_symt;
+    }
+    else
+    {
 #ifdef _WIN64
-    if (!id-- || id >= vector_length(&module->vsymt)) return NULL;
-    return *(struct symt**)vector_at(&module->vsymt, id);
+        if (!id--) return NULL;
+        vector = &module->vsymt;
 #else
-    return (struct symt*)id;
+        return (struct symt*)id;
 #endif
+    }
+    return (id >= vector_length(vector)) ? NULL : *(struct symt**)vector_at(vector, id);
 }
 
 static BOOL symt_grow_sorttab(struct module* module, unsigned sz)
@@ -595,6 +628,25 @@ struct symt_hierarchy_point* symt_new_label(struct module* module,
     return sym;
 }
 
+struct symt_custom* symt_new_custom(struct module* module, const char* name,
+                                    DWORD64 addr, DWORD size)
+{
+    struct symt_custom*        sym;
+
+    TRACE_(dbghelp_symt)("Adding custom symbol %s:%s\n",
+                         debugstr_w(module->modulename), name);
+
+    if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
+    {
+        sym->symt.tag      = SymTagCustom;
+        sym->hash_elt.name = pool_strdup(&module->pool, name);
+        sym->address       = addr;
+        sym->size          = size;
+        symt_add_module_ht(module, (struct symt_ht*)sym);
+    }
+    return sym;
+}
+
 /* expect sym_info->MaxNameLen to be set before being called */
 static void symt_fill_sym_info(struct module_pair* pair,
                                const struct symt_function* func,
@@ -734,6 +786,10 @@ static void symt_fill_sym_info(struct module_pair* pair,
         sym_info->Flags |= SYMFLAG_THUNK;
         symt_get_address(sym, &sym_info->Address);
         break;
+    case SymTagCustom:
+        symt_get_address(sym, &sym_info->Address);
+        sym_info->Flags |= SYMFLAG_VIRTUAL;
+        break;
     default:
         symt_get_address(sym, &sym_info->Address);
         sym_info->Register = 0;
@@ -2281,30 +2337,32 @@ BOOL WINAPI SymSearchW(HANDLE hProcess, ULONG64 BaseOfDll, DWORD Index,
 BOOL WINAPI SymAddSymbol(HANDLE hProcess, ULONG64 BaseOfDll, PCSTR name,
                          DWORD64 addr, DWORD size, DWORD flags)
 {
-    WCHAR       nameW[MAX_SYM_NAME];
+    struct module_pair  pair;
+
+    TRACE("(%p %s %s %u)\n", hProcess, wine_dbgstr_a(name), wine_dbgstr_longlong(addr), size);
 
-    MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, ARRAY_SIZE(nameW));
-    return SymAddSymbolW(hProcess, BaseOfDll, nameW, addr, size, flags);
+    pair.pcs = process_find_by_handle(hProcess);
+    if (!pair.pcs) return FALSE;
+    pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
+    if (!module_get_debug(&pair)) return FALSE;
+
+    return symt_new_custom(pair.effective, name, addr, size) != NULL;
 }
 
 /******************************************************************
  *		SymAddSymbolW (DBGHELP.@)
  *
  */
-BOOL WINAPI SymAddSymbolW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR name,
+BOOL WINAPI SymAddSymbolW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR nameW,
                           DWORD64 addr, DWORD size, DWORD flags)
 {
-    struct module_pair  pair;
+    char       name[MAX_SYM_NAME];
 
-    TRACE("(%p %s %s %u)\n", hProcess, wine_dbgstr_w(name), wine_dbgstr_longlong(addr), size);
+    TRACE("(%p %s %s %u)\n", hProcess, wine_dbgstr_w(nameW), wine_dbgstr_longlong(addr), size);
 
-    pair.pcs = process_find_by_handle(hProcess);
-    if (!pair.pcs) return FALSE;
-    pair.requested = module_find_by_addr(pair.pcs, BaseOfDll, DMT_UNKNOWN);
-    if (!module_get_debug(&pair)) return FALSE;
+    WideCharToMultiByte(CP_ACP, 0, nameW, -1, name, ARRAY_SIZE(name), NULL, NULL);
 
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    return SymAddSymbol(hProcess, BaseOfDll, name, addr, size, flags);
 }
 
 /******************************************************************
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c
index b09406028e8..d41e13ef79e 100644
--- a/dlls/dbghelp/type.c
+++ b/dlls/dbghelp/type.c
@@ -99,6 +99,7 @@ const char* symt_get_name(const struct symt* sym)
     case SymTagBaseType:        return ((const struct symt_basic*)sym)->hash_elt.name;
     case SymTagLabel:           return ((const struct symt_hierarchy_point*)sym)->hash_elt.name;
     case SymTagThunk:           return ((const struct symt_thunk*)sym)->hash_elt.name;
+    case SymTagCustom:          return ((const struct symt_custom*)sym)->hash_elt.name;
     /* hierarchy tree */
     case SymTagEnum:            return ((const struct symt_enum*)sym)->hash_elt.name;
     case SymTagTypedef:         return ((const struct symt_typedef*)sym)->hash_elt.name;
@@ -166,6 +167,9 @@ BOOL symt_get_address(const struct symt* type, ULONG64* addr)
     case SymTagThunk:
         *addr = ((const struct symt_thunk*)type)->address;
         break;
+    case SymTagCustom:
+        *addr = ((const struct symt_custom*)type)->address;
+        break;
     default:
         FIXME("Unsupported sym-tag %s for get-address\n", symt_get_tag_str(type->tag));
         /* fall through */
@@ -580,6 +584,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
             case SymTagFuncDebugEnd:
             case SymTagTypedef:
             case SymTagBaseType:
+            case SymTagCustom:
                 /* for those, CHILDRENCOUNT returns 0 */
                 return tifp->Count == 0;
             default:
@@ -654,6 +659,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
         case SymTagLabel:
         case SymTagTypedef:
         case SymTagBaseType:
+        case SymTagCustom:
             X(DWORD) = 0;
             break;
         default:
@@ -730,6 +736,9 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
         case SymTagThunk:
             X(DWORD64) = ((const struct symt_thunk*)type)->size;
             break;
+        case SymTagCustom:
+            X(DWORD64) = ((const struct symt_custom*)type)->size;
+            break;
         default:
             FIXME("Unsupported sym-tag %s for get-length\n", 
                   symt_get_tag_str(type->tag));
@@ -776,6 +785,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
         case SymTagTypedef:
         case SymTagBaseClass:
         case SymTagPublicSymbol:
+        case SymTagCustom:
             X(DWORD) = symt_ptr2index(module, &module->top->symt);
             break;
         default:
@@ -835,6 +845,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
         case SymTagFuncDebugStart:
         case SymTagFuncDebugEnd:
         case SymTagLabel:
+        case SymTagCustom:
             return FALSE;
         }
         break;
@@ -907,6 +918,7 @@ BOOL symt_get_info(struct module* module, const struct symt* type,
         case SymTagCompiland:
         case SymTagUDT:
         case SymTagBaseType:
+        case SymTagCustom:
             return FALSE;
         }
         break;




More information about the wine-devel mailing list