dbghelp: Fix NameLen usage in SYMBOL_INFO(W).

SYMBOL_INFO.NameLen should be the actual length of the symbol, not the
length of the (potentially truncated) string returned in
SYMBOL_INFO.Name. Add an helper (symbol_setname) to set those fields
properly.

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-08-30 09:24:04 +02:00 committed by Alexandre Julliard
parent 8a3e0d686e
commit d268cb028a
3 changed files with 37 additions and 22 deletions

View File

@ -704,6 +704,7 @@ extern WCHAR* symt_get_nameW(const struct symt* sym) DECLSPEC_HIDDEN;
extern BOOL symt_get_address(const struct symt* type, ULONG64* addr) DECLSPEC_HIDDEN;
extern int __cdecl symt_cmp_addr(const void* p1, const void* p2) DECLSPEC_HIDDEN;
extern void copy_symbolW(SYMBOL_INFOW* siw, const SYMBOL_INFO* si) DECLSPEC_HIDDEN;
extern void symbol_setname(SYMBOL_INFO* si, const char* name) DECLSPEC_HIDDEN;
extern struct symt_ht*
symt_find_nearest(struct module* module, DWORD_PTR addr) DECLSPEC_HIDDEN;
extern struct symt_compiland*

View File

@ -35,6 +35,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
extern char * CDECL __unDName(char *buffer, const char *mangled, int len,
void * (CDECL *pfn_alloc)(size_t), void (CDECL *pfn_free)(void *), unsigned short flags);
static const WCHAR starW[] = {'*','\0'};
static inline int cmp_addr(ULONG64 a1, ULONG64 a2)
@ -561,6 +564,7 @@ static void symt_fill_sym_info(struct module_pair* pair,
{
const char* name;
DWORD64 size;
char* tmp;
if (!symt_get_info(pair->effective, sym, TI_GET_TYPE, &sym_info->TypeIndex))
sym_info->TypeIndex = 0;
@ -697,17 +701,16 @@ static void symt_fill_sym_info(struct module_pair* pair,
sym_info->Scope = 0; /* FIXME */
sym_info->Tag = sym->tag;
name = symt_get_name(sym);
if (sym_info->MaxNameLen)
if (sym_info->MaxNameLen &&
sym->tag == SymTagPublicSymbol && (dbghelp_options & SYMOPT_UNDNAME) &&
(tmp = __unDName(NULL, name, 0, malloc, free, UNDNAME_NAME_ONLY)) != NULL)
{
if (sym->tag != SymTagPublicSymbol || !(dbghelp_options & SYMOPT_UNDNAME) ||
((sym_info->NameLen = UnDecorateSymbolName(name, sym_info->Name,
sym_info->MaxNameLen, UNDNAME_NAME_ONLY)) == 0))
{
sym_info->NameLen = min(strlen(name), sym_info->MaxNameLen - 1);
memcpy(sym_info->Name, name, sym_info->NameLen);
sym_info->Name[sym_info->NameLen] = '\0';
}
symbol_setname(sym_info, tmp);
free(tmp);
}
else
symbol_setname(sym_info, name);
TRACE_(dbghelp_symt)("%p => %s %u %s\n",
sym, sym_info->Name, sym_info->Size,
wine_dbgstr_longlong(sym_info->Address));
@ -992,6 +995,29 @@ static BOOL symt_enum_locals(struct process* pcs, const WCHAR* mask,
return FALSE;
}
/**********************************************************
* symbol_setname
*
* Properly sets Name and NameLen in SYMBOL_INFO
* according to MaxNameLen value
*/
void symbol_setname(SYMBOL_INFO* sym_info, const char* name)
{
SIZE_T len = 0;
if (name)
{
sym_info->NameLen = strlen(name);
if (sym_info->MaxNameLen)
{
len = min(sym_info->NameLen, sym_info->MaxNameLen - 1);
memcpy(sym_info->Name, name, len);
}
}
else
sym_info->NameLen = 0;
sym_info->Name[len] = '\0';
}
/******************************************************************
* copy_symbolW
*
@ -1811,9 +1837,6 @@ BOOL WINAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym, PSTR UnDecName, DWORD UnDecName
UNDNAME_COMPLETE) != 0;
}
extern char * CDECL __unDName(char *buffer, const char *mangled, int len,
void * (CDECL *pfn_alloc)(size_t), void (CDECL *pfn_free)(void *), unsigned short flags);
/***********************************************************************
* UnDecorateSymbolName (DBGHELP.@)
*/

View File

@ -450,7 +450,6 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
struct module_pair pair;
char buffer[sizeof(SYMBOL_INFO) + 256];
SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
const char* tmp;
struct symt* type;
DWORD64 size;
unsigned int i;
@ -480,15 +479,7 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
sym_info->Register = 0; /* FIXME */
sym_info->Scope = 0; /* FIXME */
sym_info->Tag = type->tag;
tmp = symt_get_name(type);
if (tmp)
{
sym_info->NameLen = min(strlen(tmp),sym_info->MaxNameLen-1);
memcpy(sym_info->Name, tmp, sym_info->NameLen);
sym_info->Name[sym_info->NameLen] = '\0';
}
else
sym_info->Name[sym_info->NameLen = 0] = '\0';
symbol_setname(sym_info, symt_get_name(type));
if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break;
}
return TRUE;