Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/dbghelp/symbol.c | 96 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 26 deletions(-)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 96a1f87..c93c412 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -1479,6 +1479,48 @@ BOOL symt_fill_func_line_info(const struct module* module, const struct symt_fun if (found) { line->FileName = (char*)source_get(module, dli->u.source_file); + + return TRUE; + } + } + return FALSE; +} + +/****************************************************************** + * sym_fill_func_line_info64W + * + * fills information about a file + */ +static BOOL symt_fill_func_line_info64W(const struct module* module, const struct symt_function* func, + DWORD64 addr, IMAGEHLP_LINEW64* line) +{ + struct line_info* dli = NULL; + BOOL found = FALSE; + int i; + + assert(func->symt.tag == SymTagFunction); + + for (i=vector_length(&func->vlines)-1; i>=0; i--) + { + dli = vector_at(&func->vlines, i); + 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) + { + char *filename = (char*)source_get(module, dli->u.source_file); + int len = lstrlenA(filename)+1; + + line->FileName = fetch_buffer(module->process, len * sizeof(WCHAR)); + + MultiByteToWideChar(CP_ACP, 0, filename, -1, line->FileName, len); + return TRUE; } } @@ -1548,16 +1590,17 @@ static void copy_line_64_from_32(IMAGEHLP_LINE64* l64, const IMAGEHLP_LINE* l32) * copy_line_W64_from_32 (internal) * */ -static void copy_line_W64_from_64(struct process* pcs, IMAGEHLP_LINEW64* l64w, const IMAGEHLP_LINE64* l64) +static void copy_line_64_from_W64(struct process* pcs, IMAGEHLP_LINE64* l64, const IMAGEHLP_LINEW64* l64w) { - unsigned len; + char path[MAX_PATH]; + unsigned len = WideCharToMultiByte(CP_ACP, 0, l64w->FileName, -1, path, MAX_PATH, NULL, NULL);
- l64w->Key = l64->Key; - l64w->LineNumber = l64->LineNumber; - len = MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, NULL, 0); - if ((l64w->FileName = fetch_buffer(pcs, len * sizeof(WCHAR)))) - MultiByteToWideChar(CP_ACP, 0, l64->FileName, -1, l64w->FileName, len); - l64w->Address = l64->Address; + l64->Key = l64w->Key; + l64->LineNumber = l64w->LineNumber; + l64->FileName = fetch_buffer(pcs, len + 1); + lstrcpyA(l64->FileName, path); + + l64->Address = l64w->Address; }
/****************************************************************** @@ -1596,23 +1639,16 @@ BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, BOOL WINAPI SymGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line) { - struct module_pair pair; - struct symt_ht* symt; + IMAGEHLP_LINEW64 line64;
TRACE("%p %s %p %p\n", hProcess, wine_dbgstr_longlong(dwAddr), pdwDisplacement, Line);
if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
- pair.pcs = process_find_by_handle(hProcess); - if (!pair.pcs) return FALSE; - pair.requested = module_find_by_addr(pair.pcs, dwAddr, DMT_UNKNOWN); - if (!module_get_debug(&pair)) return FALSE; - if ((symt = symt_find_nearest(pair.effective, dwAddr)) == NULL) return FALSE; - - if (symt->symt.tag != SymTagFunction) return FALSE; - if (!symt_fill_func_line_info(pair.effective, (struct symt_function*)symt, - dwAddr, Line)) return FALSE; - *pdwDisplacement = dwAddr - Line->Address; + line64.SizeOfStruct = sizeof(line64); + if(!SymGetLineFromAddrW64(hProcess, dwAddr, pdwDisplacement, &line64)) + return FALSE; + copy_line_64_from_W64(process_find_by_handle(hProcess), Line, &line64); return TRUE; }
@@ -1620,15 +1656,23 @@ BOOL WINAPI SymGetLineFromAddr64(HANDLE hProcess, DWORD64 dwAddr, * SymGetLineFromAddrW64 (DBGHELP.@) * */ -BOOL WINAPI SymGetLineFromAddrW64(HANDLE hProcess, DWORD64 dwAddr, +BOOL WINAPI SymGetLineFromAddrW64(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINEW64 Line) { - IMAGEHLP_LINE64 il64; + struct module_pair pair; + struct symt_ht* symt; + + pair.pcs = process_find_by_handle(hProcess); + if (!pair.pcs) return FALSE; + pair.requested = module_find_by_addr(pair.pcs, dwAddr, DMT_UNKNOWN); + if (!module_get_debug(&pair)) return FALSE; + if ((symt = symt_find_nearest(pair.effective, dwAddr)) == NULL) return FALSE; + + if (symt->symt.tag != SymTagFunction) return FALSE; + if (!symt_fill_func_line_info64W(pair.effective, (struct symt_function*)symt, + dwAddr, Line)) return FALSE; + *pdwDisplacement = dwAddr - Line->Address;
- il64.SizeOfStruct = sizeof(il64); - if (!SymGetLineFromAddr64(hProcess, dwAddr, pdwDisplacement, &il64)) - return FALSE; - copy_line_W64_from_64(process_find_by_handle(hProcess), Line, &il64); return TRUE; }
On 3/14/19 12:11 AM, Alistair Leslie-Hughes wrote:
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com
dlls/dbghelp/symbol.c | 96 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 26 deletions(-)
Is this really worth doing, if it means doing two conversions instead of one? Is there an external reason for this?