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