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_add_thread(gdbctx
->process
, de
->dwThreadId
,
441 de
->u
.CreateProcessInfo
.hThread
,
442 de
->u
.CreateProcessInfo
.lpThreadLocalBase
);
445 case LOAD_DLL_DEBUG_EVENT
:
446 fetch_module_name( de
->u
.LoadDll
.lpImageName
, de
->u
.LoadDll
.lpBaseOfDll
,
447 u
.buffer
, ARRAY_SIZE(u
.buffer
) );
448 fprintf(stderr
, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
449 de
->dwProcessId
, de
->dwThreadId
,
450 dbg_W2A(u
.buffer
, -1),
451 de
->u
.LoadDll
.lpBaseOfDll
,
452 de
->u
.LoadDll
.dwDebugInfoFileOffset
,
453 de
->u
.LoadDll
.nDebugInfoSize
);
454 dbg_load_module(gdbctx
->process
->handle
, de
->u
.LoadDll
.hFile
, u
.buffer
,
455 (DWORD_PTR
)de
->u
.LoadDll
.lpBaseOfDll
, 0);
458 case UNLOAD_DLL_DEBUG_EVENT
:
459 fprintf(stderr
, "%08x:%08x: unload DLL @%p\n",
460 de
->dwProcessId
, de
->dwThreadId
, de
->u
.UnloadDll
.lpBaseOfDll
);
461 SymUnloadModule(gdbctx
->process
->handle
,
462 (DWORD_PTR
)de
->u
.UnloadDll
.lpBaseOfDll
);
465 case EXCEPTION_DEBUG_EVENT
:
466 TRACE("%08x:%08x: exception code=0x%08x\n", de
->dwProcessId
,
467 de
->dwThreadId
, de
->u
.Exception
.ExceptionRecord
.ExceptionCode
);
469 if (handle_exception(gdbctx
, &de
->u
.Exception
))
473 case CREATE_THREAD_DEBUG_EVENT
:
474 fprintf(stderr
, "%08x:%08x: create thread D @%p\n", de
->dwProcessId
,
475 de
->dwThreadId
, de
->u
.CreateThread
.lpStartAddress
);
477 dbg_add_thread(gdbctx
->process
,
479 de
->u
.CreateThread
.hThread
,
480 de
->u
.CreateThread
.lpThreadLocalBase
);
483 case EXIT_THREAD_DEBUG_EVENT
:
484 fprintf(stderr
, "%08x:%08x: exit thread (%u)\n",
485 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitThread
.dwExitCode
);
486 if ((thread
= dbg_get_thread(gdbctx
->process
, de
->dwThreadId
)))
487 dbg_del_thread(thread
);
490 case EXIT_PROCESS_DEBUG_EVENT
:
491 fprintf(stderr
, "%08x:%08x: exit process (%u)\n",
492 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitProcess
.dwExitCode
);
494 dbg_del_process(gdbctx
->process
);
495 gdbctx
->process
= NULL
;
498 case OUTPUT_DEBUG_STRING_EVENT
:
499 memory_get_string(gdbctx
->process
,
500 de
->u
.DebugString
.lpDebugStringData
, TRUE
,
501 de
->u
.DebugString
.fUnicode
, u
.bufferA
, sizeof(u
.bufferA
));
502 fprintf(stderr
, "%08x:%08x: output debug string (%s)\n",
503 de
->dwProcessId
, de
->dwThreadId
, debugstr_a(u
.bufferA
));
507 fprintf(stderr
, "%08x:%08x: rip error=%u type=%u\n", de
->dwProcessId
,
508 de
->dwThreadId
, de
->u
.RipInfo
.dwError
, de
->u
.RipInfo
.dwType
);
512 FIXME("%08x:%08x: unknown event (%u)\n",
513 de
->dwProcessId
, de
->dwThreadId
, de
->dwDebugEventCode
);
516 LIST_FOR_EACH_ENTRY(thread
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
518 if (!thread
->suspended
) SuspendThread(thread
->handle
);
519 thread
->suspended
= TRUE
;
525 static void handle_step_or_continue(struct gdb_context
* gdbctx
, int tid
, BOOL step
, int sig
)
527 struct dbg_process
*process
= gdbctx
->process
;
528 struct dbg_thread
*thread
;
530 if (tid
== 0) tid
= gdbctx
->de
.dwThreadId
;
531 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
533 if (tid
!= -1 && thread
->tid
!= tid
) continue;
534 if (!thread
->suspended
) continue;
535 thread
->suspended
= FALSE
;
537 if (process
->pid
== gdbctx
->de
.dwProcessId
&& thread
->tid
== gdbctx
->de
.dwThreadId
)
538 gdbctx
->de_reply
= (sig
== -1 ? DBG_CONTINUE
: DBG_EXCEPTION_NOT_HANDLED
);
540 dbg_thread_set_single_step(thread
, step
);
541 ResumeThread(thread
->handle
);
545 static BOOL
check_for_interrupt(struct gdb_context
* gdbctx
)
547 struct pollfd pollfd
;
551 pollfd
.fd
= gdbctx
->sock
;
552 pollfd
.events
= POLLIN
;
555 if ((ret
= poll(&pollfd
, 1, 0)) == 1) {
556 ret
= read(gdbctx
->sock
, &pkt
, 1);
558 ERR("read failed\n");
562 ERR("Unexpected break packet %#02x\n", pkt
);
566 } else if (ret
== -1) {
567 ERR("poll failed\n");
572 static void wait_for_debuggee(struct gdb_context
* gdbctx
)
574 if (gdbctx
->de
.dwDebugEventCode
)
575 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, gdbctx
->de_reply
);
579 if (!WaitForDebugEvent(&gdbctx
->de
, 10))
581 if (GetLastError() == ERROR_SEM_TIMEOUT
)
583 if (check_for_interrupt(gdbctx
)) {
584 if (!DebugBreakProcess(gdbctx
->process
->handle
)) {
585 ERR("Failed to break into debuggee\n");
588 WaitForDebugEvent(&gdbctx
->de
, INFINITE
);
596 if (!handle_debug_event(gdbctx
))
598 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
602 static void detach_debuggee(struct gdb_context
* gdbctx
, BOOL kill
)
604 handle_step_or_continue(gdbctx
, -1, FALSE
, -1);
606 if (gdbctx
->de
.dwDebugEventCode
)
607 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
610 DebugActiveProcessStop(gdbctx
->process
->pid
);
611 dbg_del_process(gdbctx
->process
);
612 gdbctx
->process
= NULL
;
615 static void get_process_info(struct gdb_context
* gdbctx
, char* buffer
, size_t len
)
619 if (!GetExitCodeProcess(gdbctx
->process
->handle
, &status
))
621 strcpy(buffer
, "Unknown process");
624 if (status
== STILL_ACTIVE
)
626 strcpy(buffer
, "Running");
629 snprintf(buffer
, len
, "Terminated (%u)", status
);
631 switch (GetPriorityClass(gdbctx
->process
->handle
))
634 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
635 case ABOVE_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", above normal priority"); break;
637 #ifdef BELOW_NORMAL_PRIORITY_CLASS
638 case BELOW_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", below normal priority"); break;
640 case HIGH_PRIORITY_CLASS
: strcat(buffer
, ", high priority"); break;
641 case IDLE_PRIORITY_CLASS
: strcat(buffer
, ", idle priority"); break;
642 case NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", normal priority"); break;
643 case REALTIME_PRIORITY_CLASS
: strcat(buffer
, ", realtime priority"); break;
645 strcat(buffer
, "\n");
648 static void get_thread_info(struct gdb_context
* gdbctx
, unsigned tid
,
649 char* buffer
, size_t len
)
651 struct dbg_thread
* thd
;
655 /* FIXME: use the size of buffer */
656 thd
= dbg_get_thread(gdbctx
->process
, tid
);
659 strcpy(buffer
, "No information");
662 if (GetExitCodeThread(thd
->handle
, &status
))
664 if (status
== STILL_ACTIVE
)
666 /* FIXME: this is a bit brutal... some nicer way shall be found */
667 switch (status
= SuspendThread(thd
->handle
))
670 case 0: strcpy(buffer
, "Running"); break;
671 default: snprintf(buffer
, len
, "Suspended (%u)", status
- 1);
673 ResumeThread(thd
->handle
);
676 snprintf(buffer
, len
, "Terminated (exit code = %u)", status
);
680 strcpy(buffer
, "Unknown threadID");
682 switch (prio
= GetThreadPriority(thd
->handle
))
684 case THREAD_PRIORITY_ERROR_RETURN
: break;
685 case THREAD_PRIORITY_ABOVE_NORMAL
: strcat(buffer
, ", priority +1 above normal"); break;
686 case THREAD_PRIORITY_BELOW_NORMAL
: strcat(buffer
, ", priority -1 below normal"); break;
687 case THREAD_PRIORITY_HIGHEST
: strcat(buffer
, ", priority +2 above normal"); break;
688 case THREAD_PRIORITY_LOWEST
: strcat(buffer
, ", priority -2 below normal"); break;
689 case THREAD_PRIORITY_IDLE
: strcat(buffer
, ", priority idle"); break;
690 case THREAD_PRIORITY_NORMAL
: strcat(buffer
, ", priority normal"); break;
691 case THREAD_PRIORITY_TIME_CRITICAL
: strcat(buffer
, ", priority time-critical"); break;
692 default: snprintf(buffer
+ strlen(buffer
), len
- strlen(buffer
), ", priority = %d", prio
);
694 assert(strlen(buffer
) < len
);
697 /* =============================================== *
698 * P A C K E T U T I L S *
699 * =============================================== *
702 enum packet_return
{packet_error
= 0x00, packet_ok
= 0x01, packet_done
= 0x02,
703 packet_last_f
= 0x80};
705 static char* packet_realloc(char* buf
, int size
)
708 return HeapAlloc(GetProcessHeap(), 0, size
);
709 return HeapReAlloc(GetProcessHeap(), 0, buf
, size
);
713 static void packet_reply_grow(struct gdb_context
* gdbctx
, size_t size
)
715 if (gdbctx
->out_buf_alloc
< gdbctx
->out_len
+ size
)
717 gdbctx
->out_buf_alloc
= ((gdbctx
->out_len
+ size
) / 32 + 1) * 32;
718 gdbctx
->out_buf
= packet_realloc(gdbctx
->out_buf
, gdbctx
->out_buf_alloc
);
722 static void packet_reply_hex_to(struct gdb_context
* gdbctx
, const void* src
, int len
)
724 packet_reply_grow(gdbctx
, len
* 2);
725 hex_to(&gdbctx
->out_buf
[gdbctx
->out_len
], src
, len
);
726 gdbctx
->out_len
+= len
* 2;
729 static inline void packet_reply_hex_to_str(struct gdb_context
* gdbctx
, const char* src
)
731 packet_reply_hex_to(gdbctx
, src
, strlen(src
));
734 static void packet_reply_val(struct gdb_context
* gdbctx
, unsigned long val
, int len
)
738 shift
= (len
- 1) * 8;
739 packet_reply_grow(gdbctx
, len
* 2);
740 for (i
= 0; i
< len
; i
++, shift
-= 8)
742 gdbctx
->out_buf
[gdbctx
->out_len
++] = hex_to0((val
>> (shift
+ 4)) & 0x0F);
743 gdbctx
->out_buf
[gdbctx
->out_len
++] = hex_to0((val
>> shift
) & 0x0F);
747 static inline void packet_reply_add(struct gdb_context
* gdbctx
, const char* str
)
749 int len
= strlen(str
);
750 packet_reply_grow(gdbctx
, len
);
751 memcpy(&gdbctx
->out_buf
[gdbctx
->out_len
], str
, len
);
752 gdbctx
->out_len
+= len
;
755 static void packet_reply_open(struct gdb_context
* gdbctx
)
757 assert(gdbctx
->out_curr_packet
== -1);
758 packet_reply_add(gdbctx
, "$");
759 gdbctx
->out_curr_packet
= gdbctx
->out_len
;
762 static void packet_reply_close(struct gdb_context
* gdbctx
)
767 plen
= gdbctx
->out_len
- gdbctx
->out_curr_packet
;
768 packet_reply_add(gdbctx
, "#");
769 cksum
= checksum(&gdbctx
->out_buf
[gdbctx
->out_curr_packet
], plen
);
770 packet_reply_hex_to(gdbctx
, &cksum
, 1);
771 gdbctx
->out_curr_packet
= -1;
774 static void packet_reply_open_xfer(struct gdb_context
* gdbctx
)
776 packet_reply_open(gdbctx
);
777 packet_reply_add(gdbctx
, "m");
780 static void packet_reply_close_xfer(struct gdb_context
* gdbctx
, int off
, int len
)
782 int begin
= gdbctx
->out_curr_packet
+ 1;
785 if (begin
+ off
< gdbctx
->out_len
)
787 gdbctx
->out_len
-= off
;
788 memmove(gdbctx
->out_buf
+ begin
, gdbctx
->out_buf
+ begin
+ off
, gdbctx
->out_len
);
792 gdbctx
->out_buf
[gdbctx
->out_curr_packet
] = 'l';
793 gdbctx
->out_len
= gdbctx
->out_curr_packet
+ 1;
796 plen
= gdbctx
->out_len
- begin
;
797 if (len
>= 0 && plen
> len
) gdbctx
->out_len
-= (plen
- len
);
798 else gdbctx
->out_buf
[gdbctx
->out_curr_packet
] = 'l';
800 packet_reply_close(gdbctx
);
803 static enum packet_return
packet_reply(struct gdb_context
* gdbctx
, const char* packet
)
805 packet_reply_open(gdbctx
);
807 assert(strchr(packet
, '$') == NULL
&& strchr(packet
, '#') == NULL
);
809 packet_reply_add(gdbctx
, packet
);
811 packet_reply_close(gdbctx
);
816 static enum packet_return
packet_reply_error(struct gdb_context
* gdbctx
, int error
)
818 packet_reply_open(gdbctx
);
820 packet_reply_add(gdbctx
, "E");
821 packet_reply_val(gdbctx
, error
, 1);
823 packet_reply_close(gdbctx
);
828 static inline void packet_reply_register_hex_to(struct gdb_context
* gdbctx
, dbg_ctx_t
* ctx
, unsigned idx
)
830 const struct gdb_register
*cpu_register_map
= gdbctx
->process
->be_cpu
->gdb_register_map
;
831 packet_reply_hex_to(gdbctx
, cpu_register_ptr(gdbctx
, ctx
, idx
), cpu_register_map
[idx
].length
);
834 /* =============================================== *
835 * P A C K E T H A N D L E R S *
836 * =============================================== *
839 static void packet_reply_status_xpoints(struct gdb_context
* gdbctx
, struct dbg_thread
*thread
,
842 struct dbg_process
*process
= thread
->process
;
843 struct backend_cpu
*cpu
= process
->be_cpu
;
844 struct gdb_xpoint
*x
;
846 LIST_FOR_EACH_ENTRY(x
, &gdbctx
->xpoint_list
, struct gdb_xpoint
, entry
)
848 if (x
->pid
!= process
->pid
|| x
->tid
!= thread
->tid
)
850 if (!cpu
->is_watchpoint_set(ctx
, x
->value
))
852 if (x
->type
== be_xpoint_watch_write
)
854 packet_reply_add(gdbctx
, "watch:");
855 packet_reply_val(gdbctx
, (unsigned long)x
->addr
, sizeof(x
->addr
));
856 packet_reply_add(gdbctx
, ";");
858 if (x
->type
== be_xpoint_watch_read
)
860 packet_reply_add(gdbctx
, "rwatch:");
861 packet_reply_val(gdbctx
, (unsigned long)x
->addr
, sizeof(x
->addr
));
862 packet_reply_add(gdbctx
, ";");
867 static enum packet_return
packet_reply_status(struct gdb_context
* gdbctx
)
869 struct dbg_process
*process
= gdbctx
->process
;
870 struct dbg_thread
*thread
;
871 struct backend_cpu
*backend
;
875 switch (gdbctx
->de
.dwDebugEventCode
)
878 if (!process
) return packet_error
;
879 if (!(backend
= process
->be_cpu
)) return packet_error
;
880 if (!(thread
= dbg_get_thread(process
, gdbctx
->de
.dwThreadId
)) ||
881 !backend
->get_context(thread
->handle
, &ctx
))
884 packet_reply_open(gdbctx
);
885 packet_reply_add(gdbctx
, "T");
886 packet_reply_val(gdbctx
, signal_from_debug_event(&gdbctx
->de
), 1);
887 packet_reply_add(gdbctx
, "thread:");
888 packet_reply_val(gdbctx
, gdbctx
->de
.dwThreadId
, 4);
889 packet_reply_add(gdbctx
, ";");
890 packet_reply_status_xpoints(gdbctx
, thread
, &ctx
);
892 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
894 packet_reply_val(gdbctx
, i
, 1);
895 packet_reply_add(gdbctx
, ":");
896 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
897 packet_reply_add(gdbctx
, ";");
900 packet_reply_close(gdbctx
);
903 case EXIT_PROCESS_DEBUG_EVENT
:
904 packet_reply_open(gdbctx
);
905 packet_reply_add(gdbctx
, "W");
906 packet_reply_val(gdbctx
, gdbctx
->de
.u
.ExitProcess
.dwExitCode
, 4);
907 packet_reply_close(gdbctx
);
908 return packet_done
| packet_last_f
;
912 static enum packet_return
packet_last_signal(struct gdb_context
* gdbctx
)
914 assert(gdbctx
->in_packet_len
== 0);
915 return packet_reply_status(gdbctx
);
918 static enum packet_return
packet_continue(struct gdb_context
* gdbctx
)
922 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
923 FIXME("Continue at address %p not supported\n", addr
);
925 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, -1);
927 wait_for_debuggee(gdbctx
);
928 return packet_reply_status(gdbctx
);
931 static enum packet_return
packet_verbose_cont(struct gdb_context
* gdbctx
)
933 char *buf
= gdbctx
->in_packet
, *end
= gdbctx
->in_packet
+ gdbctx
->in_packet_len
;
935 if (gdbctx
->in_packet
[4] == '?')
937 packet_reply_open(gdbctx
);
938 packet_reply_add(gdbctx
, "vCont");
939 packet_reply_add(gdbctx
, ";c");
940 packet_reply_add(gdbctx
, ";C");
941 packet_reply_add(gdbctx
, ";s");
942 packet_reply_add(gdbctx
, ";S");
943 packet_reply_close(gdbctx
);
947 while (buf
< end
&& (buf
= memchr(buf
+ 1, ';', end
- buf
- 1)))
949 int tid
= -1, sig
= -1;
952 switch ((action
= buf
[1]))
962 if (sscanf(buf
, ";%*c%2x", &sig
) <= 0 ||
963 sig
!= signal_from_debug_event(&gdbctx
->de
))
971 if (buf
< end
&& *buf
== ':' && (n
= sscanf(buf
, ":%x", &tid
)) <= 0)
974 handle_step_or_continue(gdbctx
, tid
, action
== 's' || action
== 'S', sig
);
977 wait_for_debuggee(gdbctx
);
978 return packet_reply_status(gdbctx
);
981 static enum packet_return
packet_verbose(struct gdb_context
* gdbctx
)
983 if (gdbctx
->in_packet_len
>= 4 && !memcmp(gdbctx
->in_packet
, "Cont", 4))
985 return packet_verbose_cont(gdbctx
);
988 if (gdbctx
->in_packet_len
== 14 && !memcmp(gdbctx
->in_packet
, "MustReplyEmpty", 14))
989 return packet_reply(gdbctx
, "");
994 static enum packet_return
packet_continue_signal(struct gdb_context
* gdbctx
)
999 if ((n
= sscanf(gdbctx
->in_packet
, "%x;%p", &sig
, &addr
)) == 2)
1000 FIXME("Continue at address %p not supported\n", addr
);
1001 if (n
< 1) return packet_error
;
1003 if (sig
!= signal_from_debug_event(&gdbctx
->de
))
1005 ERR("Changing signals is not supported.\n");
1006 return packet_error
;
1009 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, sig
);
1011 wait_for_debuggee(gdbctx
);
1012 return packet_reply_status(gdbctx
);
1015 static enum packet_return
packet_delete_breakpoint(struct gdb_context
* gdbctx
)
1017 struct dbg_process
*process
= gdbctx
->process
;
1018 struct dbg_thread
*thread
;
1019 struct backend_cpu
*cpu
;
1020 struct gdb_xpoint
*x
;
1026 if (!process
) return packet_error
;
1027 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1029 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1030 return packet_error
;
1033 return packet_error
;
1035 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1037 if (!cpu
->get_context(thread
->handle
, &ctx
))
1039 if ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_exec
, addr
, size
)))
1040 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1041 if ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_read
, addr
, size
)))
1042 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1043 if ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_write
, addr
, size
)))
1044 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1045 cpu
->set_context(thread
->handle
, &ctx
);
1048 while ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_exec
, addr
, size
)))
1049 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1050 while ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_read
, addr
, size
)))
1051 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1052 while ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_write
, addr
, size
)))
1053 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1058 static enum packet_return
packet_insert_breakpoint(struct gdb_context
* gdbctx
)
1060 struct dbg_process
*process
= gdbctx
->process
;
1061 struct dbg_thread
*thread
;
1062 struct backend_cpu
*cpu
;
1068 if (!process
) return packet_error
;
1069 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1071 if (memchr(gdbctx
->in_packet
, ';', gdbctx
->in_packet_len
))
1073 FIXME("breakpoint commands not supported\n");
1074 return packet_error
;
1077 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1078 return packet_error
;
1081 return packet_error
;
1083 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1085 if (!cpu
->get_context(thread
->handle
, &ctx
))
1088 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_exec
, addr
, size
);
1089 if (type
== '2' || type
== '4')
1090 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_read
, addr
, size
);
1091 if (type
== '3' || type
== '4')
1092 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_write
, addr
, size
);
1093 cpu
->set_context(thread
->handle
, &ctx
);
1099 static enum packet_return
packet_detach(struct gdb_context
* gdbctx
)
1101 detach_debuggee(gdbctx
, FALSE
);
1102 return packet_ok
| packet_last_f
;
1105 static enum packet_return
packet_read_registers(struct gdb_context
* gdbctx
)
1107 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1108 struct backend_cpu
*backend
;
1112 if (!thread
) return packet_error
;
1113 if (!thread
->process
) return packet_error
;
1114 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1116 if (!backend
->get_context(thread
->handle
, &ctx
))
1117 return packet_error
;
1119 packet_reply_open(gdbctx
);
1120 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1121 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
1123 packet_reply_close(gdbctx
);
1127 static enum packet_return
packet_write_registers(struct gdb_context
* gdbctx
)
1129 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1130 struct backend_cpu
*backend
;
1135 if (!thread
) return packet_error
;
1136 if (!thread
->process
) return packet_error
;
1137 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1139 if (!backend
->get_context(thread
->handle
, &ctx
))
1140 return packet_error
;
1142 if (gdbctx
->in_packet_len
< backend
->gdb_num_regs
* 2)
1143 return packet_error
;
1145 ptr
= gdbctx
->in_packet
;
1146 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1147 cpu_register_hex_from(gdbctx
, &ctx
, i
, &ptr
);
1149 if (!backend
->set_context(thread
->handle
, &ctx
))
1151 ERR("Failed to set context for tid %04x, error %u\n", thread
->tid
, GetLastError());
1152 return packet_error
;
1158 static enum packet_return
packet_kill(struct gdb_context
* gdbctx
)
1160 detach_debuggee(gdbctx
, TRUE
);
1161 return packet_ok
| packet_last_f
;
1164 static enum packet_return
packet_thread(struct gdb_context
* gdbctx
)
1166 switch (gdbctx
->in_packet
[0])
1169 if (sscanf(gdbctx
->in_packet
, "c%x", &gdbctx
->exec_tid
) == 1)
1171 return packet_error
;
1173 if (sscanf(gdbctx
->in_packet
, "g%x", &gdbctx
->other_tid
) == 1)
1175 return packet_error
;
1177 FIXME("Unknown thread sub-command %c\n", gdbctx
->in_packet
[0]);
1178 return packet_error
;
1182 static enum packet_return
packet_read_memory(struct gdb_context
* gdbctx
)
1185 unsigned int len
, blk_len
, nread
;
1189 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2) return packet_error
;
1190 if (len
<= 0) return packet_error
;
1191 TRACE("Read %u bytes at %p\n", len
, addr
);
1192 for (nread
= 0; nread
< len
; nread
+= r
, addr
+= r
)
1194 blk_len
= min(sizeof(buffer
), len
- nread
);
1195 if (!gdbctx
->process
->process_io
->read(gdbctx
->process
->handle
, addr
,
1196 buffer
, blk_len
, &r
) || r
== 0)
1198 /* fail at first address, return error */
1199 if (nread
== 0) return packet_reply_error(gdbctx
, EFAULT
);
1200 /* something has already been read, return partial information */
1203 if (nread
== 0) packet_reply_open(gdbctx
);
1204 packet_reply_hex_to(gdbctx
, buffer
, r
);
1206 packet_reply_close(gdbctx
);
1210 static enum packet_return
packet_write_memory(struct gdb_context
* gdbctx
)
1213 unsigned int len
, blk_len
;
1218 ptr
= memchr(gdbctx
->in_packet
, ':', gdbctx
->in_packet_len
);
1221 ERR("Cannot find ':' in %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1222 return packet_error
;
1226 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2)
1228 ERR("Failed to parse %s\n", debugstr_a(gdbctx
->in_packet
));
1229 return packet_error
;
1231 if (ptr
- gdbctx
->in_packet
+ len
* 2 != gdbctx
->in_packet_len
)
1233 ERR("Length %u does not match packet length %u\n",
1234 (int)(ptr
- gdbctx
->in_packet
) + len
* 2, gdbctx
->in_packet_len
);
1235 return packet_error
;
1237 TRACE("Write %u bytes at %p\n", len
, addr
);
1240 blk_len
= min(sizeof(buffer
), len
);
1241 hex_from(buffer
, ptr
, blk_len
);
1242 if (!gdbctx
->process
->process_io
->write(gdbctx
->process
->handle
, addr
, buffer
, blk_len
, &w
) ||
1249 return packet_ok
; /* FIXME: error while writing ? */
1252 static enum packet_return
packet_read_register(struct gdb_context
* gdbctx
)
1254 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1255 struct backend_cpu
*backend
;
1259 if (!thread
) return packet_error
;
1260 if (!thread
->process
) return packet_error
;
1261 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1263 if (!backend
->get_context(thread
->handle
, &ctx
))
1264 return packet_error
;
1266 if (sscanf(gdbctx
->in_packet
, "%zx", ®
) != 1)
1267 return packet_error
;
1268 if (reg
>= backend
->gdb_num_regs
)
1270 WARN("Unhandled register %zu\n", reg
);
1271 return packet_error
;
1274 TRACE("%zu => %s\n", reg
, wine_dbgstr_longlong(cpu_register(gdbctx
, &ctx
, reg
)));
1276 packet_reply_open(gdbctx
);
1277 packet_reply_register_hex_to(gdbctx
, &ctx
, reg
);
1278 packet_reply_close(gdbctx
);
1282 static enum packet_return
packet_write_register(struct gdb_context
* gdbctx
)
1284 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1285 struct backend_cpu
*backend
;
1290 if (!thread
) return packet_error
;
1291 if (!thread
->process
) return packet_error
;
1292 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1294 if (!backend
->get_context(thread
->handle
, &ctx
))
1295 return packet_error
;
1297 if (!(ptr
= strchr(gdbctx
->in_packet
, '=')))
1298 return packet_error
;
1301 if (sscanf(gdbctx
->in_packet
, "%zx", ®
) != 1)
1302 return packet_error
;
1303 if (reg
>= backend
->gdb_num_regs
)
1305 /* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
1306 * it wouldn't matter too much, and it fakes our support for all regs
1308 WARN("Unhandled register %zu\n", reg
);
1312 TRACE("%zu <= %s\n", reg
, debugstr_an(ptr
, (int)(gdbctx
->in_packet_len
- (ptr
- gdbctx
->in_packet
))));
1314 cpu_register_hex_from(gdbctx
, &ctx
, reg
, (const char**)&ptr
);
1315 if (!backend
->set_context(thread
->handle
, &ctx
))
1317 ERR("Failed to set context for tid %04x, error %u\n", thread
->tid
, GetLastError());
1318 return packet_error
;
1324 static void packet_query_monitor_wnd_helper(struct gdb_context
* gdbctx
, HWND hWnd
, int indent
)
1332 if (!GetClassNameA(hWnd
, clsName
, sizeof(clsName
)))
1333 strcpy(clsName
, "-- Unknown --");
1334 if (!GetWindowTextA(hWnd
, wndName
, sizeof(wndName
)))
1335 strcpy(wndName
, "-- Empty --");
1337 packet_reply_open(gdbctx
);
1338 packet_reply_add(gdbctx
, "O");
1339 snprintf(buffer
, sizeof(buffer
),
1340 "%*s%04lx%*s%-17.17s %08x %0*lx %.14s\n",
1341 indent
, "", (ULONG_PTR
)hWnd
, 13 - indent
, "",
1342 clsName
, GetWindowLongW(hWnd
, GWL_STYLE
),
1343 ADDRWIDTH
, (ULONG_PTR
)GetWindowLongPtrW(hWnd
, GWLP_WNDPROC
),
1345 packet_reply_hex_to_str(gdbctx
, buffer
);
1346 packet_reply_close(gdbctx
);
1348 if ((child
= GetWindow(hWnd
, GW_CHILD
)) != 0)
1349 packet_query_monitor_wnd_helper(gdbctx
, child
, indent
+ 1);
1350 } while ((hWnd
= GetWindow(hWnd
, GW_HWNDNEXT
)) != 0);
1353 static void packet_query_monitor_wnd(struct gdb_context
* gdbctx
, int len
, const char* str
)
1357 /* we do the output in several 'O' packets, with the last one being just OK for
1358 * marking the end of the output */
1359 packet_reply_open(gdbctx
);
1360 packet_reply_add(gdbctx
, "O");
1361 snprintf(buffer
, sizeof(buffer
),
1362 "%-16.16s %-17.17s %-8.8s %s\n",
1363 "hwnd", "Class Name", " Style", " WndProc Text");
1364 packet_reply_hex_to_str(gdbctx
, buffer
);
1365 packet_reply_close(gdbctx
);
1367 /* FIXME: could also add a pmt to this command in str... */
1368 packet_query_monitor_wnd_helper(gdbctx
, GetDesktopWindow(), 0);
1369 packet_reply(gdbctx
, "OK");
1372 static void packet_query_monitor_process(struct gdb_context
* gdbctx
, int len
, const char* str
)
1374 HANDLE snap
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
1375 char buffer
[31+MAX_PATH
];
1377 PROCESSENTRY32 entry
;
1380 if (snap
== INVALID_HANDLE_VALUE
)
1383 entry
.dwSize
= sizeof(entry
);
1384 ok
= Process32First(snap
, &entry
);
1386 /* we do the output in several 'O' packets, with the last one being just OK for
1387 * marking the end of the output */
1389 packet_reply_open(gdbctx
);
1390 packet_reply_add(gdbctx
, "O");
1391 snprintf(buffer
, sizeof(buffer
),
1392 " %-8.8s %-8.8s %-8.8s %s\n",
1393 "pid", "threads", "parent", "executable");
1394 packet_reply_hex_to_str(gdbctx
, buffer
);
1395 packet_reply_close(gdbctx
);
1400 if (entry
.th32ProcessID
== gdbctx
->process
->pid
) deco
= '>';
1401 packet_reply_open(gdbctx
);
1402 packet_reply_add(gdbctx
, "O");
1403 snprintf(buffer
, sizeof(buffer
),
1404 "%c%08x %-8d %08x '%s'\n",
1405 deco
, entry
.th32ProcessID
, entry
.cntThreads
,
1406 entry
.th32ParentProcessID
, entry
.szExeFile
);
1407 packet_reply_hex_to_str(gdbctx
, buffer
);
1408 packet_reply_close(gdbctx
);
1409 ok
= Process32Next(snap
, &entry
);
1412 packet_reply(gdbctx
, "OK");
1415 static void packet_query_monitor_mem(struct gdb_context
* gdbctx
, int len
, const char* str
)
1417 MEMORY_BASIC_INFORMATION mbi
;
1424 /* we do the output in several 'O' packets, with the last one being just OK for
1425 * marking the end of the output */
1426 packet_reply_open(gdbctx
);
1427 packet_reply_add(gdbctx
, "O");
1428 packet_reply_hex_to_str(gdbctx
, "Address Size State Type RWX\n");
1429 packet_reply_close(gdbctx
);
1431 while (VirtualQueryEx(gdbctx
->process
->handle
, addr
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
))
1435 case MEM_COMMIT
: state
= "commit "; break;
1436 case MEM_FREE
: state
= "free "; break;
1437 case MEM_RESERVE
: state
= "reserve"; break;
1438 default: state
= "??? "; break;
1440 if (mbi
.State
!= MEM_FREE
)
1444 case MEM_IMAGE
: type
= "image "; break;
1445 case MEM_MAPPED
: type
= "mapped "; break;
1446 case MEM_PRIVATE
: type
= "private"; break;
1447 case 0: type
= " "; break;
1448 default: type
= "??? "; break;
1450 memset(prot
, ' ' , sizeof(prot
)-1);
1451 prot
[sizeof(prot
)-1] = '\0';
1452 if (mbi
.AllocationProtect
& (PAGE_READONLY
|PAGE_READWRITE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
))
1454 if (mbi
.AllocationProtect
& (PAGE_READWRITE
|PAGE_EXECUTE_READWRITE
))
1456 if (mbi
.AllocationProtect
& (PAGE_WRITECOPY
|PAGE_EXECUTE_WRITECOPY
))
1458 if (mbi
.AllocationProtect
& (PAGE_EXECUTE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
))
1466 packet_reply_open(gdbctx
);
1467 snprintf(buffer
, sizeof(buffer
), "%0*lx %0*lx %s %s %s\n",
1468 (unsigned)sizeof(void*), (DWORD_PTR
)addr
,
1469 (unsigned)sizeof(void*), mbi
.RegionSize
, state
, type
, prot
);
1470 packet_reply_add(gdbctx
, "O");
1471 packet_reply_hex_to_str(gdbctx
, buffer
);
1472 packet_reply_close(gdbctx
);
1474 if (addr
+ mbi
.RegionSize
< addr
) /* wrap around ? */
1476 addr
+= mbi
.RegionSize
;
1478 packet_reply(gdbctx
, "OK");
1486 void (*handler
)(struct gdb_context
*, int, const char*);
1489 {0, "wnd", 3, packet_query_monitor_wnd
},
1490 {0, "window", 6, packet_query_monitor_wnd
},
1491 {0, "proc", 4, packet_query_monitor_process
},
1492 {0, "process", 7, packet_query_monitor_process
},
1493 {0, "mem", 3, packet_query_monitor_mem
},
1497 static enum packet_return
packet_query_remote_command(struct gdb_context
* gdbctx
,
1498 const char* hxcmd
, size_t len
)
1501 struct query_detail
* qd
;
1503 assert((len
& 1) == 0 && len
< 2 * sizeof(buffer
));
1505 hex_from(buffer
, hxcmd
, len
);
1507 for (qd
= query_details
; qd
->name
!= NULL
; qd
++)
1509 if (len
< qd
->len
|| strncmp(buffer
, qd
->name
, qd
->len
) != 0) continue;
1510 if (!qd
->with_arg
&& len
!= qd
->len
) continue;
1512 (qd
->handler
)(gdbctx
, len
- qd
->len
, buffer
+ qd
->len
);
1515 return packet_reply_error(gdbctx
, EINVAL
);
1518 static BOOL CALLBACK
packet_query_libraries_cb(PCSTR mod_name
, DWORD64 base
, PVOID ctx
)
1520 struct gdb_context
* gdbctx
= ctx
;
1521 MEMORY_BASIC_INFORMATION mbi
;
1522 IMAGE_SECTION_HEADER
*sec
;
1523 IMAGE_DOS_HEADER
*dos
= NULL
;
1524 IMAGE_NT_HEADERS
*nth
= NULL
;
1525 IMAGEHLP_MODULE64 mod
;
1530 mod
.SizeOfStruct
= sizeof(mod
);
1531 SymGetModuleInfo64(gdbctx
->process
->handle
, base
, &mod
);
1533 packet_reply_add(gdbctx
, "<library name=\"");
1534 if (strcmp(mod
.LoadedImageName
, "[vdso].so") == 0)
1535 packet_reply_add(gdbctx
, "linux-vdso.so.1");
1536 else if (mod
.LoadedImageName
[0] == '/')
1537 packet_reply_add(gdbctx
, mod
.LoadedImageName
);
1540 UNICODE_STRING nt_name
;
1541 ANSI_STRING ansi_name
;
1542 char *unix_path
, *tmp
;
1544 RtlInitAnsiString(&ansi_name
, mod
.LoadedImageName
);
1545 RtlAnsiStringToUnicodeString(&nt_name
, &ansi_name
, TRUE
);
1547 if ((unix_path
= wine_get_unix_file_name(nt_name
.Buffer
)))
1549 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) &&
1550 is_wow64
&& (tmp
= strstr(unix_path
, "system32")))
1551 memcpy(tmp
, "syswow64", 8);
1552 packet_reply_add(gdbctx
, unix_path
);
1555 packet_reply_add(gdbctx
, mod
.LoadedImageName
);
1557 HeapFree(GetProcessHeap(), 0, unix_path
);
1558 RtlFreeUnicodeString(&nt_name
);
1560 packet_reply_add(gdbctx
, "\">");
1562 size
= sizeof(buffer
);
1563 if (VirtualQueryEx(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
) &&
1564 mbi
.Type
== MEM_IMAGE
&& mbi
.State
!= MEM_FREE
)
1566 if (ReadProcessMemory(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, buffer
, size
, &size
) &&
1567 size
>= sizeof(IMAGE_DOS_HEADER
))
1568 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1570 if (dos
&& dos
->e_magic
== IMAGE_DOS_SIGNATURE
&& dos
->e_lfanew
< size
)
1571 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1573 if (nth
&& memcmp(&nth
->Signature
, "PE\0\0", 4))
1577 if (!nth
) memset(buffer
, 0, sizeof(buffer
));
1579 /* if the module is not PE we have cleared buffer with 0, this makes
1580 * the following computation valid in all cases. */
1581 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1582 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1583 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) && is_wow64
)
1584 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS32
*)nth
);
1586 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS64
*)nth
);
1588 for (i
= 0; i
< max(nth
->FileHeader
.NumberOfSections
, 1); ++i
)
1590 if ((char *)(sec
+ i
) >= buffer
+ size
) break;
1591 packet_reply_add(gdbctx
, "<segment address=\"0x");
1592 packet_reply_val(gdbctx
, mod
.BaseOfImage
+ sec
[i
].VirtualAddress
, sizeof(unsigned long));
1593 packet_reply_add(gdbctx
, "\"/>");
1596 packet_reply_add(gdbctx
, "</library>");
1601 static void packet_query_libraries(struct gdb_context
* gdbctx
)
1605 /* this will resynchronize builtin dbghelp's internal ELF module list */
1606 SymLoadModule(gdbctx
->process
->handle
, 0, 0, 0, 0, 0);
1608 packet_reply_add(gdbctx
, "<library-list>");
1609 opt
= SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, TRUE
);
1610 SymEnumerateModules64(gdbctx
->process
->handle
, packet_query_libraries_cb
, gdbctx
);
1611 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, opt
);
1612 packet_reply_add(gdbctx
, "</library-list>");
1615 static void packet_query_threads(struct gdb_context
* gdbctx
)
1617 struct dbg_process
* process
= gdbctx
->process
;
1618 struct dbg_thread
* thread
;
1620 packet_reply_add(gdbctx
, "<threads>");
1621 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1623 packet_reply_add(gdbctx
, "<thread ");
1624 packet_reply_add(gdbctx
, "id=\"");
1625 packet_reply_val(gdbctx
, thread
->tid
, 4);
1626 packet_reply_add(gdbctx
, "\" name=\"");
1627 packet_reply_add(gdbctx
, thread
->name
);
1628 packet_reply_add(gdbctx
, "\"/>");
1630 packet_reply_add(gdbctx
, "</threads>");
1633 static void packet_query_target_xml(struct gdb_context
* gdbctx
, struct backend_cpu
* cpu
)
1635 const char* feature_prefix
= NULL
;
1636 const char* feature
= NULL
;
1640 packet_reply_add(gdbctx
, "<target>");
1641 switch (cpu
->machine
)
1643 case IMAGE_FILE_MACHINE_AMD64
:
1644 packet_reply_add(gdbctx
, "<architecture>i386:x86-64</architecture>");
1645 feature_prefix
= "org.gnu.gdb.i386.";
1647 case IMAGE_FILE_MACHINE_I386
:
1648 packet_reply_add(gdbctx
, "<architecture>i386</architecture>");
1649 feature_prefix
= "org.gnu.gdb.i386.";
1651 case IMAGE_FILE_MACHINE_ARMNT
:
1652 packet_reply_add(gdbctx
, "<architecture>arm</architecture>");
1653 feature_prefix
= "org.gnu.gdb.arm.";
1655 case IMAGE_FILE_MACHINE_ARM64
:
1656 packet_reply_add(gdbctx
, "<architecture>aarch64</architecture>");
1657 feature_prefix
= "org.gnu.gdb.aarch64.";
1661 for (i
= 0; i
< cpu
->gdb_num_regs
; ++i
)
1663 if (cpu
->gdb_register_map
[i
].feature
)
1665 if (feature
) packet_reply_add(gdbctx
, "</feature>");
1666 feature
= cpu
->gdb_register_map
[i
].feature
;
1668 packet_reply_add(gdbctx
, "<feature name=\"");
1669 if (feature_prefix
) packet_reply_add(gdbctx
, feature_prefix
);
1670 packet_reply_add(gdbctx
, feature
);
1671 packet_reply_add(gdbctx
, "\">");
1673 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1674 strcmp(feature
, "core") == 0)
1675 packet_reply_add(gdbctx
, "<flags id=\"i386_eflags\" size=\"4\">"
1676 "<field name=\"CF\" start=\"0\" end=\"0\"/>"
1677 "<field name=\"\" start=\"1\" end=\"1\"/>"
1678 "<field name=\"PF\" start=\"2\" end=\"2\"/>"
1679 "<field name=\"AF\" start=\"4\" end=\"4\"/>"
1680 "<field name=\"ZF\" start=\"6\" end=\"6\"/>"
1681 "<field name=\"SF\" start=\"7\" end=\"7\"/>"
1682 "<field name=\"TF\" start=\"8\" end=\"8\"/>"
1683 "<field name=\"IF\" start=\"9\" end=\"9\"/>"
1684 "<field name=\"DF\" start=\"10\" end=\"10\"/>"
1685 "<field name=\"OF\" start=\"11\" end=\"11\"/>"
1686 "<field name=\"NT\" start=\"14\" end=\"14\"/>"
1687 "<field name=\"RF\" start=\"16\" end=\"16\"/>"
1688 "<field name=\"VM\" start=\"17\" end=\"17\"/>"
1689 "<field name=\"AC\" start=\"18\" end=\"18\"/>"
1690 "<field name=\"VIF\" start=\"19\" end=\"19\"/>"
1691 "<field name=\"VIP\" start=\"20\" end=\"20\"/>"
1692 "<field name=\"ID\" start=\"21\" end=\"21\"/>"
1695 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1696 strcmp(feature
, "sse") == 0)
1697 packet_reply_add(gdbctx
, "<vector id=\"v4f\" type=\"ieee_single\" count=\"4\"/>"
1698 "<vector id=\"v2d\" type=\"ieee_double\" count=\"2\"/>"
1699 "<vector id=\"v16i8\" type=\"int8\" count=\"16\"/>"
1700 "<vector id=\"v8i16\" type=\"int16\" count=\"8\"/>"
1701 "<vector id=\"v4i32\" type=\"int32\" count=\"4\"/>"
1702 "<vector id=\"v2i64\" type=\"int64\" count=\"2\"/>"
1703 "<union id=\"vec128\">"
1704 "<field name=\"v4_float\" type=\"v4f\"/>"
1705 "<field name=\"v2_double\" type=\"v2d\"/>"
1706 "<field name=\"v16_int8\" type=\"v16i8\"/>"
1707 "<field name=\"v8_int16\" type=\"v8i16\"/>"
1708 "<field name=\"v4_int32\" type=\"v4i32\"/>"
1709 "<field name=\"v2_int64\" type=\"v2i64\"/>"
1710 "<field name=\"uint128\" type=\"uint128\"/>"
1712 "<flags id=\"i386_mxcsr\" size=\"4\">"
1713 "<field name=\"IE\" start=\"0\" end=\"0\"/>"
1714 "<field name=\"DE\" start=\"1\" end=\"1\"/>"
1715 "<field name=\"ZE\" start=\"2\" end=\"2\"/>"
1716 "<field name=\"OE\" start=\"3\" end=\"3\"/>"
1717 "<field name=\"UE\" start=\"4\" end=\"4\"/>"
1718 "<field name=\"PE\" start=\"5\" end=\"5\"/>"
1719 "<field name=\"DAZ\" start=\"6\" end=\"6\"/>"
1720 "<field name=\"IM\" start=\"7\" end=\"7\"/>"
1721 "<field name=\"DM\" start=\"8\" end=\"8\"/>"
1722 "<field name=\"ZM\" start=\"9\" end=\"9\"/>"
1723 "<field name=\"OM\" start=\"10\" end=\"10\"/>"
1724 "<field name=\"UM\" start=\"11\" end=\"11\"/>"
1725 "<field name=\"PM\" start=\"12\" end=\"12\"/>"
1726 "<field name=\"FZ\" start=\"15\" end=\"15\"/>"
1730 snprintf(buffer
, ARRAY_SIZE(buffer
), "<reg name=\"%s\" bitsize=\"%zu\"",
1731 cpu
->gdb_register_map
[i
].name
, 8 * cpu
->gdb_register_map
[i
].length
);
1732 packet_reply_add(gdbctx
, buffer
);
1734 if (cpu
->gdb_register_map
[i
].type
)
1736 packet_reply_add(gdbctx
, " type=\"");
1737 packet_reply_add(gdbctx
, cpu
->gdb_register_map
[i
].type
);
1738 packet_reply_add(gdbctx
, "\"");
1741 packet_reply_add(gdbctx
, "/>");
1744 if (feature
) packet_reply_add(gdbctx
, "</feature>");
1745 packet_reply_add(gdbctx
, "</target>");
1748 static enum packet_return
packet_query(struct gdb_context
* gdbctx
)
1751 struct backend_cpu
*cpu
;
1753 switch (gdbctx
->in_packet
[0])
1756 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
1758 struct dbg_thread
* thd
;
1760 packet_reply_open(gdbctx
);
1761 packet_reply_add(gdbctx
, "m");
1762 LIST_FOR_EACH_ENTRY(thd
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
1764 packet_reply_val(gdbctx
, thd
->tid
, 4);
1765 if (list_next(&gdbctx
->process
->threads
, &thd
->entry
) != NULL
)
1766 packet_reply_add(gdbctx
, ",");
1768 packet_reply_close(gdbctx
);
1771 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
1775 packet_reply_open(gdbctx
);
1776 packet_reply_add(gdbctx
, "O");
1777 get_process_info(gdbctx
, result
, sizeof(result
));
1778 packet_reply_hex_to_str(gdbctx
, result
);
1779 packet_reply_close(gdbctx
);
1784 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
1786 packet_reply(gdbctx
, "l");
1789 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
1791 packet_reply(gdbctx
, "l");
1796 if (strncmp(gdbctx
->in_packet
, "Attached", gdbctx
->in_packet_len
) == 0)
1797 return packet_reply(gdbctx
, "1");
1800 if (gdbctx
->in_packet_len
== 1)
1802 struct dbg_thread
* thd
;
1803 /* FIXME: doc says 16 bit val ??? */
1804 /* grab first created thread, aka last in list */
1805 assert(gdbctx
->process
&& !list_empty(&gdbctx
->process
->threads
));
1806 thd
= LIST_ENTRY(list_tail(&gdbctx
->process
->threads
), struct dbg_thread
, entry
);
1807 packet_reply_open(gdbctx
);
1808 packet_reply_add(gdbctx
, "QC");
1809 packet_reply_val(gdbctx
, thd
->tid
, 4);
1810 packet_reply_close(gdbctx
);
1815 if (strncmp(gdbctx
->in_packet
, "Offsets", gdbctx
->in_packet_len
) == 0)
1819 snprintf(buf
, sizeof(buf
),
1820 "Text=%08lx;Data=%08lx;Bss=%08lx",
1821 gdbctx
->wine_segs
[0], gdbctx
->wine_segs
[1],
1822 gdbctx
->wine_segs
[2]);
1823 return packet_reply(gdbctx
, buf
);
1827 if (gdbctx
->in_packet_len
> 5 && strncmp(gdbctx
->in_packet
, "Rcmd,", 5) == 0)
1829 return packet_query_remote_command(gdbctx
, gdbctx
->in_packet
+ 5,
1830 gdbctx
->in_packet_len
- 5);
1834 if (strncmp(gdbctx
->in_packet
, "Symbol::", gdbctx
->in_packet_len
) == 0)
1836 if (strncmp(gdbctx
->in_packet
, "Supported", 9) == 0)
1838 packet_reply_open(gdbctx
);
1839 packet_reply_add(gdbctx
, "QStartNoAckMode+;");
1840 packet_reply_add(gdbctx
, "qXfer:libraries:read+;");
1841 packet_reply_add(gdbctx
, "qXfer:threads:read+;");
1842 packet_reply_add(gdbctx
, "qXfer:features:read+;");
1843 packet_reply_close(gdbctx
);
1848 if (gdbctx
->in_packet_len
> 15 &&
1849 strncmp(gdbctx
->in_packet
, "ThreadExtraInfo", 15) == 0 &&
1850 gdbctx
->in_packet
[15] == ',')
1856 tid
= strtol(gdbctx
->in_packet
+ 16, &end
, 16);
1857 if (end
== NULL
) break;
1858 get_thread_info(gdbctx
, tid
, result
, sizeof(result
));
1859 packet_reply_open(gdbctx
);
1860 packet_reply_hex_to_str(gdbctx
, result
);
1861 packet_reply_close(gdbctx
);
1864 if (strncmp(gdbctx
->in_packet
, "TStatus", 7) == 0)
1866 /* Tracepoints not supported */
1867 packet_reply_open(gdbctx
);
1868 packet_reply_close(gdbctx
);
1873 if (sscanf(gdbctx
->in_packet
, "Xfer:libraries:read::%x,%x", &off
, &len
) == 2)
1875 if (!gdbctx
->process
) return packet_error
;
1877 packet_reply_open_xfer(gdbctx
);
1878 packet_query_libraries(gdbctx
);
1879 packet_reply_close_xfer(gdbctx
, off
, len
);
1883 if (sscanf(gdbctx
->in_packet
, "Xfer:threads:read::%x,%x", &off
, &len
) == 2)
1885 if (!gdbctx
->process
) return packet_error
;
1887 packet_reply_open_xfer(gdbctx
);
1888 packet_query_threads(gdbctx
);
1889 packet_reply_close_xfer(gdbctx
, off
, len
);
1893 if (sscanf(gdbctx
->in_packet
, "Xfer:features:read:target.xml:%x,%x", &off
, &len
) == 2)
1895 if (!gdbctx
->process
) return packet_error
;
1896 if (!(cpu
= gdbctx
->process
->be_cpu
)) return packet_error
;
1898 packet_reply_open_xfer(gdbctx
);
1899 packet_query_target_xml(gdbctx
, cpu
);
1900 packet_reply_close_xfer(gdbctx
, off
, len
);
1905 ERR("Unhandled query %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1906 return packet_error
;
1909 static enum packet_return
packet_set(struct gdb_context
* gdbctx
)
1911 if (strncmp(gdbctx
->in_packet
, "StartNoAckMode", 14) == 0)
1913 gdbctx
->no_ack_mode
= TRUE
;
1917 return packet_error
;
1920 static enum packet_return
packet_step(struct gdb_context
* gdbctx
)
1924 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
1925 FIXME("Continue at address %p not supported\n", addr
);
1927 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, TRUE
, -1);
1929 wait_for_debuggee(gdbctx
);
1930 return packet_reply_status(gdbctx
);
1933 static enum packet_return
packet_thread_alive(struct gdb_context
* gdbctx
)
1938 tid
= strtol(gdbctx
->in_packet
, &end
, 16);
1939 if (tid
== -1 || tid
== 0)
1940 return packet_reply_error(gdbctx
, EINVAL
);
1941 if (dbg_get_thread(gdbctx
->process
, tid
) != NULL
)
1943 return packet_reply_error(gdbctx
, ESRCH
);
1946 /* =============================================== *
1947 * P A C K E T I N F R A S T R U C T U R E *
1948 * =============================================== *
1954 enum packet_return (*handler
)(struct gdb_context
* gdbctx
);
1957 static struct packet_entry packet_entries
[] =
1959 {'?', packet_last_signal
},
1960 {'c', packet_continue
},
1961 {'C', packet_continue_signal
},
1962 {'D', packet_detach
},
1963 {'g', packet_read_registers
},
1964 {'G', packet_write_registers
},
1966 {'H', packet_thread
},
1967 {'m', packet_read_memory
},
1968 {'M', packet_write_memory
},
1969 {'p', packet_read_register
},
1970 {'P', packet_write_register
},
1971 {'q', packet_query
},
1974 {'T', packet_thread_alive
},
1975 {'v', packet_verbose
},
1976 {'z', packet_delete_breakpoint
},
1977 {'Z', packet_insert_breakpoint
},
1980 static BOOL
extract_packets(struct gdb_context
* gdbctx
)
1982 char *ptr
, *sum
= gdbctx
->in_buf
, *end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
1983 enum packet_return ret
= packet_error
;
1987 /* ptr points to the beginning ('$') of the current packet
1988 * sum points to the beginning ('#') of the current packet checksum ("#xx")
1989 * len is the length of the current packet data (sum - ptr - 1)
1990 * end points to the end of the received data buffer
1993 while (!gdbctx
->no_ack_mode
&&
1994 (ptr
= memchr(sum
, '$', end
- sum
)) &&
1995 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
1996 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
1998 len
= sum
- ptr
- 1;
2001 if (cksum
== checksum(ptr
+ 1, len
))
2003 TRACE("Acking: %s\n", debugstr_an(ptr
, sum
- ptr
));
2004 write(gdbctx
->sock
, "+", 1);
2008 ERR("Nacking: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2009 cksum
, checksum(ptr
+ 1, len
));
2010 write(gdbctx
->sock
, "-", 1);
2014 while ((ret
& packet_last_f
) == 0 &&
2015 (ptr
= memchr(gdbctx
->in_buf
, '$', gdbctx
->in_len
)) &&
2016 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
2017 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2019 if (ptr
!= gdbctx
->in_buf
)
2020 WARN("Ignoring: %s\n", debugstr_an(gdbctx
->in_buf
, ptr
- gdbctx
->in_buf
));
2022 len
= sum
- ptr
- 1;
2025 if (cksum
== checksum(ptr
+ 1, len
))
2027 TRACE("Handling: %s\n", debugstr_an(ptr
, sum
- ptr
));
2030 gdbctx
->in_packet
= ptr
+ 2;
2031 gdbctx
->in_packet_len
= len
- 1;
2032 gdbctx
->in_packet
[gdbctx
->in_packet_len
] = '\0';
2034 for (i
= 0; i
< ARRAY_SIZE(packet_entries
); i
++)
2035 if (packet_entries
[i
].key
== ptr
[1])
2038 if (i
== ARRAY_SIZE(packet_entries
))
2039 WARN("Unhandled: %s\n", debugstr_an(ptr
+ 1, len
));
2040 else if (((ret
= (packet_entries
[i
].handler
)(gdbctx
)) & ~packet_last_f
) == packet_error
)
2041 WARN("Failed: %s\n", debugstr_an(ptr
+ 1, len
));
2043 switch (ret
& ~packet_last_f
)
2045 case packet_error
: packet_reply(gdbctx
, ""); break;
2046 case packet_ok
: packet_reply(gdbctx
, "OK"); break;
2047 case packet_done
: break;
2050 TRACE("Reply: %s\n", debugstr_an(gdbctx
->out_buf
, gdbctx
->out_len
));
2051 i
= write(gdbctx
->sock
, gdbctx
->out_buf
, gdbctx
->out_len
);
2052 assert(i
== gdbctx
->out_len
);
2053 gdbctx
->out_len
= 0;
2056 WARN("Ignoring: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2057 cksum
, checksum(ptr
+ 1, len
));
2059 gdbctx
->in_len
= end
- sum
;
2060 memmove(gdbctx
->in_buf
, sum
, end
- sum
);
2061 end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
2064 return (ret
& packet_last_f
);
2067 static int fetch_data(struct gdb_context
* gdbctx
)
2069 int len
, in_len
= gdbctx
->in_len
;
2071 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2075 if (gdbctx
->in_len
+ STEP
> gdbctx
->in_buf_alloc
)
2076 gdbctx
->in_buf
= packet_realloc(gdbctx
->in_buf
, gdbctx
->in_buf_alloc
+= STEP
);
2078 len
= read(gdbctx
->sock
, gdbctx
->in_buf
+ gdbctx
->in_len
, gdbctx
->in_buf_alloc
- gdbctx
->in_len
- 1);
2079 if (len
<= 0) break;
2080 gdbctx
->in_len
+= len
;
2081 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2082 if (len
< gdbctx
->in_buf_alloc
- gdbctx
->in_len
) break;
2085 gdbctx
->in_buf
[gdbctx
->in_len
] = '\0';
2086 return gdbctx
->in_len
- in_len
;
2089 #define FLAG_NO_START 1
2090 #define FLAG_WITH_XTERM 2
2092 static BOOL
gdb_exec(unsigned port
, unsigned flags
)
2096 const char *gdb_path
, *tmp_path
;
2099 if (!(gdb_path
= getenv("WINE_GDB"))) gdb_path
= "gdb";
2100 if (!(tmp_path
= getenv("TMPDIR"))) tmp_path
= "/tmp";
2101 strcpy(buf
, tmp_path
);
2102 strcat(buf
, "/winegdb.XXXXXX");
2103 fd
= mkstemps(buf
, 0);
2104 if (fd
== -1) return FALSE
;
2105 if ((f
= fdopen(fd
, "w+")) == NULL
) return FALSE
;
2106 fprintf(f
, "target remote localhost:%d\n", ntohs(port
));
2107 fprintf(f
, "set prompt Wine-gdb>\\ \n");
2108 /* gdb 5.1 seems to require it, won't hurt anyway */
2109 fprintf(f
, "sharedlibrary\n");
2110 /* This is needed (but not a decent & final fix)
2111 * Without this, gdb would skip our inter-DLL relay code (because
2112 * we don't have any line number information for the relay code)
2113 * With this, we will stop on first instruction of the stub, and
2114 * reusing step, will get us through the relay stub at the actual
2115 * function we're looking at.
2117 fprintf(f
, "set step-mode on\n");
2118 /* tell gdb to delete this file when done handling it... */
2119 fprintf(f
, "shell rm -f \"%s\"\n", buf
);
2121 if (flags
& FLAG_WITH_XTERM
)
2122 execlp("xterm", "xterm", "-e", gdb_path
, "-x", buf
, NULL
);
2124 execlp(gdb_path
, gdb_path
, "-x", buf
, NULL
);
2125 assert(0); /* never reached */
2129 static BOOL
gdb_startup(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2132 struct sockaddr_in s_addrs
= {0};
2133 socklen_t s_len
= sizeof(s_addrs
);
2134 struct pollfd pollfd
;
2137 /* step 1: create socket for gdb connection request */
2138 if ((sock
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
2140 ERR("Failed to create socket: %s\n", strerror(errno
));
2144 s_addrs
.sin_family
= AF_INET
;
2145 s_addrs
.sin_addr
.s_addr
= INADDR_ANY
;
2146 s_addrs
.sin_port
= htons(port
);
2147 if (bind(sock
, (struct sockaddr
*)&s_addrs
, sizeof(s_addrs
)) == -1)
2150 if (listen(sock
, 1) == -1 || getsockname(sock
, (struct sockaddr
*)&s_addrs
, &s_len
) == -1)
2153 /* step 2: do the process internal creation */
2154 handle_debug_event(gdbctx
);
2156 /* step 3: fire up gdb (if requested) */
2157 if (flags
& FLAG_NO_START
)
2158 fprintf(stderr
, "target remote localhost:%d\n", ntohs(s_addrs
.sin_port
));
2162 case -1: /* error in parent... */
2163 ERR("Failed to start gdb: fork: %s\n", strerror(errno
));
2165 default: /* in parent... success */
2166 signal(SIGINT
, SIG_IGN
);
2168 case 0: /* in child... and alive */
2169 gdb_exec(s_addrs
.sin_port
, flags
);
2170 /* if we're here, exec failed, so report failure */
2174 /* step 4: wait for gdb to connect actually */
2176 pollfd
.events
= POLLIN
;
2179 switch (poll(&pollfd
, 1, -1))
2182 if (pollfd
.revents
& POLLIN
)
2185 gdbctx
->sock
= accept(sock
, (struct sockaddr
*)&s_addrs
, &s_len
);
2186 if (gdbctx
->sock
== -1)
2189 TRACE("connected on %d\n", gdbctx
->sock
);
2190 /* don't keep our small packets too long: send them ASAP back to GDB
2191 * without this, GDB really crawls
2193 setsockopt(gdbctx
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (char*)&dummy
, sizeof(dummy
));
2197 ERR("Timed out connecting to gdb\n");
2200 ERR("Failed to connect to gdb: poll: %s\n", strerror(errno
));
2211 static BOOL
gdb_init_context(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2216 gdbctx
->in_buf
= NULL
;
2217 gdbctx
->in_buf_alloc
= 0;
2219 gdbctx
->out_buf
= NULL
;
2220 gdbctx
->out_buf_alloc
= 0;
2221 gdbctx
->out_len
= 0;
2222 gdbctx
->out_curr_packet
= -1;
2224 gdbctx
->exec_tid
= -1;
2225 gdbctx
->other_tid
= -1;
2226 list_init(&gdbctx
->xpoint_list
);
2227 gdbctx
->process
= NULL
;
2228 gdbctx
->no_ack_mode
= FALSE
;
2229 for (i
= 0; i
< ARRAY_SIZE(gdbctx
->wine_segs
); i
++)
2230 gdbctx
->wine_segs
[i
] = 0;
2232 /* wait for first trap */
2233 while (WaitForDebugEvent(&gdbctx
->de
, INFINITE
))
2235 if (gdbctx
->de
.dwDebugEventCode
== CREATE_PROCESS_DEBUG_EVENT
)
2237 /* this should be the first event we get,
2238 * and the only one of this type */
2239 assert(gdbctx
->process
== NULL
&& gdbctx
->de
.dwProcessId
== dbg_curr_pid
);
2240 /* gdbctx->dwProcessId = pid; */
2241 if (!gdb_startup(gdbctx
, flags
, port
)) return FALSE
;
2243 else if (!handle_debug_event(gdbctx
))
2245 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
2250 static int gdb_remote(unsigned flags
, unsigned port
)
2252 struct pollfd pollfd
;
2253 struct gdb_context gdbctx
;
2256 for (doLoop
= gdb_init_context(&gdbctx
, flags
, port
); doLoop
;)
2258 pollfd
.fd
= gdbctx
.sock
;
2259 pollfd
.events
= POLLIN
;
2262 switch (poll(&pollfd
, 1, -1))
2266 if (pollfd
.revents
& (POLLHUP
| POLLERR
))
2268 ERR("gdb hung up\n");
2269 /* kill also debuggee process - questionnable - */
2270 detach_debuggee(&gdbctx
, TRUE
);
2274 if ((pollfd
.revents
& POLLIN
) && fetch_data(&gdbctx
) > 0)
2276 if (extract_packets(&gdbctx
)) doLoop
= FALSE
;
2280 /* timeout, should never happen (infinite timeout) */
2283 ERR("poll failed: %s\n", strerror(errno
));
2293 int gdb_main(int argc
, char* argv
[])
2296 unsigned gdb_flags
= 0, port
= 0;
2300 while (argc
> 0 && argv
[0][0] == '-')
2302 if (strcmp(argv
[0], "--no-start") == 0)
2304 gdb_flags
|= FLAG_NO_START
;
2308 if (strcmp(argv
[0], "--with-xterm") == 0)
2310 gdb_flags
|= FLAG_WITH_XTERM
;
2314 if (strcmp(argv
[0], "--port") == 0 && argc
> 1)
2316 port
= strtoul(argv
[1], &port_end
, 10);
2319 fprintf(stderr
, "Invalid port: %s\n", argv
[1]);
2322 argc
-= 2; argv
+= 2;
2327 if (dbg_active_attach(argc
, argv
) == start_ok
||
2328 dbg_active_launch(argc
, argv
) == start_ok
)
2329 return gdb_remote(gdb_flags
, port
);
2331 fprintf(stderr
, "GdbProxy mode not supported on this platform\n");