diff --git a/programs/winedbg/Makefile.in b/programs/winedbg/Makefile.in index dd343dbebdd..b340ecb189c 100644 --- a/programs/winedbg/Makefile.in +++ b/programs/winedbg/Makefile.in @@ -25,6 +25,7 @@ C_SRCS = \ stack.c \ tgt_active.c \ tgt_minidump.c \ + tgt_module.c \ types.c \ winedbg.c diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y index 3b5414a766e..aea48bd8a08 100644 --- a/programs/winedbg/dbg.y +++ b/programs/winedbg/dbg.y @@ -54,8 +54,8 @@ static int dbg_error(const char*); %token tENABLE tDISABLE tBREAK tHBREAK tWATCH tDELETE tSET tPRINT tEXAM %token tABORT tECHO %token tCLASS tMAPS tSTACK tSEGMENTS tSYMBOL tREGS tALLREGS tWND tQUEUE tLOCAL tEXCEPTION -%token tPROCESS tTHREAD tMODREF tEOL tEOF -%token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE +%token tPROCESS tTHREAD tEOL tEOF +%token tFRAME tSHARE tMODULE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE %token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS tSOURCE %token tPATH tIDENTIFIER tSTRING tDEBUGSTR tINTVAR %token tNUM tFORMAT @@ -285,6 +285,8 @@ info_command: maintenance_command: tMAINTENANCE tTYPE { print_types(); } + | tMAINTENANCE tMODULE tSTRING { tgt_module_load($3, FALSE); } + | tMAINTENANCE '*' tMODULE tSTRING { tgt_module_load($4, TRUE); } ; noprocess_state: diff --git a/programs/winedbg/debug.l b/programs/winedbg/debug.l index 451c96d2b14..9613fed7fab 100644 --- a/programs/winedbg/debug.l +++ b/programs/winedbg/debug.l @@ -177,11 +177,12 @@ STRING \"[^\n"]+\" whatis|whati|what { BEGIN(NOCMD); return tWHATIS; } run|ru|r { BEGIN(ASTRING_EXPECTED); return tRUN;} detach|detac|deta|det { BEGIN(NOCMD); return tDETACH; } -maintenance|maint { BEGIN(MAINT_CMD); return tMAINTENANCE; } +maintenance|maint { BEGIN(MAINT_CMD); return tMAINTENANCE; } minidump|mdmp { BEGIN(PATH_EXPECTED); return tMINIDUMP; } echo { BEGIN(ASTRING_EXPECTED); return tECHO; } attach|attac|atta|att { BEGIN(NOCMD); return tATTACH; } -share|shar|sha { return tSHARE; } +share|shar|sha { return tSHARE; } +module|modul|mod { BEGIN(ASTRING_EXPECTED); return tMODULE; } locals|local|loca|loc { return tLOCAL; } class|clas|cla { return tCLASS; } process|proces|proce|proc { return tPROCESS; } diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index 91d5a78c163..031724756c9 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -393,6 +393,9 @@ extern BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe); extern void minidump_write(const char*, const EXCEPTION_RECORD*); extern enum dbg_start minidump_reload(int argc, char* argv[]); + /* tgt_module.c */ +extern enum dbg_start tgt_module_load(const char* name, BOOL keep); + /* types.c */ extern void print_value(const struct dbg_lvalue* addr, char format, int level); extern int types_print_type(const struct dbg_type*, BOOL details); diff --git a/programs/winedbg/tgt_module.c b/programs/winedbg/tgt_module.c new file mode 100644 index 00000000000..0f725106df7 --- /dev/null +++ b/programs/winedbg/tgt_module.c @@ -0,0 +1,90 @@ +/* + * Wine debugger - loading a module for debug purposes + * + * Copyright 2006 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT + +#include "config.h" + +#include +#include +#include +#include + +#include "debugger.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winedbg); + +static struct be_process_io be_process_module_io; + +static BOOL WINAPI tgt_process_module_read(HANDLE hProcess, const void* addr, + void* buffer, SIZE_T len, SIZE_T* rlen) +{ + return FALSE; +} + +static BOOL WINAPI tgt_process_module_write(HANDLE hProcess, void* addr, + const void* buffer, SIZE_T len, SIZE_T* wlen) +{ + return FALSE; +} + +enum dbg_start tgt_module_load(const char* name, BOOL keep) +{ + DWORD opts = SymGetOptions(); + HANDLE hDummy = (HANDLE)0x87654321; + + SymSetOptions((opts & ~(SYMOPT_UNDNAME|SYMOPT_DEFERRED_LOADS)) | + SYMOPT_LOAD_LINES | SYMOPT_AUTO_PUBLICS | 0x40000000); + SymInitialize(hDummy, NULL, FALSE); + SymLoadModule(hDummy, NULL, name, NULL, 0, 0); + + if (keep) + { + dbg_printf("Non supported mode... errors may occur\n" + "Use at your own risks\n"); + SymSetOptions(SymGetOptions() | 0x40000000); + dbg_curr_process = dbg_add_process(&be_process_module_io, 1, hDummy); + dbg_curr_pid = 1; + /* FIXME: missing thread creation, fetching frames, restoring dbghelp's options... */ + } + else + { + SymCleanup(hDummy); + SymSetOptions(opts); + } + + return start_ok; +} + +static BOOL tgt_process_module_close_process(struct dbg_process* pcs, BOOL kill) +{ + SymCleanup(pcs->handle); + dbg_del_process(pcs); + return TRUE; +} + +static struct be_process_io be_process_module_io = +{ + tgt_process_module_close_process, + tgt_process_module_read, + tgt_process_module_write, +};