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
= thread
->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
->tid
, 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
;
408 gdbctx
->exec_tid
= de
->dwThreadId
;
409 gdbctx
->other_tid
= de
->dwThreadId
;
410 gdbctx
->de_reply
= DBG_REPLY_LATER
;
412 switch (de
->dwDebugEventCode
)
414 case CREATE_PROCESS_DEBUG_EVENT
:
415 gdbctx
->process
= dbg_add_process(&be_process_gdbproxy_io
, de
->dwProcessId
,
416 de
->u
.CreateProcessInfo
.hProcess
);
417 if (!gdbctx
->process
)
420 memory_get_string_indirect(gdbctx
->process
,
421 de
->u
.CreateProcessInfo
.lpImageName
,
422 de
->u
.CreateProcessInfo
.fUnicode
,
423 u
.buffer
, ARRAY_SIZE(u
.buffer
));
424 dbg_set_process_name(gdbctx
->process
, u
.buffer
);
426 fprintf(stderr
, "%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n",
427 de
->dwProcessId
, de
->dwThreadId
,
428 dbg_W2A(u
.buffer
, -1),
429 de
->u
.CreateProcessInfo
.lpImageName
,
430 de
->u
.CreateProcessInfo
.lpStartAddress
,
431 de
->u
.CreateProcessInfo
.dwDebugInfoFileOffset
,
432 de
->u
.CreateProcessInfo
.nDebugInfoSize
);
434 /* de->u.CreateProcessInfo.lpStartAddress; */
435 if (!dbg_init(gdbctx
->process
->handle
, u
.buffer
, TRUE
))
436 ERR("Couldn't initiate DbgHelp\n");
438 fprintf(stderr
, "%04x:%04x: create thread I @%p\n", de
->dwProcessId
,
439 de
->dwThreadId
, de
->u
.CreateProcessInfo
.lpStartAddress
);
441 dbg_add_thread(gdbctx
->process
, de
->dwThreadId
,
442 de
->u
.CreateProcessInfo
.hThread
,
443 de
->u
.CreateProcessInfo
.lpThreadLocalBase
);
446 case LOAD_DLL_DEBUG_EVENT
:
447 memory_get_string_indirect(gdbctx
->process
,
448 de
->u
.LoadDll
.lpImageName
,
449 de
->u
.LoadDll
.fUnicode
,
450 u
.buffer
, ARRAY_SIZE(u
.buffer
));
451 fprintf(stderr
, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
452 de
->dwProcessId
, de
->dwThreadId
,
453 dbg_W2A(u
.buffer
, -1),
454 de
->u
.LoadDll
.lpBaseOfDll
,
455 de
->u
.LoadDll
.dwDebugInfoFileOffset
,
456 de
->u
.LoadDll
.nDebugInfoSize
);
457 dbg_load_module(gdbctx
->process
->handle
, de
->u
.LoadDll
.hFile
, u
.buffer
,
458 (DWORD_PTR
)de
->u
.LoadDll
.lpBaseOfDll
, 0);
461 case UNLOAD_DLL_DEBUG_EVENT
:
462 fprintf(stderr
, "%08x:%08x: unload DLL @%p\n",
463 de
->dwProcessId
, de
->dwThreadId
, de
->u
.UnloadDll
.lpBaseOfDll
);
464 SymUnloadModule(gdbctx
->process
->handle
,
465 (DWORD_PTR
)de
->u
.UnloadDll
.lpBaseOfDll
);
468 case EXCEPTION_DEBUG_EVENT
:
469 TRACE("%08x:%08x: exception code=0x%08x\n", de
->dwProcessId
,
470 de
->dwThreadId
, de
->u
.Exception
.ExceptionRecord
.ExceptionCode
);
472 if (handle_exception(gdbctx
, &de
->u
.Exception
))
476 case CREATE_THREAD_DEBUG_EVENT
:
477 fprintf(stderr
, "%08x:%08x: create thread D @%p\n", de
->dwProcessId
,
478 de
->dwThreadId
, de
->u
.CreateThread
.lpStartAddress
);
480 dbg_add_thread(gdbctx
->process
,
482 de
->u
.CreateThread
.hThread
,
483 de
->u
.CreateThread
.lpThreadLocalBase
);
486 case EXIT_THREAD_DEBUG_EVENT
:
487 fprintf(stderr
, "%08x:%08x: exit thread (%u)\n",
488 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitThread
.dwExitCode
);
489 if ((thread
= dbg_get_thread(gdbctx
->process
, de
->dwThreadId
)))
490 dbg_del_thread(thread
);
493 case EXIT_PROCESS_DEBUG_EVENT
:
494 fprintf(stderr
, "%08x:%08x: exit process (%u)\n",
495 de
->dwProcessId
, de
->dwThreadId
, de
->u
.ExitProcess
.dwExitCode
);
497 dbg_del_process(gdbctx
->process
);
498 gdbctx
->process
= NULL
;
501 case OUTPUT_DEBUG_STRING_EVENT
:
502 memory_get_string(gdbctx
->process
,
503 de
->u
.DebugString
.lpDebugStringData
, TRUE
,
504 de
->u
.DebugString
.fUnicode
, u
.bufferA
, sizeof(u
.bufferA
));
505 fprintf(stderr
, "%08x:%08x: output debug string (%s)\n",
506 de
->dwProcessId
, de
->dwThreadId
, debugstr_a(u
.bufferA
));
510 fprintf(stderr
, "%08x:%08x: rip error=%u type=%u\n", de
->dwProcessId
,
511 de
->dwThreadId
, de
->u
.RipInfo
.dwError
, de
->u
.RipInfo
.dwType
);
515 FIXME("%08x:%08x: unknown event (%u)\n",
516 de
->dwProcessId
, de
->dwThreadId
, de
->dwDebugEventCode
);
519 LIST_FOR_EACH_ENTRY(thread
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
521 if (!thread
->suspended
) SuspendThread(thread
->handle
);
522 thread
->suspended
= TRUE
;
528 static void handle_step_or_continue(struct gdb_context
* gdbctx
, int tid
, BOOL step
, int sig
)
530 struct dbg_process
*process
= gdbctx
->process
;
531 struct dbg_thread
*thread
;
533 if (tid
== 0) tid
= gdbctx
->de
.dwThreadId
;
534 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
536 if (tid
!= -1 && thread
->tid
!= tid
) continue;
537 if (!thread
->suspended
) continue;
538 thread
->suspended
= FALSE
;
540 if (process
->pid
== gdbctx
->de
.dwProcessId
&& thread
->tid
== gdbctx
->de
.dwThreadId
)
541 gdbctx
->de_reply
= (sig
== -1 ? DBG_CONTINUE
: DBG_EXCEPTION_NOT_HANDLED
);
543 dbg_thread_set_single_step(thread
, step
);
544 ResumeThread(thread
->handle
);
548 static BOOL
check_for_interrupt(struct gdb_context
* gdbctx
)
550 struct pollfd pollfd
;
554 pollfd
.fd
= gdbctx
->sock
;
555 pollfd
.events
= POLLIN
;
558 if ((ret
= poll(&pollfd
, 1, 0)) == 1) {
559 ret
= read(gdbctx
->sock
, &pkt
, 1);
561 ERR("read failed\n");
565 ERR("Unexpected break packet %#02x\n", pkt
);
569 } else if (ret
== -1) {
570 ERR("poll failed\n");
575 static void wait_for_debuggee(struct gdb_context
* gdbctx
)
577 if (gdbctx
->de
.dwDebugEventCode
)
578 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, gdbctx
->de_reply
);
582 if (!WaitForDebugEvent(&gdbctx
->de
, 10))
584 if (GetLastError() == ERROR_SEM_TIMEOUT
)
586 if (check_for_interrupt(gdbctx
)) {
587 if (!DebugBreakProcess(gdbctx
->process
->handle
)) {
588 ERR("Failed to break into debuggee\n");
591 WaitForDebugEvent(&gdbctx
->de
, INFINITE
);
599 if (!handle_debug_event(gdbctx
))
601 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
605 static void detach_debuggee(struct gdb_context
* gdbctx
, BOOL kill
)
607 handle_step_or_continue(gdbctx
, -1, FALSE
, -1);
609 if (gdbctx
->de
.dwDebugEventCode
)
610 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
613 DebugActiveProcessStop(gdbctx
->process
->pid
);
614 dbg_del_process(gdbctx
->process
);
615 gdbctx
->process
= NULL
;
618 static void get_process_info(struct gdb_context
* gdbctx
, char* buffer
, size_t len
)
622 if (!GetExitCodeProcess(gdbctx
->process
->handle
, &status
))
624 strcpy(buffer
, "Unknown process");
627 if (status
== STILL_ACTIVE
)
629 strcpy(buffer
, "Running");
632 snprintf(buffer
, len
, "Terminated (%u)", status
);
634 switch (GetPriorityClass(gdbctx
->process
->handle
))
637 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
638 case ABOVE_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", above normal priority"); break;
640 #ifdef BELOW_NORMAL_PRIORITY_CLASS
641 case BELOW_NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", below normal priority"); break;
643 case HIGH_PRIORITY_CLASS
: strcat(buffer
, ", high priority"); break;
644 case IDLE_PRIORITY_CLASS
: strcat(buffer
, ", idle priority"); break;
645 case NORMAL_PRIORITY_CLASS
: strcat(buffer
, ", normal priority"); break;
646 case REALTIME_PRIORITY_CLASS
: strcat(buffer
, ", realtime priority"); break;
648 strcat(buffer
, "\n");
651 static void get_thread_info(struct gdb_context
* gdbctx
, unsigned tid
,
652 char* buffer
, size_t len
)
654 struct dbg_thread
* thd
;
658 /* FIXME: use the size of buffer */
659 thd
= dbg_get_thread(gdbctx
->process
, tid
);
662 strcpy(buffer
, "No information");
665 if (GetExitCodeThread(thd
->handle
, &status
))
667 if (status
== STILL_ACTIVE
)
669 /* FIXME: this is a bit brutal... some nicer way shall be found */
670 switch (status
= SuspendThread(thd
->handle
))
673 case 0: strcpy(buffer
, "Running"); break;
674 default: snprintf(buffer
, len
, "Suspended (%u)", status
- 1);
676 ResumeThread(thd
->handle
);
679 snprintf(buffer
, len
, "Terminated (exit code = %u)", status
);
683 strcpy(buffer
, "Unknown threadID");
685 switch (prio
= GetThreadPriority(thd
->handle
))
687 case THREAD_PRIORITY_ERROR_RETURN
: break;
688 case THREAD_PRIORITY_ABOVE_NORMAL
: strcat(buffer
, ", priority +1 above normal"); break;
689 case THREAD_PRIORITY_BELOW_NORMAL
: strcat(buffer
, ", priority -1 below normal"); break;
690 case THREAD_PRIORITY_HIGHEST
: strcat(buffer
, ", priority +2 above normal"); break;
691 case THREAD_PRIORITY_LOWEST
: strcat(buffer
, ", priority -2 below normal"); break;
692 case THREAD_PRIORITY_IDLE
: strcat(buffer
, ", priority idle"); break;
693 case THREAD_PRIORITY_NORMAL
: strcat(buffer
, ", priority normal"); break;
694 case THREAD_PRIORITY_TIME_CRITICAL
: strcat(buffer
, ", priority time-critical"); break;
695 default: snprintf(buffer
+ strlen(buffer
), len
- strlen(buffer
), ", priority = %d", prio
);
697 assert(strlen(buffer
) < len
);
700 /* =============================================== *
701 * P A C K E T U T I L S *
702 * =============================================== *
705 enum packet_return
{packet_error
= 0x00, packet_ok
= 0x01, packet_done
= 0x02,
706 packet_last_f
= 0x80};
708 static char* packet_realloc(char* buf
, int size
)
711 return HeapAlloc(GetProcessHeap(), 0, size
);
712 return HeapReAlloc(GetProcessHeap(), 0, buf
, size
);
716 static void packet_reply_grow(struct gdb_context
* gdbctx
, size_t size
)
718 if (gdbctx
->out_buf_alloc
< gdbctx
->out_len
+ size
)
720 gdbctx
->out_buf_alloc
= ((gdbctx
->out_len
+ size
) / 32 + 1) * 32;
721 gdbctx
->out_buf
= packet_realloc(gdbctx
->out_buf
, gdbctx
->out_buf_alloc
);
725 static void packet_reply_hex_to(struct gdb_context
* gdbctx
, const void* src
, int len
)
727 packet_reply_grow(gdbctx
, len
* 2);
728 hex_to(&gdbctx
->out_buf
[gdbctx
->out_len
], src
, len
);
729 gdbctx
->out_len
+= len
* 2;
732 static inline void packet_reply_hex_to_str(struct gdb_context
* gdbctx
, const char* src
)
734 packet_reply_hex_to(gdbctx
, src
, strlen(src
));
737 static void packet_reply_val(struct gdb_context
* gdbctx
, unsigned long val
, int len
)
741 shift
= (len
- 1) * 8;
742 packet_reply_grow(gdbctx
, len
* 2);
743 for (i
= 0; i
< len
; i
++, shift
-= 8)
745 gdbctx
->out_buf
[gdbctx
->out_len
++] = hex_to0((val
>> (shift
+ 4)) & 0x0F);
746 gdbctx
->out_buf
[gdbctx
->out_len
++] = hex_to0((val
>> shift
) & 0x0F);
750 static inline void packet_reply_add(struct gdb_context
* gdbctx
, const char* str
)
752 int len
= strlen(str
);
753 packet_reply_grow(gdbctx
, len
);
754 memcpy(&gdbctx
->out_buf
[gdbctx
->out_len
], str
, len
);
755 gdbctx
->out_len
+= len
;
758 static void packet_reply_open(struct gdb_context
* gdbctx
)
760 assert(gdbctx
->out_curr_packet
== -1);
761 packet_reply_add(gdbctx
, "$");
762 gdbctx
->out_curr_packet
= gdbctx
->out_len
;
765 static void packet_reply_close(struct gdb_context
* gdbctx
)
770 plen
= gdbctx
->out_len
- gdbctx
->out_curr_packet
;
771 packet_reply_add(gdbctx
, "#");
772 cksum
= checksum(&gdbctx
->out_buf
[gdbctx
->out_curr_packet
], plen
);
773 packet_reply_hex_to(gdbctx
, &cksum
, 1);
774 gdbctx
->out_curr_packet
= -1;
777 static void packet_reply_open_xfer(struct gdb_context
* gdbctx
)
779 packet_reply_open(gdbctx
);
780 packet_reply_add(gdbctx
, "m");
783 static void packet_reply_close_xfer(struct gdb_context
* gdbctx
, int off
, int len
)
785 int begin
= gdbctx
->out_curr_packet
+ 1;
788 if (begin
+ off
< gdbctx
->out_len
)
790 gdbctx
->out_len
-= off
;
791 memmove(gdbctx
->out_buf
+ begin
, gdbctx
->out_buf
+ begin
+ off
, gdbctx
->out_len
);
795 gdbctx
->out_buf
[gdbctx
->out_curr_packet
] = 'l';
796 gdbctx
->out_len
= gdbctx
->out_curr_packet
+ 1;
799 plen
= gdbctx
->out_len
- begin
;
800 if (len
>= 0 && plen
> len
) gdbctx
->out_len
-= (plen
- len
);
801 else gdbctx
->out_buf
[gdbctx
->out_curr_packet
] = 'l';
803 packet_reply_close(gdbctx
);
806 static enum packet_return
packet_reply(struct gdb_context
* gdbctx
, const char* packet
)
808 packet_reply_open(gdbctx
);
810 assert(strchr(packet
, '$') == NULL
&& strchr(packet
, '#') == NULL
);
812 packet_reply_add(gdbctx
, packet
);
814 packet_reply_close(gdbctx
);
819 static enum packet_return
packet_reply_error(struct gdb_context
* gdbctx
, int error
)
821 packet_reply_open(gdbctx
);
823 packet_reply_add(gdbctx
, "E");
824 packet_reply_val(gdbctx
, error
, 1);
826 packet_reply_close(gdbctx
);
831 static inline void packet_reply_register_hex_to(struct gdb_context
* gdbctx
, dbg_ctx_t
* ctx
, unsigned idx
)
833 const struct gdb_register
*cpu_register_map
= gdbctx
->process
->be_cpu
->gdb_register_map
;
834 packet_reply_hex_to(gdbctx
, cpu_register_ptr(gdbctx
, ctx
, idx
), cpu_register_map
[idx
].length
);
837 /* =============================================== *
838 * P A C K E T H A N D L E R S *
839 * =============================================== *
842 static void packet_reply_status_xpoints(struct gdb_context
* gdbctx
, struct dbg_thread
*thread
,
845 struct dbg_process
*process
= thread
->process
;
846 struct backend_cpu
*cpu
= process
->be_cpu
;
847 struct gdb_xpoint
*x
;
849 LIST_FOR_EACH_ENTRY(x
, &gdbctx
->xpoint_list
, struct gdb_xpoint
, entry
)
851 if (x
->pid
!= process
->pid
|| x
->tid
!= thread
->tid
)
853 if (!cpu
->is_watchpoint_set(ctx
, x
->value
))
855 if (x
->type
== be_xpoint_watch_write
)
857 packet_reply_add(gdbctx
, "watch:");
858 packet_reply_val(gdbctx
, (unsigned long)x
->addr
, sizeof(x
->addr
));
859 packet_reply_add(gdbctx
, ";");
861 if (x
->type
== be_xpoint_watch_read
)
863 packet_reply_add(gdbctx
, "rwatch:");
864 packet_reply_val(gdbctx
, (unsigned long)x
->addr
, sizeof(x
->addr
));
865 packet_reply_add(gdbctx
, ";");
870 static enum packet_return
packet_reply_status(struct gdb_context
* gdbctx
)
872 struct dbg_process
*process
= gdbctx
->process
;
873 struct dbg_thread
*thread
;
874 struct backend_cpu
*backend
;
878 switch (gdbctx
->de
.dwDebugEventCode
)
881 if (!process
) return packet_error
;
882 if (!(backend
= process
->be_cpu
)) return packet_error
;
883 if (!(thread
= dbg_get_thread(process
, gdbctx
->de
.dwThreadId
)) ||
884 !backend
->get_context(thread
->handle
, &ctx
))
887 packet_reply_open(gdbctx
);
888 packet_reply_add(gdbctx
, "T");
889 packet_reply_val(gdbctx
, signal_from_debug_event(&gdbctx
->de
), 1);
890 packet_reply_add(gdbctx
, "thread:");
891 packet_reply_val(gdbctx
, gdbctx
->de
.dwThreadId
, 4);
892 packet_reply_add(gdbctx
, ";");
893 packet_reply_status_xpoints(gdbctx
, thread
, &ctx
);
895 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
897 packet_reply_val(gdbctx
, i
, 1);
898 packet_reply_add(gdbctx
, ":");
899 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
900 packet_reply_add(gdbctx
, ";");
903 packet_reply_close(gdbctx
);
906 case EXIT_PROCESS_DEBUG_EVENT
:
907 packet_reply_open(gdbctx
);
908 packet_reply_add(gdbctx
, "W");
909 packet_reply_val(gdbctx
, gdbctx
->de
.u
.ExitProcess
.dwExitCode
, 4);
910 packet_reply_close(gdbctx
);
911 return packet_done
| packet_last_f
;
915 static enum packet_return
packet_last_signal(struct gdb_context
* gdbctx
)
917 assert(gdbctx
->in_packet_len
== 0);
918 return packet_reply_status(gdbctx
);
921 static enum packet_return
packet_continue(struct gdb_context
* gdbctx
)
925 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
926 FIXME("Continue at address %p not supported\n", addr
);
928 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, -1);
930 wait_for_debuggee(gdbctx
);
931 return packet_reply_status(gdbctx
);
934 static enum packet_return
packet_verbose_cont(struct gdb_context
* gdbctx
)
936 char *buf
= gdbctx
->in_packet
, *end
= gdbctx
->in_packet
+ gdbctx
->in_packet_len
;
938 if (gdbctx
->in_packet
[4] == '?')
940 packet_reply_open(gdbctx
);
941 packet_reply_add(gdbctx
, "vCont");
942 packet_reply_add(gdbctx
, ";c");
943 packet_reply_add(gdbctx
, ";C");
944 packet_reply_add(gdbctx
, ";s");
945 packet_reply_add(gdbctx
, ";S");
946 packet_reply_close(gdbctx
);
950 while (buf
< end
&& (buf
= memchr(buf
+ 1, ';', end
- buf
- 1)))
952 int tid
= -1, sig
= -1;
955 switch ((action
= buf
[1]))
965 if (sscanf(buf
, ";%*c%2x", &sig
) <= 0 ||
966 sig
!= signal_from_debug_event(&gdbctx
->de
))
974 if (buf
< end
&& *buf
== ':' && (n
= sscanf(buf
, ":%x", &tid
)) <= 0)
977 handle_step_or_continue(gdbctx
, tid
, action
== 's' || action
== 'S', sig
);
980 wait_for_debuggee(gdbctx
);
981 return packet_reply_status(gdbctx
);
984 static enum packet_return
packet_verbose(struct gdb_context
* gdbctx
)
986 if (gdbctx
->in_packet_len
>= 4 && !memcmp(gdbctx
->in_packet
, "Cont", 4))
988 return packet_verbose_cont(gdbctx
);
991 if (gdbctx
->in_packet_len
== 14 && !memcmp(gdbctx
->in_packet
, "MustReplyEmpty", 14))
992 return packet_reply(gdbctx
, "");
997 static enum packet_return
packet_continue_signal(struct gdb_context
* gdbctx
)
1002 if ((n
= sscanf(gdbctx
->in_packet
, "%x;%p", &sig
, &addr
)) == 2)
1003 FIXME("Continue at address %p not supported\n", addr
);
1004 if (n
< 1) return packet_error
;
1006 if (sig
!= signal_from_debug_event(&gdbctx
->de
))
1008 ERR("Changing signals is not supported.\n");
1009 return packet_error
;
1012 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, FALSE
, sig
);
1014 wait_for_debuggee(gdbctx
);
1015 return packet_reply_status(gdbctx
);
1018 static enum packet_return
packet_delete_breakpoint(struct gdb_context
* gdbctx
)
1020 struct dbg_process
*process
= gdbctx
->process
;
1021 struct dbg_thread
*thread
;
1022 struct backend_cpu
*cpu
;
1023 struct gdb_xpoint
*x
;
1029 if (!process
) return packet_error
;
1030 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1032 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1033 return packet_error
;
1036 return packet_error
;
1038 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1040 if (!cpu
->get_context(thread
->handle
, &ctx
))
1042 if ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_exec
, addr
, size
)))
1043 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1044 if ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_read
, addr
, size
)))
1045 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1046 if ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, thread
, be_xpoint_watch_write
, addr
, size
)))
1047 gdbctx_delete_xpoint(gdbctx
, thread
, &ctx
, x
);
1048 cpu
->set_context(thread
->handle
, &ctx
);
1051 while ((type
== '1') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_exec
, addr
, size
)))
1052 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1053 while ((type
== '2' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_read
, addr
, size
)))
1054 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1055 while ((type
== '3' || type
== '4') && (x
= gdb_find_xpoint(gdbctx
, NULL
, be_xpoint_watch_write
, addr
, size
)))
1056 gdbctx_delete_xpoint(gdbctx
, NULL
, NULL
, x
);
1061 static enum packet_return
packet_insert_breakpoint(struct gdb_context
* gdbctx
)
1063 struct dbg_process
*process
= gdbctx
->process
;
1064 struct dbg_thread
*thread
;
1065 struct backend_cpu
*cpu
;
1071 if (!process
) return packet_error
;
1072 if (!(cpu
= process
->be_cpu
)) return packet_error
;
1074 if (memchr(gdbctx
->in_packet
, ';', gdbctx
->in_packet_len
))
1076 FIXME("breakpoint commands not supported\n");
1077 return packet_error
;
1080 if (sscanf(gdbctx
->in_packet
, "%c,%p,%x", &type
, &addr
, &size
) < 3)
1081 return packet_error
;
1084 return packet_error
;
1086 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1088 if (!cpu
->get_context(thread
->handle
, &ctx
))
1091 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_exec
, addr
, size
);
1092 if (type
== '2' || type
== '4')
1093 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_read
, addr
, size
);
1094 if (type
== '3' || type
== '4')
1095 gdbctx_insert_xpoint(gdbctx
, thread
, &ctx
, be_xpoint_watch_write
, addr
, size
);
1096 cpu
->set_context(thread
->handle
, &ctx
);
1102 static enum packet_return
packet_detach(struct gdb_context
* gdbctx
)
1104 detach_debuggee(gdbctx
, FALSE
);
1105 return packet_ok
| packet_last_f
;
1108 static enum packet_return
packet_read_registers(struct gdb_context
* gdbctx
)
1110 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1111 struct backend_cpu
*backend
;
1115 if (!thread
) return packet_error
;
1116 if (!thread
->process
) return packet_error
;
1117 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1119 if (!backend
->get_context(thread
->handle
, &ctx
))
1120 return packet_error
;
1122 packet_reply_open(gdbctx
);
1123 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1124 packet_reply_register_hex_to(gdbctx
, &ctx
, i
);
1126 packet_reply_close(gdbctx
);
1130 static enum packet_return
packet_write_registers(struct gdb_context
* gdbctx
)
1132 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1133 struct backend_cpu
*backend
;
1138 if (!thread
) return packet_error
;
1139 if (!thread
->process
) return packet_error
;
1140 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1142 if (!backend
->get_context(thread
->handle
, &ctx
))
1143 return packet_error
;
1145 if (gdbctx
->in_packet_len
< backend
->gdb_num_regs
* 2)
1146 return packet_error
;
1148 ptr
= gdbctx
->in_packet
;
1149 for (i
= 0; i
< backend
->gdb_num_regs
; i
++)
1150 cpu_register_hex_from(gdbctx
, &ctx
, i
, &ptr
);
1152 if (!backend
->set_context(thread
->handle
, &ctx
))
1154 ERR("Failed to set context for tid %04x, error %u\n", thread
->tid
, GetLastError());
1155 return packet_error
;
1161 static enum packet_return
packet_kill(struct gdb_context
* gdbctx
)
1163 detach_debuggee(gdbctx
, TRUE
);
1164 return packet_ok
| packet_last_f
;
1167 static enum packet_return
packet_thread(struct gdb_context
* gdbctx
)
1169 switch (gdbctx
->in_packet
[0])
1172 if (sscanf(gdbctx
->in_packet
, "c%x", &gdbctx
->exec_tid
) == 1)
1174 return packet_error
;
1176 if (sscanf(gdbctx
->in_packet
, "g%x", &gdbctx
->other_tid
) == 1)
1178 return packet_error
;
1180 FIXME("Unknown thread sub-command %c\n", gdbctx
->in_packet
[0]);
1181 return packet_error
;
1185 static enum packet_return
packet_read_memory(struct gdb_context
* gdbctx
)
1188 unsigned int len
, blk_len
, nread
;
1192 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2) return packet_error
;
1193 if (len
<= 0) return packet_error
;
1194 TRACE("Read %u bytes at %p\n", len
, addr
);
1195 for (nread
= 0; nread
< len
; nread
+= r
, addr
+= r
)
1197 blk_len
= min(sizeof(buffer
), len
- nread
);
1198 if (!gdbctx
->process
->process_io
->read(gdbctx
->process
->handle
, addr
,
1199 buffer
, blk_len
, &r
) || r
== 0)
1201 /* fail at first address, return error */
1202 if (nread
== 0) return packet_reply_error(gdbctx
, EFAULT
);
1203 /* something has already been read, return partial information */
1206 if (nread
== 0) packet_reply_open(gdbctx
);
1207 packet_reply_hex_to(gdbctx
, buffer
, r
);
1209 packet_reply_close(gdbctx
);
1213 static enum packet_return
packet_write_memory(struct gdb_context
* gdbctx
)
1216 unsigned int len
, blk_len
;
1221 ptr
= memchr(gdbctx
->in_packet
, ':', gdbctx
->in_packet_len
);
1224 ERR("Cannot find ':' in %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1225 return packet_error
;
1229 if (sscanf(gdbctx
->in_packet
, "%p,%x", &addr
, &len
) != 2)
1231 ERR("Failed to parse %s\n", debugstr_a(gdbctx
->in_packet
));
1232 return packet_error
;
1234 if (ptr
- gdbctx
->in_packet
+ len
* 2 != gdbctx
->in_packet_len
)
1236 ERR("Length %u does not match packet length %u\n",
1237 (int)(ptr
- gdbctx
->in_packet
) + len
* 2, gdbctx
->in_packet_len
);
1238 return packet_error
;
1240 TRACE("Write %u bytes at %p\n", len
, addr
);
1243 blk_len
= min(sizeof(buffer
), len
);
1244 hex_from(buffer
, ptr
, blk_len
);
1245 if (!gdbctx
->process
->process_io
->write(gdbctx
->process
->handle
, addr
, buffer
, blk_len
, &w
) ||
1252 return packet_ok
; /* FIXME: error while writing ? */
1255 static enum packet_return
packet_read_register(struct gdb_context
* gdbctx
)
1257 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1258 struct backend_cpu
*backend
;
1262 if (!thread
) return packet_error
;
1263 if (!thread
->process
) return packet_error
;
1264 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1266 if (!backend
->get_context(thread
->handle
, &ctx
))
1267 return packet_error
;
1269 if (sscanf(gdbctx
->in_packet
, "%zx", ®
) != 1)
1270 return packet_error
;
1271 if (reg
>= backend
->gdb_num_regs
)
1273 WARN("Unhandled register %zu\n", reg
);
1274 return packet_error
;
1277 TRACE("%zu => %s\n", reg
, wine_dbgstr_longlong(cpu_register(gdbctx
, &ctx
, reg
)));
1279 packet_reply_open(gdbctx
);
1280 packet_reply_register_hex_to(gdbctx
, &ctx
, reg
);
1281 packet_reply_close(gdbctx
);
1285 static enum packet_return
packet_write_register(struct gdb_context
* gdbctx
)
1287 struct dbg_thread
*thread
= dbg_thread_from_tid(gdbctx
, gdbctx
->other_tid
);
1288 struct backend_cpu
*backend
;
1293 if (!thread
) return packet_error
;
1294 if (!thread
->process
) return packet_error
;
1295 if (!(backend
= thread
->process
->be_cpu
)) return packet_error
;
1297 if (!backend
->get_context(thread
->handle
, &ctx
))
1298 return packet_error
;
1300 if (!(ptr
= strchr(gdbctx
->in_packet
, '=')))
1301 return packet_error
;
1304 if (sscanf(gdbctx
->in_packet
, "%zx", ®
) != 1)
1305 return packet_error
;
1306 if (reg
>= backend
->gdb_num_regs
)
1308 /* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
1309 * it wouldn't matter too much, and it fakes our support for all regs
1311 WARN("Unhandled register %zu\n", reg
);
1315 TRACE("%zu <= %s\n", reg
, debugstr_an(ptr
, (int)(gdbctx
->in_packet_len
- (ptr
- gdbctx
->in_packet
))));
1317 cpu_register_hex_from(gdbctx
, &ctx
, reg
, (const char**)&ptr
);
1318 if (!backend
->set_context(thread
->handle
, &ctx
))
1320 ERR("Failed to set context for tid %04x, error %u\n", thread
->tid
, GetLastError());
1321 return packet_error
;
1327 static void packet_query_monitor_wnd_helper(struct gdb_context
* gdbctx
, HWND hWnd
, int indent
)
1335 if (!GetClassNameA(hWnd
, clsName
, sizeof(clsName
)))
1336 strcpy(clsName
, "-- Unknown --");
1337 if (!GetWindowTextA(hWnd
, wndName
, sizeof(wndName
)))
1338 strcpy(wndName
, "-- Empty --");
1340 packet_reply_open(gdbctx
);
1341 packet_reply_add(gdbctx
, "O");
1342 snprintf(buffer
, sizeof(buffer
),
1343 "%*s%04lx%*s%-17.17s %08x %0*lx %.14s\n",
1344 indent
, "", (ULONG_PTR
)hWnd
, 13 - indent
, "",
1345 clsName
, GetWindowLongW(hWnd
, GWL_STYLE
),
1346 ADDRWIDTH
, (ULONG_PTR
)GetWindowLongPtrW(hWnd
, GWLP_WNDPROC
),
1348 packet_reply_hex_to_str(gdbctx
, buffer
);
1349 packet_reply_close(gdbctx
);
1351 if ((child
= GetWindow(hWnd
, GW_CHILD
)) != 0)
1352 packet_query_monitor_wnd_helper(gdbctx
, child
, indent
+ 1);
1353 } while ((hWnd
= GetWindow(hWnd
, GW_HWNDNEXT
)) != 0);
1356 static void packet_query_monitor_wnd(struct gdb_context
* gdbctx
, int len
, const char* str
)
1360 /* we do the output in several 'O' packets, with the last one being just OK for
1361 * marking the end of the output */
1362 packet_reply_open(gdbctx
);
1363 packet_reply_add(gdbctx
, "O");
1364 snprintf(buffer
, sizeof(buffer
),
1365 "%-16.16s %-17.17s %-8.8s %s\n",
1366 "hwnd", "Class Name", " Style", " WndProc Text");
1367 packet_reply_hex_to_str(gdbctx
, buffer
);
1368 packet_reply_close(gdbctx
);
1370 /* FIXME: could also add a pmt to this command in str... */
1371 packet_query_monitor_wnd_helper(gdbctx
, GetDesktopWindow(), 0);
1372 packet_reply(gdbctx
, "OK");
1375 static void packet_query_monitor_process(struct gdb_context
* gdbctx
, int len
, const char* str
)
1377 HANDLE snap
= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
, 0);
1378 char buffer
[31+MAX_PATH
];
1380 PROCESSENTRY32 entry
;
1383 if (snap
== INVALID_HANDLE_VALUE
)
1386 entry
.dwSize
= sizeof(entry
);
1387 ok
= Process32First(snap
, &entry
);
1389 /* we do the output in several 'O' packets, with the last one being just OK for
1390 * marking the end of the output */
1392 packet_reply_open(gdbctx
);
1393 packet_reply_add(gdbctx
, "O");
1394 snprintf(buffer
, sizeof(buffer
),
1395 " %-8.8s %-8.8s %-8.8s %s\n",
1396 "pid", "threads", "parent", "executable");
1397 packet_reply_hex_to_str(gdbctx
, buffer
);
1398 packet_reply_close(gdbctx
);
1403 if (entry
.th32ProcessID
== gdbctx
->process
->pid
) deco
= '>';
1404 packet_reply_open(gdbctx
);
1405 packet_reply_add(gdbctx
, "O");
1406 snprintf(buffer
, sizeof(buffer
),
1407 "%c%08x %-8d %08x '%s'\n",
1408 deco
, entry
.th32ProcessID
, entry
.cntThreads
,
1409 entry
.th32ParentProcessID
, entry
.szExeFile
);
1410 packet_reply_hex_to_str(gdbctx
, buffer
);
1411 packet_reply_close(gdbctx
);
1412 ok
= Process32Next(snap
, &entry
);
1415 packet_reply(gdbctx
, "OK");
1418 static void packet_query_monitor_mem(struct gdb_context
* gdbctx
, int len
, const char* str
)
1420 MEMORY_BASIC_INFORMATION mbi
;
1427 /* we do the output in several 'O' packets, with the last one being just OK for
1428 * marking the end of the output */
1429 packet_reply_open(gdbctx
);
1430 packet_reply_add(gdbctx
, "O");
1431 packet_reply_hex_to_str(gdbctx
, "Address Size State Type RWX\n");
1432 packet_reply_close(gdbctx
);
1434 while (VirtualQueryEx(gdbctx
->process
->handle
, addr
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
))
1438 case MEM_COMMIT
: state
= "commit "; break;
1439 case MEM_FREE
: state
= "free "; break;
1440 case MEM_RESERVE
: state
= "reserve"; break;
1441 default: state
= "??? "; break;
1443 if (mbi
.State
!= MEM_FREE
)
1447 case MEM_IMAGE
: type
= "image "; break;
1448 case MEM_MAPPED
: type
= "mapped "; break;
1449 case MEM_PRIVATE
: type
= "private"; break;
1450 case 0: type
= " "; break;
1451 default: type
= "??? "; break;
1453 memset(prot
, ' ' , sizeof(prot
)-1);
1454 prot
[sizeof(prot
)-1] = '\0';
1455 if (mbi
.AllocationProtect
& (PAGE_READONLY
|PAGE_READWRITE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
))
1457 if (mbi
.AllocationProtect
& (PAGE_READWRITE
|PAGE_EXECUTE_READWRITE
))
1459 if (mbi
.AllocationProtect
& (PAGE_WRITECOPY
|PAGE_EXECUTE_WRITECOPY
))
1461 if (mbi
.AllocationProtect
& (PAGE_EXECUTE
|PAGE_EXECUTE_READ
|PAGE_EXECUTE_READWRITE
))
1469 packet_reply_open(gdbctx
);
1470 snprintf(buffer
, sizeof(buffer
), "%0*lx %0*lx %s %s %s\n",
1471 (unsigned)sizeof(void*), (DWORD_PTR
)addr
,
1472 (unsigned)sizeof(void*), mbi
.RegionSize
, state
, type
, prot
);
1473 packet_reply_add(gdbctx
, "O");
1474 packet_reply_hex_to_str(gdbctx
, buffer
);
1475 packet_reply_close(gdbctx
);
1477 if (addr
+ mbi
.RegionSize
< addr
) /* wrap around ? */
1479 addr
+= mbi
.RegionSize
;
1481 packet_reply(gdbctx
, "OK");
1489 void (*handler
)(struct gdb_context
*, int, const char*);
1492 {0, "wnd", 3, packet_query_monitor_wnd
},
1493 {0, "window", 6, packet_query_monitor_wnd
},
1494 {0, "proc", 4, packet_query_monitor_process
},
1495 {0, "process", 7, packet_query_monitor_process
},
1496 {0, "mem", 3, packet_query_monitor_mem
},
1500 static enum packet_return
packet_query_remote_command(struct gdb_context
* gdbctx
,
1501 const char* hxcmd
, size_t len
)
1504 struct query_detail
* qd
;
1506 assert((len
& 1) == 0 && len
< 2 * sizeof(buffer
));
1508 hex_from(buffer
, hxcmd
, len
);
1510 for (qd
= query_details
; qd
->name
!= NULL
; qd
++)
1512 if (len
< qd
->len
|| strncmp(buffer
, qd
->name
, qd
->len
) != 0) continue;
1513 if (!qd
->with_arg
&& len
!= qd
->len
) continue;
1515 (qd
->handler
)(gdbctx
, len
- qd
->len
, buffer
+ qd
->len
);
1518 return packet_reply_error(gdbctx
, EINVAL
);
1521 static BOOL CALLBACK
packet_query_libraries_cb(PCSTR mod_name
, DWORD64 base
, PVOID ctx
)
1523 struct gdb_context
* gdbctx
= ctx
;
1524 MEMORY_BASIC_INFORMATION mbi
;
1525 IMAGE_SECTION_HEADER
*sec
;
1526 IMAGE_DOS_HEADER
*dos
= NULL
;
1527 IMAGE_NT_HEADERS
*nth
= NULL
;
1528 IMAGEHLP_MODULE64 mod
;
1533 mod
.SizeOfStruct
= sizeof(mod
);
1534 SymGetModuleInfo64(gdbctx
->process
->handle
, base
, &mod
);
1536 packet_reply_add(gdbctx
, "<library name=\"");
1537 if (strcmp(mod
.LoadedImageName
, "[vdso].so") == 0)
1538 packet_reply_add(gdbctx
, "linux-vdso.so.1");
1539 else if (mod
.LoadedImageName
[0] == '/')
1540 packet_reply_add(gdbctx
, mod
.LoadedImageName
);
1543 UNICODE_STRING nt_name
;
1544 ANSI_STRING ansi_name
;
1545 char *unix_path
, *tmp
;
1547 RtlInitAnsiString(&ansi_name
, mod
.LoadedImageName
);
1548 RtlAnsiStringToUnicodeString(&nt_name
, &ansi_name
, TRUE
);
1550 if ((unix_path
= wine_get_unix_file_name(nt_name
.Buffer
)))
1552 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) &&
1553 is_wow64
&& (tmp
= strstr(unix_path
, "system32")))
1554 memcpy(tmp
, "syswow64", 8);
1555 packet_reply_add(gdbctx
, unix_path
);
1558 packet_reply_add(gdbctx
, mod
.LoadedImageName
);
1560 HeapFree(GetProcessHeap(), 0, unix_path
);
1561 RtlFreeUnicodeString(&nt_name
);
1563 packet_reply_add(gdbctx
, "\">");
1565 size
= sizeof(buffer
);
1566 if (VirtualQueryEx(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, &mbi
, sizeof(mbi
)) >= sizeof(mbi
) &&
1567 mbi
.Type
== MEM_IMAGE
&& mbi
.State
!= MEM_FREE
)
1569 if (ReadProcessMemory(gdbctx
->process
->handle
, (void *)(UINT_PTR
)mod
.BaseOfImage
, buffer
, size
, &size
) &&
1570 size
>= sizeof(IMAGE_DOS_HEADER
))
1571 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1573 if (dos
&& dos
->e_magic
== IMAGE_DOS_SIGNATURE
&& dos
->e_lfanew
< size
)
1574 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1576 if (nth
&& memcmp(&nth
->Signature
, "PE\0\0", 4))
1580 if (!nth
) memset(buffer
, 0, sizeof(buffer
));
1582 /* if the module is not PE we have cleared buffer with 0, this makes
1583 * the following computation valid in all cases. */
1584 dos
= (IMAGE_DOS_HEADER
*)buffer
;
1585 nth
= (IMAGE_NT_HEADERS
*)(buffer
+ dos
->e_lfanew
);
1586 if (IsWow64Process(gdbctx
->process
->handle
, &is_wow64
) && is_wow64
)
1587 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS32
*)nth
);
1589 sec
= IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS64
*)nth
);
1591 for (i
= 0; i
< max(nth
->FileHeader
.NumberOfSections
, 1); ++i
)
1593 if ((char *)(sec
+ i
) >= buffer
+ size
) break;
1594 packet_reply_add(gdbctx
, "<segment address=\"0x");
1595 packet_reply_val(gdbctx
, mod
.BaseOfImage
+ sec
[i
].VirtualAddress
, sizeof(unsigned long));
1596 packet_reply_add(gdbctx
, "\"/>");
1599 packet_reply_add(gdbctx
, "</library>");
1604 static void packet_query_libraries(struct gdb_context
* gdbctx
)
1608 /* this will resynchronize builtin dbghelp's internal ELF module list */
1609 SymLoadModule(gdbctx
->process
->handle
, 0, 0, 0, 0, 0);
1611 packet_reply_add(gdbctx
, "<library-list>");
1612 opt
= SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, TRUE
);
1613 SymEnumerateModules64(gdbctx
->process
->handle
, packet_query_libraries_cb
, gdbctx
);
1614 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES
, opt
);
1615 packet_reply_add(gdbctx
, "</library-list>");
1618 static void packet_query_threads(struct gdb_context
* gdbctx
)
1620 struct dbg_process
* process
= gdbctx
->process
;
1621 struct dbg_thread
* thread
;
1623 packet_reply_add(gdbctx
, "<threads>");
1624 LIST_FOR_EACH_ENTRY(thread
, &process
->threads
, struct dbg_thread
, entry
)
1626 packet_reply_add(gdbctx
, "<thread ");
1627 packet_reply_add(gdbctx
, "id=\"");
1628 packet_reply_val(gdbctx
, thread
->tid
, 4);
1629 packet_reply_add(gdbctx
, "\" name=\"");
1630 packet_reply_add(gdbctx
, thread
->name
);
1631 packet_reply_add(gdbctx
, "\"/>");
1633 packet_reply_add(gdbctx
, "</threads>");
1636 static void packet_query_target_xml(struct gdb_context
* gdbctx
, struct backend_cpu
* cpu
)
1638 const char* feature_prefix
= NULL
;
1639 const char* feature
= NULL
;
1643 packet_reply_add(gdbctx
, "<target>");
1644 switch (cpu
->machine
)
1646 case IMAGE_FILE_MACHINE_AMD64
:
1647 packet_reply_add(gdbctx
, "<architecture>i386:x86-64</architecture>");
1648 feature_prefix
= "org.gnu.gdb.i386.";
1650 case IMAGE_FILE_MACHINE_I386
:
1651 packet_reply_add(gdbctx
, "<architecture>i386</architecture>");
1652 feature_prefix
= "org.gnu.gdb.i386.";
1654 case IMAGE_FILE_MACHINE_ARMNT
:
1655 packet_reply_add(gdbctx
, "<architecture>arm</architecture>");
1656 feature_prefix
= "org.gnu.gdb.arm.";
1658 case IMAGE_FILE_MACHINE_ARM64
:
1659 packet_reply_add(gdbctx
, "<architecture>aarch64</architecture>");
1660 feature_prefix
= "org.gnu.gdb.aarch64.";
1664 for (i
= 0; i
< cpu
->gdb_num_regs
; ++i
)
1666 if (cpu
->gdb_register_map
[i
].feature
)
1668 if (feature
) packet_reply_add(gdbctx
, "</feature>");
1669 feature
= cpu
->gdb_register_map
[i
].feature
;
1671 packet_reply_add(gdbctx
, "<feature name=\"");
1672 if (feature_prefix
) packet_reply_add(gdbctx
, feature_prefix
);
1673 packet_reply_add(gdbctx
, feature
);
1674 packet_reply_add(gdbctx
, "\">");
1676 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1677 strcmp(feature
, "core") == 0)
1678 packet_reply_add(gdbctx
, "<flags id=\"i386_eflags\" size=\"4\">"
1679 "<field name=\"CF\" start=\"0\" end=\"0\"/>"
1680 "<field name=\"\" start=\"1\" end=\"1\"/>"
1681 "<field name=\"PF\" start=\"2\" end=\"2\"/>"
1682 "<field name=\"AF\" start=\"4\" end=\"4\"/>"
1683 "<field name=\"ZF\" start=\"6\" end=\"6\"/>"
1684 "<field name=\"SF\" start=\"7\" end=\"7\"/>"
1685 "<field name=\"TF\" start=\"8\" end=\"8\"/>"
1686 "<field name=\"IF\" start=\"9\" end=\"9\"/>"
1687 "<field name=\"DF\" start=\"10\" end=\"10\"/>"
1688 "<field name=\"OF\" start=\"11\" end=\"11\"/>"
1689 "<field name=\"NT\" start=\"14\" end=\"14\"/>"
1690 "<field name=\"RF\" start=\"16\" end=\"16\"/>"
1691 "<field name=\"VM\" start=\"17\" end=\"17\"/>"
1692 "<field name=\"AC\" start=\"18\" end=\"18\"/>"
1693 "<field name=\"VIF\" start=\"19\" end=\"19\"/>"
1694 "<field name=\"VIP\" start=\"20\" end=\"20\"/>"
1695 "<field name=\"ID\" start=\"21\" end=\"21\"/>"
1698 if (strcmp(feature_prefix
, "org.gnu.gdb.i386.") == 0 &&
1699 strcmp(feature
, "sse") == 0)
1700 packet_reply_add(gdbctx
, "<vector id=\"v4f\" type=\"ieee_single\" count=\"4\"/>"
1701 "<vector id=\"v2d\" type=\"ieee_double\" count=\"2\"/>"
1702 "<vector id=\"v16i8\" type=\"int8\" count=\"16\"/>"
1703 "<vector id=\"v8i16\" type=\"int16\" count=\"8\"/>"
1704 "<vector id=\"v4i32\" type=\"int32\" count=\"4\"/>"
1705 "<vector id=\"v2i64\" type=\"int64\" count=\"2\"/>"
1706 "<union id=\"vec128\">"
1707 "<field name=\"v4_float\" type=\"v4f\"/>"
1708 "<field name=\"v2_double\" type=\"v2d\"/>"
1709 "<field name=\"v16_int8\" type=\"v16i8\"/>"
1710 "<field name=\"v8_int16\" type=\"v8i16\"/>"
1711 "<field name=\"v4_int32\" type=\"v4i32\"/>"
1712 "<field name=\"v2_int64\" type=\"v2i64\"/>"
1713 "<field name=\"uint128\" type=\"uint128\"/>"
1715 "<flags id=\"i386_mxcsr\" size=\"4\">"
1716 "<field name=\"IE\" start=\"0\" end=\"0\"/>"
1717 "<field name=\"DE\" start=\"1\" end=\"1\"/>"
1718 "<field name=\"ZE\" start=\"2\" end=\"2\"/>"
1719 "<field name=\"OE\" start=\"3\" end=\"3\"/>"
1720 "<field name=\"UE\" start=\"4\" end=\"4\"/>"
1721 "<field name=\"PE\" start=\"5\" end=\"5\"/>"
1722 "<field name=\"DAZ\" start=\"6\" end=\"6\"/>"
1723 "<field name=\"IM\" start=\"7\" end=\"7\"/>"
1724 "<field name=\"DM\" start=\"8\" end=\"8\"/>"
1725 "<field name=\"ZM\" start=\"9\" end=\"9\"/>"
1726 "<field name=\"OM\" start=\"10\" end=\"10\"/>"
1727 "<field name=\"UM\" start=\"11\" end=\"11\"/>"
1728 "<field name=\"PM\" start=\"12\" end=\"12\"/>"
1729 "<field name=\"FZ\" start=\"15\" end=\"15\"/>"
1733 snprintf(buffer
, ARRAY_SIZE(buffer
), "<reg name=\"%s\" bitsize=\"%zu\"",
1734 cpu
->gdb_register_map
[i
].name
, 8 * cpu
->gdb_register_map
[i
].length
);
1735 packet_reply_add(gdbctx
, buffer
);
1737 if (cpu
->gdb_register_map
[i
].type
)
1739 packet_reply_add(gdbctx
, " type=\"");
1740 packet_reply_add(gdbctx
, cpu
->gdb_register_map
[i
].type
);
1741 packet_reply_add(gdbctx
, "\"");
1744 packet_reply_add(gdbctx
, "/>");
1747 if (feature
) packet_reply_add(gdbctx
, "</feature>");
1748 packet_reply_add(gdbctx
, "</target>");
1751 static enum packet_return
packet_query(struct gdb_context
* gdbctx
)
1754 struct backend_cpu
*cpu
;
1756 switch (gdbctx
->in_packet
[0])
1759 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
1761 struct dbg_thread
* thd
;
1763 packet_reply_open(gdbctx
);
1764 packet_reply_add(gdbctx
, "m");
1765 LIST_FOR_EACH_ENTRY(thd
, &gdbctx
->process
->threads
, struct dbg_thread
, entry
)
1767 packet_reply_val(gdbctx
, thd
->tid
, 4);
1768 if (list_next(&gdbctx
->process
->threads
, &thd
->entry
) != NULL
)
1769 packet_reply_add(gdbctx
, ",");
1771 packet_reply_close(gdbctx
);
1774 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
1778 packet_reply_open(gdbctx
);
1779 packet_reply_add(gdbctx
, "O");
1780 get_process_info(gdbctx
, result
, sizeof(result
));
1781 packet_reply_hex_to_str(gdbctx
, result
);
1782 packet_reply_close(gdbctx
);
1787 if (strncmp(gdbctx
->in_packet
+ 1, "ThreadInfo", gdbctx
->in_packet_len
- 1) == 0)
1789 packet_reply(gdbctx
, "l");
1792 else if (strncmp(gdbctx
->in_packet
+ 1, "ProcessInfo", gdbctx
->in_packet_len
- 1) == 0)
1794 packet_reply(gdbctx
, "l");
1799 if (strncmp(gdbctx
->in_packet
, "Attached", gdbctx
->in_packet_len
) == 0)
1800 return packet_reply(gdbctx
, "1");
1803 if (gdbctx
->in_packet_len
== 1)
1805 struct dbg_thread
* thd
;
1806 /* FIXME: doc says 16 bit val ??? */
1807 /* grab first created thread, aka last in list */
1808 assert(gdbctx
->process
&& !list_empty(&gdbctx
->process
->threads
));
1809 thd
= LIST_ENTRY(list_tail(&gdbctx
->process
->threads
), struct dbg_thread
, entry
);
1810 packet_reply_open(gdbctx
);
1811 packet_reply_add(gdbctx
, "QC");
1812 packet_reply_val(gdbctx
, thd
->tid
, 4);
1813 packet_reply_close(gdbctx
);
1818 if (strncmp(gdbctx
->in_packet
, "Offsets", gdbctx
->in_packet_len
) == 0)
1822 snprintf(buf
, sizeof(buf
),
1823 "Text=%08lx;Data=%08lx;Bss=%08lx",
1824 gdbctx
->wine_segs
[0], gdbctx
->wine_segs
[1],
1825 gdbctx
->wine_segs
[2]);
1826 return packet_reply(gdbctx
, buf
);
1830 if (gdbctx
->in_packet_len
> 5 && strncmp(gdbctx
->in_packet
, "Rcmd,", 5) == 0)
1832 return packet_query_remote_command(gdbctx
, gdbctx
->in_packet
+ 5,
1833 gdbctx
->in_packet_len
- 5);
1837 if (strncmp(gdbctx
->in_packet
, "Symbol::", gdbctx
->in_packet_len
) == 0)
1839 if (strncmp(gdbctx
->in_packet
, "Supported", 9) == 0)
1841 packet_reply_open(gdbctx
);
1842 packet_reply_add(gdbctx
, "QStartNoAckMode+;");
1843 packet_reply_add(gdbctx
, "qXfer:libraries:read+;");
1844 packet_reply_add(gdbctx
, "qXfer:threads:read+;");
1845 packet_reply_add(gdbctx
, "qXfer:features:read+;");
1846 packet_reply_close(gdbctx
);
1851 if (gdbctx
->in_packet_len
> 15 &&
1852 strncmp(gdbctx
->in_packet
, "ThreadExtraInfo", 15) == 0 &&
1853 gdbctx
->in_packet
[15] == ',')
1859 tid
= strtol(gdbctx
->in_packet
+ 16, &end
, 16);
1860 if (end
== NULL
) break;
1861 get_thread_info(gdbctx
, tid
, result
, sizeof(result
));
1862 packet_reply_open(gdbctx
);
1863 packet_reply_hex_to_str(gdbctx
, result
);
1864 packet_reply_close(gdbctx
);
1867 if (strncmp(gdbctx
->in_packet
, "TStatus", 7) == 0)
1869 /* Tracepoints not supported */
1870 packet_reply_open(gdbctx
);
1871 packet_reply_close(gdbctx
);
1876 if (sscanf(gdbctx
->in_packet
, "Xfer:libraries:read::%x,%x", &off
, &len
) == 2)
1878 if (!gdbctx
->process
) return packet_error
;
1880 packet_reply_open_xfer(gdbctx
);
1881 packet_query_libraries(gdbctx
);
1882 packet_reply_close_xfer(gdbctx
, off
, len
);
1886 if (sscanf(gdbctx
->in_packet
, "Xfer:threads:read::%x,%x", &off
, &len
) == 2)
1888 if (!gdbctx
->process
) return packet_error
;
1890 packet_reply_open_xfer(gdbctx
);
1891 packet_query_threads(gdbctx
);
1892 packet_reply_close_xfer(gdbctx
, off
, len
);
1896 if (sscanf(gdbctx
->in_packet
, "Xfer:features:read:target.xml:%x,%x", &off
, &len
) == 2)
1898 if (!gdbctx
->process
) return packet_error
;
1899 if (!(cpu
= gdbctx
->process
->be_cpu
)) return packet_error
;
1901 packet_reply_open_xfer(gdbctx
);
1902 packet_query_target_xml(gdbctx
, cpu
);
1903 packet_reply_close_xfer(gdbctx
, off
, len
);
1908 ERR("Unhandled query %s\n", debugstr_an(gdbctx
->in_packet
, gdbctx
->in_packet_len
));
1909 return packet_error
;
1912 static enum packet_return
packet_set(struct gdb_context
* gdbctx
)
1914 if (strncmp(gdbctx
->in_packet
, "StartNoAckMode", 14) == 0)
1916 gdbctx
->no_ack_mode
= TRUE
;
1920 return packet_error
;
1923 static enum packet_return
packet_step(struct gdb_context
* gdbctx
)
1927 if (sscanf(gdbctx
->in_packet
, "%p", &addr
) == 1)
1928 FIXME("Continue at address %p not supported\n", addr
);
1930 handle_step_or_continue(gdbctx
, gdbctx
->exec_tid
, TRUE
, -1);
1932 wait_for_debuggee(gdbctx
);
1933 return packet_reply_status(gdbctx
);
1936 static enum packet_return
packet_thread_alive(struct gdb_context
* gdbctx
)
1941 tid
= strtol(gdbctx
->in_packet
, &end
, 16);
1942 if (tid
== -1 || tid
== 0)
1943 return packet_reply_error(gdbctx
, EINVAL
);
1944 if (dbg_get_thread(gdbctx
->process
, tid
) != NULL
)
1946 return packet_reply_error(gdbctx
, ESRCH
);
1949 /* =============================================== *
1950 * P A C K E T I N F R A S T R U C T U R E *
1951 * =============================================== *
1957 enum packet_return (*handler
)(struct gdb_context
* gdbctx
);
1960 static struct packet_entry packet_entries
[] =
1962 {'?', packet_last_signal
},
1963 {'c', packet_continue
},
1964 {'C', packet_continue_signal
},
1965 {'D', packet_detach
},
1966 {'g', packet_read_registers
},
1967 {'G', packet_write_registers
},
1969 {'H', packet_thread
},
1970 {'m', packet_read_memory
},
1971 {'M', packet_write_memory
},
1972 {'p', packet_read_register
},
1973 {'P', packet_write_register
},
1974 {'q', packet_query
},
1977 {'T', packet_thread_alive
},
1978 {'v', packet_verbose
},
1979 {'z', packet_delete_breakpoint
},
1980 {'Z', packet_insert_breakpoint
},
1983 static BOOL
extract_packets(struct gdb_context
* gdbctx
)
1985 char *ptr
, *sum
= gdbctx
->in_buf
, *end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
1986 enum packet_return ret
= packet_error
;
1990 /* ptr points to the beginning ('$') of the current packet
1991 * sum points to the beginning ('#') of the current packet checksum ("#xx")
1992 * len is the length of the current packet data (sum - ptr - 1)
1993 * end points to the end of the received data buffer
1996 while (!gdbctx
->no_ack_mode
&&
1997 (ptr
= memchr(sum
, '$', end
- sum
)) &&
1998 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
1999 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2001 len
= sum
- ptr
- 1;
2004 if (cksum
== checksum(ptr
+ 1, len
))
2006 TRACE("Acking: %s\n", debugstr_an(ptr
, sum
- ptr
));
2007 write(gdbctx
->sock
, "+", 1);
2011 ERR("Nacking: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2012 cksum
, checksum(ptr
+ 1, len
));
2013 write(gdbctx
->sock
, "-", 1);
2017 while ((ret
& packet_last_f
) == 0 &&
2018 (ptr
= memchr(gdbctx
->in_buf
, '$', gdbctx
->in_len
)) &&
2019 (sum
= memchr(ptr
, '#', end
- ptr
)) &&
2020 (end
- sum
>= 3) && sscanf(sum
, "#%02x", &cksum
) == 1)
2022 if (ptr
!= gdbctx
->in_buf
)
2023 WARN("Ignoring: %s\n", debugstr_an(gdbctx
->in_buf
, ptr
- gdbctx
->in_buf
));
2025 len
= sum
- ptr
- 1;
2028 if (cksum
== checksum(ptr
+ 1, len
))
2030 TRACE("Handling: %s\n", debugstr_an(ptr
, sum
- ptr
));
2033 gdbctx
->in_packet
= ptr
+ 2;
2034 gdbctx
->in_packet_len
= len
- 1;
2035 gdbctx
->in_packet
[gdbctx
->in_packet_len
] = '\0';
2037 for (i
= 0; i
< ARRAY_SIZE(packet_entries
); i
++)
2038 if (packet_entries
[i
].key
== ptr
[1])
2041 if (i
== ARRAY_SIZE(packet_entries
))
2042 WARN("Unhandled: %s\n", debugstr_an(ptr
+ 1, len
));
2043 else if (((ret
= (packet_entries
[i
].handler
)(gdbctx
)) & ~packet_last_f
) == packet_error
)
2044 WARN("Failed: %s\n", debugstr_an(ptr
+ 1, len
));
2046 switch (ret
& ~packet_last_f
)
2048 case packet_error
: packet_reply(gdbctx
, ""); break;
2049 case packet_ok
: packet_reply(gdbctx
, "OK"); break;
2050 case packet_done
: break;
2053 TRACE("Reply: %s\n", debugstr_an(gdbctx
->out_buf
, gdbctx
->out_len
));
2054 i
= write(gdbctx
->sock
, gdbctx
->out_buf
, gdbctx
->out_len
);
2055 assert(i
== gdbctx
->out_len
);
2056 gdbctx
->out_len
= 0;
2059 WARN("Ignoring: %s (checksum: %d != %d)\n", debugstr_an(ptr
, sum
- ptr
),
2060 cksum
, checksum(ptr
+ 1, len
));
2062 gdbctx
->in_len
= end
- sum
;
2063 memmove(gdbctx
->in_buf
, sum
, end
- sum
);
2064 end
= gdbctx
->in_buf
+ gdbctx
->in_len
;
2067 return (ret
& packet_last_f
);
2070 static int fetch_data(struct gdb_context
* gdbctx
)
2072 int len
, in_len
= gdbctx
->in_len
;
2074 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2078 if (gdbctx
->in_len
+ STEP
> gdbctx
->in_buf_alloc
)
2079 gdbctx
->in_buf
= packet_realloc(gdbctx
->in_buf
, gdbctx
->in_buf_alloc
+= STEP
);
2081 len
= read(gdbctx
->sock
, gdbctx
->in_buf
+ gdbctx
->in_len
, gdbctx
->in_buf_alloc
- gdbctx
->in_len
- 1);
2082 if (len
<= 0) break;
2083 gdbctx
->in_len
+= len
;
2084 assert(gdbctx
->in_len
<= gdbctx
->in_buf_alloc
);
2085 if (len
< gdbctx
->in_buf_alloc
- gdbctx
->in_len
) break;
2088 gdbctx
->in_buf
[gdbctx
->in_len
] = '\0';
2089 return gdbctx
->in_len
- in_len
;
2092 #define FLAG_NO_START 1
2093 #define FLAG_WITH_XTERM 2
2095 static BOOL
gdb_exec(unsigned port
, unsigned flags
)
2099 const char *gdb_path
, *tmp_path
;
2102 if (!(gdb_path
= getenv("WINE_GDB"))) gdb_path
= "gdb";
2103 if (!(tmp_path
= getenv("TMPDIR"))) tmp_path
= "/tmp";
2104 strcpy(buf
, tmp_path
);
2105 strcat(buf
, "/winegdb.XXXXXX");
2106 fd
= mkstemps(buf
, 0);
2107 if (fd
== -1) return FALSE
;
2108 if ((f
= fdopen(fd
, "w+")) == NULL
) return FALSE
;
2109 fprintf(f
, "target remote localhost:%d\n", ntohs(port
));
2110 fprintf(f
, "set prompt Wine-gdb>\\ \n");
2111 /* gdb 5.1 seems to require it, won't hurt anyway */
2112 fprintf(f
, "sharedlibrary\n");
2113 /* This is needed (but not a decent & final fix)
2114 * Without this, gdb would skip our inter-DLL relay code (because
2115 * we don't have any line number information for the relay code)
2116 * With this, we will stop on first instruction of the stub, and
2117 * reusing step, will get us through the relay stub at the actual
2118 * function we're looking at.
2120 fprintf(f
, "set step-mode on\n");
2121 /* tell gdb to delete this file when done handling it... */
2122 fprintf(f
, "shell rm -f \"%s\"\n", buf
);
2124 if (flags
& FLAG_WITH_XTERM
)
2125 execlp("xterm", "xterm", "-e", gdb_path
, "-x", buf
, NULL
);
2127 execlp(gdb_path
, gdb_path
, "-x", buf
, NULL
);
2128 assert(0); /* never reached */
2132 static BOOL
gdb_startup(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2135 struct sockaddr_in s_addrs
= {0};
2136 socklen_t s_len
= sizeof(s_addrs
);
2137 struct pollfd pollfd
;
2140 /* step 1: create socket for gdb connection request */
2141 if ((sock
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
2143 ERR("Failed to create socket: %s\n", strerror(errno
));
2147 s_addrs
.sin_family
= AF_INET
;
2148 s_addrs
.sin_addr
.s_addr
= INADDR_ANY
;
2149 s_addrs
.sin_port
= htons(port
);
2150 if (bind(sock
, (struct sockaddr
*)&s_addrs
, sizeof(s_addrs
)) == -1)
2153 if (listen(sock
, 1) == -1 || getsockname(sock
, (struct sockaddr
*)&s_addrs
, &s_len
) == -1)
2156 /* step 2: do the process internal creation */
2157 handle_debug_event(gdbctx
);
2159 /* step 3: fire up gdb (if requested) */
2160 if (flags
& FLAG_NO_START
)
2161 fprintf(stderr
, "target remote localhost:%d\n", ntohs(s_addrs
.sin_port
));
2165 case -1: /* error in parent... */
2166 ERR("Failed to start gdb: fork: %s\n", strerror(errno
));
2168 default: /* in parent... success */
2169 signal(SIGINT
, SIG_IGN
);
2171 case 0: /* in child... and alive */
2172 gdb_exec(s_addrs
.sin_port
, flags
);
2173 /* if we're here, exec failed, so report failure */
2177 /* step 4: wait for gdb to connect actually */
2179 pollfd
.events
= POLLIN
;
2182 switch (poll(&pollfd
, 1, -1))
2185 if (pollfd
.revents
& POLLIN
)
2188 gdbctx
->sock
= accept(sock
, (struct sockaddr
*)&s_addrs
, &s_len
);
2189 if (gdbctx
->sock
== -1)
2192 TRACE("connected on %d\n", gdbctx
->sock
);
2193 /* don't keep our small packets too long: send them ASAP back to GDB
2194 * without this, GDB really crawls
2196 setsockopt(gdbctx
->sock
, IPPROTO_TCP
, TCP_NODELAY
, (char*)&dummy
, sizeof(dummy
));
2200 ERR("Timed out connecting to gdb\n");
2203 ERR("Failed to connect to gdb: poll: %s\n", strerror(errno
));
2214 static BOOL
gdb_init_context(struct gdb_context
* gdbctx
, unsigned flags
, unsigned port
)
2219 gdbctx
->in_buf
= NULL
;
2220 gdbctx
->in_buf_alloc
= 0;
2222 gdbctx
->out_buf
= NULL
;
2223 gdbctx
->out_buf_alloc
= 0;
2224 gdbctx
->out_len
= 0;
2225 gdbctx
->out_curr_packet
= -1;
2227 gdbctx
->exec_tid
= -1;
2228 gdbctx
->other_tid
= -1;
2229 list_init(&gdbctx
->xpoint_list
);
2230 gdbctx
->process
= NULL
;
2231 gdbctx
->no_ack_mode
= FALSE
;
2232 for (i
= 0; i
< ARRAY_SIZE(gdbctx
->wine_segs
); i
++)
2233 gdbctx
->wine_segs
[i
] = 0;
2235 /* wait for first trap */
2236 while (WaitForDebugEvent(&gdbctx
->de
, INFINITE
))
2238 if (gdbctx
->de
.dwDebugEventCode
== CREATE_PROCESS_DEBUG_EVENT
)
2240 /* this should be the first event we get,
2241 * and the only one of this type */
2242 assert(gdbctx
->process
== NULL
&& gdbctx
->de
.dwProcessId
== dbg_curr_pid
);
2243 /* gdbctx->dwProcessId = pid; */
2244 if (!gdb_startup(gdbctx
, flags
, port
)) return FALSE
;
2246 else if (!handle_debug_event(gdbctx
))
2248 ContinueDebugEvent(gdbctx
->de
.dwProcessId
, gdbctx
->de
.dwThreadId
, DBG_CONTINUE
);
2253 static int gdb_remote(unsigned flags
, unsigned port
)
2255 struct pollfd pollfd
;
2256 struct gdb_context gdbctx
;
2259 for (doLoop
= gdb_init_context(&gdbctx
, flags
, port
); doLoop
;)
2261 pollfd
.fd
= gdbctx
.sock
;
2262 pollfd
.events
= POLLIN
;
2265 switch (poll(&pollfd
, 1, -1))
2269 if (pollfd
.revents
& (POLLHUP
| POLLERR
))
2271 ERR("gdb hung up\n");
2272 /* kill also debuggee process - questionnable - */
2273 detach_debuggee(&gdbctx
, TRUE
);
2277 if ((pollfd
.revents
& POLLIN
) && fetch_data(&gdbctx
) > 0)
2279 if (extract_packets(&gdbctx
)) doLoop
= FALSE
;
2283 /* timeout, should never happen (infinite timeout) */
2286 ERR("poll failed: %s\n", strerror(errno
));
2296 int gdb_main(int argc
, char* argv
[])
2299 unsigned gdb_flags
= 0, port
= 0;
2303 while (argc
> 0 && argv
[0][0] == '-')
2305 if (strcmp(argv
[0], "--no-start") == 0)
2307 gdb_flags
|= FLAG_NO_START
;
2311 if (strcmp(argv
[0], "--with-xterm") == 0)
2313 gdb_flags
|= FLAG_WITH_XTERM
;
2317 if (strcmp(argv
[0], "--port") == 0 && argc
> 1)
2319 port
= strtoul(argv
[1], &port_end
, 10);
2322 fprintf(stderr
, "Invalid port: %s\n", argv
[1]);
2325 argc
-= 2; argv
+= 2;
2330 if (dbg_active_attach(argc
, argv
) == start_ok
||
2331 dbg_active_launch(argc
, argv
) == start_ok
)
2332 return gdb_remote(gdb_flags
, port
);
2334 fprintf(stderr
, "GdbProxy mode not supported on this platform\n");