Signed-off-by: Eric Pouech eric.pouech@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;