From: Evan Tang etang@codeweavers.com
--- programs/winedbg/debugger.h | 11 ++++++++ programs/winedbg/tgt_active.c | 2 ++ programs/winedbg/winedbg.c | 48 +++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+)
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index c4c0402ef5f..8e00770917c 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -246,6 +246,12 @@ struct dbg_thread BOOL suspended; };
+struct dbg_module +{ + struct list entry; + DWORD_PTR base; +}; + struct dbg_delayed_bp { BOOL is_symbol; @@ -271,6 +277,7 @@ struct dbg_process void* pio_data; const WCHAR* imageName; struct list threads; + struct list modules; struct backend_cpu* be_cpu; HANDLE event_on_first_exception; BOOL active_debuggee; @@ -522,6 +529,10 @@ extern void dbg_del_process(struct dbg_process* p); struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid, HANDLE h, void* teb); extern struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid); extern void dbg_del_thread(struct dbg_thread* t); +extern struct dbg_module* dbg_add_module(struct dbg_process* p, DWORD_PTR base); +extern struct dbg_module* dbg_get_module(struct dbg_process* p, DWORD_PTR base); +extern void dbg_del_module(struct dbg_module* mod); +extern BOOL dbg_del_module_by_base(struct dbg_process* p, DWORD_PTR base); extern BOOL dbg_init(HANDLE hProc, const WCHAR* in, BOOL invade); extern BOOL dbg_load_module(HANDLE hProc, HANDLE hFile, const WCHAR* name, DWORD_PTR base, DWORD size); extern void dbg_set_option(const char*, const char*); diff --git a/programs/winedbg/tgt_active.c b/programs/winedbg/tgt_active.c index 9e130038f22..bfaf9d0b654 100644 --- a/programs/winedbg/tgt_active.c +++ b/programs/winedbg/tgt_active.c @@ -485,6 +485,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) de->u.LoadDll.nDebugInfoSize); dbg_load_module(dbg_curr_process->handle, de->u.LoadDll.hFile, u.buffer, (DWORD_PTR)de->u.LoadDll.lpBaseOfDll, 0); + dbg_add_module(dbg_curr_process, (DWORD_PTR)de->u.LoadDll.lpBaseOfDll); break_set_xpoints(FALSE); break_check_delayed_bp(); break_set_xpoints(TRUE); @@ -503,6 +504,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) break_delete_xpoints_from_module((DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); types_unload_module((DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); SymUnloadModule64(dbg_curr_process->handle, (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); + dbg_del_module_by_base(dbg_curr_process, (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll); break;
case OUTPUT_DEBUG_STRING_EVENT: diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c index 84ec7802396..ab2e94f5673 100644 --- a/programs/winedbg/winedbg.c +++ b/programs/winedbg/winedbg.c @@ -273,6 +273,7 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid, p->pio_data = NULL; p->imageName = NULL; list_init(&p->threads); + list_init(&p->modules); p->event_on_first_exception = NULL; p->active_debuggee = FALSE; p->next_bp = 1; /* breakpoint 0 is reserved for step-over */ @@ -316,11 +317,16 @@ void dbg_del_process(struct dbg_process* p) { struct dbg_thread* t; struct dbg_thread* t2; + struct dbg_module* mod; + struct dbg_module* mod2; int i;
LIST_FOR_EACH_ENTRY_SAFE(t, t2, &p->threads, struct dbg_thread, entry) dbg_del_thread(t);
+ LIST_FOR_EACH_ENTRY_SAFE(mod, mod2, &p->modules, struct dbg_module, entry) + dbg_del_module(mod); + for (i = 0; i < p->num_delayed_bp; i++) if (p->delayed_bp[i].is_symbol) free(p->delayed_bp[i].u.symbol.name); @@ -436,6 +442,48 @@ void dbg_del_thread(struct dbg_thread* t) free(t); }
+struct dbg_module* dbg_add_module(struct dbg_process* p, DWORD_PTR base) +{ + struct dbg_module* mod = malloc(sizeof(struct dbg_module)); + + if (!mod) + return NULL; + + mod->base = base; + + list_add_head(&p->modules, &mod->entry); + + return mod; +} + +struct dbg_module* dbg_get_module(struct dbg_process* p, DWORD_PTR base) +{ + struct dbg_module* mod; + + if (!p) + return NULL; + LIST_FOR_EACH_ENTRY(mod, &p->modules, struct dbg_module, entry) + if (mod->base == base) + return mod; + return NULL; +} + +void dbg_del_module(struct dbg_module* mod) +{ + list_remove(&mod->entry); + free(mod); +} + +BOOL dbg_del_module_by_base(struct dbg_process* p, DWORD_PTR base) +{ + struct dbg_module* mod = dbg_get_module(p, base); + + if (mod) + dbg_del_module(mod); + + return !!mod; +} + void dbg_set_option(const char* option, const char* val) { if (!strcasecmp(option, "module_load_mismatched"))