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