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