2 * A Win32 based proxy implementing the GBD remote protocol.
3 * This makes it possible to debug Wine (and any "emulated"
4 * program) under Linux using GDB.
6 * Copyright (c) Eric Pouech 2002-2004
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 /* Protocol specification can be found here:
24 * http://sources.redhat.com/gdb/onlinedocs/gdb/Maintenance-Commands.html
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(winedbg
);
48 enum be_xpoint_type type
;
61 #define QX_NAME_SIZE 32
62 #define QX_ANNEX_SIZE MAX_PATH
72 /* split into individual packet */
76 struct reply_buffer out_buf
;
78 /* generic GDB thread information */
79 int exec_tid
; /* tid used in step & continue */
80 int other_tid
; /* tid to be used in any other operation */
81 struct list xpoint_list
;
82 /* current Win32 trap env */
85 /* Win32 information */
86 struct dbg_process
* process
;
87 /* Unix environment */
88 ULONG_PTR wine_segs
[3]; /* load addresses of the ELF wine exec segments (text, bss and data) */
91 char qxfer_object_annex
[QX_ANNEX_SIZE
];
92 struct reply_buffer qxfer_buffer
;
95 /* assume standard signal and errno values */
119 static void gdbctx_delete_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
120 dbg_ctx_t
*ctx
, struct gdb_xpoint
*x
)
122 struct dbg_process
*process
= gdbctx
->process
;
123 struct backend_cpu
*cpu
= process
->be_cpu
;
125 if (!cpu
->remove_Xpoint(process
->handle
, process
->process_io
, ctx
, x
->type
, x
->addr
, x
->value
, x
->size
))
126 ERR("%04lx:%04lx: Couldn't remove breakpoint at:%p/%x type:%d\n", process
->pid
, thread
? thread
->tid
: ~0, x
->addr
, x
->size
, x
->type
);
128 list_remove(&x
->entry
);
132 static void gdbctx_insert_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
133 dbg_ctx_t
*ctx
, enum be_xpoint_type type
, void *addr
, int size
)
135 struct dbg_process
*process
= thread
->process
;
136 struct backend_cpu
*cpu
= process
->be_cpu
;
137 struct gdb_xpoint
*x
;
140 if (!cpu
->insert_Xpoint(process
->handle
, process
->process_io
, ctx
, type
, addr
, &value
, size
))
142 ERR("%04lx:%04lx: Couldn't insert breakpoint at:%p/%x type:%d\n", process
->pid
, thread
->tid
, addr
, size
, type
);
146 if (!(x
= malloc(sizeof(struct gdb_xpoint
))))
148 ERR("%04lx:%04lx: Couldn't allocate memory for breakpoint at:%p/%x type:%d\n", process
->pid
, thread
->tid
, addr
, size
, type
);
152 x
->pid
= process
->pid
;
153 x
->tid
= thread
->tid
;
158 list_add_head(&gdbctx
->xpoint_list
, &x
->entry
);
161 static struct gdb_xpoint
*gdb_find_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
162 enum be_xpoint_type type
, void *addr
, int size
)
164 struct gdb_xpoint
*x
;
166 LIST_FOR_EACH_ENTRY(x
, &gdbctx
->xpoint_list
, struct gdb_xpoint
, entry
)
168 if (thread
&& (x
->pid
!= thread
->process
->pid
|| x
->tid
!= thread
->tid
))
170 if (x
->type
== type
&& x
->addr
== addr
&& x
->size
== size
)
177 static BOOL
tgt_process_gdbproxy_read(HANDLE hProcess
, const void* addr
,
178 void* buffer
, SIZE_T len
, SIZE_T
* rlen
)
180 return ReadProcessMemory( hProcess
, addr
, buffer
, len
, rlen
);
183 static BOOL
tgt_process_gdbproxy_write(HANDLE hProcess
, void* addr
,
184 const void* buffer
, SIZE_T len
, SIZE_T
* wlen
)
186 return WriteProcessMemory( hProcess
, addr
, buffer
, len
, wlen
);
189 static struct be_process_io be_process_gdbproxy_io
=
191 NULL
, /* we shouldn't use close_process() in gdbproxy */
192 tgt_process_gdbproxy_read
,
193 tgt_process_gdbproxy_write
196 /* =============================================== *
197 * B A S I C M A N I P U L A T I O N S *
198 * =============================================== *
201 static inline int hex_from0(char ch
)
203 if (ch
>= '0' && ch
<= '9') return ch
- '0';
204 if (ch
>= 'A' && ch
<= 'F') return ch
- 'A' + 10;
205 if (ch
>= 'a' && ch
<= 'f') return ch
- 'a' + 10;
211 static inline unsigned char hex_to0(int x
)
213 assert(x
>= 0 && x
< 16);
214 return "0123456789abcdef"[x
];
217 static void hex_from(void* dst
, const char* src
, size_t len
)
219 unsigned char *p
= dst
;
222 *p
++ = (hex_from0(src
[0]) << 4) | hex_from0(src
[1]);
227 static void hex_to(char* dst
, const void* src
, size_t len
)
229 const unsigned char *p
= src
;
232 *dst
++ = hex_to0(*p
>> 4);
233 *dst
++ = hex_to0(*p
& 0x0F);
238 static void reply_buffer_clear(struct reply_buffer
* reply
)
243 static void reply_buffer_grow(struct reply_buffer
* reply
, size_t size
)
245 size_t required_alloc
= reply
->len
+ size
;
247 if (reply
->alloc
< required_alloc
)
249 reply
->alloc
= reply
->alloc
* 3 / 2;
250 if (reply
->alloc
< required_alloc
)
251 reply
->alloc
= required_alloc
;
253 reply
->base
= realloc(reply
->base
, reply
->alloc
);
257 static void reply_buffer_append(struct reply_buffer
* reply
, const void* data
, size_t size
)
259 reply_buffer_grow(reply
, size
);
260 memcpy(reply
->base
+ reply
->len
, data
, size
);
264 static inline void reply_buffer_append_str(struct reply_buffer
* reply
, const char* str
)
266 reply_buffer_append(reply
, str
, strlen(str
));
269 static inline void reply_buffer_append_wstr(struct reply_buffer
* reply
, const WCHAR
* wstr
)
274 len
= WideCharToMultiByte(CP_ACP
, 0, wstr
, -1, NULL
, 0, NULL
, NULL
);
276 if (str
&& WideCharToMultiByte(CP_ACP
, 0, wstr
, -1, str
, len
, NULL
, NULL
))
277 reply_buffer_append_str(reply
, str
);
281 static inline void reply_buffer_append_hex(struct reply_buffer
* reply
, const void* src
, size_t len
)
283 reply_buffer_grow(reply
, len
* 2);
284 hex_to((char *)reply
->base
+ reply
->len
, src
, len
);
285 reply
->len
+= len
* 2;
288 static inline void reply_buffer_append_uinthex(struct reply_buffer
* reply
, ULONG_PTR val
, int len
)
290 char buf
[sizeof(ULONG_PTR
) * 2], *ptr
;
292 assert(len
<= sizeof(ULONG_PTR
));
297 *--ptr
= hex_to0(val
& 0x0F);
301 reply_buffer_append(reply
, ptr
, len
* 2);
304 static const unsigned char xml_special_chars_lookup_table
[16] = {
305 /* The characters should be sorted by its value modulo table length. */
309 0x22, /* ": 0010|0010 */
311 0x26, /* &: 0010|0110 */
312 0x27, /* ': 0010|0111 */
314 0x3C, /* <: 0011|1100 */
316 0x3E, /* >: 0011|1110 */
320 static inline BOOL
is_nul_or_xml_special_char(unsigned char val
)
322 const size_t length
= ARRAY_SIZE(xml_special_chars_lookup_table
);
323 return xml_special_chars_lookup_table
[val
% length
] == val
;
326 static void reply_buffer_append_xmlstr(struct reply_buffer
* reply
, const char* str
)
328 const char *ptr
= str
, *curr
;
334 while (!is_nul_or_xml_special_char((unsigned char)*ptr
))
337 reply_buffer_append(reply
, curr
, ptr
- curr
);
341 case '"': reply_buffer_append_str(reply
, """); break;
342 case '&': reply_buffer_append_str(reply
, "&"); break;
343 case '\'': reply_buffer_append_str(reply
, "'"); break;
344 case '<': reply_buffer_append_str(reply
, "<"); break;
345 case '>': reply_buffer_append_str(reply
, ">"); break;
353 static unsigned char checksum(const void* data
, int len
)
356 const unsigned char* ptr
= data
;
363 static inline void* cpu_register_ptr(struct gdb_context
*gdbctx
,
364 dbg_ctx_t
*ctx
, unsigned idx
)
366 assert(idx
< gdbctx
->process
->be_cpu
->gdb_num_regs
);
367 return (char*)ctx
+ gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].offset
;
370 static inline DWORD64
cpu_register(struct gdb_context
*gdbctx
,
371 dbg_ctx_t
*ctx
, unsigned idx
)
373 switch (gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].length
)
375 case 1: return *(BYTE
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
376 case 2: return *(WORD
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
377 case 4: return *(DWORD
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
378 case 8: return *(DWORD64
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
380 ERR("got unexpected size: %u\n",
381 (unsigned)gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].length
);
387 static inline void cpu_register_hex_from(struct gdb_context
*gdbctx
,
388 dbg_ctx_t
* ctx
, unsigned idx
, const char **phex
)
390 const struct gdb_register
*cpu_register_map
= gdbctx
->process
->be_cpu
->gdb_register_map
;
391 hex_from(cpu_register_ptr(gdbctx
, ctx
, idx
), *phex
, cpu_register_map
[idx
].length
);
394 /* =============================================== *
395 * W I N 3 2 D E B U G I N T E R F A C E *
396 * =============================================== *
399 static struct dbg_thread
* dbg_thread_from_tid(struct gdb_context
* gdbctx
, int tid
)
401 struct dbg_process
*process
= gdbctx
->process
;
402 struct dbg_thread
*thread
;
404 if (!process
) return NULL
;
406 if (tid
== 0) tid
= gdbctx
->de
.dwThreadId
;
407 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
409 if (tid
> 0 && thread
->tid
!= tid
) continue;
416 static void dbg_thread_set_single_step(struct dbg_thread
*thread
, BOOL enable
)
418 struct backend_cpu
*backend
;
422 if (!thread
->process
) return;
423 if (!(backend
= thread
->process
->be_cpu
)) return;
425 if (!backend
->get_context(thread
->handle
, &ctx
))
427 ERR("get_context failed for thread %04lx:%04lx\n", thread
->process
->pid
, thread
->tid
);
430 backend
->single_step(&ctx
, enable
);
431 if (!backend
->set_context(thread
->handle
, &ctx
))
432 ERR("set_context failed for thread %04lx:%04lx\n", thread
->process
->pid
, thread
->tid
);
435 static unsigned char signal_from_debug_event(DEBUG_EVENT
* de
)
439 if (de
->dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
441 if (de
->dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
444 ec
= de
->u
.Exception
.ExceptionRecord
.ExceptionCode
;
447 case EXCEPTION_ACCESS_VIOLATION
:
448 case EXCEPTION_PRIV_INSTRUCTION
:
449 case EXCEPTION_STACK_OVERFLOW
:
450 case EXCEPTION_GUARD_PAGE
:
452 case EXCEPTION_DATATYPE_MISALIGNMENT
:
454 case EXCEPTION_SINGLE_STEP
:
455 case EXCEPTION_BREAKPOINT
:
457 case EXCEPTION_FLT_DENORMAL_OPERAND
:
458 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
459 case EXCEPTION_FLT_INEXACT_RESULT
:
460 case EXCEPTION_FLT_INVALID_OPERATION
:
461 case EXCEPTION_FLT_OVERFLOW
:
462 case EXCEPTION_FLT_STACK_CHECK
:
463 case EXCEPTION_FLT_UNDERFLOW
:
465 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
466 case EXCEPTION_INT_OVERFLOW
:
468 case EXCEPTION_ILLEGAL_INSTRUCTION
:
472 case STATUS_POSSIBLE_DEADLOCK
:
474 /* should not be here */
475 case EXCEPTION_INVALID_HANDLE
:
476 case EXCEPTION_WINE_NAME_THREAD
:
479 ERR("Unknown exception code 0x%08lx\n", ec
);
484 static BOOL
handle_exception(struct gdb_context
* gdbctx
, EXCEPTION_DEBUG_INFO
* exc
)
486 EXCEPTION_RECORD
* rec
= &exc
->ExceptionRecord
;
488 switch (rec
->ExceptionCode
)
490 case EXCEPTION_WINE_NAME_THREAD
:
492 const THREADNAME_INFO
*threadname
= (const THREADNAME_INFO
*)rec
->ExceptionInformation
;
493 struct dbg_thread
*thread
;
497 if (threadname
->dwType
!= 0x1000)
499 if (threadname
->dwThreadID
== -1)
500 thread
= dbg_get_thread(gdbctx
->process
, gdbctx
->de
.dwThreadId
);
502 thread
= dbg_get_thread(gdbctx
->process
, threadname
->dwThreadID
);
505 if (gdbctx
->process
->process_io
->read( gdbctx
->process
->handle
,
506 threadname
->szName
, name
, sizeof(name
), &read
) && read
== sizeof(name
))
508 fprintf(stderr
, "Thread ID=%04lx renamed to \"%.9s\"\n",
509 threadname
->dwThreadID
, name
);
513 ERR("Cannot set name of thread %04lx\n", threadname
->dwThreadID
);
516 case EXCEPTION_INVALID_HANDLE
:
523 static BOOL
handle_debug_event(struct gdb_context
* gdbctx
, BOOL stop_on_dll_load_unload
)
525 DEBUG_EVENT
*de
= &gdbctx
->de
;
526 struct dbg_thread
*thread
;
534 gdbctx
->exec_tid
= de
->dwThreadId
;
535 gdbctx
->other_tid
= de
->dwThreadId
;
536 gdbctx
->de_reply
= DBG_REPLY_LATER
;
538 switch (de
->dwDebugEventCode
)
540 case CREATE_PROCESS_DEBUG_EVENT
:
541 gdbctx
->process
= dbg_add_process(&be_process_gdbproxy_io
, de
->dwProcessId
,
542 de
->u
.CreateProcessInfo
.hProcess
);
543 if (!gdbctx
->process
)
546 size
= ARRAY_SIZE(u
.buffer
);
547 QueryFullProcessImageNameW( gdbctx
->process
->handle
, 0, u
.buffer
, &size
);
548 dbg_set_process_name(gdbctx
->process
, u
.buffer
);
550 fprintf(stderr
, "%04lx:%04lx: create process '%ls'/%p @%p (%lu<%lu>)\n",
551 de
->dwProcessId
, de
->dwThreadId
,
553 de
->u
.CreateProcessInfo
.lpImageName
,
554 de
->u
.CreateProcessInfo
.lpStartAddress
,
555 de
->u
.CreateProcessInfo
.dwDebugInfoFileOffset
,
556 de
->u
.CreateProcessInfo
.nDebugInfoSize
);
558 /* de->u.CreateProcessInfo.lpStartAddress; */
559 if (!dbg_init(gdbctx
->process
->handle
, u
.buffer
, TRUE
))
560 ERR("Couldn't initiate DbgHelp\n");
562 fprintf(stderr
, "%04lx:%04lx: create thread I @%p\n", de
->dwProcessId
,
563 de
->dwThreadId
, de
->u
.CreateProcessInfo
.lpStartAddress
);
565 dbg_load_module(gdbctx
->process
->handle
, de
->u
.CreateProcessInfo
.hFile
, u
.buffer
,
566 (DWORD_PTR
)de
->u
.CreateProcessInfo
.lpBaseOfImage
, 0);
568 dbg_add_thread(gdbctx
->process
, de
->dwThreadId
,
569 de
->u
.CreateProcessInfo
.hThread
,
570 de
->u
.CreateProcessInfo
.lpThreadLocalBase
);
573 case LOAD_DLL_DEBUG_EVENT
:
574 fetch_module_name( de
->u
.LoadDll
.lpImageName
, de
->u
.LoadDll
.lpBaseOfDll
,
575 u
.buffer
, ARRAY_SIZE(u
.buffer
) );
576 fprintf(stderr
, "%04lx:%04lx: loads DLL %ls @%p (%lu<%lu>)\n",
577 de
->dwProcessId
, de
->dwThreadId
,
579 de
->u
.LoadDll
.lpBaseOfDll
,
580 de
->u
.LoadDll
.dwDebugInfoFileOffset
,
581 de
->u
.LoadDll
.nDebugInfoSize
);
582 dbg_load_module(gdbctx
->process
->handle
, de
->u
.LoadDll
.hFile
, u
.buffer
,
583 (DWORD_PTR
)de
->u
.LoadDll
.lpBaseOfDll
, 0);
584 if (stop_on_dll_load_unload
)
588 case UNLOAD_DLL_DEBUG_EVENT
:
589 fprintf(stderr
, "%08lx:%08lx: unload DLL @%p\n",
590 de
->dwProcessId
, de
->dwThreadId
, de
->u
.UnloadDll
.lpBaseOfDll
);
591 SymUnloadModule(gdbctx
->process
->handle
,
592 (DWORD_PTR
)de
->u
.UnloadDll
.lpBaseOfDll
);
593 if (stop_on_dll_load_unload
)
597 case EXCEPTION_DEBUG_EVENT
:
598 TRACE("%08lx:%08lx: exception code=0x%08lx\n", de
->dwProcessId
,
599 de
->dwThreadId
, de
->u
.Exception
.ExceptionRecord
.ExceptionCode
);
601 if (handle_exception(gdbctx
, &de
->u
.Exception
))
605 case CREATE_THREAD_DEBUG_EVENT
:
606 fprintf(stderr
, "%08lx:%08lx: create thread D @%p\n", de
->dwProcessId
,
607 de
->dwThreadId
, de
->u
.CreateThread
.lpStartAddress
);
609 dbg_add_thread(gdbctx
->process
,
611 de
->u
.CreateThread
.hThread
,
612 de
->u
.CreateThread
.lpThreadLocalBase
);
615 case EXIT_THREAD_DEBUG_EVENT
:
616 fprintf(stderr
, "%08lx:%08lx: exit thread (%lu)\n",
617 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitThread
.dwExitCode
);
618 if ((thread
= dbg_get_thread(gdbctx
->process
, de
->dwThreadId
)))
619 dbg_del_thread(thread
);
622 case EXIT_PROCESS_DEBUG_EVENT
:
623 fprintf(stderr
, "%08lx:%08lx: exit process (%lu)\n",
624 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitProcess
.dwExitCode
);
626 dbg_del_process(gdbctx
->process
);
627 gdbctx
->process
= NULL
;
630 case OUTPUT_DEBUG_STRING_EVENT
:
631 memory_get_string(gdbctx
->process
,
632 de
->u
.DebugString
.lpDebugStringData
, TRUE
,
633 de
->u
.DebugString
.fUnicode
, u
.bufferA
, sizeof(u
.bufferA
));
634 fprintf(stderr
, "%08lx:%08lx: output debug string (%s)\n",
635 de
->dwProcessId
, de
->dwThreadId
, debugstr_a(u
.bufferA
));
639 fprintf(stderr
, "%08lx:%08lx: rip error=%lu type=%lu\n", de
->dwProcessId
,
640 de
->dwThreadId
, de
->u
.RipInfo
.dwError
, de
->u
.RipInfo
.dwType
);
644 FIXME("%08lx:%08lx: unknown event (%lu)\n",
645 de
->dwProcessId
, de
->dwThreadId
, de
->dwDebugEventCode
);
648 LIST_FOR_EACH_ENTRY(thread
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
650 if (!thread
->suspended
) SuspendThread(thread
->handle
);
651 thread
->suspended
= TRUE
;
657 static void handle_step_or_continue(struct gdb_context
* gdbctx
, int tid
, BOOL step
, int sig
)
659 struct dbg_process
*process
= gdbctx
->process
;
660 struct dbg_thread
*thread
;
662 if (tid
== 0) tid
= gdbctx
->de
.dwThreadId
;
663 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
665 if (tid
!= -1 && thread
->tid
!= tid
) continue;
666 if (!thread
->suspended
) continue;
667 thread
->suspended
= FALSE
;
669 if (process
->pid
== gdbctx
->de
.dwProcessId
&& thread
->tid
== gdbctx
->de
.dwThreadId
)
670 gdbctx
->de_reply
= (sig
== -1 ? DBG_CONTINUE
: DBG_EXCEPTION_NOT_HANDLED
);
672 dbg_thread_set_single_step(thread
, step
);
673 ResumeThread(thread
->handle
);
677 static BOOL
check_for_interrupt(struct gdb_context
* gdbctx
)
681 struct timeval tv
= { 0, 0 };
683 FD_ZERO( &read_fds
);
684 FD_SET( gdbctx
->sock
, &read_fds
);
686 if (select( 0, &read_fds
, NULL
, NULL
, &tv
) > 0)
688 if (recv(gdbctx
->sock
, &pkt
, 1, 0) != 1) {
689 ERR("read failed\n");
693 ERR("Unexpected break packet %#02x\n", pkt
);
701 static void wait_for_debuggee(struct gdb_context
* gdbctx
)
703 if (gdbctx
->de
.dwDebugEventCode
)
704 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, gdbctx
->de_reply
);
708 if (!WaitForDebugEvent(&gdbctx
->de
, 10))
710 if (GetLastError() == ERROR_SEM_TIMEOUT
)
712 if (check_for_interrupt(gdbctx
)) {
713 if (!DebugBreakProcess(gdbctx
->process
->handle
)) {
714 ERR("Failed to break into debuggee\n");
717 WaitForDebugEvent(&gdbctx
->de
, INFINITE
);
725 if (!handle_debug_event(gdbctx
, TRUE
))
727 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
731 static void detach_debuggee(struct gdb_context
* gdbctx
, BOOL kill
)
733 handle_step_or_continue(gdbctx
, -1, FALSE
, -1);
735 if (gdbctx
->de
.dwDebugEventCode
)
736 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
739 DebugActiveProcessStop(gdbctx
->process
->pid
);
740 dbg_del_process(gdbctx
->process
);
741 gdbctx
->process
= NULL
;
744 static void get_process_info(struct gdb_context
* gdbctx
, char* buffer
, size_t len
)
748 if (!GetExitCodeProcess(gdbctx
->process
->handle
, &status
))
750 strcpy(buffer
, "Unknown process");
753 if (status
== STILL_ACTIVE
)
755 strcpy(buffer
, "Running");
758 snprintf(buffer
, len
, "Terminated (%lu)", status
);
760 switch (GetPriorityClass(gdbctx
->process
->handle
))
763 case ABOVE_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", above normal priority"); break;
764 case BELOW_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", below normal priority"); break;
765 case HIGH_PRIORITY_CLASS
: strcat(buffer
, ", high priority"); break;
766 case IDLE_PRIORITY_CLASS
: strcat(buffer
, ", idle priority"); break;
767 case NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", normal priority"); break;
768 case REALTIME_PRIORITY_CLASS
: strcat(buffer
, ", realtime priority"); break;
770 strcat(buffer
, "\n");
773 static void get_thread_info(struct gdb_context
* gdbctx
, unsigned tid
,
774 char* buffer
, size_t len
)
776 struct dbg_thread
* thd
;
780 /* FIXME: use the size of buffer */
781 thd
= dbg_get_thread(gdbctx
->process
, tid
);
784 strcpy(buffer
, "No information");
787 if (GetExitCodeThread(thd
->handle
, &status
))
789 if (status
== STILL_ACTIVE
)
791 /* FIXME: this is a bit brutal... some nicer way shall be found */
792 switch (status
= SuspendThread(thd
->handle
))
795 case 0: strcpy(buffer
, "Running"); break;
796 default: snprintf(buffer
, len
, "Suspended (%lu)", status
- 1);
798 ResumeThread(thd
->handle
);
801 snprintf(buffer
, len
, "Terminated (exit code = %lu)", status
);
805 strcpy(buffer
, "Unknown threadID");
807 switch (prio
= GetThreadPriority(thd
->handle
))
809 case THREAD_PRIORITY_ERROR_RETURN
: break;
810 case THREAD_PRIORITY_ABOVE_NORMAL
: strcat(buffer
, ", priority +1 above normal"); break;
811 case THREAD_PRIORITY_BELOW_NORMAL
: strcat(buffer
, ", priority -1 below normal"); break;
812 case THREAD_PRIORITY_HIGHEST
: strcat(buffer
, ", priority +2 above normal"); break;
813 case THREAD_PRIORITY_LOWEST
: strcat(buffer
, ", priority -2 below normal"); break;
814 case THREAD_PRIORITY_IDLE
: strcat(buffer
, ", priority idle"); break;
815 case THREAD_PRIORITY_NORMAL
: strcat(buffer
, ", priority normal"); break;
816 case THREAD_PRIORITY_TIME_CRITICAL
: strcat(buffer
, ", priority time-critical"); break;
817 default: snprintf(buffer
+ strlen(buffer
), len
- strlen(buffer
), ", priority = %d", prio
);
819 assert(strlen(buffer
) < len
);
822 /* =============================================== *
823 * P A C K E T U T I L S *
824 * =============================================== *
827 static int addr_width(struct gdb_context
* gdbctx
)
829 int sz
= (gdbctx
&& gdbctx
->process
&& gdbctx
->process
->be_cpu
) ?
830 gdbctx
->process
->be_cpu
->pointer_size
: (int)sizeof(void*);
834 enum packet_return
{packet_error
= 0x00, packet_ok
= 0x01, packet_done
= 0x02,
835 packet_send_buffer
= 0x03, packet_last_f
= 0x80};
837 static void packet_reply_hex_to(struct gdb_context
* gdbctx
, const void* src
, int len
)
839 reply_buffer_append_hex(&gdbctx
->out_buf
, src
, len
);
842 static inline void packet_reply_hex_to_str(struct gdb_context
* gdbctx
, const char* src
)
844 packet_reply_hex_to(gdbctx
, src
, strlen(src
));
847 static void packet_reply_val(struct gdb_context
* gdbctx
, ULONG_PTR val
, int len
)
849 reply_buffer_append_uinthex(&gdbctx
->out_buf
, val
, len
);
852 static const unsigned char gdb_special_chars_lookup_table
[4] = {
853 /* The characters should be indexed by its value modulo table length. */
855 0x24, /* $: 001001|00 */
856 0x7D, /* }: 011111|01 */
857 0x2A, /* *: 001010|10 */
858 0x23 /* #: 001000|11 */
861 static inline BOOL
is_gdb_special_char(unsigned char val
)
863 /* A note on the GDB special character scanning code:
865 * We cannot use strcspn() since we plan to transmit binary data in
866 * packet reply, which can contain NULL (0x00) bytes. We also don't want
867 * to slow down memory dump transfers. Therefore, we use a tiny lookup
868 * table that contains all the four special characters to speed up scanning.
870 const size_t length
= ARRAY_SIZE(gdb_special_chars_lookup_table
);
871 return gdb_special_chars_lookup_table
[val
% length
] == val
;
874 static void packet_reply_add_data(struct gdb_context
* gdbctx
, const void* data
, size_t len
)
876 const unsigned char *ptr
= data
, *end
= ptr
+ len
, *curr
;
877 unsigned char esc_seq
[2];
883 while (ptr
!= end
&& !is_gdb_special_char(*ptr
))
886 reply_buffer_append(&gdbctx
->out_buf
, curr
, ptr
- curr
);
887 if (ptr
== end
) break;
890 esc_seq
[1] = 0x20 ^ *ptr
++;
891 reply_buffer_append(&gdbctx
->out_buf
, esc_seq
, 2);
895 static inline void packet_reply_add(struct gdb_context
* gdbctx
, const char* str
)
897 packet_reply_add_data(gdbctx
, str
, strlen(str
));
900 static void packet_reply_open(struct gdb_context
* gdbctx
)
902 assert(gdbctx
->out_curr_packet
== -1);
903 reply_buffer_append(&gdbctx
->out_buf
, "$", 1);
904 gdbctx
->out_curr_packet
= gdbctx
->out_buf
.len
;
907 static void packet_reply_close(struct gdb_context
* gdbctx
)
912 plen
= gdbctx
->out_buf
.len
- gdbctx
->out_curr_packet
;
913 reply_buffer_append(&gdbctx
->out_buf
, "#", 1);
914 cksum
= checksum(gdbctx
->out_buf
.base
+ gdbctx
->out_curr_packet
, plen
);
915 packet_reply_hex_to(gdbctx
, &cksum
, 1);
916 gdbctx
->out_curr_packet
= -1;
919 static enum packet_return
packet_reply(struct gdb_context
* gdbctx
, const char* packet
)
921 packet_reply_open(gdbctx
);
923 packet_reply_add(gdbctx
, packet
);
925 packet_reply_close(gdbctx
);
930 static enum packet_return
packet_reply_error(struct gdb_context
* gdbctx
, int error
)
932 packet_reply_open(gdbctx
);
934 packet_reply_add(gdbctx
, "E");
935 packet_reply_val(gdbctx
, error
, 1);
937 packet_reply_close(gdbctx
);
942 static inline void packet_reply_register_hex_to(struct gdb_context
* gdbctx
, dbg_ctx_t
* ctx
, unsigned idx
)
944 const struct gdb_register
*cpu_register_map
= gdbctx
->process
->be_cpu
->gdb_register_map
;
945 packet_reply_hex_to(gdbctx
, cpu_register_ptr(gdbctx
, ctx
, idx
), cpu_register_map
[idx
].length
);
948 static void packet_reply_xfer(struct gdb_context
* gdbctx
, size_t off
, size_t len
, BOOL
* more_p
)
951 size_t data_len
, trunc_len
;
953 packet_reply_open(gdbctx
);
954 data_len
= gdbctx
->qxfer_buffer
.len
;
956 /* check if off + len would overflow */
957 more
= off
< data_len
&& off
+ len
< data_len
;
959 packet_reply_add(gdbctx
, "m");
961 packet_reply_add(gdbctx
, "l");
965 trunc_len
= min(len
, data_len
- off
);
966 packet_reply_add_data(gdbctx
, gdbctx
->qxfer_buffer
.base
+ off
, trunc_len
);
969 packet_reply_close(gdbctx
);
974 /* =============================================== *
975 * P A C K E T H A N D L E R S *
976 * =============================================== *
979 static void packet_reply_status_xpoints(struct gdb_context
* gdbctx
, struct dbg_thread
*thread
,
982 struct dbg_process
*process
= thread
->process
;
983 struct backend_cpu
*cpu
= process
->be_cpu
;
984 struct gdb_xpoint
*x
;
986 LIST_FOR_EACH_ENTRY(x
, &gdbctx
->xpoint_list
, struct gdb_xpoint
, entry
)
988 if (x
->pid
!= process
->pid
|| x
->tid
!= thread
->tid
)
990 if (!cpu
->is_watchpoint_set(ctx
, x
->value
))
992 if (x
->type
== be_xpoint_watch_write
)
994 packet_reply_add(gdbctx
, "watch:");
995 packet_reply_val(gdbctx
, (ULONG_PTR
)x
->addr
, sizeof(x
->addr
));
996 packet_reply_add(gdbctx
, ";");
998 if (x
->type
== be_xpoint_watch_read
)
1000 packet_reply_add(gdbctx
, "rwatch:");
1001 packet_reply_val(gdbctx
, (ULONG_PTR
)x
->addr
, sizeof(x
->addr
));
1002 packet_reply_add(gdbctx
, ";");
1007 static void packet_reply_begin_stop_reply(struct gdb_context
* gdbctx
, unsigned char signal
)
1009 packet_reply_add(gdbctx
, "T");
1010 packet_reply_val(gdbctx
, signal
, 1);
1012 /* We should always report the current thread ID for all stop replies.
1013 * Otherwise, GDB complains with the following message:
1015 * Warning: multi-threaded target stopped without sending a thread-id,
1016 * using first non-exited thread
1018 packet_reply_add(gdbctx
, "thread:");
1019 packet_reply_val(gdbctx
, gdbctx
->de
.dwThreadId
, 4);
1020 packet_reply_add(gdbctx
, ";");
1023 static enum packet_return
packet_reply_status(struct gdb_context
* gdbctx
)
1025 struct dbg_process
*process
= gdbctx
->process
;
1026 struct dbg_thread
*thread
;
1027 struct backend_cpu
*backend
;
1031 switch (gdbctx
->de
.dwDebugEventCode
)
1034 if (!process
) return packet_error
;
1035 if (!(backend
= process
->be_cpu
)) return packet_error
;
1036 if (!(thread
= dbg_get_thread(process
, gdbctx
->de
.dwThreadId
)) ||
1037 !backend
->get_context(thread
->handle
, &ctx
))
1038 return packet_error
;
1040 packet_reply_open(gdbctx
);
1041 packet_reply_begin_stop_reply(gdbctx
, signal_from_debug_event(&gdbctx
->de
));
1042 packet_reply_status_xpoints(gdbctx
, thread
, &ctx
);
1044 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1046 packet_reply_val(gdbctx
, i
, 1);
1047 packet_reply_add(gdbctx
, ":");
1048 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
1049 packet_reply_add(gdbctx
, ";");
1052 packet_reply_close(gdbctx
);
1055 case EXIT_PROCESS_DEBUG_EVENT
:
1056 packet_reply_open(gdbctx
);
1057 packet_reply_add(gdbctx
, "W");
1058 packet_reply_val(gdbctx
, gdbctx
->de
.u
.ExitProcess
.dwExitCode
, 4);
1059 packet_reply_close(gdbctx
);
1060 return packet_done
| packet_last_f
;
1062 case LOAD_DLL_DEBUG_EVENT
:
1063 case UNLOAD_DLL_DEBUG_EVENT
:
1064 packet_reply_open(gdbctx
);
1065 packet_reply_begin_stop_reply(gdbctx
, HOST_SIGTRAP
);
1066 packet_reply_add(gdbctx
, "library:;");
1067 packet_reply_close(gdbctx
);
1072 static enum packet_return
packet_last_signal(struct gdb_context
* gdbctx
)
1074 assert(gdbctx
->in_packet_len
== 0);
1075 return packet_reply_status(gdbctx
);
1078 static enum packet_return
packet_continue(struct gdb_context
* gdbctx
)
1082 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
1083 FIXME("Continue at address %p not supported\n", addr
);
1085 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, -1);
1087 wait_for_debuggee(gdbctx
);
1088 return packet_reply_status(gdbctx
);
1091 static enum packet_return
packet_verbose_cont(struct gdb_context
* gdbctx
)
1093 char *buf
= gdbctx
->in_packet
, *end
= gdbctx
->in_packet
+ gdbctx
->in_packet_len
;
1095 if (gdbctx
->in_packet
[4] == '?')
1097 packet_reply_open(gdbctx
);
1098 packet_reply_add(gdbctx
, "vCont");
1099 packet_reply_add(gdbctx
, ";c");
1100 packet_reply_add(gdbctx
, ";C");
1101 packet_reply_add(gdbctx
, ";s");
1102 packet_reply_add(gdbctx
, ";S");
1103 packet_reply_close(gdbctx
);
1107 while (buf
< end
&& (buf
= memchr(buf
+ 1, ';', end
- buf
- 1)))
1109 int tid
= -1, sig
= -1;
1112 switch ((action
= buf
[1]))
1115 return packet_error
;
1122 if (sscanf(buf
, ";%*c%2x", &sig
) <= 0 ||
1123 sig
!= signal_from_debug_event(&gdbctx
->de
))
1124 return packet_error
;
1130 return packet_error
;
1131 if (buf
< end
&& *buf
== ':' && (n
= sscanf(buf
, ":%x", &tid
)) <= 0)
1132 return packet_error
;
1134 handle_step_or_continue(gdbctx
, tid
, action
== 's' || action
== 'S', sig
);
1137 wait_for_debuggee(gdbctx
);
1138 return packet_reply_status(gdbctx
);
1141 static enum packet_return
packet_verbose(struct gdb_context
* gdbctx
)
1143 if (gdbctx
->in_packet_len
>= 4 && !memcmp(gdbctx
->in_packet
, "Cont", 4))
1145 return packet_verbose_cont(gdbctx
);
1148 if (gdbctx
->in_packet_len
== 14 && !memcmp(gdbctx
->in_packet
, "MustReplyEmpty", 14))
1149 return packet_reply(gdbctx
, "");
1151 return packet_error
;
1154 static enum packet_return
packet_continue_signal(struct gdb_context
* gdbctx
)
1159 if ((n
= sscanf(gdbctx
->in_packet
, "%x;%p", &sig
, &addr
)) == 2)
1160 FIXME("Continue at address %p not supported\n", addr
);
1161 if (n
< 1) return packet_error
;
1163 if (sig
!= signal_from_debug_event(&gdbctx
->de
))
1165 ERR("Changing signals is not supported.\n");
1166 return packet_error
;
1169 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, sig
);
1171 wait_for_debuggee(gdbctx
);
1172 return packet_reply_status(gdbctx
);
1175 static enum packet_return
packet_delete_breakpoint(struct gdb_context
* gdbctx
)
1177 struct dbg_process
*process
= gdbctx
->process
;
1178 struct dbg_thread
*thread
;
1179 struct backend_cpu
*cpu
;
1180 struct gdb_xpoint
*x
;
1186 if (!process
) return packet_error
;
1187 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1189 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1190 return packet_error
;
1193 return packet_error
;
1195 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1197 if (!cpu
->get_context(thread
->handle
, &ctx
))
1199 if ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_exec
, addr
, size
)))
1200 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1201 if ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_read
, addr
, size
)))
1202 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1203 if ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_write
, addr
, size
)))
1204 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1205 cpu
->set_context(thread
->handle
, &ctx
);
1208 while ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_exec
, addr
, size
)))
1209 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1210 while ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_read
, addr
, size
)))
1211 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1212 while ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_write
, addr
, size
)))
1213 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1218 static enum packet_return
packet_insert_breakpoint(struct gdb_context
* gdbctx
)
1220 struct dbg_process
*process
= gdbctx
->process
;
1221 struct dbg_thread
*thread
;
1222 struct backend_cpu
*cpu
;
1228 if (!process
) return packet_error
;
1229 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1231 if (memchr(gdbctx
->in_packet
, ';', gdbctx
->in_packet_len
))
1233 FIXME("breakpoint commands not supported\n");
1234 return packet_error
;
1237 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1238 return packet_error
;
1241 return packet_error
;
1243 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1245 if (!cpu
->get_context(thread
->handle
, &ctx
))
1248 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_exec
, addr
, size
);
1249 if (type
== '2' || type
== '4')
1250 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_read
, addr
, size
);
1251 if (type
== '3' || type
== '4')
1252 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_write
, addr
, size
);
1253 cpu
->set_context(thread
->handle
, &ctx
);
1259 static enum packet_return
packet_detach(struct gdb_context
* gdbctx
)
1261 detach_debuggee(gdbctx
, FALSE
);
1262 return packet_ok
| packet_last_f
;
1265 static enum packet_return
packet_read_registers(struct gdb_context
* gdbctx
)
1267 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1268 struct backend_cpu
*backend
;
1272 if (!thread
) return packet_error
;
1273 if (!thread
->process
) return packet_error
;
1274 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1276 if (!backend
->get_context(thread
->handle
, &ctx
))
1277 return packet_error
;
1279 packet_reply_open(gdbctx
);
1280 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1281 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
1283 packet_reply_close(gdbctx
);
1287 static enum packet_return
packet_write_registers(struct gdb_context
* gdbctx
)
1289 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1290 struct backend_cpu
*backend
;
1295 if (!thread
) return packet_error
;
1296 if (!thread
->process
) return packet_error
;
1297 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1299 if (!backend
->get_context(thread
->handle
, &ctx
))
1300 return packet_error
;
1302 if (gdbctx
->in_packet_len
< backend
->gdb_num_regs
* 2)
1303 return packet_error
;
1305 ptr
= gdbctx
->in_packet
;
1306 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1307 cpu_register_hex_from(gdbctx
, &ctx
, i
, &ptr
);
1309 if (!backend
->set_context(thread
->handle
, &ctx
))
1311 ERR("Failed to set context for tid %04lx, error %lu\n", thread
->tid
, GetLastError());
1312 return packet_error
;
1318 static enum packet_return
packet_kill(struct gdb_context
* gdbctx
)
1320 detach_debuggee(gdbctx
, TRUE
);
1321 return packet_ok
| packet_last_f
;
1324 static enum packet_return
packet_thread(struct gdb_context
* gdbctx
)
1326 switch (gdbctx
->in_packet
[0])
1329 if (sscanf(gdbctx
->in_packet
, "c%x", &gdbctx
->exec_tid
) == 1)
1331 return packet_error
;
1333 if (sscanf(gdbctx
->in_packet
, "g%x", &gdbctx
->other_tid
) == 1)
1335 return packet_error
;
1337 FIXME("Unknown thread sub-command %c\n", gdbctx
->in_packet
[0]);
1338 return packet_error
;
1342 static enum packet_return
packet_read_memory(struct gdb_context
* gdbctx
)
1345 unsigned int len
, blk_len
, nread
;
1349 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2) return packet_error
;
1350 if (len
<= 0) return packet_error
;
1351 TRACE("Read %u bytes at %p\n", len
, addr
);
1352 for (nread
= 0; nread
< len
; nread
+= r
, addr
+= r
)
1354 blk_len
= min(sizeof(buffer
), len
- nread
);
1355 if (!gdbctx
->process
->process_io
->read(gdbctx
->process
->handle
, addr
,
1356 buffer
, blk_len
, &r
) || r
== 0)
1358 /* fail at first address, return error */
1359 if (nread
== 0) return packet_reply_error(gdbctx
, HOST_EFAULT
);
1360 /* something has already been read, return partial information */
1363 if (nread
== 0) packet_reply_open(gdbctx
);
1364 packet_reply_hex_to(gdbctx
, buffer
, r
);
1366 packet_reply_close(gdbctx
);
1370 static enum packet_return
packet_write_memory(struct gdb_context
* gdbctx
)
1373 unsigned int len
, blk_len
;
1378 ptr
= memchr(gdbctx
->in_packet
, ':', gdbctx
->in_packet_len
);
1381 ERR("Cannot find ':' in %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1382 return packet_error
;
1386 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2)
1388 ERR("Failed to parse %s\n", debugstr_a(gdbctx
->in_packet
));
1389 return packet_error
;
1391 if (ptr
- gdbctx
->in_packet
+ len
* 2 != gdbctx
->in_packet_len
)
1393 ERR("Length %u does not match packet length %u\n",
1394 (int)(ptr
- gdbctx
->in_packet
) + len
* 2, gdbctx
->in_packet_len
);
1395 return packet_error
;
1397 TRACE("Write %u bytes at %p\n", len
, addr
);
1400 blk_len
= min(sizeof(buffer
), len
);
1401 hex_from(buffer
, ptr
, blk_len
);
1402 if (!gdbctx
->process
->process_io
->write(gdbctx
->process
->handle
, addr
, buffer
, blk_len
, &w
) ||
1409 return packet_ok
; /* FIXME: error while writing ? */
1412 static enum packet_return
packet_read_register(struct gdb_context
* gdbctx
)
1414 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1415 struct backend_cpu
*backend
;
1419 if (!thread
) return packet_error
;
1420 if (!thread
->process
) return packet_error
;
1421 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1423 if (!backend
->get_context(thread
->handle
, &ctx
))
1424 return packet_error
;
1426 if (sscanf(gdbctx
->in_packet
, "%Ix", ®
) != 1)
1427 return packet_error
;
1428 if (reg
>= backend
->gdb_num_regs
)
1430 WARN("Unhandled register %Iu\n", reg
);
1431 return packet_error
;
1434 TRACE("%Iu => %I64x\n", reg
, cpu_register(gdbctx
, &ctx
, reg
));
1436 packet_reply_open(gdbctx
);
1437 packet_reply_register_hex_to(gdbctx
, &ctx
, reg
);
1438 packet_reply_close(gdbctx
);
1442 static enum packet_return
packet_write_register(struct gdb_context
* gdbctx
)
1444 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1445 struct backend_cpu
*backend
;
1450 if (!thread
) return packet_error
;
1451 if (!thread
->process
) return packet_error
;
1452 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1454 if (!backend
->get_context(thread
->handle
, &ctx
))
1455 return packet_error
;
1457 if (!(ptr
= strchr(gdbctx
->in_packet
, '=')))
1458 return packet_error
;
1461 if (sscanf(gdbctx
->in_packet
, "%Ix", ®
) != 1)
1462 return packet_error
;
1463 if (reg
>= backend
->gdb_num_regs
)
1465 /* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
1466 * it wouldn't matter too much, and it fakes our support for all regs
1468 WARN("Unhandled register %Iu\n", reg
);
1472 TRACE("%Iu <= %s\n", reg
, debugstr_an(ptr
, (int)(gdbctx
->in_packet_len
- (ptr
- gdbctx
->in_packet
))));
1474 cpu_register_hex_from(gdbctx
, &ctx
, reg
, (const char**)&ptr
);
1475 if (!backend
->set_context(thread
->handle
, &ctx
))
1477 ERR("Failed to set context for tid %04lx, error %lu\n", thread
->tid
, GetLastError());
1478 return packet_error
;
1484 static void packet_query_monitor_wnd_helper(struct gdb_context
* gdbctx
, HWND hWnd
, int indent
)
1492 if (!GetClassNameA(hWnd
, clsName
, sizeof(clsName
)))
1493 strcpy(clsName
, "-- Unknown --");
1494 if (!GetWindowTextA(hWnd
, wndName
, sizeof(wndName
)))
1495 strcpy(wndName
, "-- Empty --");
1497 packet_reply_open(gdbctx
);
1498 packet_reply_add(gdbctx
, "O");
1499 snprintf(buffer
, sizeof(buffer
),
1500 "%*s%04Ix%*s%-17.17s %08lx %0*Ix %.14s\n",
1501 indent
, "", (ULONG_PTR
)hWnd
, 13 - indent
, "",
1502 clsName
, GetWindowLongW(hWnd
, GWL_STYLE
),
1503 addr_width(gdbctx
), (ULONG_PTR
)GetWindowLongPtrW(hWnd
, GWLP_WNDPROC
),
1505 packet_reply_hex_to_str(gdbctx
, buffer
);
1506 packet_reply_close(gdbctx
);
1508 if ((child
= GetWindow(hWnd
, GW_CHILD
)) != 0)
1509 packet_query_monitor_wnd_helper(gdbctx
, child
, indent
+ 1);
1510 } while ((hWnd
= GetWindow(hWnd
, GW_HWNDNEXT
)) != 0);
1513 static void packet_query_monitor_wnd(struct gdb_context
* gdbctx
, int len
, const char* str
)
1517 /* we do the output in several 'O' packets, with the last one being just OK for
1518 * marking the end of the output */
1519 packet_reply_open(gdbctx
);
1520 packet_reply_add(gdbctx
, "O");
1521 snprintf(buffer
, sizeof(buffer
),
1522 "%-16.16s %-17.17s %-8.8s %s\n",
1523 "hwnd", "Class Name", " Style", " WndProc Text");
1524 packet_reply_hex_to_str(gdbctx
, buffer
);
1525 packet_reply_close(gdbctx
);
1527 /* FIXME: could also add a pmt to this command in str... */
1528 packet_query_monitor_wnd_helper(gdbctx
, GetDesktopWindow(), 0);
1529 packet_reply(gdbctx
, "OK");
1532 static void packet_query_monitor_process(struct gdb_context
* gdbctx
, int len
, const char* str
)
1534 HANDLE snap
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
1535 char buffer
[31+MAX_PATH
];
1537 PROCESSENTRY32 entry
;
1540 if (snap
== INVALID_HANDLE_VALUE
)
1543 entry
.dwSize
= sizeof(entry
);
1544 ok
= Process32First(snap
, &entry
);
1546 /* we do the output in several 'O' packets, with the last one being just OK for
1547 * marking the end of the output */
1549 packet_reply_open(gdbctx
);
1550 packet_reply_add(gdbctx
, "O");
1551 snprintf(buffer
, sizeof(buffer
),
1552 " %-8.8s %-8.8s %-8.8s %s\n",
1553 "pid", "threads", "parent", "executable");
1554 packet_reply_hex_to_str(gdbctx
, buffer
);
1555 packet_reply_close(gdbctx
);
1560 if (entry
.th32ProcessID
== gdbctx
->process
->pid
) deco
= '>';
1561 packet_reply_open(gdbctx
);
1562 packet_reply_add(gdbctx
, "O");
1563 snprintf(buffer
, sizeof(buffer
),
1564 "%c%08lx %-8ld %08lx '%s'\n",
1565 deco
, entry
.th32ProcessID
, entry
.cntThreads
,
1566 entry
.th32ParentProcessID
, entry
.szExeFile
);
1567 packet_reply_hex_to_str(gdbctx
, buffer
);
1568 packet_reply_close(gdbctx
);
1569 ok
= Process32Next(snap
, &entry
);
1572 packet_reply(gdbctx
, "OK");
1575 static void packet_query_monitor_mem(struct gdb_context
* gdbctx
, int len
, const char* str
)
1577 MEMORY_BASIC_INFORMATION mbi
;
1584 /* we do the output in several 'O' packets, with the last one being just OK for
1585 * marking the end of the output */
1586 packet_reply_open(gdbctx
);
1587 packet_reply_add(gdbctx
, "O");
1588 packet_reply_hex_to_str(gdbctx
, "Address Size State Type RWX\n");
1589 packet_reply_close(gdbctx
);
1591 while (VirtualQueryEx(gdbctx
->process
->handle
, addr
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
))
1595 case MEM_COMMIT
: state
= "commit "; break;
1596 case MEM_FREE
: state
= "free "; break;
1597 case MEM_RESERVE
: state
= "reserve"; break;
1598 default: state
= "??? "; break;
1600 if (mbi
.State
!= MEM_FREE
)
1604 case MEM_IMAGE
: type
= "image "; break;
1605 case MEM_MAPPED
: type
= "mapped "; break;
1606 case MEM_PRIVATE
: type
= "private"; break;
1607 case 0: type
= " "; break;
1608 default: type
= "??? "; break;
1610 memset(prot
, ' ' , sizeof(prot
)-1);
1611 prot
[sizeof(prot
)-1] = '\0';
1612 if (mbi
.AllocationProtect
& (PAGE_READONLY
|PAGE_READWRITE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
|PAGE_WRITECOPY
|PAGE_EXECUTE_WRITECOPY
))
1614 if (mbi
.AllocationProtect
& (PAGE_READWRITE
|PAGE_EXECUTE_READWRITE
))
1616 if (mbi
.AllocationProtect
& (PAGE_WRITECOPY
|PAGE_EXECUTE_WRITECOPY
))
1618 if (mbi
.AllocationProtect
& (PAGE_EXECUTE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
|PAGE_EXECUTE_WRITECOPY
))
1626 packet_reply_open(gdbctx
);
1627 snprintf(buffer
, sizeof(buffer
), "%0*Ix %0*Ix %s %s %s\n",
1628 addr_width(gdbctx
), (DWORD_PTR
)addr
,
1629 addr_width(gdbctx
), mbi
.RegionSize
, state
, type
, prot
);
1630 packet_reply_add(gdbctx
, "O");
1631 packet_reply_hex_to_str(gdbctx
, buffer
);
1632 packet_reply_close(gdbctx
);
1634 if (addr
+ mbi
.RegionSize
< addr
) /* wrap around ? */
1636 addr
+= mbi
.RegionSize
;
1638 packet_reply(gdbctx
, "OK");
1646 void (*handler
)(struct gdb_context
*, int, const char*);
1649 {0, "wnd", 3, packet_query_monitor_wnd
},
1650 {0, "window", 6, packet_query_monitor_wnd
},
1651 {0, "proc", 4, packet_query_monitor_process
},
1652 {0, "process", 7, packet_query_monitor_process
},
1653 {0, "mem", 3, packet_query_monitor_mem
},
1657 static enum packet_return
packet_query_remote_command(struct gdb_context
* gdbctx
,
1658 const char* hxcmd
, size_t len
)
1661 struct query_detail
* qd
;
1663 assert((len
& 1) == 0 && len
< 2 * sizeof(buffer
));
1665 hex_from(buffer
, hxcmd
, len
);
1667 for (qd
= query_details
; qd
->name
!= NULL
; qd
++)
1669 if (len
< qd
->len
|| strncmp(buffer
, qd
->name
, qd
->len
) != 0) continue;
1670 if (!qd
->with_arg
&& len
!= qd
->len
) continue;
1672 (qd
->handler
)(gdbctx
, len
- qd
->len
, buffer
+ qd
->len
);
1675 return packet_reply_error(gdbctx
, HOST_EINVAL
);
1678 static BOOL CALLBACK
packet_query_libraries_cb(PCSTR mod_name
, DWORD64 base
, PVOID ctx
)
1680 struct gdb_context
* gdbctx
= ctx
;
1681 struct reply_buffer
* reply
= &gdbctx
->qxfer_buffer
;
1682 MEMORY_BASIC_INFORMATION mbi
;
1683 IMAGE_SECTION_HEADER
*sec
;
1684 IMAGE_DOS_HEADER
*dos
= NULL
;
1685 IMAGE_NT_HEADERS
*nth
= NULL
;
1686 IMAGEHLP_MODULE64 mod
;
1691 mod
.SizeOfStruct
= sizeof(mod
);
1692 if (!SymGetModuleInfo64(gdbctx
->process
->handle
, base
, &mod
) ||
1693 mod
.MachineType
!= gdbctx
->process
->be_cpu
->machine
)
1696 reply_buffer_append_str(reply
, "<library name=\"");
1697 if (strcmp(mod
.LoadedImageName
, "[vdso].so") == 0)
1698 reply_buffer_append_xmlstr(reply
, "linux-vdso.so.1");
1699 else if (mod
.LoadedImageName
[0] == '/')
1700 reply_buffer_append_xmlstr(reply
, mod
.LoadedImageName
);
1703 UNICODE_STRING nt_name
;
1704 ANSI_STRING ansi_name
;
1705 char *unix_path
, *tmp
;
1707 RtlInitAnsiString(&ansi_name
, mod
.LoadedImageName
);
1708 RtlAnsiStringToUnicodeString(&nt_name
, &ansi_name
, TRUE
);
1710 if ((unix_path
= wine_get_unix_file_name(nt_name
.Buffer
)))
1712 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) &&
1713 is_wow64
&& (tmp
= strstr(unix_path
, "system32")))
1714 memcpy(tmp
, "syswow64", 8);
1715 reply_buffer_append_xmlstr(reply
, unix_path
);
1718 reply_buffer_append_xmlstr(reply
, mod
.LoadedImageName
);
1720 HeapFree(GetProcessHeap(), 0, unix_path
);
1721 RtlFreeUnicodeString(&nt_name
);
1723 reply_buffer_append_str(reply
, "\">");
1725 size
= sizeof(buffer
);
1726 if (VirtualQueryEx(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
) &&
1727 mbi
.Type
== MEM_IMAGE
&& mbi
.State
!= MEM_FREE
)
1729 if (ReadProcessMemory(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, buffer
, size
, &size
) &&
1730 size
>= sizeof(IMAGE_DOS_HEADER
))
1731 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1733 if (dos
&& dos
->e_magic
== IMAGE_DOS_SIGNATURE
&& dos
->e_lfanew
< size
)
1734 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1736 if (nth
&& memcmp(&nth
->Signature
, "PE\0\0", 4))
1740 if (!nth
) memset(buffer
, 0, sizeof(buffer
));
1742 /* if the module is not PE we have cleared buffer with 0, this makes
1743 * the following computation valid in all cases. */
1744 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1745 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1746 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) && is_wow64
)
1747 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS32
*)nth
);
1749 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS64
*)nth
);
1751 for (i
= 0; i
< max(nth
->FileHeader
.NumberOfSections
, 1); ++i
)
1753 if ((char *)(sec
+ i
) >= buffer
+ size
) break;
1754 reply_buffer_append_str(reply
, "<segment address=\"0x");
1755 reply_buffer_append_uinthex(reply
, mod
.BaseOfImage
+ sec
[i
].VirtualAddress
, sizeof(ULONG_PTR
));
1756 reply_buffer_append_str(reply
, "\"/>");
1759 reply_buffer_append_str(reply
, "</library>");
1764 static enum packet_return
packet_query_libraries(struct gdb_context
* gdbctx
)
1766 struct reply_buffer
* reply
= &gdbctx
->qxfer_buffer
;
1767 BOOL opt_native
, opt_real_path
;
1769 if (!gdbctx
->process
) return packet_error
;
1771 if (gdbctx
->qxfer_object_annex
[0])
1772 return packet_reply_error(gdbctx
, 0);
1774 /* this will resynchronize builtin dbghelp's internal ELF module list */
1775 SymLoadModule(gdbctx
->process
->handle
, 0, 0, 0, 0, 0);
1777 reply_buffer_append_str(reply
, "<library-list>");
1778 /* request also ELF modules, and also real path to loaded modules */
1779 opt_native
= SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, TRUE
);
1780 opt_real_path
= SymSetExtendedOption(SYMOPT_EX_WINE_MODULE_REAL_PATH
, TRUE
);
1781 SymEnumerateModules64(gdbctx
->process
->handle
, packet_query_libraries_cb
, gdbctx
);
1782 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, opt_native
);
1783 SymSetExtendedOption(SYMOPT_EX_WINE_MODULE_REAL_PATH
, opt_real_path
);
1784 reply_buffer_append_str(reply
, "</library-list>");
1786 return packet_send_buffer
;
1789 static enum packet_return
packet_query_threads(struct gdb_context
* gdbctx
)
1791 struct reply_buffer
* reply
= &gdbctx
->qxfer_buffer
;
1792 struct dbg_process
* process
= gdbctx
->process
;
1793 struct dbg_thread
* thread
;
1796 if (!process
) return packet_error
;
1798 if (gdbctx
->qxfer_object_annex
[0])
1799 return packet_reply_error(gdbctx
, 0);
1801 reply_buffer_append_str(reply
, "<threads>");
1802 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1804 reply_buffer_append_str(reply
, "<thread ");
1805 reply_buffer_append_str(reply
, "id=\"");
1806 reply_buffer_append_uinthex(reply
, thread
->tid
, 4);
1807 reply_buffer_append_str(reply
, "\" name=\"");
1808 if ((description
= fetch_thread_description(thread
->tid
)))
1810 reply_buffer_append_wstr(reply
, description
);
1811 LocalFree(description
);
1813 else if (strlen(thread
->name
))
1815 reply_buffer_append_str(reply
, thread
->name
);
1820 snprintf(tid
, sizeof(tid
), "%04lx", thread
->tid
);
1821 reply_buffer_append_str(reply
, tid
);
1823 reply_buffer_append_str(reply
, "\"/>");
1825 reply_buffer_append_str(reply
, "</threads>");
1827 return packet_send_buffer
;
1830 static void packet_query_target_xml(struct gdb_context
* gdbctx
, struct reply_buffer
* reply
, struct backend_cpu
* cpu
)
1832 const char* feature_prefix
= NULL
;
1833 const char* feature
= NULL
;
1837 reply_buffer_append_str(reply
, "<target>");
1838 switch (cpu
->machine
)
1840 case IMAGE_FILE_MACHINE_AMD64
:
1841 reply_buffer_append_str(reply
, "<architecture>i386:x86-64</architecture>");
1842 feature_prefix
= "org.gnu.gdb.i386.";
1844 case IMAGE_FILE_MACHINE_I386
:
1845 reply_buffer_append_str(reply
, "<architecture>i386</architecture>");
1846 feature_prefix
= "org.gnu.gdb.i386.";
1848 case IMAGE_FILE_MACHINE_ARMNT
:
1849 reply_buffer_append_str(reply
, "<architecture>arm</architecture>");
1850 feature_prefix
= "org.gnu.gdb.arm.";
1852 case IMAGE_FILE_MACHINE_ARM64
:
1853 reply_buffer_append_str(reply
, "<architecture>aarch64</architecture>");
1854 feature_prefix
= "org.gnu.gdb.aarch64.";
1858 for (i
= 0; i
< cpu
->gdb_num_regs
; ++i
)
1860 if (cpu
->gdb_register_map
[i
].feature
)
1862 if (feature
) reply_buffer_append_str(reply
, "</feature>");
1863 feature
= cpu
->gdb_register_map
[i
].feature
;
1865 reply_buffer_append_str(reply
, "<feature name=\"");
1866 if (feature_prefix
) reply_buffer_append_xmlstr(reply
, feature_prefix
);
1867 reply_buffer_append_xmlstr(reply
, feature
);
1868 reply_buffer_append_str(reply
, "\">");
1870 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1871 strcmp(feature
, "core") == 0)
1872 reply_buffer_append_str(reply
, "<flags id=\"i386_eflags\" size=\"4\">"
1873 "<field name=\"CF\" start=\"0\" end=\"0\"/>"
1874 "<field name=\"\" start=\"1\" end=\"1\"/>"
1875 "<field name=\"PF\" start=\"2\" end=\"2\"/>"
1876 "<field name=\"AF\" start=\"4\" end=\"4\"/>"
1877 "<field name=\"ZF\" start=\"6\" end=\"6\"/>"
1878 "<field name=\"SF\" start=\"7\" end=\"7\"/>"
1879 "<field name=\"TF\" start=\"8\" end=\"8\"/>"
1880 "<field name=\"IF\" start=\"9\" end=\"9\"/>"
1881 "<field name=\"DF\" start=\"10\" end=\"10\"/>"
1882 "<field name=\"OF\" start=\"11\" end=\"11\"/>"
1883 "<field name=\"NT\" start=\"14\" end=\"14\"/>"
1884 "<field name=\"RF\" start=\"16\" end=\"16\"/>"
1885 "<field name=\"VM\" start=\"17\" end=\"17\"/>"
1886 "<field name=\"AC\" start=\"18\" end=\"18\"/>"
1887 "<field name=\"VIF\" start=\"19\" end=\"19\"/>"
1888 "<field name=\"VIP\" start=\"20\" end=\"20\"/>"
1889 "<field name=\"ID\" start=\"21\" end=\"21\"/>"
1892 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1893 strcmp(feature
, "sse") == 0)
1894 reply_buffer_append_str(reply
, "<vector id=\"v4f\" type=\"ieee_single\" count=\"4\"/>"
1895 "<vector id=\"v2d\" type=\"ieee_double\" count=\"2\"/>"
1896 "<vector id=\"v16i8\" type=\"int8\" count=\"16\"/>"
1897 "<vector id=\"v8i16\" type=\"int16\" count=\"8\"/>"
1898 "<vector id=\"v4i32\" type=\"int32\" count=\"4\"/>"
1899 "<vector id=\"v2i64\" type=\"int64\" count=\"2\"/>"
1900 "<union id=\"vec128\">"
1901 "<field name=\"v4_float\" type=\"v4f\"/>"
1902 "<field name=\"v2_double\" type=\"v2d\"/>"
1903 "<field name=\"v16_int8\" type=\"v16i8\"/>"
1904 "<field name=\"v8_int16\" type=\"v8i16\"/>"
1905 "<field name=\"v4_int32\" type=\"v4i32\"/>"
1906 "<field name=\"v2_int64\" type=\"v2i64\"/>"
1907 "<field name=\"uint128\" type=\"uint128\"/>"
1909 "<flags id=\"i386_mxcsr\" size=\"4\">"
1910 "<field name=\"IE\" start=\"0\" end=\"0\"/>"
1911 "<field name=\"DE\" start=\"1\" end=\"1\"/>"
1912 "<field name=\"ZE\" start=\"2\" end=\"2\"/>"
1913 "<field name=\"OE\" start=\"3\" end=\"3\"/>"
1914 "<field name=\"UE\" start=\"4\" end=\"4\"/>"
1915 "<field name=\"PE\" start=\"5\" end=\"5\"/>"
1916 "<field name=\"DAZ\" start=\"6\" end=\"6\"/>"
1917 "<field name=\"IM\" start=\"7\" end=\"7\"/>"
1918 "<field name=\"DM\" start=\"8\" end=\"8\"/>"
1919 "<field name=\"ZM\" start=\"9\" end=\"9\"/>"
1920 "<field name=\"OM\" start=\"10\" end=\"10\"/>"
1921 "<field name=\"UM\" start=\"11\" end=\"11\"/>"
1922 "<field name=\"PM\" start=\"12\" end=\"12\"/>"
1923 "<field name=\"FZ\" start=\"15\" end=\"15\"/>"
1927 snprintf(buffer
, ARRAY_SIZE(buffer
), "<reg name=\"%s\" bitsize=\"%Iu\"",
1928 cpu
->gdb_register_map
[i
].name
, 8 * cpu
->gdb_register_map
[i
].length
);
1929 reply_buffer_append_str(reply
, buffer
);
1931 if (cpu
->gdb_register_map
[i
].type
)
1933 reply_buffer_append_str(reply
, " type=\"");
1934 reply_buffer_append_xmlstr(reply
, cpu
->gdb_register_map
[i
].type
);
1935 reply_buffer_append_str(reply
, "\"");
1938 reply_buffer_append_str(reply
, "/>");
1941 if (feature
) reply_buffer_append_str(reply
, "</feature>");
1942 reply_buffer_append_str(reply
, "</target>");
1945 static enum packet_return
packet_query_features(struct gdb_context
* gdbctx
)
1947 struct reply_buffer
* reply
= &gdbctx
->qxfer_buffer
;
1948 struct dbg_process
* process
= gdbctx
->process
;
1950 if (!process
) return packet_error
;
1952 if (strncmp(gdbctx
->qxfer_object_annex
, "target.xml", QX_ANNEX_SIZE
) == 0)
1954 struct backend_cpu
*cpu
= process
->be_cpu
;
1955 if (!cpu
) return packet_error
;
1957 packet_query_target_xml(gdbctx
, reply
, cpu
);
1959 return packet_send_buffer
;
1962 return packet_reply_error(gdbctx
, 0);
1965 static enum packet_return
packet_query_exec_file(struct gdb_context
* gdbctx
)
1967 struct reply_buffer
* reply
= &gdbctx
->qxfer_buffer
;
1968 struct dbg_process
* process
= gdbctx
->process
;
1973 if (!process
) return packet_error
;
1975 if (gdbctx
->qxfer_object_annex
[0] || !process
->imageName
)
1976 return packet_reply_error(gdbctx
, HOST_EPERM
);
1978 if (!(unix_path
= wine_get_unix_file_name(process
->imageName
)))
1979 return packet_reply_error(gdbctx
, GetLastError() == ERROR_NOT_ENOUGH_MEMORY
? HOST_ENOMEM
: HOST_ENOENT
);
1981 if (IsWow64Process(process
->handle
, &is_wow64
) &&
1982 is_wow64
&& (tmp
= strstr(unix_path
, "system32")))
1983 memcpy(tmp
, "syswow64", 8);
1985 reply_buffer_append_str(reply
, unix_path
);
1987 HeapFree(GetProcessHeap(), 0, unix_path
);
1989 return packet_send_buffer
;
1995 enum packet_return (*handler
)(struct gdb_context
* gdbctx
);
1996 } qxfer_handlers
[] =
1998 {"libraries", packet_query_libraries
},
1999 {"threads" , packet_query_threads
},
2000 {"features" , packet_query_features
},
2001 {"exec-file", packet_query_exec_file
},
2004 static enum packet_return
packet_query(struct gdb_context
* gdbctx
)
2006 char object_name
[QX_NAME_SIZE
], annex
[QX_ANNEX_SIZE
];
2007 unsigned int off
, len
;
2009 switch (gdbctx
->in_packet
[0])
2012 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
2014 struct dbg_thread
* thd
;
2016 packet_reply_open(gdbctx
);
2017 packet_reply_add(gdbctx
, "m");
2018 LIST_FOR_EACH_ENTRY(thd
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
2020 packet_reply_val(gdbctx
, thd
->tid
, 4);
2021 if (list_next(&gdbctx
->process
->threads
, &thd
->entry
) != NULL
)
2022 packet_reply_add(gdbctx
, ",");
2024 packet_reply_close(gdbctx
);
2027 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
2031 packet_reply_open(gdbctx
);
2032 packet_reply_add(gdbctx
, "O");
2033 get_process_info(gdbctx
, result
, sizeof(result
));
2034 packet_reply_hex_to_str(gdbctx
, result
);
2035 packet_reply_close(gdbctx
);
2040 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
2042 packet_reply(gdbctx
, "l");
2045 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
2047 packet_reply(gdbctx
, "l");
2052 if (strncmp(gdbctx
->in_packet
, "Attached", gdbctx
->in_packet_len
) == 0)
2053 return packet_reply(gdbctx
, "1");
2056 if (gdbctx
->in_packet_len
== 1)
2058 struct dbg_thread
* thd
;
2059 /* FIXME: doc says 16 bit val ??? */
2060 /* grab first created thread, aka last in list */
2061 assert(gdbctx
->process
&& !list_empty(&gdbctx
->process
->threads
));
2062 thd
= LIST_ENTRY(list_tail(&gdbctx
->process
->threads
), struct dbg_thread
, entry
);
2063 packet_reply_open(gdbctx
);
2064 packet_reply_add(gdbctx
, "QC");
2065 packet_reply_val(gdbctx
, thd
->tid
, 4);
2066 packet_reply_close(gdbctx
);
2071 if (gdbctx
->in_packet_len
> 10 &&
2072 strncmp(gdbctx
->in_packet
, "GetTIBAddr", 10) == 0 &&
2073 gdbctx
->in_packet
[10] == ':')
2077 struct dbg_thread
* thd
;
2079 tid
= strtol(gdbctx
->in_packet
+ 11, &end
, 16);
2080 if (end
== NULL
) break;
2082 thd
= dbg_get_thread(gdbctx
->process
, tid
);
2084 return packet_reply_error(gdbctx
, HOST_EINVAL
);
2085 packet_reply_open(gdbctx
);
2086 packet_reply_val(gdbctx
, (ULONG_PTR
)thd
->teb
, sizeof(thd
->teb
));
2087 packet_reply_close(gdbctx
);
2092 if (strncmp(gdbctx
->in_packet
, "Offsets", gdbctx
->in_packet_len
) == 0)
2096 snprintf(buf
, sizeof(buf
),
2097 "Text=%08Ix;Data=%08Ix;Bss=%08Ix",
2098 gdbctx
->wine_segs
[0], gdbctx
->wine_segs
[1],
2099 gdbctx
->wine_segs
[2]);
2100 return packet_reply(gdbctx
, buf
);
2104 if (gdbctx
->in_packet_len
> 5 && strncmp(gdbctx
->in_packet
, "Rcmd,", 5) == 0)
2106 return packet_query_remote_command(gdbctx
, gdbctx
->in_packet
+ 5,
2107 gdbctx
->in_packet_len
- 5);
2111 if (strncmp(gdbctx
->in_packet
, "Symbol::", gdbctx
->in_packet_len
) == 0)
2113 if (strncmp(gdbctx
->in_packet
, "Supported", 9) == 0)
2117 packet_reply_open(gdbctx
);
2118 packet_reply_add(gdbctx
, "QStartNoAckMode+;");
2119 for (i
= 0; i
< ARRAY_SIZE(qxfer_handlers
); i
++)
2121 packet_reply_add(gdbctx
, "qXfer:");
2122 packet_reply_add(gdbctx
, qxfer_handlers
[i
].name
);
2123 packet_reply_add(gdbctx
, ":read+;");
2125 packet_reply_close(gdbctx
);
2130 if (gdbctx
->in_packet_len
> 15 &&
2131 strncmp(gdbctx
->in_packet
, "ThreadExtraInfo", 15) == 0 &&
2132 gdbctx
->in_packet
[15] == ',')
2138 tid
= strtol(gdbctx
->in_packet
+ 16, &end
, 16);
2139 if (end
== NULL
) break;
2140 get_thread_info(gdbctx
, tid
, result
, sizeof(result
));
2141 packet_reply_open(gdbctx
);
2142 packet_reply_hex_to_str(gdbctx
, result
);
2143 packet_reply_close(gdbctx
);
2146 if (strncmp(gdbctx
->in_packet
, "TStatus", 7) == 0)
2148 /* Tracepoints not supported */
2149 packet_reply_open(gdbctx
);
2150 packet_reply_close(gdbctx
);
2156 if (sscanf(gdbctx
->in_packet
, "Xfer:%31[^:]:read::%x,%x", object_name
, &off
, &len
) == 3 ||
2157 sscanf(gdbctx
->in_packet
, "Xfer:%31[^:]:read:%255[^:]:%x,%x", object_name
, annex
, &off
, &len
) == 4)
2159 enum packet_return result
;
2163 for (i
= 0; i
< ARRAY_SIZE(qxfer_handlers
); i
++)
2165 if (strcmp(qxfer_handlers
[i
].name
, object_name
) == 0)
2169 if (i
>= ARRAY_SIZE(qxfer_handlers
))
2171 ERR("unhandled qXfer %s read %s %u,%u\n", debugstr_a(object_name
), debugstr_a(annex
), off
, len
);
2172 return packet_error
;
2175 TRACE("qXfer %s read %s %u,%u\n", debugstr_a(object_name
), debugstr_a(annex
), off
, len
);
2178 gdbctx
->qxfer_buffer
.len
> 0 &&
2179 gdbctx
->qxfer_object_idx
== i
&&
2180 strcmp(gdbctx
->qxfer_object_annex
, annex
) == 0)
2182 result
= packet_send_buffer
;
2183 TRACE("qXfer read result = %d (cached)\n", result
);
2187 reply_buffer_clear(&gdbctx
->qxfer_buffer
);
2189 gdbctx
->qxfer_object_idx
= i
;
2190 strcpy(gdbctx
->qxfer_object_annex
, annex
);
2192 result
= (*qxfer_handlers
[i
].handler
)(gdbctx
);
2193 TRACE("qXfer read result = %d\n", result
);
2197 if ((result
& ~packet_last_f
) == packet_send_buffer
)
2199 packet_reply_xfer(gdbctx
, off
, len
, &more
);
2200 result
= (result
& packet_last_f
) | packet_done
;
2205 gdbctx
->qxfer_object_idx
= -1;
2206 gdbctx
->qxfer_object_annex
[0] = '\0';
2207 reply_buffer_clear(&gdbctx
->qxfer_buffer
);
2214 ERR("Unhandled query %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
2215 return packet_error
;
2218 static enum packet_return
packet_set(struct gdb_context
* gdbctx
)
2220 if (strncmp(gdbctx
->in_packet
, "StartNoAckMode", 14) == 0)
2222 gdbctx
->no_ack_mode
= TRUE
;
2226 return packet_error
;
2229 static enum packet_return
packet_step(struct gdb_context
* gdbctx
)
2233 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
2234 FIXME("Continue at address %p not supported\n", addr
);
2236 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, TRUE
, -1);
2238 wait_for_debuggee(gdbctx
);
2239 return packet_reply_status(gdbctx
);
2242 static enum packet_return
packet_thread_alive(struct gdb_context
* gdbctx
)
2247 tid
= strtol(gdbctx
->in_packet
, &end
, 16);
2248 if (tid
== -1 || tid
== 0)
2249 return packet_reply_error(gdbctx
, HOST_EINVAL
);
2250 if (dbg_get_thread(gdbctx
->process
, tid
) != NULL
)
2252 return packet_reply_error(gdbctx
, HOST_ESRCH
);
2255 /* =============================================== *
2256 * P A C K E T I N F R A S T R U C T U R E *
2257 * =============================================== *
2263 enum packet_return (*handler
)(struct gdb_context
* gdbctx
);
2266 static struct packet_entry packet_entries
[] =
2268 {'?', packet_last_signal
},
2269 {'c', packet_continue
},
2270 {'C', packet_continue_signal
},
2271 {'D', packet_detach
},
2272 {'g', packet_read_registers
},
2273 {'G', packet_write_registers
},
2275 {'H', packet_thread
},
2276 {'m', packet_read_memory
},
2277 {'M', packet_write_memory
},
2278 {'p', packet_read_register
},
2279 {'P', packet_write_register
},
2280 {'q', packet_query
},
2283 {'T', packet_thread_alive
},
2284 {'v', packet_verbose
},
2285 {'z', packet_delete_breakpoint
},
2286 {'Z', packet_insert_breakpoint
},
2289 static BOOL
extract_packets(struct gdb_context
* gdbctx
)
2291 char *ptr
, *sum
= gdbctx
->in_buf
, *end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
2292 enum packet_return ret
= packet_error
;
2296 /* ptr points to the beginning ('$') of the current packet
2297 * sum points to the beginning ('#') of the current packet checksum ("#xx")
2298 * len is the length of the current packet data (sum - ptr - 1)
2299 * end points to the end of the received data buffer
2302 while (!gdbctx
->no_ack_mode
&&
2303 (ptr
= memchr(sum
, '$', end
- sum
)) &&
2304 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
2305 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2307 len
= sum
- ptr
- 1;
2310 if (cksum
== checksum(ptr
+ 1, len
))
2312 TRACE("Acking: %s\n", debugstr_an(ptr
, sum
- ptr
));
2313 send(gdbctx
->sock
, "+", 1, 0);
2317 ERR("Nacking: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2318 cksum
, checksum(ptr
+ 1, len
));
2319 send(gdbctx
->sock
, "-", 1, 0);
2323 while ((ret
& packet_last_f
) == 0 &&
2324 (ptr
= memchr(gdbctx
->in_buf
, '$', gdbctx
->in_len
)) &&
2325 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
2326 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2328 if (ptr
!= gdbctx
->in_buf
)
2329 WARN("Ignoring: %s\n", debugstr_an(gdbctx
->in_buf
, ptr
- gdbctx
->in_buf
));
2331 len
= sum
- ptr
- 1;
2334 if (cksum
== checksum(ptr
+ 1, len
))
2336 TRACE("Handling: %s\n", debugstr_an(ptr
, sum
- ptr
));
2339 gdbctx
->in_packet
= ptr
+ 2;
2340 gdbctx
->in_packet_len
= len
- 1;
2341 gdbctx
->in_packet
[gdbctx
->in_packet_len
] = '\0';
2343 for (i
= 0; i
< ARRAY_SIZE(packet_entries
); i
++)
2344 if (packet_entries
[i
].key
== ptr
[1])
2347 if (i
== ARRAY_SIZE(packet_entries
))
2348 WARN("Unhandled: %s\n", debugstr_an(ptr
+ 1, len
));
2349 else if (((ret
= (packet_entries
[i
].handler
)(gdbctx
)) & ~packet_last_f
) == packet_error
)
2350 WARN("Failed: %s\n", debugstr_an(ptr
+ 1, len
));
2352 switch (ret
& ~packet_last_f
)
2354 case packet_error
: packet_reply(gdbctx
, ""); break;
2355 case packet_ok
: packet_reply(gdbctx
, "OK"); break;
2356 case packet_done
: break;
2359 TRACE("Reply: %s\n", debugstr_an((char *)gdbctx
->out_buf
.base
, gdbctx
->out_buf
.len
));
2360 i
= send(gdbctx
->sock
, (char *)gdbctx
->out_buf
.base
, gdbctx
->out_buf
.len
, 0);
2361 assert(i
== gdbctx
->out_buf
.len
);
2362 reply_buffer_clear(&gdbctx
->out_buf
);
2365 WARN("Ignoring: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2366 cksum
, checksum(ptr
+ 1, len
));
2368 gdbctx
->in_len
= end
- sum
;
2369 memmove(gdbctx
->in_buf
, sum
, end
- sum
);
2370 end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
2373 return (ret
& packet_last_f
);
2376 static int fetch_data(struct gdb_context
* gdbctx
)
2378 int len
, in_len
= gdbctx
->in_len
;
2380 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2384 if (gdbctx
->in_len
+ STEP
> gdbctx
->in_buf_alloc
)
2385 gdbctx
->in_buf
= realloc(gdbctx
->in_buf
, gdbctx
->in_buf_alloc
+= STEP
);
2387 len
= recv(gdbctx
->sock
, gdbctx
->in_buf
+ gdbctx
->in_len
, gdbctx
->in_buf_alloc
- gdbctx
->in_len
- 1, 0);
2388 if (len
<= 0) break;
2389 gdbctx
->in_len
+= len
;
2390 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2391 if (len
< gdbctx
->in_buf_alloc
- gdbctx
->in_len
) break;
2394 gdbctx
->in_buf
[gdbctx
->in_len
] = '\0';
2395 return gdbctx
->in_len
- in_len
;
2398 #define FLAG_NO_START 1
2399 #define FLAG_WITH_XTERM 2
2401 static BOOL
gdb_exec(unsigned port
, unsigned flags
)
2403 WCHAR tmp
[MAX_PATH
], buf
[MAX_PATH
];
2404 const char *argv
[6];
2406 const char *gdb_path
;
2409 if (!(gdb_path
= getenv("WINE_GDB"))) gdb_path
= "gdb";
2410 GetTempPathW( MAX_PATH
, buf
);
2411 GetTempFileNameW( buf
, L
"gdb", 0, tmp
);
2412 if ((f
= _wfopen( tmp
, L
"w+" )) == NULL
) return FALSE
;
2413 unix_tmp
= wine_get_unix_file_name( tmp
);
2414 fprintf(f
, "target remote localhost:%d\n", ntohs(port
));
2415 fprintf(f
, "set prompt Wine-gdb>\\ \n");
2416 /* gdb 5.1 seems to require it, won't hurt anyway */
2417 fprintf(f
, "sharedlibrary\n");
2418 /* This is needed (but not a decent & final fix)
2419 * Without this, gdb would skip our inter-DLL relay code (because
2420 * we don't have any line number information for the relay code)
2421 * With this, we will stop on first instruction of the stub, and
2422 * reusing step, will get us through the relay stub at the actual
2423 * function we're looking at.
2425 fprintf(f
, "set step-mode on\n");
2426 /* tell gdb to delete this file when done handling it... */
2427 fprintf(f
, "shell rm -f \"%s\"\n", unix_tmp
);
2435 if (flags
& FLAG_WITH_XTERM
)
2436 __wine_unix_spawnvp( (char **)argv
, FALSE
);
2438 __wine_unix_spawnvp( (char **)argv
+ 2, FALSE
);
2439 HeapFree( GetProcessHeap(), 0, unix_tmp
);
2443 static BOOL
gdb_startup(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2446 BOOL reuseaddr
= TRUE
;
2447 struct sockaddr_in s_addrs
= {0};
2448 int s_len
= sizeof(s_addrs
);
2453 WSAStartup( MAKEWORD(2, 2), &data
);
2455 /* step 1: create socket for gdb connection request */
2456 if ((sock
= socket(AF_INET
, SOCK_STREAM
, 0)) == INVALID_SOCKET
)
2458 ERR("Failed to create socket: %u\n", WSAGetLastError());
2462 setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&reuseaddr
, sizeof(reuseaddr
));
2464 s_addrs
.sin_family
= AF_INET
;
2465 s_addrs
.sin_addr
.S_un
.S_addr
= INADDR_ANY
;
2466 s_addrs
.sin_port
= htons(port
);
2467 if (bind(sock
, (struct sockaddr
*)&s_addrs
, sizeof(s_addrs
)) == -1)
2470 if (listen(sock
, 1) == -1 || getsockname(sock
, (struct sockaddr
*)&s_addrs
, &s_len
) == -1)
2473 /* step 2: do the process internal creation */
2474 handle_debug_event(gdbctx
, FALSE
);
2476 /* step 3: fire up gdb (if requested) */
2477 if (flags
& FLAG_NO_START
)
2478 fprintf(stderr
, "target remote localhost:%d\n", ntohs(s_addrs
.sin_port
));
2480 gdb_exec(s_addrs
.sin_port
, flags
);
2482 /* step 4: wait for gdb to connect actually */
2483 FD_ZERO( &read_fds
);
2484 FD_SET( sock
, &read_fds
);
2486 if (select( 0, &read_fds
, NULL
, NULL
, NULL
) > 0)
2490 gdbctx
->sock
= accept(sock
, (struct sockaddr
*)&s_addrs
, &s_len
);
2491 if (gdbctx
->sock
!= INVALID_SOCKET
)
2494 TRACE("connected on %Iu\n", gdbctx
->sock
);
2495 /* don't keep our small packets too long: send them ASAP back to GDB
2496 * without this, GDB really crawls
2498 setsockopt(gdbctx
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (char*)&dummy
, sizeof(dummy
));
2501 else ERR("Failed to connect to gdb: %u\n", WSAGetLastError());
2508 static BOOL
gdb_init_context(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2512 gdbctx
->sock
= INVALID_SOCKET
;
2513 gdbctx
->in_buf
= NULL
;
2514 gdbctx
->in_buf_alloc
= 0;
2516 memset(&gdbctx
->out_buf
, 0, sizeof(gdbctx
->out_buf
));
2517 gdbctx
->out_curr_packet
= -1;
2519 gdbctx
->exec_tid
= -1;
2520 gdbctx
->other_tid
= -1;
2521 list_init(&gdbctx
->xpoint_list
);
2522 gdbctx
->process
= NULL
;
2523 gdbctx
->no_ack_mode
= FALSE
;
2524 for (i
= 0; i
< ARRAY_SIZE(gdbctx
->wine_segs
); i
++)
2525 gdbctx
->wine_segs
[i
] = 0;
2527 gdbctx
->qxfer_object_idx
= -1;
2528 memset(gdbctx
->qxfer_object_annex
, 0, sizeof(gdbctx
->qxfer_object_annex
));
2529 memset(&gdbctx
->qxfer_buffer
, 0, sizeof(gdbctx
->qxfer_buffer
));
2531 /* wait for first trap */
2532 while (WaitForDebugEvent(&gdbctx
->de
, INFINITE
))
2534 if (gdbctx
->de
.dwDebugEventCode
== CREATE_PROCESS_DEBUG_EVENT
)
2536 /* this should be the first event we get,
2537 * and the only one of this type */
2538 assert(gdbctx
->process
== NULL
&& gdbctx
->de
.dwProcessId
== dbg_curr_pid
);
2539 /* gdbctx->dwProcessId = pid; */
2540 if (!gdb_startup(gdbctx
, flags
, port
)) return FALSE
;
2542 else if (!handle_debug_event(gdbctx
, FALSE
))
2544 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
2549 static int gdb_remote(unsigned flags
, unsigned port
)
2551 struct gdb_context gdbctx
;
2553 if (!gdb_init_context(&gdbctx
, flags
, port
)) return 0;
2554 /* don't handle ctrl-c, but let gdb do the job */
2555 SetConsoleCtrlHandler(NULL
, TRUE
);
2558 fd_set read_fds
, err_fds
;
2560 FD_ZERO( &read_fds
);
2561 FD_ZERO( &err_fds
);
2562 FD_SET( gdbctx
.sock
, &read_fds
);
2563 FD_SET( gdbctx
.sock
, &err_fds
);
2565 if (select( 0, &read_fds
, NULL
, &err_fds
, NULL
) == -1) break;
2567 if (FD_ISSET( gdbctx
.sock
, &err_fds
))
2569 ERR("gdb hung up\n");
2570 /* kill also debuggee process - questionnable - */
2571 detach_debuggee(&gdbctx
, TRUE
);
2574 if (FD_ISSET( gdbctx
.sock
, &read_fds
))
2576 if (fetch_data(&gdbctx
) > 0)
2578 if (extract_packets(&gdbctx
)) break;
2585 int gdb_main(int argc
, char* argv
[])
2587 unsigned gdb_flags
= 0, port
= 0;
2591 while (argc
> 0 && argv
[0][0] == '-')
2593 if (strcmp(argv
[0], "--no-start") == 0)
2595 gdb_flags
|= FLAG_NO_START
;
2599 if (strcmp(argv
[0], "--with-xterm") == 0)
2601 gdb_flags
|= FLAG_WITH_XTERM
;
2605 if (strcmp(argv
[0], "--port") == 0 && argc
> 1)
2607 port
= strtoul(argv
[1], &port_end
, 10);
2610 fprintf(stderr
, "Invalid port: %s\n", argv
[1]);
2613 argc
-= 2; argv
+= 2;
2618 if (dbg_active_attach(argc
, argv
) == start_ok
||
2619 dbg_active_launch(argc
, argv
) == start_ok
)
2620 return gdb_remote(gdb_flags
, port
);