From 9c1b57c3d46a39d0389444b332b24ee7bebd2a10 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Thu, 3 Nov 2005 09:51:26 +0000 Subject: [PATCH] Implemented SymEnumLines. --- dlls/dbghelp/dbghelp.spec | 1 + dlls/dbghelp/dbghelp_private.h | 13 +++++++ dlls/dbghelp/source.c | 66 ++++++++++++++++++++++++++++++++++ dlls/dbghelp/symbol.c | 13 ------- include/dbghelp.h | 13 +++++++ 5 files changed, 93 insertions(+), 13 deletions(-) diff --git a/dlls/dbghelp/dbghelp.spec b/dlls/dbghelp/dbghelp.spec index ae13ef7d6d4..898deaa5236 100644 --- a/dlls/dbghelp/dbghelp.spec +++ b/dlls/dbghelp/dbghelp.spec @@ -26,6 +26,7 @@ @ stub StackWalk64 @ stdcall StackWalk(long long long ptr ptr ptr ptr ptr ptr) @ stdcall SymCleanup(long) +@ stdcall SymEnumLines(ptr double str str ptr ptr) @ stdcall SymEnumSourceFiles(ptr double str ptr ptr) @ stub SymEnumSym @ stdcall SymEnumSymbols(ptr double str ptr ptr) diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index c114060a872..01a6b411986 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -289,6 +289,19 @@ struct process IMAGEHLP_STACK_FRAME ctx_frame; }; +struct line_info +{ + unsigned long is_first : 1, + is_last : 1, + is_source_file : 1, + line_number; + union + { + unsigned long pc_offset; /* if is_source_file isn't set */ + unsigned source_file; /* if is_source_file is set */ + } u; +}; + /* dbghelp.c */ extern struct process* process_find_by_handle(HANDLE hProcess); extern HANDLE hMsvcrt; diff --git a/dlls/dbghelp/source.c b/dlls/dbghelp/source.c index 09cb33440af..b606ae1d825 100644 --- a/dlls/dbghelp/source.c +++ b/dlls/dbghelp/source.c @@ -26,6 +26,9 @@ #include "dbghelp_private.h" #include "wine/debug.h" +#ifdef HAVE_REGEX_H +# include +#endif WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); @@ -136,3 +139,66 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, LPSTR Mask, return TRUE; } + +/****************************************************************** + * SymEnumLines (DBGHELP.@) + * + */ +BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland, + PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user) +{ + struct process* pcs; + struct module* module; + struct hash_table_iter hti; + struct symt_ht* sym; + regex_t re; + struct line_info* dli; + void* ptr; + SRCCODEINFO sci; + char* file; + + if (!cb) return FALSE; + pcs = process_find_by_handle(hProcess); + if (!pcs) return FALSE; + if (!(dbghelp_options & SYMOPT_LOAD_LINES)) return TRUE; + if (regcomp(&re, srcfile, REG_NOSUB)) + { + FIXME("Couldn't compile %s\n", srcfile); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (compiland) FIXME("Unsupported yet (filtering on compiland %s)\n", compiland); + module = module_find_by_addr(pcs, base, DMT_UNKNOWN); + if (!(module = module_get_debug(pcs, module))) return FALSE; + + sci.SizeOfStruct = sizeof(sci); + sci.ModBase = base; + + hash_table_iter_init(&module->ht_symbols, &hti, NULL); + while ((ptr = hash_table_iter_up(&hti))) + { + sym = GET_ENTRY(ptr, struct symt_ht, hash_elt); + if (sym->symt.tag != SymTagFunction) continue; + + dli = NULL; + sci.FileName[0] = '\0'; + while ((dli = vector_iter_up(&((struct symt_function*)sym)->vlines, dli))) + { + if (dli->is_source_file) + { + file = (char*)source_get(module, dli->u.source_file); + if (regexec(&re, file, 0, NULL, 0) != 0) file = ""; + strcpy(sci.FileName, file); + } + else if (sci.FileName[0]) + { + sci.Key = dli; + sci.Obj[0] = '\0'; /* FIXME */ + sci.LineNumber = dli->line_number; + sci.Address = dli->u.pc_offset; + if (!cb(&sci, user)) break; + } + } + } + return TRUE; +} diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index d5fa0862c17..923884b5403 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -40,19 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt); -struct line_info -{ - unsigned long is_first : 1, - is_last : 1, - is_source_file : 1, - line_number; - union - { - unsigned long pc_offset; /* if is_source_file isn't set */ - unsigned source_file; /* if is_source_file is set */ - } u; -}; - inline static int cmp_addr(ULONG64 a1, ULONG64 a2) { if (a1 > a2) return 1; diff --git a/include/dbghelp.h b/include/dbghelp.h index 8ec5f93c027..d6c9f444379 100644 --- a/include/dbghelp.h +++ b/include/dbghelp.h @@ -749,6 +749,19 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE, ULONG64, LPSTR, PSYM_ENUMSOURCFILES_CALLB BOOL WINAPI SymGetLineFromAddr(HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE); BOOL WINAPI SymGetLinePrev(HANDLE, PIMAGEHLP_LINE); BOOL WINAPI SymGetLineNext(HANDLE, PIMAGEHLP_LINE); +typedef struct _SRCCODEINFO +{ + DWORD SizeOfStruct; + PVOID Key; + DWORD64 ModBase; + char Obj[MAX_PATH+1]; + char FileName[MAX_PATH+1]; + DWORD LineNumber; + DWORD64 Address; +} SRCCODEINFO, *PSRCCODEINFO; + +typedef BOOL (CALLBACK* PSYM_ENUMLINES_CALLBACK)(PSRCCODEINFO, PVOID); +BOOL WINAPI SymEnumLines(HANDLE, ULONG64, PCSTR, PCSTR, PSYM_ENUMLINES_CALLBACK, PVOID); /************************* * File & image handling *