Commit d6be549a authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- started infrastructure for proper multi-target support (active

process, minidump...) - all read/write memory ops are now done thru a centralized process_io facility - minor fixes & cleanups in CPU backends
parent 3c3495ea
...@@ -21,6 +21,7 @@ C_SRCS = \ ...@@ -21,6 +21,7 @@ C_SRCS = \
source.c \ source.c \
symbol.c \ symbol.c \
stack.c \ stack.c \
tgt_active.c \
tgt_minidump.c \ tgt_minidump.c \
types.c \ types.c \
winedbg.c winedbg.c
......
...@@ -82,9 +82,9 @@ static void be_alpha_disasm_one_insn(ADDRESS* addr, int display) ...@@ -82,9 +82,9 @@ static void be_alpha_disasm_one_insn(ADDRESS* addr, int display)
dbg_printf("Disasm NIY\n"); dbg_printf("Disasm NIY\n");
} }
static unsigned be_alpha_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx, static unsigned be_alpha_insert_Xpoint(HANDLE hProcess, struct be_process_io* pio,
enum be_xpoint_type type, void* addr, CONTEXT* ctx, enum be_xpoint_type type,
unsigned long* val, unsigned size) void* addr, unsigned long* val, unsigned size)
{ {
unsigned long xbp; unsigned long xbp;
unsigned long sz; unsigned long sz;
...@@ -93,9 +93,9 @@ static unsigned be_alpha_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx, ...@@ -93,9 +93,9 @@ static unsigned be_alpha_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
{ {
case be_xpoint_break: case be_xpoint_break:
if (!size) return 0; if (!size) return 0;
if (!ReadProcessMemory(hProcess, addr, val, 4, &sz) || sz != 4) return 0; if (!pio->read(hProcess, addr, val, 4, &sz) || sz != 4) return 0;
xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */ xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */
if (!WriteProcessMemory(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0; if (!pio->write(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0;
break; break;
default: default:
dbg_printf("Unknown/unsupported bp type %c\n", type); dbg_printf("Unknown/unsupported bp type %c\n", type);
......
...@@ -82,13 +82,13 @@ struct backend_cpu ...@@ -82,13 +82,13 @@ struct backend_cpu
* break points / watchpoints handling * break points / watchpoints handling
* -------------------------------------------------------------------------------*/ * -------------------------------------------------------------------------------*/
/* Inserts an Xpoint in the CPU context and/or debuggee address space */ /* Inserts an Xpoint in the CPU context and/or debuggee address space */
unsigned (*insert_Xpoint)(HANDLE hProcess, CONTEXT* ctx, unsigned (*insert_Xpoint)(HANDLE hProcess, struct be_process_io* pio,
enum be_xpoint_type type, void* addr, CONTEXT* ctx, enum be_xpoint_type type,
unsigned long* val, unsigned size); void* addr, unsigned long* val, unsigned size);
/* Removes an Xpoint in the CPU context and/or debuggee address space */ /* Removes an Xpoint in the CPU context and/or debuggee address space */
unsigned (*remove_Xpoint)(HANDLE hProcess, CONTEXT* ctx, unsigned (*remove_Xpoint)(HANDLE hProcess, struct be_process_io* pio,
enum be_xpoint_type type, void* addr, CONTEXT* ctx, enum be_xpoint_type type,
unsigned long val, unsigned size); void* addr, unsigned long val, unsigned size);
/* Checks whether a given watchpoint has been triggered */ /* Checks whether a given watchpoint has been triggered */
unsigned (*is_watchpoint_set)(const CONTEXT* ctx, unsigned idx); unsigned (*is_watchpoint_set)(const CONTEXT* ctx, unsigned idx);
/* Clears the watchpoint indicator */ /* Clears the watchpoint indicator */
......
...@@ -304,7 +304,7 @@ static unsigned be_i386_is_break_insn(const void* insn) ...@@ -304,7 +304,7 @@ static unsigned be_i386_is_break_insn(const void* insn)
{ {
BYTE c; BYTE c;
if (!dbg_read_memory(insn, &c, 1)) return FALSE; if (!dbg_read_memory(insn, &c, sizeof(c))) return FALSE;
return c == 0xCC; return c == 0xCC;
} }
...@@ -313,9 +313,10 @@ static unsigned be_i386_is_func_call(const void* insn, ADDRESS* callee) ...@@ -313,9 +313,10 @@ static unsigned be_i386_is_func_call(const void* insn, ADDRESS* callee)
BYTE ch; BYTE ch;
int delta; int delta;
dbg_read_memory(insn, &ch, sizeof(ch)); if (!dbg_read_memory(insn, &ch, sizeof(ch))) return FALSE;
if (ch == 0xe8) switch (ch)
{ {
case 0xe8:
dbg_read_memory((const char*)insn + 1, &delta, sizeof(delta)); dbg_read_memory((const char*)insn + 1, &delta, sizeof(delta));
callee->Mode = AddrModeFlat; callee->Mode = AddrModeFlat;
...@@ -324,8 +325,19 @@ static unsigned be_i386_is_func_call(const void* insn, ADDRESS* callee) ...@@ -324,8 +325,19 @@ static unsigned be_i386_is_func_call(const void* insn, ADDRESS* callee)
callee->Offset += delta; callee->Offset += delta;
return TRUE; return TRUE;
} case 0xff:
if (!dbg_read_memory((const char*)insn + 1, &ch, sizeof(ch)))
return FALSE; return FALSE;
ch &= 0x38;
if (ch != 0x10 && ch != 0x18) return FALSE;
/* fall through */
case 0x9c:
case 0xCD:
WINE_FIXME("Unsupported yet call insn (0x%02x) at %p\n", ch, insn);
/* fall through */
default:
return FALSE;
}
} }
#define DR7_CONTROL_SHIFT 16 #define DR7_CONTROL_SHIFT 16
...@@ -380,9 +392,9 @@ static inline int be_i386_get_unused_DR(CONTEXT* ctx, unsigned long** r) ...@@ -380,9 +392,9 @@ static inline int be_i386_get_unused_DR(CONTEXT* ctx, unsigned long** r)
return -1; return -1;
} }
static unsigned be_i386_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx, static unsigned be_i386_insert_Xpoint(HANDLE hProcess, struct be_process_io* pio,
enum be_xpoint_type type, void* addr, CONTEXT* ctx, enum be_xpoint_type type,
unsigned long* val, unsigned size) void* addr, unsigned long* val, unsigned size)
{ {
unsigned char ch; unsigned char ch;
unsigned long sz; unsigned long sz;
...@@ -394,10 +406,10 @@ static unsigned be_i386_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx, ...@@ -394,10 +406,10 @@ static unsigned be_i386_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
{ {
case be_xpoint_break: case be_xpoint_break:
if (size != 0) return 0; if (size != 0) return 0;
if (!ReadProcessMemory(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0; if (!pio->read(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
*val = ch; *val = ch;
ch = 0xcc; ch = 0xcc;
if (!WriteProcessMemory(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0; if (!pio->write(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
break; break;
case be_xpoint_watch_exec: case be_xpoint_watch_exec:
bits = DR7_RW_EXECUTE; bits = DR7_RW_EXECUTE;
...@@ -431,9 +443,9 @@ static unsigned be_i386_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx, ...@@ -431,9 +443,9 @@ static unsigned be_i386_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
return 1; return 1;
} }
static unsigned be_i386_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx, static unsigned be_i386_remove_Xpoint(HANDLE hProcess, struct be_process_io* pio,
enum be_xpoint_type type, void* addr, CONTEXT* ctx, enum be_xpoint_type type,
unsigned long val, unsigned size) void* addr, unsigned long val, unsigned size)
{ {
unsigned long sz; unsigned long sz;
unsigned char ch; unsigned char ch;
...@@ -442,12 +454,12 @@ static unsigned be_i386_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx, ...@@ -442,12 +454,12 @@ static unsigned be_i386_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx,
{ {
case be_xpoint_break: case be_xpoint_break:
if (size != 0) return 0; if (size != 0) return 0;
if (!ReadProcessMemory(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0; if (!pio->read(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
if (ch != (unsigned char)0xCC) if (ch != (unsigned char)0xCC)
WINE_FIXME("Cannot get back %02x instead of 0xCC at %08lx\n", WINE_FIXME("Cannot get back %02x instead of 0xCC at %08lx\n",
ch, (unsigned long)addr); ch, (unsigned long)addr);
ch = (unsigned char)val; ch = (unsigned char)val;
if (!WriteProcessMemory(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0; if (!pio->write(hProcess, addr, &ch, 1, &sz) || sz != 1) return 0;
break; break;
case be_xpoint_watch_exec: case be_xpoint_watch_exec:
case be_xpoint_watch_read: case be_xpoint_watch_read:
......
...@@ -44,7 +44,7 @@ static void be_ppc_single_step(CONTEXT* ctx, unsigned enable) ...@@ -44,7 +44,7 @@ static void be_ppc_single_step(CONTEXT* ctx, unsigned enable)
# define MSR_SE (1<<10) # define MSR_SE (1<<10)
#endif #endif
if (enable) ctx->Msr |= MSR_SE; if (enable) ctx->Msr |= MSR_SE;
else ctx->Msr &= MSR_SE; else ctx->Msr &= ~MSR_SE;
} }
static void be_ppc_print_context(HANDLE hThread, const CONTEXT* ctx) static void be_ppc_print_context(HANDLE hThread, const CONTEXT* ctx)
...@@ -95,9 +95,9 @@ static void be_ppc_disasm_one_insn(ADDRESS* addr, int display) ...@@ -95,9 +95,9 @@ static void be_ppc_disasm_one_insn(ADDRESS* addr, int display)
dbg_printf("Disasm NIY\n"); dbg_printf("Disasm NIY\n");
} }
static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx, static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, struct be_process_io* pio,
enum be_xpoint_type type, void* addr, CONTEXT* ctx, enum be_xpoint_type type,
unsigned long* val, unsigned size) void* addr, unsigned long* val, unsigned size)
{ {
unsigned long xbp; unsigned long xbp;
unsigned long sz; unsigned long sz;
...@@ -106,9 +106,9 @@ static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx, ...@@ -106,9 +106,9 @@ static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
{ {
case be_xpoint_break: case be_xpoint_break:
if (!size) return 0; if (!size) return 0;
if (!ReadProcessMemory(hProcess, addr, val, 4, &sz) || sz != 4) return 0; if (!pio->read(hProcess, addr, val, 4, &sz) || sz != 4) return 0;
xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */ xbp = 0x7d821008; /* 7d 82 10 08 ... in big endian */
if (!WriteProcessMemory(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0; if (!pio->write(hProcess, addr, &xbp, 4, &sz) || sz != 4) return 0;
break; break;
default: default:
dbg_printf("Unknown/unsupported bp type %c\n", type); dbg_printf("Unknown/unsupported bp type %c\n", type);
...@@ -117,9 +117,9 @@ static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx, ...@@ -117,9 +117,9 @@ static unsigned be_ppc_insert_Xpoint(HANDLE hProcess, CONTEXT* ctx,
return 1; return 1;
} }
static unsigned be_ppc_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx, static unsigned be_ppc_remove_Xpoint(HANDLE hProcess, struct be_process_io* pio,
enum be_xpoint_type type, void* addr, CONTEXT* ctx, enum be_xpoint_type type,
unsigned long val, unsigned size) void* addr, unsigned long val, unsigned size)
{ {
unsigned long sz; unsigned long sz;
...@@ -127,7 +127,7 @@ static unsigned be_ppc_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx, ...@@ -127,7 +127,7 @@ static unsigned be_ppc_remove_Xpoint(HANDLE hProcess, CONTEXT* ctx,
{ {
case be_xpoint_break: case be_xpoint_break:
if (!size) return 0; if (!size) return 0;
if (!WriteProcessMemory(hProcess, addr, &val, 4, &sz) || sz != 4) return 0; if (!pio->write(hProcess, addr, &val, 4, &sz) || sz == 4) return 0;
break; break;
default: default:
dbg_printf("Unknown/unsupported bp type %c\n", type); dbg_printf("Unknown/unsupported bp type %c\n", type);
......
...@@ -53,12 +53,14 @@ void break_set_xpoints(BOOL set) ...@@ -53,12 +53,14 @@ void break_set_xpoints(BOOL set)
addr = (void*)memory_to_linear_addr(&bp[i].addr); addr = (void*)memory_to_linear_addr(&bp[i].addr);
if (set) if (set)
ret = be_cpu->insert_Xpoint(dbg_curr_process->handle, &dbg_context, ret = be_cpu->insert_Xpoint(dbg_curr_process->handle,
bp[i].xpoint_type, addr, dbg_curr_process->process_io,
&dbg_context, bp[i].xpoint_type, addr,
&bp[i].info, size); &bp[i].info, size);
else else
ret = be_cpu->remove_Xpoint(dbg_curr_process->handle, &dbg_context, ret = be_cpu->remove_Xpoint(dbg_curr_process->handle,
bp[i].xpoint_type, addr, dbg_curr_process->process_io,
&dbg_context, bp[i].xpoint_type, addr,
bp[i].info, size); bp[i].info, size);
if (!ret) if (!ret)
{ {
......
...@@ -191,6 +191,7 @@ struct dbg_process ...@@ -191,6 +191,7 @@ struct dbg_process
{ {
HANDLE handle; HANDLE handle;
DWORD pid; DWORD pid;
struct be_process_io* process_io;
const char* imageName; const char* imageName;
struct dbg_thread* threads; struct dbg_thread* threads;
unsigned continue_on_first_exception; unsigned continue_on_first_exception;
...@@ -202,6 +203,13 @@ struct dbg_process ...@@ -202,6 +203,13 @@ struct dbg_process
struct dbg_process* prev; struct dbg_process* prev;
}; };
/* describes the way the debugger interacts with a given process */
struct be_process_io
{
BOOL (WINAPI *read)(HANDLE, const void*, void*, DWORD, DWORD*);
BOOL (WINAPI *write)(HANDLE, void*, const void*, DWORD, DWORD*);
};
extern struct dbg_process* dbg_curr_process; extern struct dbg_process* dbg_curr_process;
extern DWORD dbg_curr_pid; extern DWORD dbg_curr_pid;
extern struct dbg_thread* dbg_curr_thread; extern struct dbg_thread* dbg_curr_thread;
...@@ -314,8 +322,8 @@ extern void* memory_to_linear_addr(const ADDRESS* address); ...@@ -314,8 +322,8 @@ extern void* memory_to_linear_addr(const ADDRESS* address);
extern BOOL memory_get_current_pc(ADDRESS* address); extern BOOL memory_get_current_pc(ADDRESS* address);
extern BOOL memory_get_current_stack(ADDRESS* address); extern BOOL memory_get_current_stack(ADDRESS* address);
extern BOOL memory_get_current_frame(ADDRESS* address); extern BOOL memory_get_current_frame(ADDRESS* address);
extern BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size); extern BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size);
extern BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size); extern BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, char* buffer, int size);
extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count); extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count);
extern BOOL memory_disasm_one_insn(ADDRESS* addr); extern BOOL memory_disasm_one_insn(ADDRESS* addr);
extern void print_bare_address(const ADDRESS* addr); extern void print_bare_address(const ADDRESS* addr);
...@@ -373,7 +381,8 @@ extern BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe, BOOL wfe); ...@@ -373,7 +381,8 @@ extern BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe, BOOL wfe);
extern BOOL dbg_detach_debuggee(void); extern BOOL dbg_detach_debuggee(void);
extern BOOL dbg_interrupt_debuggee(void); extern BOOL dbg_interrupt_debuggee(void);
extern void dbg_run_debuggee(const char* args); extern void dbg_run_debuggee(const char* args);
extern struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName); extern struct dbg_process* dbg_add_process(DWORD pid, HANDLE h);
extern void dbg_set_process_name(struct dbg_process* p, const char* name);
extern struct dbg_process* dbg_get_process(DWORD pid); extern struct dbg_process* dbg_get_process(DWORD pid);
extern void dbg_del_process(struct dbg_process* p); 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); struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid, HANDLE h, void* teb);
......
...@@ -443,10 +443,14 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de) ...@@ -443,10 +443,14 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
switch (de->dwDebugEventCode) switch (de->dwDebugEventCode)
{ {
case CREATE_PROCESS_DEBUG_EVENT: case CREATE_PROCESS_DEBUG_EVENT:
memory_get_string_indirect(de->u.CreateProcessInfo.hProcess, gdbctx->process = dbg_add_process(de->dwProcessId,
de->u.CreateProcessInfo.hProcess);
if (!gdbctx->process) break;
memory_get_string_indirect(gdbctx->process,
de->u.CreateProcessInfo.lpImageName, de->u.CreateProcessInfo.lpImageName,
de->u.CreateProcessInfo.fUnicode, de->u.CreateProcessInfo.fUnicode,
buffer, sizeof(buffer)); buffer, sizeof(buffer));
dbg_set_process_name(gdbctx->process, buffer);
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT) if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
fprintf(stderr, "%08lx:%08lx: create process '%s'/%p @%08lx (%ld<%ld>)\n", fprintf(stderr, "%08lx:%08lx: create process '%s'/%p @%08lx (%ld<%ld>)\n",
...@@ -456,9 +460,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de) ...@@ -456,9 +460,6 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
de->u.CreateProcessInfo.dwDebugInfoFileOffset, de->u.CreateProcessInfo.dwDebugInfoFileOffset,
de->u.CreateProcessInfo.nDebugInfoSize); de->u.CreateProcessInfo.nDebugInfoSize);
gdbctx->process = dbg_add_process(de->dwProcessId,
de->u.CreateProcessInfo.hProcess,
buffer);
/* de->u.CreateProcessInfo.lpStartAddress; */ /* de->u.CreateProcessInfo.lpStartAddress; */
if (!SymInitialize(gdbctx->process->handle, NULL, TRUE)) if (!SymInitialize(gdbctx->process->handle, NULL, TRUE))
fprintf(stderr, "Couldn't initiate DbgHelp\n"); fprintf(stderr, "Couldn't initiate DbgHelp\n");
...@@ -476,7 +477,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de) ...@@ -476,7 +477,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
case LOAD_DLL_DEBUG_EVENT: case LOAD_DLL_DEBUG_EVENT:
assert(dbg_curr_thread); assert(dbg_curr_thread);
memory_get_string_indirect(gdbctx->process->handle, memory_get_string_indirect(gdbctx->process,
de->u.LoadDll.lpImageName, de->u.LoadDll.lpImageName,
de->u.LoadDll.fUnicode, de->u.LoadDll.fUnicode,
buffer, sizeof(buffer)); buffer, sizeof(buffer));
...@@ -547,7 +548,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de) ...@@ -547,7 +548,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
case OUTPUT_DEBUG_STRING_EVENT: case OUTPUT_DEBUG_STRING_EVENT:
assert(dbg_curr_thread); assert(dbg_curr_thread);
memory_get_string(gdbctx->process->handle, memory_get_string(gdbctx->process,
de->u.DebugString.lpDebugStringData, TRUE, de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer)); de->u.DebugString.fUnicode, buffer, sizeof(buffer));
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT) if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
...@@ -1263,7 +1264,7 @@ static enum packet_return packet_read_memory(struct gdb_context* gdbctx) ...@@ -1263,7 +1264,7 @@ static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
for (nread = 0; nread < len; nread += r, addr += r) for (nread = 0; nread < len; nread += r, addr += r)
{ {
blk_len = min(sizeof(buffer), len - nread); blk_len = min(sizeof(buffer), len - nread);
if (!ReadProcessMemory(gdbctx->process->handle, addr, buffer, blk_len, &r) || if (!gdbctx->process->process_io->read(gdbctx->process->handle, addr, buffer, blk_len, &r) ||
r == 0) r == 0)
{ {
/* fail at first address, return error */ /* fail at first address, return error */
...@@ -1316,16 +1317,12 @@ static enum packet_return packet_write_memory(struct gdb_context* gdbctx) ...@@ -1316,16 +1317,12 @@ static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
{ {
blk_len = min(sizeof(buffer), len); blk_len = min(sizeof(buffer), len);
hex_from(buffer, ptr, blk_len); hex_from(buffer, ptr, blk_len);
{ if (!gdbctx->process->process_io->write(gdbctx->process->handle, addr, buffer, blk_len, &w) ||
BOOL ret; w != blk_len)
ret = WriteProcessMemory(gdbctx->process->handle, addr, buffer, blk_len, &w);
if (!ret || w != blk_len)
break; break;
} addr += blk_len;
addr += w; len -= blk_len;
len -= w; ptr += blk_len;
ptr += w;
} }
return packet_ok; /* FIXME: error while writing ? */ return packet_ok; /* FIXME: error while writing ? */
} }
...@@ -1789,7 +1786,8 @@ static enum packet_return packet_remove_breakpoint(struct gdb_context* gdbctx) ...@@ -1789,7 +1786,8 @@ static enum packet_return packet_remove_breakpoint(struct gdb_context* gdbctx)
{ {
if (xpt->addr == addr && xpt->type == t) if (xpt->addr == addr && xpt->type == t)
{ {
if (be_cpu->remove_Xpoint(gdbctx->process->handle, &gdbctx->context, if (be_cpu->remove_Xpoint(gdbctx->process->handle,
gdbctx->process->process_io, &gdbctx->context,
t, xpt->addr, xpt->val, len)) t, xpt->addr, xpt->val, len))
{ {
xpt->type = -1; xpt->type = -1;
...@@ -1835,7 +1833,8 @@ static enum packet_return packet_set_breakpoint(struct gdb_context* gdbctx) ...@@ -1835,7 +1833,8 @@ static enum packet_return packet_set_breakpoint(struct gdb_context* gdbctx)
{ {
if (xpt->type == -1) if (xpt->type == -1)
{ {
if (be_cpu->insert_Xpoint(gdbctx->process->handle, &gdbctx->context, if (be_cpu->insert_Xpoint(gdbctx->process->handle,
gdbctx->process->process_io, &gdbctx->context,
t, addr, &xpt->val, len)) t, addr, &xpt->val, len))
{ {
xpt->addr = addr; xpt->addr = addr;
......
...@@ -169,13 +169,13 @@ void memory_examine(const struct dbg_lvalue *lvalue, int count, char format) ...@@ -169,13 +169,13 @@ void memory_examine(const struct dbg_lvalue *lvalue, int count, char format)
{ {
case 'u': case 'u':
if (count == 1) count = 256; if (count == 1) count = 256;
memory_get_string(dbg_curr_process->handle, linear, memory_get_string(dbg_curr_process, linear,
TRUE, TRUE, buffer, min(count, sizeof(buffer))); TRUE, TRUE, buffer, min(count, sizeof(buffer)));
dbg_printf("%s\n", buffer); dbg_printf("%s\n", buffer);
return; return;
case 's': case 's':
if (count == 1) count = 256; if (count == 1) count = 256;
memory_get_string(dbg_curr_process->handle, linear, memory_get_string(dbg_curr_process, linear,
TRUE, FALSE, buffer, min(count, sizeof(buffer))); TRUE, FALSE, buffer, min(count, sizeof(buffer)));
dbg_printf("%s\n", buffer); dbg_printf("%s\n", buffer);
return; return;
...@@ -233,8 +233,8 @@ void memory_examine(const struct dbg_lvalue *lvalue, int count, char format) ...@@ -233,8 +233,8 @@ void memory_examine(const struct dbg_lvalue *lvalue, int count, char format)
} }
} }
BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, BOOL memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee,
char* buffer, int size) BOOL unicode, char* buffer, int size)
{ {
DWORD sz; DWORD sz;
WCHAR* buffW; WCHAR* buffW;
...@@ -243,10 +243,10 @@ BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, ...@@ -243,10 +243,10 @@ BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode,
if (!addr) return FALSE; if (!addr) return FALSE;
if (in_debuggee) if (in_debuggee)
{ {
if (!unicode) return ReadProcessMemory(hp, addr, buffer, size, &sz); if (!unicode) return pcs->process_io->read(pcs->handle, addr, buffer, size, &sz);
buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
ReadProcessMemory(hp, addr, buffW, size * sizeof(WCHAR), &sz); pcs->process_io->read(pcs->handle, addr, buffW, size * sizeof(WCHAR), &sz);
WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size, WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size,
NULL, NULL); NULL, NULL);
HeapFree(GetProcessHeap(), 0, buffW); HeapFree(GetProcessHeap(), 0, buffW);
...@@ -258,16 +258,16 @@ BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, ...@@ -258,16 +258,16 @@ BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode,
return TRUE; return TRUE;
} }
BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size) BOOL memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, char* buffer, int size)
{ {
void* ad; void* ad;
DWORD sz; DWORD sz;
buffer[0] = 0; buffer[0] = 0;
if (addr && if (addr &&
ReadProcessMemory(hp, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad) pcs->process_io->read(pcs->handle, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad)
{ {
return memory_get_string(hp, ad, TRUE, unicode, buffer, size); return memory_get_string(pcs, ad, TRUE, unicode, buffer, size);
} }
return FALSE; return FALSE;
} }
...@@ -337,7 +337,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue) ...@@ -337,7 +337,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue)
{ {
char buffer[1024]; char buffer[1024];
memory_get_string(dbg_curr_process->handle, val_ptr, memory_get_string(dbg_curr_process, val_ptr,
lvalue->cookie == DLV_TARGET, lvalue->cookie == DLV_TARGET,
size == 2, buffer, sizeof(buffer)); size == 2, buffer, sizeof(buffer));
dbg_printf("\"%s\"", buffer); dbg_printf("\"%s\"", buffer);
......
/*
* Wine debugger - back-end for an active target
*
* Copyright 2005 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "debugger.h"
#include "winternl.h"
#include "wine/debug.h"
#include "wine/exception.h"
WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
struct be_process_io be_process_active_io =
{
ReadProcessMemory,
WriteProcessMemory,
};
...@@ -454,7 +454,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level) ...@@ -454,7 +454,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level)
*/ */
/* FIXME should check basic type here (should be a char!!!!)... */ /* FIXME should check basic type here (should be a char!!!!)... */
len = min(count, sizeof(buffer)); len = min(count, sizeof(buffer));
memory_get_string(dbg_curr_process->handle, memory_get_string(dbg_curr_process,
memory_to_linear_addr(&lvalue->addr), memory_to_linear_addr(&lvalue->addr),
lvalue->cookie == DLV_TARGET, TRUE, buffer, len); lvalue->cookie == DLV_TARGET, TRUE, buffer, len);
dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : ""); dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
......
...@@ -239,8 +239,11 @@ struct dbg_process* dbg_get_process(DWORD pid) ...@@ -239,8 +239,11 @@ struct dbg_process* dbg_get_process(DWORD pid)
return p; return p;
} }
struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName) struct dbg_process* dbg_add_process(DWORD pid, HANDLE h)
{ {
/* FIXME: temporary */
extern struct be_process_io be_process_active_io;
struct dbg_process* p; struct dbg_process* p;
if ((p = dbg_get_process(pid))) if ((p = dbg_get_process(pid)))
...@@ -252,7 +255,7 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName) ...@@ -252,7 +255,7 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName)
else else
{ {
p->handle = h; p->handle = h;
p->imageName = imageName ? strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1), imageName) : NULL; p->imageName = NULL;
} }
return p; return p;
} }
...@@ -260,7 +263,8 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName) ...@@ -260,7 +263,8 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName)
if (!(p = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_process)))) return NULL; if (!(p = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_process)))) return NULL;
p->handle = h; p->handle = h;
p->pid = pid; p->pid = pid;
p->imageName = imageName ? strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1), imageName) : NULL; p->process_io = &be_process_active_io;
p->imageName = NULL;
p->threads = NULL; p->threads = NULL;
p->continue_on_first_exception = FALSE; p->continue_on_first_exception = FALSE;
p->next_bp = 1; /* breakpoint 0 is reserved for step-over */ p->next_bp = 1; /* breakpoint 0 is reserved for step-over */
...@@ -275,6 +279,16 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName) ...@@ -275,6 +279,16 @@ struct dbg_process* dbg_add_process(DWORD pid, HANDLE h, const char* imageName)
return p; return p;
} }
void dbg_set_process_name(struct dbg_process* p, const char* imageName)
{
assert(p->imageName == NULL);
if (imageName)
{
char* tmp = HeapAlloc(GetProcessHeap(), 0, strlen(imageName) + 1);
if (tmp) p->imageName = strcpy(tmp, imageName);
}
}
void dbg_del_process(struct dbg_process* p) void dbg_del_process(struct dbg_process* p)
{ {
int i; int i;
...@@ -418,7 +432,7 @@ BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe, BOOL wfe) ...@@ -418,7 +432,7 @@ BOOL dbg_attach_debuggee(DWORD pid, BOOL cofe, BOOL wfe)
{ {
DEBUG_EVENT de; DEBUG_EVENT de;
if (!(dbg_curr_process = dbg_add_process(pid, 0, NULL))) return FALSE; if (!(dbg_curr_process = dbg_add_process(pid, 0))) return FALSE;
if (!DebugActiveProcess(pid)) if (!DebugActiveProcess(pid))
{ {
...@@ -660,11 +674,11 @@ static DWORD dbg_handle_exception(const EXCEPTION_RECORD* rec, BOOL first_chance ...@@ -660,11 +674,11 @@ static DWORD dbg_handle_exception(const EXCEPTION_RECORD* rec, BOOL first_chance
case EXCEPTION_WINE_STUB: case EXCEPTION_WINE_STUB:
{ {
char dll[32], name[64]; char dll[32], name[64];
memory_get_string(dbg_curr_process->handle, memory_get_string(dbg_curr_process,
(void*)rec->ExceptionInformation[0], TRUE, FALSE, (void*)rec->ExceptionInformation[0], TRUE, FALSE,
dll, sizeof(dll)); dll, sizeof(dll));
if (HIWORD(rec->ExceptionInformation[1])) if (HIWORD(rec->ExceptionInformation[1]))
memory_get_string(dbg_curr_process->handle, memory_get_string(dbg_curr_process,
(void*)rec->ExceptionInformation[1], TRUE, FALSE, (void*)rec->ExceptionInformation[1], TRUE, FALSE,
name, sizeof(name)); name, sizeof(name));
else else
...@@ -772,25 +786,27 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) ...@@ -772,25 +786,27 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
break; break;
case CREATE_PROCESS_DEBUG_EVENT: case CREATE_PROCESS_DEBUG_EVENT:
memory_get_string_indirect(de->u.CreateProcessInfo.hProcess, dbg_curr_process = dbg_add_process(de->dwProcessId,
de->u.CreateProcessInfo.hProcess);
if (dbg_curr_process == NULL)
{
WINE_ERR("Couldn't create process\n");
break;
}
memory_get_string_indirect(dbg_curr_process,
de->u.CreateProcessInfo.lpImageName, de->u.CreateProcessInfo.lpImageName,
de->u.CreateProcessInfo.fUnicode, de->u.CreateProcessInfo.fUnicode,
buffer, sizeof(buffer)); buffer, sizeof(buffer));
if (!buffer[0]) strcpy(buffer, "<Debugged Process>");
WINE_TRACE("%08lx:%08lx: create process '%s'/%p @%08lx (%ld<%ld>)\n", WINE_TRACE("%08lx:%08lx: create process '%s'/%p @%08lx (%ld<%ld>)\n",
de->dwProcessId, de->dwThreadId, de->dwProcessId, de->dwThreadId,
buffer, de->u.CreateProcessInfo.lpImageName, buffer, de->u.CreateProcessInfo.lpImageName,
(unsigned long)(void*)de->u.CreateProcessInfo.lpStartAddress, (unsigned long)(void*)de->u.CreateProcessInfo.lpStartAddress,
de->u.CreateProcessInfo.dwDebugInfoFileOffset, de->u.CreateProcessInfo.dwDebugInfoFileOffset,
de->u.CreateProcessInfo.nDebugInfoSize); de->u.CreateProcessInfo.nDebugInfoSize);
dbg_set_process_name(dbg_curr_process, buffer);
dbg_curr_process = dbg_add_process(de->dwProcessId,
de->u.CreateProcessInfo.hProcess,
buffer[0] ? buffer : "<Debugged Process>");
if (dbg_curr_process == NULL)
{
WINE_ERR("Couldn't create process\n");
break;
}
if (!SymInitialize(dbg_curr_process->handle, NULL, TRUE)) if (!SymInitialize(dbg_curr_process->handle, NULL, TRUE))
dbg_printf("Couldn't initiate DbgHelp\n"); dbg_printf("Couldn't initiate DbgHelp\n");
...@@ -878,7 +894,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) ...@@ -878,7 +894,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
WINE_ERR("Unknown thread\n"); WINE_ERR("Unknown thread\n");
break; break;
} }
memory_get_string_indirect(dbg_curr_process->handle, memory_get_string_indirect(dbg_curr_process,
de->u.LoadDll.lpImageName, de->u.LoadDll.lpImageName,
de->u.LoadDll.fUnicode, de->u.LoadDll.fUnicode,
buffer, sizeof(buffer)); buffer, sizeof(buffer));
...@@ -918,7 +934,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) ...@@ -918,7 +934,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
break; break;
} }
memory_get_string(dbg_curr_process->handle, memory_get_string(dbg_curr_process,
de->u.DebugString.lpDebugStringData, TRUE, de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer)); de->u.DebugString.fUnicode, buffer, sizeof(buffer));
WINE_TRACE("%08lx:%08lx: output debug string (%s)\n", WINE_TRACE("%08lx:%08lx: output debug string (%s)\n",
...@@ -1057,7 +1073,7 @@ static unsigned dbg_start_debuggee(LPSTR cmdLine) ...@@ -1057,7 +1073,7 @@ static unsigned dbg_start_debuggee(LPSTR cmdLine)
return TRUE; return TRUE;
} }
dbg_curr_pid = info.dwProcessId; dbg_curr_pid = info.dwProcessId;
if (!(dbg_curr_process = dbg_add_process(dbg_curr_pid, 0, NULL))) return FALSE; if (!(dbg_curr_process = dbg_add_process(dbg_curr_pid, 0))) return FALSE;
return TRUE; return TRUE;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment