Release 1.5.29.
[wine] / programs / winedbg / gdbproxy.c
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.
5  *
6  * Copyright (c) Eric Pouech 2002-2004
7  *
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.
12  *
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.
17  *
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
21  */
22
23 /* Protocol specification can be found here:
24  * http://sources.redhat.com/gdb/onlinedocs/gdb/Maintenance-Commands.html
25  */
26
27 #include "config.h"
28 #include "wine/port.h"
29
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
55
56 /* if we don't have poll support on this system
57  * we won't provide gdb proxy support here...
58  */
59 #ifdef HAVE_POLL
60
61 #include "debugger.h"
62
63 #include "windef.h"
64 #include "winbase.h"
65 #include "tlhelp32.h"
66
67 #define GDBPXY_TRC_LOWLEVEL             0x01
68 #define GDBPXY_TRC_PACKET               0x02
69 #define GDBPXY_TRC_COMMAND              0x04
70 #define GDBPXY_TRC_COMMAND_ERROR        0x08
71 #define GDBPXY_TRC_WIN32_EVENT          0x10
72 #define GDBPXY_TRC_WIN32_ERROR          0x20
73 #define GDBPXY_TRC_COMMAND_FIXME        0x80
74
75 struct gdb_ctx_Xpoint
76 {
77     enum be_xpoint_type         type;   /* -1 means free */
78     void*                       addr;
79     unsigned long               val;
80 };
81
82 struct gdb_context
83 {
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     struct dbg_thread*          exec_thread;    /* thread used in step & continue */
100     struct dbg_thread*          other_thread;   /* thread to be used in any other operation */
101     unsigned                    trace;
102     /* current Win32 trap env */
103     unsigned                    last_sig;
104     BOOL                        in_trap;
105     CONTEXT                     context;
106     /* Win32 information */
107     struct dbg_process*         process;
108 #define NUM_XPOINT      32
109     struct gdb_ctx_Xpoint       Xpoints[NUM_XPOINT];
110     /* Unix environment */
111     unsigned long               wine_segs[3];   /* load addresses of the ELF wine exec segments (text, bss and data) */
112 };
113
114 static BOOL tgt_process_gdbproxy_read(HANDLE hProcess, const void* addr,
115                                       void* buffer, SIZE_T len, SIZE_T* rlen)
116 {
117     return ReadProcessMemory( hProcess, addr, buffer, len, rlen );
118 }
119
120 static BOOL tgt_process_gdbproxy_write(HANDLE hProcess, void* addr,
121                                        const void* buffer, SIZE_T len, SIZE_T* wlen)
122 {
123     return WriteProcessMemory( hProcess, addr, buffer, len, wlen );
124 }
125
126 static struct be_process_io be_process_gdbproxy_io =
127 {
128     NULL, /* we shouldn't use close_process() in gdbproxy */
129     tgt_process_gdbproxy_read,
130     tgt_process_gdbproxy_write
131 };
132
133 /* =============================================== *
134  *       B A S I C   M A N I P U L A T I O N S     *
135  * =============================================== *
136  */
137
138 static inline int hex_from0(char ch)
139 {
140     if (ch >= '0' && ch <= '9') return ch - '0';
141     if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
142     if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
143
144     assert(0);
145     return 0;
146 }
147
148 static inline unsigned char hex_to0(int x)
149 {
150     assert(x >= 0 && x < 16);
151     return "0123456789abcdef"[x];
152 }
153
154 static int hex_to_int(const char* src, size_t len)
155 {
156     unsigned int returnval = 0;
157     while (len--)
158     {
159         returnval <<= 4;
160         returnval |= hex_from0(*src++);
161     }
162     return returnval;
163 }
164
165 static void hex_from(void* dst, const char* src, size_t len)
166 {
167     unsigned char *p = dst;
168     while (len--)
169     {
170         *p++ = (hex_from0(src[0]) << 4) | hex_from0(src[1]);
171         src += 2;
172     }
173 }
174
175 static void hex_to(char* dst, const void* src, size_t len)
176 {
177     const unsigned char *p = src;
178     while (len--)
179     {
180         *dst++ = hex_to0(*p >> 4);
181         *dst++ = hex_to0(*p & 0x0F);
182         p++;
183     }
184 }
185
186 static unsigned char checksum(const char* ptr, int len)
187 {
188     unsigned cksum = 0;
189
190     while (len-- > 0)
191         cksum += (unsigned char)*ptr++;
192     return cksum;
193 }
194
195 /* =============================================== *
196  *              C P U   H A N D L E R S            *
197  * =============================================== *
198  */
199
200 /* This struct helps us to manage the different representations of a register:
201  * ctx_offset and ctx_length are the location and size in Win32 CONTEXT
202  * gdb_length is the length gdb expects on the wire
203  * As the two sizes could be different, we have to convert between the two
204  * (for example, on x86_64, Seg?s are 4 bytes on the wire and 2 in CONTEXT)
205  */
206 struct cpu_register
207 {
208     size_t      ctx_offset;
209     size_t      ctx_length;
210     size_t      gdb_length;
211 };
212
213 #define REG(r,gs)  {FIELD_OFFSET(CONTEXT, r), sizeof(((CONTEXT*)NULL)->r), gs}
214
215 #ifdef __i386__
216 static const char target_xml[] = "";
217 static struct cpu_register cpu_register_map[] = {
218     REG(Eax, 4),
219     REG(Ecx, 4),
220     REG(Edx, 4),
221     REG(Ebx, 4),
222     REG(Esp, 4),
223     REG(Ebp, 4),
224     REG(Esi, 4),
225     REG(Edi, 4),
226     REG(Eip, 4),
227     REG(EFlags, 4),
228     REG(SegCs, 4),
229     REG(SegSs, 4),
230     REG(SegDs, 4),
231     REG(SegEs, 4),
232     REG(SegFs, 4),
233     REG(SegGs, 4),
234 };
235 #elif defined(__powerpc__)
236 static const char target_xml[] = "";
237 static struct cpu_register cpu_register_map[] = {
238     REG(Gpr0, 4),
239     REG(Gpr1, 4),
240     REG(Gpr2, 4),
241     REG(Gpr3, 4),
242     REG(Gpr4, 4),
243     REG(Gpr5, 4),
244     REG(Gpr6, 4),
245     REG(Gpr7, 4),
246     REG(Gpr8, 4),
247     REG(Gpr9, 4),
248     REG(Gpr10, 4),
249     REG(Gpr11, 4),
250     REG(Gpr12, 4),
251     REG(Gpr13, 4),
252     REG(Gpr14, 4),
253     REG(Gpr15, 4),
254     REG(Gpr16, 4),
255     REG(Gpr17, 4),
256     REG(Gpr18, 4),
257     REG(Gpr19, 4),
258     REG(Gpr20, 4),
259     REG(Gpr21, 4),
260     REG(Gpr22, 4),
261     REG(Gpr23, 4),
262     REG(Gpr24, 4),
263     REG(Gpr25, 4),
264     REG(Gpr26, 4),
265     REG(Gpr27, 4),
266     REG(Gpr28, 4),
267     REG(Gpr29, 4),
268     REG(Gpr30, 4),
269     REG(Gpr31, 4),
270     REG(Fpr0, 4),
271     REG(Fpr1, 4),
272     REG(Fpr2, 4),
273     REG(Fpr3, 4),
274     REG(Fpr4, 4),
275     REG(Fpr5, 4),
276     REG(Fpr6, 4),
277     REG(Fpr7, 4),
278     REG(Fpr8, 4),
279     REG(Fpr9, 4),
280     REG(Fpr10, 4),
281     REG(Fpr11, 4),
282     REG(Fpr12, 4),
283     REG(Fpr13, 4),
284     REG(Fpr14, 4),
285     REG(Fpr15, 4),
286     REG(Fpr16, 4),
287     REG(Fpr17, 4),
288     REG(Fpr18, 4),
289     REG(Fpr19, 4),
290     REG(Fpr20, 4),
291     REG(Fpr21, 4),
292     REG(Fpr22, 4),
293     REG(Fpr23, 4),
294     REG(Fpr24, 4),
295     REG(Fpr25, 4),
296     REG(Fpr26, 4),
297     REG(Fpr27, 4),
298     REG(Fpr28, 4),
299     REG(Fpr29, 4),
300     REG(Fpr30, 4),
301     REG(Fpr31, 4),
302
303     REG(Iar, 4),
304     REG(Msr, 4),
305     REG(Cr, 4),
306     REG(Lr, 4),
307     REG(Ctr, 4),
308     REG(Xer, 4),
309     /* FIXME: MQ is missing? FIELD_OFFSET(CONTEXT, Mq), */
310     /* see gdb/nlm/ppc.c */
311 };
312 #elif defined(__x86_64__)
313 static const char target_xml[] = "";
314 static struct cpu_register cpu_register_map[] = {
315     REG(Rax, 8),
316     REG(Rbx, 8),
317     REG(Rcx, 8),
318     REG(Rdx, 8),
319     REG(Rsi, 8),
320     REG(Rdi, 8),
321     REG(Rbp, 8),
322     REG(Rsp, 8),
323     REG(R8, 8),
324     REG(R9, 8),
325     REG(R10, 8),
326     REG(R11, 8),
327     REG(R12, 8),
328     REG(R13, 8),
329     REG(R14, 8),
330     REG(R15, 8),
331     REG(Rip, 8),
332     REG(EFlags, 4),
333     REG(SegCs, 4),
334     REG(SegSs, 4),
335     REG(SegDs, 4),
336     REG(SegEs, 4),
337     REG(SegFs, 4),
338     REG(SegGs, 4),
339 };
340 #elif defined(__arm__)
341 static const char target_xml[] =
342     "l <target><architecture>arm</architecture>\n"
343     "<feature name=\"org.gnu.gdb.arm.core\">\n"
344     "    <reg name=\"r0\" bitsize=\"32\" type=\"uint32\"/>\n"
345     "    <reg name=\"r1\" bitsize=\"32\" type=\"uint32\"/>\n"
346     "    <reg name=\"r2\" bitsize=\"32\" type=\"uint32\"/>\n"
347     "    <reg name=\"r3\" bitsize=\"32\" type=\"uint32\"/>\n"
348     "    <reg name=\"r4\" bitsize=\"32\" type=\"uint32\"/>\n"
349     "    <reg name=\"r5\" bitsize=\"32\" type=\"uint32\"/>\n"
350     "    <reg name=\"r6\" bitsize=\"32\" type=\"uint32\"/>\n"
351     "    <reg name=\"r7\" bitsize=\"32\" type=\"uint32\"/>\n"
352     "    <reg name=\"r8\" bitsize=\"32\" type=\"uint32\"/>\n"
353     "    <reg name=\"r9\" bitsize=\"32\" type=\"uint32\"/>\n"
354     "    <reg name=\"r10\" bitsize=\"32\" type=\"uint32\"/>\n"
355     "    <reg name=\"r11\" bitsize=\"32\" type=\"uint32\"/>\n"
356     "    <reg name=\"r12\" bitsize=\"32\" type=\"uint32\"/>\n"
357     "    <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\n"
358     "    <reg name=\"lr\" bitsize=\"32\"/>\n"
359     "    <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\n"
360     "    <reg name=\"cpsr\" bitsize=\"32\"/>\n"
361     "</feature></target>\n";
362
363 static struct cpu_register cpu_register_map[] = {
364     REG(R0, 4),
365     REG(R1, 4),
366     REG(R2, 4),
367     REG(R3, 4),
368     REG(R4, 4),
369     REG(R5, 4),
370     REG(R6, 4),
371     REG(R7, 4),
372     REG(R8, 4),
373     REG(R9, 4),
374     REG(R10, 4),
375     REG(Fp, 4),
376     REG(Ip, 4),
377     REG(Sp, 4),
378     REG(Lr, 4),
379     REG(Pc, 4),
380     REG(Cpsr, 4),
381 };
382 #elif defined(__aarch64__)
383 static const char target_xml[] = "";
384 static struct cpu_register cpu_register_map[] = {
385     REG(X0,  8),
386     REG(X1,  8),
387     REG(X2,  8),
388     REG(X3,  8),
389     REG(X4,  8),
390     REG(X5,  8),
391     REG(X6,  8),
392     REG(X7,  8),
393     REG(X8,  8),
394     REG(X9,  8),
395     REG(X10, 8),
396     REG(X11, 8),
397     REG(X12, 8),
398     REG(X13, 8),
399     REG(X14, 8),
400     REG(X15, 8),
401     REG(X16, 8),
402     REG(X17, 8),
403     REG(X18, 8),
404     REG(X19, 8),
405     REG(X20, 8),
406     REG(X21, 8),
407     REG(X22, 8),
408     REG(X23, 8),
409     REG(X24, 8),
410     REG(X25, 8),
411     REG(X26, 8),
412     REG(X27, 8),
413     REG(X28, 8),
414     REG(X29, 8),
415     REG(X30, 8),
416     REG(Sp,  8),
417     REG(Pc,  8),
418     REG(PState, 8),
419 };
420 #else
421 # error Define the registers map for your CPU
422 #endif
423 #undef REG
424
425 static const size_t cpu_num_regs = (sizeof(cpu_register_map) / sizeof(cpu_register_map[0]));
426
427 static inline void* cpu_register_ptr(CONTEXT* ctx, unsigned idx)
428 {
429     assert(idx < cpu_num_regs);
430     return (char*)ctx + cpu_register_map[idx].ctx_offset;
431 }
432
433 static inline DWORD64   cpu_register(CONTEXT* ctx, unsigned idx)
434 {
435     switch (cpu_register_map[idx].ctx_length)
436     {
437     case 2: return *(WORD*)cpu_register_ptr(ctx, idx);
438     case 4: return *(DWORD*)cpu_register_ptr(ctx, idx);
439     case 8: return *(DWORD64*)cpu_register_ptr(ctx, idx);
440     default:
441         fprintf(stderr, "got unexpected size: %u\n", (unsigned)cpu_register_map[idx].ctx_length);
442         assert(0);
443         return 0;
444     }
445 }
446
447 static inline   void    cpu_register_hex_from(CONTEXT* ctx, unsigned idx, const char** phex)
448 {
449     DWORD64     val = 0;
450     unsigned    i;
451     BYTE        b;
452
453     for (i = 0; i < cpu_register_map[idx].gdb_length; i++)
454     {
455         hex_from(&b, *phex, 1);
456         *phex += 2;
457         val += (DWORD64)b << (8 * i);
458     }
459     switch (cpu_register_map[idx].ctx_length)
460     {
461     case 2: *(WORD*)cpu_register_ptr(ctx, idx) = (WORD)val; break;
462     case 4: *(DWORD*)cpu_register_ptr(ctx, idx) = (DWORD)val; break;
463     case 8: *(DWORD64*)cpu_register_ptr(ctx, idx) = val; break;
464     default: assert(0);
465     }
466 }
467
468 /* =============================================== *
469  *    W I N 3 2   D E B U G   I N T E R F A C E    *
470  * =============================================== *
471  */
472
473 static BOOL fetch_context(struct gdb_context* gdbctx, HANDLE h, CONTEXT* ctx)
474 {
475     ctx->ContextFlags =  CONTEXT_CONTROL
476                        | CONTEXT_INTEGER
477 #ifdef CONTEXT_SEGMENTS
478                        | CONTEXT_SEGMENTS
479 #endif
480 #ifdef CONTEXT_DEBUG_REGISTERS
481                        | CONTEXT_DEBUG_REGISTERS
482 #endif
483                        ;
484     if (!GetThreadContext(h, ctx))
485     {
486         if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
487             fprintf(stderr, "Can't get thread's context\n");
488         return FALSE;
489     }
490     return TRUE;
491 }
492
493 static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* exc)
494 {
495     EXCEPTION_RECORD*   rec = &exc->ExceptionRecord;
496     BOOL                ret = FALSE;
497
498     switch (rec->ExceptionCode)
499     {
500     case EXCEPTION_ACCESS_VIOLATION:
501     case EXCEPTION_PRIV_INSTRUCTION:
502     case EXCEPTION_STACK_OVERFLOW:
503     case EXCEPTION_GUARD_PAGE:
504         gdbctx->last_sig = SIGSEGV;
505         ret = TRUE;
506         break;
507     case EXCEPTION_DATATYPE_MISALIGNMENT:
508         gdbctx->last_sig = SIGBUS;
509         ret = TRUE;
510         break;
511     case EXCEPTION_SINGLE_STEP:
512         /* fall through */
513     case EXCEPTION_BREAKPOINT:
514         gdbctx->last_sig = SIGTRAP;
515         ret = TRUE;
516         break;
517     case EXCEPTION_FLT_DENORMAL_OPERAND:
518     case EXCEPTION_FLT_DIVIDE_BY_ZERO:
519     case EXCEPTION_FLT_INEXACT_RESULT:
520     case EXCEPTION_FLT_INVALID_OPERATION:
521     case EXCEPTION_FLT_OVERFLOW:
522     case EXCEPTION_FLT_STACK_CHECK:
523     case EXCEPTION_FLT_UNDERFLOW:
524         gdbctx->last_sig = SIGFPE;
525         ret = TRUE;
526         break;
527     case EXCEPTION_INT_DIVIDE_BY_ZERO:
528     case EXCEPTION_INT_OVERFLOW:
529         gdbctx->last_sig = SIGFPE;
530         ret = TRUE;
531         break;
532     case EXCEPTION_ILLEGAL_INSTRUCTION:
533         gdbctx->last_sig = SIGILL;
534         ret = TRUE;
535         break;
536     case CONTROL_C_EXIT:
537         gdbctx->last_sig = SIGINT;
538         ret = TRUE;
539         break;
540     case STATUS_POSSIBLE_DEADLOCK:
541         gdbctx->last_sig = SIGALRM;
542         ret = TRUE;
543         /* FIXME: we could also add here a O packet with additional information */
544         break;
545     default:
546         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
547             fprintf(stderr, "Unhandled exception code 0x%08x\n", rec->ExceptionCode);
548         gdbctx->last_sig = SIGABRT;
549         ret = TRUE;
550         break;
551     }
552     return ret;
553 }
554
555 static  void    handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
556 {
557     union {
558         char                bufferA[256];
559         WCHAR               buffer[256];
560     } u;
561
562     dbg_curr_thread = dbg_get_thread(gdbctx->process, de->dwThreadId);
563
564     switch (de->dwDebugEventCode)
565     {
566     case CREATE_PROCESS_DEBUG_EVENT:
567         gdbctx->process = dbg_add_process(&be_process_gdbproxy_io, de->dwProcessId,
568                                           de->u.CreateProcessInfo.hProcess);
569         if (!gdbctx->process) break;
570         memory_get_string_indirect(gdbctx->process,
571                                    de->u.CreateProcessInfo.lpImageName,
572                                    de->u.CreateProcessInfo.fUnicode,
573                                    u.buffer, sizeof(u.buffer) / sizeof(WCHAR));
574         dbg_set_process_name(gdbctx->process, u.buffer);
575
576         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
577             fprintf(stderr, "%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n",
578                     de->dwProcessId, de->dwThreadId,
579                     dbg_W2A(u.buffer, -1),
580                     de->u.CreateProcessInfo.lpImageName,
581                     de->u.CreateProcessInfo.lpStartAddress,
582                     de->u.CreateProcessInfo.dwDebugInfoFileOffset,
583                     de->u.CreateProcessInfo.nDebugInfoSize);
584
585         /* de->u.CreateProcessInfo.lpStartAddress; */
586         if (!dbg_init(gdbctx->process->handle, u.buffer, TRUE))
587             fprintf(stderr, "Couldn't initiate DbgHelp\n");
588
589         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
590             fprintf(stderr, "%04x:%04x: create thread I @%p\n",
591                     de->dwProcessId, de->dwThreadId,
592                     de->u.CreateProcessInfo.lpStartAddress);
593
594         assert(dbg_curr_thread == NULL); /* shouldn't be there */
595         dbg_add_thread(gdbctx->process, de->dwThreadId,
596                        de->u.CreateProcessInfo.hThread,
597                        de->u.CreateProcessInfo.lpThreadLocalBase);
598         break;
599
600     case LOAD_DLL_DEBUG_EVENT:
601         assert(dbg_curr_thread);
602         memory_get_string_indirect(gdbctx->process,
603                                    de->u.LoadDll.lpImageName,
604                                    de->u.LoadDll.fUnicode,
605                                    u.buffer, sizeof(u.buffer) / sizeof(WCHAR));
606         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
607             fprintf(stderr, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
608                     de->dwProcessId, de->dwThreadId,
609                     dbg_W2A(u.buffer, -1),
610                     de->u.LoadDll.lpBaseOfDll,
611                     de->u.LoadDll.dwDebugInfoFileOffset,
612                     de->u.LoadDll.nDebugInfoSize);
613         dbg_load_module(gdbctx->process->handle, de->u.LoadDll.hFile, u.buffer,
614                         (DWORD_PTR)de->u.LoadDll.lpBaseOfDll, 0);
615         break;
616
617     case UNLOAD_DLL_DEBUG_EVENT:
618         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
619             fprintf(stderr, "%08x:%08x: unload DLL @%p\n",
620                     de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll);
621         SymUnloadModule(gdbctx->process->handle,
622                         (DWORD_PTR)de->u.UnloadDll.lpBaseOfDll);
623         break;
624
625     case EXCEPTION_DEBUG_EVENT:
626         assert(dbg_curr_thread);
627         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
628             fprintf(stderr, "%08x:%08x: exception code=0x%08x\n",
629                     de->dwProcessId, de->dwThreadId,
630                     de->u.Exception.ExceptionRecord.ExceptionCode);
631
632         if (fetch_context(gdbctx, dbg_curr_thread->handle, &gdbctx->context))
633         {
634             gdbctx->in_trap = handle_exception(gdbctx, &de->u.Exception);
635         }
636         break;
637
638     case CREATE_THREAD_DEBUG_EVENT:
639         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
640             fprintf(stderr, "%08x:%08x: create thread D @%p\n",
641                     de->dwProcessId, de->dwThreadId, de->u.CreateThread.lpStartAddress);
642
643         dbg_add_thread(gdbctx->process,
644                        de->dwThreadId,
645                        de->u.CreateThread.hThread,
646                        de->u.CreateThread.lpThreadLocalBase);
647         break;
648
649     case EXIT_THREAD_DEBUG_EVENT:
650         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
651             fprintf(stderr, "%08x:%08x: exit thread (%u)\n",
652                     de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
653
654         assert(dbg_curr_thread);
655         if (dbg_curr_thread == gdbctx->exec_thread) gdbctx->exec_thread = NULL;
656         if (dbg_curr_thread == gdbctx->other_thread) gdbctx->other_thread = NULL;
657         dbg_del_thread(dbg_curr_thread);
658         break;
659
660     case EXIT_PROCESS_DEBUG_EVENT:
661         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
662             fprintf(stderr, "%08x:%08x: exit process (%u)\n",
663                     de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode);
664
665         dbg_del_process(gdbctx->process);
666         gdbctx->process = NULL;
667         /* now signal gdb that we're done */
668         gdbctx->last_sig = SIGTERM;
669         gdbctx->in_trap = TRUE;
670         break;
671
672     case OUTPUT_DEBUG_STRING_EVENT:
673         assert(dbg_curr_thread);
674         memory_get_string(gdbctx->process,
675                           de->u.DebugString.lpDebugStringData, TRUE,
676                           de->u.DebugString.fUnicode, u.bufferA, sizeof(u.bufferA));
677         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
678             fprintf(stderr, "%08x:%08x: output debug string (%s)\n",
679                     de->dwProcessId, de->dwThreadId, u.bufferA);
680         break;
681
682     case RIP_EVENT:
683         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
684             fprintf(stderr, "%08x:%08x: rip error=%u type=%u\n",
685                     de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError,
686                     de->u.RipInfo.dwType);
687         break;
688
689     default:
690         if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
691             fprintf(stderr, "%08x:%08x: unknown event (%u)\n",
692                     de->dwProcessId, de->dwThreadId, de->dwDebugEventCode);
693     }
694 }
695
696 static void resume_debuggee(struct gdb_context* gdbctx, DWORD cont)
697 {
698     if (dbg_curr_thread)
699     {
700         if (!SetThreadContext(dbg_curr_thread->handle, &gdbctx->context))
701             if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
702                 fprintf(stderr, "Cannot set context on thread %04x\n", dbg_curr_thread->tid);
703         if (!ContinueDebugEvent(gdbctx->process->pid, dbg_curr_thread->tid, cont))
704             if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
705                 fprintf(stderr, "Cannot continue on %04x (%x)\n",
706                         dbg_curr_thread->tid, cont);
707     }
708     else if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
709         fprintf(stderr, "Cannot find last thread\n");
710 }
711
712
713 static void resume_debuggee_thread(struct gdb_context* gdbctx, DWORD cont, unsigned int threadid)
714 {
715
716     if (dbg_curr_thread)
717     {
718         if(dbg_curr_thread->tid  == threadid){
719             /* Windows debug and GDB don't seem to work well here, windows only likes ContinueDebugEvent being used on the reporter of the event */
720             if (!SetThreadContext(dbg_curr_thread->handle, &gdbctx->context))
721                 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
722                     fprintf(stderr, "Cannot set context on thread %04x\n", dbg_curr_thread->tid);
723             if (!ContinueDebugEvent(gdbctx->process->pid, dbg_curr_thread->tid, cont))
724                 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
725                     fprintf(stderr, "Cannot continue on %04x (%x)\n",
726                             dbg_curr_thread->tid, cont);
727         }
728     }
729     else if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
730         fprintf(stderr, "Cannot find last thread\n");
731 }
732
733 static BOOL     check_for_interrupt(struct gdb_context* gdbctx)
734 {
735         struct pollfd       pollfd;
736         int ret;
737         char pkt;
738                                 
739         pollfd.fd = gdbctx->sock;
740         pollfd.events = POLLIN;
741         pollfd.revents = 0;
742                                 
743         if ((ret = poll(&pollfd, 1, 0)) == 1) {
744                 ret = read(gdbctx->sock, &pkt, 1);
745                 if (ret != 1) {
746                         if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR) {
747                                 fprintf(stderr, "read failed\n");
748                         }
749                         return FALSE;
750                 }
751                 if (pkt != '\003') {
752                         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR) {
753                                 fprintf(stderr, "Unexpected break packet (%c/0x%X)\n", pkt, pkt);                               
754                         }
755                         return FALSE;
756                 }
757                 return TRUE;
758         } else if (ret == -1) {
759                 fprintf(stderr, "poll failed\n");
760         }
761         return FALSE;
762 }
763
764 static void    wait_for_debuggee(struct gdb_context* gdbctx)
765 {
766     DEBUG_EVENT         de;
767
768     gdbctx->in_trap = FALSE;
769     for (;;)
770     {
771                 if (!WaitForDebugEvent(&de, 10))
772                 {
773                         if (GetLastError() == ERROR_SEM_TIMEOUT)
774                         {
775                                 if (check_for_interrupt(gdbctx)) {
776                                         if (!DebugBreakProcess(gdbctx->process->handle)) {
777                                                 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR) {
778                                                         fprintf(stderr, "Failed to break into debugee\n");
779                                                 }
780                                                 break;
781                                         }
782                                         WaitForDebugEvent(&de, INFINITE);       
783                                 } else {
784                                         continue;
785                                 } 
786                         } else {
787                                 break;
788                         } 
789                 }
790         handle_debug_event(gdbctx, &de);
791         assert(!gdbctx->process ||
792                gdbctx->process->pid == 0 ||
793                de.dwProcessId == gdbctx->process->pid);
794         assert(!dbg_curr_thread || de.dwThreadId == dbg_curr_thread->tid);
795         if (gdbctx->in_trap) break;
796         ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
797     }
798 }
799
800 static void detach_debuggee(struct gdb_context* gdbctx, BOOL kill)
801 {
802     be_cpu->single_step(&gdbctx->context, FALSE);
803     resume_debuggee(gdbctx, DBG_CONTINUE);
804     if (!kill)
805         DebugActiveProcessStop(gdbctx->process->pid);
806     dbg_del_process(gdbctx->process);
807     gdbctx->process = NULL;
808 }
809
810 static void get_process_info(struct gdb_context* gdbctx, char* buffer, size_t len)
811 {
812     DWORD status;
813
814     if (!GetExitCodeProcess(gdbctx->process->handle, &status))
815     {
816         strcpy(buffer, "Unknown process");
817         return;
818     }
819     if (status == STILL_ACTIVE)
820     {
821         strcpy(buffer, "Running");
822     }
823     else
824         snprintf(buffer, len, "Terminated (%u)", status);
825
826     switch (GetPriorityClass(gdbctx->process->handle))
827     {
828     case 0: break;
829 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
830     case ABOVE_NORMAL_PRIORITY_CLASS:   strcat(buffer, ", above normal priority");      break;
831 #endif
832 #ifdef BELOW_NORMAL_PRIORITY_CLASS
833     case BELOW_NORMAL_PRIORITY_CLASS:   strcat(buffer, ", below normal priotity");      break;
834 #endif
835     case HIGH_PRIORITY_CLASS:           strcat(buffer, ", high priority");              break;
836     case IDLE_PRIORITY_CLASS:           strcat(buffer, ", idle priority");              break;
837     case NORMAL_PRIORITY_CLASS:         strcat(buffer, ", normal priority");            break;
838     case REALTIME_PRIORITY_CLASS:       strcat(buffer, ", realtime priority");          break;
839     }
840     strcat(buffer, "\n");
841 }
842
843 static void get_thread_info(struct gdb_context* gdbctx, unsigned tid,
844                             char* buffer, size_t len)
845 {
846     struct dbg_thread*  thd;
847     DWORD               status;
848     int                 prio;
849
850     /* FIXME: use the size of buffer */
851     thd = dbg_get_thread(gdbctx->process, tid);
852     if (thd == NULL)
853     {
854         strcpy(buffer, "No information");
855         return;
856     }
857     if (GetExitCodeThread(thd->handle, &status))
858     {
859         if (status == STILL_ACTIVE)
860         {
861             /* FIXME: this is a bit brutal... some nicer way shall be found */
862             switch (status = SuspendThread(thd->handle))
863             {
864             case -1: break;
865             case 0:  strcpy(buffer, "Running"); break;
866             default: snprintf(buffer, len, "Suspended (%u)", status - 1);
867             }
868             ResumeThread(thd->handle);
869         }
870         else
871             snprintf(buffer, len, "Terminated (exit code = %u)", status);
872     }
873     else
874     {
875         strcpy(buffer, "Unknown threadID");
876     }
877     switch (prio = GetThreadPriority(thd->handle))
878     {
879     case THREAD_PRIORITY_ERROR_RETURN:  break;
880     case THREAD_PRIORITY_ABOVE_NORMAL:  strcat(buffer, ", priority +1 above normal"); break;
881     case THREAD_PRIORITY_BELOW_NORMAL:  strcat(buffer, ", priority -1 below normal"); break;
882     case THREAD_PRIORITY_HIGHEST:       strcat(buffer, ", priority +2 above normal"); break;
883     case THREAD_PRIORITY_LOWEST:        strcat(buffer, ", priority -2 below normal"); break;
884     case THREAD_PRIORITY_IDLE:          strcat(buffer, ", priority idle"); break;
885     case THREAD_PRIORITY_NORMAL:        strcat(buffer, ", priority normal"); break;
886     case THREAD_PRIORITY_TIME_CRITICAL: strcat(buffer, ", priority time-critical"); break;
887     default: snprintf(buffer + strlen(buffer), len - strlen(buffer), ", priority = %d", prio);
888     }
889     assert(strlen(buffer) < len);
890 }
891
892 /* =============================================== *
893  *          P A C K E T        U T I L S           *
894  * =============================================== *
895  */
896
897 enum packet_return {packet_error = 0x00, packet_ok = 0x01, packet_done = 0x02,
898                     packet_last_f = 0x80};
899
900 static char* packet_realloc(char* buf, int size)
901 {
902     if (!buf)
903         return HeapAlloc(GetProcessHeap(), 0, size);
904     return HeapReAlloc(GetProcessHeap(), 0, buf, size);
905
906 }
907
908 static void packet_reply_grow(struct gdb_context* gdbctx, size_t size)
909 {
910     if (gdbctx->out_buf_alloc < gdbctx->out_len + size)
911     {
912         gdbctx->out_buf_alloc = ((gdbctx->out_len + size) / 32 + 1) * 32;
913         gdbctx->out_buf = packet_realloc(gdbctx->out_buf, gdbctx->out_buf_alloc);
914     }
915 }
916
917 static void packet_reply_hex_to(struct gdb_context* gdbctx, const void* src, int len)
918 {
919     packet_reply_grow(gdbctx, len * 2);
920     hex_to(&gdbctx->out_buf[gdbctx->out_len], src, len);
921     gdbctx->out_len += len * 2;
922 }
923
924 static inline void packet_reply_hex_to_str(struct gdb_context* gdbctx, const char* src)
925 {
926     packet_reply_hex_to(gdbctx, src, strlen(src));
927 }
928
929 static void packet_reply_val(struct gdb_context* gdbctx, unsigned long val, int len)
930 {
931     int i, shift;
932
933     shift = (len - 1) * 8;
934     packet_reply_grow(gdbctx, len * 2);
935     for (i = 0; i < len; i++, shift -= 8)
936     {
937         gdbctx->out_buf[gdbctx->out_len++] = hex_to0((val >> (shift + 4)) & 0x0F);
938         gdbctx->out_buf[gdbctx->out_len++] = hex_to0((val >>  shift     ) & 0x0F);
939     }
940 }
941
942 static inline void packet_reply_add(struct gdb_context* gdbctx, const char* str, int len)
943 {
944     packet_reply_grow(gdbctx, len);
945     memcpy(&gdbctx->out_buf[gdbctx->out_len], str, len);
946     gdbctx->out_len += len;
947 }
948
949 static inline void packet_reply_cat(struct gdb_context* gdbctx, const char* str)
950 {
951     packet_reply_add(gdbctx, str, strlen(str));
952 }
953
954 static inline void packet_reply_catc(struct gdb_context* gdbctx, char ch)
955 {
956     packet_reply_add(gdbctx, &ch, 1);
957 }
958
959 static void packet_reply_open(struct gdb_context* gdbctx)
960 {
961     assert(gdbctx->out_curr_packet == -1);
962     packet_reply_catc(gdbctx, '$');
963     gdbctx->out_curr_packet = gdbctx->out_len;
964 }
965
966 static void packet_reply_close(struct gdb_context* gdbctx)
967 {
968     unsigned char       cksum;
969     int plen;
970
971     plen = gdbctx->out_len - gdbctx->out_curr_packet;
972     packet_reply_catc(gdbctx, '#');
973     cksum = checksum(&gdbctx->out_buf[gdbctx->out_curr_packet], plen);
974     packet_reply_hex_to(gdbctx, &cksum, 1);
975     if (gdbctx->trace & GDBPXY_TRC_PACKET)
976         fprintf(stderr, "Reply : %*.*s\n",
977                 plen, plen, &gdbctx->out_buf[gdbctx->out_curr_packet]);
978     gdbctx->out_curr_packet = -1;
979 }
980
981 static enum packet_return packet_reply(struct gdb_context* gdbctx, const char* packet, int len)
982 {
983     packet_reply_open(gdbctx);
984
985     if (len == -1) len = strlen(packet);
986     assert(memchr(packet, '$', len) == NULL && memchr(packet, '#', len) == NULL);
987
988     packet_reply_add(gdbctx, packet, len);
989
990     packet_reply_close(gdbctx);
991
992     return packet_done;
993 }
994
995 static enum packet_return packet_reply_error(struct gdb_context* gdbctx, int error)
996 {
997     packet_reply_open(gdbctx);
998
999     packet_reply_add(gdbctx, "E", 1);
1000     packet_reply_val(gdbctx, error, 1);
1001
1002     packet_reply_close(gdbctx);
1003
1004     return packet_done;
1005 }
1006
1007 static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, unsigned idx)
1008 {
1009     DWORD64     val = cpu_register(&gdbctx->context, idx);
1010     unsigned    i;
1011
1012     for (i = 0; i < cpu_register_map[idx].gdb_length; i++)
1013     {
1014         BYTE    b = val;
1015         packet_reply_hex_to(gdbctx, &b, 1);
1016         val >>= 8;
1017     }
1018 }
1019
1020 /* =============================================== *
1021  *          P A C K E T   H A N D L E R S          *
1022  * =============================================== *
1023  */
1024
1025 static enum packet_return packet_reply_status(struct gdb_context* gdbctx)
1026 {
1027     enum packet_return ret = packet_done;
1028
1029     packet_reply_open(gdbctx);
1030
1031     if (gdbctx->process != NULL)
1032     {
1033         unsigned char           sig;
1034         unsigned                i;
1035
1036         packet_reply_catc(gdbctx, 'T');
1037         sig = gdbctx->last_sig;
1038         packet_reply_val(gdbctx, sig, 1);
1039         packet_reply_add(gdbctx, "thread:", 7);
1040         packet_reply_val(gdbctx, dbg_curr_thread->tid, 4);
1041         packet_reply_catc(gdbctx, ';');
1042
1043         for (i = 0; i < cpu_num_regs; i++)
1044         {
1045             /* FIXME: this call will also grow the buffer...
1046              * unneeded, but not harmful
1047              */
1048             packet_reply_val(gdbctx, i, 1);
1049             packet_reply_catc(gdbctx, ':');
1050             packet_reply_register_hex_to(gdbctx, i);
1051             packet_reply_catc(gdbctx, ';');
1052         }
1053     }
1054     else
1055     {
1056         /* Try to put an exit code
1057          * Cannot use GetExitCodeProcess, wouldn't fit in a 8 bit value, so
1058          * just indicate the end of process and exit */
1059         packet_reply_add(gdbctx, "W00", 3);
1060         /*if (!gdbctx->extended)*/ ret |= packet_last_f;
1061     }
1062
1063     packet_reply_close(gdbctx);
1064
1065     return ret;
1066 }
1067
1068 #if 0
1069 static enum packet_return packet_extended(struct gdb_context* gdbctx)
1070 {
1071     gdbctx->extended = 1;
1072     return packet_ok;
1073 }
1074 #endif
1075
1076 static enum packet_return packet_last_signal(struct gdb_context* gdbctx)
1077 {
1078     assert(gdbctx->in_packet_len == 0);
1079     return packet_reply_status(gdbctx);
1080 }
1081
1082 static enum packet_return packet_continue(struct gdb_context* gdbctx)
1083 {
1084     /* FIXME: add support for address in packet */
1085     assert(gdbctx->in_packet_len == 0);
1086     if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
1087         if (gdbctx->trace & GDBPXY_TRC_COMMAND_FIXME)
1088             fprintf(stderr, "NIY: cont on %04x, while last thread is %04x\n",
1089                     gdbctx->exec_thread->tid, dbg_curr_thread->tid);
1090     resume_debuggee(gdbctx, DBG_CONTINUE);
1091     wait_for_debuggee(gdbctx);
1092     return packet_reply_status(gdbctx);
1093 }
1094
1095 static enum packet_return packet_verbose_cont(struct gdb_context* gdbctx)
1096 {
1097     int i;
1098     int defaultAction = -1; /* magic non action */
1099     unsigned char sig;
1100     int actions =0;
1101     int actionIndex[20]; /* allow for up to 20 actions */
1102     int threadIndex[20];
1103     int threadCount = 0;
1104     unsigned int threadIDs[100]; /* TODO: Should make this dynamic */
1105     unsigned int threadID = 0;
1106     struct dbg_thread*  thd;
1107
1108     /* OK we have vCont followed by..
1109     * ? for query
1110     * c for packet_continue
1111     * Csig for packet_continue_signal
1112     * s for step
1113     * Ssig  for step signal
1114     * and then an optional thread ID at the end..
1115     * *******************************************/
1116
1117     /* Query */
1118     if (gdbctx->in_packet[4] == '?')
1119     {
1120         /*
1121           Reply:
1122           `vCont[;action]...'
1123           The vCont packet is supported. Each action is a supported command in the vCont packet.
1124           `'
1125           The vCont packet is not supported.  (this didn't seem to be obeyed!)
1126         */
1127         packet_reply_open(gdbctx);
1128         packet_reply_add(gdbctx, "vCont", 5);
1129         /* add all the supported actions to the reply (all of them for now) */
1130         packet_reply_add(gdbctx, ";c", 2);
1131         packet_reply_add(gdbctx, ";C", 2);
1132         packet_reply_add(gdbctx, ";s", 2);
1133         packet_reply_add(gdbctx, ";S", 2);
1134         packet_reply_close(gdbctx);
1135         return packet_done;
1136     }
1137
1138     /* This may not be the 'fastest' code in the world. but it should be nice and easy to debug.
1139     (as it's run when people are debugging break points I'm sure they won't notice the extra 100 cycles anyway)
1140     now if only gdb talked XML.... */
1141 #if 0 /* handy for debugging */
1142     fprintf(stderr, "no, but can we find a default packet %.*s %d\n", gdbctx->in_packet_len, gdbctx->in_packet,  gdbctx->in_packet_len);
1143 #endif
1144
1145     /* go through the packet and identify where all the actions start at */
1146     for (i = 4; i < gdbctx->in_packet_len - 1; i++)
1147     {
1148         if (gdbctx->in_packet[i] == ';')
1149         {
1150             threadIndex[actions] = 0;
1151             actionIndex[actions++] = i;
1152         }
1153         else if (gdbctx->in_packet[i] == ':')
1154         {
1155             threadIndex[actions - 1] = i;
1156         }
1157     }
1158
1159     /* now look up the default action */
1160     for (i = 0 ; i < actions; i++)
1161     {
1162         if (threadIndex[i] == 0)
1163         {
1164             if (defaultAction != -1)
1165             {
1166                 fprintf(stderr,"Too many default actions specified\n");
1167                 return packet_error;
1168             }
1169             defaultAction = i;
1170         }
1171     }
1172
1173     /* Now, I have this default action thing that needs to be applied to all non counted threads */
1174
1175     /* go through all the threads and stick their ids in the to be done list. */
1176     LIST_FOR_EACH_ENTRY(thd, &gdbctx->process->threads, struct dbg_thread, entry)
1177     {
1178         threadIDs[threadCount++] = thd->tid;
1179         /* check to see if we have more threads than I counted on, and tell the user what to do
1180          * (they're running winedbg, so I'm sure they can fix the problem from the error message!) */
1181         if (threadCount == 100)
1182         {
1183             fprintf(stderr, "Wow, that's a lot of threads, change threadIDs in wine/programs/winedbg/gdbproxy.c to be higher\n");
1184             break;
1185         }
1186     }
1187
1188     /* Ok, now we have... actionIndex full of actions and we know what threads there are, so all
1189      * that remains is to apply the actions to the threads and the default action to any threads
1190      * left */
1191     if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
1192     if (gdbctx->trace & GDBPXY_TRC_COMMAND_FIXME)
1193         fprintf(stderr, "NIY: cont on %04x, while last thread is %04x\n",
1194                 gdbctx->exec_thread->tid, dbg_curr_thread->tid);
1195
1196     /* deal with the threaded stuff first */
1197     for (i = 0; i < actions ; i++)
1198     {
1199         if (threadIndex[i] != 0)
1200         {
1201             int j, idLength = 0;
1202             if (i < actions - 1)
1203             {
1204                 idLength = (actionIndex[i+1] - threadIndex[i]) - 1;
1205             }
1206             else
1207             {
1208                 idLength = (gdbctx->in_packet_len - threadIndex[i]) - 1;
1209             }
1210
1211             threadID = hex_to_int(gdbctx->in_packet + threadIndex[i] + 1 , idLength);
1212             /* process the action */
1213             switch (gdbctx->in_packet[actionIndex[i] + 1])
1214             {
1215             case 's': /* step */
1216                 be_cpu->single_step(&gdbctx->context, TRUE);
1217                 /* fall through*/
1218             case 'c': /* continue */
1219                 resume_debuggee_thread(gdbctx, DBG_CONTINUE, threadID);
1220                 break;
1221             case 'S': /* step Sig, */
1222                 be_cpu->single_step(&gdbctx->context, TRUE);
1223                 /* fall through */
1224             case 'C': /* continue sig */
1225                 hex_from(&sig, gdbctx->in_packet + actionIndex[i] + 2, 1);
1226                 /* cannot change signals on the fly */
1227                 if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1228                     fprintf(stderr, "sigs: %u %u\n", sig, gdbctx->last_sig);
1229                 if (sig != gdbctx->last_sig)
1230                     return packet_error;
1231                 resume_debuggee_thread(gdbctx, DBG_EXCEPTION_NOT_HANDLED, threadID);
1232                 break;
1233             }
1234             for (j = 0 ; j < threadCount; j++)
1235             {
1236                 if (threadIDs[j] == threadID)
1237                 {
1238                     threadIDs[j] = 0;
1239                     break;
1240                 }
1241             }
1242         }
1243     } /* for i=0 ; i< actions */
1244
1245     /* now we have manage the default action */
1246     if (defaultAction >= 0)
1247     {
1248         for (i = 0 ; i< threadCount; i++)
1249         {
1250             /* check to see if we've already done something to the thread*/
1251             if (threadIDs[i] != 0)
1252             {
1253                 /* if not apply the default action*/
1254                 threadID = threadIDs[i];
1255                 /* process the action (yes this is almost identical to the one above!) */
1256                 switch (gdbctx->in_packet[actionIndex[defaultAction] + 1])
1257                 {
1258                 case 's': /* step */
1259                     be_cpu->single_step(&gdbctx->context, TRUE);
1260                     /* fall through */
1261                 case 'c': /* continue */
1262                     resume_debuggee_thread(gdbctx, DBG_CONTINUE, threadID);
1263                     break;
1264                 case 'S':
1265                      be_cpu->single_step(&gdbctx->context, TRUE);
1266                      /* fall through */
1267                 case 'C': /* continue sig */
1268                     hex_from(&sig, gdbctx->in_packet + actionIndex[defaultAction] + 2, 1);
1269                     /* cannot change signals on the fly */
1270                     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1271                         fprintf(stderr, "sigs: %u %u\n", sig, gdbctx->last_sig);
1272                     if (sig != gdbctx->last_sig)
1273                         return packet_error;
1274                     resume_debuggee_thread(gdbctx, DBG_EXCEPTION_NOT_HANDLED, threadID);
1275                     break;
1276                 }
1277             }
1278         }
1279     } /* if(defaultAction >=0) */
1280
1281     wait_for_debuggee(gdbctx);
1282     be_cpu->single_step(&gdbctx->context, FALSE);
1283     return packet_reply_status(gdbctx);
1284 }
1285
1286 struct verbose_defail
1287 {
1288     const char*         name;
1289     unsigned            len;
1290     enum packet_return  (*handler)(struct gdb_context*);
1291 } verbose_details[] =
1292 {
1293     /* {"Attach",           6}, */
1294     {"Cont",             4, packet_verbose_cont},
1295     /* {"File",             4},
1296     {"FlashErase",      10},
1297     {"FlashWrite",      10},
1298     {"FlashDone",        9},
1299     {"Kill",             4},
1300     {"Run",              3},
1301     {"Stopped",          7},*/
1302 };
1303
1304 static enum packet_return packet_verbose(struct gdb_context* gdbctx)
1305 {
1306     unsigned i;
1307     unsigned klen;
1308
1309     for (klen = 0; ; klen++)
1310     {
1311         if (klen == gdbctx->in_packet_len ||
1312             gdbctx->in_packet[klen] == ';' ||
1313             gdbctx->in_packet[klen] == ':' ||
1314             gdbctx->in_packet[klen] == '?')
1315         {
1316             if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1317                 fprintf(stderr, "trying to process a verbose packet %*.*s\n",
1318                         gdbctx->in_packet_len, gdbctx->in_packet_len, gdbctx->in_packet);
1319             for (i = 0; i < sizeof(verbose_details)/sizeof(verbose_details[0]); i++)
1320             {
1321                 if (klen == verbose_details[i].len &&
1322                     !memcmp(gdbctx->in_packet, verbose_details[i].name, verbose_details[i].len))
1323                 {
1324                     return verbose_details[i].handler(gdbctx);
1325                 }
1326             }
1327             /* no matching handler found, abort */
1328             break;
1329         }
1330     }
1331
1332     if (gdbctx->trace & GDBPXY_TRC_COMMAND_FIXME)
1333         fprintf(stderr, "No support for verbose packet %*.*s\n",
1334                 gdbctx->in_packet_len, gdbctx->in_packet_len, gdbctx->in_packet);
1335     return packet_error;
1336  }
1337
1338 static enum packet_return packet_continue_signal(struct gdb_context* gdbctx)
1339 {
1340     unsigned char sig;
1341
1342     /* FIXME: add support for address in packet */
1343     assert(gdbctx->in_packet_len == 2);
1344     if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
1345         if (gdbctx->trace & GDBPXY_TRC_COMMAND_FIXME)
1346             fprintf(stderr, "NIY: cont/sig on %04x, while last thread is %04x\n",
1347                     gdbctx->exec_thread->tid, dbg_curr_thread->tid);
1348     hex_from(&sig, gdbctx->in_packet, 1);
1349     /* cannot change signals on the fly */
1350     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1351         fprintf(stderr, "sigs: %u %u\n", sig, gdbctx->last_sig);
1352     if (sig != gdbctx->last_sig)
1353         return packet_error;
1354     resume_debuggee(gdbctx, DBG_EXCEPTION_NOT_HANDLED);
1355     wait_for_debuggee(gdbctx);
1356     return packet_reply_status(gdbctx);
1357 }
1358
1359 static enum packet_return packet_detach(struct gdb_context* gdbctx)
1360 {
1361     detach_debuggee(gdbctx, FALSE);
1362     return packet_ok | packet_last_f;
1363 }
1364
1365 static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
1366 {
1367     int                 i;
1368     CONTEXT             ctx;
1369     CONTEXT*            pctx = &gdbctx->context;
1370
1371     assert(gdbctx->in_trap);
1372
1373     if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
1374     {
1375         if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
1376             return packet_error;
1377     }
1378
1379     packet_reply_open(gdbctx);
1380     for (i = 0; i < cpu_num_regs; i++)
1381     {
1382         packet_reply_register_hex_to(gdbctx, i);
1383     }
1384     packet_reply_close(gdbctx);
1385     return packet_done;
1386 }
1387
1388 static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
1389 {
1390     unsigned    i;
1391     CONTEXT     ctx;
1392     CONTEXT*    pctx = &gdbctx->context;
1393     const char* ptr;
1394
1395     assert(gdbctx->in_trap);
1396     if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
1397     {
1398         if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
1399             return packet_error;
1400     }
1401     if (gdbctx->in_packet_len < cpu_num_regs * 2) return packet_error;
1402
1403     ptr = gdbctx->in_packet;
1404     for (i = 0; i < cpu_num_regs; i++)
1405     {
1406         cpu_register_hex_from(pctx, i, &ptr);
1407     }
1408     if (pctx != &gdbctx->context && !SetThreadContext(gdbctx->other_thread->handle, pctx))
1409     {
1410         if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
1411             fprintf(stderr, "Cannot set context on thread %04x\n", gdbctx->other_thread->tid);
1412         return packet_error;
1413     }
1414     return packet_ok;
1415 }
1416
1417 static enum packet_return packet_kill(struct gdb_context* gdbctx)
1418 {
1419     detach_debuggee(gdbctx, TRUE);
1420 #if 0
1421     if (!gdbctx->extended)
1422         /* dunno whether GDB cares or not */
1423 #endif
1424     wait(NULL);
1425     exit(0);
1426     /* assume we can't really answer something here */
1427     /* return packet_done; */
1428 }
1429
1430 static enum packet_return packet_thread(struct gdb_context* gdbctx)
1431 {
1432     char* end;
1433     unsigned thread;
1434
1435     switch (gdbctx->in_packet[0])
1436     {
1437     case 'c':
1438     case 'g':
1439         if (gdbctx->in_packet[1] == '-')
1440             thread = -strtol(gdbctx->in_packet + 2, &end, 16);
1441         else
1442             thread = strtol(gdbctx->in_packet + 1, &end, 16);
1443         if (end == NULL || end > gdbctx->in_packet + gdbctx->in_packet_len)
1444         {
1445             if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1446                 fprintf(stderr, "Cannot get threadid %*.*s\n",
1447                         gdbctx->in_packet_len - 1, gdbctx->in_packet_len - 1,
1448                         gdbctx->in_packet + 1);
1449             return packet_error;
1450         }
1451         if (gdbctx->in_packet[0] == 'c')
1452             gdbctx->exec_thread = dbg_get_thread(gdbctx->process, thread);
1453         else
1454             gdbctx->other_thread = dbg_get_thread(gdbctx->process, thread);
1455         return packet_ok;
1456     default:
1457         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1458             fprintf(stderr, "Unknown thread sub-command %c\n", gdbctx->in_packet[0]);
1459         return packet_error;
1460     }
1461 }
1462
1463 static enum packet_return packet_read_memory(struct gdb_context* gdbctx)
1464 {
1465     char               *addr;
1466     unsigned int        len, blk_len, nread;
1467     char                buffer[32];
1468     SIZE_T              r = 0;
1469
1470     assert(gdbctx->in_trap);
1471     /* FIXME:check in_packet_len for reading %p,%x */
1472     if (sscanf(gdbctx->in_packet, "%p,%x", &addr, &len) != 2) return packet_error;
1473     if (len <= 0) return packet_error;
1474     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1475         fprintf(stderr, "Read mem at %p for %u bytes\n", addr, len);
1476     for (nread = 0; nread < len; nread += r, addr += r)
1477     {
1478         blk_len = min(sizeof(buffer), len - nread);
1479         if (!gdbctx->process->process_io->read(gdbctx->process->handle, addr, buffer, blk_len, &r) ||
1480             r == 0)
1481         {
1482             /* fail at first address, return error */
1483             if (nread == 0) return packet_reply_error(gdbctx, EFAULT);
1484             /* something has already been read, return partial information */
1485             break;
1486         }
1487         if (nread == 0) packet_reply_open(gdbctx);
1488         packet_reply_hex_to(gdbctx, buffer, r);
1489     }
1490     packet_reply_close(gdbctx);
1491     return packet_done;
1492 }
1493
1494 static enum packet_return packet_write_memory(struct gdb_context* gdbctx)
1495 {
1496     char*               addr;
1497     unsigned int        len, blk_len;
1498     char*               ptr;
1499     char                buffer[32];
1500     SIZE_T              w;
1501
1502     assert(gdbctx->in_trap);
1503     ptr = memchr(gdbctx->in_packet, ':', gdbctx->in_packet_len);
1504     if (ptr == NULL)
1505     {
1506         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1507             fprintf(stderr, "Cannot find ':' in %*.*s\n",
1508                     gdbctx->in_packet_len, gdbctx->in_packet_len, gdbctx->in_packet);
1509         return packet_error;
1510     }
1511     *ptr++ = '\0';
1512
1513     if (sscanf(gdbctx->in_packet, "%p,%x", &addr, &len) != 2)
1514     {
1515         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1516             fprintf(stderr, "Cannot scan addr,len in %s\n", gdbctx->in_packet);
1517         return packet_error;
1518     }
1519     if (ptr - gdbctx->in_packet + len * 2 != gdbctx->in_packet_len)
1520     {
1521         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1522             fprintf(stderr, "Wrong sizes %u <> %u\n",
1523                     (int)(ptr - gdbctx->in_packet) + len * 2, gdbctx->in_packet_len);
1524         return packet_error;
1525     }
1526     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1527         fprintf(stderr, "Write %u bytes at %p\n", len, addr);
1528     while (len > 0)
1529     {
1530         blk_len = min(sizeof(buffer), len);
1531         hex_from(buffer, ptr, blk_len);
1532         if (!gdbctx->process->process_io->write(gdbctx->process->handle, addr, buffer, blk_len, &w) ||
1533             w != blk_len)
1534             break;
1535         addr += blk_len;
1536         len -= blk_len;
1537         ptr += blk_len;
1538     }
1539     return packet_ok; /* FIXME: error while writing ? */
1540 }
1541
1542 static enum packet_return packet_read_register(struct gdb_context* gdbctx)
1543 {
1544     unsigned            reg;
1545     CONTEXT             ctx;
1546     CONTEXT*            pctx = &gdbctx->context;
1547
1548     assert(gdbctx->in_trap);
1549     reg = hex_to_int(gdbctx->in_packet, gdbctx->in_packet_len);
1550     if (reg >= cpu_num_regs)
1551     {
1552         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1553             fprintf(stderr, "Register out of bounds %x\n", reg);
1554         return packet_error;
1555     }
1556     if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
1557     {
1558         if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
1559             return packet_error;
1560     }
1561     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1562         fprintf(stderr, "Read register %x => %08x%08x\n", reg,
1563                 (unsigned)(cpu_register(pctx, reg) >> 32), (unsigned)cpu_register(pctx, reg));
1564     packet_reply_open(gdbctx);
1565     packet_reply_register_hex_to(gdbctx, reg);
1566     packet_reply_close(gdbctx);
1567     return packet_done;
1568 }
1569
1570 static enum packet_return packet_write_register(struct gdb_context* gdbctx)
1571 {
1572     unsigned            reg;
1573     char*               ptr;
1574     CONTEXT             ctx;
1575     CONTEXT*            pctx = &gdbctx->context;
1576
1577     assert(gdbctx->in_trap);
1578
1579     reg = strtoul(gdbctx->in_packet, &ptr, 16);
1580     if (ptr == NULL || reg >= cpu_num_regs || *ptr++ != '=')
1581     {
1582         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1583             fprintf(stderr, "Invalid register index %s\n", gdbctx->in_packet);
1584         /* FIXME: if just the reg is above cpu_num_regs, don't tell gdb
1585          *        it wouldn't matter too much, and it fakes our support for all regs
1586          */
1587         return (ptr == NULL) ? packet_error : packet_ok;
1588     }
1589     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1590     {
1591         int len = gdbctx->in_packet_len - (ptr - gdbctx->in_packet);
1592         fprintf(stderr, "Writing reg %u <= %*.*s\n", reg, len, len, ptr);
1593     }
1594
1595     if (dbg_curr_thread != gdbctx->other_thread && gdbctx->other_thread)
1596     {
1597         if (!fetch_context(gdbctx, gdbctx->other_thread->handle, pctx = &ctx))
1598             return packet_error;
1599     }
1600
1601     cpu_register_hex_from(pctx, reg, (const char**)&ptr);
1602     if (pctx != &gdbctx->context && !SetThreadContext(gdbctx->other_thread->handle, pctx))
1603     {
1604         if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
1605             fprintf(stderr, "Cannot set context for thread %04x\n", gdbctx->other_thread->tid);
1606         return packet_error;
1607     }
1608
1609     return packet_ok;
1610 }
1611
1612 static void packet_query_monitor_wnd_helper(struct gdb_context* gdbctx, HWND hWnd, int indent)
1613 {
1614     char        buffer[128];
1615     char        clsName[128];
1616     char        wndName[128];
1617     HWND        child;
1618
1619     do {
1620        if (!GetClassNameA(hWnd, clsName, sizeof(clsName)))
1621           strcpy(clsName, "-- Unknown --");
1622        if (!GetWindowTextA(hWnd, wndName, sizeof(wndName)))
1623           strcpy(wndName, "-- Empty --");
1624
1625        packet_reply_open(gdbctx);
1626        packet_reply_catc(gdbctx, 'O');
1627        snprintf(buffer, sizeof(buffer),
1628                 "%*s%04lx%*s%-17.17s %08x %0*lx %.14s\n",
1629                 indent, "", (ULONG_PTR)hWnd, 13 - indent, "",
1630                 clsName, GetWindowLongW(hWnd, GWL_STYLE),
1631                 ADDRWIDTH, (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_WNDPROC),
1632                 wndName);
1633        packet_reply_hex_to_str(gdbctx, buffer);
1634        packet_reply_close(gdbctx);
1635
1636        if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
1637           packet_query_monitor_wnd_helper(gdbctx, child, indent + 1);
1638     } while ((hWnd = GetWindow(hWnd, GW_HWNDNEXT)) != 0);
1639 }
1640
1641 static void packet_query_monitor_wnd(struct gdb_context* gdbctx, int len, const char* str)
1642 {
1643     char        buffer[128];
1644
1645     /* we do the output in several 'O' packets, with the last one being just OK for
1646      * marking the end of the output */
1647     packet_reply_open(gdbctx);
1648     packet_reply_catc(gdbctx, 'O');
1649     snprintf(buffer, sizeof(buffer),
1650              "%-16.16s %-17.17s %-8.8s %s\n",
1651              "hwnd", "Class Name", " Style", " WndProc Text");
1652     packet_reply_hex_to_str(gdbctx, buffer);
1653     packet_reply_close(gdbctx);
1654
1655     /* FIXME: could also add a pmt to this command in str... */
1656     packet_query_monitor_wnd_helper(gdbctx, GetDesktopWindow(), 0);
1657     packet_reply(gdbctx, "OK", 2);
1658 }
1659
1660 static void packet_query_monitor_process(struct gdb_context* gdbctx, int len, const char* str)
1661 {
1662     HANDLE              snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1663     char                buffer[128];
1664     char                deco;
1665     PROCESSENTRY32      entry;
1666     BOOL                ok;
1667
1668     if (snap == INVALID_HANDLE_VALUE)
1669         return;
1670
1671     entry.dwSize = sizeof(entry);
1672     ok = Process32First(snap, &entry);
1673
1674     /* we do the output in several 'O' packets, with the last one being just OK for
1675      * marking the end of the output */
1676
1677     packet_reply_open(gdbctx);
1678     packet_reply_catc(gdbctx, 'O');
1679     snprintf(buffer, sizeof(buffer),
1680              " %-8.8s %-8.8s %-8.8s %s\n",
1681              "pid", "threads", "parent", "executable");
1682     packet_reply_hex_to_str(gdbctx, buffer);
1683     packet_reply_close(gdbctx);
1684
1685     while (ok)
1686     {
1687         deco = ' ';
1688         if (entry.th32ProcessID == gdbctx->process->pid) deco = '>';
1689         packet_reply_open(gdbctx);
1690         packet_reply_catc(gdbctx, 'O');
1691         snprintf(buffer, sizeof(buffer),
1692                  "%c%08x %-8d %08x '%s'\n",
1693                  deco, entry.th32ProcessID, entry.cntThreads,
1694                  entry.th32ParentProcessID, entry.szExeFile);
1695         packet_reply_hex_to_str(gdbctx, buffer);
1696         packet_reply_close(gdbctx);
1697         ok = Process32Next(snap, &entry);
1698     }
1699     CloseHandle(snap);
1700     packet_reply(gdbctx, "OK", 2);
1701 }
1702
1703 static void packet_query_monitor_mem(struct gdb_context* gdbctx, int len, const char* str)
1704 {
1705     MEMORY_BASIC_INFORMATION    mbi;
1706     char*                       addr = 0;
1707     const char*                 state;
1708     const char*                 type;
1709     char                        prot[3+1];
1710     char                        buffer[128];
1711
1712     /* we do the output in several 'O' packets, with the last one being just OK for
1713      * marking the end of the output */
1714     packet_reply_open(gdbctx);
1715     packet_reply_catc(gdbctx, 'O');
1716     packet_reply_hex_to_str(gdbctx, "Address  Size     State   Type    RWX\n");
1717     packet_reply_close(gdbctx);
1718
1719     while (VirtualQueryEx(gdbctx->process->handle, addr, &mbi, sizeof(mbi)) >= sizeof(mbi))
1720     {
1721         switch (mbi.State)
1722         {
1723         case MEM_COMMIT:        state = "commit "; break;
1724         case MEM_FREE:          state = "free   "; break;
1725         case MEM_RESERVE:       state = "reserve"; break;
1726         default:                state = "???    "; break;
1727         }
1728         if (mbi.State != MEM_FREE)
1729         {
1730             switch (mbi.Type)
1731             {
1732             case MEM_IMAGE:         type = "image  "; break;
1733             case MEM_MAPPED:        type = "mapped "; break;
1734             case MEM_PRIVATE:       type = "private"; break;
1735             case 0:                 type = "       "; break;
1736             default:                type = "???    "; break;
1737             }
1738             memset(prot, ' ' , sizeof(prot)-1);
1739             prot[sizeof(prot)-1] = '\0';
1740             if (mbi.AllocationProtect & (PAGE_READONLY|PAGE_READWRITE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
1741                 prot[0] = 'R';
1742             if (mbi.AllocationProtect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE))
1743                 prot[1] = 'W';
1744             if (mbi.AllocationProtect & (PAGE_WRITECOPY|PAGE_EXECUTE_WRITECOPY))
1745                 prot[1] = 'C';
1746             if (mbi.AllocationProtect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
1747                 prot[2] = 'X';
1748         }
1749         else
1750         {
1751             type = "";
1752             prot[0] = '\0';
1753         }
1754         packet_reply_open(gdbctx);
1755         snprintf(buffer, sizeof(buffer), "%0*lx %0*lx %s %s %s\n",
1756                  (unsigned)sizeof(void*), (DWORD_PTR)addr,
1757                  (unsigned)sizeof(void*), mbi.RegionSize, state, type, prot);
1758         packet_reply_catc(gdbctx, 'O');
1759         packet_reply_hex_to_str(gdbctx, buffer);
1760         packet_reply_close(gdbctx);
1761
1762         if (addr + mbi.RegionSize < addr) /* wrap around ? */
1763             break;
1764         addr += mbi.RegionSize;
1765     }
1766     packet_reply(gdbctx, "OK", 2);
1767 }
1768
1769 static void packet_query_monitor_trace(struct gdb_context* gdbctx,
1770                                        int len, const char* str)
1771 {
1772     char        buffer[128];
1773
1774     if (len == 0)
1775     {
1776         snprintf(buffer, sizeof(buffer), "trace=%x\n", gdbctx->trace);
1777     }
1778     else if (len >= 2 && str[0] == '=')
1779     {
1780         unsigned val = atoi(&str[1]);
1781         snprintf(buffer, sizeof(buffer), "trace: %x => %x\n", gdbctx->trace, val);
1782         gdbctx->trace = val;
1783     }
1784     else
1785     {
1786         /* FIXME: ugly but can use error packet here */
1787         packet_reply_cat(gdbctx, "E00");
1788         return;
1789     }
1790     packet_reply_open(gdbctx);
1791     packet_reply_hex_to_str(gdbctx, buffer);
1792     packet_reply_close(gdbctx);
1793 }
1794
1795 struct query_detail
1796 {
1797     int         with_arg;
1798     const char* name;
1799     size_t      len;
1800     void        (*handler)(struct gdb_context*, int, const char*);
1801 } query_details[] =
1802 {
1803     {0, "wnd",     3, packet_query_monitor_wnd},
1804     {0, "window",  6, packet_query_monitor_wnd},
1805     {0, "proc",    4, packet_query_monitor_process},
1806     {0, "process", 7, packet_query_monitor_process},
1807     {0, "mem",     3, packet_query_monitor_mem},
1808     {1, "trace",   5, packet_query_monitor_trace},
1809     {0, NULL,      0, NULL},
1810 };
1811
1812 static enum packet_return packet_query_remote_command(struct gdb_context* gdbctx,
1813                                                       const char* hxcmd, size_t len)
1814 {
1815     char                        buffer[128];
1816     struct query_detail*        qd;
1817
1818     assert((len & 1) == 0 && len < 2 * sizeof(buffer));
1819     len /= 2;
1820     hex_from(buffer, hxcmd, len);
1821
1822     for (qd = query_details; qd->name != NULL; qd++)
1823     {
1824         if (len < qd->len || strncmp(buffer, qd->name, qd->len) != 0) continue;
1825         if (!qd->with_arg && len != qd->len) continue;
1826
1827         (qd->handler)(gdbctx, len - qd->len, buffer + qd->len);
1828         return packet_done;
1829     }
1830     return packet_reply_error(gdbctx, EINVAL);
1831 }
1832
1833 static enum packet_return packet_query(struct gdb_context* gdbctx)
1834 {
1835     switch (gdbctx->in_packet[0])
1836     {
1837     case 'f':
1838         if (strncmp(gdbctx->in_packet + 1, "ThreadInfo", gdbctx->in_packet_len - 1) == 0)
1839         {
1840             struct dbg_thread*  thd;
1841
1842             packet_reply_open(gdbctx);
1843             packet_reply_add(gdbctx, "m", 1);
1844             LIST_FOR_EACH_ENTRY(thd, &gdbctx->process->threads, struct dbg_thread, entry)
1845             {
1846                 packet_reply_val(gdbctx, thd->tid, 4);
1847                 if (list_next(&gdbctx->process->threads, &thd->entry) != NULL)
1848                     packet_reply_add(gdbctx, ",", 1);
1849             }
1850             packet_reply_close(gdbctx);
1851             return packet_done;
1852         }
1853         else if (strncmp(gdbctx->in_packet + 1, "ProcessInfo", gdbctx->in_packet_len - 1) == 0)
1854         {
1855             char        result[128];
1856
1857             packet_reply_open(gdbctx);
1858             packet_reply_catc(gdbctx, 'O');
1859             get_process_info(gdbctx, result, sizeof(result));
1860             packet_reply_hex_to_str(gdbctx, result);
1861             packet_reply_close(gdbctx);
1862             return packet_done;
1863         }
1864         break;
1865     case 's':
1866         if (strncmp(gdbctx->in_packet + 1, "ThreadInfo", gdbctx->in_packet_len - 1) == 0)
1867         {
1868             packet_reply(gdbctx, "l", 1);
1869             return packet_done;
1870         }
1871         else if (strncmp(gdbctx->in_packet + 1, "ProcessInfo", gdbctx->in_packet_len - 1) == 0)
1872         {
1873             packet_reply(gdbctx, "l", 1);
1874             return packet_done;
1875         }
1876         break;
1877     case 'A':
1878         if (strncmp(gdbctx->in_packet, "Attached", gdbctx->in_packet_len) == 0)
1879         {
1880             char    buf[2];
1881
1882             buf[0] = '1';
1883             buf[1] = 0;
1884             return packet_reply(gdbctx, buf, -1);
1885         }
1886         break;
1887     case 'C':
1888         if (gdbctx->in_packet_len == 1)
1889         {
1890             struct dbg_thread*  thd;
1891             /* FIXME: doc says 16 bit val ??? */
1892             /* grab first created thread, aka last in list */
1893             assert(gdbctx->process && !list_empty(&gdbctx->process->threads));
1894             thd = LIST_ENTRY(list_tail(&gdbctx->process->threads), struct dbg_thread, entry);
1895             packet_reply_open(gdbctx);
1896             packet_reply_add(gdbctx, "QC", 2);
1897             packet_reply_val(gdbctx, thd->tid, 4);
1898             packet_reply_close(gdbctx);
1899             return packet_done;
1900         }
1901         break;
1902     case 'O':
1903         if (strncmp(gdbctx->in_packet, "Offsets", gdbctx->in_packet_len) == 0)
1904         {
1905             char    buf[64];
1906
1907             snprintf(buf, sizeof(buf),
1908                      "Text=%08lx;Data=%08lx;Bss=%08lx",
1909                      gdbctx->wine_segs[0], gdbctx->wine_segs[1],
1910                      gdbctx->wine_segs[2]);
1911             return packet_reply(gdbctx, buf, -1);
1912         }
1913         break;
1914     case 'R':
1915         if (gdbctx->in_packet_len > 5 && strncmp(gdbctx->in_packet, "Rcmd,", 5) == 0)
1916         {
1917             return packet_query_remote_command(gdbctx, gdbctx->in_packet + 5,
1918                                                gdbctx->in_packet_len - 5);
1919         }
1920         break;
1921     case 'S':
1922         if (strncmp(gdbctx->in_packet, "Symbol::", gdbctx->in_packet_len) == 0)
1923             return packet_ok;
1924         if (strncmp(gdbctx->in_packet, "Supported", 9) == 0)
1925         {
1926             if (strlen(target_xml))
1927                 return packet_reply(gdbctx, "PacketSize=400;qXfer:features:read+", -1);
1928             else
1929             {
1930                 /* no features supported */
1931                 packet_reply_open(gdbctx);
1932                 packet_reply_close(gdbctx);
1933                 return packet_done;
1934             }
1935         }
1936         break;
1937     case 'T':
1938         if (gdbctx->in_packet_len > 15 &&
1939             strncmp(gdbctx->in_packet, "ThreadExtraInfo", 15) == 0 &&
1940             gdbctx->in_packet[15] == ',')
1941         {
1942             unsigned    tid;
1943             char*       end;
1944             char        result[128];
1945
1946             tid = strtol(gdbctx->in_packet + 16, &end, 16);
1947             if (end == NULL) break;
1948             get_thread_info(gdbctx, tid, result, sizeof(result));
1949             packet_reply_open(gdbctx);
1950             packet_reply_hex_to_str(gdbctx, result);
1951             packet_reply_close(gdbctx);
1952             return packet_done;
1953         }
1954         if (strncmp(gdbctx->in_packet, "TStatus", 7) == 0)
1955         {
1956             /* Tracepoints not supported */
1957             packet_reply_open(gdbctx);
1958             packet_reply_close(gdbctx);
1959             return packet_done;
1960         }
1961         break;
1962     case 'X':
1963         if (strlen(target_xml) && strncmp(gdbctx->in_packet, "Xfer:features:read:target.xml", 29) == 0)
1964             return packet_reply(gdbctx, target_xml, -1);
1965         break;
1966     }
1967     if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1968         fprintf(stderr, "Unknown or malformed query %*.*s\n",
1969                 gdbctx->in_packet_len, gdbctx->in_packet_len, gdbctx->in_packet);
1970     return packet_error;
1971 }
1972
1973 static enum packet_return packet_step(struct gdb_context* gdbctx)
1974 {
1975     /* FIXME: add support for address in packet */
1976     assert(gdbctx->in_packet_len == 0);
1977     if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
1978         if (gdbctx->trace & GDBPXY_TRC_COMMAND_FIXME)
1979             fprintf(stderr, "NIY: step on %04x, while last thread is %04x\n",
1980                     gdbctx->exec_thread->tid, dbg_curr_thread->tid);
1981     be_cpu->single_step(&gdbctx->context, TRUE);
1982     resume_debuggee(gdbctx, DBG_CONTINUE);
1983     wait_for_debuggee(gdbctx);
1984     be_cpu->single_step(&gdbctx->context, FALSE);
1985     return packet_reply_status(gdbctx);
1986 }
1987
1988 #if 0
1989 static enum packet_return packet_step_signal(struct gdb_context* gdbctx)
1990 {
1991     unsigned char sig;
1992
1993     /* FIXME: add support for address in packet */
1994     assert(gdbctx->in_packet_len == 2);
1995     if (dbg_curr_thread->tid != gdbctx->exec_thread && gdbctx->exec_thread)
1996         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1997             fprintf(stderr, "NIY: step/sig on %u, while last thread is %u\n",
1998                     gdbctx->exec_thread, DEBUG_CurrThread->tid);
1999     hex_from(&sig, gdbctx->in_packet, 1);
2000     /* cannot change signals on the fly */
2001     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
2002         fprintf(stderr, "sigs: %u %u\n", sig, gdbctx->last_sig);
2003     if (sig != gdbctx->last_sig)
2004         return packet_error;
2005     resume_debuggee(gdbctx, DBG_EXCEPTION_NOT_HANDLED);
2006     wait_for_debuggee(gdbctx);
2007     return packet_reply_status(gdbctx);
2008 }
2009 #endif
2010
2011 static enum packet_return packet_thread_alive(struct gdb_context* gdbctx)
2012 {
2013     char*       end;
2014     unsigned    tid;
2015
2016     tid = strtol(gdbctx->in_packet, &end, 16);
2017     if (tid == -1 || tid == 0)
2018         return packet_reply_error(gdbctx, EINVAL);
2019     if (dbg_get_thread(gdbctx->process, tid) != NULL)
2020         return packet_ok;
2021     return packet_reply_error(gdbctx, ESRCH);
2022 }
2023
2024 static enum packet_return packet_remove_breakpoint(struct gdb_context* gdbctx)
2025 {
2026     void*                       addr;
2027     unsigned                    len;
2028     struct gdb_ctx_Xpoint*      xpt;
2029     enum be_xpoint_type         t;
2030
2031     /* FIXME: check packet_len */
2032     if (gdbctx->in_packet[0] < '0' || gdbctx->in_packet[0] > '4' ||
2033         gdbctx->in_packet[1] != ',' ||
2034         sscanf(gdbctx->in_packet + 2, "%p,%x", &addr, &len) != 2)
2035         return packet_error;
2036     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
2037         fprintf(stderr, "Remove bp %p[%u] typ=%c\n",
2038                 addr, len, gdbctx->in_packet[0]);
2039     switch (gdbctx->in_packet[0])
2040     {
2041     case '0': t = be_xpoint_break; len = 0; break;
2042     case '1': t = be_xpoint_watch_exec; break;
2043     case '2': t = be_xpoint_watch_read; break;
2044     case '3': t = be_xpoint_watch_write; break;
2045     default: return packet_error;
2046     }
2047     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
2048     {
2049         if (xpt->addr == addr && xpt->type == t)
2050         {
2051             if (be_cpu->remove_Xpoint(gdbctx->process->handle,
2052                                       gdbctx->process->process_io, &gdbctx->context,
2053                                       t, xpt->addr, xpt->val, len))
2054             {
2055                 xpt->type = -1;
2056                 return packet_ok;
2057             }
2058             break;
2059         }
2060     }
2061     return packet_error;
2062 }
2063
2064 static enum packet_return packet_set_breakpoint(struct gdb_context* gdbctx)
2065 {
2066     void*                       addr;
2067     unsigned                    len;
2068     struct gdb_ctx_Xpoint*      xpt;
2069     enum be_xpoint_type         t;
2070
2071     /* FIXME: check packet_len */
2072     if (gdbctx->in_packet[0] < '0' || gdbctx->in_packet[0] > '4' ||
2073         gdbctx->in_packet[1] != ',' ||
2074         sscanf(gdbctx->in_packet + 2, "%p,%x", &addr, &len) != 2)
2075         return packet_error;
2076     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
2077         fprintf(stderr, "Set bp %p[%u] typ=%c\n",
2078                 addr, len, gdbctx->in_packet[0]);
2079     switch (gdbctx->in_packet[0])
2080     {
2081     case '0': t = be_xpoint_break; len = 0; break;
2082     case '1': t = be_xpoint_watch_exec; break;
2083     case '2': t = be_xpoint_watch_read; break;
2084     case '3': t = be_xpoint_watch_write; break;
2085     default: return packet_error;
2086     }
2087     /* because of packet command handling, this should be made idempotent */
2088     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
2089     {
2090         if (xpt->addr == addr && xpt->type == t)
2091             return packet_ok; /* nothing to do */
2092     }
2093     /* really set the Xpoint */
2094     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
2095     {
2096         if (xpt->type == -1)
2097         {
2098             if (be_cpu->insert_Xpoint(gdbctx->process->handle,
2099                                       gdbctx->process->process_io, &gdbctx->context, 
2100                                       t, addr, &xpt->val, len))
2101             {
2102                 xpt->addr = addr;
2103                 xpt->type = t;
2104                 return packet_ok;
2105             }
2106             fprintf(stderr, "cannot set xpoint\n");
2107             break;
2108         }
2109     }
2110     /* no more entries... eech */
2111     fprintf(stderr, "Running out of spots for {break|watch}points\n");
2112     return packet_error;
2113 }
2114
2115 /* =============================================== *
2116  *    P A C K E T  I N F R A S T R U C T U R E     *
2117  * =============================================== *
2118  */
2119
2120 struct packet_entry
2121 {
2122     char                key;
2123     enum packet_return  (*handler)(struct gdb_context* gdbctx);
2124 };
2125
2126 static struct packet_entry packet_entries[] =
2127 {
2128         /*{'!', packet_extended}, */
2129         {'?', packet_last_signal},
2130         {'c', packet_continue},
2131         {'C', packet_continue_signal},
2132         {'D', packet_detach},
2133         {'g', packet_read_registers},
2134         {'G', packet_write_registers},
2135         {'k', packet_kill},
2136         {'H', packet_thread},
2137         {'m', packet_read_memory},
2138         {'M', packet_write_memory},
2139         {'p', packet_read_register},
2140         {'P', packet_write_register},
2141         {'q', packet_query},
2142         /* {'Q', packet_set}, */
2143         /* {'R', packet,restart}, only in extended mode ! */
2144         {'s', packet_step},        
2145         /*{'S', packet_step_signal}, hard(er) to implement */
2146         {'T', packet_thread_alive},
2147         {'v', packet_verbose},
2148         {'z', packet_remove_breakpoint},
2149         {'Z', packet_set_breakpoint},
2150 };
2151
2152 static BOOL extract_packets(struct gdb_context* gdbctx)
2153 {
2154     char*               end;
2155     int                 plen;
2156     unsigned char       in_cksum, loc_cksum;
2157     char*               ptr;
2158     enum packet_return  ret = packet_error;
2159     int                 num_packet = 0;
2160
2161     while ((ret & packet_last_f) == 0)
2162     {
2163         if (gdbctx->in_len && (gdbctx->trace & GDBPXY_TRC_LOWLEVEL))
2164             fprintf(stderr, "In-buf: %*.*s\n",
2165                     gdbctx->in_len, gdbctx->in_len, gdbctx->in_buf);
2166         ptr = memchr(gdbctx->in_buf, '$', gdbctx->in_len);
2167         if (ptr == NULL) return FALSE;
2168         if (ptr != gdbctx->in_buf)
2169         {
2170             int glen = ptr - gdbctx->in_buf; /* garbage len */
2171             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2172                 fprintf(stderr, "Removing garbage: %*.*s\n",
2173                         glen, glen, gdbctx->in_buf);
2174             gdbctx->in_len -= glen;
2175             memmove(gdbctx->in_buf, ptr, gdbctx->in_len);
2176         }
2177         end = memchr(gdbctx->in_buf + 1, '#', gdbctx->in_len);
2178         if (end == NULL) return FALSE;
2179         /* no checksum yet */
2180         if (end + 3 > gdbctx->in_buf + gdbctx->in_len) return FALSE;
2181         plen = end - gdbctx->in_buf - 1;
2182         hex_from(&in_cksum, end + 1, 1);
2183         loc_cksum = checksum(gdbctx->in_buf + 1, plen);
2184         if (loc_cksum == in_cksum)
2185         {
2186             if (num_packet == 0) {
2187                 int                 i;
2188                 
2189                 ret = packet_error;
2190                 
2191                 write(gdbctx->sock, "+", 1);
2192                 assert(plen);
2193                 
2194                 /* FIXME: should use bsearch if packet_entries was sorted */
2195                 for (i = 0; i < sizeof(packet_entries)/sizeof(packet_entries[0]); i++)
2196                 {
2197                     if (packet_entries[i].key == gdbctx->in_buf[1]) break;
2198                 }
2199                 if (i == sizeof(packet_entries)/sizeof(packet_entries[0]))
2200                 {
2201                     if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
2202                         fprintf(stderr, "Unknown packet request %*.*s\n",
2203                                 plen, plen, &gdbctx->in_buf[1]);
2204                 }
2205                 else
2206                 {
2207                     gdbctx->in_packet = gdbctx->in_buf + 2;
2208                     gdbctx->in_packet_len = plen - 1;
2209                     if (gdbctx->trace & GDBPXY_TRC_PACKET)
2210                         fprintf(stderr, "Packet: %c%*.*s\n",
2211                                 gdbctx->in_buf[1],
2212                                 gdbctx->in_packet_len, gdbctx->in_packet_len,
2213                                 gdbctx->in_packet);
2214                     ret = (packet_entries[i].handler)(gdbctx);
2215                 }
2216                 switch (ret & ~packet_last_f)
2217                 {
2218                 case packet_error:  packet_reply(gdbctx, "", 0); break;
2219                 case packet_ok:     packet_reply(gdbctx, "OK", 2); break;
2220                 case packet_done:   break;
2221                 }
2222                 if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2223                     fprintf(stderr, "Reply-full: %*.*s\n",
2224                             gdbctx->out_len, gdbctx->out_len, gdbctx->out_buf);
2225                 i = write(gdbctx->sock, gdbctx->out_buf, gdbctx->out_len);
2226                 assert(i == gdbctx->out_len);
2227                 /* if this fails, we'll have to use POLLOUT...
2228                  */
2229                 gdbctx->out_len = 0;
2230                 num_packet++;
2231             }
2232             else 
2233             {
2234                 /* FIXME: If we have more than one packet in our input buffer,
2235                  * it's very likely that we took too long to answer to a given packet
2236                  * and gdb is sending us the same packet again.
2237                  * So we simply drop the second packet. This will lower the risk of error,
2238                  * but there's still some race conditions here.
2239                  * A better fix (yet not perfect) would be to have two threads:
2240                  * - one managing the packets for gdb
2241                  * - the second one managing the commands...
2242                  * This would allow us to send the reply with the '+' character (Ack of
2243                  * the command) way sooner than we do now.
2244                  */
2245                 if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2246                     fprintf(stderr, "Dropping packet, I was too slow to respond\n");
2247             }
2248         }
2249         else
2250         {
2251             write(gdbctx->sock, "+", 1);
2252             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2253                 fprintf(stderr, "Dropping packet, invalid checksum %d <> %d\n", in_cksum, loc_cksum);
2254         }
2255         gdbctx->in_len -= plen + 4;
2256         memmove(gdbctx->in_buf, end + 3, gdbctx->in_len);
2257     }
2258     return TRUE;
2259 }
2260
2261 static int fetch_data(struct gdb_context* gdbctx)
2262 {
2263     int len, in_len = gdbctx->in_len;
2264
2265     assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
2266     for (;;)
2267     {
2268 #define STEP 128
2269         if (gdbctx->in_len + STEP > gdbctx->in_buf_alloc)
2270             gdbctx->in_buf = packet_realloc(gdbctx->in_buf, gdbctx->in_buf_alloc += STEP);
2271 #undef STEP
2272         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2273             fprintf(stderr, "%d %d %*.*s\n",
2274                     gdbctx->in_len, gdbctx->in_buf_alloc,
2275                     gdbctx->in_len, gdbctx->in_len, gdbctx->in_buf);
2276         len = read(gdbctx->sock, gdbctx->in_buf + gdbctx->in_len, gdbctx->in_buf_alloc - gdbctx->in_len);
2277         if (len <= 0) break;
2278         gdbctx->in_len += len;
2279         assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
2280         if (len < gdbctx->in_buf_alloc - gdbctx->in_len) break;
2281     }
2282     if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2283         fprintf(stderr, "=> %d\n", gdbctx->in_len - in_len);
2284     return gdbctx->in_len - in_len;
2285 }
2286
2287 #define FLAG_NO_START   1
2288 #define FLAG_WITH_XTERM 2
2289
2290 static BOOL gdb_exec(const char* wine_path, unsigned port, unsigned flags)
2291 {
2292     char            buf[MAX_PATH];
2293     int             fd;
2294     const char*     gdb_path;
2295     FILE*           f;
2296
2297     if (!(gdb_path = getenv("WINE_GDB"))) gdb_path = "gdb";
2298     strcpy(buf,"/tmp/winegdb.XXXXXX");
2299     fd = mkstemps(buf, 0);
2300     if (fd == -1) return FALSE;
2301     if ((f = fdopen(fd, "w+")) == NULL) return FALSE;
2302     fprintf(f, "file %s\n", wine_path);
2303     fprintf(f, "target remote localhost:%d\n", ntohs(port));
2304     fprintf(f, "monitor trace=%d\n", GDBPXY_TRC_COMMAND_FIXME);
2305     fprintf(f, "set prompt Wine-gdb>\\ \n");
2306     /* gdb 5.1 seems to require it, won't hurt anyway */
2307     fprintf(f, "sharedlibrary\n");
2308     /* This is needed (but not a decent & final fix)
2309      * Without this, gdb would skip our inter-DLL relay code (because
2310      * we don't have any line number information for the relay code)
2311      * With this, we will stop on first instruction of the stub, and
2312      * reusing step, will get us through the relay stub at the actual
2313      * function we're looking at.
2314      */
2315     fprintf(f, "set step-mode on\n");
2316     /* tell gdb to delete this file when done handling it... */
2317     fprintf(f, "shell rm -f \"%s\"\n", buf);
2318     fclose(f);
2319     if (flags & FLAG_WITH_XTERM)
2320         execlp("xterm", "xterm", "-e", gdb_path, "-x", buf, NULL);
2321     else
2322         execlp(gdb_path, gdb_path, "-x", buf, NULL);
2323     assert(0); /* never reached */
2324     return TRUE;
2325 }
2326
2327 static BOOL gdb_startup(struct gdb_context* gdbctx, DEBUG_EVENT* de, unsigned flags)
2328 {
2329     int                 sock;
2330     struct sockaddr_in  s_addrs;
2331     socklen_t           s_len = sizeof(s_addrs);
2332     struct pollfd       pollfd;
2333     IMAGEHLP_MODULE64   imh_mod;
2334     BOOL                ret = FALSE;
2335
2336     /* step 1: create socket for gdb connection request */
2337     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
2338     {
2339         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2340             fprintf(stderr, "Can't create socket");
2341         return FALSE;
2342     }
2343
2344     if (listen(sock, 1) == -1 || getsockname(sock, (struct sockaddr*)&s_addrs, &s_len) == -1)
2345         goto cleanup;
2346
2347     /* step 2: do the process internal creation */
2348     handle_debug_event(gdbctx, de);
2349
2350     /* step3: get the wine loader name */
2351     if (!dbg_get_debuggee_info(gdbctx->process->handle, &imh_mod))
2352         goto cleanup;
2353
2354     /* step 4: fire up gdb (if requested) */
2355     if (flags & FLAG_NO_START)
2356         fprintf(stderr, "target remote localhost:%d\n", ntohs(s_addrs.sin_port));
2357     else
2358         switch (fork())
2359         {
2360         case -1: /* error in parent... */
2361             fprintf(stderr, "Cannot create gdb\n");
2362             goto cleanup;
2363         default: /* in parent... success */
2364             signal(SIGINT, SIG_IGN);
2365             break;
2366         case 0: /* in child... and alive */
2367             gdb_exec(imh_mod.LoadedImageName, s_addrs.sin_port, flags);
2368             /* if we're here, exec failed, so report failure */
2369             goto cleanup;
2370         }
2371
2372     /* step 5: wait for gdb to connect actually */
2373     pollfd.fd = sock;
2374     pollfd.events = POLLIN;
2375     pollfd.revents = 0;
2376
2377     switch (poll(&pollfd, 1, -1))
2378     {
2379     case 1:
2380         if (pollfd.revents & POLLIN)
2381         {
2382             int dummy = 1;
2383             gdbctx->sock = accept(sock, (struct sockaddr*)&s_addrs, &s_len);
2384             if (gdbctx->sock == -1)
2385                 break;
2386             ret = TRUE;
2387             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2388                 fprintf(stderr, "Connected on %d\n", gdbctx->sock);
2389             /* don't keep our small packets too long: send them ASAP back to GDB
2390              * without this, GDB really crawls
2391              */
2392             setsockopt(gdbctx->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&dummy, sizeof(dummy));
2393         }
2394         break;
2395     case 0:
2396         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2397             fprintf(stderr, "Poll for cnx failed (timeout)\n");
2398         break;
2399     case -1:
2400         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2401             fprintf(stderr, "Poll for cnx failed (error)\n");
2402         break;
2403     default:
2404         assert(0);
2405     }
2406
2407 cleanup:
2408     close(sock);
2409     return ret;
2410 }
2411
2412 static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags)
2413 {
2414     DEBUG_EVENT         de;
2415     int                 i;
2416
2417     gdbctx->sock = -1;
2418     gdbctx->in_buf = NULL;
2419     gdbctx->in_buf_alloc = 0;
2420     gdbctx->in_len = 0;
2421     gdbctx->out_buf = NULL;
2422     gdbctx->out_buf_alloc = 0;
2423     gdbctx->out_len = 0;
2424     gdbctx->out_curr_packet = -1;
2425
2426     gdbctx->exec_thread = gdbctx->other_thread = NULL;
2427     gdbctx->last_sig = 0;
2428     gdbctx->in_trap = FALSE;
2429     gdbctx->trace = /*GDBPXY_TRC_PACKET | GDBPXY_TRC_COMMAND |*/ GDBPXY_TRC_COMMAND_ERROR | GDBPXY_TRC_COMMAND_FIXME | GDBPXY_TRC_WIN32_EVENT;
2430     gdbctx->process = NULL;
2431     for (i = 0; i < NUM_XPOINT; i++)
2432         gdbctx->Xpoints[i].type = -1;
2433     for (i = 0; i < sizeof(gdbctx->wine_segs) / sizeof(gdbctx->wine_segs[0]); i++)
2434         gdbctx->wine_segs[i] = 0;
2435
2436     /* wait for first trap */
2437     while (WaitForDebugEvent(&de, INFINITE))
2438     {
2439         if (de.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT)
2440         {
2441             /* this should be the first event we get,
2442              * and the only one of this type  */
2443             assert(gdbctx->process == NULL && de.dwProcessId == dbg_curr_pid);
2444             /* gdbctx->dwProcessId = pid; */
2445             if (!gdb_startup(gdbctx, &de, flags)) return FALSE;
2446             assert(!gdbctx->in_trap);
2447         }
2448         else
2449         {
2450             handle_debug_event(gdbctx, &de);
2451             if (gdbctx->in_trap) break;
2452         }
2453         ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
2454     }
2455     return TRUE;
2456 }
2457
2458 static int gdb_remote(unsigned flags)
2459 {
2460     struct pollfd       pollfd;
2461     struct gdb_context  gdbctx;
2462     BOOL                doLoop;
2463
2464     for (doLoop = gdb_init_context(&gdbctx, flags); doLoop;)
2465     {
2466         pollfd.fd = gdbctx.sock;
2467         pollfd.events = POLLIN;
2468         pollfd.revents = 0;
2469
2470         switch (poll(&pollfd, 1, -1))
2471         {
2472         case 1:
2473             /* got something */
2474             if (pollfd.revents & (POLLHUP | POLLERR))
2475             {
2476                 if (gdbctx.trace & GDBPXY_TRC_LOWLEVEL)
2477                     fprintf(stderr, "Gdb hung up\n");
2478                 /* kill also debuggee process - questionnable - */
2479                 detach_debuggee(&gdbctx, TRUE);
2480                 doLoop = FALSE;
2481                 break;
2482             }
2483             if ((pollfd.revents & POLLIN) && fetch_data(&gdbctx) > 0)
2484             {
2485                 if (extract_packets(&gdbctx)) doLoop = FALSE;
2486             }
2487             break;
2488         case 0:
2489             /* timeout, should never happen (infinite timeout) */
2490             break;
2491         case -1:
2492             if (gdbctx.trace & GDBPXY_TRC_LOWLEVEL)
2493                 fprintf(stderr, "Poll failed\n");
2494             doLoop = FALSE;
2495             break;
2496         }
2497     }
2498     wait(NULL);
2499     return 0;
2500 }
2501 #endif
2502
2503 int gdb_main(int argc, char* argv[])
2504 {
2505 #ifdef HAVE_POLL
2506     unsigned gdb_flags = 0;
2507
2508     argc--; argv++;
2509     while (argc > 0 && argv[0][0] == '-')
2510     {
2511         if (strcmp(argv[0], "--no-start") == 0)
2512         {
2513             gdb_flags |= FLAG_NO_START;
2514             argc--; argv++;
2515             continue;
2516         }
2517         if (strcmp(argv[0], "--with-xterm") == 0)
2518         {
2519             gdb_flags |= FLAG_WITH_XTERM;
2520             argc--; argv++;
2521             continue;
2522         }
2523         return -1;
2524     }
2525     if (dbg_active_attach(argc, argv) == start_ok ||
2526         dbg_active_launch(argc, argv) == start_ok)
2527         return gdb_remote(gdb_flags);
2528 #else
2529     fprintf(stderr, "GdbProxy mode not supported on this platform\n");
2530 #endif
2531     return -1;
2532 }