d3d11: Implement d3d11_device_context_ClearUnorderedAccessViewFloat().
[wine.git] / programs / winedbg / gdbproxy.c
blob478e0d16fe0f7c97f86317cfa74cf75bd66c361a
1 /*
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
27 #include "config.h"
28 #include "wine/port.h"
30 #include <assert.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #ifdef HAVE_SYS_POLL_H
38 # include <sys/poll.h>
39 #endif
40 #ifdef HAVE_SYS_WAIT_H
41 # include <sys/wait.h>
42 #endif
43 #ifdef HAVE_SYS_SOCKET_H
44 # include <sys/socket.h>
45 #endif
46 #ifdef HAVE_NETINET_IN_H
47 # include <netinet/in.h>
48 #endif
49 #ifdef HAVE_NETINET_TCP_H
50 # include <netinet/tcp.h>
51 #endif
52 #ifdef HAVE_UNISTD_H
53 # include <unistd.h>
54 #endif
56 /* if we don't have poll support on this system
57 * we won't provide gdb proxy support here...
59 #ifdef HAVE_POLL
61 #include "debugger.h"
63 #include "windef.h"
64 #include "winbase.h"
65 #include "tlhelp32.h"
66 #include "wine/exception.h"
67 #include "wine/debug.h"
69 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
71 struct gdb_xpoint
73 struct list entry;
74 int pid;
75 int tid;
76 enum be_xpoint_type type;
77 void *addr;
78 int size;
79 unsigned long value;
82 struct gdb_context
84 /* gdb information */
85 int sock;
86 /* incoming buffer */
87 char* in_buf;
88 int in_buf_alloc;
89 int in_len;
90 /* split into individual packet */
91 char* in_packet;
92 int in_packet_len;
93 /* outgoing buffer */
94 char* out_buf;
95 int out_buf_alloc;
96 int out_len;
97 int out_curr_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 */
103 DEBUG_EVENT de;
104 DWORD de_reply;
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) */
109 BOOL no_ack_mode;
112 static void gdbctx_delete_xpoint(struct gdb_context *gdbctx, struct dbg_thread *thread,
113 dbg_ctx_t *ctx, struct gdb_xpoint *x)
115 struct dbg_process *process = gdbctx->process;
116 struct backend_cpu *cpu = process->be_cpu;
118 if (!cpu->remove_Xpoint(process->handle, process->process_io, ctx, x->type, x->addr, x->value, x->size))
119 ERR("%04x:%04x: Couldn't remove breakpoint at:%p/%x type:%d\n", process->pid, thread ? thread->tid : ~0, x->addr, x->size, x->type);
121 list_remove(&x->entry);
122 HeapFree(GetProcessHeap(), 0, x);
125 static void gdbctx_insert_xpoint(struct gdb_context *gdbctx, struct dbg_thread *thread,
126 dbg_ctx_t *ctx, enum be_xpoint_type type, void *addr, int size)
128 struct dbg_process *process = thread->process;
129 struct backend_cpu *cpu = process->be_cpu;
130 struct gdb_xpoint *x;
131 unsigned long value;
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);
136 return;
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);
142 return;
145 x->pid = process->pid;
146 x->tid = thread->tid;
147 x->type = type;
148 x->addr = addr;
149 x->size = size;
150 x->value = value;
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))
162 continue;
163 if (x->type == type && x->addr == addr && x->size == size)
164 return x;
167 return NULL;
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;
200 assert(0);
201 return 0;
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;
213 while (len--)
215 *p++ = (hex_from0(src[0]) << 4) | hex_from0(src[1]);
216 src += 2;
220 static void hex_to(char* dst, const void* src, size_t len)
222 const unsigned char *p = src;
223 while (len--)
225 *dst++ = hex_to0(*p >> 4);
226 *dst++ = hex_to0(*p & 0x0F);
227 p++;
231 static unsigned char checksum(const char* ptr, int len)
233 unsigned cksum = 0;
235 while (len-- > 0)
236 cksum += (unsigned char)*ptr++;
237 return cksum;
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);
256 default:
257 ERR("got unexpected size: %u\n",
258 (unsigned)gdbctx->process->be_cpu->gdb_register_map[idx].length);
259 assert(0);
260 return 0;
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;
287 return thread;
290 return NULL;
293 static void dbg_thread_set_single_step(struct dbg_thread *thread, BOOL enable)
295 struct backend_cpu *backend;
296 dbg_ctx_t ctx;
298 if (!thread) return;
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);
305 return;
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)
314 DWORD ec;
316 if (de->dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
317 return SIGTERM;
318 if (de->dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
319 return SIGTRAP;
321 ec = de->u.Exception.ExceptionRecord.ExceptionCode;
322 switch (ec)
324 case EXCEPTION_ACCESS_VIOLATION:
325 case EXCEPTION_PRIV_INSTRUCTION:
326 case EXCEPTION_STACK_OVERFLOW:
327 case EXCEPTION_GUARD_PAGE:
328 return SIGSEGV;
329 case EXCEPTION_DATATYPE_MISALIGNMENT:
330 return SIGBUS;
331 case EXCEPTION_SINGLE_STEP:
332 case EXCEPTION_BREAKPOINT:
333 return SIGTRAP;
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:
341 return SIGFPE;
342 case EXCEPTION_INT_DIVIDE_BY_ZERO:
343 case EXCEPTION_INT_OVERFLOW:
344 return SIGFPE;
345 case EXCEPTION_ILLEGAL_INSTRUCTION:
346 return SIGILL;
347 case CONTROL_C_EXIT:
348 return SIGINT;
349 case STATUS_POSSIBLE_DEADLOCK:
350 return SIGALRM;
351 /* should not be here */
352 case EXCEPTION_INVALID_HANDLE:
353 case EXCEPTION_WINE_NAME_THREAD:
354 return SIGTRAP;
355 default:
356 ERR("Unknown exception code 0x%08x\n", ec);
357 return SIGABRT;
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;
371 char name[9];
372 SIZE_T read;
374 if (threadname->dwThreadID == -1)
375 thread = dbg_get_thread(gdbctx->process, gdbctx->de.dwThreadId);
376 else
377 thread = dbg_get_thread(gdbctx->process, threadname->dwThreadID);
378 if (thread)
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);
387 else
388 ERR("Cannot set name of thread %04x\n", threadname->dwThreadID);
389 return TRUE;
391 case EXCEPTION_INVALID_HANDLE:
392 return TRUE;
393 default:
394 return FALSE;
398 static BOOL handle_debug_event(struct gdb_context* gdbctx)
400 DEBUG_EVENT *de = &gdbctx->de;
401 struct dbg_thread *thread;
403 union {
404 char bufferA[256];
405 WCHAR buffer[256];
406 } u;
407 DWORD size;
409 gdbctx->exec_tid = de->dwThreadId;
410 gdbctx->other_tid = de->dwThreadId;
411 gdbctx->de_reply = DBG_REPLY_LATER;
413 switch (de->dwDebugEventCode)
415 case CREATE_PROCESS_DEBUG_EVENT:
416 gdbctx->process = dbg_add_process(&be_process_gdbproxy_io, de->dwProcessId,
417 de->u.CreateProcessInfo.hProcess);
418 if (!gdbctx->process)
419 return TRUE;
421 size = ARRAY_SIZE(u.buffer);
422 QueryFullProcessImageNameW( gdbctx->process->handle, 0, u.buffer, &size );
423 dbg_set_process_name(gdbctx->process, u.buffer);
425 fprintf(stderr, "%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n",
426 de->dwProcessId, de->dwThreadId,
427 dbg_W2A(u.buffer, -1),
428 de->u.CreateProcessInfo.lpImageName,
429 de->u.CreateProcessInfo.lpStartAddress,
430 de->u.CreateProcessInfo.dwDebugInfoFileOffset,
431 de->u.CreateProcessInfo.nDebugInfoSize);
433 /* de->u.CreateProcessInfo.lpStartAddress; */
434 if (!dbg_init(gdbctx->process->handle, u.buffer, TRUE))
435 ERR("Couldn't initiate DbgHelp\n");
437 fprintf(stderr, "%04x:%04x: create thread I @%p\n", de->dwProcessId,
438 de->dwThreadId, de->u.CreateProcessInfo.lpStartAddress);
440 dbg_add_thread(gdbctx->process, de->dwThreadId,
441 de->u.CreateProcessInfo.hThread,
442 de->u.CreateProcessInfo.lpThreadLocalBase);
443 return TRUE;
445 case LOAD_DLL_DEBUG_EVENT:
446 fetch_module_name( de->u.LoadDll.lpImageName, de->u.LoadDll.lpBaseOfDll,
447 u.buffer, ARRAY_SIZE(u.buffer) );
448 fprintf(stderr, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
449 de->dwProcessId, de->dwThreadId,
450 dbg_W2A(u.buffer, -1),
451 de->u.LoadDll.lpBaseOfDll,
452 de->u.LoadDll.dwDebugInfoFileOffset,
453 de->u.LoadDll.nDebugInfoSize);
454 dbg_load_module(gdbctx->process->handle, de->u.LoadDll.hFile, u.buffer,
455 (DWORD_PTR)de->u.LoadDll.lpBaseOfDll, 0);
456 return TRUE;
458 case UNLOAD_DLL_DEBUG_EVENT:
459 fprintf(stderr, "%08x:%08x: unload DLL @%p\n",
460 de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll);
461 SymUnloadModule(gdbctx->process->handle,
462 (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll);
463 return TRUE;
465 case EXCEPTION_DEBUG_EVENT:
466 TRACE("%08x:%08x: exception code=0x%08x\n", de->dwProcessId,
467 de->dwThreadId, de->u.Exception.ExceptionRecord.ExceptionCode);
469 if (handle_exception(gdbctx, &de->u.Exception))
470 return TRUE;
471 break;
473 case CREATE_THREAD_DEBUG_EVENT:
474 fprintf(stderr, "%08x:%08x: create thread D @%p\n", de->dwProcessId,
475 de->dwThreadId, de->u.CreateThread.lpStartAddress);
477 dbg_add_thread(gdbctx->process,
478 de->dwThreadId,
479 de->u.CreateThread.hThread,
480 de->u.CreateThread.lpThreadLocalBase);
481 return TRUE;
483 case EXIT_THREAD_DEBUG_EVENT:
484 fprintf(stderr, "%08x:%08x: exit thread (%u)\n",
485 de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
486 if ((thread = dbg_get_thread(gdbctx->process, de->dwThreadId)))
487 dbg_del_thread(thread);
488 return TRUE;
490 case EXIT_PROCESS_DEBUG_EVENT:
491 fprintf(stderr, "%08x:%08x: exit process (%u)\n",
492 de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode);
494 dbg_del_process(gdbctx->process);
495 gdbctx->process = NULL;
496 return FALSE;
498 case OUTPUT_DEBUG_STRING_EVENT:
499 memory_get_string(gdbctx->process,
500 de->u.DebugString.lpDebugStringData, TRUE,
501 de->u.DebugString.fUnicode, u.bufferA, sizeof(u.bufferA));
502 fprintf(stderr, "%08x:%08x: output debug string (%s)\n",
503 de->dwProcessId, de->dwThreadId, debugstr_a(u.bufferA));
504 return TRUE;
506 case RIP_EVENT:
507 fprintf(stderr, "%08x:%08x: rip error=%u type=%u\n", de->dwProcessId,
508 de->dwThreadId, de->u.RipInfo.dwError, de->u.RipInfo.dwType);
509 return TRUE;
511 default:
512 FIXME("%08x:%08x: unknown event (%u)\n",
513 de->dwProcessId, de->dwThreadId, de->dwDebugEventCode);
516 LIST_FOR_EACH_ENTRY(thread, &gdbctx->process->threads, struct dbg_thread, entry)
518 if (!thread->suspended) SuspendThread(thread->handle);
519 thread->suspended = TRUE;
522 return FALSE;
525 static void handle_step_or_continue(struct gdb_context* gdbctx, int tid, BOOL step, int sig)
527 struct dbg_process *process = gdbctx->process;
528 struct dbg_thread *thread;
530 if (tid == 0) tid = gdbctx->de.dwThreadId;
531 LIST_FOR_EACH_ENTRY(thread, &process->threads, struct dbg_thread, entry)
533 if (tid != -1 && thread->tid != tid) continue;
534 if (!thread->suspended) continue;
535 thread->suspended = FALSE;
537 if (process->pid == gdbctx->de.dwProcessId && thread->tid == gdbctx->de.dwThreadId)
538 gdbctx->de_reply = (sig == -1 ? DBG_CONTINUE : DBG_EXCEPTION_NOT_HANDLED);
540 dbg_thread_set_single_step(thread, step);
541 ResumeThread(thread->handle);
545 static BOOL check_for_interrupt(struct gdb_context* gdbctx)
547 struct pollfd pollfd;
548 int ret;
549 char pkt;
551 pollfd.fd = gdbctx->sock;
552 pollfd.events = POLLIN;
553 pollfd.revents = 0;
555 if ((ret = poll(&pollfd, 1, 0)) == 1) {
556 ret = read(gdbctx->sock, &pkt, 1);
557 if (ret != 1) {
558 ERR("read failed\n");
559 return FALSE;
561 if (pkt != '\003') {
562 ERR("Unexpected break packet %#02x\n", pkt);
563 return FALSE;
565 return TRUE;
566 } else if (ret == -1) {
567 ERR("poll failed\n");
569 return FALSE;
572 static void wait_for_debuggee(struct gdb_context* gdbctx)
574 if (gdbctx->de.dwDebugEventCode)
575 ContinueDebugEvent(gdbctx->de.dwProcessId, gdbctx->de.dwThreadId, gdbctx->de_reply);
577 for (;;)
579 if (!WaitForDebugEvent(&gdbctx->de, 10))
581 if (GetLastError() == ERROR_SEM_TIMEOUT)
583 if (check_for_interrupt(gdbctx)) {
584 if (!DebugBreakProcess(gdbctx->process->handle)) {
585 ERR("Failed to break into debuggee\n");
586 break;
588 WaitForDebugEvent(&gdbctx->de, INFINITE);
589 } else {
590 continue;
592 } else {
593 break;
596 if (!handle_debug_event(gdbctx))
597 break;
598 ContinueDebugEvent(gdbctx->de.dwProcessId, gdbctx->de.dwThreadId, DBG_CONTINUE);
602 static void detach_debuggee(struct gdb_context* gdbctx, BOOL kill)
604 handle_step_or_continue(gdbctx, -1, FALSE, -1);
606 if (gdbctx->de.dwDebugEventCode)
607 ContinueDebugEvent(gdbctx->de.dwProcessId, gdbctx->de.dwThreadId, DBG_CONTINUE);
609 if (!kill)
610 DebugActiveProcessStop(gdbctx->process->pid);
611 dbg_del_process(gdbctx->process);
612 gdbctx->process = NULL;
615 static void get_process_info(struct gdb_context* gdbctx, char* buffer, size_t len)
617 DWORD status;
619 if (!GetExitCodeProcess(gdbctx->process->handle, &status))
621 strcpy(buffer, "Unknown process");
622 return;
624 if (status == STILL_ACTIVE)
626 strcpy(buffer, "Running");
628 else
629 snprintf(buffer, len, "Terminated (%u)", status);
631 switch (GetPriorityClass(gdbctx->process->handle))
633 case 0: break;
634 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
635 case ABOVE_NORMAL_PRIORITY_CLASS: strcat(buffer, ", above normal priority"); break;
636 #endif
637 #ifdef BELOW_NORMAL_PRIORITY_CLASS
638 case BELOW_NORMAL_PRIORITY_CLASS: strcat(buffer, ", below normal priority"); break;
639 #endif
640 case HIGH_PRIORITY_CLASS: strcat(buffer, ", high priority"); break;
641 case IDLE_PRIORITY_CLASS: strcat(buffer, ", idle priority"); break;
642 case NORMAL_PRIORITY_CLASS: strcat(buffer, ", normal priority"); break;
643 case REALTIME_PRIORITY_CLASS: strcat(buffer, ", realtime priority"); break;
645 strcat(buffer, "\n");
648 static void get_thread_info(struct gdb_context* gdbctx, unsigned tid,
649 char* buffer, size_t len)
651 struct dbg_thread* thd;
652 DWORD status;
653 int prio;
655 /* FIXME: use the size of buffer */
656 thd = dbg_get_thread(gdbctx->process, tid);
657 if (thd == NULL)
659 strcpy(buffer, "No information");
660 return;
662 if (GetExitCodeThread(thd->handle, &status))
664 if (status == STILL_ACTIVE)
666 /* FIXME: this is a bit brutal... some nicer way shall be found */
667 switch (status = SuspendThread(thd->handle))
669 case -1: break;
670 case 0: strcpy(buffer, "Running"); break;
671 default: snprintf(buffer, len, "Suspended (%u)", status - 1);
673 ResumeThread(thd->handle);
675 else
676 snprintf(buffer, len, "Terminated (exit code = %u)", status);
678 else
680 strcpy(buffer, "Unknown threadID");
682 switch (prio = GetThreadPriority(thd->handle))
684 case THREAD_PRIORITY_ERROR_RETURN: break;
685 case THREAD_PRIORITY_ABOVE_NORMAL: strcat(buffer, ", priority +1 above normal"); break;
686 case THREAD_PRIORITY_BELOW_NORMAL: strcat(buffer, ", priority -1 below normal"); break;
687 case THREAD_PRIORITY_HIGHEST: strcat(buffer, ", priority +2 above normal"); break;
688 case THREAD_PRIORITY_LOWEST: strcat(buffer, ", priority -2 below normal"); break;
689 case THREAD_PRIORITY_IDLE: strcat(buffer, ", priority idle"); break;
690 case THREAD_PRIORITY_NORMAL: strcat(buffer, ", priority normal"); break;
691 case THREAD_PRIORITY_TIME_CRITICAL: strcat(buffer, ", priority time-critical"); break;
692 default: snprintf(buffer + strlen(buffer), len - strlen(buffer), ", priority = %d", prio);
694 assert(strlen(buffer) < len);
697 /* =============================================== *
698 * P A C K E T U T I L S *
699 * =============================================== *
702 enum packet_return {packet_error = 0x00, packet_ok = 0x01, packet_done = 0x02,
703 packet_last_f = 0x80};
705 static char* packet_realloc(char* buf, int size)
707 if (!buf)
708 return HeapAlloc(GetProcessHeap(), 0, size);
709 return HeapReAlloc(GetProcessHeap(), 0, buf, size);
713 static void packet_reply_grow(struct gdb_context* gdbctx, size_t size)
715 if (gdbctx->out_buf_alloc < gdbctx->out_len + size)
717 gdbctx->out_buf_alloc = ((gdbctx->out_len + size) / 32 + 1) * 32;
718 gdbctx->out_buf = packet_realloc(gdbctx->out_buf, gdbctx->out_buf_alloc);
722 static void packet_reply_hex_to(struct gdb_context* gdbctx, const void* src, int len)
724 packet_reply_grow(gdbctx, len * 2);
725 hex_to(&gdbctx->out_buf[gdbctx->out_len], src, len);
726 gdbctx->out_len += len * 2;
729 static inline void packet_reply_hex_to_str(struct gdb_context* gdbctx, const char* src)
731 packet_reply_hex_to(gdbctx, src, strlen(src));
734 static void packet_reply_val(struct gdb_context* gdbctx, unsigned long val, int len)
736 int i, shift;
738 shift = (len - 1) * 8;
739 packet_reply_grow(gdbctx, len * 2);
740 for (i = 0; i < len; i++, shift -= 8)
742 gdbctx->out_buf[gdbctx->out_len++] = hex_to0((val >> (shift + 4)) & 0x0F);
743 gdbctx->out_buf[gdbctx->out_len++] = hex_to0((val >> shift ) & 0x0F);
747 static inline void packet_reply_add(struct gdb_context* gdbctx, const char* str)
749 int len = strlen(str);
750 packet_reply_grow(gdbctx, len);
751 memcpy(&gdbctx->out_buf[gdbctx->out_len], str, len);
752 gdbctx->out_len += len;
755 static void packet_reply_open(struct gdb_context* gdbctx)
757 assert(gdbctx->out_curr_packet == -1);
758 packet_reply_add(gdbctx, "$");
759 gdbctx->out_curr_packet = gdbctx->out_len;
762 static void packet_reply_close(struct gdb_context* gdbctx)
764 unsigned char cksum;
765 int plen;
767 plen = gdbctx->out_len - gdbctx->out_curr_packet;
768 packet_reply_add(gdbctx, "#");
769 cksum = checksum(&gdbctx->out_buf[gdbctx->out_curr_packet], plen);
770 packet_reply_hex_to(gdbctx, &cksum, 1);
771 gdbctx->out_curr_packet = -1;
774 static void packet_reply_open_xfer(struct gdb_context* gdbctx)
776 packet_reply_open(gdbctx);
777 packet_reply_add(gdbctx, "m");
780 static void packet_reply_close_xfer(struct gdb_context* gdbctx, int off, int len)
782 int begin = gdbctx->out_curr_packet + 1;
783 int plen;
785 if (begin + off < gdbctx->out_len)
787 gdbctx->out_len -= off;
788 memmove(gdbctx->out_buf + begin, gdbctx->out_buf + begin + off, gdbctx->out_len);
790 else
792 gdbctx->out_buf[gdbctx->out_curr_packet] = 'l';
793 gdbctx->out_len = gdbctx->out_curr_packet + 1;
796 plen = gdbctx->out_len - begin;
797 if (len >= 0 && plen > len) gdbctx->out_len -= (plen - len);
798 else gdbctx->out_buf[gdbctx->out_curr_packet] = 'l';
800 packet_reply_close(gdbctx);
803 static enum packet_return packet_reply(struct gdb_context* gdbctx, const char* packet)
805 packet_reply_open(gdbctx);
807 assert(strchr(packet, '$') == NULL && strchr(packet, '#') == NULL);
809 packet_reply_add(gdbctx, packet);
811 packet_reply_close(gdbctx);
813 return packet_done;
816 static enum packet_return packet_reply_error(struct gdb_context* gdbctx, int error)
818 packet_reply_open(gdbctx);
820 packet_reply_add(gdbctx, "E");
821 packet_reply_val(gdbctx, error, 1);
823 packet_reply_close(gdbctx);
825 return packet_done;
828 static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, dbg_ctx_t* ctx, unsigned idx)
830 const struct gdb_register *cpu_register_map = gdbctx->process->be_cpu->gdb_register_map;
831 packet_reply_hex_to(gdbctx, cpu_register_ptr(gdbctx, ctx, idx), cpu_register_map[idx].length);
834 /* =============================================== *
835 * P A C K E T H A N D L E R S *
836 * =============================================== *
839 static void packet_reply_status_xpoints(struct gdb_context* gdbctx, struct dbg_thread *thread,
840 dbg_ctx_t *ctx)
842 struct dbg_process *process = thread->process;
843 struct backend_cpu *cpu = process->be_cpu;
844 struct gdb_xpoint *x;
846 LIST_FOR_EACH_ENTRY(x, &gdbctx->xpoint_list, struct gdb_xpoint, entry)
848 if (x->pid != process->pid || x->tid != thread->tid)
849 continue;
850 if (!cpu->is_watchpoint_set(ctx, x->value))
851 continue;
852 if (x->type == be_xpoint_watch_write)
854 packet_reply_add(gdbctx, "watch:");
855 packet_reply_val(gdbctx, (unsigned long)x->addr, sizeof(x->addr));
856 packet_reply_add(gdbctx, ";");
858 if (x->type == be_xpoint_watch_read)
860 packet_reply_add(gdbctx, "rwatch:");
861 packet_reply_val(gdbctx, (unsigned long)x->addr, sizeof(x->addr));
862 packet_reply_add(gdbctx, ";");
867 static enum packet_return packet_reply_status(struct gdb_context* gdbctx)
869 struct dbg_process *process = gdbctx->process;
870 struct dbg_thread *thread;
871 struct backend_cpu *backend;
872 dbg_ctx_t ctx;
873 size_t i;
875 switch (gdbctx->de.dwDebugEventCode)
877 default:
878 if (!process) return packet_error;
879 if (!(backend = process->be_cpu)) return packet_error;
880 if (!(thread = dbg_get_thread(process, gdbctx->de.dwThreadId)) ||
881 !backend->get_context(thread->handle, &ctx))
882 return packet_error;
884 packet_reply_open(gdbctx);
885 packet_reply_add(gdbctx, "T");
886 packet_reply_val(gdbctx, signal_from_debug_event(&gdbctx->de), 1);
887 packet_reply_add(gdbctx, "thread:");
888 packet_reply_val(gdbctx, gdbctx->de.dwThreadId, 4);
889 packet_reply_add(gdbctx, ";");
890 packet_reply_status_xpoints(gdbctx, thread, &ctx);
892 for (i = 0; i < backend->gdb_num_regs; i++)
894 packet_reply_val(gdbctx, i, 1);
895 packet_reply_add(gdbctx, ":");
896 packet_reply_register_hex_to(gdbctx, &ctx, i);
897 packet_reply_add(gdbctx, ";");
900 packet_reply_close(gdbctx);
901 return packet_done;
903 case EXIT_PROCESS_DEBUG_EVENT:
904 packet_reply_open(gdbctx);
905 packet_reply_add(gdbctx, "W");
906 packet_reply_val(gdbctx, gdbctx->de.u.ExitProcess.dwExitCode, 4);
907 packet_reply_close(gdbctx);
908 return packet_done | packet_last_f;
912 static enum packet_return packet_last_signal(struct gdb_context* gdbctx)
914 assert(gdbctx->in_packet_len == 0);
915 return packet_reply_status(gdbctx);
918 static enum packet_return packet_continue(struct gdb_context* gdbctx)
920 void *addr;
922 if (sscanf(gdbctx->in_packet, "%p", &addr) == 1)
923 FIXME("Continue at address %p not supported\n", addr);
925 handle_step_or_continue(gdbctx, gdbctx->exec_tid, FALSE, -1);
927 wait_for_debuggee(gdbctx);
928 return packet_reply_status(gdbctx);
931 static enum packet_return packet_verbose_cont(struct gdb_context* gdbctx)
933 char *buf = gdbctx->in_packet, *end = gdbctx->in_packet + gdbctx->in_packet_len;
935 if (gdbctx->in_packet[4] == '?')
937 packet_reply_open(gdbctx);
938 packet_reply_add(gdbctx, "vCont");
939 packet_reply_add(gdbctx, ";c");
940 packet_reply_add(gdbctx, ";C");
941 packet_reply_add(gdbctx, ";s");
942 packet_reply_add(gdbctx, ";S");
943 packet_reply_close(gdbctx);
944 return packet_done;
947 while (buf < end && (buf = memchr(buf + 1, ';', end - buf - 1)))
949 int tid = -1, sig = -1;
950 int action, n;
952 switch ((action = buf[1]))
954 default:
955 return packet_error;
956 case 'c':
957 case 's':
958 buf += 2;
959 break;
960 case 'C':
961 case 'S':
962 if (sscanf(buf, ";%*c%2x", &sig) <= 0 ||
963 sig != signal_from_debug_event(&gdbctx->de))
964 return packet_error;
965 buf += 4;
966 break;
969 if (buf > end)
970 return packet_error;
971 if (buf < end && *buf == ':' && (n = sscanf(buf, ":%x", &tid)) <= 0)
972 return packet_error;
974 handle_step_or_continue(gdbctx, tid, action == 's' || action == 'S', sig);
977 wait_for_debuggee(gdbctx);
978 return packet_reply_status(gdbctx);
981 static enum packet_return packet_verbose(struct gdb_context* gdbctx)
983 if (gdbctx->in_packet_len >= 4 && !memcmp(gdbctx->in_packet, "Cont", 4))
985 return packet_verbose_cont(gdbctx);
988 if (gdbctx->in_packet_len == 14 && !memcmp(gdbctx->in_packet, "MustReplyEmpty", 14))
989 return packet_reply(gdbctx, "");
991 return packet_error;
994 static enum packet_return packet_continue_signal(struct gdb_context* gdbctx)
996 void *addr;
997 int sig, n;
999 if ((n = sscanf(gdbctx->in_packet, "%x;%p", &sig, &addr)) == 2)
1000 FIXME("Continue at address %p not supported\n", addr);
1001 if (n < 1) return packet_error;
1003 if (sig != signal_from_debug_event(&gdbctx->de))
1005 ERR("Changing signals is not supported.\n");
1006 return packet_error;
1009 handle_step_or_continue(gdbctx, gdbctx->exec_tid, FALSE, sig);
1011 wait_for_debuggee(gdbctx);
1012 return packet_reply_status(gdbctx);
1015 static enum packet_return packet_delete_breakpoint(struct gdb_context* gdbctx)
1017 struct dbg_process *process = gdbctx->process;
1018 struct dbg_thread *thread;
1019 struct backend_cpu *cpu;
1020 struct gdb_xpoint *x;
1021 dbg_ctx_t ctx;
1022 char type;
1023 void *addr;
1024 int size;
1026 if (!process) return packet_error;
1027 if (!(cpu = process->be_cpu)) return packet_error;
1029 if (sscanf(gdbctx->in_packet, "%c,%p,%x", &type, &addr, &size) < 3)
1030 return packet_error;
1032 if (type == '0')
1033 return packet_error;
1035 LIST_FOR_EACH_ENTRY(thread, &process->threads, struct dbg_thread, entry)
1037 if (!cpu->get_context(thread->handle, &ctx))
1038 continue;
1039 if ((type == '1') && (x = gdb_find_xpoint(gdbctx, thread, be_xpoint_watch_exec, addr, size)))
1040 gdbctx_delete_xpoint(gdbctx, thread, &ctx, x);
1041 if ((type == '2' || type == '4') && (x = gdb_find_xpoint(gdbctx, thread, be_xpoint_watch_read, addr, size)))
1042 gdbctx_delete_xpoint(gdbctx, thread, &ctx, x);
1043 if ((type == '3' || type == '4') && (x = gdb_find_xpoint(gdbctx, thread, be_xpoint_watch_write, addr, size)))
1044 gdbctx_delete_xpoint(gdbctx, thread, &ctx, x);
1045 cpu->set_context(thread->handle, &ctx);
1048 while ((type == '1') && (x = gdb_find_xpoint(gdbctx, NULL, be_xpoint_watch_exec, addr, size)))
1049 gdbctx_delete_xpoint(gdbctx, NULL, NULL, x);
1050 while ((type == '2' || type == '4') && (x = gdb_find_xpoint(gdbctx, NULL, be_xpoint_watch_read, addr, size)))
1051 gdbctx_delete_xpoint(gdbctx, NULL, NULL, x);
1052 while ((type == '3' || type == '4') && (x = gdb_find_xpoint(gdbctx, NULL, be_xpoint_watch_write, addr, size)))
1053 gdbctx_delete_xpoint(gdbctx, NULL, NULL, x);
1055 return packet_ok;
1058 static enum packet_return packet_insert_breakpoint(struct gdb_context* gdbctx)
1060 struct dbg_process *process = gdbctx->process;
1061 struct dbg_thread *thread;
1062 struct backend_cpu *cpu;
1063 dbg_ctx_t ctx;
1064 char type;
1065 void *addr;
1066 int size;
1068 if (!process) return packet_error;
1069 if (!(cpu = process->be_cpu)) return packet_error;
1071 if (memchr(gdbctx->in_packet, ';', gdbctx->in_packet_len))
1073 FIXME("breakpoint commands not supported\n");
1074 return packet_error;
1077 if (sscanf(gdbctx->in_packet, "%c,%p,%x", &type, &addr, &size) < 3)
1078 return packet_error;
1080 if (type == '0')
1081 return packet_error;
1083 LIST_FOR_EACH_ENTRY(thread, &process->threads, struct dbg_thread, entry)
1085 if (!cpu->get_context(thread->handle, &ctx))
1086 continue;
1087 if (type == '1')
1088 gdbctx_insert_xpoint(gdbctx, thread, &ctx, be_xpoint_watch_exec, addr, size);
1089 if (type == '2' || type == '4')
1090 gdbctx_insert_xpoint(gdbctx, thread, &ctx, be_xpoint_watch_read, addr, size);
1091 if (type == '3' || type == '4')
1092 gdbctx_insert_xpoint(gdbctx, thread, &ctx, be_xpoint_watch_write, addr, size);
1093 cpu->set_context(thread->handle, &ctx);
1096 return packet_ok;
1099 static enum packet_return packet_detach(struct gdb_context* gdbctx)
1101 detach_debuggee(gdbctx, FALSE);
1102 return packet_ok | packet_last_f;
1105 static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
1107 struct dbg_thread *thread = dbg_thread_from_tid(gdbctx, gdbctx->other_tid);
1108 struct backend_cpu *backend;
1109 dbg_ctx_t ctx;
1110 size_t i;
1112 if (!thread) return packet_error;
1113 if (!thread->process) return packet_error;
1114 if (!(backend = thread->process->be_cpu)) return packet_error;
1116 if (!backend->get_context(thread->handle, &ctx))
1117 return packet_error;
1119 packet_reply_open(gdbctx);
1120 for (i = 0; i < backend->gdb_num_regs; i++)
1121 packet_reply_register_hex_to(gdbctx, &ctx, i);
1123 packet_reply_close(gdbctx);
1124 return packet_done;
1127 static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
1129 struct dbg_thread *thread = dbg_thread_from_tid(gdbctx, gdbctx->other_tid);
1130 struct backend_cpu *backend;
1131 dbg_ctx_t ctx;
1132 const char *ptr;
1133 size_t i;
1135 if (!thread) return packet_error;
1136 if (!thread->process) return packet_error;
1137 if (!(backend = thread->process->be_cpu)) return packet_error;
1139 if (!backend->get_context(thread->handle, &ctx))
1140 return packet_error;
1142 if (gdbctx->in_packet_len < backend->gdb_num_regs * 2)
1143 return packet_error;
1145 ptr = gdbctx->in_packet;
1146 for (i = 0; i < backend->gdb_num_regs; i++)
1147 cpu_register_hex_from(gdbctx, &ctx, i, &ptr);
1149 if (!backend->set_context(thread->handle, &ctx))
1151 ERR("Failed to set context for tid %04x, error %u\n", thread->tid, GetLastError());
1152 return packet_error;
1155 return packet_ok;
1158 static enum packet_return packet_kill(struct gdb_context* gdbctx)
1160 detach_debuggee(gdbctx, TRUE);
1161 return packet_ok | packet_last_f;
1164 static enum packet_return packet_thread(struct gdb_context* gdbctx)
1166 switch (gdbctx->in_packet[0])
1168 case 'c':
1169 if (sscanf(gdbctx->in_packet, "c%x", &gdbctx->exec_tid) == 1)
1170 return packet_ok;
1171 return packet_error;
1172 case 'g':
1173 if (sscanf(gdbctx->in_packet, "g%x", &gdbctx->other_tid) == 1)
1174 return packet_ok;
1175 return packet_error;
1176 default:
1177 FIXME("Unknown thread sub-command %c\n", gdbctx->in_packet[0]);
1178 return packet_error;
1182 static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
1184 char *addr;
1185 unsigned int len, blk_len, nread;
1186 char buffer[32];
1187 SIZE_T r = 0;
1189 if (sscanf(gdbctx->in_packet, "%p,%x", &addr, &len) != 2) return packet_error;
1190 if (len <= 0) return packet_error;
1191 TRACE("Read %u bytes at %p\n", len, addr);
1192 for (nread = 0; nread < len; nread += r, addr += r)
1194 blk_len = min(sizeof(buffer), len - nread);
1195 if (!gdbctx->process->process_io->read(gdbctx->process->handle, addr,
1196 buffer, blk_len, &r) || r == 0)
1198 /* fail at first address, return error */
1199 if (nread == 0) return packet_reply_error(gdbctx, EFAULT);
1200 /* something has already been read, return partial information */
1201 break;
1203 if (nread == 0) packet_reply_open(gdbctx);
1204 packet_reply_hex_to(gdbctx, buffer, r);
1206 packet_reply_close(gdbctx);
1207 return packet_done;
1210 static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
1212 char* addr;
1213 unsigned int len, blk_len;
1214 char* ptr;
1215 char buffer[32];
1216 SIZE_T w;
1218 ptr = memchr(gdbctx->in_packet, ':', gdbctx->in_packet_len);
1219 if (ptr == NULL)
1221 ERR("Cannot find ':' in %s\n", debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
1222 return packet_error;
1224 *ptr++ = '\0';
1226 if (sscanf(gdbctx->in_packet, "%p,%x", &addr, &len) != 2)
1228 ERR("Failed to parse %s\n", debugstr_a(gdbctx->in_packet));
1229 return packet_error;
1231 if (ptr - gdbctx->in_packet + len * 2 != gdbctx->in_packet_len)
1233 ERR("Length %u does not match packet length %u\n",
1234 (int)(ptr - gdbctx->in_packet) + len * 2, gdbctx->in_packet_len);
1235 return packet_error;
1237 TRACE("Write %u bytes at %p\n", len, addr);
1238 while (len > 0)
1240 blk_len = min(sizeof(buffer), len);
1241 hex_from(buffer, ptr, blk_len);
1242 if (!gdbctx->process->process_io->write(gdbctx->process->handle, addr, buffer, blk_len, &w) ||
1243 w != blk_len)
1244 break;
1245 addr += blk_len;
1246 len -= blk_len;
1247 ptr += blk_len;
1249 return packet_ok; /* FIXME: error while writing ? */
1252 static enum packet_return packet_read_register(struct gdb_context* gdbctx)
1254 struct dbg_thread *thread = dbg_thread_from_tid(gdbctx, gdbctx->other_tid);
1255 struct backend_cpu *backend;
1256 dbg_ctx_t ctx;
1257 size_t reg;
1259 if (!thread) return packet_error;
1260 if (!thread->process) return packet_error;
1261 if (!(backend = thread->process->be_cpu)) return packet_error;
1263 if (!backend->get_context(thread->handle, &ctx))
1264 return packet_error;
1266 if (sscanf(gdbctx->in_packet, "%zx", &reg) != 1)
1267 return packet_error;
1268 if (reg >= backend->gdb_num_regs)
1270 WARN("Unhandled register %zu\n", reg);
1271 return packet_error;
1274 TRACE("%zu => %s\n", reg, wine_dbgstr_longlong(cpu_register(gdbctx, &ctx, reg)));
1276 packet_reply_open(gdbctx);
1277 packet_reply_register_hex_to(gdbctx, &ctx, reg);
1278 packet_reply_close(gdbctx);
1279 return packet_done;
1282 static enum packet_return packet_write_register(struct gdb_context* gdbctx)
1284 struct dbg_thread *thread = dbg_thread_from_tid(gdbctx, gdbctx->other_tid);
1285 struct backend_cpu *backend;
1286 dbg_ctx_t ctx;
1287 size_t reg;
1288 char *ptr;
1290 if (!thread) return packet_error;
1291 if (!thread->process) return packet_error;
1292 if (!(backend = thread->process->be_cpu)) return packet_error;
1294 if (!backend->get_context(thread->handle, &ctx))
1295 return packet_error;
1297 if (!(ptr = strchr(gdbctx->in_packet, '=')))
1298 return packet_error;
1299 *ptr++ = '\0';
1301 if (sscanf(gdbctx->in_packet, "%zx", &reg) != 1)
1302 return packet_error;
1303 if (reg >= backend->gdb_num_regs)
1305 /* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
1306 * it wouldn't matter too much, and it fakes our support for all regs
1308 WARN("Unhandled register %zu\n", reg);
1309 return packet_ok;
1312 TRACE("%zu <= %s\n", reg, debugstr_an(ptr, (int)(gdbctx->in_packet_len - (ptr - gdbctx->in_packet))));
1314 cpu_register_hex_from(gdbctx, &ctx, reg, (const char**)&ptr);
1315 if (!backend->set_context(thread->handle, &ctx))
1317 ERR("Failed to set context for tid %04x, error %u\n", thread->tid, GetLastError());
1318 return packet_error;
1321 return packet_ok;
1324 static void packet_query_monitor_wnd_helper(struct gdb_context* gdbctx, HWND hWnd, int indent)
1326 char buffer[128];
1327 char clsName[128];
1328 char wndName[128];
1329 HWND child;
1331 do {
1332 if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
1333 strcpy(clsName, "-- Unknown --");
1334 if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
1335 strcpy(wndName, "-- Empty --");
1337 packet_reply_open(gdbctx);
1338 packet_reply_add(gdbctx, "O");
1339 snprintf(buffer, sizeof(buffer),
1340 "%*s%04lx%*s%-17.17s %08x %0*lx %.14s\n",
1341 indent, "", (ULONG_PTR)hWnd, 13 - indent, "",
1342 clsName, GetWindowLongW(hWnd, GWL_STYLE),
1343 ADDRWIDTH, (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_WNDPROC),
1344 wndName);
1345 packet_reply_hex_to_str(gdbctx, buffer);
1346 packet_reply_close(gdbctx);
1348 if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
1349 packet_query_monitor_wnd_helper(gdbctx, child, indent + 1);
1350 } while ((hWnd = GetWindow(hWnd, GW_HWNDNEXT)) != 0);
1353 static void packet_query_monitor_wnd(struct gdb_context* gdbctx, int len, const char* str)
1355 char buffer[128];
1357 /* we do the output in several 'O' packets, with the last one being just OK for
1358 * marking the end of the output */
1359 packet_reply_open(gdbctx);
1360 packet_reply_add(gdbctx, "O");
1361 snprintf(buffer, sizeof(buffer),
1362 "%-16.16s %-17.17s %-8.8s %s\n",
1363 "hwnd", "Class Name", " Style", " WndProc Text");
1364 packet_reply_hex_to_str(gdbctx, buffer);
1365 packet_reply_close(gdbctx);
1367 /* FIXME: could also add a pmt to this command in str... */
1368 packet_query_monitor_wnd_helper(gdbctx, GetDesktopWindow(), 0);
1369 packet_reply(gdbctx, "OK");
1372 static void packet_query_monitor_process(struct gdb_context* gdbctx, int len, const char* str)
1374 HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1375 char buffer[31+MAX_PATH];
1376 char deco;
1377 PROCESSENTRY32 entry;
1378 BOOL ok;
1380 if (snap == INVALID_HANDLE_VALUE)
1381 return;
1383 entry.dwSize = sizeof(entry);
1384 ok = Process32First(snap, &entry);
1386 /* we do the output in several 'O' packets, with the last one being just OK for
1387 * marking the end of the output */
1389 packet_reply_open(gdbctx);
1390 packet_reply_add(gdbctx, "O");
1391 snprintf(buffer, sizeof(buffer),
1392 " %-8.8s %-8.8s %-8.8s %s\n",
1393 "pid", "threads", "parent", "executable");
1394 packet_reply_hex_to_str(gdbctx, buffer);
1395 packet_reply_close(gdbctx);
1397 while (ok)
1399 deco = ' ';
1400 if (entry.th32ProcessID == gdbctx->process->pid) deco = '>';
1401 packet_reply_open(gdbctx);
1402 packet_reply_add(gdbctx, "O");
1403 snprintf(buffer, sizeof(buffer),
1404 "%c%08x %-8d %08x '%s'\n",
1405 deco, entry.th32ProcessID, entry.cntThreads,
1406 entry.th32ParentProcessID, entry.szExeFile);
1407 packet_reply_hex_to_str(gdbctx, buffer);
1408 packet_reply_close(gdbctx);
1409 ok = Process32Next(snap, &entry);
1411 CloseHandle(snap);
1412 packet_reply(gdbctx, "OK");
1415 static void packet_query_monitor_mem(struct gdb_context* gdbctx, int len, const char* str)
1417 MEMORY_BASIC_INFORMATION mbi;
1418 char* addr = 0;
1419 const char* state;
1420 const char* type;
1421 char prot[3+1];
1422 char buffer[128];
1424 /* we do the output in several 'O' packets, with the last one being just OK for
1425 * marking the end of the output */
1426 packet_reply_open(gdbctx);
1427 packet_reply_add(gdbctx, "O");
1428 packet_reply_hex_to_str(gdbctx, "Address Size State Type RWX\n");
1429 packet_reply_close(gdbctx);
1431 while (VirtualQueryEx(gdbctx->process->handle, addr, &mbi, sizeof(mbi)) >= sizeof(mbi))
1433 switch (mbi.State)
1435 case MEM_COMMIT: state = "commit "; break;
1436 case MEM_FREE: state = "free "; break;
1437 case MEM_RESERVE: state = "reserve"; break;
1438 default: state = "??? "; break;
1440 if (mbi.State != MEM_FREE)
1442 switch (mbi.Type)
1444 case MEM_IMAGE: type = "image "; break;
1445 case MEM_MAPPED: type = "mapped "; break;
1446 case MEM_PRIVATE: type = "private"; break;
1447 case 0: type = " "; break;
1448 default: type = "??? "; break;
1450 memset(prot, ' ' , sizeof(prot)-1);
1451 prot[sizeof(prot)-1] = '\0';
1452 if (mbi.AllocationProtect & (PAGE_READONLY|PAGE_READWRITE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
1453 prot[0] = 'R';
1454 if (mbi.AllocationProtect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE))
1455 prot[1] = 'W';
1456 if (mbi.AllocationProtect & (PAGE_WRITECOPY|PAGE_EXECUTE_WRITECOPY))
1457 prot[1] = 'C';
1458 if (mbi.AllocationProtect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
1459 prot[2] = 'X';
1461 else
1463 type = "";
1464 prot[0] = '\0';
1466 packet_reply_open(gdbctx);
1467 snprintf(buffer, sizeof(buffer), "%0*lx %0*lx %s %s %s\n",
1468 (unsigned)sizeof(void*), (DWORD_PTR)addr,
1469 (unsigned)sizeof(void*), mbi.RegionSize, state, type, prot);
1470 packet_reply_add(gdbctx, "O");
1471 packet_reply_hex_to_str(gdbctx, buffer);
1472 packet_reply_close(gdbctx);
1474 if (addr + mbi.RegionSize < addr) /* wrap around ? */
1475 break;
1476 addr += mbi.RegionSize;
1478 packet_reply(gdbctx, "OK");
1481 struct query_detail
1483 int with_arg;
1484 const char* name;
1485 size_t len;
1486 void (*handler)(struct gdb_context*, int, const char*);
1487 } query_details[] =
1489 {0, "wnd", 3, packet_query_monitor_wnd},
1490 {0, "window", 6, packet_query_monitor_wnd},
1491 {0, "proc", 4, packet_query_monitor_process},
1492 {0, "process", 7, packet_query_monitor_process},
1493 {0, "mem", 3, packet_query_monitor_mem},
1494 {0, NULL, 0, NULL},
1497 static enum packet_return packet_query_remote_command(struct gdb_context* gdbctx,
1498 const char* hxcmd, size_t len)
1500 char buffer[128];
1501 struct query_detail* qd;
1503 assert((len & 1) == 0 && len < 2 * sizeof(buffer));
1504 len /= 2;
1505 hex_from(buffer, hxcmd, len);
1507 for (qd = query_details; qd->name != NULL; qd++)
1509 if (len < qd->len || strncmp(buffer, qd->name, qd->len) != 0) continue;
1510 if (!qd->with_arg && len != qd->len) continue;
1512 (qd->handler)(gdbctx, len - qd->len, buffer + qd->len);
1513 return packet_done;
1515 return packet_reply_error(gdbctx, EINVAL);
1518 static BOOL CALLBACK packet_query_libraries_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
1520 struct gdb_context* gdbctx = ctx;
1521 MEMORY_BASIC_INFORMATION mbi;
1522 IMAGE_SECTION_HEADER *sec;
1523 IMAGE_DOS_HEADER *dos = NULL;
1524 IMAGE_NT_HEADERS *nth = NULL;
1525 IMAGEHLP_MODULE64 mod;
1526 SIZE_T size, i;
1527 BOOL is_wow64;
1528 char buffer[0x400];
1530 mod.SizeOfStruct = sizeof(mod);
1531 SymGetModuleInfo64(gdbctx->process->handle, base, &mod);
1533 packet_reply_add(gdbctx, "<library name=\"");
1534 if (strcmp(mod.LoadedImageName, "[vdso].so") == 0)
1535 packet_reply_add(gdbctx, "linux-vdso.so.1");
1536 else if (mod.LoadedImageName[0] == '/')
1537 packet_reply_add(gdbctx, mod.LoadedImageName);
1538 else
1540 UNICODE_STRING nt_name;
1541 ANSI_STRING ansi_name;
1542 char *unix_path, *tmp;
1544 RtlInitAnsiString(&ansi_name, mod.LoadedImageName);
1545 RtlAnsiStringToUnicodeString(&nt_name, &ansi_name, TRUE);
1547 if ((unix_path = wine_get_unix_file_name(nt_name.Buffer)))
1549 if (IsWow64Process(gdbctx->process->handle, &is_wow64) &&
1550 is_wow64 && (tmp = strstr(unix_path, "system32")))
1551 memcpy(tmp, "syswow64", 8);
1552 packet_reply_add(gdbctx, unix_path);
1554 else
1555 packet_reply_add(gdbctx, mod.LoadedImageName);
1557 HeapFree(GetProcessHeap(), 0, unix_path);
1558 RtlFreeUnicodeString(&nt_name);
1560 packet_reply_add(gdbctx, "\">");
1562 size = sizeof(buffer);
1563 if (VirtualQueryEx(gdbctx->process->handle, (void *)(UINT_PTR)mod.BaseOfImage, &mbi, sizeof(mbi)) >= sizeof(mbi) &&
1564 mbi.Type == MEM_IMAGE && mbi.State != MEM_FREE)
1566 if (ReadProcessMemory(gdbctx->process->handle, (void *)(UINT_PTR)mod.BaseOfImage, buffer, size, &size) &&
1567 size >= sizeof(IMAGE_DOS_HEADER))
1568 dos = (IMAGE_DOS_HEADER *)buffer;
1570 if (dos && dos->e_magic == IMAGE_DOS_SIGNATURE && dos->e_lfanew < size)
1571 nth = (IMAGE_NT_HEADERS *)(buffer + dos->e_lfanew);
1573 if (nth && memcmp(&nth->Signature, "PE\0\0", 4))
1574 nth = NULL;
1577 if (!nth) memset(buffer, 0, sizeof(buffer));
1579 /* if the module is not PE we have cleared buffer with 0, this makes
1580 * the following computation valid in all cases. */
1581 dos = (IMAGE_DOS_HEADER *)buffer;
1582 nth = (IMAGE_NT_HEADERS *)(buffer + dos->e_lfanew);
1583 if (IsWow64Process(gdbctx->process->handle, &is_wow64) && is_wow64)
1584 sec = IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS32 *)nth);
1585 else
1586 sec = IMAGE_FIRST_SECTION((IMAGE_NT_HEADERS64 *)nth);
1588 for (i = 0; i < max(nth->FileHeader.NumberOfSections, 1); ++i)
1590 if ((char *)(sec + i) >= buffer + size) break;
1591 packet_reply_add(gdbctx, "<segment address=\"0x");
1592 packet_reply_val(gdbctx, mod.BaseOfImage + sec[i].VirtualAddress, sizeof(unsigned long));
1593 packet_reply_add(gdbctx, "\"/>");
1596 packet_reply_add(gdbctx, "</library>");
1598 return TRUE;
1601 static void packet_query_libraries(struct gdb_context* gdbctx)
1603 BOOL opt;
1605 /* this will resynchronize builtin dbghelp's internal ELF module list */
1606 SymLoadModule(gdbctx->process->handle, 0, 0, 0, 0, 0);
1608 packet_reply_add(gdbctx, "<library-list>");
1609 opt = SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, TRUE);
1610 SymEnumerateModules64(gdbctx->process->handle, packet_query_libraries_cb, gdbctx);
1611 SymSetExtendedOption(SYMOPT_EX_WINE_NATIVE_MODULES, opt);
1612 packet_reply_add(gdbctx, "</library-list>");
1615 static void packet_query_threads(struct gdb_context* gdbctx)
1617 struct dbg_process* process = gdbctx->process;
1618 struct dbg_thread* thread;
1620 packet_reply_add(gdbctx, "<threads>");
1621 LIST_FOR_EACH_ENTRY(thread, &process->threads, struct dbg_thread, entry)
1623 packet_reply_add(gdbctx, "<thread ");
1624 packet_reply_add(gdbctx, "id=\"");
1625 packet_reply_val(gdbctx, thread->tid, 4);
1626 packet_reply_add(gdbctx, "\" name=\"");
1627 packet_reply_add(gdbctx, thread->name);
1628 packet_reply_add(gdbctx, "\"/>");
1630 packet_reply_add(gdbctx, "</threads>");
1633 static void packet_query_target_xml(struct gdb_context* gdbctx, struct backend_cpu* cpu)
1635 const char* feature_prefix = NULL;
1636 const char* feature = NULL;
1637 char buffer[256];
1638 int i;
1640 packet_reply_add(gdbctx, "<target>");
1641 switch (cpu->machine)
1643 case IMAGE_FILE_MACHINE_AMD64:
1644 packet_reply_add(gdbctx, "<architecture>i386:x86-64</architecture>");
1645 feature_prefix = "org.gnu.gdb.i386.";
1646 break;
1647 case IMAGE_FILE_MACHINE_I386:
1648 packet_reply_add(gdbctx, "<architecture>i386</architecture>");
1649 feature_prefix = "org.gnu.gdb.i386.";
1650 break;
1651 case IMAGE_FILE_MACHINE_ARMNT:
1652 packet_reply_add(gdbctx, "<architecture>arm</architecture>");
1653 feature_prefix = "org.gnu.gdb.arm.";
1654 break;
1655 case IMAGE_FILE_MACHINE_ARM64:
1656 packet_reply_add(gdbctx, "<architecture>aarch64</architecture>");
1657 feature_prefix = "org.gnu.gdb.aarch64.";
1658 break;
1661 for (i = 0; i < cpu->gdb_num_regs; ++i)
1663 if (cpu->gdb_register_map[i].feature)
1665 if (feature) packet_reply_add(gdbctx, "</feature>");
1666 feature = cpu->gdb_register_map[i].feature;
1668 packet_reply_add(gdbctx, "<feature name=\"");
1669 if (feature_prefix) packet_reply_add(gdbctx, feature_prefix);
1670 packet_reply_add(gdbctx, feature);
1671 packet_reply_add(gdbctx, "\">");
1673 if (strcmp(feature_prefix, "org.gnu.gdb.i386.") == 0 &&
1674 strcmp(feature, "core") == 0)
1675 packet_reply_add(gdbctx, "<flags id=\"i386_eflags\" size=\"4\">"
1676 "<field name=\"CF\" start=\"0\" end=\"0\"/>"
1677 "<field name=\"\" start=\"1\" end=\"1\"/>"
1678 "<field name=\"PF\" start=\"2\" end=\"2\"/>"
1679 "<field name=\"AF\" start=\"4\" end=\"4\"/>"
1680 "<field name=\"ZF\" start=\"6\" end=\"6\"/>"
1681 "<field name=\"SF\" start=\"7\" end=\"7\"/>"
1682 "<field name=\"TF\" start=\"8\" end=\"8\"/>"
1683 "<field name=\"IF\" start=\"9\" end=\"9\"/>"
1684 "<field name=\"DF\" start=\"10\" end=\"10\"/>"
1685 "<field name=\"OF\" start=\"11\" end=\"11\"/>"
1686 "<field name=\"NT\" start=\"14\" end=\"14\"/>"
1687 "<field name=\"RF\" start=\"16\" end=\"16\"/>"
1688 "<field name=\"VM\" start=\"17\" end=\"17\"/>"
1689 "<field name=\"AC\" start=\"18\" end=\"18\"/>"
1690 "<field name=\"VIF\" start=\"19\" end=\"19\"/>"
1691 "<field name=\"VIP\" start=\"20\" end=\"20\"/>"
1692 "<field name=\"ID\" start=\"21\" end=\"21\"/>"
1693 "</flags>");
1695 if (strcmp(feature_prefix, "org.gnu.gdb.i386.") == 0 &&
1696 strcmp(feature, "sse") == 0)
1697 packet_reply_add(gdbctx, "<vector id=\"v4f\" type=\"ieee_single\" count=\"4\"/>"
1698 "<vector id=\"v2d\" type=\"ieee_double\" count=\"2\"/>"
1699 "<vector id=\"v16i8\" type=\"int8\" count=\"16\"/>"
1700 "<vector id=\"v8i16\" type=\"int16\" count=\"8\"/>"
1701 "<vector id=\"v4i32\" type=\"int32\" count=\"4\"/>"
1702 "<vector id=\"v2i64\" type=\"int64\" count=\"2\"/>"
1703 "<union id=\"vec128\">"
1704 "<field name=\"v4_float\" type=\"v4f\"/>"
1705 "<field name=\"v2_double\" type=\"v2d\"/>"
1706 "<field name=\"v16_int8\" type=\"v16i8\"/>"
1707 "<field name=\"v8_int16\" type=\"v8i16\"/>"
1708 "<field name=\"v4_int32\" type=\"v4i32\"/>"
1709 "<field name=\"v2_int64\" type=\"v2i64\"/>"
1710 "<field name=\"uint128\" type=\"uint128\"/>"
1711 "</union>"
1712 "<flags id=\"i386_mxcsr\" size=\"4\">"
1713 "<field name=\"IE\" start=\"0\" end=\"0\"/>"
1714 "<field name=\"DE\" start=\"1\" end=\"1\"/>"
1715 "<field name=\"ZE\" start=\"2\" end=\"2\"/>"
1716 "<field name=\"OE\" start=\"3\" end=\"3\"/>"
1717 "<field name=\"UE\" start=\"4\" end=\"4\"/>"
1718 "<field name=\"PE\" start=\"5\" end=\"5\"/>"
1719 "<field name=\"DAZ\" start=\"6\" end=\"6\"/>"
1720 "<field name=\"IM\" start=\"7\" end=\"7\"/>"
1721 "<field name=\"DM\" start=\"8\" end=\"8\"/>"
1722 "<field name=\"ZM\" start=\"9\" end=\"9\"/>"
1723 "<field name=\"OM\" start=\"10\" end=\"10\"/>"
1724 "<field name=\"UM\" start=\"11\" end=\"11\"/>"
1725 "<field name=\"PM\" start=\"12\" end=\"12\"/>"
1726 "<field name=\"FZ\" start=\"15\" end=\"15\"/>"
1727 "</flags>");
1730 snprintf(buffer, ARRAY_SIZE(buffer), "<reg name=\"%s\" bitsize=\"%zu\"",
1731 cpu->gdb_register_map[i].name, 8 * cpu->gdb_register_map[i].length);
1732 packet_reply_add(gdbctx, buffer);
1734 if (cpu->gdb_register_map[i].type)
1736 packet_reply_add(gdbctx, " type=\"");
1737 packet_reply_add(gdbctx, cpu->gdb_register_map[i].type);
1738 packet_reply_add(gdbctx, "\"");
1741 packet_reply_add(gdbctx, "/>");
1744 if (feature) packet_reply_add(gdbctx, "</feature>");
1745 packet_reply_add(gdbctx, "</target>");
1748 static enum packet_return packet_query(struct gdb_context* gdbctx)
1750 int off, len;
1751 struct backend_cpu *cpu;
1753 switch (gdbctx->in_packet[0])
1755 case 'f':
1756 if (strncmp(gdbctx->in_packet + 1, "ThreadInfo", gdbctx->in_packet_len - 1) == 0)
1758 struct dbg_thread* thd;
1760 packet_reply_open(gdbctx);
1761 packet_reply_add(gdbctx, "m");
1762 LIST_FOR_EACH_ENTRY(thd, &gdbctx->process->threads, struct dbg_thread, entry)
1764 packet_reply_val(gdbctx, thd->tid, 4);
1765 if (list_next(&gdbctx->process->threads, &thd->entry) != NULL)
1766 packet_reply_add(gdbctx, ",");
1768 packet_reply_close(gdbctx);
1769 return packet_done;
1771 else if (strncmp(gdbctx->in_packet + 1, "ProcessInfo", gdbctx->in_packet_len - 1) == 0)
1773 char result[128];
1775 packet_reply_open(gdbctx);
1776 packet_reply_add(gdbctx, "O");
1777 get_process_info(gdbctx, result, sizeof(result));
1778 packet_reply_hex_to_str(gdbctx, result);
1779 packet_reply_close(gdbctx);
1780 return packet_done;
1782 break;
1783 case 's':
1784 if (strncmp(gdbctx->in_packet + 1, "ThreadInfo", gdbctx->in_packet_len - 1) == 0)
1786 packet_reply(gdbctx, "l");
1787 return packet_done;
1789 else if (strncmp(gdbctx->in_packet + 1, "ProcessInfo", gdbctx->in_packet_len - 1) == 0)
1791 packet_reply(gdbctx, "l");
1792 return packet_done;
1794 break;
1795 case 'A':
1796 if (strncmp(gdbctx->in_packet, "Attached", gdbctx->in_packet_len) == 0)
1797 return packet_reply(gdbctx, "1");
1798 break;
1799 case 'C':
1800 if (gdbctx->in_packet_len == 1)
1802 struct dbg_thread* thd;
1803 /* FIXME: doc says 16 bit val ??? */
1804 /* grab first created thread, aka last in list */
1805 assert(gdbctx->process && !list_empty(&gdbctx->process->threads));
1806 thd = LIST_ENTRY(list_tail(&gdbctx->process->threads), struct dbg_thread, entry);
1807 packet_reply_open(gdbctx);
1808 packet_reply_add(gdbctx, "QC");
1809 packet_reply_val(gdbctx, thd->tid, 4);
1810 packet_reply_close(gdbctx);
1811 return packet_done;
1813 break;
1814 case 'O':
1815 if (strncmp(gdbctx->in_packet, "Offsets", gdbctx->in_packet_len) == 0)
1817 char buf[64];
1819 snprintf(buf, sizeof(buf),
1820 "Text=%08lx;Data=%08lx;Bss=%08lx",
1821 gdbctx->wine_segs[0], gdbctx->wine_segs[1],
1822 gdbctx->wine_segs[2]);
1823 return packet_reply(gdbctx, buf);
1825 break;
1826 case 'R':
1827 if (gdbctx->in_packet_len > 5 && strncmp(gdbctx->in_packet, "Rcmd,", 5) == 0)
1829 return packet_query_remote_command(gdbctx, gdbctx->in_packet + 5,
1830 gdbctx->in_packet_len - 5);
1832 break;
1833 case 'S':
1834 if (strncmp(gdbctx->in_packet, "Symbol::", gdbctx->in_packet_len) == 0)
1835 return packet_ok;
1836 if (strncmp(gdbctx->in_packet, "Supported", 9) == 0)
1838 packet_reply_open(gdbctx);
1839 packet_reply_add(gdbctx, "QStartNoAckMode+;");
1840 packet_reply_add(gdbctx, "qXfer:libraries:read+;");
1841 packet_reply_add(gdbctx, "qXfer:threads:read+;");
1842 packet_reply_add(gdbctx, "qXfer:features:read+;");
1843 packet_reply_close(gdbctx);
1844 return packet_done;
1846 break;
1847 case 'T':
1848 if (gdbctx->in_packet_len > 15 &&
1849 strncmp(gdbctx->in_packet, "ThreadExtraInfo", 15) == 0 &&
1850 gdbctx->in_packet[15] == ',')
1852 unsigned tid;
1853 char* end;
1854 char result[128];
1856 tid = strtol(gdbctx->in_packet + 16, &end, 16);
1857 if (end == NULL) break;
1858 get_thread_info(gdbctx, tid, result, sizeof(result));
1859 packet_reply_open(gdbctx);
1860 packet_reply_hex_to_str(gdbctx, result);
1861 packet_reply_close(gdbctx);
1862 return packet_done;
1864 if (strncmp(gdbctx->in_packet, "TStatus", 7) == 0)
1866 /* Tracepoints not supported */
1867 packet_reply_open(gdbctx);
1868 packet_reply_close(gdbctx);
1869 return packet_done;
1871 break;
1872 case 'X':
1873 if (sscanf(gdbctx->in_packet, "Xfer:libraries:read::%x,%x", &off, &len) == 2)
1875 if (!gdbctx->process) return packet_error;
1877 packet_reply_open_xfer(gdbctx);
1878 packet_query_libraries(gdbctx);
1879 packet_reply_close_xfer(gdbctx, off, len);
1880 return packet_done;
1883 if (sscanf(gdbctx->in_packet, "Xfer:threads:read::%x,%x", &off, &len) == 2)
1885 if (!gdbctx->process) return packet_error;
1887 packet_reply_open_xfer(gdbctx);
1888 packet_query_threads(gdbctx);
1889 packet_reply_close_xfer(gdbctx, off, len);
1890 return packet_done;
1893 if (sscanf(gdbctx->in_packet, "Xfer:features:read:target.xml:%x,%x", &off, &len) == 2)
1895 if (!gdbctx->process) return packet_error;
1896 if (!(cpu = gdbctx->process->be_cpu)) return packet_error;
1898 packet_reply_open_xfer(gdbctx);
1899 packet_query_target_xml(gdbctx, cpu);
1900 packet_reply_close_xfer(gdbctx, off, len);
1901 return packet_done;
1903 break;
1905 ERR("Unhandled query %s\n", debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
1906 return packet_error;
1909 static enum packet_return packet_set(struct gdb_context* gdbctx)
1911 if (strncmp(gdbctx->in_packet, "StartNoAckMode", 14) == 0)
1913 gdbctx->no_ack_mode = TRUE;
1914 return packet_ok;
1917 return packet_error;
1920 static enum packet_return packet_step(struct gdb_context* gdbctx)
1922 void *addr;
1924 if (sscanf(gdbctx->in_packet, "%p", &addr) == 1)
1925 FIXME("Continue at address %p not supported\n", addr);
1927 handle_step_or_continue(gdbctx, gdbctx->exec_tid, TRUE, -1);
1929 wait_for_debuggee(gdbctx);
1930 return packet_reply_status(gdbctx);
1933 static enum packet_return packet_thread_alive(struct gdb_context* gdbctx)
1935 char* end;
1936 unsigned tid;
1938 tid = strtol(gdbctx->in_packet, &end, 16);
1939 if (tid == -1 || tid == 0)
1940 return packet_reply_error(gdbctx, EINVAL);
1941 if (dbg_get_thread(gdbctx->process, tid) != NULL)
1942 return packet_ok;
1943 return packet_reply_error(gdbctx, ESRCH);
1946 /* =============================================== *
1947 * P A C K E T I N F R A S T R U C T U R E *
1948 * =============================================== *
1951 struct packet_entry
1953 char key;
1954 enum packet_return (*handler)(struct gdb_context* gdbctx);
1957 static struct packet_entry packet_entries[] =
1959 {'?', packet_last_signal},
1960 {'c', packet_continue},
1961 {'C', packet_continue_signal},
1962 {'D', packet_detach},
1963 {'g', packet_read_registers},
1964 {'G', packet_write_registers},
1965 {'k', packet_kill},
1966 {'H', packet_thread},
1967 {'m', packet_read_memory},
1968 {'M', packet_write_memory},
1969 {'p', packet_read_register},
1970 {'P', packet_write_register},
1971 {'q', packet_query},
1972 {'Q', packet_set},
1973 {'s', packet_step},
1974 {'T', packet_thread_alive},
1975 {'v', packet_verbose},
1976 {'z', packet_delete_breakpoint},
1977 {'Z', packet_insert_breakpoint},
1980 static BOOL extract_packets(struct gdb_context* gdbctx)
1982 char *ptr, *sum = gdbctx->in_buf, *end = gdbctx->in_buf + gdbctx->in_len;
1983 enum packet_return ret = packet_error;
1984 unsigned int cksum;
1985 int i, len;
1987 /* ptr points to the beginning ('$') of the current packet
1988 * sum points to the beginning ('#') of the current packet checksum ("#xx")
1989 * len is the length of the current packet data (sum - ptr - 1)
1990 * end points to the end of the received data buffer
1993 while (!gdbctx->no_ack_mode &&
1994 (ptr = memchr(sum, '$', end - sum)) &&
1995 (sum = memchr(ptr, '#', end - ptr)) &&
1996 (end - sum >= 3) && sscanf(sum, "#%02x", &cksum) == 1)
1998 len = sum - ptr - 1;
1999 sum += 3;
2001 if (cksum == checksum(ptr + 1, len))
2003 TRACE("Acking: %s\n", debugstr_an(ptr, sum - ptr));
2004 write(gdbctx->sock, "+", 1);
2006 else
2008 ERR("Nacking: %s (checksum: %d != %d)\n", debugstr_an(ptr, sum - ptr),
2009 cksum, checksum(ptr + 1, len));
2010 write(gdbctx->sock, "-", 1);
2014 while ((ret & packet_last_f) == 0 &&
2015 (ptr = memchr(gdbctx->in_buf, '$', gdbctx->in_len)) &&
2016 (sum = memchr(ptr, '#', end - ptr)) &&
2017 (end - sum >= 3) && sscanf(sum, "#%02x", &cksum) == 1)
2019 if (ptr != gdbctx->in_buf)
2020 WARN("Ignoring: %s\n", debugstr_an(gdbctx->in_buf, ptr - gdbctx->in_buf));
2022 len = sum - ptr - 1;
2023 sum += 3;
2025 if (cksum == checksum(ptr + 1, len))
2027 TRACE("Handling: %s\n", debugstr_an(ptr, sum - ptr));
2029 ret = packet_error;
2030 gdbctx->in_packet = ptr + 2;
2031 gdbctx->in_packet_len = len - 1;
2032 gdbctx->in_packet[gdbctx->in_packet_len] = '\0';
2034 for (i = 0; i < ARRAY_SIZE(packet_entries); i++)
2035 if (packet_entries[i].key == ptr[1])
2036 break;
2038 if (i == ARRAY_SIZE(packet_entries))
2039 WARN("Unhandled: %s\n", debugstr_an(ptr + 1, len));
2040 else if (((ret = (packet_entries[i].handler)(gdbctx)) & ~packet_last_f) == packet_error)
2041 WARN("Failed: %s\n", debugstr_an(ptr + 1, len));
2043 switch (ret & ~packet_last_f)
2045 case packet_error: packet_reply(gdbctx, ""); break;
2046 case packet_ok: packet_reply(gdbctx, "OK"); break;
2047 case packet_done: break;
2050 TRACE("Reply: %s\n", debugstr_an(gdbctx->out_buf, gdbctx->out_len));
2051 i = write(gdbctx->sock, gdbctx->out_buf, gdbctx->out_len);
2052 assert(i == gdbctx->out_len);
2053 gdbctx->out_len = 0;
2055 else
2056 WARN("Ignoring: %s (checksum: %d != %d)\n", debugstr_an(ptr, sum - ptr),
2057 cksum, checksum(ptr + 1, len));
2059 gdbctx->in_len = end - sum;
2060 memmove(gdbctx->in_buf, sum, end - sum);
2061 end = gdbctx->in_buf + gdbctx->in_len;
2064 return (ret & packet_last_f);
2067 static int fetch_data(struct gdb_context* gdbctx)
2069 int len, in_len = gdbctx->in_len;
2071 assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
2072 for (;;)
2074 #define STEP 128
2075 if (gdbctx->in_len + STEP > gdbctx->in_buf_alloc)
2076 gdbctx->in_buf = packet_realloc(gdbctx->in_buf, gdbctx->in_buf_alloc += STEP);
2077 #undef STEP
2078 len = read(gdbctx->sock, gdbctx->in_buf + gdbctx->in_len, gdbctx->in_buf_alloc - gdbctx->in_len - 1);
2079 if (len <= 0) break;
2080 gdbctx->in_len += len;
2081 assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
2082 if (len < gdbctx->in_buf_alloc - gdbctx->in_len) break;
2085 gdbctx->in_buf[gdbctx->in_len] = '\0';
2086 return gdbctx->in_len - in_len;
2089 #define FLAG_NO_START 1
2090 #define FLAG_WITH_XTERM 2
2092 static BOOL gdb_exec(unsigned port, unsigned flags)
2094 char buf[MAX_PATH];
2095 int fd;
2096 const char *gdb_path, *tmp_path;
2097 FILE* f;
2099 if (!(gdb_path = getenv("WINE_GDB"))) gdb_path = "gdb";
2100 if (!(tmp_path = getenv("TMPDIR"))) tmp_path = "/tmp";
2101 strcpy(buf, tmp_path);
2102 strcat(buf, "/winegdb.XXXXXX");
2103 fd = mkstemps(buf, 0);
2104 if (fd == -1) return FALSE;
2105 if ((f = fdopen(fd, "w+")) == NULL) return FALSE;
2106 fprintf(f, "target remote localhost:%d\n", ntohs(port));
2107 fprintf(f, "set prompt Wine-gdb>\\ \n");
2108 /* gdb 5.1 seems to require it, won't hurt anyway */
2109 fprintf(f, "sharedlibrary\n");
2110 /* This is needed (but not a decent & final fix)
2111 * Without this, gdb would skip our inter-DLL relay code (because
2112 * we don't have any line number information for the relay code)
2113 * With this, we will stop on first instruction of the stub, and
2114 * reusing step, will get us through the relay stub at the actual
2115 * function we're looking at.
2117 fprintf(f, "set step-mode on\n");
2118 /* tell gdb to delete this file when done handling it... */
2119 fprintf(f, "shell rm -f \"%s\"\n", buf);
2120 fclose(f);
2121 if (flags & FLAG_WITH_XTERM)
2122 execlp("xterm", "xterm", "-e", gdb_path, "-x", buf, NULL);
2123 else
2124 execlp(gdb_path, gdb_path, "-x", buf, NULL);
2125 assert(0); /* never reached */
2126 return TRUE;
2129 static BOOL gdb_startup(struct gdb_context* gdbctx, unsigned flags, unsigned port)
2131 int sock;
2132 struct sockaddr_in s_addrs = {0};
2133 socklen_t s_len = sizeof(s_addrs);
2134 struct pollfd pollfd;
2135 BOOL ret = FALSE;
2137 /* step 1: create socket for gdb connection request */
2138 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
2140 ERR("Failed to create socket: %s\n", strerror(errno));
2141 return FALSE;
2144 s_addrs.sin_family = AF_INET;
2145 s_addrs.sin_addr.s_addr = INADDR_ANY;
2146 s_addrs.sin_port = htons(port);
2147 if (bind(sock, (struct sockaddr *)&s_addrs, sizeof(s_addrs)) == -1)
2148 goto cleanup;
2150 if (listen(sock, 1) == -1 || getsockname(sock, (struct sockaddr*)&s_addrs, &s_len) == -1)
2151 goto cleanup;
2153 /* step 2: do the process internal creation */
2154 handle_debug_event(gdbctx);
2156 /* step 3: fire up gdb (if requested) */
2157 if (flags & FLAG_NO_START)
2158 fprintf(stderr, "target remote localhost:%d\n", ntohs(s_addrs.sin_port));
2159 else
2160 switch (fork())
2162 case -1: /* error in parent... */
2163 ERR("Failed to start gdb: fork: %s\n", strerror(errno));
2164 goto cleanup;
2165 default: /* in parent... success */
2166 signal(SIGINT, SIG_IGN);
2167 break;
2168 case 0: /* in child... and alive */
2169 gdb_exec(s_addrs.sin_port, flags);
2170 /* if we're here, exec failed, so report failure */
2171 goto cleanup;
2174 /* step 4: wait for gdb to connect actually */
2175 pollfd.fd = sock;
2176 pollfd.events = POLLIN;
2177 pollfd.revents = 0;
2179 switch (poll(&pollfd, 1, -1))
2181 case 1:
2182 if (pollfd.revents & POLLIN)
2184 int dummy = 1;
2185 gdbctx->sock = accept(sock, (struct sockaddr*)&s_addrs, &s_len);
2186 if (gdbctx->sock == -1)
2187 break;
2188 ret = TRUE;
2189 TRACE("connected on %d\n", gdbctx->sock);
2190 /* don't keep our small packets too long: send them ASAP back to GDB
2191 * without this, GDB really crawls
2193 setsockopt(gdbctx->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&dummy, sizeof(dummy));
2195 break;
2196 case 0:
2197 ERR("Timed out connecting to gdb\n");
2198 break;
2199 case -1:
2200 ERR("Failed to connect to gdb: poll: %s\n", strerror(errno));
2201 break;
2202 default:
2203 assert(0);
2206 cleanup:
2207 close(sock);
2208 return ret;
2211 static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags, unsigned port)
2213 int i;
2215 gdbctx->sock = -1;
2216 gdbctx->in_buf = NULL;
2217 gdbctx->in_buf_alloc = 0;
2218 gdbctx->in_len = 0;
2219 gdbctx->out_buf = NULL;
2220 gdbctx->out_buf_alloc = 0;
2221 gdbctx->out_len = 0;
2222 gdbctx->out_curr_packet = -1;
2224 gdbctx->exec_tid = -1;
2225 gdbctx->other_tid = -1;
2226 list_init(&gdbctx->xpoint_list);
2227 gdbctx->process = NULL;
2228 gdbctx->no_ack_mode = FALSE;
2229 for (i = 0; i < ARRAY_SIZE(gdbctx->wine_segs); i++)
2230 gdbctx->wine_segs[i] = 0;
2232 /* wait for first trap */
2233 while (WaitForDebugEvent(&gdbctx->de, INFINITE))
2235 if (gdbctx->de.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT)
2237 /* this should be the first event we get,
2238 * and the only one of this type */
2239 assert(gdbctx->process == NULL && gdbctx->de.dwProcessId == dbg_curr_pid);
2240 /* gdbctx->dwProcessId = pid; */
2241 if (!gdb_startup(gdbctx, flags, port)) return FALSE;
2243 else if (!handle_debug_event(gdbctx))
2244 break;
2245 ContinueDebugEvent(gdbctx->de.dwProcessId, gdbctx->de.dwThreadId, DBG_CONTINUE);
2247 return TRUE;
2250 static int gdb_remote(unsigned flags, unsigned port)
2252 struct pollfd pollfd;
2253 struct gdb_context gdbctx;
2254 BOOL doLoop;
2256 for (doLoop = gdb_init_context(&gdbctx, flags, port); doLoop;)
2258 pollfd.fd = gdbctx.sock;
2259 pollfd.events = POLLIN;
2260 pollfd.revents = 0;
2262 switch (poll(&pollfd, 1, -1))
2264 case 1:
2265 /* got something */
2266 if (pollfd.revents & (POLLHUP | POLLERR))
2268 ERR("gdb hung up\n");
2269 /* kill also debuggee process - questionnable - */
2270 detach_debuggee(&gdbctx, TRUE);
2271 doLoop = FALSE;
2272 break;
2274 if ((pollfd.revents & POLLIN) && fetch_data(&gdbctx) > 0)
2276 if (extract_packets(&gdbctx)) doLoop = FALSE;
2278 break;
2279 case 0:
2280 /* timeout, should never happen (infinite timeout) */
2281 break;
2282 case -1:
2283 ERR("poll failed: %s\n", strerror(errno));
2284 doLoop = FALSE;
2285 break;
2288 wait(NULL);
2289 return 0;
2291 #endif
2293 int gdb_main(int argc, char* argv[])
2295 #ifdef HAVE_POLL
2296 unsigned gdb_flags = 0, port = 0;
2297 char *port_end;
2299 argc--; argv++;
2300 while (argc > 0 && argv[0][0] == '-')
2302 if (strcmp(argv[0], "--no-start") == 0)
2304 gdb_flags |= FLAG_NO_START;
2305 argc--; argv++;
2306 continue;
2308 if (strcmp(argv[0], "--with-xterm") == 0)
2310 gdb_flags |= FLAG_WITH_XTERM;
2311 argc--; argv++;
2312 continue;
2314 if (strcmp(argv[0], "--port") == 0 && argc > 1)
2316 port = strtoul(argv[1], &port_end, 10);
2317 if (*port_end)
2319 fprintf(stderr, "Invalid port: %s\n", argv[1]);
2320 return -1;
2322 argc -= 2; argv += 2;
2323 continue;
2325 return -1;
2327 if (dbg_active_attach(argc, argv) == start_ok ||
2328 dbg_active_launch(argc, argv) == start_ok)
2329 return gdb_remote(gdb_flags, port);
2330 #else
2331 fprintf(stderr, "GdbProxy mode not supported on this platform\n");
2332 #endif
2333 return -1;