Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)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;
}
--
1.9.1