kernel32: Get rid of the binary_info structure.
[wine.git] / programs / winedbg / gdbproxy.c
blob025cb38131005b531a7dab7e92bc70c6067551a6
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/debug.h"
68 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
70 struct gdb_context
72 /* gdb information */
73 int sock;
74 /* incoming buffer */
75 char* in_buf;
76 int in_buf_alloc;
77 int in_len;
78 /* split into individual packet */
79 char* in_packet;
80 int in_packet_len;
81 /* outgoing buffer */
82 char* out_buf;
83 int out_buf_alloc;
84 int out_len;
85 int out_curr_packet;
86 /* generic GDB thread information */
87 struct dbg_thread* exec_thread; /* thread used in step & continue */
88 struct dbg_thread* other_thread; /* thread to be used in any other operation */
89 /* current Win32 trap env */
90 unsigned last_sig;
91 BOOL in_trap;
92 dbg_ctx_t context;
93 /* Win32 information */
94 struct dbg_process* process;
95 /* Unix environment */
96 unsigned long wine_segs[3]; /* load addresses of the ELF wine exec segments (text, bss and data) */
99 static BOOL tgt_process_gdbproxy_read(HANDLE hProcess, const void* addr,
100 void* buffer, SIZE_T len, SIZE_T* rlen)
102 return ReadProcessMemory( hProcess, addr, buffer, len, rlen );
105 static BOOL tgt_process_gdbproxy_write(HANDLE hProcess, void* addr,
106 const void* buffer, SIZE_T len, SIZE_T* wlen)
108 return WriteProcessMemory( hProcess, addr, buffer, len, wlen );
111 static struct be_process_io be_process_gdbproxy_io =
113 NULL, /* we shouldn't use close_process() in gdbproxy */
114 tgt_process_gdbproxy_read,
115 tgt_process_gdbproxy_write
118 /* =============================================== *
119 * B A S I C M A N I P U L A T I O N S *
120 * =============================================== *
123 static inline int hex_from0(char ch)
125 if (ch >= '0' && ch <= '9') return ch - '0';
126 if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
127 if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
129 assert(0);
130 return 0;
133 static inline unsigned char hex_to0(int x)
135 assert(x >= 0 && x < 16);
136 return "0123456789abcdef"[x];
139 static int hex_to_int(const char* src, size_t len)
141 unsigned int returnval = 0;
142 while (len--)
144 returnval <<= 4;
145 returnval |= hex_from0(*src++);
147 return returnval;
150 static void hex_from(void* dst, const char* src, size_t len)
152 unsigned char *p = dst;
153 while (len--)
155 *p++ = (hex_from0(src[0]) << 4) | hex_from0(src[1]);
156 src += 2;
160 static void hex_to(char* dst, const void* src, size_t len)
162 const unsigned char *p = src;
163 while (len--)
165 *dst++ = hex_to0(*p >> 4);
166 *dst++ = hex_to0(*p & 0x0F);
167 p++;
171 static unsigned char checksum(const char* ptr, int len)
173 unsigned cksum = 0;
175 while (len-- > 0)
176 cksum += (unsigned char)*ptr++;
177 return cksum;
180 #ifdef __i386__
181 static const char target_xml[] = "";
182 #elif defined(__powerpc__)
183 static const char target_xml[] = "";
184 #elif defined(__x86_64__)
185 static const char target_xml[] = "";
186 #elif defined(__arm__)
187 static const char target_xml[] =
188 "l <target><architecture>arm</architecture>\n"
189 "<feature name=\"org.gnu.gdb.arm.core\">\n"
190 " <reg name=\"r0\" bitsize=\"32\" type=\"uint32\"/>\n"
191 " <reg name=\"r1\" bitsize=\"32\" type=\"uint32\"/>\n"
192 " <reg name=\"r2\" bitsize=\"32\" type=\"uint32\"/>\n"
193 " <reg name=\"r3\" bitsize=\"32\" type=\"uint32\"/>\n"
194 " <reg name=\"r4\" bitsize=\"32\" type=\"uint32\"/>\n"
195 " <reg name=\"r5\" bitsize=\"32\" type=\"uint32\"/>\n"
196 " <reg name=\"r6\" bitsize=\"32\" type=\"uint32\"/>\n"
197 " <reg name=\"r7\" bitsize=\"32\" type=\"uint32\"/>\n"
198 " <reg name=\"r8\" bitsize=\"32\" type=\"uint32\"/>\n"
199 " <reg name=\"r9\" bitsize=\"32\" type=\"uint32\"/>\n"
200 " <reg name=\"r10\" bitsize=\"32\" type=\"uint32\"/>\n"
201 " <reg name=\"r11\" bitsize=\"32\" type=\"uint32\"/>\n"
202 " <reg name=\"r12\" bitsize=\"32\" type=\"uint32\"/>\n"
203 " <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\n"
204 " <reg name=\"lr\" bitsize=\"32\"/>\n"
205 " <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\n"
206 " <reg name=\"cpsr\" bitsize=\"32\"/>\n"
207 "</feature></target>\n";
208 #elif defined(__aarch64__)
209 static const char target_xml[] = "";
210 #else
211 # error Define the registers map for your CPU
212 #endif
214 static inline void* cpu_register_ptr(struct gdb_context *gdbctx,
215 dbg_ctx_t *ctx, unsigned idx)
217 assert(idx < gdbctx->process->be_cpu->gdb_num_regs);
218 return (char*)ctx + gdbctx->process->be_cpu->gdb_register_map[idx].ctx_offset;
221 static inline DWORD64 cpu_register(struct gdb_context *gdbctx,
222 dbg_ctx_t *ctx, unsigned idx)
224 switch (gdbctx->process->be_cpu->gdb_register_map[idx].ctx_length)
226 case 1: return *(BYTE*)cpu_register_ptr(gdbctx, ctx, idx);
227 case 2: return *(WORD*)cpu_register_ptr(gdbctx, ctx, idx);
228 case 4: return *(DWORD*)cpu_register_ptr(gdbctx, ctx, idx);
229 case 8: return *(DWORD64*)cpu_register_ptr(gdbctx, ctx, idx);
230 default:
231 ERR("got unexpected size: %u\n",
232 (unsigned)gdbctx->process->be_cpu->gdb_register_map[idx].ctx_length);
233 assert(0);
234 return 0;
238 static inline void cpu_register_hex_from(struct gdb_context *gdbctx,
239 dbg_ctx_t* ctx, unsigned idx, const char **phex)
241 const struct gdb_register *cpu_register_map = gdbctx->process->be_cpu->gdb_register_map;
243 if (cpu_register_map[idx].gdb_length == cpu_register_map[idx].ctx_length)
244 hex_from(cpu_register_ptr(gdbctx, ctx, idx), *phex, cpu_register_map[idx].gdb_length);
245 else
247 DWORD64 val = 0;
248 unsigned i;
249 BYTE b;
251 for (i = 0; i < cpu_register_map[idx].gdb_length; i++)
253 hex_from(&b, *phex, 1);
254 *phex += 2;
255 val += (DWORD64)b << (8 * i);
257 switch (cpu_register_map[idx].ctx_length)
259 case 1: *(BYTE*)cpu_register_ptr(gdbctx, ctx, idx) = (BYTE)val; break;
260 case 2: *(WORD*)cpu_register_ptr(gdbctx, ctx, idx) = (WORD)val; break;
261 case 4: *(DWORD*)cpu_register_ptr(gdbctx, ctx, idx) = (DWORD)val; break;
262 case 8: *(DWORD64*)cpu_register_ptr(gdbctx, ctx, idx) = val; break;
263 default: assert(0);
268 /* =============================================== *
269 * W I N 3 2 D E B U G I N T E R F A C E *
270 * =============================================== *
273 static BOOL fetch_context(struct gdb_context *gdbctx, HANDLE h, dbg_ctx_t *ctx)
275 if (!gdbctx->process->be_cpu->get_context(h, ctx))
277 ERR("Failed to get context, error %u\n", GetLastError());
278 return FALSE;
280 return TRUE;
283 static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* exc)
285 EXCEPTION_RECORD* rec = &exc->ExceptionRecord;
286 BOOL ret = FALSE;
288 switch (rec->ExceptionCode)
290 case EXCEPTION_ACCESS_VIOLATION:
291 case EXCEPTION_PRIV_INSTRUCTION:
292 case EXCEPTION_STACK_OVERFLOW:
293 case EXCEPTION_GUARD_PAGE:
294 gdbctx->last_sig = SIGSEGV;
295 ret = TRUE;
296 break;
297 case EXCEPTION_DATATYPE_MISALIGNMENT:
298 gdbctx->last_sig = SIGBUS;
299 ret = TRUE;
300 break;
301 case EXCEPTION_SINGLE_STEP:
302 /* fall through */
303 case EXCEPTION_BREAKPOINT:
304 gdbctx->last_sig = SIGTRAP;
305 ret = TRUE;
306 break;
307 case EXCEPTION_FLT_DENORMAL_OPERAND:
308 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
309 case EXCEPTION_FLT_INEXACT_RESULT:
310 case EXCEPTION_FLT_INVALID_OPERATION:
311 case EXCEPTION_FLT_OVERFLOW:
312 case EXCEPTION_FLT_STACK_CHECK:
313 case EXCEPTION_FLT_UNDERFLOW:
314 gdbctx->last_sig = SIGFPE;
315 ret = TRUE;
316 break;
317 case EXCEPTION_INT_DIVIDE_BY_ZERO:
318 case EXCEPTION_INT_OVERFLOW:
319 gdbctx->last_sig = SIGFPE;
320 ret = TRUE;
321 break;
322 case EXCEPTION_ILLEGAL_INSTRUCTION:
323 gdbctx->last_sig = SIGILL;
324 ret = TRUE;
325 break;
326 case CONTROL_C_EXIT:
327 gdbctx->last_sig = SIGINT;
328 ret = TRUE;
329 break;
330 case STATUS_POSSIBLE_DEADLOCK:
331 gdbctx->last_sig = SIGALRM;
332 ret = TRUE;
333 /* FIXME: we could also add here a O packet with additional information */
334 break;
335 case EXCEPTION_NAME_THREAD:
337 const THREADNAME_INFO *threadname = (const THREADNAME_INFO *)rec->ExceptionInformation;
338 struct dbg_thread *thread;
339 char name[9];
340 SIZE_T read;
342 if (threadname->dwThreadID == -1)
343 thread = dbg_curr_thread;
344 else
345 thread = dbg_get_thread(gdbctx->process, threadname->dwThreadID);
346 if (thread)
348 if (gdbctx->process->process_io->read( gdbctx->process->handle,
349 threadname->szName, name, sizeof(name), &read) && read == sizeof(name))
351 fprintf(stderr, "Thread ID=%04x renamed to \"%.9s\"\n",
352 threadname->dwThreadID, name);
355 else
356 ERR("Cannot set name of thread %04x\n", threadname->dwThreadID);
357 return DBG_CONTINUE;
359 case EXCEPTION_INVALID_HANDLE:
360 return DBG_CONTINUE;
361 default:
362 fprintf(stderr, "Unhandled exception code 0x%08x\n", rec->ExceptionCode);
363 gdbctx->last_sig = SIGABRT;
364 ret = TRUE;
365 break;
367 return ret;
370 static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
372 union {
373 char bufferA[256];
374 WCHAR buffer[256];
375 } u;
377 dbg_curr_thread = dbg_get_thread(gdbctx->process, de->dwThreadId);
379 switch (de->dwDebugEventCode)
381 case CREATE_PROCESS_DEBUG_EVENT:
382 gdbctx->process = dbg_add_process(&be_process_gdbproxy_io, de->dwProcessId,
383 de->u.CreateProcessInfo.hProcess);
384 if (!gdbctx->process) break;
385 memory_get_string_indirect(gdbctx->process,
386 de->u.CreateProcessInfo.lpImageName,
387 de->u.CreateProcessInfo.fUnicode,
388 u.buffer, ARRAY_SIZE(u.buffer));
389 dbg_set_process_name(gdbctx->process, u.buffer);
391 fprintf(stderr, "%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n",
392 de->dwProcessId, de->dwThreadId,
393 dbg_W2A(u.buffer, -1),
394 de->u.CreateProcessInfo.lpImageName,
395 de->u.CreateProcessInfo.lpStartAddress,
396 de->u.CreateProcessInfo.dwDebugInfoFileOffset,
397 de->u.CreateProcessInfo.nDebugInfoSize);
399 /* de->u.CreateProcessInfo.lpStartAddress; */
400 if (!dbg_init(gdbctx->process->handle, u.buffer, TRUE))
401 ERR("Couldn't initiate DbgHelp\n");
403 fprintf(stderr, "%04x:%04x: create thread I @%p\n", de->dwProcessId,
404 de->dwThreadId, de->u.CreateProcessInfo.lpStartAddress);
406 assert(dbg_curr_thread == NULL); /* shouldn't be there */
407 dbg_add_thread(gdbctx->process, de->dwThreadId,
408 de->u.CreateProcessInfo.hThread,
409 de->u.CreateProcessInfo.lpThreadLocalBase);
410 break;
412 case LOAD_DLL_DEBUG_EVENT:
413 assert(dbg_curr_thread);
414 memory_get_string_indirect(gdbctx->process,
415 de->u.LoadDll.lpImageName,
416 de->u.LoadDll.fUnicode,
417 u.buffer, ARRAY_SIZE(u.buffer));
418 fprintf(stderr, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
419 de->dwProcessId, de->dwThreadId,
420 dbg_W2A(u.buffer, -1),
421 de->u.LoadDll.lpBaseOfDll,
422 de->u.LoadDll.dwDebugInfoFileOffset,
423 de->u.LoadDll.nDebugInfoSize);
424 dbg_load_module(gdbctx->process->handle, de->u.LoadDll.hFile, u.buffer,
425 (DWORD_PTR)de->u.LoadDll.lpBaseOfDll, 0);
426 break;
428 case UNLOAD_DLL_DEBUG_EVENT:
429 fprintf(stderr, "%08x:%08x: unload DLL @%p\n",
430 de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll);
431 SymUnloadModule(gdbctx->process->handle,
432 (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll);
433 break;
435 case EXCEPTION_DEBUG_EVENT:
436 assert(dbg_curr_thread);
437 TRACE("%08x:%08x: exception code=0x%08x\n", de->dwProcessId,
438 de->dwThreadId, de->u.Exception.ExceptionRecord.ExceptionCode);
440 if (fetch_context(gdbctx, dbg_curr_thread->handle, &gdbctx->context))
442 gdbctx->in_trap = handle_exception(gdbctx, &de->u.Exception);
444 break;
446 case CREATE_THREAD_DEBUG_EVENT:
447 fprintf(stderr, "%08x:%08x: create thread D @%p\n", de->dwProcessId,
448 de->dwThreadId, de->u.CreateThread.lpStartAddress);
450 dbg_add_thread(gdbctx->process,
451 de->dwThreadId,
452 de->u.CreateThread.hThread,
453 de->u.CreateThread.lpThreadLocalBase);
454 break;
456 case EXIT_THREAD_DEBUG_EVENT:
457 fprintf(stderr, "%08x:%08x: exit thread (%u)\n",
458 de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
460 assert(dbg_curr_thread);
461 if (dbg_curr_thread == gdbctx->exec_thread) gdbctx->exec_thread = NULL;
462 if (dbg_curr_thread == gdbctx->other_thread) gdbctx->other_thread = NULL;
463 dbg_del_thread(dbg_curr_thread);
464 break;
466 case EXIT_PROCESS_DEBUG_EVENT:
467 fprintf(stderr, "%08x:%08x: exit process (%u)\n",
468 de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode);
470 dbg_del_process(gdbctx->process);
471 gdbctx->process = NULL;
472 /* now signal gdb that we're done */
473 gdbctx->last_sig = SIGTERM;
474 gdbctx->in_trap = TRUE;
475 break;
477 case OUTPUT_DEBUG_STRING_EVENT:
478 assert(dbg_curr_thread);
479 memory_get_string(gdbctx->process,
480 de->u.DebugString.lpDebugStringData, TRUE,
481 de->u.DebugString.fUnicode, u.bufferA, sizeof(u.bufferA));
482 fprintf(stderr, "%08x:%08x: output debug string (%s)\n",
483 de->dwProcessId, de->dwThreadId, debugstr_a(u.bufferA));
484 break;
486 case RIP_EVENT:
487 fprintf(stderr, "%08x:%08x: rip error=%u type=%u\n", de->dwProcessId,
488 de->dwThreadId, de->u.RipInfo.dwError, de->u.RipInfo.dwType);
489 break;
491 default:
492 FIXME("%08x:%08x: unknown event (%u)\n",
493 de->dwProcessId, de->dwThreadId, de->dwDebugEventCode);
497 static void resume_debuggee(struct gdb_context* gdbctx, DWORD cont)
499 if (dbg_curr_thread)
501 if (!gdbctx->process->be_cpu->set_context(dbg_curr_thread->handle, &gdbctx->context))
502 ERR("Failed to set context for thread %04x, error %u\n",
503 dbg_curr_thread->tid, GetLastError());
504 if (!ContinueDebugEvent(gdbctx->process->pid, dbg_curr_thread->tid, cont))
505 ERR("Failed to continue thread %04x, error %u\n",
506 dbg_curr_thread->tid, GetLastError());
508 else
509 ERR("Cannot find last thread\n");
513 static void resume_debuggee_thread(struct gdb_context* gdbctx, DWORD cont, unsigned int threadid)
516 if (dbg_curr_thread)
518 if(dbg_curr_thread->tid == threadid){
519 /* Windows debug and GDB don't seem to work well here, windows only likes ContinueDebugEvent being used on the reporter of the event */
520 if (!gdbctx->process->be_cpu->set_context(dbg_curr_thread->handle, &gdbctx->context))
521 ERR("Failed to set context for thread %04x, error %u\n",
522 dbg_curr_thread->tid, GetLastError());
523 if (!ContinueDebugEvent(gdbctx->process->pid, dbg_curr_thread->tid, cont))
524 ERR("Failed to continue thread %04x, error %u\n",
525 dbg_curr_thread->tid, GetLastError());
528 else
529 ERR("Cannot find last thread\n");
532 static BOOL check_for_interrupt(struct gdb_context* gdbctx)
534 struct pollfd pollfd;
535 int ret;
536 char pkt;
538 pollfd.fd = gdbctx->sock;
539 pollfd.events = POLLIN;
540 pollfd.revents = 0;
542 if ((ret = poll(&pollfd, 1, 0)) == 1) {
543 ret = read(gdbctx->sock, &pkt, 1);
544 if (ret != 1) {
545 ERR("read failed\n");
546 return FALSE;
548 if (pkt != '\003') {
549 ERR("Unexpected break packet %#02x\n", pkt);
550 return FALSE;
552 return TRUE;
553 } else if (ret == -1) {
554 ERR("poll failed\n");
556 return FALSE;
559 static void wait_for_debuggee(struct gdb_context* gdbctx)
561 DEBUG_EVENT de;
563 gdbctx->in_trap = FALSE;
564 for (;;)
566 if (!WaitForDebugEvent(&de, 10))
568 if (GetLastError() == ERROR_SEM_TIMEOUT)
570 if (check_for_interrupt(gdbctx)) {
571 if (!DebugBreakProcess(gdbctx->process->handle)) {
572 ERR("Failed to break into debugee\n");
573 break;
575 WaitForDebugEvent(&de, INFINITE);
576 } else {
577 continue;
579 } else {
580 break;
583 handle_debug_event(gdbctx, &de);
584 assert(!gdbctx->process ||
585 gdbctx->process->pid == 0 ||
586 de.dwProcessId == gdbctx->process->pid);
587 assert(!dbg_curr_thread || de.dwThreadId == dbg_curr_thread->tid);
588 if (gdbctx->in_trap) break;
589 ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
593 static void detach_debuggee(struct gdb_context* gdbctx, BOOL kill)
595 assert(gdbctx->process->be_cpu);
596 gdbctx->process->be_cpu->single_step(&gdbctx->context, FALSE);
597 resume_debuggee(gdbctx, DBG_CONTINUE);
598 if (!kill)
599 DebugActiveProcessStop(gdbctx->process->pid);
600 dbg_del_process(gdbctx->process);
601 gdbctx->process = NULL;
604 static void get_process_info(struct gdb_context* gdbctx, char* buffer, size_t len)
606 DWORD status;
608 if (!GetExitCodeProcess(gdbctx->process->handle, &status))
610 strcpy(buffer, "Unknown process");
611 return;
613 if (status == STILL_ACTIVE)
615 strcpy(buffer, "Running");
617 else
618 snprintf(buffer, len, "Terminated (%u)", status);
620 switch (GetPriorityClass(gdbctx->process->handle))
622 case 0: break;
623 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
624 case ABOVE_NORMAL_PRIORITY_CLASS: strcat(buffer, ", above normal priority"); break;
625 #endif
626 #ifdef BELOW_NORMAL_PRIORITY_CLASS
627 case BELOW_NORMAL_PRIORITY_CLASS: strcat(buffer, ", below normal priotity"); break;
628 #endif
629 case HIGH_PRIORITY_CLASS: strcat(buffer, ", high priority"); break;
630 case IDLE_PRIORITY_CLASS: strcat(buffer, ", idle priority"); break;
631 case NORMAL_PRIORITY_CLASS: strcat(buffer, ", normal priority"); break;
632 case REALTIME_PRIORITY_CLASS: strcat(buffer, ", realtime priority"); break;
634 strcat(buffer, "\n");
637 static void get_thread_info(struct gdb_context* gdbctx, unsigned tid,
638 char* buffer, size_t len)
640 struct dbg_thread* thd;
641 DWORD status;
642 int prio;
644 /* FIXME: use the size of buffer */
645 thd = dbg_get_thread(gdbctx->process, tid);
646 if (thd == NULL)
648 strcpy(buffer, "No information");
649 return;
651 if (GetExitCodeThread(thd->handle, &status))
653 if (status == STILL_ACTIVE)
655 /* FIXME: this is a bit brutal... some nicer way shall be found */
656 switch (status = SuspendThread(thd->handle))
658 case -1: break;
659 case 0: strcpy(buffer, "Running"); break;
660 default: snprintf(buffer, len, "Suspended (%u)", status - 1);
662 ResumeThread(thd->handle);
664 else
665 snprintf(buffer, len, "Terminated (exit code = %u)", status);
667 else
669 strcpy(buffer, "Unknown threadID");
671 switch (prio = GetThreadPriority(thd->handle))
673 case THREAD_PRIORITY_ERROR_RETURN: break;
674 case THREAD_PRIORITY_ABOVE_NORMAL: strcat(buffer, ", priority +1 above normal"); break;
675 case THREAD_PRIORITY_BELOW_NORMAL: strcat(buffer, ", priority -1 below normal"); break;
676 case THREAD_PRIORITY_HIGHEST: strcat(buffer, ", priority +2 above normal"); break;
677 case THREAD_PRIORITY_LOWEST: strcat(buffer, ", priority -2 below normal"); break;
678 case THREAD_PRIORITY_IDLE: strcat(buffer, ", priority idle"); break;
679 case THREAD_PRIORITY_NORMAL: strcat(buffer, ", priority normal"); break;
680 case THREAD_PRIORITY_TIME_CRITICAL: strcat(buffer, ", priority time-critical"); break;
681 default: snprintf(buffer + strlen(buffer), len - strlen(buffer), ", priority = %d", prio);
683 assert(strlen(buffer) < len);
686 /* =============================================== *
687 * P A C K E T U T I L S *
688 * =============================================== *
691 enum packet_return {packet_error = 0x00, packet_ok = 0x01, packet_done = 0x02,
692 packet_last_f = 0x80};
694 static char* packet_realloc(char* buf, int size)
696 if (!buf)
697 return HeapAlloc(GetProcessHeap(), 0, size);
698 return HeapReAlloc(GetProcessHeap(), 0, buf, size);
702 static void packet_reply_grow(struct gdb_context* gdbctx, size_t size)
704 if (gdbctx->out_buf_alloc < gdbctx->out_len + size)
706 gdbctx->out_buf_alloc = ((gdbctx->out_len + size) / 32 + 1) * 32;
707 gdbctx->out_buf = packet_realloc(gdbctx->out_buf, gdbctx->out_buf_alloc);
711 static void packet_reply_hex_to(struct gdb_context* gdbctx, const void* src, int len)
713 packet_reply_grow(gdbctx, len * 2);
714 hex_to(&gdbctx->out_buf[gdbctx->out_len], src, len);
715 gdbctx->out_len += len * 2;
718 static inline void packet_reply_hex_to_str(struct gdb_context* gdbctx, const char* src)
720 packet_reply_hex_to(gdbctx, src, strlen(src));
723 static void packet_reply_val(struct gdb_context* gdbctx, unsigned long val, int len)
725 int i, shift;
727 shift = (len - 1) * 8;
728 packet_reply_grow(gdbctx, len * 2);
729 for (i = 0; i < len; i++, shift -= 8)
731 gdbctx->out_buf[gdbctx->out_len++] = hex_to0((val >> (shift + 4)) & 0x0F);
732 gdbctx->out_buf[gdbctx->out_len++] = hex_to0((val >> shift ) & 0x0F);
736 static inline void packet_reply_add(struct gdb_context* gdbctx, const char* str, int len)
738 packet_reply_grow(gdbctx, len);
739 memcpy(&gdbctx->out_buf[gdbctx->out_len], str, len);
740 gdbctx->out_len += len;
743 static inline void packet_reply_cat(struct gdb_context* gdbctx, const char* str)
745 packet_reply_add(gdbctx, str, strlen(str));
748 static inline void packet_reply_catc(struct gdb_context* gdbctx, char ch)
750 packet_reply_add(gdbctx, &ch, 1);
753 static void packet_reply_open(struct gdb_context* gdbctx)
755 assert(gdbctx->out_curr_packet == -1);
756 packet_reply_catc(gdbctx, '$');
757 gdbctx->out_curr_packet = gdbctx->out_len;
760 static void packet_reply_close(struct gdb_context* gdbctx)
762 unsigned char cksum;
763 int plen;
765 plen = gdbctx->out_len - gdbctx->out_curr_packet;
766 packet_reply_catc(gdbctx, '#');
767 cksum = checksum(&gdbctx->out_buf[gdbctx->out_curr_packet], plen);
768 packet_reply_hex_to(gdbctx, &cksum, 1);
769 gdbctx->out_curr_packet = -1;
772 static enum packet_return packet_reply(struct gdb_context* gdbctx, const char* packet, int len)
774 packet_reply_open(gdbctx);
776 if (len == -1) len = strlen(packet);
777 assert(memchr(packet, '$', len) == NULL && memchr(packet, '#', len) == NULL);
779 packet_reply_add(gdbctx, packet, len);
781 packet_reply_close(gdbctx);
783 return packet_done;
786 static enum packet_return packet_reply_error(struct gdb_context* gdbctx, int error)
788 packet_reply_open(gdbctx);
790 packet_reply_add(gdbctx, "E", 1);
791 packet_reply_val(gdbctx, error, 1);
793 packet_reply_close(gdbctx);
795 return packet_done;
798 static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, unsigned idx)
800 const struct gdb_register *cpu_register_map = gdbctx->process->be_cpu->gdb_register_map;
802 if (cpu_register_map[idx].gdb_length == cpu_register_map[idx].ctx_length)
803 packet_reply_hex_to(gdbctx, cpu_register_ptr(gdbctx, &gdbctx->context, idx),
804 cpu_register_map[idx].gdb_length);
805 else
807 DWORD64 val = cpu_register(gdbctx, &gdbctx->context, idx);
808 unsigned i;
810 for (i = 0; i < cpu_register_map[idx].gdb_length; i++)
812 BYTE b = val;
813 packet_reply_hex_to(gdbctx, &b, 1);
814 val >>= 8;
819 /* =============================================== *
820 * P A C K E T H A N D L E R S *
821 * =============================================== *
824 static enum packet_return packet_reply_status(struct gdb_context* gdbctx)
826 enum packet_return ret = packet_done;
828 packet_reply_open(gdbctx);
830 if (gdbctx->process != NULL)
832 unsigned char sig;
833 unsigned i;
835 packet_reply_catc(gdbctx, 'T');
836 sig = gdbctx->last_sig;
837 packet_reply_val(gdbctx, sig, 1);
838 packet_reply_add(gdbctx, "thread:", 7);
839 packet_reply_val(gdbctx, dbg_curr_thread->tid, 4);
840 packet_reply_catc(gdbctx, ';');
842 for (i = 0; i < gdbctx->process->be_cpu->gdb_num_regs; i++)
844 /* FIXME: this call will also grow the buffer...
845 * unneeded, but not harmful
847 packet_reply_val(gdbctx, i, 1);
848 packet_reply_catc(gdbctx, ':');
849 packet_reply_register_hex_to(gdbctx, i);
850 packet_reply_catc(gdbctx, ';');
853 else
855 /* Try to put an exit code
856 * Cannot use GetExitCodeProcess, wouldn't fit in a 8 bit value, so
857 * just indicate the end of process and exit */
858 packet_reply_add(gdbctx, "W00", 3);
859 /*if (!gdbctx->extended)*/ ret |= packet_last_f;
862 packet_reply_close(gdbctx);
864 return ret;
867 #if 0
868 static enum packet_return packet_extended(struct gdb_context* gdbctx)
870 gdbctx->extended = 1;
871 return packet_ok;
873 #endif
875 static enum packet_return packet_last_signal(struct gdb_context* gdbctx)
877 assert(gdbctx->in_packet_len == 0);
878 return packet_reply_status(gdbctx);
881 static enum packet_return packet_continue(struct gdb_context* gdbctx)
883 /* FIXME: add support for address in packet */
884 assert(gdbctx->in_packet_len == 0);
885 if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
886 FIXME("Can't continue thread %04x while on thread %04x\n",
887 gdbctx->exec_thread->tid, dbg_curr_thread->tid);
888 resume_debuggee(gdbctx, DBG_CONTINUE);
889 wait_for_debuggee(gdbctx);
890 return packet_reply_status(gdbctx);
893 static enum packet_return packet_verbose_cont(struct gdb_context* gdbctx)
895 int i;
896 int defaultAction = -1; /* magic non action */
897 unsigned char sig;
898 int actions =0;
899 int actionIndex[20]; /* allow for up to 20 actions */
900 int threadIndex[20];
901 int threadCount = 0;
902 unsigned int threadIDs[100]; /* TODO: Should make this dynamic */
903 unsigned int threadID = 0;
904 struct dbg_thread* thd;
906 /* OK we have vCont followed by..
907 * ? for query
908 * c for packet_continue
909 * Csig for packet_continue_signal
910 * s for step
911 * Ssig for step signal
912 * and then an optional thread ID at the end..
913 * *******************************************/
915 /* Query */
916 if (gdbctx->in_packet[4] == '?')
919 Reply:
920 `vCont[;action]...'
921 The vCont packet is supported. Each action is a supported command in the vCont packet.
923 The vCont packet is not supported. (this didn't seem to be obeyed!)
925 packet_reply_open(gdbctx);
926 packet_reply_add(gdbctx, "vCont", 5);
927 /* add all the supported actions to the reply (all of them for now) */
928 packet_reply_add(gdbctx, ";c", 2);
929 packet_reply_add(gdbctx, ";C", 2);
930 packet_reply_add(gdbctx, ";s", 2);
931 packet_reply_add(gdbctx, ";S", 2);
932 packet_reply_close(gdbctx);
933 return packet_done;
936 /* go through the packet and identify where all the actions start at */
937 for (i = 4; i < gdbctx->in_packet_len - 1; i++)
939 if (gdbctx->in_packet[i] == ';')
941 threadIndex[actions] = 0;
942 actionIndex[actions++] = i;
944 else if (gdbctx->in_packet[i] == ':')
946 threadIndex[actions - 1] = i;
950 /* now look up the default action */
951 for (i = 0 ; i < actions; i++)
953 if (threadIndex[i] == 0)
955 if (defaultAction != -1)
957 fprintf(stderr,"Too many default actions specified\n");
958 return packet_error;
960 defaultAction = i;
964 /* Now, I have this default action thing that needs to be applied to all non counted threads */
966 /* go through all the threads and stick their ids in the to be done list. */
967 LIST_FOR_EACH_ENTRY(thd, &gdbctx->process->threads, struct dbg_thread, entry)
969 threadIDs[threadCount++] = thd->tid;
970 /* check to see if we have more threads than I counted on, and tell the user what to do
971 * (they're running winedbg, so I'm sure they can fix the problem from the error message!) */
972 if (threadCount == 100)
974 fprintf(stderr, "Wow, that's a lot of threads, change threadIDs in wine/programs/winedbg/gdbproxy.c to be higher\n");
975 break;
979 /* Ok, now we have... actionIndex full of actions and we know what threads there are, so all
980 * that remains is to apply the actions to the threads and the default action to any threads
981 * left */
982 if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
983 FIXME("Can't continue thread %04x while on thread %04x\n",
984 gdbctx->exec_thread->tid, dbg_curr_thread->tid);
986 /* deal with the threaded stuff first */
987 for (i = 0; i < actions ; i++)
989 if (threadIndex[i] != 0)
991 int j, idLength = 0;
992 if (i < actions - 1)
994 idLength = (actionIndex[i+1] - threadIndex[i]) - 1;
996 else
998 idLength = (gdbctx->in_packet_len - threadIndex[i]) - 1;
1001 threadID = hex_to_int(gdbctx->in_packet + threadIndex[i] + 1 , idLength);
1002 /* process the action */
1003 switch (gdbctx->in_packet[actionIndex[i] + 1])
1005 case 's': /* step */
1006 gdbctx->process->be_cpu->single_step(&gdbctx->context, TRUE);
1007 /* fall through*/
1008 case 'c': /* continue */
1009 resume_debuggee_thread(gdbctx, DBG_CONTINUE, threadID);
1010 break;
1011 case 'S': /* step Sig, */
1012 gdbctx->process->be_cpu->single_step(&gdbctx->context, TRUE);
1013 /* fall through */
1014 case 'C': /* continue sig */
1015 hex_from(&sig, gdbctx->in_packet + actionIndex[i] + 2, 1);
1016 /* cannot change signals on the fly */
1017 TRACE("sigs: %u %u\n", sig, gdbctx->last_sig);
1018 if (sig != gdbctx->last_sig)
1019 return packet_error;
1020 resume_debuggee_thread(gdbctx, DBG_EXCEPTION_NOT_HANDLED, threadID);
1021 break;
1023 for (j = 0 ; j < threadCount; j++)
1025 if (threadIDs[j] == threadID)
1027 threadIDs[j] = 0;
1028 break;
1032 } /* for i=0 ; i< actions */
1034 /* now we have manage the default action */
1035 if (defaultAction >= 0)
1037 for (i = 0 ; i< threadCount; i++)
1039 /* check to see if we've already done something to the thread*/
1040 if (threadIDs[i] != 0)
1042 /* if not apply the default action*/
1043 threadID = threadIDs[i];
1044 /* process the action (yes this is almost identical to the one above!) */
1045 switch (gdbctx->in_packet[actionIndex[defaultAction] + 1])
1047 case 's': /* step */
1048 gdbctx->process->be_cpu->single_step(&gdbctx->context, TRUE);
1049 /* fall through */
1050 case 'c': /* continue */
1051 resume_debuggee_thread(gdbctx, DBG_CONTINUE, threadID);
1052 break;
1053 case 'S':
1054 gdbctx->process->be_cpu->single_step(&gdbctx->context, TRUE);
1055 /* fall through */
1056 case 'C': /* continue sig */
1057 hex_from(&sig, gdbctx->in_packet + actionIndex[defaultAction] + 2, 1);
1058 /* cannot change signals on the fly */
1059 TRACE("sigs: %u %u\n", sig, gdbctx->last_sig);
1060 if (sig != gdbctx->last_sig)
1061 return packet_error;
1062 resume_debuggee_thread(gdbctx, DBG_EXCEPTION_NOT_HANDLED, threadID);
1063 break;
1067 } /* if(defaultAction >=0) */
1069 wait_for_debuggee(gdbctx);
1070 if (gdbctx->process)
1071 gdbctx->process->be_cpu->single_step(&gdbctx->context, FALSE);
1072 return packet_reply_status(gdbctx);
1075 static enum packet_return packet_verbose(struct gdb_context* gdbctx)
1077 if (gdbctx->in_packet_len >= 4 && !memcmp(gdbctx->in_packet, "Cont", 4))
1079 return packet_verbose_cont(gdbctx);
1082 WARN("Unhandled verbose packet %s\n",
1083 debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
1084 return packet_error;
1087 static enum packet_return packet_continue_signal(struct gdb_context* gdbctx)
1089 unsigned char sig;
1091 /* FIXME: add support for address in packet */
1092 assert(gdbctx->in_packet_len == 2);
1093 if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
1094 FIXME("Can't continue thread %04x while on thread %04x\n",
1095 gdbctx->exec_thread->tid, dbg_curr_thread->tid);
1096 hex_from(&sig, gdbctx->in_packet, 1);
1097 /* cannot change signals on the fly */
1098 TRACE("sigs: %u %u\n", sig, gdbctx->last_sig);
1099 if (sig != gdbctx->last_sig)
1100 return packet_error;
1101 resume_debuggee(gdbctx, DBG_EXCEPTION_NOT_HANDLED);
1102 wait_for_debuggee(gdbctx);
1103 return packet_reply_status(gdbctx);
1106 static enum packet_return packet_detach(struct gdb_context* gdbctx)
1108 detach_debuggee(gdbctx, FALSE);
1109 return packet_ok | packet_last_f;
1112 static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
1114 int i;
1115 dbg_ctx_t ctx;
1117 assert(gdbctx->in_trap);
1119 if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
1121 if (!fetch_context(gdbctx, gdbctx->other_thread->handle, &ctx))
1122 return packet_error;
1125 packet_reply_open(gdbctx);
1126 for (i = 0; i < gdbctx->process->be_cpu->gdb_num_regs; i++)
1127 packet_reply_register_hex_to(gdbctx, i);
1129 packet_reply_close(gdbctx);
1130 return packet_done;
1133 static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
1135 const size_t cpu_num_regs = gdbctx->process->be_cpu->gdb_num_regs;
1136 unsigned i;
1137 dbg_ctx_t ctx;
1138 dbg_ctx_t *pctx = &gdbctx->context;
1139 const char* ptr;
1141 assert(gdbctx->in_trap);
1142 if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
1144 if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
1145 return packet_error;
1147 if (gdbctx->in_packet_len < cpu_num_regs * 2) return packet_error;
1149 ptr = gdbctx->in_packet;
1150 for (i = 0; i < cpu_num_regs; i++)
1151 cpu_register_hex_from(gdbctx, pctx, i, &ptr);
1153 if (pctx != &gdbctx->context &&
1154 !gdbctx->process->be_cpu->set_context(gdbctx->other_thread->handle, pctx))
1156 ERR("Failed to set context for tid %04x, error %u\n",
1157 gdbctx->other_thread->tid, GetLastError());
1158 return packet_error;
1160 return packet_ok;
1163 static enum packet_return packet_kill(struct gdb_context* gdbctx)
1165 detach_debuggee(gdbctx, TRUE);
1166 #if 0
1167 if (!gdbctx->extended)
1168 /* dunno whether GDB cares or not */
1169 #endif
1170 wait(NULL);
1171 exit(0);
1172 /* assume we can't really answer something here */
1173 /* return packet_done; */
1176 static enum packet_return packet_thread(struct gdb_context* gdbctx)
1178 char* end;
1179 unsigned thread;
1181 switch (gdbctx->in_packet[0])
1183 case 'c':
1184 case 'g':
1185 if (gdbctx->in_packet[1] == '-')
1186 thread = -strtol(gdbctx->in_packet + 2, &end, 16);
1187 else
1188 thread = strtol(gdbctx->in_packet + 1, &end, 16);
1189 if (end == NULL || end > gdbctx->in_packet + gdbctx->in_packet_len)
1191 ERR("Failed to parse %s\n",
1192 debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
1193 return packet_error;
1195 if (gdbctx->in_packet[0] == 'c')
1196 gdbctx->exec_thread = dbg_get_thread(gdbctx->process, thread);
1197 else
1198 gdbctx->other_thread = dbg_get_thread(gdbctx->process, thread);
1199 return packet_ok;
1200 default:
1201 FIXME("Unknown thread sub-command %c\n", gdbctx->in_packet[0]);
1202 return packet_error;
1206 static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
1208 char *addr;
1209 unsigned int len, blk_len, nread;
1210 char buffer[32];
1211 SIZE_T r = 0;
1213 assert(gdbctx->in_trap);
1214 /* FIXME:check in_packet_len for reading %p,%x */
1215 if (sscanf(gdbctx->in_packet, "%p,%x", &addr, &len) != 2) return packet_error;
1216 if (len <= 0) return packet_error;
1217 TRACE("Read %u bytes at %p\n", len, addr);
1218 for (nread = 0; nread < len; nread += r, addr += r)
1220 blk_len = min(sizeof(buffer), len - nread);
1221 if (!gdbctx->process->process_io->read(gdbctx->process->handle, addr,
1222 buffer, blk_len, &r) || r == 0)
1224 /* fail at first address, return error */
1225 if (nread == 0) return packet_reply_error(gdbctx, EFAULT);
1226 /* something has already been read, return partial information */
1227 break;
1229 if (nread == 0) packet_reply_open(gdbctx);
1230 packet_reply_hex_to(gdbctx, buffer, r);
1232 packet_reply_close(gdbctx);
1233 return packet_done;
1236 static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
1238 char* addr;
1239 unsigned int len, blk_len;
1240 char* ptr;
1241 char buffer[32];
1242 SIZE_T w;
1244 assert(gdbctx->in_trap);
1245 ptr = memchr(gdbctx->in_packet, ':', gdbctx->in_packet_len);
1246 if (ptr == NULL)
1248 ERR("Cannot find ':' in %s\n", debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
1249 return packet_error;
1251 *ptr++ = '\0';
1253 if (sscanf(gdbctx->in_packet, "%p,%x", &addr, &len) != 2)
1255 ERR("Failed to parse %s\n", debugstr_a(gdbctx->in_packet));
1256 return packet_error;
1258 if (ptr - gdbctx->in_packet + len * 2 != gdbctx->in_packet_len)
1260 ERR("Length %u does not match packet length %u\n",
1261 (int)(ptr - gdbctx->in_packet) + len * 2, gdbctx->in_packet_len);
1262 return packet_error;
1264 TRACE("Write %u bytes at %p\n", len, addr);
1265 while (len > 0)
1267 blk_len = min(sizeof(buffer), len);
1268 hex_from(buffer, ptr, blk_len);
1269 if (!gdbctx->process->process_io->write(gdbctx->process->handle, addr, buffer, blk_len, &w) ||
1270 w != blk_len)
1271 break;
1272 addr += blk_len;
1273 len -= blk_len;
1274 ptr += blk_len;
1276 return packet_ok; /* FIXME: error while writing ? */
1279 static enum packet_return packet_read_register(struct gdb_context* gdbctx)
1281 unsigned reg;
1282 dbg_ctx_t ctx;
1283 dbg_ctx_t *pctx = &gdbctx->context;
1285 assert(gdbctx->in_trap);
1286 reg = hex_to_int(gdbctx->in_packet, gdbctx->in_packet_len);
1287 if (reg >= gdbctx->process->be_cpu->gdb_num_regs)
1289 WARN("Unhandled register %u\n", reg);
1290 return packet_error;
1292 if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
1294 if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
1295 return packet_error;
1298 TRACE("%u => %s\n", reg, wine_dbgstr_longlong(cpu_register(gdbctx, pctx, reg)));
1300 packet_reply_open(gdbctx);
1301 packet_reply_register_hex_to(gdbctx, reg);
1302 packet_reply_close(gdbctx);
1303 return packet_done;
1306 static enum packet_return packet_write_register(struct gdb_context* gdbctx)
1308 unsigned reg;
1309 char* ptr;
1310 dbg_ctx_t ctx;
1311 dbg_ctx_t *pctx = &gdbctx->context;
1313 assert(gdbctx->in_trap);
1315 reg = strtoul(gdbctx->in_packet, &ptr, 16);
1316 if (ptr == NULL || reg >= gdbctx->process->be_cpu->gdb_num_regs || *ptr++ != '=')
1318 WARN("Unhandled register %s\n",
1319 debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
1320 /* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
1321 * it wouldn't matter too much, and it fakes our support for all regs
1323 return (ptr == NULL) ? packet_error : packet_ok;
1326 TRACE("%u <= %s\n", reg,
1327 debugstr_an(ptr, (int)(gdbctx->in_packet_len - (ptr - gdbctx->in_packet))));
1329 if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
1331 if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
1332 return packet_error;
1335 cpu_register_hex_from(gdbctx, pctx, reg, (const char**)&ptr);
1336 if (pctx != &gdbctx->context &&
1337 !gdbctx->process->be_cpu->set_context(gdbctx->other_thread->handle, pctx))
1339 ERR("Failed to set context for tid %04x, error %u\n",
1340 gdbctx->other_thread->tid, GetLastError());
1341 return packet_error;
1344 return packet_ok;
1347 static void packet_query_monitor_wnd_helper(struct gdb_context* gdbctx, HWND hWnd, int indent)
1349 char buffer[128];
1350 char clsName[128];
1351 char wndName[128];
1352 HWND child;
1354 do {
1355 if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
1356 strcpy(clsName, "-- Unknown --");
1357 if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
1358 strcpy(wndName, "-- Empty --");
1360 packet_reply_open(gdbctx);
1361 packet_reply_catc(gdbctx, 'O');
1362 snprintf(buffer, sizeof(buffer),
1363 "%*s%04lx%*s%-17.17s %08x %0*lx %.14s\n",
1364 indent, "", (ULONG_PTR)hWnd, 13 - indent, "",
1365 clsName, GetWindowLongW(hWnd, GWL_STYLE),
1366 ADDRWIDTH, (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_WNDPROC),
1367 wndName);
1368 packet_reply_hex_to_str(gdbctx, buffer);
1369 packet_reply_close(gdbctx);
1371 if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
1372 packet_query_monitor_wnd_helper(gdbctx, child, indent + 1);
1373 } while ((hWnd = GetWindow(hWnd, GW_HWNDNEXT)) != 0);
1376 static void packet_query_monitor_wnd(struct gdb_context* gdbctx, int len, const char* str)
1378 char buffer[128];
1380 /* we do the output in several 'O' packets, with the last one being just OK for
1381 * marking the end of the output */
1382 packet_reply_open(gdbctx);
1383 packet_reply_catc(gdbctx, 'O');
1384 snprintf(buffer, sizeof(buffer),
1385 "%-16.16s %-17.17s %-8.8s %s\n",
1386 "hwnd", "Class Name", " Style", " WndProc Text");
1387 packet_reply_hex_to_str(gdbctx, buffer);
1388 packet_reply_close(gdbctx);
1390 /* FIXME: could also add a pmt to this command in str... */
1391 packet_query_monitor_wnd_helper(gdbctx, GetDesktopWindow(), 0);
1392 packet_reply(gdbctx, "OK", 2);
1395 static void packet_query_monitor_process(struct gdb_context* gdbctx, int len, const char* str)
1397 HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1398 char buffer[31+MAX_PATH];
1399 char deco;
1400 PROCESSENTRY32 entry;
1401 BOOL ok;
1403 if (snap == INVALID_HANDLE_VALUE)
1404 return;
1406 entry.dwSize = sizeof(entry);
1407 ok = Process32First(snap, &entry);
1409 /* we do the output in several 'O' packets, with the last one being just OK for
1410 * marking the end of the output */
1412 packet_reply_open(gdbctx);
1413 packet_reply_catc(gdbctx, 'O');
1414 snprintf(buffer, sizeof(buffer),
1415 " %-8.8s %-8.8s %-8.8s %s\n",
1416 "pid", "threads", "parent", "executable");
1417 packet_reply_hex_to_str(gdbctx, buffer);
1418 packet_reply_close(gdbctx);
1420 while (ok)
1422 deco = ' ';
1423 if (entry.th32ProcessID == gdbctx->process->pid) deco = '>';
1424 packet_reply_open(gdbctx);
1425 packet_reply_catc(gdbctx, 'O');
1426 snprintf(buffer, sizeof(buffer),
1427 "%c%08x %-8d %08x '%s'\n",
1428 deco, entry.th32ProcessID, entry.cntThreads,
1429 entry.th32ParentProcessID, entry.szExeFile);
1430 packet_reply_hex_to_str(gdbctx, buffer);
1431 packet_reply_close(gdbctx);
1432 ok = Process32Next(snap, &entry);
1434 CloseHandle(snap);
1435 packet_reply(gdbctx, "OK", 2);
1438 static void packet_query_monitor_mem(struct gdb_context* gdbctx, int len, const char* str)
1440 MEMORY_BASIC_INFORMATION mbi;
1441 char* addr = 0;
1442 const char* state;
1443 const char* type;
1444 char prot[3+1];
1445 char buffer[128];
1447 /* we do the output in several 'O' packets, with the last one being just OK for
1448 * marking the end of the output */
1449 packet_reply_open(gdbctx);
1450 packet_reply_catc(gdbctx, 'O');
1451 packet_reply_hex_to_str(gdbctx, "Address Size State Type RWX\n");
1452 packet_reply_close(gdbctx);
1454 while (VirtualQueryEx(gdbctx->process->handle, addr, &mbi, sizeof(mbi)) >= sizeof(mbi))
1456 switch (mbi.State)
1458 case MEM_COMMIT: state = "commit "; break;
1459 case MEM_FREE: state = "free "; break;
1460 case MEM_RESERVE: state = "reserve"; break;
1461 default: state = "??? "; break;
1463 if (mbi.State != MEM_FREE)
1465 switch (mbi.Type)
1467 case MEM_IMAGE: type = "image "; break;
1468 case MEM_MAPPED: type = "mapped "; break;
1469 case MEM_PRIVATE: type = "private"; break;
1470 case 0: type = " "; break;
1471 default: type = "??? "; break;
1473 memset(prot, ' ' , sizeof(prot)-1);
1474 prot[sizeof(prot)-1] = '\0';
1475 if (mbi.AllocationProtect & (PAGE_READONLY|PAGE_READWRITE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
1476 prot[0] = 'R';
1477 if (mbi.AllocationProtect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE))
1478 prot[1] = 'W';
1479 if (mbi.AllocationProtect & (PAGE_WRITECOPY|PAGE_EXECUTE_WRITECOPY))
1480 prot[1] = 'C';
1481 if (mbi.AllocationProtect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
1482 prot[2] = 'X';
1484 else
1486 type = "";
1487 prot[0] = '\0';
1489 packet_reply_open(gdbctx);
1490 snprintf(buffer, sizeof(buffer), "%0*lx %0*lx %s %s %s\n",
1491 (unsigned)sizeof(void*), (DWORD_PTR)addr,
1492 (unsigned)sizeof(void*), mbi.RegionSize, state, type, prot);
1493 packet_reply_catc(gdbctx, 'O');
1494 packet_reply_hex_to_str(gdbctx, buffer);
1495 packet_reply_close(gdbctx);
1497 if (addr + mbi.RegionSize < addr) /* wrap around ? */
1498 break;
1499 addr += mbi.RegionSize;
1501 packet_reply(gdbctx, "OK", 2);
1504 struct query_detail
1506 int with_arg;
1507 const char* name;
1508 size_t len;
1509 void (*handler)(struct gdb_context*, int, const char*);
1510 } query_details[] =
1512 {0, "wnd", 3, packet_query_monitor_wnd},
1513 {0, "window", 6, packet_query_monitor_wnd},
1514 {0, "proc", 4, packet_query_monitor_process},
1515 {0, "process", 7, packet_query_monitor_process},
1516 {0, "mem", 3, packet_query_monitor_mem},
1517 {0, NULL, 0, NULL},
1520 static enum packet_return packet_query_remote_command(struct gdb_context* gdbctx,
1521 const char* hxcmd, size_t len)
1523 char buffer[128];
1524 struct query_detail* qd;
1526 assert((len & 1) == 0 && len < 2 * sizeof(buffer));
1527 len /= 2;
1528 hex_from(buffer, hxcmd, len);
1530 for (qd = query_details; qd->name != NULL; qd++)
1532 if (len < qd->len || strncmp(buffer, qd->name, qd->len) != 0) continue;
1533 if (!qd->with_arg && len != qd->len) continue;
1535 (qd->handler)(gdbctx, len - qd->len, buffer + qd->len);
1536 return packet_done;
1538 return packet_reply_error(gdbctx, EINVAL);
1541 static enum packet_return packet_query(struct gdb_context* gdbctx)
1543 switch (gdbctx->in_packet[0])
1545 case 'f':
1546 if (strncmp(gdbctx->in_packet + 1, "ThreadInfo", gdbctx->in_packet_len - 1) == 0)
1548 struct dbg_thread* thd;
1550 packet_reply_open(gdbctx);
1551 packet_reply_add(gdbctx, "m", 1);
1552 LIST_FOR_EACH_ENTRY(thd, &gdbctx->process->threads, struct dbg_thread, entry)
1554 packet_reply_val(gdbctx, thd->tid, 4);
1555 if (list_next(&gdbctx->process->threads, &thd->entry) != NULL)
1556 packet_reply_add(gdbctx, ",", 1);
1558 packet_reply_close(gdbctx);
1559 return packet_done;
1561 else if (strncmp(gdbctx->in_packet + 1, "ProcessInfo", gdbctx->in_packet_len - 1) == 0)
1563 char result[128];
1565 packet_reply_open(gdbctx);
1566 packet_reply_catc(gdbctx, 'O');
1567 get_process_info(gdbctx, result, sizeof(result));
1568 packet_reply_hex_to_str(gdbctx, result);
1569 packet_reply_close(gdbctx);
1570 return packet_done;
1572 break;
1573 case 's':
1574 if (strncmp(gdbctx->in_packet + 1, "ThreadInfo", gdbctx->in_packet_len - 1) == 0)
1576 packet_reply(gdbctx, "l", 1);
1577 return packet_done;
1579 else if (strncmp(gdbctx->in_packet + 1, "ProcessInfo", gdbctx->in_packet_len - 1) == 0)
1581 packet_reply(gdbctx, "l", 1);
1582 return packet_done;
1584 break;
1585 case 'A':
1586 if (strncmp(gdbctx->in_packet, "Attached", gdbctx->in_packet_len) == 0)
1588 char buf[2];
1590 buf[0] = '1';
1591 buf[1] = 0;
1592 return packet_reply(gdbctx, buf, -1);
1594 break;
1595 case 'C':
1596 if (gdbctx->in_packet_len == 1)
1598 struct dbg_thread* thd;
1599 /* FIXME: doc says 16 bit val ??? */
1600 /* grab first created thread, aka last in list */
1601 assert(gdbctx->process && !list_empty(&gdbctx->process->threads));
1602 thd = LIST_ENTRY(list_tail(&gdbctx->process->threads), struct dbg_thread, entry);
1603 packet_reply_open(gdbctx);
1604 packet_reply_add(gdbctx, "QC", 2);
1605 packet_reply_val(gdbctx, thd->tid, 4);
1606 packet_reply_close(gdbctx);
1607 return packet_done;
1609 break;
1610 case 'O':
1611 if (strncmp(gdbctx->in_packet, "Offsets", gdbctx->in_packet_len) == 0)
1613 char buf[64];
1615 snprintf(buf, sizeof(buf),
1616 "Text=%08lx;Data=%08lx;Bss=%08lx",
1617 gdbctx->wine_segs[0], gdbctx->wine_segs[1],
1618 gdbctx->wine_segs[2]);
1619 return packet_reply(gdbctx, buf, -1);
1621 break;
1622 case 'R':
1623 if (gdbctx->in_packet_len > 5 && strncmp(gdbctx->in_packet, "Rcmd,", 5) == 0)
1625 return packet_query_remote_command(gdbctx, gdbctx->in_packet + 5,
1626 gdbctx->in_packet_len - 5);
1628 break;
1629 case 'S':
1630 if (strncmp(gdbctx->in_packet, "Symbol::", gdbctx->in_packet_len) == 0)
1631 return packet_ok;
1632 if (strncmp(gdbctx->in_packet, "Supported", 9) == 0)
1634 if (strlen(target_xml))
1635 return packet_reply(gdbctx, "PacketSize=400;qXfer:features:read+", -1);
1636 else
1638 /* no features supported */
1639 packet_reply_open(gdbctx);
1640 packet_reply_close(gdbctx);
1641 return packet_done;
1644 break;
1645 case 'T':
1646 if (gdbctx->in_packet_len > 15 &&
1647 strncmp(gdbctx->in_packet, "ThreadExtraInfo", 15) == 0 &&
1648 gdbctx->in_packet[15] == ',')
1650 unsigned tid;
1651 char* end;
1652 char result[128];
1654 tid = strtol(gdbctx->in_packet + 16, &end, 16);
1655 if (end == NULL) break;
1656 get_thread_info(gdbctx, tid, result, sizeof(result));
1657 packet_reply_open(gdbctx);
1658 packet_reply_hex_to_str(gdbctx, result);
1659 packet_reply_close(gdbctx);
1660 return packet_done;
1662 if (strncmp(gdbctx->in_packet, "TStatus", 7) == 0)
1664 /* Tracepoints not supported */
1665 packet_reply_open(gdbctx);
1666 packet_reply_close(gdbctx);
1667 return packet_done;
1669 break;
1670 case 'X':
1671 if (strlen(target_xml) && strncmp(gdbctx->in_packet, "Xfer:features:read:target.xml", 29) == 0)
1672 return packet_reply(gdbctx, target_xml, -1);
1673 break;
1675 ERR("Unhandled query %s\n", debugstr_an(gdbctx->in_packet, gdbctx->in_packet_len));
1676 return packet_error;
1679 static enum packet_return packet_step(struct gdb_context* gdbctx)
1681 /* FIXME: add support for address in packet */
1682 assert(gdbctx->in_packet_len == 0);
1683 if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
1684 FIXME("Can't single-step thread %04x while on thread %04x\n",
1685 gdbctx->exec_thread->tid, dbg_curr_thread->tid);
1686 gdbctx->process->be_cpu->single_step(&gdbctx->context, TRUE);
1687 resume_debuggee(gdbctx, DBG_CONTINUE);
1688 wait_for_debuggee(gdbctx);
1689 gdbctx->process->be_cpu->single_step(&gdbctx->context, FALSE);
1690 return packet_reply_status(gdbctx);
1693 #if 0
1694 static enum packet_return packet_step_signal(struct gdb_context* gdbctx)
1696 unsigned char sig;
1698 /* FIXME: add support for address in packet */
1699 assert(gdbctx->in_packet_len == 2);
1700 if (dbg_curr_thread->tid != gdbctx->exec_thread && gdbctx->exec_thread)
1701 if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1702 fprintf(stderr, "NIY: step/sig on %u, while last thread is %u\n",
1703 gdbctx->exec_thread, DEBUG_CurrThread->tid);
1704 hex_from(&sig, gdbctx->in_packet, 1);
1705 /* cannot change signals on the fly */
1706 if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1707 fprintf(stderr, "sigs: %u %u\n", sig, gdbctx->last_sig);
1708 if (sig != gdbctx->last_sig)
1709 return packet_error;
1710 resume_debuggee(gdbctx, DBG_EXCEPTION_NOT_HANDLED);
1711 wait_for_debuggee(gdbctx);
1712 return packet_reply_status(gdbctx);
1714 #endif
1716 static enum packet_return packet_thread_alive(struct gdb_context* gdbctx)
1718 char* end;
1719 unsigned tid;
1721 tid = strtol(gdbctx->in_packet, &end, 16);
1722 if (tid == -1 || tid == 0)
1723 return packet_reply_error(gdbctx, EINVAL);
1724 if (dbg_get_thread(gdbctx->process, tid) != NULL)
1725 return packet_ok;
1726 return packet_reply_error(gdbctx, ESRCH);
1729 /* =============================================== *
1730 * P A C K E T I N F R A S T R U C T U R E *
1731 * =============================================== *
1734 struct packet_entry
1736 char key;
1737 enum packet_return (*handler)(struct gdb_context* gdbctx);
1740 static struct packet_entry packet_entries[] =
1742 /*{'!', packet_extended}, */
1743 {'?', packet_last_signal},
1744 {'c', packet_continue},
1745 {'C', packet_continue_signal},
1746 {'D', packet_detach},
1747 {'g', packet_read_registers},
1748 {'G', packet_write_registers},
1749 {'k', packet_kill},
1750 {'H', packet_thread},
1751 {'m', packet_read_memory},
1752 {'M', packet_write_memory},
1753 {'p', packet_read_register},
1754 {'P', packet_write_register},
1755 {'q', packet_query},
1756 /* {'Q', packet_set}, */
1757 /* {'R', packet,restart}, only in extended mode ! */
1758 {'s', packet_step},
1759 /*{'S', packet_step_signal}, hard(er) to implement */
1760 {'T', packet_thread_alive},
1761 {'v', packet_verbose},
1764 static BOOL extract_packets(struct gdb_context* gdbctx)
1766 char* end;
1767 int plen;
1768 unsigned char in_cksum, loc_cksum;
1769 char* ptr;
1770 enum packet_return ret = packet_error;
1771 int num_packet = 0;
1773 while ((ret & packet_last_f) == 0)
1775 TRACE("Packet: %s\n", debugstr_an(gdbctx->in_buf, gdbctx->in_len));
1776 ptr = memchr(gdbctx->in_buf, '$', gdbctx->in_len);
1777 if (ptr == NULL) return FALSE;
1778 if (ptr != gdbctx->in_buf)
1780 int glen = ptr - gdbctx->in_buf; /* garbage len */
1781 WARN("Removing garbage: %s\n", debugstr_an(gdbctx->in_buf, glen));
1782 gdbctx->in_len -= glen;
1783 memmove(gdbctx->in_buf, ptr, gdbctx->in_len);
1785 end = memchr(gdbctx->in_buf + 1, '#', gdbctx->in_len);
1786 if (end == NULL) return FALSE;
1787 /* no checksum yet */
1788 if (end + 3 > gdbctx->in_buf + gdbctx->in_len) return FALSE;
1789 plen = end - gdbctx->in_buf - 1;
1790 hex_from(&in_cksum, end + 1, 1);
1791 loc_cksum = checksum(gdbctx->in_buf + 1, plen);
1792 if (loc_cksum == in_cksum)
1794 if (num_packet == 0) {
1795 int i;
1797 ret = packet_error;
1799 write(gdbctx->sock, "+", 1);
1800 assert(plen);
1802 /* FIXME: should use bsearch if packet_entries was sorted */
1803 for (i = 0; i < ARRAY_SIZE(packet_entries); i++)
1805 if (packet_entries[i].key == gdbctx->in_buf[1]) break;
1807 if (i == ARRAY_SIZE(packet_entries))
1808 WARN("Unhandled packet %s\n", debugstr_an(&gdbctx->in_buf[1], plen));
1809 else
1811 gdbctx->in_packet = gdbctx->in_buf + 2;
1812 gdbctx->in_packet_len = plen - 1;
1813 ret = (packet_entries[i].handler)(gdbctx);
1815 switch (ret & ~packet_last_f)
1817 case packet_error: packet_reply(gdbctx, "", 0); break;
1818 case packet_ok: packet_reply(gdbctx, "OK", 2); break;
1819 case packet_done: break;
1821 TRACE("Reply: %s\n", debugstr_an(gdbctx->out_buf, gdbctx->out_len));
1822 i = write(gdbctx->sock, gdbctx->out_buf, gdbctx->out_len);
1823 assert(i == gdbctx->out_len);
1824 /* if this fails, we'll have to use POLLOUT...
1826 gdbctx->out_len = 0;
1827 num_packet++;
1829 else
1831 /* FIXME: If we have more than one packet in our input buffer,
1832 * it's very likely that we took too long to answer to a given packet
1833 * and gdb is sending us the same packet again.
1834 * So we simply drop the second packet. This will lower the risk of error,
1835 * but there are still some race conditions here.
1836 * A better fix (yet not perfect) would be to have two threads:
1837 * - one managing the packets for gdb
1838 * - the second one managing the commands...
1839 * This would allow us to send the reply with the '+' character (Ack of
1840 * the command) way sooner than we do now.
1842 ERR("Dropping packet; I was too slow to respond\n");
1845 else
1847 write(gdbctx->sock, "+", 1);
1848 ERR("Dropping packet; invalid checksum %d <> %d\n", in_cksum, loc_cksum);
1850 gdbctx->in_len -= plen + 4;
1851 memmove(gdbctx->in_buf, end + 3, gdbctx->in_len);
1853 return TRUE;
1856 static int fetch_data(struct gdb_context* gdbctx)
1858 int len, in_len = gdbctx->in_len;
1860 assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
1861 for (;;)
1863 #define STEP 128
1864 if (gdbctx->in_len + STEP > gdbctx->in_buf_alloc)
1865 gdbctx->in_buf = packet_realloc(gdbctx->in_buf, gdbctx->in_buf_alloc += STEP);
1866 #undef STEP
1867 len = read(gdbctx->sock, gdbctx->in_buf + gdbctx->in_len, gdbctx->in_buf_alloc - gdbctx->in_len);
1868 if (len <= 0) break;
1869 gdbctx->in_len += len;
1870 assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
1871 if (len < gdbctx->in_buf_alloc - gdbctx->in_len) break;
1873 return gdbctx->in_len - in_len;
1876 #define FLAG_NO_START 1
1877 #define FLAG_WITH_XTERM 2
1879 static BOOL gdb_exec(const char* wine_path, unsigned port, unsigned flags)
1881 char buf[MAX_PATH];
1882 int fd;
1883 const char *gdb_path, *tmp_path;
1884 FILE* f;
1886 if (!(gdb_path = getenv("WINE_GDB"))) gdb_path = "gdb";
1887 if (!(tmp_path = getenv("TMPDIR"))) tmp_path = "/tmp";
1888 strcpy(buf, tmp_path);
1889 strcat(buf, "/winegdb.XXXXXX");
1890 fd = mkstemps(buf, 0);
1891 if (fd == -1) return FALSE;
1892 if ((f = fdopen(fd, "w+")) == NULL) return FALSE;
1893 fprintf(f, "file \"%s\"\n", wine_path);
1894 fprintf(f, "target remote localhost:%d\n", ntohs(port));
1895 fprintf(f, "set prompt Wine-gdb>\\ \n");
1896 /* gdb 5.1 seems to require it, won't hurt anyway */
1897 fprintf(f, "sharedlibrary\n");
1898 /* This is needed (but not a decent & final fix)
1899 * Without this, gdb would skip our inter-DLL relay code (because
1900 * we don't have any line number information for the relay code)
1901 * With this, we will stop on first instruction of the stub, and
1902 * reusing step, will get us through the relay stub at the actual
1903 * function we're looking at.
1905 fprintf(f, "set step-mode on\n");
1906 /* tell gdb to delete this file when done handling it... */
1907 fprintf(f, "shell rm -f \"%s\"\n", buf);
1908 fclose(f);
1909 if (flags & FLAG_WITH_XTERM)
1910 execlp("xterm", "xterm", "-e", gdb_path, "-x", buf, NULL);
1911 else
1912 execlp(gdb_path, gdb_path, "-x", buf, NULL);
1913 assert(0); /* never reached */
1914 return TRUE;
1917 static BOOL gdb_startup(struct gdb_context* gdbctx, DEBUG_EVENT* de, unsigned flags, unsigned port)
1919 int sock;
1920 struct sockaddr_in s_addrs = {0};
1921 socklen_t s_len = sizeof(s_addrs);
1922 struct pollfd pollfd;
1923 IMAGEHLP_MODULE64 imh_mod;
1924 BOOL ret = FALSE;
1926 /* step 1: create socket for gdb connection request */
1927 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
1929 ERR("Failed to create socket: %s\n", strerror(errno));
1930 return FALSE;
1933 s_addrs.sin_family = AF_INET;
1934 s_addrs.sin_addr.s_addr = INADDR_ANY;
1935 s_addrs.sin_port = htons(port);
1936 if (bind(sock, (struct sockaddr *)&s_addrs, sizeof(s_addrs)) == -1)
1937 goto cleanup;
1939 if (listen(sock, 1) == -1 || getsockname(sock, (struct sockaddr*)&s_addrs, &s_len) == -1)
1940 goto cleanup;
1942 /* step 2: do the process internal creation */
1943 handle_debug_event(gdbctx, de);
1945 /* step3: get the wine loader name */
1946 if (!dbg_get_debuggee_info(gdbctx->process->handle, &imh_mod))
1947 goto cleanup;
1949 /* step 4: fire up gdb (if requested) */
1950 if (flags & FLAG_NO_START)
1951 fprintf(stderr, "target remote localhost:%d\n", ntohs(s_addrs.sin_port));
1952 else
1953 switch (fork())
1955 case -1: /* error in parent... */
1956 ERR("Failed to start gdb: fork: %s\n", strerror(errno));
1957 goto cleanup;
1958 default: /* in parent... success */
1959 signal(SIGINT, SIG_IGN);
1960 break;
1961 case 0: /* in child... and alive */
1962 gdb_exec(imh_mod.LoadedImageName, s_addrs.sin_port, flags);
1963 /* if we're here, exec failed, so report failure */
1964 goto cleanup;
1967 /* step 5: wait for gdb to connect actually */
1968 pollfd.fd = sock;
1969 pollfd.events = POLLIN;
1970 pollfd.revents = 0;
1972 switch (poll(&pollfd, 1, -1))
1974 case 1:
1975 if (pollfd.revents & POLLIN)
1977 int dummy = 1;
1978 gdbctx->sock = accept(sock, (struct sockaddr*)&s_addrs, &s_len);
1979 if (gdbctx->sock == -1)
1980 break;
1981 ret = TRUE;
1982 TRACE("connected on %d\n", gdbctx->sock);
1983 /* don't keep our small packets too long: send them ASAP back to GDB
1984 * without this, GDB really crawls
1986 setsockopt(gdbctx->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&dummy, sizeof(dummy));
1988 break;
1989 case 0:
1990 ERR("Timed out connecting to gdb\n");
1991 break;
1992 case -1:
1993 ERR("Failed to connect to gdb: poll: %s\n", strerror(errno));
1994 break;
1995 default:
1996 assert(0);
1999 cleanup:
2000 close(sock);
2001 return ret;
2004 static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags, unsigned port)
2006 DEBUG_EVENT de;
2007 int i;
2009 gdbctx->sock = -1;
2010 gdbctx->in_buf = NULL;
2011 gdbctx->in_buf_alloc = 0;
2012 gdbctx->in_len = 0;
2013 gdbctx->out_buf = NULL;
2014 gdbctx->out_buf_alloc = 0;
2015 gdbctx->out_len = 0;
2016 gdbctx->out_curr_packet = -1;
2018 gdbctx->exec_thread = gdbctx->other_thread = NULL;
2019 gdbctx->last_sig = 0;
2020 gdbctx->in_trap = FALSE;
2021 gdbctx->process = NULL;
2022 for (i = 0; i < ARRAY_SIZE(gdbctx->wine_segs); i++)
2023 gdbctx->wine_segs[i] = 0;
2025 /* wait for first trap */
2026 while (WaitForDebugEvent(&de, INFINITE))
2028 if (de.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT)
2030 /* this should be the first event we get,
2031 * and the only one of this type */
2032 assert(gdbctx->process == NULL && de.dwProcessId == dbg_curr_pid);
2033 /* gdbctx->dwProcessId = pid; */
2034 if (!gdb_startup(gdbctx, &de, flags, port)) return FALSE;
2035 assert(!gdbctx->in_trap);
2037 else
2039 handle_debug_event(gdbctx, &de);
2040 if (gdbctx->in_trap) break;
2042 ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
2044 return TRUE;
2047 static int gdb_remote(unsigned flags, unsigned port)
2049 struct pollfd pollfd;
2050 struct gdb_context gdbctx;
2051 BOOL doLoop;
2053 for (doLoop = gdb_init_context(&gdbctx, flags, port); doLoop;)
2055 pollfd.fd = gdbctx.sock;
2056 pollfd.events = POLLIN;
2057 pollfd.revents = 0;
2059 switch (poll(&pollfd, 1, -1))
2061 case 1:
2062 /* got something */
2063 if (pollfd.revents & (POLLHUP | POLLERR))
2065 ERR("gdb hung up\n");
2066 /* kill also debuggee process - questionnable - */
2067 detach_debuggee(&gdbctx, TRUE);
2068 doLoop = FALSE;
2069 break;
2071 if ((pollfd.revents & POLLIN) && fetch_data(&gdbctx) > 0)
2073 if (extract_packets(&gdbctx)) doLoop = FALSE;
2075 break;
2076 case 0:
2077 /* timeout, should never happen (infinite timeout) */
2078 break;
2079 case -1:
2080 ERR("poll failed: %s\n", strerror(errno));
2081 doLoop = FALSE;
2082 break;
2085 wait(NULL);
2086 return 0;
2088 #endif
2090 int gdb_main(int argc, char* argv[])
2092 #ifdef HAVE_POLL
2093 unsigned gdb_flags = 0, port = 0;
2094 char *port_end;
2096 argc--; argv++;
2097 while (argc > 0 && argv[0][0] == '-')
2099 if (strcmp(argv[0], "--no-start") == 0)
2101 gdb_flags |= FLAG_NO_START;
2102 argc--; argv++;
2103 continue;
2105 if (strcmp(argv[0], "--with-xterm") == 0)
2107 gdb_flags |= FLAG_WITH_XTERM;
2108 argc--; argv++;
2109 continue;
2111 if (strcmp(argv[0], "--port") == 0 && argc > 1)
2113 port = strtoul(argv[1], &port_end, 10);
2114 if (*port_end)
2116 fprintf(stderr, "Invalid port: %s\n", argv[1]);
2117 return -1;
2119 argc -= 2; argv += 2;
2120 continue;
2122 return -1;
2124 if (dbg_active_attach(argc, argv) == start_ok ||
2125 dbg_active_launch(argc, argv) == start_ok)
2126 return gdb_remote(gdb_flags, port);
2127 #else
2128 fprintf(stderr, "GdbProxy mode not supported on this platform\n");
2129 #endif
2130 return -1;