dbghelp: Added support for custom symbols.

Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Eric Pouech 2021-10-06 10:02:31 +02:00 committed by Alexandre Julliard
parent 841083898b
commit b6044788ea
4 changed files with 111 additions and 28 deletions

View file

@ -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;

View file

@ -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
*/

View file

@ -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;
@ -2280,31 +2336,33 @@ 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];
MultiByteToWideChar(CP_ACP, 0, name, -1, nameW, ARRAY_SIZE(nameW));
return SymAddSymbolW(hProcess, BaseOfDll, nameW, addr, size, flags);
}
/******************************************************************
* SymAddSymbolW (DBGHELP.@)
*
*/
BOOL WINAPI SymAddSymbolW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR name,
DWORD64 addr, DWORD size, DWORD flags)
{
struct module_pair pair;
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_a(name), 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;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
return symt_new_custom(pair.effective, name, addr, size) != NULL;
}
/******************************************************************
* SymAddSymbolW (DBGHELP.@)
*
*/
BOOL WINAPI SymAddSymbolW(HANDLE hProcess, ULONG64 BaseOfDll, PCWSTR nameW,
DWORD64 addr, DWORD size, DWORD flags)
{
char name[MAX_SYM_NAME];
TRACE("(%p %s %s %u)\n", hProcess, wine_dbgstr_w(nameW), wine_dbgstr_longlong(addr), size);
WideCharToMultiByte(CP_ACP, 0, nameW, -1, name, ARRAY_SIZE(name), NULL, NULL);
return SymAddSymbol(hProcess, BaseOfDll, name, addr, size, flags);
}
/******************************************************************

View file

@ -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;