[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