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/debug.h"
68 WINE_DEFAULT_DEBUG_CHANNEL(winedbg
);
75 enum be_xpoint_type type
;
89 /* split into individual packet */
97 /* generic GDB thread information */
98 int exec_tid
; /* tid used in step & continue */
99 int other_tid
; /* tid to be used in any other operation */
100 struct list xpoint_list
;
101 /* current Win32 trap env */
104 /* Win32 information */
105 struct dbg_process
* process
;
106 /* Unix environment */
107 unsigned long wine_segs
[3]; /* load addresses of the ELF wine exec segments (text, bss and data) */
111 static void gdbctx_delete_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
112 dbg_ctx_t
*ctx
, struct gdb_xpoint
*x
)
114 struct dbg_process
*process
= thread
->process
;
115 struct backend_cpu
*cpu
= process
->be_cpu
;
117 if (!cpu
->remove_Xpoint(process
->handle
, process
->process_io
, ctx
, x
->type
, x
->addr
, x
->value
, x
->size
))
118 ERR("%04x:%04x: Couldn't remove breakpoint at:%p/%x type:%d\n", process
->pid
, thread
->tid
, x
->addr
, x
->size
, x
->type
);
120 list_remove(&x
->entry
);
121 HeapFree(GetProcessHeap(), 0, x
);
124 static void gdbctx_insert_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
125 dbg_ctx_t
*ctx
, enum be_xpoint_type type
, void *addr
, int size
)
127 struct dbg_process
*process
= thread
->process
;
128 struct backend_cpu
*cpu
= process
->be_cpu
;
129 struct gdb_xpoint
*x
;
132 if (!cpu
->insert_Xpoint(process
->handle
, process
->process_io
, ctx
, type
, addr
, &value
, size
))
134 ERR("%04x:%04x: Couldn't insert breakpoint at:%p/%x type:%d\n", process
->pid
, thread
->tid
, addr
, size
, type
);
138 if (!(x
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct gdb_xpoint
))))
140 ERR("%04x:%04x: Couldn't allocate memory for breakpoint at:%p/%x type:%d\n", process
->pid
, thread
->tid
, addr
, size
, type
);
144 x
->pid
= process
->pid
;
145 x
->tid
= thread
->tid
;
150 list_add_head(&gdbctx
->xpoint_list
, &x
->entry
);
153 static struct gdb_xpoint
*gdb_find_xpoint(struct gdb_context
*gdbctx
, struct dbg_thread
*thread
,
154 enum be_xpoint_type type
, void *addr
, int size
)
156 struct gdb_xpoint
*x
;
158 LIST_FOR_EACH_ENTRY(x
, &gdbctx
->xpoint_list
, struct gdb_xpoint
, entry
)
160 if (thread
&& (x
->pid
!= thread
->process
->pid
|| x
->tid
!= thread
->tid
))
162 if (x
->type
== type
&& x
->addr
== addr
&& x
->size
== size
)
169 static BOOL
tgt_process_gdbproxy_read(HANDLE hProcess
, const void* addr
,
170 void* buffer
, SIZE_T len
, SIZE_T
* rlen
)
172 return ReadProcessMemory( hProcess
, addr
, buffer
, len
, rlen
);
175 static BOOL
tgt_process_gdbproxy_write(HANDLE hProcess
, void* addr
,
176 const void* buffer
, SIZE_T len
, SIZE_T
* wlen
)
178 return WriteProcessMemory( hProcess
, addr
, buffer
, len
, wlen
);
181 static struct be_process_io be_process_gdbproxy_io
=
183 NULL
, /* we shouldn't use close_process() in gdbproxy */
184 tgt_process_gdbproxy_read
,
185 tgt_process_gdbproxy_write
188 /* =============================================== *
189 * B A S I C M A N I P U L A T I O N S *
190 * =============================================== *
193 static inline int hex_from0(char ch
)
195 if (ch
>= '0' && ch
<= '9') return ch
- '0';
196 if (ch
>= 'A' && ch
<= 'F') return ch
- 'A' + 10;
197 if (ch
>= 'a' && ch
<= 'f') return ch
- 'a' + 10;
203 static inline unsigned char hex_to0(int x
)
205 assert(x
>= 0 && x
< 16);
206 return "0123456789abcdef"[x
];
209 static void hex_from(void* dst
, const char* src
, size_t len
)
211 unsigned char *p
= dst
;
214 *p
++ = (hex_from0(src
[0]) << 4) | hex_from0(src
[1]);
219 static void hex_to(char* dst
, const void* src
, size_t len
)
221 const unsigned char *p
= src
;
224 *dst
++ = hex_to0(*p
>> 4);
225 *dst
++ = hex_to0(*p
& 0x0F);
230 static unsigned char checksum(const char* ptr
, int len
)
235 cksum
+= (unsigned char)*ptr
++;
239 static inline void* cpu_register_ptr(struct gdb_context
*gdbctx
,
240 dbg_ctx_t
*ctx
, unsigned idx
)
242 assert(idx
< gdbctx
->process
->be_cpu
->gdb_num_regs
);
243 return (char*)ctx
+ gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].offset
;
246 static inline DWORD64
cpu_register(struct gdb_context
*gdbctx
,
247 dbg_ctx_t
*ctx
, unsigned idx
)
249 switch (gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].length
)
251 case 1: return *(BYTE
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
252 case 2: return *(WORD
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
253 case 4: return *(DWORD
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
254 case 8: return *(DWORD64
*)cpu_register_ptr(gdbctx
, ctx
, idx
);
256 ERR("got unexpected size: %u\n",
257 (unsigned)gdbctx
->process
->be_cpu
->gdb_register_map
[idx
].length
);
263 static inline void cpu_register_hex_from(struct gdb_context
*gdbctx
,
264 dbg_ctx_t
* ctx
, unsigned idx
, const char **phex
)
266 const struct gdb_register
*cpu_register_map
= gdbctx
->process
->be_cpu
->gdb_register_map
;
267 hex_from(cpu_register_ptr(gdbctx
, ctx
, idx
), *phex
, cpu_register_map
[idx
].length
);
270 /* =============================================== *
271 * W I N 3 2 D E B U G I N T E R F A C E *
272 * =============================================== *
275 static struct dbg_thread
* dbg_thread_from_tid(struct gdb_context
* gdbctx
, int tid
)
277 struct dbg_process
*process
= gdbctx
->process
;
278 struct dbg_thread
*thread
;
280 if (!process
) return NULL
;
282 if (tid
== 0) tid
= gdbctx
->de
.dwThreadId
;
283 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
285 if (tid
> 0 && thread
->tid
!= tid
) continue;
292 static void dbg_thread_set_single_step(struct dbg_thread
*thread
, BOOL enable
)
294 struct backend_cpu
*backend
;
298 if (!thread
->process
) return;
299 if (!(backend
= thread
->process
->be_cpu
)) return;
301 if (!backend
->get_context(thread
->handle
, &ctx
))
303 ERR("get_context failed for thread %04x:%04x\n", thread
->process
->pid
, thread
->tid
);
306 backend
->single_step(&ctx
, enable
);
307 if (!backend
->set_context(thread
->handle
, &ctx
))
308 ERR("set_context failed for thread %04x:%04x\n", thread
->process
->pid
, thread
->tid
);
311 static unsigned char signal_from_debug_event(DEBUG_EVENT
* de
)
315 if (de
->dwDebugEventCode
== EXIT_PROCESS_DEBUG_EVENT
)
317 if (de
->dwDebugEventCode
!= EXCEPTION_DEBUG_EVENT
)
320 ec
= de
->u
.Exception
.ExceptionRecord
.ExceptionCode
;
323 case EXCEPTION_ACCESS_VIOLATION
:
324 case EXCEPTION_PRIV_INSTRUCTION
:
325 case EXCEPTION_STACK_OVERFLOW
:
326 case EXCEPTION_GUARD_PAGE
:
328 case EXCEPTION_DATATYPE_MISALIGNMENT
:
330 case EXCEPTION_SINGLE_STEP
:
331 case EXCEPTION_BREAKPOINT
:
333 case EXCEPTION_FLT_DENORMAL_OPERAND
:
334 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
335 case EXCEPTION_FLT_INEXACT_RESULT
:
336 case EXCEPTION_FLT_INVALID_OPERATION
:
337 case EXCEPTION_FLT_OVERFLOW
:
338 case EXCEPTION_FLT_STACK_CHECK
:
339 case EXCEPTION_FLT_UNDERFLOW
:
341 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
342 case EXCEPTION_INT_OVERFLOW
:
344 case EXCEPTION_ILLEGAL_INSTRUCTION
:
348 case STATUS_POSSIBLE_DEADLOCK
:
350 /* should not be here */
351 case EXCEPTION_INVALID_HANDLE
:
352 case EXCEPTION_NAME_THREAD
:
355 ERR("Unknown exception code 0x%08x\n", ec
);
360 static BOOL
handle_exception(struct gdb_context
* gdbctx
, EXCEPTION_DEBUG_INFO
* exc
)
362 EXCEPTION_RECORD
* rec
= &exc
->ExceptionRecord
;
364 switch (rec
->ExceptionCode
)
366 case EXCEPTION_NAME_THREAD
:
368 const THREADNAME_INFO
*threadname
= (const THREADNAME_INFO
*)rec
->ExceptionInformation
;
369 struct dbg_thread
*thread
;
373 if (threadname
->dwThreadID
== -1)
374 thread
= dbg_get_thread(gdbctx
->process
, gdbctx
->de
.dwThreadId
);
376 thread
= dbg_get_thread(gdbctx
->process
, threadname
->dwThreadID
);
379 if (gdbctx
->process
->process_io
->read( gdbctx
->process
->handle
,
380 threadname
->szName
, name
, sizeof(name
), &read
) && read
== sizeof(name
))
382 fprintf(stderr
, "Thread ID=%04x renamed to \"%.9s\"\n",
383 threadname
->dwThreadID
, name
);
387 ERR("Cannot set name of thread %04x\n", threadname
->dwThreadID
);
390 case EXCEPTION_INVALID_HANDLE
:
397 static BOOL
handle_debug_event(struct gdb_context
* gdbctx
)
399 DEBUG_EVENT
*de
= &gdbctx
->de
;
400 struct dbg_thread
*thread
;
407 gdbctx
->exec_tid
= de
->dwThreadId
;
408 gdbctx
->other_tid
= de
->dwThreadId
;
409 gdbctx
->de_reply
= DBG_REPLY_LATER
;
411 switch (de
->dwDebugEventCode
)
413 case CREATE_PROCESS_DEBUG_EVENT
:
414 gdbctx
->process
= dbg_add_process(&be_process_gdbproxy_io
, de
->dwProcessId
,
415 de
->u
.CreateProcessInfo
.hProcess
);
416 if (!gdbctx
->process
)
419 memory_get_string_indirect(gdbctx
->process
,
420 de
->u
.CreateProcessInfo
.lpImageName
,
421 de
->u
.CreateProcessInfo
.fUnicode
,
422 u
.buffer
, ARRAY_SIZE(u
.buffer
));
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 memory_get_string_indirect(gdbctx
->process
,
447 de
->u
.LoadDll
.lpImageName
,
448 de
->u
.LoadDll
.fUnicode
,
449 u
.buffer
, ARRAY_SIZE(u
.buffer
));
450 fprintf(stderr
, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
451 de
->dwProcessId
, de
->dwThreadId
,
452 dbg_W2A(u
.buffer
, -1),
453 de
->u
.LoadDll
.lpBaseOfDll
,
454 de
->u
.LoadDll
.dwDebugInfoFileOffset
,
455 de
->u
.LoadDll
.nDebugInfoSize
);
456 dbg_load_module(gdbctx
->process
->handle
, de
->u
.LoadDll
.hFile
, u
.buffer
,
457 (DWORD_PTR
)de
->u
.LoadDll
.lpBaseOfDll
, 0);
460 case UNLOAD_DLL_DEBUG_EVENT
:
461 fprintf(stderr
, "%08x:%08x: unload DLL @%p\n",
462 de
->dwProcessId
, de
->dwThreadId
, de
->u
.UnloadDll
.lpBaseOfDll
);
463 SymUnloadModule(gdbctx
->process
->handle
,
464 (DWORD_PTR
)de
->u
.UnloadDll
.lpBaseOfDll
);
467 case EXCEPTION_DEBUG_EVENT
:
468 TRACE("%08x:%08x: exception code=0x%08x\n", de
->dwProcessId
,
469 de
->dwThreadId
, de
->u
.Exception
.ExceptionRecord
.ExceptionCode
);
471 if (handle_exception(gdbctx
, &de
->u
.Exception
))
475 case CREATE_THREAD_DEBUG_EVENT
:
476 fprintf(stderr
, "%08x:%08x: create thread D @%p\n", de
->dwProcessId
,
477 de
->dwThreadId
, de
->u
.CreateThread
.lpStartAddress
);
479 dbg_add_thread(gdbctx
->process
,
481 de
->u
.CreateThread
.hThread
,
482 de
->u
.CreateThread
.lpThreadLocalBase
);
485 case EXIT_THREAD_DEBUG_EVENT
:
486 fprintf(stderr
, "%08x:%08x: exit thread (%u)\n",
487 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitThread
.dwExitCode
);
488 if ((thread
= dbg_get_thread(gdbctx
->process
, de
->dwThreadId
)))
489 dbg_del_thread(thread
);
492 case EXIT_PROCESS_DEBUG_EVENT
:
493 fprintf(stderr
, "%08x:%08x: exit process (%u)\n",
494 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitProcess
.dwExitCode
);
496 dbg_del_process(gdbctx
->process
);
497 gdbctx
->process
= NULL
;
500 case OUTPUT_DEBUG_STRING_EVENT
:
501 memory_get_string(gdbctx
->process
,
502 de
->u
.DebugString
.lpDebugStringData
, TRUE
,
503 de
->u
.DebugString
.fUnicode
, u
.bufferA
, sizeof(u
.bufferA
));
504 fprintf(stderr
, "%08x:%08x: output debug string (%s)\n",
505 de
->dwProcessId
, de
->dwThreadId
, debugstr_a(u
.bufferA
));
509 fprintf(stderr
, "%08x:%08x: rip error=%u type=%u\n", de
->dwProcessId
,
510 de
->dwThreadId
, de
->u
.RipInfo
.dwError
, de
->u
.RipInfo
.dwType
);
514 FIXME("%08x:%08x: unknown event (%u)\n",
515 de
->dwProcessId
, de
->dwThreadId
, de
->dwDebugEventCode
);
518 LIST_FOR_EACH_ENTRY(thread
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
520 if (!thread
->suspended
) SuspendThread(thread
->handle
);
521 thread
->suspended
= TRUE
;
527 static void handle_step_or_continue(struct gdb_context
* gdbctx
, int tid
, BOOL step
, int sig
)
529 struct dbg_process
*process
= gdbctx
->process
;
530 struct dbg_thread
*thread
;
532 if (tid
== 0) tid
= gdbctx
->de
.dwThreadId
;
533 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
535 if (tid
!= -1 && thread
->tid
!= tid
) continue;
536 if (!thread
->suspended
) continue;
537 thread
->suspended
= FALSE
;
539 if (process
->pid
== gdbctx
->de
.dwProcessId
&& thread
->tid
== gdbctx
->de
.dwThreadId
)
540 gdbctx
->de_reply
= (sig
== -1 ? DBG_CONTINUE
: DBG_EXCEPTION_NOT_HANDLED
);
542 dbg_thread_set_single_step(thread
, step
);
543 ResumeThread(thread
->handle
);
547 static BOOL
check_for_interrupt(struct gdb_context
* gdbctx
)
549 struct pollfd pollfd
;
553 pollfd
.fd
= gdbctx
->sock
;
554 pollfd
.events
= POLLIN
;
557 if ((ret
= poll(&pollfd
, 1, 0)) == 1) {
558 ret
= read(gdbctx
->sock
, &pkt
, 1);
560 ERR("read failed\n");
564 ERR("Unexpected break packet %#02x\n", pkt
);
568 } else if (ret
== -1) {
569 ERR("poll failed\n");
574 static void wait_for_debuggee(struct gdb_context
* gdbctx
)
576 if (gdbctx
->de
.dwDebugEventCode
)
577 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, gdbctx
->de_reply
);
581 if (!WaitForDebugEvent(&gdbctx
->de
, 10))
583 if (GetLastError() == ERROR_SEM_TIMEOUT
)
585 if (check_for_interrupt(gdbctx
)) {
586 if (!DebugBreakProcess(gdbctx
->process
->handle
)) {
587 ERR("Failed to break into debuggee\n");
590 WaitForDebugEvent(&gdbctx
->de
, INFINITE
);
598 if (!handle_debug_event(gdbctx
))
600 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
604 static void detach_debuggee(struct gdb_context
* gdbctx
, BOOL kill
)
606 handle_step_or_continue(gdbctx
, -1, FALSE
, -1);
608 if (gdbctx
->de
.dwDebugEventCode
)
609 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
612 DebugActiveProcessStop(gdbctx
->process
->pid
);
613 dbg_del_process(gdbctx
->process
);
614 gdbctx
->process
= NULL
;
617 static void get_process_info(struct gdb_context
* gdbctx
, char* buffer
, size_t len
)
621 if (!GetExitCodeProcess(gdbctx
->process
->handle
, &status
))
623 strcpy(buffer
, "Unknown process");
626 if (status
== STILL_ACTIVE
)
628 strcpy(buffer
, "Running");
631 snprintf(buffer
, len
, "Terminated (%u)", status
);
633 switch (GetPriorityClass(gdbctx
->process
->handle
))
636 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
637 case ABOVE_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", above normal priority"); break;
639 #ifdef BELOW_NORMAL_PRIORITY_CLASS
640 case BELOW_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", below normal priority"); break;
642 case HIGH_PRIORITY_CLASS
: strcat(buffer
, ", high priority"); break;
643 case IDLE_PRIORITY_CLASS
: strcat(buffer
, ", idle priority"); break;
644 case NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", normal priority"); break;
645 case REALTIME_PRIORITY_CLASS
: strcat(buffer
, ", realtime priority"); break;
647 strcat(buffer
, "\n");
650 static void get_thread_info(struct gdb_context
* gdbctx
, unsigned tid
,
651 char* buffer
, size_t len
)
653 struct dbg_thread
* thd
;
657 /* FIXME: use the size of buffer */
658 thd
= dbg_get_thread(gdbctx
->process
, tid
);
661 strcpy(buffer
, "No information");
664 if (GetExitCodeThread(thd
->handle
, &status
))
666 if (status
== STILL_ACTIVE
)
668 /* FIXME: this is a bit brutal... some nicer way shall be found */
669 switch (status
= SuspendThread(thd
->handle
))
672 case 0: strcpy(buffer
, "Running"); break;
673 default: snprintf(buffer
, len
, "Suspended (%u)", status
- 1);
675 ResumeThread(thd
->handle
);
678 snprintf(buffer
, len
, "Terminated (exit code = %u)", status
);
682 strcpy(buffer
, "Unknown threadID");
684 switch (prio
= GetThreadPriority(thd
->handle
))
686 case THREAD_PRIORITY_ERROR_RETURN
: break;
687 case THREAD_PRIORITY_ABOVE_NORMAL
: strcat(buffer
, ", priority +1 above normal"); break;
688 case THREAD_PRIORITY_BELOW_NORMAL
: strcat(buffer
, ", priority -1 below normal"); break;
689 case THREAD_PRIORITY_HIGHEST
: strcat(buffer
, ", priority +2 above normal"); break;
690 case THREAD_PRIORITY_LOWEST
: strcat(buffer
, ", priority -2 below normal"); break;
691 case THREAD_PRIORITY_IDLE
: strcat(buffer
, ", priority idle"); break;
692 case THREAD_PRIORITY_NORMAL
: strcat(buffer
, ", priority normal"); break;
693 case THREAD_PRIORITY_TIME_CRITICAL
: strcat(buffer
, ", priority time-critical"); break;
694 default: snprintf(buffer
+ strlen(buffer
), len
- strlen(buffer
), ", priority = %d", prio
);
696 assert(strlen(buffer
) < len
);
699 /* =============================================== *
700 * P A C K E T U T I L S *
701 * =============================================== *
704 enum packet_return
{packet_error
= 0x00, packet_ok
= 0x01, packet_done
= 0x02,
705 packet_last_f
= 0x80};
707 static char* packet_realloc(char* buf
, int size
)
710 return HeapAlloc(GetProcessHeap(), 0, size
);
711 return HeapReAlloc(GetProcessHeap(), 0, buf
, size
);
715 static void packet_reply_grow(struct gdb_context
* gdbctx
, size_t size
)
717 if (gdbctx
->out_buf_alloc
< gdbctx
->out_len
+ size
)
719 gdbctx
->out_buf_alloc
= ((gdbctx
->out_len
+ size
) / 32 + 1) * 32;
720 gdbctx
->out_buf
= packet_realloc(gdbctx
->out_buf
, gdbctx
->out_buf_alloc
);
724 static void packet_reply_hex_to(struct gdb_context
* gdbctx
, const void* src
, int len
)
726 packet_reply_grow(gdbctx
, len
* 2);
727 hex_to(&gdbctx
->out_buf
[gdbctx
->out_len
], src
, len
);
728 gdbctx
->out_len
+= len
* 2;
731 static inline void packet_reply_hex_to_str(struct gdb_context
* gdbctx
, const char* src
)
733 packet_reply_hex_to(gdbctx
, src
, strlen(src
));
736 static void packet_reply_val(struct gdb_context
* gdbctx
, unsigned long val
, int len
)
740 shift
= (len
- 1) * 8;
741 packet_reply_grow(gdbctx
, len
* 2);
742 for (i
= 0; i
< len
; i
++, shift
-= 8)
744 gdbctx
->out_buf
[gdbctx
->out_len
++] = hex_to0((val
>> (shift
+ 4)) & 0x0F);
745 gdbctx
->out_buf
[gdbctx
->out_len
++] = hex_to0((val
>> shift
) & 0x0F);
749 static inline void packet_reply_add(struct gdb_context
* gdbctx
, const char* str
)
751 int len
= strlen(str
);
752 packet_reply_grow(gdbctx
, len
);
753 memcpy(&gdbctx
->out_buf
[gdbctx
->out_len
], str
, len
);
754 gdbctx
->out_len
+= len
;
757 static void packet_reply_open(struct gdb_context
* gdbctx
)
759 assert(gdbctx
->out_curr_packet
== -1);
760 packet_reply_add(gdbctx
, "$");
761 gdbctx
->out_curr_packet
= gdbctx
->out_len
;
764 static void packet_reply_close(struct gdb_context
* gdbctx
)
769 plen
= gdbctx
->out_len
- gdbctx
->out_curr_packet
;
770 packet_reply_add(gdbctx
, "#");
771 cksum
= checksum(&gdbctx
->out_buf
[gdbctx
->out_curr_packet
], plen
);
772 packet_reply_hex_to(gdbctx
, &cksum
, 1);
773 gdbctx
->out_curr_packet
= -1;
776 static void packet_reply_open_xfer(struct gdb_context
* gdbctx
)
778 packet_reply_open(gdbctx
);
779 packet_reply_add(gdbctx
, "m");
782 static void packet_reply_close_xfer(struct gdb_context
* gdbctx
, int off
, int len
)
784 int begin
= gdbctx
->out_curr_packet
+ 1;
787 if (begin
+ off
< gdbctx
->out_len
)
789 gdbctx
->out_len
-= off
;
790 memmove(gdbctx
->out_buf
+ begin
, gdbctx
->out_buf
+ begin
+ off
, gdbctx
->out_len
);
794 gdbctx
->out_buf
[gdbctx
->out_curr_packet
] = 'l';
795 gdbctx
->out_len
= gdbctx
->out_curr_packet
+ 1;
798 plen
= gdbctx
->out_len
- begin
;
799 if (len
>= 0 && plen
> len
) gdbctx
->out_len
-= (plen
- len
);
800 else gdbctx
->out_buf
[gdbctx
->out_curr_packet
] = 'l';
802 packet_reply_close(gdbctx
);
805 static enum packet_return
packet_reply(struct gdb_context
* gdbctx
, const char* packet
)
807 packet_reply_open(gdbctx
);
809 assert(strchr(packet
, '$') == NULL
&& strchr(packet
, '#') == NULL
);
811 packet_reply_add(gdbctx
, packet
);
813 packet_reply_close(gdbctx
);
818 static enum packet_return
packet_reply_error(struct gdb_context
* gdbctx
, int error
)
820 packet_reply_open(gdbctx
);
822 packet_reply_add(gdbctx
, "E");
823 packet_reply_val(gdbctx
, error
, 1);
825 packet_reply_close(gdbctx
);
830 static inline void packet_reply_register_hex_to(struct gdb_context
* gdbctx
, dbg_ctx_t
* ctx
, unsigned idx
)
832 const struct gdb_register
*cpu_register_map
= gdbctx
->process
->be_cpu
->gdb_register_map
;
833 packet_reply_hex_to(gdbctx
, cpu_register_ptr(gdbctx
, ctx
, idx
), cpu_register_map
[idx
].length
);
836 /* =============================================== *
837 * P A C K E T H A N D L E R S *
838 * =============================================== *
841 static void packet_reply_status_xpoints(struct gdb_context
* gdbctx
, struct dbg_thread
*thread
,
844 struct dbg_process
*process
= thread
->process
;
845 struct backend_cpu
*cpu
= process
->be_cpu
;
846 struct gdb_xpoint
*x
;
848 LIST_FOR_EACH_ENTRY(x
, &gdbctx
->xpoint_list
, struct gdb_xpoint
, entry
)
850 if (x
->pid
!= process
->pid
|| x
->tid
!= thread
->tid
)
852 if (!cpu
->is_watchpoint_set(ctx
, x
->value
))
854 if (x
->type
== be_xpoint_watch_write
)
856 packet_reply_add(gdbctx
, "watch:");
857 packet_reply_val(gdbctx
, (unsigned long)x
->addr
, sizeof(x
->addr
));
858 packet_reply_add(gdbctx
, ";");
860 if (x
->type
== be_xpoint_watch_read
)
862 packet_reply_add(gdbctx
, "rwatch:");
863 packet_reply_val(gdbctx
, (unsigned long)x
->addr
, sizeof(x
->addr
));
864 packet_reply_add(gdbctx
, ";");
869 static enum packet_return
packet_reply_status(struct gdb_context
* gdbctx
)
871 struct dbg_process
*process
= gdbctx
->process
;
872 struct dbg_thread
*thread
;
873 struct backend_cpu
*backend
;
877 switch (gdbctx
->de
.dwDebugEventCode
)
880 if (!process
) return packet_error
;
881 if (!(backend
= process
->be_cpu
)) return packet_error
;
882 if (!(thread
= dbg_get_thread(process
, gdbctx
->de
.dwThreadId
)) ||
883 !backend
->get_context(thread
->handle
, &ctx
))
886 packet_reply_open(gdbctx
);
887 packet_reply_add(gdbctx
, "T");
888 packet_reply_val(gdbctx
, signal_from_debug_event(&gdbctx
->de
), 1);
889 packet_reply_add(gdbctx
, "thread:");
890 packet_reply_val(gdbctx
, gdbctx
->de
.dwThreadId
, 4);
891 packet_reply_add(gdbctx
, ";");
892 packet_reply_status_xpoints(gdbctx
, thread
, &ctx
);
894 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
896 packet_reply_val(gdbctx
, i
, 1);
897 packet_reply_add(gdbctx
, ":");
898 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
899 packet_reply_add(gdbctx
, ";");
902 packet_reply_close(gdbctx
);
905 case EXIT_PROCESS_DEBUG_EVENT
:
906 packet_reply_open(gdbctx
);
907 packet_reply_add(gdbctx
, "W");
908 packet_reply_val(gdbctx
, gdbctx
->de
.u
.ExitProcess
.dwExitCode
, 4);
909 packet_reply_close(gdbctx
);
910 return packet_done
| packet_last_f
;
914 static enum packet_return
packet_last_signal(struct gdb_context
* gdbctx
)
916 assert(gdbctx
->in_packet_len
== 0);
917 return packet_reply_status(gdbctx
);
920 static enum packet_return
packet_continue(struct gdb_context
* gdbctx
)
924 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
925 FIXME("Continue at address %p not supported\n", addr
);
927 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, -1);
929 wait_for_debuggee(gdbctx
);
930 return packet_reply_status(gdbctx
);
933 static enum packet_return
packet_verbose_cont(struct gdb_context
* gdbctx
)
935 char *buf
= gdbctx
->in_packet
, *end
= gdbctx
->in_packet
+ gdbctx
->in_packet_len
;
937 if (gdbctx
->in_packet
[4] == '?')
939 packet_reply_open(gdbctx
);
940 packet_reply_add(gdbctx
, "vCont");
941 packet_reply_add(gdbctx
, ";c");
942 packet_reply_add(gdbctx
, ";C");
943 packet_reply_add(gdbctx
, ";s");
944 packet_reply_add(gdbctx
, ";S");
945 packet_reply_close(gdbctx
);
949 while (buf
< end
&& (buf
= memchr(buf
+ 1, ';', end
- buf
- 1)))
951 int tid
= -1, sig
= -1;
954 switch ((action
= buf
[1]))
964 if (sscanf(buf
, ";%*c%2x", &sig
) <= 0 ||
965 sig
!= signal_from_debug_event(&gdbctx
->de
))
973 if (buf
< end
&& *buf
== ':' && (n
= sscanf(buf
, ":%x", &tid
)) <= 0)
976 handle_step_or_continue(gdbctx
, tid
, action
== 's' || action
== 'S', sig
);
979 wait_for_debuggee(gdbctx
);
980 return packet_reply_status(gdbctx
);
983 static enum packet_return
packet_verbose(struct gdb_context
* gdbctx
)
985 if (gdbctx
->in_packet_len
>= 4 && !memcmp(gdbctx
->in_packet
, "Cont", 4))
987 return packet_verbose_cont(gdbctx
);
990 if (gdbctx
->in_packet_len
== 14 && !memcmp(gdbctx
->in_packet
, "MustReplyEmpty", 14))
991 return packet_reply(gdbctx
, "");
996 static enum packet_return
packet_continue_signal(struct gdb_context
* gdbctx
)
1001 if ((n
= sscanf(gdbctx
->in_packet
, "%x;%p", &sig
, &addr
)) == 2)
1002 FIXME("Continue at address %p not supported\n", addr
);
1003 if (n
< 1) return packet_error
;
1005 if (sig
!= signal_from_debug_event(&gdbctx
->de
))
1007 ERR("Changing signals is not supported.\n");
1008 return packet_error
;
1011 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, sig
);
1013 wait_for_debuggee(gdbctx
);
1014 return packet_reply_status(gdbctx
);
1017 static enum packet_return
packet_delete_breakpoint(struct gdb_context
* gdbctx
)
1019 struct dbg_process
*process
= gdbctx
->process
;
1020 struct dbg_thread
*thread
;
1021 struct backend_cpu
*cpu
;
1022 struct gdb_xpoint
*x
;
1028 if (!process
) return packet_error
;
1029 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1031 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1032 return packet_error
;
1035 return packet_error
;
1037 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1039 if (!cpu
->get_context(thread
->handle
, &ctx
))
1041 if ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_exec
, addr
, size
)))
1042 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1043 if ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_read
, addr
, size
)))
1044 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1045 if ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_write
, addr
, size
)))
1046 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1047 cpu
->set_context(thread
->handle
, &ctx
);
1050 while ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_exec
, addr
, size
)))
1051 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1052 while ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_read
, addr
, size
)))
1053 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1054 while ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_write
, addr
, size
)))
1055 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1060 static enum packet_return
packet_insert_breakpoint(struct gdb_context
* gdbctx
)
1062 struct dbg_process
*process
= gdbctx
->process
;
1063 struct dbg_thread
*thread
;
1064 struct backend_cpu
*cpu
;
1070 if (!process
) return packet_error
;
1071 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1073 if (memchr(gdbctx
->in_packet
, ';', gdbctx
->in_packet_len
))
1075 FIXME("breakpoint commands not supported\n");
1076 return packet_error
;
1079 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1080 return packet_error
;
1083 return packet_error
;
1085 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1087 if (!cpu
->get_context(thread
->handle
, &ctx
))
1090 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_exec
, addr
, size
);
1091 if (type
== '2' || type
== '4')
1092 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_read
, addr
, size
);
1093 if (type
== '3' || type
== '4')
1094 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_write
, addr
, size
);
1095 cpu
->set_context(thread
->handle
, &ctx
);
1101 static enum packet_return
packet_detach(struct gdb_context
* gdbctx
)
1103 detach_debuggee(gdbctx
, FALSE
);
1104 return packet_ok
| packet_last_f
;
1107 static enum packet_return
packet_read_registers(struct gdb_context
* gdbctx
)
1109 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1110 struct backend_cpu
*backend
;
1114 if (!thread
) return packet_error
;
1115 if (!thread
->process
) return packet_error
;
1116 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1118 if (!backend
->get_context(thread
->handle
, &ctx
))
1119 return packet_error
;
1121 packet_reply_open(gdbctx
);
1122 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1123 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
1125 packet_reply_close(gdbctx
);
1129 static enum packet_return
packet_write_registers(struct gdb_context
* gdbctx
)
1131 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1132 struct backend_cpu
*backend
;
1137 if (!thread
) return packet_error
;
1138 if (!thread
->process
) return packet_error
;
1139 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1141 if (!backend
->get_context(thread
->handle
, &ctx
))
1142 return packet_error
;
1144 if (gdbctx
->in_packet_len
< backend
->gdb_num_regs
* 2)
1145 return packet_error
;
1147 ptr
= gdbctx
->in_packet
;
1148 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1149 cpu_register_hex_from(gdbctx
, &ctx
, i
, &ptr
);
1151 if (!backend
->set_context(thread
->handle
, &ctx
))
1153 ERR("Failed to set context for tid %04x, error %u\n", thread
->tid
, GetLastError());
1154 return packet_error
;
1160 static enum packet_return
packet_kill(struct gdb_context
* gdbctx
)
1162 detach_debuggee(gdbctx
, TRUE
);
1163 return packet_ok
| packet_last_f
;
1166 static enum packet_return
packet_thread(struct gdb_context
* gdbctx
)
1168 switch (gdbctx
->in_packet
[0])
1171 if (sscanf(gdbctx
->in_packet
, "c%x", &gdbctx
->exec_tid
) == 1)
1173 return packet_error
;
1175 if (sscanf(gdbctx
->in_packet
, "g%x", &gdbctx
->other_tid
) == 1)
1177 return packet_error
;
1179 FIXME("Unknown thread sub-command %c\n", gdbctx
->in_packet
[0]);
1180 return packet_error
;
1184 static enum packet_return
packet_read_memory(struct gdb_context
* gdbctx
)
1187 unsigned int len
, blk_len
, nread
;
1191 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2) return packet_error
;
1192 if (len
<= 0) return packet_error
;
1193 TRACE("Read %u bytes at %p\n", len
, addr
);
1194 for (nread
= 0; nread
< len
; nread
+= r
, addr
+= r
)
1196 blk_len
= min(sizeof(buffer
), len
- nread
);
1197 if (!gdbctx
->process
->process_io
->read(gdbctx
->process
->handle
, addr
,
1198 buffer
, blk_len
, &r
) || r
== 0)
1200 /* fail at first address, return error */
1201 if (nread
== 0) return packet_reply_error(gdbctx
, EFAULT
);
1202 /* something has already been read, return partial information */
1205 if (nread
== 0) packet_reply_open(gdbctx
);
1206 packet_reply_hex_to(gdbctx
, buffer
, r
);
1208 packet_reply_close(gdbctx
);
1212 static enum packet_return
packet_write_memory(struct gdb_context
* gdbctx
)
1215 unsigned int len
, blk_len
;
1220 ptr
= memchr(gdbctx
->in_packet
, ':', gdbctx
->in_packet_len
);
1223 ERR("Cannot find ':' in %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1224 return packet_error
;
1228 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2)
1230 ERR("Failed to parse %s\n", debugstr_a(gdbctx
->in_packet
));
1231 return packet_error
;
1233 if (ptr
- gdbctx
->in_packet
+ len
* 2 != gdbctx
->in_packet_len
)
1235 ERR("Length %u does not match packet length %u\n",
1236 (int)(ptr
- gdbctx
->in_packet
) + len
* 2, gdbctx
->in_packet_len
);
1237 return packet_error
;
1239 TRACE("Write %u bytes at %p\n", len
, addr
);
1242 blk_len
= min(sizeof(buffer
), len
);
1243 hex_from(buffer
, ptr
, blk_len
);
1244 if (!gdbctx
->process
->process_io
->write(gdbctx
->process
->handle
, addr
, buffer
, blk_len
, &w
) ||
1251 return packet_ok
; /* FIXME: error while writing ? */
1254 static enum packet_return
packet_read_register(struct gdb_context
* gdbctx
)
1256 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1257 struct backend_cpu
*backend
;
1261 if (!thread
) return packet_error
;
1262 if (!thread
->process
) return packet_error
;
1263 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1265 if (!backend
->get_context(thread
->handle
, &ctx
))
1266 return packet_error
;
1268 if (sscanf(gdbctx
->in_packet
, "%zx", ®
) != 1)
1269 return packet_error
;
1270 if (reg
>= backend
->gdb_num_regs
)
1272 WARN("Unhandled register %zu\n", reg
);
1273 return packet_error
;
1276 TRACE("%zu => %s\n", reg
, wine_dbgstr_longlong(cpu_register(gdbctx
, &ctx
, reg
)));
1278 packet_reply_open(gdbctx
);
1279 packet_reply_register_hex_to(gdbctx
, &ctx
, reg
);
1280 packet_reply_close(gdbctx
);
1284 static enum packet_return
packet_write_register(struct gdb_context
* gdbctx
)
1286 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1287 struct backend_cpu
*backend
;
1292 if (!thread
) return packet_error
;
1293 if (!thread
->process
) return packet_error
;
1294 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1296 if (!backend
->get_context(thread
->handle
, &ctx
))
1297 return packet_error
;
1299 if (!(ptr
= strchr(gdbctx
->in_packet
, '=')))
1300 return packet_error
;
1303 if (sscanf(gdbctx
->in_packet
, "%zx", ®
) != 1)
1304 return packet_error
;
1305 if (reg
>= backend
->gdb_num_regs
)
1307 /* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
1308 * it wouldn't matter too much, and it fakes our support for all regs
1310 WARN("Unhandled register %zu\n", reg
);
1314 TRACE("%zu <= %s\n", reg
, debugstr_an(ptr
, (int)(gdbctx
->in_packet_len
- (ptr
- gdbctx
->in_packet
))));
1316 cpu_register_hex_from(gdbctx
, &ctx
, reg
, (const char**)&ptr
);
1317 if (!backend
->set_context(thread
->handle
, &ctx
))
1319 ERR("Failed to set context for tid %04x, error %u\n", thread
->tid
, GetLastError());
1320 return packet_error
;
1326 static void packet_query_monitor_wnd_helper(struct gdb_context
* gdbctx
, HWND hWnd
, int indent
)
1334 if (!GetClassNameA(hWnd
, clsName
, sizeof(clsName
)))
1335 strcpy(clsName
, "-- Unknown --");
1336 if (!GetWindowTextA(hWnd
, wndName
, sizeof(wndName
)))
1337 strcpy(wndName
, "-- Empty --");
1339 packet_reply_open(gdbctx
);
1340 packet_reply_add(gdbctx
, "O");
1341 snprintf(buffer
, sizeof(buffer
),
1342 "%*s%04lx%*s%-17.17s %08x %0*lx %.14s\n",
1343 indent
, "", (ULONG_PTR
)hWnd
, 13 - indent
, "",
1344 clsName
, GetWindowLongW(hWnd
, GWL_STYLE
),
1345 ADDRWIDTH
, (ULONG_PTR
)GetWindowLongPtrW(hWnd
, GWLP_WNDPROC
),
1347 packet_reply_hex_to_str(gdbctx
, buffer
);
1348 packet_reply_close(gdbctx
);
1350 if ((child
= GetWindow(hWnd
, GW_CHILD
)) != 0)
1351 packet_query_monitor_wnd_helper(gdbctx
, child
, indent
+ 1);
1352 } while ((hWnd
= GetWindow(hWnd
, GW_HWNDNEXT
)) != 0);
1355 static void packet_query_monitor_wnd(struct gdb_context
* gdbctx
, int len
, const char* str
)
1359 /* we do the output in several 'O' packets, with the last one being just OK for
1360 * marking the end of the output */
1361 packet_reply_open(gdbctx
);
1362 packet_reply_add(gdbctx
, "O");
1363 snprintf(buffer
, sizeof(buffer
),
1364 "%-16.16s %-17.17s %-8.8s %s\n",
1365 "hwnd", "Class Name", " Style", " WndProc Text");
1366 packet_reply_hex_to_str(gdbctx
, buffer
);
1367 packet_reply_close(gdbctx
);
1369 /* FIXME: could also add a pmt to this command in str... */
1370 packet_query_monitor_wnd_helper(gdbctx
, GetDesktopWindow(), 0);
1371 packet_reply(gdbctx
, "OK");
1374 static void packet_query_monitor_process(struct gdb_context
* gdbctx
, int len
, const char* str
)
1376 HANDLE snap
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
1377 char buffer
[31+MAX_PATH
];
1379 PROCESSENTRY32 entry
;
1382 if (snap
== INVALID_HANDLE_VALUE
)
1385 entry
.dwSize
= sizeof(entry
);
1386 ok
= Process32First(snap
, &entry
);
1388 /* we do the output in several 'O' packets, with the last one being just OK for
1389 * marking the end of the output */
1391 packet_reply_open(gdbctx
);
1392 packet_reply_add(gdbctx
, "O");
1393 snprintf(buffer
, sizeof(buffer
),
1394 " %-8.8s %-8.8s %-8.8s %s\n",
1395 "pid", "threads", "parent", "executable");
1396 packet_reply_hex_to_str(gdbctx
, buffer
);
1397 packet_reply_close(gdbctx
);
1402 if (entry
.th32ProcessID
== gdbctx
->process
->pid
) deco
= '>';
1403 packet_reply_open(gdbctx
);
1404 packet_reply_add(gdbctx
, "O");
1405 snprintf(buffer
, sizeof(buffer
),
1406 "%c%08x %-8d %08x '%s'\n",
1407 deco
, entry
.th32ProcessID
, entry
.cntThreads
,
1408 entry
.th32ParentProcessID
, entry
.szExeFile
);
1409 packet_reply_hex_to_str(gdbctx
, buffer
);
1410 packet_reply_close(gdbctx
);
1411 ok
= Process32Next(snap
, &entry
);
1414 packet_reply(gdbctx
, "OK");
1417 static void packet_query_monitor_mem(struct gdb_context
* gdbctx
, int len
, const char* str
)
1419 MEMORY_BASIC_INFORMATION mbi
;
1426 /* we do the output in several 'O' packets, with the last one being just OK for
1427 * marking the end of the output */
1428 packet_reply_open(gdbctx
);
1429 packet_reply_add(gdbctx
, "O");
1430 packet_reply_hex_to_str(gdbctx
, "Address Size State Type RWX\n");
1431 packet_reply_close(gdbctx
);
1433 while (VirtualQueryEx(gdbctx
->process
->handle
, addr
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
))
1437 case MEM_COMMIT
: state
= "commit "; break;
1438 case MEM_FREE
: state
= "free "; break;
1439 case MEM_RESERVE
: state
= "reserve"; break;
1440 default: state
= "??? "; break;
1442 if (mbi
.State
!= MEM_FREE
)
1446 case MEM_IMAGE
: type
= "image "; break;
1447 case MEM_MAPPED
: type
= "mapped "; break;
1448 case MEM_PRIVATE
: type
= "private"; break;
1449 case 0: type
= " "; break;
1450 default: type
= "??? "; break;
1452 memset(prot
, ' ' , sizeof(prot
)-1);
1453 prot
[sizeof(prot
)-1] = '\0';
1454 if (mbi
.AllocationProtect
& (PAGE_READONLY
|PAGE_READWRITE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
))
1456 if (mbi
.AllocationProtect
& (PAGE_READWRITE
|PAGE_EXECUTE_READWRITE
))
1458 if (mbi
.AllocationProtect
& (PAGE_WRITECOPY
|PAGE_EXECUTE_WRITECOPY
))
1460 if (mbi
.AllocationProtect
& (PAGE_EXECUTE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
))
1468 packet_reply_open(gdbctx
);
1469 snprintf(buffer
, sizeof(buffer
), "%0*lx %0*lx %s %s %s\n",
1470 (unsigned)sizeof(void*), (DWORD_PTR
)addr
,
1471 (unsigned)sizeof(void*), mbi
.RegionSize
, state
, type
, prot
);
1472 packet_reply_add(gdbctx
, "O");
1473 packet_reply_hex_to_str(gdbctx
, buffer
);
1474 packet_reply_close(gdbctx
);
1476 if (addr
+ mbi
.RegionSize
< addr
) /* wrap around ? */
1478 addr
+= mbi
.RegionSize
;
1480 packet_reply(gdbctx
, "OK");
1488 void (*handler
)(struct gdb_context
*, int, const char*);
1491 {0, "wnd", 3, packet_query_monitor_wnd
},
1492 {0, "window", 6, packet_query_monitor_wnd
},
1493 {0, "proc", 4, packet_query_monitor_process
},
1494 {0, "process", 7, packet_query_monitor_process
},
1495 {0, "mem", 3, packet_query_monitor_mem
},
1499 static enum packet_return
packet_query_remote_command(struct gdb_context
* gdbctx
,
1500 const char* hxcmd
, size_t len
)
1503 struct query_detail
* qd
;
1505 assert((len
& 1) == 0 && len
< 2 * sizeof(buffer
));
1507 hex_from(buffer
, hxcmd
, len
);
1509 for (qd
= query_details
; qd
->name
!= NULL
; qd
++)
1511 if (len
< qd
->len
|| strncmp(buffer
, qd
->name
, qd
->len
) != 0) continue;
1512 if (!qd
->with_arg
&& len
!= qd
->len
) continue;
1514 (qd
->handler
)(gdbctx
, len
- qd
->len
, buffer
+ qd
->len
);
1517 return packet_reply_error(gdbctx
, EINVAL
);
1520 static BOOL CALLBACK
packet_query_libraries_cb(PCSTR mod_name
, DWORD64 base
, PVOID ctx
)
1522 struct gdb_context
* gdbctx
= ctx
;
1523 MEMORY_BASIC_INFORMATION mbi
;
1524 IMAGE_SECTION_HEADER
*sec
;
1525 IMAGE_DOS_HEADER
*dos
= NULL
;
1526 IMAGE_NT_HEADERS
*nth
= NULL
;
1527 IMAGEHLP_MODULE64 mod
;
1532 mod
.SizeOfStruct
= sizeof(mod
);
1533 SymGetModuleInfo64(gdbctx
->process
->handle
, base
, &mod
);
1535 packet_reply_add(gdbctx
, "<library name=\"");
1536 if (strcmp(mod
.LoadedImageName
, "[vdso].so") == 0)
1537 packet_reply_add(gdbctx
, "linux-vdso.so.1");
1538 else if (mod
.LoadedImageName
[0] == '/')
1539 packet_reply_add(gdbctx
, mod
.LoadedImageName
);
1542 UNICODE_STRING nt_name
;
1543 ANSI_STRING ansi_name
;
1544 char *unix_path
, *tmp
;
1546 RtlInitAnsiString(&ansi_name
, mod
.LoadedImageName
);
1547 RtlAnsiStringToUnicodeString(&nt_name
, &ansi_name
, TRUE
);
1549 if ((unix_path
= wine_get_unix_file_name(nt_name
.Buffer
)))
1551 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) &&
1552 is_wow64
&& (tmp
= strstr(unix_path
, "system32")))
1553 memcpy(tmp
, "syswow64", 8);
1554 packet_reply_add(gdbctx
, unix_path
);
1557 packet_reply_add(gdbctx
, mod
.LoadedImageName
);
1559 HeapFree(GetProcessHeap(), 0, unix_path
);
1560 RtlFreeUnicodeString(&nt_name
);
1562 packet_reply_add(gdbctx
, "\">");
1564 size
= sizeof(buffer
);
1565 if (VirtualQueryEx(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
) &&
1566 mbi
.Type
== MEM_IMAGE
&& mbi
.State
!= MEM_FREE
)
1568 if (ReadProcessMemory(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, buffer
, size
, &size
) &&
1569 size
>= sizeof(IMAGE_DOS_HEADER
))
1570 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1572 if (dos
&& dos
->e_magic
== IMAGE_DOS_SIGNATURE
&& dos
->e_lfanew
< size
)
1573 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1575 if (nth
&& memcmp(&nth
->Signature
, "PE\0\0", 4))
1579 if (!nth
) memset(buffer
, 0, sizeof(buffer
));
1581 /* if the module is not PE we have cleared buffer with 0, this makes
1582 * the following computation valid in all cases. */
1583 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1584 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1585 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) && is_wow64
)
1586 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS32
*)nth
);
1588 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS64
*)nth
);
1590 for (i
= 0; i
< max(nth
->FileHeader
.NumberOfSections
, 1); ++i
)
1592 if ((char *)(sec
+ i
) >= buffer
+ size
) break;
1593 packet_reply_add(gdbctx
, "<segment address=\"0x");
1594 packet_reply_val(gdbctx
, mod
.BaseOfImage
+ sec
[i
].VirtualAddress
, sizeof(unsigned long));
1595 packet_reply_add(gdbctx
, "\"/>");
1598 packet_reply_add(gdbctx
, "</library>");
1603 static void packet_query_libraries(struct gdb_context
* gdbctx
)
1607 /* this will resynchronize builtin dbghelp's internal ELF module list */
1608 SymLoadModule(gdbctx
->process
->handle
, 0, 0, 0, 0, 0);
1610 packet_reply_add(gdbctx
, "<library-list>");
1611 opt
= SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, TRUE
);
1612 SymEnumerateModules64(gdbctx
->process
->handle
, packet_query_libraries_cb
, gdbctx
);
1613 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, opt
);
1614 packet_reply_add(gdbctx
, "</library-list>");
1617 static void packet_query_threads(struct gdb_context
* gdbctx
)
1619 struct dbg_process
* process
= gdbctx
->process
;
1620 struct dbg_thread
* thread
;
1622 packet_reply_add(gdbctx
, "<threads>");
1623 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1625 packet_reply_add(gdbctx
, "<thread ");
1626 packet_reply_add(gdbctx
, "id=\"");
1627 packet_reply_val(gdbctx
, thread
->tid
, 4);
1628 packet_reply_add(gdbctx
, "\" name=\"");
1629 packet_reply_add(gdbctx
, thread
->name
);
1630 packet_reply_add(gdbctx
, "\"/>");
1632 packet_reply_add(gdbctx
, "</threads>");
1635 static void packet_query_target_xml(struct gdb_context
* gdbctx
, struct backend_cpu
* cpu
)
1637 const char* feature_prefix
= NULL
;
1638 const char* feature
= NULL
;
1642 packet_reply_add(gdbctx
, "<target>");
1643 switch (cpu
->machine
)
1645 case IMAGE_FILE_MACHINE_AMD64
:
1646 packet_reply_add(gdbctx
, "<architecture>i386:x86-64</architecture>");
1647 feature_prefix
= "org.gnu.gdb.i386.";
1649 case IMAGE_FILE_MACHINE_I386
:
1650 packet_reply_add(gdbctx
, "<architecture>i386</architecture>");
1651 feature_prefix
= "org.gnu.gdb.i386.";
1653 case IMAGE_FILE_MACHINE_ARMNT
:
1654 packet_reply_add(gdbctx
, "<architecture>arm</architecture>");
1655 feature_prefix
= "org.gnu.gdb.arm.";
1657 case IMAGE_FILE_MACHINE_ARM64
:
1658 packet_reply_add(gdbctx
, "<architecture>aarch64</architecture>");
1659 feature_prefix
= "org.gnu.gdb.aarch64.";
1663 for (i
= 0; i
< cpu
->gdb_num_regs
; ++i
)
1665 if (cpu
->gdb_register_map
[i
].feature
)
1667 if (feature
) packet_reply_add(gdbctx
, "</feature>");
1668 feature
= cpu
->gdb_register_map
[i
].feature
;
1670 packet_reply_add(gdbctx
, "<feature name=\"");
1671 if (feature_prefix
) packet_reply_add(gdbctx
, feature_prefix
);
1672 packet_reply_add(gdbctx
, feature
);
1673 packet_reply_add(gdbctx
, "\">");
1675 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1676 strcmp(feature
, "core") == 0)
1677 packet_reply_add(gdbctx
, "<flags id=\"i386_eflags\" size=\"4\">"
1678 "<field name=\"CF\" start=\"0\" end=\"0\"/>"
1679 "<field name=\"\" start=\"1\" end=\"1\"/>"
1680 "<field name=\"PF\" start=\"2\" end=\"2\"/>"
1681 "<field name=\"AF\" start=\"4\" end=\"4\"/>"
1682 "<field name=\"ZF\" start=\"6\" end=\"6\"/>"
1683 "<field name=\"SF\" start=\"7\" end=\"7\"/>"
1684 "<field name=\"TF\" start=\"8\" end=\"8\"/>"
1685 "<field name=\"IF\" start=\"9\" end=\"9\"/>"
1686 "<field name=\"DF\" start=\"10\" end=\"10\"/>"
1687 "<field name=\"OF\" start=\"11\" end=\"11\"/>"
1688 "<field name=\"NT\" start=\"14\" end=\"14\"/>"
1689 "<field name=\"RF\" start=\"16\" end=\"16\"/>"
1690 "<field name=\"VM\" start=\"17\" end=\"17\"/>"
1691 "<field name=\"AC\" start=\"18\" end=\"18\"/>"
1692 "<field name=\"VIF\" start=\"19\" end=\"19\"/>"
1693 "<field name=\"VIP\" start=\"20\" end=\"20\"/>"
1694 "<field name=\"ID\" start=\"21\" end=\"21\"/>"
1697 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1698 strcmp(feature
, "sse") == 0)
1699 packet_reply_add(gdbctx
, "<vector id=\"v4f\" type=\"ieee_single\" count=\"4\"/>"
1700 "<vector id=\"v2d\" type=\"ieee_double\" count=\"2\"/>"
1701 "<vector id=\"v16i8\" type=\"int8\" count=\"16\"/>"
1702 "<vector id=\"v8i16\" type=\"int16\" count=\"8\"/>"
1703 "<vector id=\"v4i32\" type=\"int32\" count=\"4\"/>"
1704 "<vector id=\"v2i64\" type=\"int64\" count=\"2\"/>"
1705 "<union id=\"vec128\">"
1706 "<field name=\"v4_float\" type=\"v4f\"/>"
1707 "<field name=\"v2_double\" type=\"v2d\"/>"
1708 "<field name=\"v16_int8\" type=\"v16i8\"/>"
1709 "<field name=\"v8_int16\" type=\"v8i16\"/>"
1710 "<field name=\"v4_int32\" type=\"v4i32\"/>"
1711 "<field name=\"v2_int64\" type=\"v2i64\"/>"
1712 "<field name=\"uint128\" type=\"uint128\"/>"
1714 "<flags id=\"i386_mxcsr\" size=\"4\">"
1715 "<field name=\"IE\" start=\"0\" end=\"0\"/>"
1716 "<field name=\"DE\" start=\"1\" end=\"1\"/>"
1717 "<field name=\"ZE\" start=\"2\" end=\"2\"/>"
1718 "<field name=\"OE\" start=\"3\" end=\"3\"/>"
1719 "<field name=\"UE\" start=\"4\" end=\"4\"/>"
1720 "<field name=\"PE\" start=\"5\" end=\"5\"/>"
1721 "<field name=\"DAZ\" start=\"6\" end=\"6\"/>"
1722 "<field name=\"IM\" start=\"7\" end=\"7\"/>"
1723 "<field name=\"DM\" start=\"8\" end=\"8\"/>"
1724 "<field name=\"ZM\" start=\"9\" end=\"9\"/>"
1725 "<field name=\"OM\" start=\"10\" end=\"10\"/>"
1726 "<field name=\"UM\" start=\"11\" end=\"11\"/>"
1727 "<field name=\"PM\" start=\"12\" end=\"12\"/>"
1728 "<field name=\"FZ\" start=\"15\" end=\"15\"/>"
1732 snprintf(buffer
, ARRAY_SIZE(buffer
), "<reg name=\"%s\" bitsize=\"%zu\"",
1733 cpu
->gdb_register_map
[i
].name
, 8 * cpu
->gdb_register_map
[i
].length
);
1734 packet_reply_add(gdbctx
, buffer
);
1736 if (cpu
->gdb_register_map
[i
].type
)
1738 packet_reply_add(gdbctx
, " type=\"");
1739 packet_reply_add(gdbctx
, cpu
->gdb_register_map
[i
].type
);
1740 packet_reply_add(gdbctx
, "\"");
1743 packet_reply_add(gdbctx
, "/>");
1746 if (feature
) packet_reply_add(gdbctx
, "</feature>");
1747 packet_reply_add(gdbctx
, "</target>");
1750 static enum packet_return
packet_query(struct gdb_context
* gdbctx
)
1753 struct backend_cpu
*cpu
;
1755 switch (gdbctx
->in_packet
[0])
1758 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
1760 struct dbg_thread
* thd
;
1762 packet_reply_open(gdbctx
);
1763 packet_reply_add(gdbctx
, "m");
1764 LIST_FOR_EACH_ENTRY(thd
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
1766 packet_reply_val(gdbctx
, thd
->tid
, 4);
1767 if (list_next(&gdbctx
->process
->threads
, &thd
->entry
) != NULL
)
1768 packet_reply_add(gdbctx
, ",");
1770 packet_reply_close(gdbctx
);
1773 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
1777 packet_reply_open(gdbctx
);
1778 packet_reply_add(gdbctx
, "O");
1779 get_process_info(gdbctx
, result
, sizeof(result
));
1780 packet_reply_hex_to_str(gdbctx
, result
);
1781 packet_reply_close(gdbctx
);
1786 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
1788 packet_reply(gdbctx
, "l");
1791 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
1793 packet_reply(gdbctx
, "l");
1798 if (strncmp(gdbctx
->in_packet
, "Attached", gdbctx
->in_packet_len
) == 0)
1799 return packet_reply(gdbctx
, "1");
1802 if (gdbctx
->in_packet_len
== 1)
1804 struct dbg_thread
* thd
;
1805 /* FIXME: doc says 16 bit val ??? */
1806 /* grab first created thread, aka last in list */
1807 assert(gdbctx
->process
&& !list_empty(&gdbctx
->process
->threads
));
1808 thd
= LIST_ENTRY(list_tail(&gdbctx
->process
->threads
), struct dbg_thread
, entry
);
1809 packet_reply_open(gdbctx
);
1810 packet_reply_add(gdbctx
, "QC");
1811 packet_reply_val(gdbctx
, thd
->tid
, 4);
1812 packet_reply_close(gdbctx
);
1817 if (strncmp(gdbctx
->in_packet
, "Offsets", gdbctx
->in_packet_len
) == 0)
1821 snprintf(buf
, sizeof(buf
),
1822 "Text=%08lx;Data=%08lx;Bss=%08lx",
1823 gdbctx
->wine_segs
[0], gdbctx
->wine_segs
[1],
1824 gdbctx
->wine_segs
[2]);
1825 return packet_reply(gdbctx
, buf
);
1829 if (gdbctx
->in_packet_len
> 5 && strncmp(gdbctx
->in_packet
, "Rcmd,", 5) == 0)
1831 return packet_query_remote_command(gdbctx
, gdbctx
->in_packet
+ 5,
1832 gdbctx
->in_packet_len
- 5);
1836 if (strncmp(gdbctx
->in_packet
, "Symbol::", gdbctx
->in_packet_len
) == 0)
1838 if (strncmp(gdbctx
->in_packet
, "Supported", 9) == 0)
1840 packet_reply_open(gdbctx
);
1841 packet_reply_add(gdbctx
, "QStartNoAckMode+;");
1842 packet_reply_add(gdbctx
, "qXfer:libraries:read+;");
1843 packet_reply_add(gdbctx
, "qXfer:threads:read+;");
1844 packet_reply_add(gdbctx
, "qXfer:features:read+;");
1845 packet_reply_close(gdbctx
);
1850 if (gdbctx
->in_packet_len
> 15 &&
1851 strncmp(gdbctx
->in_packet
, "ThreadExtraInfo", 15) == 0 &&
1852 gdbctx
->in_packet
[15] == ',')
1858 tid
= strtol(gdbctx
->in_packet
+ 16, &end
, 16);
1859 if (end
== NULL
) break;
1860 get_thread_info(gdbctx
, tid
, result
, sizeof(result
));
1861 packet_reply_open(gdbctx
);
1862 packet_reply_hex_to_str(gdbctx
, result
);
1863 packet_reply_close(gdbctx
);
1866 if (strncmp(gdbctx
->in_packet
, "TStatus", 7) == 0)
1868 /* Tracepoints not supported */
1869 packet_reply_open(gdbctx
);
1870 packet_reply_close(gdbctx
);
1875 if (sscanf(gdbctx
->in_packet
, "Xfer:libraries:read::%x,%x", &off
, &len
) == 2)
1877 if (!gdbctx
->process
) return packet_error
;
1879 packet_reply_open_xfer(gdbctx
);
1880 packet_query_libraries(gdbctx
);
1881 packet_reply_close_xfer(gdbctx
, off
, len
);
1885 if (sscanf(gdbctx
->in_packet
, "Xfer:threads:read::%x,%x", &off
, &len
) == 2)
1887 if (!gdbctx
->process
) return packet_error
;
1889 packet_reply_open_xfer(gdbctx
);
1890 packet_query_threads(gdbctx
);
1891 packet_reply_close_xfer(gdbctx
, off
, len
);
1895 if (sscanf(gdbctx
->in_packet
, "Xfer:features:read:target.xml:%x,%x", &off
, &len
) == 2)
1897 if (!gdbctx
->process
) return packet_error
;
1898 if (!(cpu
= gdbctx
->process
->be_cpu
)) return packet_error
;
1900 packet_reply_open_xfer(gdbctx
);
1901 packet_query_target_xml(gdbctx
, cpu
);
1902 packet_reply_close_xfer(gdbctx
, off
, len
);
1907 ERR("Unhandled query %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1908 return packet_error
;
1911 static enum packet_return
packet_set(struct gdb_context
* gdbctx
)
1913 if (strncmp(gdbctx
->in_packet
, "StartNoAckMode", 14) == 0)
1915 gdbctx
->no_ack_mode
= TRUE
;
1919 return packet_error
;
1922 static enum packet_return
packet_step(struct gdb_context
* gdbctx
)
1926 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
1927 FIXME("Continue at address %p not supported\n", addr
);
1929 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, TRUE
, -1);
1931 wait_for_debuggee(gdbctx
);
1932 return packet_reply_status(gdbctx
);
1935 static enum packet_return
packet_thread_alive(struct gdb_context
* gdbctx
)
1940 tid
= strtol(gdbctx
->in_packet
, &end
, 16);
1941 if (tid
== -1 || tid
== 0)
1942 return packet_reply_error(gdbctx
, EINVAL
);
1943 if (dbg_get_thread(gdbctx
->process
, tid
) != NULL
)
1945 return packet_reply_error(gdbctx
, ESRCH
);
1948 /* =============================================== *
1949 * P A C K E T I N F R A S T R U C T U R E *
1950 * =============================================== *
1956 enum packet_return (*handler
)(struct gdb_context
* gdbctx
);
1959 static struct packet_entry packet_entries
[] =
1961 {'?', packet_last_signal
},
1962 {'c', packet_continue
},
1963 {'C', packet_continue_signal
},
1964 {'D', packet_detach
},
1965 {'g', packet_read_registers
},
1966 {'G', packet_write_registers
},
1968 {'H', packet_thread
},
1969 {'m', packet_read_memory
},
1970 {'M', packet_write_memory
},
1971 {'p', packet_read_register
},
1972 {'P', packet_write_register
},
1973 {'q', packet_query
},
1976 {'T', packet_thread_alive
},
1977 {'v', packet_verbose
},
1978 {'z', packet_delete_breakpoint
},
1979 {'Z', packet_insert_breakpoint
},
1982 static BOOL
extract_packets(struct gdb_context
* gdbctx
)
1984 char *ptr
, *sum
= gdbctx
->in_buf
, *end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
1985 enum packet_return ret
= packet_error
;
1989 /* ptr points to the beginning ('$') of the current packet
1990 * sum points to the beginning ('#') of the current packet checksum ("#xx")
1991 * len is the length of the current packet data (sum - ptr - 1)
1992 * end points to the end of the received data buffer
1995 while (!gdbctx
->no_ack_mode
&&
1996 (ptr
= memchr(sum
, '$', end
- sum
)) &&
1997 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
1998 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2000 len
= sum
- ptr
- 1;
2003 if (cksum
== checksum(ptr
+ 1, len
))
2005 TRACE("Acking: %s\n", debugstr_an(ptr
, sum
- ptr
));
2006 write(gdbctx
->sock
, "+", 1);
2010 ERR("Nacking: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2011 cksum
, checksum(ptr
+ 1, len
));
2012 write(gdbctx
->sock
, "-", 1);
2016 while ((ret
& packet_last_f
) == 0 &&
2017 (ptr
= memchr(gdbctx
->in_buf
, '$', gdbctx
->in_len
)) &&
2018 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
2019 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2021 if (ptr
!= gdbctx
->in_buf
)
2022 WARN("Ignoring: %s\n", debugstr_an(gdbctx
->in_buf
, ptr
- gdbctx
->in_buf
));
2024 len
= sum
- ptr
- 1;
2027 if (cksum
== checksum(ptr
+ 1, len
))
2029 TRACE("Handling: %s\n", debugstr_an(ptr
, sum
- ptr
));
2032 gdbctx
->in_packet
= ptr
+ 2;
2033 gdbctx
->in_packet_len
= len
- 1;
2034 gdbctx
->in_packet
[gdbctx
->in_packet_len
] = '\0';
2036 for (i
= 0; i
< ARRAY_SIZE(packet_entries
); i
++)
2037 if (packet_entries
[i
].key
== ptr
[1])
2040 if (i
== ARRAY_SIZE(packet_entries
))
2041 WARN("Unhandled: %s\n", debugstr_an(ptr
+ 1, len
));
2042 else if (((ret
= (packet_entries
[i
].handler
)(gdbctx
)) & ~packet_last_f
) == packet_error
)
2043 WARN("Failed: %s\n", debugstr_an(ptr
+ 1, len
));
2045 switch (ret
& ~packet_last_f
)
2047 case packet_error
: packet_reply(gdbctx
, ""); break;
2048 case packet_ok
: packet_reply(gdbctx
, "OK"); break;
2049 case packet_done
: break;
2052 TRACE("Reply: %s\n", debugstr_an(gdbctx
->out_buf
, gdbctx
->out_len
));
2053 i
= write(gdbctx
->sock
, gdbctx
->out_buf
, gdbctx
->out_len
);
2054 assert(i
== gdbctx
->out_len
);
2055 gdbctx
->out_len
= 0;
2058 WARN("Ignoring: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2059 cksum
, checksum(ptr
+ 1, len
));
2061 gdbctx
->in_len
= end
- sum
;
2062 memmove(gdbctx
->in_buf
, sum
, end
- sum
);
2063 end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
2066 return (ret
& packet_last_f
);
2069 static int fetch_data(struct gdb_context
* gdbctx
)
2071 int len
, in_len
= gdbctx
->in_len
;
2073 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2077 if (gdbctx
->in_len
+ STEP
> gdbctx
->in_buf_alloc
)
2078 gdbctx
->in_buf
= packet_realloc(gdbctx
->in_buf
, gdbctx
->in_buf_alloc
+= STEP
);
2080 len
= read(gdbctx
->sock
, gdbctx
->in_buf
+ gdbctx
->in_len
, gdbctx
->in_buf_alloc
- gdbctx
->in_len
- 1);
2081 if (len
<= 0) break;
2082 gdbctx
->in_len
+= len
;
2083 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2084 if (len
< gdbctx
->in_buf_alloc
- gdbctx
->in_len
) break;
2087 gdbctx
->in_buf
[gdbctx
->in_len
] = '\0';
2088 return gdbctx
->in_len
- in_len
;
2091 #define FLAG_NO_START 1
2092 #define FLAG_WITH_XTERM 2
2094 static BOOL
gdb_exec(unsigned port
, unsigned flags
)
2098 const char *gdb_path
, *tmp_path
;
2101 if (!(gdb_path
= getenv("WINE_GDB"))) gdb_path
= "gdb";
2102 if (!(tmp_path
= getenv("TMPDIR"))) tmp_path
= "/tmp";
2103 strcpy(buf
, tmp_path
);
2104 strcat(buf
, "/winegdb.XXXXXX");
2105 fd
= mkstemps(buf
, 0);
2106 if (fd
== -1) return FALSE
;
2107 if ((f
= fdopen(fd
, "w+")) == NULL
) return FALSE
;
2108 fprintf(f
, "target remote localhost:%d\n", ntohs(port
));
2109 fprintf(f
, "set prompt Wine-gdb>\\ \n");
2110 /* gdb 5.1 seems to require it, won't hurt anyway */
2111 fprintf(f
, "sharedlibrary\n");
2112 /* This is needed (but not a decent & final fix)
2113 * Without this, gdb would skip our inter-DLL relay code (because
2114 * we don't have any line number information for the relay code)
2115 * With this, we will stop on first instruction of the stub, and
2116 * reusing step, will get us through the relay stub at the actual
2117 * function we're looking at.
2119 fprintf(f
, "set step-mode on\n");
2120 /* tell gdb to delete this file when done handling it... */
2121 fprintf(f
, "shell rm -f \"%s\"\n", buf
);
2123 if (flags
& FLAG_WITH_XTERM
)
2124 execlp("xterm", "xterm", "-e", gdb_path
, "-x", buf
, NULL
);
2126 execlp(gdb_path
, gdb_path
, "-x", buf
, NULL
);
2127 assert(0); /* never reached */
2131 static BOOL
gdb_startup(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2134 struct sockaddr_in s_addrs
= {0};
2135 socklen_t s_len
= sizeof(s_addrs
);
2136 struct pollfd pollfd
;
2139 /* step 1: create socket for gdb connection request */
2140 if ((sock
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
2142 ERR("Failed to create socket: %s\n", strerror(errno
));
2146 s_addrs
.sin_family
= AF_INET
;
2147 s_addrs
.sin_addr
.s_addr
= INADDR_ANY
;
2148 s_addrs
.sin_port
= htons(port
);
2149 if (bind(sock
, (struct sockaddr
*)&s_addrs
, sizeof(s_addrs
)) == -1)
2152 if (listen(sock
, 1) == -1 || getsockname(sock
, (struct sockaddr
*)&s_addrs
, &s_len
) == -1)
2155 /* step 2: do the process internal creation */
2156 handle_debug_event(gdbctx
);
2158 /* step 3: fire up gdb (if requested) */
2159 if (flags
& FLAG_NO_START
)
2160 fprintf(stderr
, "target remote localhost:%d\n", ntohs(s_addrs
.sin_port
));
2164 case -1: /* error in parent... */
2165 ERR("Failed to start gdb: fork: %s\n", strerror(errno
));
2167 default: /* in parent... success */
2168 signal(SIGINT
, SIG_IGN
);
2170 case 0: /* in child... and alive */
2171 gdb_exec(s_addrs
.sin_port
, flags
);
2172 /* if we're here, exec failed, so report failure */
2176 /* step 4: wait for gdb to connect actually */
2178 pollfd
.events
= POLLIN
;
2181 switch (poll(&pollfd
, 1, -1))
2184 if (pollfd
.revents
& POLLIN
)
2187 gdbctx
->sock
= accept(sock
, (struct sockaddr
*)&s_addrs
, &s_len
);
2188 if (gdbctx
->sock
== -1)
2191 TRACE("connected on %d\n", gdbctx
->sock
);
2192 /* don't keep our small packets too long: send them ASAP back to GDB
2193 * without this, GDB really crawls
2195 setsockopt(gdbctx
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (char*)&dummy
, sizeof(dummy
));
2199 ERR("Timed out connecting to gdb\n");
2202 ERR("Failed to connect to gdb: poll: %s\n", strerror(errno
));
2213 static BOOL
gdb_init_context(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2218 gdbctx
->in_buf
= NULL
;
2219 gdbctx
->in_buf_alloc
= 0;
2221 gdbctx
->out_buf
= NULL
;
2222 gdbctx
->out_buf_alloc
= 0;
2223 gdbctx
->out_len
= 0;
2224 gdbctx
->out_curr_packet
= -1;
2226 gdbctx
->exec_tid
= -1;
2227 gdbctx
->other_tid
= -1;
2228 list_init(&gdbctx
->xpoint_list
);
2229 gdbctx
->process
= NULL
;
2230 gdbctx
->no_ack_mode
= FALSE
;
2231 for (i
= 0; i
< ARRAY_SIZE(gdbctx
->wine_segs
); i
++)
2232 gdbctx
->wine_segs
[i
] = 0;
2234 /* wait for first trap */
2235 while (WaitForDebugEvent(&gdbctx
->de
, INFINITE
))
2237 if (gdbctx
->de
.dwDebugEventCode
== CREATE_PROCESS_DEBUG_EVENT
)
2239 /* this should be the first event we get,
2240 * and the only one of this type */
2241 assert(gdbctx
->process
== NULL
&& gdbctx
->de
.dwProcessId
== dbg_curr_pid
);
2242 /* gdbctx->dwProcessId = pid; */
2243 if (!gdb_startup(gdbctx
, flags
, port
)) return FALSE
;
2245 else if (!handle_debug_event(gdbctx
))
2247 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
2252 static int gdb_remote(unsigned flags
, unsigned port
)
2254 struct pollfd pollfd
;
2255 struct gdb_context gdbctx
;
2258 for (doLoop
= gdb_init_context(&gdbctx
, flags
, port
); doLoop
;)
2260 pollfd
.fd
= gdbctx
.sock
;
2261 pollfd
.events
= POLLIN
;
2264 switch (poll(&pollfd
, 1, -1))
2268 if (pollfd
.revents
& (POLLHUP
| POLLERR
))
2270 ERR("gdb hung up\n");
2271 /* kill also debuggee process - questionnable - */
2272 detach_debuggee(&gdbctx
, TRUE
);
2276 if ((pollfd
.revents
& POLLIN
) && fetch_data(&gdbctx
) > 0)
2278 if (extract_packets(&gdbctx
)) doLoop
= FALSE
;
2282 /* timeout, should never happen (infinite timeout) */
2285 ERR("poll failed: %s\n", strerror(errno
));
2295 int gdb_main(int argc
, char* argv
[])
2298 unsigned gdb_flags
= 0, port
= 0;
2302 while (argc
> 0 && argv
[0][0] == '-')
2304 if (strcmp(argv
[0], "--no-start") == 0)
2306 gdb_flags
|= FLAG_NO_START
;
2310 if (strcmp(argv
[0], "--with-xterm") == 0)
2312 gdb_flags
|= FLAG_WITH_XTERM
;
2316 if (strcmp(argv
[0], "--port") == 0 && argc
> 1)
2318 port
= strtoul(argv
[1], &port_end
, 10);
2321 fprintf(stderr
, "Invalid port: %s\n", argv
[1]);
2324 argc
-= 2; argv
+= 2;
2329 if (dbg_active_attach(argc
, argv
) == start_ok
||
2330 dbg_active_launch(argc
, argv
) == start_ok
)
2331 return gdb_remote(gdb_flags
, port
);
2333 fprintf(stderr
, "GdbProxy mode not supported on this platform\n");