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:
parent
841083898b
commit
b6044788ea
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue