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
28 #include "wine/port.h"
37 #ifdef HAVE_SYS_POLL_H
38 # include <sys/poll.h>
40 #ifdef HAVE_SYS_WAIT_H
41 # include <sys/wait.h>
43 #ifdef HAVE_SYS_SOCKET_H
44 # include <sys/socket.h>
46 #ifdef HAVE_NETINET_IN_H
47 # include <netinet/in.h>
49 #ifdef HAVE_NETINET_TCP_H
50 # include <netinet/tcp.h>
56 /* if we don't have poll support on this system
57 * we won't provide gdb proxy support here...
66 #include "wine/exception.h"
67 #include "wine/debug.h"
69 WINE_DEFAULT_DEBUG_CHANNEL(winedbg
);
76 enum be_xpoint_type type
;
90 /* split into individual packet */
98 /* generic GDB thread information */
99 int exec_tid
; /* tid used in step & continue */
100 int other_tid
; /* tid to be used in any other operation */
101 struct list xpoint_list
;
102 /* current Win32 trap env */
105 /* Win32 information */
106 struct dbg_process
* process
;
107 /* Unix environment */
108 unsigned long wine_segs
[3]; /* load addresses of the ELF wine exec segments (text, bss and data) */
112 static void gdbctx_delete_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
113 dbg_ctx_t
*ctx
, struct gdb_xpoint
*x
)
115 struct dbg_process
*process
= gdbctx
->process
;
116 struct backend_cpu
*cpu
= process
->be_cpu
;
118 if (!cpu
->remove_Xpoint(process
->handle
, process
->process_io
, ctx
, x
->type
, x
->addr
, x
->value
, x
->size
))
119 ERR("%04x:%04x: Couldn't remove breakpoint at:%p/%x type:%d\n", process
->pid
, thread
? thread
->tid
: ~0, x
->addr
, x
->size
, x
->type
);
121 list_remove(&x
->entry
);
122 HeapFree(GetProcessHeap(), 0, x
);
125 static void gdbctx_insert_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
126 dbg_ctx_t
*ctx
, enum be_xpoint_type type
, void *addr
, int size
)
128 struct dbg_process
*process
= thread
->process
;
129 struct backend_cpu
*cpu
= process
->be_cpu
;
130 struct gdb_xpoint
*x
;
133 if (!cpu
->insert_Xpoint(process
->handle
, process
->process_io
, ctx
, type
, addr
, &value
, size
))
135 ERR("%04x:%04x: Couldn't insert breakpoint at:%p/%x type:%d\n", process
->pid
, thread
->tid
, addr
, size
, type
);
139 if (!(x
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct gdb_xpoint
))))
141 ERR("%04x:%04x: Couldn't allocate memory for breakpoint at:%p/%x type:%d\n", process
->pid
, thread
->tid
, addr
, size
, type
);
145 x
->pid
= process
->pid
;
146 x
->tid
= thread
->tid
;
151 list_add_head(&gdbctx
->xpoint_list
, &x
->entry
);
154 static struct gdb_xpoint
*gdb_find_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
155 enum be_xpoint_type type
, void *addr
, int size
)
157 struct gdb_xpoint
*x
;
159 LIST_FOR_EACH_ENTRY(x
, &gdbctx
->xpoint_list
, struct gdb_xpoint
, entry
)
161 if (thread
&& (x
->pid
!= thread
->process
->pid
|| x
->tid
!= thread
->tid
))
163 if (x
->type
== type
&& x
->addr
== addr
&& x
->size
== size
)
170 static BOOL
tgt_process_gdbproxy_read(HANDLE hProcess
, const void* addr
,
171 void* buffer
, SIZE_T len
, SIZE_T
* rlen
)
173 return ReadProcessMemory( hProcess
, addr
, buffer
, len
, rlen
);
176 static BOOL
tgt_process_gdbproxy_write(HANDLE hProcess
, void* addr
,
177 const void* buffer
, SIZE_T len
, SIZE_T
* wlen
)
179 return WriteProcessMemory( hProcess
, addr
, buffer
, len
, wlen
);
182 static struct be_process_io be_process_gdbproxy_io
=
184 NULL
, /* we shouldn't use close_process() in gdbproxy */
185 tgt_process_gdbproxy_read
,
186 tgt_process_gdbproxy_write
189 /* =============================================== *
190 * B A S I C M A N I P U L A T I O N S *
191 * =============================================== *
194 static inline int hex_from0(char ch
)
196 if (ch
>= '0' && ch
<= '9') return ch
- '0';
197 if (ch
>= 'A' && ch
<= 'F') return ch
- 'A' + 10;
198 if (ch
>= 'a' && ch
<= 'f') return ch
- 'a' + 10;
204 static inline unsigned char hex_to0(int x
)
206 assert(x
>= 0 && x
< 16);
207 return "0123456789abcdef"[x
];
210 static void hex_from(void* dst
, const char* src
, size_t len
)
212 unsigned char *p
= dst
;
215 *p
++ = (hex_from0(src
[0]) << 4) | hex_from0(src
[1]);
220 static void hex_to(char* dst
, const void* src
, size_t len
)
222 const unsigned char *p
= src
;
225 *dst
++ = hex_to0(*p
>> 4);
226 *dst
++ = hex_to0(*p
& 0x0F);
231 static unsigned char checksum(const char* ptr
, int len
)
236 cksum
+= (unsigned char)*ptr
++;
240 static inline void* cpu_register_ptr(struct gdb_context
*gdbctx
,
241 dbg_ctx_t
*ctx
, unsigned idx
)
243 assert(idx
< gdbctx
->process
->be_cpu
->gdb_num_regs
);
244 return (char*)ctx
+ gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].offset
;
247 static inline DWORD64
cpu_register(struct gdb_context
*gdbctx
,
248 dbg_ctx_t
*ctx
, unsigned idx
)
250 switch (gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].length
)
252 case 1: return *(BYTE
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
253 case 2: return *(WORD
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
254 case 4: return *(DWORD
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
255 case 8: return *(DWORD64
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
257 ERR("got unexpected size: %u\n",
258 (unsigned)gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].length
);
264 static inline void cpu_register_hex_from(struct gdb_context
*gdbctx
,
265 dbg_ctx_t
* ctx
, unsigned idx
, const char **phex
)
267 const struct gdb_register
*cpu_register_map
= gdbctx
->process
->be_cpu
->gdb_register_map
;
268 hex_from(cpu_register_ptr(gdbctx
, ctx
, idx
), *phex
, cpu_register_map
[idx
].length
);
271 /* =============================================== *
272 * W I N 3 2 D E B U G I N T E R F A C E *
273 * =============================================== *
276 static struct dbg_thread
* dbg_thread_from_tid(struct gdb_context
* gdbctx
, int tid
)
278 struct dbg_process
*process
= gdbctx
->process
;
279 struct dbg_thread
*thread
;
281 if (!process
) return NULL
;
283 if (tid
== 0) tid
= gdbctx
->de
.dwThreadId
;
284 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
286 if (tid
> 0 && thread
->tid
!= tid
) continue;
293 static void dbg_thread_set_single_step(struct dbg_thread
*thread
, BOOL enable
)
295 struct backend_cpu
*backend
;
299 if (!thread
->process
) return;
300 if (!(backend
= thread
->process
->be_cpu
)) return;
302 if (!backend
->get_context(thread
->handle
, &ctx
))
304 ERR("get_context failed for thread %04x:%04x\n", thread
->process
->pid
, thread
->tid
);
307 backend
->single_step(&ctx
, enable
);
308 if (!backend
->set_context(thread
->handle
, &ctx
))
309 ERR("set_context failed for thread %04x:%04x\n", thread
->process
->pid
, thread
->tid
);
312 static unsigned char signal_from_debug_event(DEBUG_EVENT
* de
)
316 if (de
->dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
318 if (de
->dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
321 ec
= de
->u
.Exception
.ExceptionRecord
.ExceptionCode
;
324 case EXCEPTION_ACCESS_VIOLATION
:
325 case EXCEPTION_PRIV_INSTRUCTION
:
326 case EXCEPTION_STACK_OVERFLOW
:
327 case EXCEPTION_GUARD_PAGE
:
329 case EXCEPTION_DATATYPE_MISALIGNMENT
:
331 case EXCEPTION_SINGLE_STEP
:
332 case EXCEPTION_BREAKPOINT
:
334 case EXCEPTION_FLT_DENORMAL_OPERAND
:
335 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
336 case EXCEPTION_FLT_INEXACT_RESULT
:
337 case EXCEPTION_FLT_INVALID_OPERATION
:
338 case EXCEPTION_FLT_OVERFLOW
:
339 case EXCEPTION_FLT_STACK_CHECK
:
340 case EXCEPTION_FLT_UNDERFLOW
:
342 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
343 case EXCEPTION_INT_OVERFLOW
:
345 case EXCEPTION_ILLEGAL_INSTRUCTION
:
349 case STATUS_POSSIBLE_DEADLOCK
:
351 /* should not be here */
352 case EXCEPTION_INVALID_HANDLE
:
353 case EXCEPTION_WINE_NAME_THREAD
:
356 ERR("Unknown exception code 0x%08x\n", ec
);
361 static BOOL
handle_exception(struct gdb_context
* gdbctx
, EXCEPTION_DEBUG_INFO
* exc
)
363 EXCEPTION_RECORD
* rec
= &exc
->ExceptionRecord
;
365 switch (rec
->ExceptionCode
)
367 case EXCEPTION_WINE_NAME_THREAD
:
369 const THREADNAME_INFO
*threadname
= (const THREADNAME_INFO
*)rec
->ExceptionInformation
;
370 struct dbg_thread
*thread
;
374 if (threadname
->dwThreadID
== -1)
375 thread
= dbg_get_thread(gdbctx
->process
, gdbctx
->de
.dwThreadId
);
377 thread
= dbg_get_thread(gdbctx
->process
, threadname
->dwThreadID
);
380 if (gdbctx
->process
->process_io
->read( gdbctx
->process
->handle
,
381 threadname
->szName
, name
, sizeof(name
), &read
) && read
== sizeof(name
))
383 fprintf(stderr
, "Thread ID=%04x renamed to \"%.9s\"\n",
384 threadname
->dwThreadID
, name
);
388 ERR("Cannot set name of thread %04x\n", threadname
->dwThreadID
);
391 case EXCEPTION_INVALID_HANDLE
:
398 static BOOL
handle_debug_event(struct gdb_context
* gdbctx
)
400 DEBUG_EVENT
*de
= &gdbctx
->de
;
401 struct dbg_thread
*thread
;
409 gdbctx
->exec_tid
= de
->dwThreadId
;
410 gdbctx
->other_tid
= de
->dwThreadId
;
411 gdbctx
->de_reply
= DBG_REPLY_LATER
;
413 switch (de
->dwDebugEventCode
)
415 case CREATE_PROCESS_DEBUG_EVENT
:
416 gdbctx
->process
= dbg_add_process(&be_process_gdbproxy_io
, de
->dwProcessId
,
417 de
->u
.CreateProcessInfo
.hProcess
);
418 if (!gdbctx
->process
)
421 size
= ARRAY_SIZE(u
.buffer
);
422 QueryFullProcessImageNameW( gdbctx
->process
->handle
, 0, u
.buffer
, &size
);
423 dbg_set_process_name(gdbctx
->process
, u
.buffer
);
425 fprintf(stderr
, "%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n",
426 de
->dwProcessId
, de
->dwThreadId
,
427 dbg_W2A(u
.buffer
, -1),
428 de
->u
.CreateProcessInfo
.lpImageName
,
429 de
->u
.CreateProcessInfo
.lpStartAddress
,
430 de
->u
.CreateProcessInfo
.dwDebugInfoFileOffset
,
431 de
->u
.CreateProcessInfo
.nDebugInfoSize
);
433 /* de->u.CreateProcessInfo.lpStartAddress; */
434 if (!dbg_init(gdbctx
->process
->handle
, u
.buffer
, TRUE
))
435 ERR("Couldn't initiate DbgHelp\n");
437 fprintf(stderr
, "%04x:%04x: create thread I @%p\n", de
->dwProcessId
,
438 de
->dwThreadId
, de
->u
.CreateProcessInfo
.lpStartAddress
);
440 dbg_load_module(gdbctx
->process
->handle
, de
->u
.CreateProcessInfo
.hFile
, u
.buffer
,
441 (DWORD_PTR
)de
->u
.CreateProcessInfo
.lpBaseOfImage
, 0);
443 dbg_add_thread(gdbctx
->process
, de
->dwThreadId
,
444 de
->u
.CreateProcessInfo
.hThread
,
445 de
->u
.CreateProcessInfo
.lpThreadLocalBase
);
448 case LOAD_DLL_DEBUG_EVENT
:
449 fetch_module_name( de
->u
.LoadDll
.lpImageName
, de
->u
.LoadDll
.lpBaseOfDll
,
450 u
.buffer
, ARRAY_SIZE(u
.buffer
) );
451 fprintf(stderr
, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
452 de
->dwProcessId
, de
->dwThreadId
,
453 dbg_W2A(u
.buffer
, -1),
454 de
->u
.LoadDll
.lpBaseOfDll
,
455 de
->u
.LoadDll
.dwDebugInfoFileOffset
,
456 de
->u
.LoadDll
.nDebugInfoSize
);
457 dbg_load_module(gdbctx
->process
->handle
, de
->u
.LoadDll
.hFile
, u
.buffer
,
458 (DWORD_PTR
)de
->u
.LoadDll
.lpBaseOfDll
, 0);
461 case UNLOAD_DLL_DEBUG_EVENT
:
462 fprintf(stderr
, "%08x:%08x: unload DLL @%p\n",
463 de
->dwProcessId
, de
->dwThreadId
, de
->u
.UnloadDll
.lpBaseOfDll
);
464 SymUnloadModule(gdbctx
->process
->handle
,
465 (DWORD_PTR
)de
->u
.UnloadDll
.lpBaseOfDll
);
468 case EXCEPTION_DEBUG_EVENT
:
469 TRACE("%08x:%08x: exception code=0x%08x\n", de
->dwProcessId
,
470 de
->dwThreadId
, de
->u
.Exception
.ExceptionRecord
.ExceptionCode
);
472 if (handle_exception(gdbctx
, &de
->u
.Exception
))
476 case CREATE_THREAD_DEBUG_EVENT
:
477 fprintf(stderr
, "%08x:%08x: create thread D @%p\n", de
->dwProcessId
,
478 de
->dwThreadId
, de
->u
.CreateThread
.lpStartAddress
);
480 dbg_add_thread(gdbctx
->process
,
482 de
->u
.CreateThread
.hThread
,
483 de
->u
.CreateThread
.lpThreadLocalBase
);
486 case EXIT_THREAD_DEBUG_EVENT
:
487 fprintf(stderr
, "%08x:%08x: exit thread (%u)\n",
488 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitThread
.dwExitCode
);
489 if ((thread
= dbg_get_thread(gdbctx
->process
, de
->dwThreadId
)))
490 dbg_del_thread(thread
);
493 case EXIT_PROCESS_DEBUG_EVENT
:
494 fprintf(stderr
, "%08x:%08x: exit process (%u)\n",
495 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitProcess
.dwExitCode
);
497 dbg_del_process(gdbctx
->process
);
498 gdbctx
->process
= NULL
;
501 case OUTPUT_DEBUG_STRING_EVENT
:
502 memory_get_string(gdbctx
->process
,
503 de
->u
.DebugString
.lpDebugStringData
, TRUE
,
504 de
->u
.DebugString
.fUnicode
, u
.bufferA
, sizeof(u
.bufferA
));
505 fprintf(stderr
, "%08x:%08x: output debug string (%s)\n",
506 de
->dwProcessId
, de
->dwThreadId
, debugstr_a(u
.bufferA
));
510 fprintf(stderr
, "%08x:%08x: rip error=%u type=%u\n", de
->dwProcessId
,
511 de
->dwThreadId
, de
->u
.RipInfo
.dwError
, de
->u
.RipInfo
.dwType
);
515 FIXME("%08x:%08x: unknown event (%u)\n",
516 de
->dwProcessId
, de
->dwThreadId
, de
->dwDebugEventCode
);
519 LIST_FOR_EACH_ENTRY(thread
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
521 if (!thread
->suspended
) SuspendThread(thread
->handle
);
522 thread
->suspended
= TRUE
;
528 static void handle_step_or_continue(struct gdb_context
* gdbctx
, int tid
, BOOL step
, int sig
)
530 struct dbg_process
*process
= gdbctx
->process
;
531 struct dbg_thread
*thread
;
533 if (tid
== 0) tid
= gdbctx
->de
.dwThreadId
;
534 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
536 if (tid
!= -1 && thread
->tid
!= tid
) continue;
537 if (!thread
->suspended
) continue;
538 thread
->suspended
= FALSE
;
540 if (process
->pid
== gdbctx
->de
.dwProcessId
&& thread
->tid
== gdbctx
->de
.dwThreadId
)
541 gdbctx
->de_reply
= (sig
== -1 ? DBG_CONTINUE
: DBG_EXCEPTION_NOT_HANDLED
);
543 dbg_thread_set_single_step(thread
, step
);
544 ResumeThread(thread
->handle
);
548 static BOOL
check_for_interrupt(struct gdb_context
* gdbctx
)
550 struct pollfd pollfd
;
554 pollfd
.fd
= gdbctx
->sock
;
555 pollfd
.events
= POLLIN
;
558 if ((ret
= poll(&pollfd
, 1, 0)) == 1) {
559 ret
= read(gdbctx
->sock
, &pkt
, 1);
561 ERR("read failed\n");
565 ERR("Unexpected break packet %#02x\n", pkt
);
569 } else if (ret
== -1) {
570 ERR("poll failed\n");
575 static void wait_for_debuggee(struct gdb_context
* gdbctx
)
577 if (gdbctx
->de
.dwDebugEventCode
)
578 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, gdbctx
->de_reply
);
582 if (!WaitForDebugEvent(&gdbctx
->de
, 10))
584 if (GetLastError() == ERROR_SEM_TIMEOUT
)
586 if (check_for_interrupt(gdbctx
)) {
587 if (!DebugBreakProcess(gdbctx
->process
->handle
)) {
588 ERR("Failed to break into debuggee\n");
591 WaitForDebugEvent(&gdbctx
->de
, INFINITE
);
599 if (!handle_debug_event(gdbctx
))
601 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
605 static void detach_debuggee(struct gdb_context
* gdbctx
, BOOL kill
)
607 handle_step_or_continue(gdbctx
, -1, FALSE
, -1);
609 if (gdbctx
->de
.dwDebugEventCode
)
610 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
613 DebugActiveProcessStop(gdbctx
->process
->pid
);
614 dbg_del_process(gdbctx
->process
);
615 gdbctx
->process
= NULL
;
618 static void get_process_info(struct gdb_context
* gdbctx
, char* buffer
, size_t len
)
622 if (!GetExitCodeProcess(gdbctx
->process
->handle
, &status
))
624 strcpy(buffer
, "Unknown process");
627 if (status
== STILL_ACTIVE
)
629 strcpy(buffer
, "Running");
632 snprintf(buffer
, len
, "Terminated (%u)", status
);
634 switch (GetPriorityClass(gdbctx
->process
->handle
))
637 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
638 case ABOVE_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", above normal priority"); break;
640 #ifdef BELOW_NORMAL_PRIORITY_CLASS
641 case BELOW_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", below normal priority"); break;
643 case HIGH_PRIORITY_CLASS
: strcat(buffer
, ", high priority"); break;
644 case IDLE_PRIORITY_CLASS
: strcat(buffer
, ", idle priority"); break;
645 case NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", normal priority"); break;
646 case REALTIME_PRIORITY_CLASS
: strcat(buffer
, ", realtime priority"); break;
648 strcat(buffer
, "\n");
651 static void get_thread_info(struct gdb_context
* gdbctx
, unsigned tid
,
652 char* buffer
, size_t len
)
654 struct dbg_thread
* thd
;
658 /* FIXME: use the size of buffer */
659 thd
= dbg_get_thread(gdbctx
->process
, tid
);
662 strcpy(buffer
, "No information");
665 if (GetExitCodeThread(thd
->handle
, &status
))
667 if (status
== STILL_ACTIVE
)
669 /* FIXME: this is a bit brutal... some nicer way shall be found */
670 switch (status
= SuspendThread(thd
->handle
))
673 case 0: strcpy(buffer
, "Running"); break;
674 default: snprintf(buffer
, len
, "Suspended (%u)", status
- 1);
676 ResumeThread(thd
->handle
);
679 snprintf(buffer
, len
, "Terminated (exit code = %u)", status
);
683 strcpy(buffer
, "Unknown threadID");
685 switch (prio
= GetThreadPriority(thd
->handle
))
687 case THREAD_PRIORITY_ERROR_RETURN
: break;
688 case THREAD_PRIORITY_ABOVE_NORMAL
: strcat(buffer
, ", priority +1 above normal"); break;
689 case THREAD_PRIORITY_BELOW_NORMAL
: strcat(buffer
, ", priority -1 below normal"); break;
690 case THREAD_PRIORITY_HIGHEST
: strcat(buffer
, ", priority +2 above normal"); break;
691 case THREAD_PRIORITY_LOWEST
: strcat(buffer
, ", priority -2 below normal"); break;
692 case THREAD_PRIORITY_IDLE
: strcat(buffer
, ", priority idle"); break;
693 case THREAD_PRIORITY_NORMAL
: strcat(buffer
, ", priority normal"); break;
694 case THREAD_PRIORITY_TIME_CRITICAL
: strcat(buffer
, ", priority time-critical"); break;
695 default: snprintf(buffer
+ strlen(buffer
), len
- strlen(buffer
), ", priority = %d", prio
);
697 assert(strlen(buffer
) < len
);
700 /* =============================================== *
701 * P A C K E T U T I L S *
702 * =============================================== *
705 static int addr_width(struct gdb_context
* gdbctx
)
707 int sz
= (gdbctx
&& gdbctx
->process
&& gdbctx
->process
->be_cpu
) ?
708 gdbctx
->process
->be_cpu
->pointer_size
: (int)sizeof(void*);
712 enum packet_return
{packet_error
= 0x00, packet_ok
= 0x01, packet_done
= 0x02,
713 packet_last_f
= 0x80};
715 static char* packet_realloc(char* buf
, int size
)
718 return HeapAlloc(GetProcessHeap(), 0, size
);
719 return HeapReAlloc(GetProcessHeap(), 0, buf
, size
);
723 static void packet_reply_grow(struct gdb_context
* gdbctx
, size_t size
)
725 if (gdbctx
->out_buf_alloc
< gdbctx
->out_len
+ size
)
727 gdbctx
->out_buf_alloc
= ((gdbctx
->out_len
+ size
) / 32 + 1) * 32;
728 gdbctx
->out_buf
= packet_realloc(gdbctx
->out_buf
, gdbctx
->out_buf_alloc
);
732 static void packet_reply_hex_to(struct gdb_context
* gdbctx
, const void* src
, int len
)
734 packet_reply_grow(gdbctx
, len
* 2);
735 hex_to(&gdbctx
->out_buf
[gdbctx
->out_len
], src
, len
);
736 gdbctx
->out_len
+= len
* 2;
739 static inline void packet_reply_hex_to_str(struct gdb_context
* gdbctx
, const char* src
)
741 packet_reply_hex_to(gdbctx
, src
, strlen(src
));
744 static void packet_reply_val(struct gdb_context
* gdbctx
, unsigned long val
, int len
)
748 shift
= (len
- 1) * 8;
749 packet_reply_grow(gdbctx
, len
* 2);
750 for (i
= 0; i
< len
; i
++, shift
-= 8)
752 gdbctx
->out_buf
[gdbctx
->out_len
++] = hex_to0((val
>> (shift
+ 4)) & 0x0F);
753 gdbctx
->out_buf
[gdbctx
->out_len
++] = hex_to0((val
>> shift
) & 0x0F);
757 static inline void packet_reply_add(struct gdb_context
* gdbctx
, const char* str
)
759 int len
= strlen(str
);
760 packet_reply_grow(gdbctx
, len
);
761 memcpy(&gdbctx
->out_buf
[gdbctx
->out_len
], str
, len
);
762 gdbctx
->out_len
+= len
;
765 static void packet_reply_open(struct gdb_context
* gdbctx
)
767 assert(gdbctx
->out_curr_packet
== -1);
768 packet_reply_add(gdbctx
, "$");
769 gdbctx
->out_curr_packet
= gdbctx
->out_len
;
772 static void packet_reply_close(struct gdb_context
* gdbctx
)
777 plen
= gdbctx
->out_len
- gdbctx
->out_curr_packet
;
778 packet_reply_add(gdbctx
, "#");
779 cksum
= checksum(&gdbctx
->out_buf
[gdbctx
->out_curr_packet
], plen
);
780 packet_reply_hex_to(gdbctx
, &cksum
, 1);
781 gdbctx
->out_curr_packet
= -1;
784 static void packet_reply_open_xfer(struct gdb_context
* gdbctx
)
786 packet_reply_open(gdbctx
);
787 packet_reply_add(gdbctx
, "m");
790 static void packet_reply_close_xfer(struct gdb_context
* gdbctx
, int off
, int len
)
792 int begin
= gdbctx
->out_curr_packet
+ 1;
795 if (begin
+ off
< gdbctx
->out_len
)
797 gdbctx
->out_len
-= off
;
798 memmove(gdbctx
->out_buf
+ begin
, gdbctx
->out_buf
+ begin
+ off
, gdbctx
->out_len
);
802 gdbctx
->out_buf
[gdbctx
->out_curr_packet
] = 'l';
803 gdbctx
->out_len
= gdbctx
->out_curr_packet
+ 1;
806 plen
= gdbctx
->out_len
- begin
;
807 if (len
>= 0 && plen
> len
) gdbctx
->out_len
-= (plen
- len
);
808 else gdbctx
->out_buf
[gdbctx
->out_curr_packet
] = 'l';
810 packet_reply_close(gdbctx
);
813 static enum packet_return
packet_reply(struct gdb_context
* gdbctx
, const char* packet
)
815 packet_reply_open(gdbctx
);
817 assert(strchr(packet
, '$') == NULL
&& strchr(packet
, '#') == NULL
);
819 packet_reply_add(gdbctx
, packet
);
821 packet_reply_close(gdbctx
);
826 static enum packet_return
packet_reply_error(struct gdb_context
* gdbctx
, int error
)
828 packet_reply_open(gdbctx
);
830 packet_reply_add(gdbctx
, "E");
831 packet_reply_val(gdbctx
, error
, 1);
833 packet_reply_close(gdbctx
);
838 static inline void packet_reply_register_hex_to(struct gdb_context
* gdbctx
, dbg_ctx_t
* ctx
, unsigned idx
)
840 const struct gdb_register
*cpu_register_map
= gdbctx
->process
->be_cpu
->gdb_register_map
;
841 packet_reply_hex_to(gdbctx
, cpu_register_ptr(gdbctx
, ctx
, idx
), cpu_register_map
[idx
].length
);
844 /* =============================================== *
845 * P A C K E T H A N D L E R S *
846 * =============================================== *
849 static void packet_reply_status_xpoints(struct gdb_context
* gdbctx
, struct dbg_thread
*thread
,
852 struct dbg_process
*process
= thread
->process
;
853 struct backend_cpu
*cpu
= process
->be_cpu
;
854 struct gdb_xpoint
*x
;
856 LIST_FOR_EACH_ENTRY(x
, &gdbctx
->xpoint_list
, struct gdb_xpoint
, entry
)
858 if (x
->pid
!= process
->pid
|| x
->tid
!= thread
->tid
)
860 if (!cpu
->is_watchpoint_set(ctx
, x
->value
))
862 if (x
->type
== be_xpoint_watch_write
)
864 packet_reply_add(gdbctx
, "watch:");
865 packet_reply_val(gdbctx
, (unsigned long)x
->addr
, sizeof(x
->addr
));
866 packet_reply_add(gdbctx
, ";");
868 if (x
->type
== be_xpoint_watch_read
)
870 packet_reply_add(gdbctx
, "rwatch:");
871 packet_reply_val(gdbctx
, (unsigned long)x
->addr
, sizeof(x
->addr
));
872 packet_reply_add(gdbctx
, ";");
877 static enum packet_return
packet_reply_status(struct gdb_context
* gdbctx
)
879 struct dbg_process
*process
= gdbctx
->process
;
880 struct dbg_thread
*thread
;
881 struct backend_cpu
*backend
;
885 switch (gdbctx
->de
.dwDebugEventCode
)
888 if (!process
) return packet_error
;
889 if (!(backend
= process
->be_cpu
)) return packet_error
;
890 if (!(thread
= dbg_get_thread(process
, gdbctx
->de
.dwThreadId
)) ||
891 !backend
->get_context(thread
->handle
, &ctx
))
894 packet_reply_open(gdbctx
);
895 packet_reply_add(gdbctx
, "T");
896 packet_reply_val(gdbctx
, signal_from_debug_event(&gdbctx
->de
), 1);
897 packet_reply_add(gdbctx
, "thread:");
898 packet_reply_val(gdbctx
, gdbctx
->de
.dwThreadId
, 4);
899 packet_reply_add(gdbctx
, ";");
900 packet_reply_status_xpoints(gdbctx
, thread
, &ctx
);
902 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
904 packet_reply_val(gdbctx
, i
, 1);
905 packet_reply_add(gdbctx
, ":");
906 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
907 packet_reply_add(gdbctx
, ";");
910 packet_reply_close(gdbctx
);
913 case EXIT_PROCESS_DEBUG_EVENT
:
914 packet_reply_open(gdbctx
);
915 packet_reply_add(gdbctx
, "W");
916 packet_reply_val(gdbctx
, gdbctx
->de
.u
.ExitProcess
.dwExitCode
, 4);
917 packet_reply_close(gdbctx
);
918 return packet_done
| packet_last_f
;
922 static enum packet_return
packet_last_signal(struct gdb_context
* gdbctx
)
924 assert(gdbctx
->in_packet_len
== 0);
925 return packet_reply_status(gdbctx
);
928 static enum packet_return
packet_continue(struct gdb_context
* gdbctx
)
932 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
933 FIXME("Continue at address %p not supported\n", addr
);
935 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, -1);
937 wait_for_debuggee(gdbctx
);
938 return packet_reply_status(gdbctx
);
941 static enum packet_return
packet_verbose_cont(struct gdb_context
* gdbctx
)
943 char *buf
= gdbctx
->in_packet
, *end
= gdbctx
->in_packet
+ gdbctx
->in_packet_len
;
945 if (gdbctx
->in_packet
[4] == '?')
947 packet_reply_open(gdbctx
);
948 packet_reply_add(gdbctx
, "vCont");
949 packet_reply_add(gdbctx
, ";c");
950 packet_reply_add(gdbctx
, ";C");
951 packet_reply_add(gdbctx
, ";s");
952 packet_reply_add(gdbctx
, ";S");
953 packet_reply_close(gdbctx
);
957 while (buf
< end
&& (buf
= memchr(buf
+ 1, ';', end
- buf
- 1)))
959 int tid
= -1, sig
= -1;
962 switch ((action
= buf
[1]))
972 if (sscanf(buf
, ";%*c%2x", &sig
) <= 0 ||
973 sig
!= signal_from_debug_event(&gdbctx
->de
))
981 if (buf
< end
&& *buf
== ':' && (n
= sscanf(buf
, ":%x", &tid
)) <= 0)
984 handle_step_or_continue(gdbctx
, tid
, action
== 's' || action
== 'S', sig
);
987 wait_for_debuggee(gdbctx
);
988 return packet_reply_status(gdbctx
);
991 static enum packet_return
packet_verbose(struct gdb_context
* gdbctx
)
993 if (gdbctx
->in_packet_len
>= 4 && !memcmp(gdbctx
->in_packet
, "Cont", 4))
995 return packet_verbose_cont(gdbctx
);
998 if (gdbctx
->in_packet_len
== 14 && !memcmp(gdbctx
->in_packet
, "MustReplyEmpty", 14))
999 return packet_reply(gdbctx
, "");
1001 return packet_error
;
1004 static enum packet_return
packet_continue_signal(struct gdb_context
* gdbctx
)
1009 if ((n
= sscanf(gdbctx
->in_packet
, "%x;%p", &sig
, &addr
)) == 2)
1010 FIXME("Continue at address %p not supported\n", addr
);
1011 if (n
< 1) return packet_error
;
1013 if (sig
!= signal_from_debug_event(&gdbctx
->de
))
1015 ERR("Changing signals is not supported.\n");
1016 return packet_error
;
1019 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, sig
);
1021 wait_for_debuggee(gdbctx
);
1022 return packet_reply_status(gdbctx
);
1025 static enum packet_return
packet_delete_breakpoint(struct gdb_context
* gdbctx
)
1027 struct dbg_process
*process
= gdbctx
->process
;
1028 struct dbg_thread
*thread
;
1029 struct backend_cpu
*cpu
;
1030 struct gdb_xpoint
*x
;
1036 if (!process
) return packet_error
;
1037 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1039 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1040 return packet_error
;
1043 return packet_error
;
1045 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1047 if (!cpu
->get_context(thread
->handle
, &ctx
))
1049 if ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_exec
, addr
, size
)))
1050 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1051 if ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_read
, addr
, size
)))
1052 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1053 if ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_write
, addr
, size
)))
1054 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1055 cpu
->set_context(thread
->handle
, &ctx
);
1058 while ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_exec
, addr
, size
)))
1059 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1060 while ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_read
, addr
, size
)))
1061 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1062 while ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_write
, addr
, size
)))
1063 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1068 static enum packet_return
packet_insert_breakpoint(struct gdb_context
* gdbctx
)
1070 struct dbg_process
*process
= gdbctx
->process
;
1071 struct dbg_thread
*thread
;
1072 struct backend_cpu
*cpu
;
1078 if (!process
) return packet_error
;
1079 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1081 if (memchr(gdbctx
->in_packet
, ';', gdbctx
->in_packet_len
))
1083 FIXME("breakpoint commands not supported\n");
1084 return packet_error
;
1087 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1088 return packet_error
;
1091 return packet_error
;
1093 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1095 if (!cpu
->get_context(thread
->handle
, &ctx
))
1098 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_exec
, addr
, size
);
1099 if (type
== '2' || type
== '4')
1100 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_read
, addr
, size
);
1101 if (type
== '3' || type
== '4')
1102 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_write
, addr
, size
);
1103 cpu
->set_context(thread
->handle
, &ctx
);
1109 static enum packet_return
packet_detach(struct gdb_context
* gdbctx
)
1111 detach_debuggee(gdbctx
, FALSE
);
1112 return packet_ok
| packet_last_f
;
1115 static enum packet_return
packet_read_registers(struct gdb_context
* gdbctx
)
1117 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1118 struct backend_cpu
*backend
;
1122 if (!thread
) return packet_error
;
1123 if (!thread
->process
) return packet_error
;
1124 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1126 if (!backend
->get_context(thread
->handle
, &ctx
))
1127 return packet_error
;
1129 packet_reply_open(gdbctx
);
1130 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1131 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
1133 packet_reply_close(gdbctx
);
1137 static enum packet_return
packet_write_registers(struct gdb_context
* gdbctx
)
1139 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1140 struct backend_cpu
*backend
;
1145 if (!thread
) return packet_error
;
1146 if (!thread
->process
) return packet_error
;
1147 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1149 if (!backend
->get_context(thread
->handle
, &ctx
))
1150 return packet_error
;
1152 if (gdbctx
->in_packet_len
< backend
->gdb_num_regs
* 2)
1153 return packet_error
;
1155 ptr
= gdbctx
->in_packet
;
1156 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1157 cpu_register_hex_from(gdbctx
, &ctx
, i
, &ptr
);
1159 if (!backend
->set_context(thread
->handle
, &ctx
))
1161 ERR("Failed to set context for tid %04x, error %u\n", thread
->tid
, GetLastError());
1162 return packet_error
;
1168 static enum packet_return
packet_kill(struct gdb_context
* gdbctx
)
1170 detach_debuggee(gdbctx
, TRUE
);
1171 return packet_ok
| packet_last_f
;
1174 static enum packet_return
packet_thread(struct gdb_context
* gdbctx
)
1176 switch (gdbctx
->in_packet
[0])
1179 if (sscanf(gdbctx
->in_packet
, "c%x", &gdbctx
->exec_tid
) == 1)
1181 return packet_error
;
1183 if (sscanf(gdbctx
->in_packet
, "g%x", &gdbctx
->other_tid
) == 1)
1185 return packet_error
;
1187 FIXME("Unknown thread sub-command %c\n", gdbctx
->in_packet
[0]);
1188 return packet_error
;
1192 static enum packet_return
packet_read_memory(struct gdb_context
* gdbctx
)
1195 unsigned int len
, blk_len
, nread
;
1199 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2) return packet_error
;
1200 if (len
<= 0) return packet_error
;
1201 TRACE("Read %u bytes at %p\n", len
, addr
);
1202 for (nread
= 0; nread
< len
; nread
+= r
, addr
+= r
)
1204 blk_len
= min(sizeof(buffer
), len
- nread
);
1205 if (!gdbctx
->process
->process_io
->read(gdbctx
->process
->handle
, addr
,
1206 buffer
, blk_len
, &r
) || r
== 0)
1208 /* fail at first address, return error */
1209 if (nread
== 0) return packet_reply_error(gdbctx
, EFAULT
);
1210 /* something has already been read, return partial information */
1213 if (nread
== 0) packet_reply_open(gdbctx
);
1214 packet_reply_hex_to(gdbctx
, buffer
, r
);
1216 packet_reply_close(gdbctx
);
1220 static enum packet_return
packet_write_memory(struct gdb_context
* gdbctx
)
1223 unsigned int len
, blk_len
;
1228 ptr
= memchr(gdbctx
->in_packet
, ':', gdbctx
->in_packet_len
);
1231 ERR("Cannot find ':' in %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1232 return packet_error
;
1236 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2)
1238 ERR("Failed to parse %s\n", debugstr_a(gdbctx
->in_packet
));
1239 return packet_error
;
1241 if (ptr
- gdbctx
->in_packet
+ len
* 2 != gdbctx
->in_packet_len
)
1243 ERR("Length %u does not match packet length %u\n",
1244 (int)(ptr
- gdbctx
->in_packet
) + len
* 2, gdbctx
->in_packet_len
);
1245 return packet_error
;
1247 TRACE("Write %u bytes at %p\n", len
, addr
);
1250 blk_len
= min(sizeof(buffer
), len
);
1251 hex_from(buffer
, ptr
, blk_len
);
1252 if (!gdbctx
->process
->process_io
->write(gdbctx
->process
->handle
, addr
, buffer
, blk_len
, &w
) ||
1259 return packet_ok
; /* FIXME: error while writing ? */
1262 static enum packet_return
packet_read_register(struct gdb_context
* gdbctx
)
1264 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1265 struct backend_cpu
*backend
;
1269 if (!thread
) return packet_error
;
1270 if (!thread
->process
) return packet_error
;
1271 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1273 if (!backend
->get_context(thread
->handle
, &ctx
))
1274 return packet_error
;
1276 if (sscanf(gdbctx
->in_packet
, "%zx", ®
) != 1)
1277 return packet_error
;
1278 if (reg
>= backend
->gdb_num_regs
)
1280 WARN("Unhandled register %zu\n", reg
);
1281 return packet_error
;
1284 TRACE("%zu => %s\n", reg
, wine_dbgstr_longlong(cpu_register(gdbctx
, &ctx
, reg
)));
1286 packet_reply_open(gdbctx
);
1287 packet_reply_register_hex_to(gdbctx
, &ctx
, reg
);
1288 packet_reply_close(gdbctx
);
1292 static enum packet_return
packet_write_register(struct gdb_context
* gdbctx
)
1294 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1295 struct backend_cpu
*backend
;
1300 if (!thread
) return packet_error
;
1301 if (!thread
->process
) return packet_error
;
1302 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1304 if (!backend
->get_context(thread
->handle
, &ctx
))
1305 return packet_error
;
1307 if (!(ptr
= strchr(gdbctx
->in_packet
, '=')))
1308 return packet_error
;
1311 if (sscanf(gdbctx
->in_packet
, "%zx", ®
) != 1)
1312 return packet_error
;
1313 if (reg
>= backend
->gdb_num_regs
)
1315 /* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
1316 * it wouldn't matter too much, and it fakes our support for all regs
1318 WARN("Unhandled register %zu\n", reg
);
1322 TRACE("%zu <= %s\n", reg
, debugstr_an(ptr
, (int)(gdbctx
->in_packet_len
- (ptr
- gdbctx
->in_packet
))));
1324 cpu_register_hex_from(gdbctx
, &ctx
, reg
, (const char**)&ptr
);
1325 if (!backend
->set_context(thread
->handle
, &ctx
))
1327 ERR("Failed to set context for tid %04x, error %u\n", thread
->tid
, GetLastError());
1328 return packet_error
;
1334 static void packet_query_monitor_wnd_helper(struct gdb_context
* gdbctx
, HWND hWnd
, int indent
)
1342 if (!GetClassNameA(hWnd
, clsName
, sizeof(clsName
)))
1343 strcpy(clsName
, "-- Unknown --");
1344 if (!GetWindowTextA(hWnd
, wndName
, sizeof(wndName
)))
1345 strcpy(wndName
, "-- Empty --");
1347 packet_reply_open(gdbctx
);
1348 packet_reply_add(gdbctx
, "O");
1349 snprintf(buffer
, sizeof(buffer
),
1350 "%*s%04lx%*s%-17.17s %08x %0*lx %.14s\n",
1351 indent
, "", (ULONG_PTR
)hWnd
, 13 - indent
, "",
1352 clsName
, GetWindowLongW(hWnd
, GWL_STYLE
),
1353 addr_width(gdbctx
), (ULONG_PTR
)GetWindowLongPtrW(hWnd
, GWLP_WNDPROC
),
1355 packet_reply_hex_to_str(gdbctx
, buffer
);
1356 packet_reply_close(gdbctx
);
1358 if ((child
= GetWindow(hWnd
, GW_CHILD
)) != 0)
1359 packet_query_monitor_wnd_helper(gdbctx
, child
, indent
+ 1);
1360 } while ((hWnd
= GetWindow(hWnd
, GW_HWNDNEXT
)) != 0);
1363 static void packet_query_monitor_wnd(struct gdb_context
* gdbctx
, int len
, const char* str
)
1367 /* we do the output in several 'O' packets, with the last one being just OK for
1368 * marking the end of the output */
1369 packet_reply_open(gdbctx
);
1370 packet_reply_add(gdbctx
, "O");
1371 snprintf(buffer
, sizeof(buffer
),
1372 "%-16.16s %-17.17s %-8.8s %s\n",
1373 "hwnd", "Class Name", " Style", " WndProc Text");
1374 packet_reply_hex_to_str(gdbctx
, buffer
);
1375 packet_reply_close(gdbctx
);
1377 /* FIXME: could also add a pmt to this command in str... */
1378 packet_query_monitor_wnd_helper(gdbctx
, GetDesktopWindow(), 0);
1379 packet_reply(gdbctx
, "OK");
1382 static void packet_query_monitor_process(struct gdb_context
* gdbctx
, int len
, const char* str
)
1384 HANDLE snap
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
1385 char buffer
[31+MAX_PATH
];
1387 PROCESSENTRY32 entry
;
1390 if (snap
== INVALID_HANDLE_VALUE
)
1393 entry
.dwSize
= sizeof(entry
);
1394 ok
= Process32First(snap
, &entry
);
1396 /* we do the output in several 'O' packets, with the last one being just OK for
1397 * marking the end of the output */
1399 packet_reply_open(gdbctx
);
1400 packet_reply_add(gdbctx
, "O");
1401 snprintf(buffer
, sizeof(buffer
),
1402 " %-8.8s %-8.8s %-8.8s %s\n",
1403 "pid", "threads", "parent", "executable");
1404 packet_reply_hex_to_str(gdbctx
, buffer
);
1405 packet_reply_close(gdbctx
);
1410 if (entry
.th32ProcessID
== gdbctx
->process
->pid
) deco
= '>';
1411 packet_reply_open(gdbctx
);
1412 packet_reply_add(gdbctx
, "O");
1413 snprintf(buffer
, sizeof(buffer
),
1414 "%c%08x %-8d %08x '%s'\n",
1415 deco
, entry
.th32ProcessID
, entry
.cntThreads
,
1416 entry
.th32ParentProcessID
, entry
.szExeFile
);
1417 packet_reply_hex_to_str(gdbctx
, buffer
);
1418 packet_reply_close(gdbctx
);
1419 ok
= Process32Next(snap
, &entry
);
1422 packet_reply(gdbctx
, "OK");
1425 static void packet_query_monitor_mem(struct gdb_context
* gdbctx
, int len
, const char* str
)
1427 MEMORY_BASIC_INFORMATION mbi
;
1434 /* we do the output in several 'O' packets, with the last one being just OK for
1435 * marking the end of the output */
1436 packet_reply_open(gdbctx
);
1437 packet_reply_add(gdbctx
, "O");
1438 packet_reply_hex_to_str(gdbctx
, "Address Size State Type RWX\n");
1439 packet_reply_close(gdbctx
);
1441 while (VirtualQueryEx(gdbctx
->process
->handle
, addr
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
))
1445 case MEM_COMMIT
: state
= "commit "; break;
1446 case MEM_FREE
: state
= "free "; break;
1447 case MEM_RESERVE
: state
= "reserve"; break;
1448 default: state
= "??? "; break;
1450 if (mbi
.State
!= MEM_FREE
)
1454 case MEM_IMAGE
: type
= "image "; break;
1455 case MEM_MAPPED
: type
= "mapped "; break;
1456 case MEM_PRIVATE
: type
= "private"; break;
1457 case 0: type
= " "; break;
1458 default: type
= "??? "; break;
1460 memset(prot
, ' ' , sizeof(prot
)-1);
1461 prot
[sizeof(prot
)-1] = '\0';
1462 if (mbi
.AllocationProtect
& (PAGE_READONLY
|PAGE_READWRITE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
|PAGE_WRITECOPY
|PAGE_EXECUTE_WRITECOPY
))
1464 if (mbi
.AllocationProtect
& (PAGE_READWRITE
|PAGE_EXECUTE_READWRITE
))
1466 if (mbi
.AllocationProtect
& (PAGE_WRITECOPY
|PAGE_EXECUTE_WRITECOPY
))
1468 if (mbi
.AllocationProtect
& (PAGE_EXECUTE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
|PAGE_EXECUTE_WRITECOPY
))
1476 packet_reply_open(gdbctx
);
1477 snprintf(buffer
, sizeof(buffer
), "%0*lx %0*lx %s %s %s\n",
1478 addr_width(gdbctx
), (DWORD_PTR
)addr
,
1479 addr_width(gdbctx
), mbi
.RegionSize
, state
, type
, prot
);
1480 packet_reply_add(gdbctx
, "O");
1481 packet_reply_hex_to_str(gdbctx
, buffer
);
1482 packet_reply_close(gdbctx
);
1484 if (addr
+ mbi
.RegionSize
< addr
) /* wrap around ? */
1486 addr
+= mbi
.RegionSize
;
1488 packet_reply(gdbctx
, "OK");
1496 void (*handler
)(struct gdb_context
*, int, const char*);
1499 {0, "wnd", 3, packet_query_monitor_wnd
},
1500 {0, "window", 6, packet_query_monitor_wnd
},
1501 {0, "proc", 4, packet_query_monitor_process
},
1502 {0, "process", 7, packet_query_monitor_process
},
1503 {0, "mem", 3, packet_query_monitor_mem
},
1507 static enum packet_return
packet_query_remote_command(struct gdb_context
* gdbctx
,
1508 const char* hxcmd
, size_t len
)
1511 struct query_detail
* qd
;
1513 assert((len
& 1) == 0 && len
< 2 * sizeof(buffer
));
1515 hex_from(buffer
, hxcmd
, len
);
1517 for (qd
= query_details
; qd
->name
!= NULL
; qd
++)
1519 if (len
< qd
->len
|| strncmp(buffer
, qd
->name
, qd
->len
) != 0) continue;
1520 if (!qd
->with_arg
&& len
!= qd
->len
) continue;
1522 (qd
->handler
)(gdbctx
, len
- qd
->len
, buffer
+ qd
->len
);
1525 return packet_reply_error(gdbctx
, EINVAL
);
1528 static BOOL CALLBACK
packet_query_libraries_cb(PCSTR mod_name
, DWORD64 base
, PVOID ctx
)
1530 struct gdb_context
* gdbctx
= ctx
;
1531 MEMORY_BASIC_INFORMATION mbi
;
1532 IMAGE_SECTION_HEADER
*sec
;
1533 IMAGE_DOS_HEADER
*dos
= NULL
;
1534 IMAGE_NT_HEADERS
*nth
= NULL
;
1535 IMAGEHLP_MODULE64 mod
;
1540 mod
.SizeOfStruct
= sizeof(mod
);
1541 SymGetModuleInfo64(gdbctx
->process
->handle
, base
, &mod
);
1543 packet_reply_add(gdbctx
, "<library name=\"");
1544 if (strcmp(mod
.LoadedImageName
, "[vdso].so") == 0)
1545 packet_reply_add(gdbctx
, "linux-vdso.so.1");
1546 else if (mod
.LoadedImageName
[0] == '/')
1547 packet_reply_add(gdbctx
, mod
.LoadedImageName
);
1550 UNICODE_STRING nt_name
;
1551 ANSI_STRING ansi_name
;
1552 char *unix_path
, *tmp
;
1554 RtlInitAnsiString(&ansi_name
, mod
.LoadedImageName
);
1555 RtlAnsiStringToUnicodeString(&nt_name
, &ansi_name
, TRUE
);
1557 if ((unix_path
= wine_get_unix_file_name(nt_name
.Buffer
)))
1559 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) &&
1560 is_wow64
&& (tmp
= strstr(unix_path
, "system32")))
1561 memcpy(tmp
, "syswow64", 8);
1562 packet_reply_add(gdbctx
, unix_path
);
1565 packet_reply_add(gdbctx
, mod
.LoadedImageName
);
1567 HeapFree(GetProcessHeap(), 0, unix_path
);
1568 RtlFreeUnicodeString(&nt_name
);
1570 packet_reply_add(gdbctx
, "\">");
1572 size
= sizeof(buffer
);
1573 if (VirtualQueryEx(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
) &&
1574 mbi
.Type
== MEM_IMAGE
&& mbi
.State
!= MEM_FREE
)
1576 if (ReadProcessMemory(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, buffer
, size
, &size
) &&
1577 size
>= sizeof(IMAGE_DOS_HEADER
))
1578 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1580 if (dos
&& dos
->e_magic
== IMAGE_DOS_SIGNATURE
&& dos
->e_lfanew
< size
)
1581 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1583 if (nth
&& memcmp(&nth
->Signature
, "PE\0\0", 4))
1587 if (!nth
) memset(buffer
, 0, sizeof(buffer
));
1589 /* if the module is not PE we have cleared buffer with 0, this makes
1590 * the following computation valid in all cases. */
1591 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1592 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1593 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) && is_wow64
)
1594 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS32
*)nth
);
1596 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS64
*)nth
);
1598 for (i
= 0; i
< max(nth
->FileHeader
.NumberOfSections
, 1); ++i
)
1600 if ((char *)(sec
+ i
) >= buffer
+ size
) break;
1601 packet_reply_add(gdbctx
, "<segment address=\"0x");
1602 packet_reply_val(gdbctx
, mod
.BaseOfImage
+ sec
[i
].VirtualAddress
, sizeof(unsigned long));
1603 packet_reply_add(gdbctx
, "\"/>");
1606 packet_reply_add(gdbctx
, "</library>");
1611 static void packet_query_libraries(struct gdb_context
* gdbctx
)
1615 /* this will resynchronize builtin dbghelp's internal ELF module list */
1616 SymLoadModule(gdbctx
->process
->handle
, 0, 0, 0, 0, 0);
1618 packet_reply_add(gdbctx
, "<library-list>");
1619 opt
= SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, TRUE
);
1620 SymEnumerateModules64(gdbctx
->process
->handle
, packet_query_libraries_cb
, gdbctx
);
1621 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, opt
);
1622 packet_reply_add(gdbctx
, "</library-list>");
1625 static void packet_query_threads(struct gdb_context
* gdbctx
)
1627 struct dbg_process
* process
= gdbctx
->process
;
1628 struct dbg_thread
* thread
;
1630 packet_reply_add(gdbctx
, "<threads>");
1631 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1633 packet_reply_add(gdbctx
, "<thread ");
1634 packet_reply_add(gdbctx
, "id=\"");
1635 packet_reply_val(gdbctx
, thread
->tid
, 4);
1636 packet_reply_add(gdbctx
, "\" name=\"");
1637 packet_reply_add(gdbctx
, thread
->name
);
1638 packet_reply_add(gdbctx
, "\"/>");
1640 packet_reply_add(gdbctx
, "</threads>");
1643 static void packet_query_target_xml(struct gdb_context
* gdbctx
, struct backend_cpu
* cpu
)
1645 const char* feature_prefix
= NULL
;
1646 const char* feature
= NULL
;
1650 packet_reply_add(gdbctx
, "<target>");
1651 switch (cpu
->machine
)
1653 case IMAGE_FILE_MACHINE_AMD64
:
1654 packet_reply_add(gdbctx
, "<architecture>i386:x86-64</architecture>");
1655 feature_prefix
= "org.gnu.gdb.i386.";
1657 case IMAGE_FILE_MACHINE_I386
:
1658 packet_reply_add(gdbctx
, "<architecture>i386</architecture>");
1659 feature_prefix
= "org.gnu.gdb.i386.";
1661 case IMAGE_FILE_MACHINE_ARMNT
:
1662 packet_reply_add(gdbctx
, "<architecture>arm</architecture>");
1663 feature_prefix
= "org.gnu.gdb.arm.";
1665 case IMAGE_FILE_MACHINE_ARM64
:
1666 packet_reply_add(gdbctx
, "<architecture>aarch64</architecture>");
1667 feature_prefix
= "org.gnu.gdb.aarch64.";
1671 for (i
= 0; i
< cpu
->gdb_num_regs
; ++i
)
1673 if (cpu
->gdb_register_map
[i
].feature
)
1675 if (feature
) packet_reply_add(gdbctx
, "</feature>");
1676 feature
= cpu
->gdb_register_map
[i
].feature
;
1678 packet_reply_add(gdbctx
, "<feature name=\"");
1679 if (feature_prefix
) packet_reply_add(gdbctx
, feature_prefix
);
1680 packet_reply_add(gdbctx
, feature
);
1681 packet_reply_add(gdbctx
, "\">");
1683 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1684 strcmp(feature
, "core") == 0)
1685 packet_reply_add(gdbctx
, "<flags id=\"i386_eflags\" size=\"4\">"
1686 "<field name=\"CF\" start=\"0\" end=\"0\"/>"
1687 "<field name=\"\" start=\"1\" end=\"1\"/>"
1688 "<field name=\"PF\" start=\"2\" end=\"2\"/>"
1689 "<field name=\"AF\" start=\"4\" end=\"4\"/>"
1690 "<field name=\"ZF\" start=\"6\" end=\"6\"/>"
1691 "<field name=\"SF\" start=\"7\" end=\"7\"/>"
1692 "<field name=\"TF\" start=\"8\" end=\"8\"/>"
1693 "<field name=\"IF\" start=\"9\" end=\"9\"/>"
1694 "<field name=\"DF\" start=\"10\" end=\"10\"/>"
1695 "<field name=\"OF\" start=\"11\" end=\"11\"/>"
1696 "<field name=\"NT\" start=\"14\" end=\"14\"/>"
1697 "<field name=\"RF\" start=\"16\" end=\"16\"/>"
1698 "<field name=\"VM\" start=\"17\" end=\"17\"/>"
1699 "<field name=\"AC\" start=\"18\" end=\"18\"/>"
1700 "<field name=\"VIF\" start=\"19\" end=\"19\"/>"
1701 "<field name=\"VIP\" start=\"20\" end=\"20\"/>"
1702 "<field name=\"ID\" start=\"21\" end=\"21\"/>"
1705 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1706 strcmp(feature
, "sse") == 0)
1707 packet_reply_add(gdbctx
, "<vector id=\"v4f\" type=\"ieee_single\" count=\"4\"/>"
1708 "<vector id=\"v2d\" type=\"ieee_double\" count=\"2\"/>"
1709 "<vector id=\"v16i8\" type=\"int8\" count=\"16\"/>"
1710 "<vector id=\"v8i16\" type=\"int16\" count=\"8\"/>"
1711 "<vector id=\"v4i32\" type=\"int32\" count=\"4\"/>"
1712 "<vector id=\"v2i64\" type=\"int64\" count=\"2\"/>"
1713 "<union id=\"vec128\">"
1714 "<field name=\"v4_float\" type=\"v4f\"/>"
1715 "<field name=\"v2_double\" type=\"v2d\"/>"
1716 "<field name=\"v16_int8\" type=\"v16i8\"/>"
1717 "<field name=\"v8_int16\" type=\"v8i16\"/>"
1718 "<field name=\"v4_int32\" type=\"v4i32\"/>"
1719 "<field name=\"v2_int64\" type=\"v2i64\"/>"
1720 "<field name=\"uint128\" type=\"uint128\"/>"
1722 "<flags id=\"i386_mxcsr\" size=\"4\">"
1723 "<field name=\"IE\" start=\"0\" end=\"0\"/>"
1724 "<field name=\"DE\" start=\"1\" end=\"1\"/>"
1725 "<field name=\"ZE\" start=\"2\" end=\"2\"/>"
1726 "<field name=\"OE\" start=\"3\" end=\"3\"/>"
1727 "<field name=\"UE\" start=\"4\" end=\"4\"/>"
1728 "<field name=\"PE\" start=\"5\" end=\"5\"/>"
1729 "<field name=\"DAZ\" start=\"6\" end=\"6\"/>"
1730 "<field name=\"IM\" start=\"7\" end=\"7\"/>"
1731 "<field name=\"DM\" start=\"8\" end=\"8\"/>"
1732 "<field name=\"ZM\" start=\"9\" end=\"9\"/>"
1733 "<field name=\"OM\" start=\"10\" end=\"10\"/>"
1734 "<field name=\"UM\" start=\"11\" end=\"11\"/>"
1735 "<field name=\"PM\" start=\"12\" end=\"12\"/>"
1736 "<field name=\"FZ\" start=\"15\" end=\"15\"/>"
1740 snprintf(buffer
, ARRAY_SIZE(buffer
), "<reg name=\"%s\" bitsize=\"%zu\"",
1741 cpu
->gdb_register_map
[i
].name
, 8 * cpu
->gdb_register_map
[i
].length
);
1742 packet_reply_add(gdbctx
, buffer
);
1744 if (cpu
->gdb_register_map
[i
].type
)
1746 packet_reply_add(gdbctx
, " type=\"");
1747 packet_reply_add(gdbctx
, cpu
->gdb_register_map
[i
].type
);
1748 packet_reply_add(gdbctx
, "\"");
1751 packet_reply_add(gdbctx
, "/>");
1754 if (feature
) packet_reply_add(gdbctx
, "</feature>");
1755 packet_reply_add(gdbctx
, "</target>");
1758 static enum packet_return
packet_query(struct gdb_context
* gdbctx
)
1761 struct backend_cpu
*cpu
;
1763 switch (gdbctx
->in_packet
[0])
1766 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
1768 struct dbg_thread
* thd
;
1770 packet_reply_open(gdbctx
);
1771 packet_reply_add(gdbctx
, "m");
1772 LIST_FOR_EACH_ENTRY(thd
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
1774 packet_reply_val(gdbctx
, thd
->tid
, 4);
1775 if (list_next(&gdbctx
->process
->threads
, &thd
->entry
) != NULL
)
1776 packet_reply_add(gdbctx
, ",");
1778 packet_reply_close(gdbctx
);
1781 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
1785 packet_reply_open(gdbctx
);
1786 packet_reply_add(gdbctx
, "O");
1787 get_process_info(gdbctx
, result
, sizeof(result
));
1788 packet_reply_hex_to_str(gdbctx
, result
);
1789 packet_reply_close(gdbctx
);
1794 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
1796 packet_reply(gdbctx
, "l");
1799 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
1801 packet_reply(gdbctx
, "l");
1806 if (strncmp(gdbctx
->in_packet
, "Attached", gdbctx
->in_packet_len
) == 0)
1807 return packet_reply(gdbctx
, "1");
1810 if (gdbctx
->in_packet_len
== 1)
1812 struct dbg_thread
* thd
;
1813 /* FIXME: doc says 16 bit val ??? */
1814 /* grab first created thread, aka last in list */
1815 assert(gdbctx
->process
&& !list_empty(&gdbctx
->process
->threads
));
1816 thd
= LIST_ENTRY(list_tail(&gdbctx
->process
->threads
), struct dbg_thread
, entry
);
1817 packet_reply_open(gdbctx
);
1818 packet_reply_add(gdbctx
, "QC");
1819 packet_reply_val(gdbctx
, thd
->tid
, 4);
1820 packet_reply_close(gdbctx
);
1825 if (strncmp(gdbctx
->in_packet
, "Offsets", gdbctx
->in_packet_len
) == 0)
1829 snprintf(buf
, sizeof(buf
),
1830 "Text=%08lx;Data=%08lx;Bss=%08lx",
1831 gdbctx
->wine_segs
[0], gdbctx
->wine_segs
[1],
1832 gdbctx
->wine_segs
[2]);
1833 return packet_reply(gdbctx
, buf
);
1837 if (gdbctx
->in_packet_len
> 5 && strncmp(gdbctx
->in_packet
, "Rcmd,", 5) == 0)
1839 return packet_query_remote_command(gdbctx
, gdbctx
->in_packet
+ 5,
1840 gdbctx
->in_packet_len
- 5);
1844 if (strncmp(gdbctx
->in_packet
, "Symbol::", gdbctx
->in_packet_len
) == 0)
1846 if (strncmp(gdbctx
->in_packet
, "Supported", 9) == 0)
1848 packet_reply_open(gdbctx
);
1849 packet_reply_add(gdbctx
, "QStartNoAckMode+;");
1850 packet_reply_add(gdbctx
, "qXfer:libraries:read+;");
1851 packet_reply_add(gdbctx
, "qXfer:threads:read+;");
1852 packet_reply_add(gdbctx
, "qXfer:features:read+;");
1853 packet_reply_close(gdbctx
);
1858 if (gdbctx
->in_packet_len
> 15 &&
1859 strncmp(gdbctx
->in_packet
, "ThreadExtraInfo", 15) == 0 &&
1860 gdbctx
->in_packet
[15] == ',')
1866 tid
= strtol(gdbctx
->in_packet
+ 16, &end
, 16);
1867 if (end
== NULL
) break;
1868 get_thread_info(gdbctx
, tid
, result
, sizeof(result
));
1869 packet_reply_open(gdbctx
);
1870 packet_reply_hex_to_str(gdbctx
, result
);
1871 packet_reply_close(gdbctx
);
1874 if (strncmp(gdbctx
->in_packet
, "TStatus", 7) == 0)
1876 /* Tracepoints not supported */
1877 packet_reply_open(gdbctx
);
1878 packet_reply_close(gdbctx
);
1883 if (sscanf(gdbctx
->in_packet
, "Xfer:libraries:read::%x,%x", &off
, &len
) == 2)
1885 if (!gdbctx
->process
) return packet_error
;
1887 packet_reply_open_xfer(gdbctx
);
1888 packet_query_libraries(gdbctx
);
1889 packet_reply_close_xfer(gdbctx
, off
, len
);
1893 if (sscanf(gdbctx
->in_packet
, "Xfer:threads:read::%x,%x", &off
, &len
) == 2)
1895 if (!gdbctx
->process
) return packet_error
;
1897 packet_reply_open_xfer(gdbctx
);
1898 packet_query_threads(gdbctx
);
1899 packet_reply_close_xfer(gdbctx
, off
, len
);
1903 if (sscanf(gdbctx
->in_packet
, "Xfer:features:read:target.xml:%x,%x", &off
, &len
) == 2)
1905 if (!gdbctx
->process
) return packet_error
;
1906 if (!(cpu
= gdbctx
->process
->be_cpu
)) return packet_error
;
1908 packet_reply_open_xfer(gdbctx
);
1909 packet_query_target_xml(gdbctx
, cpu
);
1910 packet_reply_close_xfer(gdbctx
, off
, len
);
1915 ERR("Unhandled query %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1916 return packet_error
;
1919 static enum packet_return
packet_set(struct gdb_context
* gdbctx
)
1921 if (strncmp(gdbctx
->in_packet
, "StartNoAckMode", 14) == 0)
1923 gdbctx
->no_ack_mode
= TRUE
;
1927 return packet_error
;
1930 static enum packet_return
packet_step(struct gdb_context
* gdbctx
)
1934 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
1935 FIXME("Continue at address %p not supported\n", addr
);
1937 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, TRUE
, -1);
1939 wait_for_debuggee(gdbctx
);
1940 return packet_reply_status(gdbctx
);
1943 static enum packet_return
packet_thread_alive(struct gdb_context
* gdbctx
)
1948 tid
= strtol(gdbctx
->in_packet
, &end
, 16);
1949 if (tid
== -1 || tid
== 0)
1950 return packet_reply_error(gdbctx
, EINVAL
);
1951 if (dbg_get_thread(gdbctx
->process
, tid
) != NULL
)
1953 return packet_reply_error(gdbctx
, ESRCH
);
1956 /* =============================================== *
1957 * P A C K E T I N F R A S T R U C T U R E *
1958 * =============================================== *
1964 enum packet_return (*handler
)(struct gdb_context
* gdbctx
);
1967 static struct packet_entry packet_entries
[] =
1969 {'?', packet_last_signal
},
1970 {'c', packet_continue
},
1971 {'C', packet_continue_signal
},
1972 {'D', packet_detach
},
1973 {'g', packet_read_registers
},
1974 {'G', packet_write_registers
},
1976 {'H', packet_thread
},
1977 {'m', packet_read_memory
},
1978 {'M', packet_write_memory
},
1979 {'p', packet_read_register
},
1980 {'P', packet_write_register
},
1981 {'q', packet_query
},
1984 {'T', packet_thread_alive
},
1985 {'v', packet_verbose
},
1986 {'z', packet_delete_breakpoint
},
1987 {'Z', packet_insert_breakpoint
},
1990 static BOOL
extract_packets(struct gdb_context
* gdbctx
)
1992 char *ptr
, *sum
= gdbctx
->in_buf
, *end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
1993 enum packet_return ret
= packet_error
;
1997 /* ptr points to the beginning ('$') of the current packet
1998 * sum points to the beginning ('#') of the current packet checksum ("#xx")
1999 * len is the length of the current packet data (sum - ptr - 1)
2000 * end points to the end of the received data buffer
2003 while (!gdbctx
->no_ack_mode
&&
2004 (ptr
= memchr(sum
, '$', end
- sum
)) &&
2005 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
2006 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2008 len
= sum
- ptr
- 1;
2011 if (cksum
== checksum(ptr
+ 1, len
))
2013 TRACE("Acking: %s\n", debugstr_an(ptr
, sum
- ptr
));
2014 write(gdbctx
->sock
, "+", 1);
2018 ERR("Nacking: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2019 cksum
, checksum(ptr
+ 1, len
));
2020 write(gdbctx
->sock
, "-", 1);
2024 while ((ret
& packet_last_f
) == 0 &&
2025 (ptr
= memchr(gdbctx
->in_buf
, '$', gdbctx
->in_len
)) &&
2026 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
2027 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2029 if (ptr
!= gdbctx
->in_buf
)
2030 WARN("Ignoring: %s\n", debugstr_an(gdbctx
->in_buf
, ptr
- gdbctx
->in_buf
));
2032 len
= sum
- ptr
- 1;
2035 if (cksum
== checksum(ptr
+ 1, len
))
2037 TRACE("Handling: %s\n", debugstr_an(ptr
, sum
- ptr
));
2040 gdbctx
->in_packet
= ptr
+ 2;
2041 gdbctx
->in_packet_len
= len
- 1;
2042 gdbctx
->in_packet
[gdbctx
->in_packet_len
] = '\0';
2044 for (i
= 0; i
< ARRAY_SIZE(packet_entries
); i
++)
2045 if (packet_entries
[i
].key
== ptr
[1])
2048 if (i
== ARRAY_SIZE(packet_entries
))
2049 WARN("Unhandled: %s\n", debugstr_an(ptr
+ 1, len
));
2050 else if (((ret
= (packet_entries
[i
].handler
)(gdbctx
)) & ~packet_last_f
) == packet_error
)
2051 WARN("Failed: %s\n", debugstr_an(ptr
+ 1, len
));
2053 switch (ret
& ~packet_last_f
)
2055 case packet_error
: packet_reply(gdbctx
, ""); break;
2056 case packet_ok
: packet_reply(gdbctx
, "OK"); break;
2057 case packet_done
: break;
2060 TRACE("Reply: %s\n", debugstr_an(gdbctx
->out_buf
, gdbctx
->out_len
));
2061 i
= write(gdbctx
->sock
, gdbctx
->out_buf
, gdbctx
->out_len
);
2062 assert(i
== gdbctx
->out_len
);
2063 gdbctx
->out_len
= 0;
2066 WARN("Ignoring: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2067 cksum
, checksum(ptr
+ 1, len
));
2069 gdbctx
->in_len
= end
- sum
;
2070 memmove(gdbctx
->in_buf
, sum
, end
- sum
);
2071 end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
2074 return (ret
& packet_last_f
);
2077 static int fetch_data(struct gdb_context
* gdbctx
)
2079 int len
, in_len
= gdbctx
->in_len
;
2081 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2085 if (gdbctx
->in_len
+ STEP
> gdbctx
->in_buf_alloc
)
2086 gdbctx
->in_buf
= packet_realloc(gdbctx
->in_buf
, gdbctx
->in_buf_alloc
+= STEP
);
2088 len
= read(gdbctx
->sock
, gdbctx
->in_buf
+ gdbctx
->in_len
, gdbctx
->in_buf_alloc
- gdbctx
->in_len
- 1);
2089 if (len
<= 0) break;
2090 gdbctx
->in_len
+= len
;
2091 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2092 if (len
< gdbctx
->in_buf_alloc
- gdbctx
->in_len
) break;
2095 gdbctx
->in_buf
[gdbctx
->in_len
] = '\0';
2096 return gdbctx
->in_len
- in_len
;
2099 #define FLAG_NO_START 1
2100 #define FLAG_WITH_XTERM 2
2102 static BOOL
gdb_exec(unsigned port
, unsigned flags
)
2106 const char *gdb_path
, *tmp_path
;
2109 if (!(gdb_path
= getenv("WINE_GDB"))) gdb_path
= "gdb";
2110 if (!(tmp_path
= getenv("TMPDIR"))) tmp_path
= "/tmp";
2111 strcpy(buf
, tmp_path
);
2112 strcat(buf
, "/winegdb.XXXXXX");
2113 fd
= mkstemps(buf
, 0);
2114 if (fd
== -1) return FALSE
;
2115 if ((f
= fdopen(fd
, "w+")) == NULL
) return FALSE
;
2116 fprintf(f
, "target remote localhost:%d\n", ntohs(port
));
2117 fprintf(f
, "set prompt Wine-gdb>\\ \n");
2118 /* gdb 5.1 seems to require it, won't hurt anyway */
2119 fprintf(f
, "sharedlibrary\n");
2120 /* This is needed (but not a decent & final fix)
2121 * Without this, gdb would skip our inter-DLL relay code (because
2122 * we don't have any line number information for the relay code)
2123 * With this, we will stop on first instruction of the stub, and
2124 * reusing step, will get us through the relay stub at the actual
2125 * function we're looking at.
2127 fprintf(f
, "set step-mode on\n");
2128 /* tell gdb to delete this file when done handling it... */
2129 fprintf(f
, "shell rm -f \"%s\"\n", buf
);
2131 if (flags
& FLAG_WITH_XTERM
)
2132 execlp("xterm", "xterm", "-e", gdb_path
, "-x", buf
, NULL
);
2134 execlp(gdb_path
, gdb_path
, "-x", buf
, NULL
);
2135 assert(0); /* never reached */
2139 static BOOL
gdb_startup(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2142 struct sockaddr_in s_addrs
= {0};
2143 socklen_t s_len
= sizeof(s_addrs
);
2144 struct pollfd pollfd
;
2147 /* step 1: create socket for gdb connection request */
2148 if ((sock
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
2150 ERR("Failed to create socket: %s\n", strerror(errno
));
2154 s_addrs
.sin_family
= AF_INET
;
2155 s_addrs
.sin_addr
.s_addr
= INADDR_ANY
;
2156 s_addrs
.sin_port
= htons(port
);
2157 if (bind(sock
, (struct sockaddr
*)&s_addrs
, sizeof(s_addrs
)) == -1)
2160 if (listen(sock
, 1) == -1 || getsockname(sock
, (struct sockaddr
*)&s_addrs
, &s_len
) == -1)
2163 /* step 2: do the process internal creation */
2164 handle_debug_event(gdbctx
);
2166 /* step 3: fire up gdb (if requested) */
2167 if (flags
& FLAG_NO_START
)
2168 fprintf(stderr
, "target remote localhost:%d\n", ntohs(s_addrs
.sin_port
));
2172 case -1: /* error in parent... */
2173 ERR("Failed to start gdb: fork: %s\n", strerror(errno
));
2175 default: /* in parent... success */
2176 signal(SIGINT
, SIG_IGN
);
2178 case 0: /* in child... and alive */
2179 gdb_exec(s_addrs
.sin_port
, flags
);
2180 /* if we're here, exec failed, so report failure */
2184 /* step 4: wait for gdb to connect actually */
2186 pollfd
.events
= POLLIN
;
2189 switch (poll(&pollfd
, 1, -1))
2192 if (pollfd
.revents
& POLLIN
)
2195 gdbctx
->sock
= accept(sock
, (struct sockaddr
*)&s_addrs
, &s_len
);
2196 if (gdbctx
->sock
== -1)
2199 TRACE("connected on %d\n", gdbctx
->sock
);
2200 /* don't keep our small packets too long: send them ASAP back to GDB
2201 * without this, GDB really crawls
2203 setsockopt(gdbctx
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (char*)&dummy
, sizeof(dummy
));
2207 ERR("Timed out connecting to gdb\n");
2210 ERR("Failed to connect to gdb: poll: %s\n", strerror(errno
));
2221 static BOOL
gdb_init_context(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2226 gdbctx
->in_buf
= NULL
;
2227 gdbctx
->in_buf_alloc
= 0;
2229 gdbctx
->out_buf
= NULL
;
2230 gdbctx
->out_buf_alloc
= 0;
2231 gdbctx
->out_len
= 0;
2232 gdbctx
->out_curr_packet
= -1;
2234 gdbctx
->exec_tid
= -1;
2235 gdbctx
->other_tid
= -1;
2236 list_init(&gdbctx
->xpoint_list
);
2237 gdbctx
->process
= NULL
;
2238 gdbctx
->no_ack_mode
= FALSE
;
2239 for (i
= 0; i
< ARRAY_SIZE(gdbctx
->wine_segs
); i
++)
2240 gdbctx
->wine_segs
[i
] = 0;
2242 /* wait for first trap */
2243 while (WaitForDebugEvent(&gdbctx
->de
, INFINITE
))
2245 if (gdbctx
->de
.dwDebugEventCode
== CREATE_PROCESS_DEBUG_EVENT
)
2247 /* this should be the first event we get,
2248 * and the only one of this type */
2249 assert(gdbctx
->process
== NULL
&& gdbctx
->de
.dwProcessId
== dbg_curr_pid
);
2250 /* gdbctx->dwProcessId = pid; */
2251 if (!gdb_startup(gdbctx
, flags
, port
)) return FALSE
;
2253 else if (!handle_debug_event(gdbctx
))
2255 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
2260 static int gdb_remote(unsigned flags
, unsigned port
)
2262 struct pollfd pollfd
;
2263 struct gdb_context gdbctx
;
2266 for (doLoop
= gdb_init_context(&gdbctx
, flags
, port
); doLoop
;)
2268 pollfd
.fd
= gdbctx
.sock
;
2269 pollfd
.events
= POLLIN
;
2272 switch (poll(&pollfd
, 1, -1))
2276 if (pollfd
.revents
& (POLLHUP
| POLLERR
))
2278 ERR("gdb hung up\n");
2279 /* kill also debuggee process - questionnable - */
2280 detach_debuggee(&gdbctx
, TRUE
);
2284 if ((pollfd
.revents
& POLLIN
) && fetch_data(&gdbctx
) > 0)
2286 if (extract_packets(&gdbctx
)) doLoop
= FALSE
;
2290 /* timeout, should never happen (infinite timeout) */
2293 ERR("poll failed: %s\n", strerror(errno
));
2303 int gdb_main(int argc
, char* argv
[])
2306 unsigned gdb_flags
= 0, port
= 0;
2310 while (argc
> 0 && argv
[0][0] == '-')
2312 if (strcmp(argv
[0], "--no-start") == 0)
2314 gdb_flags
|= FLAG_NO_START
;
2318 if (strcmp(argv
[0], "--with-xterm") == 0)
2320 gdb_flags
|= FLAG_WITH_XTERM
;
2324 if (strcmp(argv
[0], "--port") == 0 && argc
> 1)
2326 port
= strtoul(argv
[1], &port_end
, 10);
2329 fprintf(stderr
, "Invalid port: %s\n", argv
[1]);
2332 argc
-= 2; argv
+= 2;
2337 if (dbg_active_attach(argc
, argv
) == start_ok
||
2338 dbg_active_launch(argc
, argv
) == start_ok
)
2339 return gdb_remote(gdb_flags
, port
);
2341 fprintf(stderr
, "GdbProxy mode not supported on this platform\n");