Module: wine Branch: refs/heads/master Commit: 418591c8ea512b68bcb6d4fdcdea41216e5560c0 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=418591c8ea512b68bcb6d4fd...
Author: Eric Pouech eric.pouech@wanadoo.fr Date: Mon Jan 23 16:29:21 2006 +0100
dbghelp: Started implementation of the global callback mechanism.
---
dlls/dbghelp/dbghelp.c | 79 ++++++++++++++++++++++++++++++++++++---- dlls/dbghelp/dbghelp_private.h | 8 +++- dlls/dbghelp/module.c | 29 +++++++++++++-- include/dbghelp.h | 12 ++++++ 4 files changed, 115 insertions(+), 13 deletions(-)
diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c index 94bb0e1..e0b9048 100644 --- a/dlls/dbghelp/dbghelp.c +++ b/dlls/dbghelp/dbghelp.c @@ -61,7 +61,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); * getting several of those while looking for a unique symbol. Part of the * issue is that we don't give a scope to a static variable inside a function * + C++ management - * - implement the callback notification mechanism */
unsigned dbghelp_options = SYMOPT_UNDNAME; @@ -284,6 +283,12 @@ BOOL WINAPI SymCleanup(HANDLE hProcess) */ DWORD WINAPI SymSetOptions(DWORD opts) { + struct process* pcs; + + for (pcs = process_first; pcs; pcs = pcs->next) + { + pcs_callback(pcs, CBA_SET_OPTIONS, &opts); + } return dbghelp_options = opts; }
@@ -322,6 +327,62 @@ BOOL WINAPI SymSetContext(HANDLE hProces return TRUE; }
+/****************************************************************** + * reg_cb64to32 (internal) + * + * Registered callback for converting information from 64 bit to 32 bit + */ +static BOOL CALLBACK reg_cb64to32(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 user) +{ + PSYMBOL_REGISTERED_CALLBACK cb32 = (PSYMBOL_REGISTERED_CALLBACK)(DWORD)(user >> 32); + DWORD user32 = (DWORD)user; + void* data32; + IMAGEHLP_DEFERRED_SYMBOL_LOAD64* idsl64; + IMAGEHLP_DEFERRED_SYMBOL_LOAD idsl; + + switch (action) + { + case CBA_DEBUG_INFO: + case CBA_DEFERRED_SYMBOL_LOAD_CANCEL: + case CBA_SET_OPTIONS: + case CBA_SYMBOLS_UNLOADED: + data32 = (void*)(DWORD)data; + break; + case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE: + case CBA_DEFERRED_SYMBOL_LOAD_FAILURE: + case CBA_DEFERRED_SYMBOL_LOAD_PARTIAL: + case CBA_DEFERRED_SYMBOL_LOAD_START: + idsl64 = (IMAGEHLP_DEFERRED_SYMBOL_LOAD64*)(DWORD)data; + if (!validate_addr64(idsl64->BaseOfImage)) + return FALSE; + idsl.SizeOfStruct = sizeof(idsl); + idsl.BaseOfImage = (DWORD)idsl64->BaseOfImage; + idsl.CheckSum = idsl64->CheckSum; + idsl.TimeDateStamp = idsl64->TimeDateStamp; + memcpy(idsl.FileName, idsl64->FileName, sizeof(idsl.FileName)); + idsl.Reparse = idsl64->Reparse; + data32 = &idsl; + break; + case CBA_DUPLICATE_SYMBOL: + case CBA_EVENT: + case CBA_READ_MEMORY: + default: + FIXME("No mapping for action %lu\n", action); + return FALSE; + } + return cb32(hProcess, action, (PVOID)data32, (PVOID)user32); +} + +/****************************************************************** + * pcs_callback (internal) + */ +BOOL pcs_callback(const struct process* pcs, ULONG action, void* data) +{ + TRACE("%p %lu %p\n", pcs, action, data); + if (!pcs->reg_cb) return FALSE; + return pcs->reg_cb(pcs->handle, action, (ULONG64)(DWORD_PTR)data, pcs->reg_user); +} + /*********************************************************************** * SymRegisterCallback (DBGHELP.@) */ @@ -329,9 +390,8 @@ BOOL WINAPI SymRegisterCallback(HANDLE h PSYMBOL_REGISTERED_CALLBACK CallbackFunction, PVOID UserContext) { - FIXME("(%p, %p, %p): stub\n", hProcess, CallbackFunction, UserContext); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD64 tmp = ((ULONGLONG)(DWORD)CallbackFunction << 32) | (DWORD)UserContext; + return SymRegisterCallback64(hProcess, reg_cb64to32, tmp); }
/*********************************************************************** @@ -341,10 +401,15 @@ BOOL WINAPI SymRegisterCallback64(HANDLE PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ULONG64 UserContext) { - FIXME("(%p, %p, %s): stub\n", + struct process* pcs = process_find_by_handle(hProcess); + + TRACE("(%p, %p, %s)\n", hProcess, CallbackFunction, wine_dbgstr_longlong(UserContext)); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + if (!pcs) return FALSE; + pcs->reg_cb = CallbackFunction; + pcs->reg_user = UserContext; + + return TRUE; }
/* This is imagehlp version not dbghelp !! */ diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 8d8cb70..c3e3676 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -291,6 +291,9 @@ struct process struct process* next; HANDLE handle; char* search_path; + + PSYMBOL_REGISTERED_CALLBACK64 reg_cb; + DWORD64 reg_user;
struct module* lmodules; unsigned long dbg_hdr_addr; @@ -314,8 +317,9 @@ struct line_info /* dbghelp.c */ extern struct process* process_find_by_handle(HANDLE hProcess); extern HANDLE hMsvcrt; -extern BOOL validate_addr64(DWORD64 addr); - +extern BOOL validate_addr64(DWORD64 addr); +extern BOOL pcs_callback(const struct process* pcs, ULONG action, void* data); + /* elf_module.c */ typedef BOOL (*elf_enum_modules_cb)(const char*, unsigned long addr, void* user); extern BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb, void*); diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 3c0c5d4..afd33fd 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -232,7 +232,8 @@ struct module* module_get_containee(cons */ struct module* module_get_debug(const struct process* pcs, struct module* module) { - struct module* parent; + struct module* parent; + IMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl64;
if (!module) return NULL; /* for a PE builtin, always get info from parent */ @@ -245,10 +246,28 @@ struct module* module_get_debug(const st
switch (module->type) { - case DMT_ELF: ret = elf_load_debug_info(module, NULL); break; - case DMT_PE: ret = pe_load_debug_info(pcs, module); break; + case DMT_ELF: + ret = elf_load_debug_info(module, NULL); + break; + case DMT_PE: + idsl64.SizeOfStruct = sizeof(idsl64); + idsl64.BaseOfImage = module->module.BaseOfImage; + idsl64.CheckSum = module->module.CheckSum; + idsl64.TimeDateStamp = module->module.TimeDateStamp; + strcpy(idsl64.FileName, module->module.ImageName); + idsl64.Reparse = FALSE; + idsl64.hFile = INVALID_HANDLE_VALUE; + + pcs_callback(pcs, CBA_DEFERRED_SYMBOL_LOAD_START, &idsl64); + ret = pe_load_debug_info(pcs, module); + pcs_callback(pcs, + ret ? CBA_DEFERRED_SYMBOL_LOAD_COMPLETE : CBA_DEFERRED_SYMBOL_LOAD_FAILURE, + &idsl64); + break; case DMT_VIRTUAL: /* fall through */ - default: ret = FALSE; break; + default: + ret = FALSE; + break; } if (!ret) module->module.SymType = SymNone; assert(module->module.SymType != SymDeferred); @@ -451,6 +470,8 @@ BOOL module_remove(struct process* pcs, HeapFree(GetProcessHeap(), 0, (char*)module->sources); HeapFree(GetProcessHeap(), 0, module->addr_sorttab); pool_destroy(&module->pool); + if (module->module.SymType != SymNone) + pcs_callback(pcs, CBA_SYMBOLS_UNLOADED, NULL);
for (p = &pcs->lmodules; *p; p = &(*p)->next) { diff --git a/include/dbghelp.h b/include/dbghelp.h index 9ef700c..e53b324 100644 --- a/include/dbghelp.h +++ b/include/dbghelp.h @@ -221,6 +221,7 @@ typedef struct _SOURCEFILE #define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007 #define CBA_SET_OPTIONS 0x00000008 #define CBA_EVENT 0x00000010 +#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020 #define CBA_DEBUG_INFO 0x10000000
typedef struct _IMAGEHLP_CBA_READ_MEMORY @@ -258,6 +259,17 @@ typedef struct _IMAGEHLP_DEFERRED_SYMBOL BOOLEAN Reparse; } IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
+typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 +{ + DWORD SizeOfStruct; + DWORD64 BaseOfImage; + DWORD CheckSum; + DWORD TimeDateStamp; + CHAR FileName[MAX_PATH]; + BOOLEAN Reparse; + HANDLE hFile; +} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64; + typedef struct _IMAGEHLP_DUPLICATE_SYMBOL { DWORD SizeOfStruct;