📄 symbol.c
字号:
}
}
regfree(&mod_regex);
regfree(&sym_regex);
return TRUE;
}
module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module)))
return FALSE;
/* we always ignore module name from Mask when BaseOfDll is defined */
if (Mask && (bang = strchr(Mask, '!')))
{
if (bang == Mask) return FALSE;
Mask = bang + 1;
}
compile_regex(Mask ? Mask : "*", -1, &sym_regex);
symt_enum_module(module, &sym_regex, EnumSymbolsCallback, UserContext);
regfree(&sym_regex);
return TRUE;
}
struct sym_enumerate
{
void* ctx;
PSYM_ENUMSYMBOLS_CALLBACK cb;
};
static BOOL CALLBACK sym_enumerate_cb(PSYMBOL_INFO syminfo, ULONG size, void* ctx)
{
struct sym_enumerate* se = (struct sym_enumerate*)ctx;
return (se->cb)(syminfo->Name, syminfo->Address, syminfo->Size, se->ctx);
}
/***********************************************************************
* SymEnumerateSymbols (DBGHELP.@)
*/
BOOL WINAPI SymEnumerateSymbols(HANDLE hProcess, DWORD BaseOfDll,
PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
PVOID UserContext)
{
struct sym_enumerate se;
se.ctx = UserContext;
se.cb = EnumSymbolsCallback;
return SymEnumSymbols(hProcess, BaseOfDll, NULL, sym_enumerate_cb, &se);
}
/******************************************************************
* SymFromAddr (DBGHELP.@)
*
*/
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address,
DWORD64* Displacement, PSYMBOL_INFO Symbol)
{
struct process* pcs = process_find_by_handle(hProcess);
struct module* module;
struct symt_ht* sym;
int idx;
if (!pcs) return FALSE;
module = module_find_by_addr(pcs, Address, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE;
if ((idx = symt_find_nearest(module, Address)) == -1) return FALSE;
sym = module->addr_sorttab[idx];
symt_fill_sym_info(module, &sym->symt, Symbol);
if (Displacement) *Displacement = Address - Symbol->Address;
return TRUE;
}
/******************************************************************
* SymGetSymFromAddr (DBGHELP.@)
*
*/
BOOL WINAPI SymGetSymFromAddr(HANDLE hProcess, DWORD Address,
PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
{
char buffer[sizeof(SYMBOL_INFO) + 256];
SYMBOL_INFO*si = (SYMBOL_INFO*)buffer;
size_t len;
DWORD64 Displacement64;
if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
si->SizeOfStruct = sizeof(*si);
si->MaxNameLen = 256;
if (!SymFromAddr(hProcess, Address, &Displacement64, si))
return FALSE;
if (Displacement)
*Displacement = Displacement64;
Symbol->Address = si->Address;
Symbol->Size = si->Size;
Symbol->Flags = si->Flags;
len = min(Symbol->MaxNameLength, si->MaxNameLen);
strncpy(Symbol->Name, si->Name, len);
Symbol->Name[len - 1] = '\0';
return TRUE;
}
/******************************************************************
* SymFromName (DBGHELP.@)
*
*/
BOOL WINAPI SymFromName(HANDLE hProcess, LPSTR Name, PSYMBOL_INFO Symbol)
{
struct process* pcs = process_find_by_handle(hProcess);
struct module* module;
struct hash_table_iter hti;
void* ptr;
struct symt_ht* sym = NULL;
const char* name;
TRACE("(%p, %s, %p)\n", hProcess, Name, Symbol);
if (!pcs) return FALSE;
if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
name = strchr(Name, '!');
if (name)
{
char tmp[128];
assert(name - Name < sizeof(tmp));
memcpy(tmp, Name, name - Name);
tmp[name - Name] = '\0';
module = module_find_by_name(pcs, tmp, DMT_UNKNOWN);
if (!module) return FALSE;
Name = (char*)(name + 1);
}
else module = pcs->lmodules;
/* FIXME: Name could be made out of a regular expression */
for (; module; module = (name) ? NULL : module->next)
{
if (module->module.SymType == SymNone) continue;
if (module->module.SymType == SymDeferred)
{
struct module* xmodule = module_get_debug(pcs, module);
if (!xmodule || xmodule != module) continue;
}
hash_table_iter_init(&module->ht_symbols, &hti, Name);
while ((ptr = hash_table_iter_up(&hti)))
{
sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
if (!strcmp(sym->hash_elt.name, Name))
{
symt_fill_sym_info(module, &sym->symt, Symbol);
return TRUE;
}
}
}
return FALSE;
}
/***********************************************************************
* SymGetSymFromName (DBGHELP.@)
*/
BOOL WINAPI SymGetSymFromName(HANDLE hProcess, LPSTR Name, PIMAGEHLP_SYMBOL Symbol)
{
char buffer[sizeof(SYMBOL_INFO) + 256];
SYMBOL_INFO*si = (SYMBOL_INFO*)buffer;
size_t len;
if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
si->SizeOfStruct = sizeof(*si);
si->MaxNameLen = 256;
if (!SymFromName(hProcess, Name, si)) return FALSE;
Symbol->Address = si->Address;
Symbol->Size = si->Size;
Symbol->Flags = si->Flags;
len = min(Symbol->MaxNameLength, si->MaxNameLen);
strncpy(Symbol->Name, si->Name, len);
Symbol->Name[len - 1] = '\0';
return TRUE;
}
/******************************************************************
* sym_fill_func_line_info
*
* fills information about a file
*/
BOOL symt_fill_func_line_info(struct module* module, struct symt_function* func,
DWORD addr, IMAGEHLP_LINE* line)
{
struct line_info* dli = NULL;
BOOL found = FALSE;
assert(func->symt.tag == SymTagFunction);
while ((dli = vector_iter_down(&func->vlines, dli)))
{
if (!dli->is_source_file)
{
if (found || dli->u.pc_offset > addr) continue;
line->LineNumber = dli->line_number;
line->Address = dli->u.pc_offset;
line->Key = dli;
found = TRUE;
continue;
}
if (found)
{
line->FileName = (char*)source_get(module, dli->u.source_file);
return TRUE;
}
}
return FALSE;
}
/***********************************************************************
* SymGetSymNext (DBGHELP.@)
*/
BOOL WINAPI SymGetSymNext(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
{
/* algo:
* get module from Symbol.Address
* get index in module.addr_sorttab of Symbol.Address
* increment index
* if out of module bounds, move to next module in process address space
*/
FIXME("(%p, %p): stub\n", hProcess, Symbol);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* SymGetSymPrev (DBGHELP.@)
*/
BOOL WINAPI SymGetSymPrev(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
{
FIXME("(%p, %p): stub\n", hProcess, Symbol);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/******************************************************************
* SymGetLineFromAddr (DBGHELP.@)
*
*/
BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr,
PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
{
struct process* pcs = process_find_by_handle(hProcess);
struct module* module;
int idx;
TRACE("%p %08lx %p %p\n", hProcess, dwAddr, pdwDisplacement, Line);
if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
if (!pcs) return FALSE;
module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE;
if ((idx = symt_find_nearest(module, dwAddr)) == -1) return FALSE;
if (module->addr_sorttab[idx]->symt.tag != SymTagFunction) return FALSE;
if (!symt_fill_func_line_info(module,
(struct symt_function*)module->addr_sorttab[idx],
dwAddr, Line)) return FALSE;
if (pdwDisplacement) *pdwDisplacement = dwAddr - Line->Address;
return TRUE;
}
/******************************************************************
* SymGetLinePrev (DBGHELP.@)
*
*/
BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
{
struct process* pcs = process_find_by_handle(hProcess);
struct module* module;
struct line_info* li;
BOOL in_search = FALSE;
TRACE("(%p %p)\n", hProcess, Line);
if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
if (!pcs) return FALSE;
module = module_find_by_addr(pcs, Line->Address, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE;
if (Line->Key == 0) return FALSE;
li = (struct line_info*)Line->Key;
/* things are a bit complicated because when we encounter a DLIT_SOURCEFILE
* element we have to go back until we find the prev one to get the real
* source file name for the DLIT_OFFSET element just before
* the first DLIT_SOURCEFILE
*/
while (!li->is_first)
{
li--;
if (!li->is_source_file)
{
Line->LineNumber = li->line_number;
Line->Address = li->u.pc_offset;
Line->Key = li;
if (!in_search) return TRUE;
}
else
{
if (in_search)
{
Line->FileName = (char*)source_get(module, li->u.source_file);
return TRUE;
}
in_search = TRUE;
}
}
SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
return FALSE;
}
BOOL symt_get_func_line_next(struct module* module, PIMAGEHLP_LINE line)
{
struct line_info* li;
if (line->Key == 0) return FALSE;
li = (struct line_info*)line->Key;
while (!li->is_last)
{
li++;
if (!li->is_source_file)
{
line->LineNumber = li->line_number;
line->Address = li->u.pc_offset;
line->Key = li;
return TRUE;
}
line->FileName = (char*)source_get(module, li->u.source_file);
}
return FALSE;
}
/******************************************************************
* SymGetLineNext (DBGHELP.@)
*
*/
BOOL WINAPI SymGetLineNext(HANDLE hProcess, PIMAGEHLP_LINE Line)
{
struct process* pcs = process_find_by_handle(hProcess);
struct module* module;
TRACE("(%p %p)\n", hProcess, Line);
if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
if (!pcs) return FALSE;
module = module_find_by_addr(pcs, Line->Address, DMT_UNKNOWN);
if (!(module = module_get_debug(pcs, module))) return FALSE;
if (symt_get_func_line_next(module, Line)) return TRUE;
SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
return FALSE;
}
/***********************************************************************
* SymFunctionTableAccess (DBGHELP.@)
*/
PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
{
FIXME("(%p, 0x%08lx): stub\n", hProcess, AddrBase);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* SymUnDName (DBGHELP.@)
*/
BOOL WINAPI SymUnDName(PIMAGEHLP_SYMBOL sym, LPSTR UnDecName, DWORD UnDecNameLength)
{
TRACE("(%p %s %lu): stub\n", sym, UnDecName, UnDecNameLength);
return UnDecorateSymbolName(sym->Name, UnDecName, UnDecNameLength,
UNDNAME_COMPLETE) != 0;
}
static void* und_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); }
static void und_free (void* ptr) { HeapFree(GetProcessHeap(), 0, ptr); }
/***********************************************************************
* UnDecorateSymbolName (DBGHELP.@)
*/
DWORD WINAPI UnDecorateSymbolName(LPCSTR DecoratedName, LPSTR UnDecoratedName,
DWORD UndecoratedLength, DWORD Flags)
{
/* undocumented from msvcrt */
static char* (*p_undname)(char*, const char*, int, void* (*)(size_t), void (*)(void*), unsigned short);
static WCHAR szMsvcrt[] = {'m','s','v','c','r','t','.','d','l','l',0};
TRACE("(%s, %p, %ld, 0x%08lx): stub\n",
debugstr_a(DecoratedName), UnDecoratedName, UndecoratedLength, Flags);
if (!p_undname)
{
if (!hMsvcrt) hMsvcrt = LoadLibraryW(szMsvcrt);
if (hMsvcrt) p_undname = (void*)GetProcAddress(hMsvcrt, "__unDName");
if (!p_undname) return 0;
}
if (!UnDecoratedName) return 0;
if (!p_undname(UnDecoratedName, DecoratedName, UndecoratedLength,
und_alloc, und_free, Flags))
return 0;
return strlen(UnDecoratedName);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -