winedbg: Italian translation update.
[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/Maintenance-Commands.html
25  */
26
27 #include "config.h"
28 #include "wine/port.h"
29
30 #include <assert.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #ifdef HAVE_SYS_POLL_H
38 # include <sys/poll.h>
39 #endif
40 #ifdef HAVE_SYS_WAIT_H
41 # include <sys/wait.h>
42 #endif
43 #ifdef HAVE_SYS_SOCKET_H
44 # include <sys/socket.h>
45 #endif
46 #ifdef HAVE_NETINET_IN_H
47 # include <netinet/in.h>
48 #endif
49 #ifdef HAVE_NETINET_TCP_H
50 # include <netinet/tcp.h>
51 #endif
52 #ifdef HAVE_UNISTD_H
53 # include <unistd.h>
54 #endif
55
56 /* if we don't have poll support on this system
57  * we won't provide gdb proxy support here...
58  */
59 #ifdef HAVE_POLL
60
61 #include "debugger.h"
62
63 #include "windef.h"
64 #include "winbase.h"
65 #include "tlhelp32.h"
66
67 #define GDBPXY_TRC_LOWLEVEL             0x01
68 #define GDBPXY_TRC_PACKET               0x02
69 #define GDBPXY_TRC_COMMAND              0x04
70 #define GDBPXY_TRC_COMMAND_ERROR        0x08
71 #define GDBPXY_TRC_WIN32_EVENT          0x10
72 #define GDBPXY_TRC_WIN32_ERROR          0x20
73 #define GDBPXY_TRC_COMMAND_FIXME        0x80
74
75 struct gdb_ctx_Xpoint
76 {
77     enum be_xpoint_type         type;   /* -1 means free */
78     void*                       addr;
79     unsigned long               val;
80 };
81
82 struct gdb_context
83 {
84     /* gdb information */
85     int                         sock;
86     /* incoming buffer */
87     char*                       in_buf;
88     int                         in_buf_alloc;
89     int                         in_len;
90     /* split into individual packet */
91     char*                       in_packet;
92     int                         in_packet_len;
93     /* outgoing buffer */
94     char*                       out_buf;
95     int                         out_buf_alloc;
96     int                         out_len;
97     int                         out_curr_packet;
98     /* generic GDB thread information */
99     struct dbg_thread*          exec_thread;    /* thread used in step & continue */
100     struct dbg_thread*          other_thread;   /* thread to be used in any other operation */
101     unsigned                    trace;
102     /* current Win32 trap env */
103     unsigned                    last_sig;
104     BOOL                        in_trap;
105     CONTEXT                     context;
106     /* Win32 information */
107     struct dbg_process*         process;
108 #define NUM_XPOINT      32
109     struct gdb_ctx_Xpoint       Xpoints[NUM_XPOINT];
110     /* Unix environment */
111     unsigned long               wine_segs[3];   /* load addresses of the ELF wine exec segments (text, bss and data) */
112 };
113
114 static BOOL tgt_process_gdbproxy_read(HANDLE hProcess, const void* addr,
115                                       void* buffer, SIZE_T len, SIZE_T* rlen)
116 {
117     return ReadProcessMemory( hProcess, addr, buffer, len, rlen );
118 }
119
120 static BOOL tgt_process_gdbproxy_write(HANDLE hProcess, void* addr,
121                                        const void* buffer, SIZE_T len, SIZE_T* wlen)
122 {
123     return WriteProcessMemory( hProcess, addr, buffer, len, wlen );
124 }
125
126 static struct be_process_io be_process_gdbproxy_io =
127 {
128     NULL, /* we shouldn't use close_process() in gdbproxy */
129     tgt_process_gdbproxy_read,
130     tgt_process_gdbproxy_write
131 };
132
133 /* =============================================== *
134  *       B A S I C   M A N I P U L A T I O N S     *
135  * =============================================== *
136  */
137
138 static inline int hex_from0(char ch)
139 {
140     if (ch >= '0' && ch <= '9') return ch - '0';
141     if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
142     if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
143
144     assert(0);
145     return 0;
146 }
147
148 static inline unsigned char hex_to0(int x)
149 {
150     assert(x >= 0 && x < 16);
151     return "0123456789abcdef"[x];
152 }
153
154 static int hex_to_int(const char* src, size_t len)
155 {
156     unsigned int returnval = 0;
157     while (len--)
158     {
159         returnval <<= 4;
160         returnval |= hex_from0(*src++);
161     }
162     return returnval;
163 }
164
165 static void hex_from(void* dst, const char* src, size_t len)
166 {
167     unsigned char *p = dst;
168     while (len--)
169     {
170         *p++ = (hex_from0(src[0]) << 4) | hex_from0(src[1]);
171         src += 2;
172     }
173 }
174
175 static void hex_to(char* dst, const void* src, size_t len)
176 {
177     const unsigned char *p = src;
178     while (len--)
179     {
180         *dst++ = hex_to0(*p >> 4);
181         *dst++ = hex_to0(*p & 0x0F);
182         p++;
183     }
184 }
185
186 static unsigned char checksum(const char* ptr, int len)
187 {
188     unsigned cksum = 0;
189
190     while (len-- > 0)
191         cksum += (unsigned char)*ptr++;
192     return cksum;
193 }
194
195 /* =============================================== *
196  *              C P U   H A N D L E R S            *
197  * =============================================== *
198  */
199
200 #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     LIST_FOR_EACH_ENTRY(thd, &gdbctx->process->threads, struct dbg_thread, entry)
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 %0*lx %.14s\n",
1514                 indent, "", (ULONG_PTR)hWnd, 13 - indent, "",
1515                 clsName, GetWindowLongW(hWnd, GWL_STYLE),
1516                 ADDRWIDTH, (ULONG_PTR)GetWindowLongPtrW(hWnd, GWLP_WNDPROC),
1517                 wndName);
1518        packet_reply_hex_to_str(gdbctx, buffer);
1519        packet_reply_close(gdbctx);
1520
1521        if ((child = GetWindow(hWnd, GW_CHILD)) != 0)
1522           packet_query_monitor_wnd_helper(gdbctx, child, indent + 1);
1523     } while ((hWnd = GetWindow(hWnd, GW_HWNDNEXT)) != 0);
1524 }
1525
1526 static void packet_query_monitor_wnd(struct gdb_context* gdbctx, int len, const char* str)
1527 {
1528     char        buffer[128];
1529
1530     /* we do the output in several 'O' packets, with the last one being just OK for
1531      * marking the end of the output */
1532     packet_reply_open(gdbctx);
1533     packet_reply_catc(gdbctx, 'O');
1534     snprintf(buffer, sizeof(buffer),
1535              "%-16.16s %-17.17s %-8.8s %s\n",
1536              "hwnd", "Class Name", " Style", " WndProc Text");
1537     packet_reply_hex_to_str(gdbctx, buffer);
1538     packet_reply_close(gdbctx);
1539
1540     /* FIXME: could also add a pmt to this command in str... */
1541     packet_query_monitor_wnd_helper(gdbctx, GetDesktopWindow(), 0);
1542     packet_reply(gdbctx, "OK", 2);
1543 }
1544
1545 static void packet_query_monitor_process(struct gdb_context* gdbctx, int len, const char* str)
1546 {
1547     HANDLE              snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
1548     char                buffer[128];
1549     char                deco;
1550     PROCESSENTRY32      entry;
1551     BOOL                ok;
1552
1553     if (snap == INVALID_HANDLE_VALUE)
1554         return;
1555
1556     entry.dwSize = sizeof(entry);
1557     ok = Process32First(snap, &entry);
1558
1559     /* we do the output in several 'O' packets, with the last one being just OK for
1560      * marking the end of the output */
1561
1562     packet_reply_open(gdbctx);
1563     packet_reply_catc(gdbctx, 'O');
1564     snprintf(buffer, sizeof(buffer),
1565              " %-8.8s %-8.8s %-8.8s %s\n",
1566              "pid", "threads", "parent", "executable");
1567     packet_reply_hex_to_str(gdbctx, buffer);
1568     packet_reply_close(gdbctx);
1569
1570     while (ok)
1571     {
1572         deco = ' ';
1573         if (entry.th32ProcessID == gdbctx->process->pid) deco = '>';
1574         packet_reply_open(gdbctx);
1575         packet_reply_catc(gdbctx, 'O');
1576         snprintf(buffer, sizeof(buffer),
1577                  "%c%08x %-8d %08x '%s'\n",
1578                  deco, entry.th32ProcessID, entry.cntThreads,
1579                  entry.th32ParentProcessID, entry.szExeFile);
1580         packet_reply_hex_to_str(gdbctx, buffer);
1581         packet_reply_close(gdbctx);
1582         ok = Process32Next(snap, &entry);
1583     }
1584     CloseHandle(snap);
1585     packet_reply(gdbctx, "OK", 2);
1586 }
1587
1588 static void packet_query_monitor_mem(struct gdb_context* gdbctx, int len, const char* str)
1589 {
1590     MEMORY_BASIC_INFORMATION    mbi;
1591     char*                       addr = 0;
1592     const char*                 state;
1593     const char*                 type;
1594     char                        prot[3+1];
1595     char                        buffer[128];
1596
1597     /* we do the output in several 'O' packets, with the last one being just OK for
1598      * marking the end of the output */
1599     packet_reply_open(gdbctx);
1600     packet_reply_catc(gdbctx, 'O');
1601     packet_reply_hex_to_str(gdbctx, "Address  Size     State   Type    RWX\n");
1602     packet_reply_close(gdbctx);
1603
1604     while (VirtualQueryEx(gdbctx->process->handle, addr, &mbi, sizeof(mbi)) >= sizeof(mbi))
1605     {
1606         switch (mbi.State)
1607         {
1608         case MEM_COMMIT:        state = "commit "; break;
1609         case MEM_FREE:          state = "free   "; break;
1610         case MEM_RESERVE:       state = "reserve"; break;
1611         default:                state = "???    "; break;
1612         }
1613         if (mbi.State != MEM_FREE)
1614         {
1615             switch (mbi.Type)
1616             {
1617             case MEM_IMAGE:         type = "image  "; break;
1618             case MEM_MAPPED:        type = "mapped "; break;
1619             case MEM_PRIVATE:       type = "private"; break;
1620             case 0:                 type = "       "; break;
1621             default:                type = "???    "; break;
1622             }
1623             memset(prot, ' ' , sizeof(prot)-1);
1624             prot[sizeof(prot)-1] = '\0';
1625             if (mbi.AllocationProtect & (PAGE_READONLY|PAGE_READWRITE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
1626                 prot[0] = 'R';
1627             if (mbi.AllocationProtect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE))
1628                 prot[1] = 'W';
1629             if (mbi.AllocationProtect & (PAGE_WRITECOPY|PAGE_EXECUTE_WRITECOPY))
1630                 prot[1] = 'C';
1631             if (mbi.AllocationProtect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))
1632                 prot[2] = 'X';
1633         }
1634         else
1635         {
1636             type = "";
1637             prot[0] = '\0';
1638         }
1639         packet_reply_open(gdbctx);
1640         snprintf(buffer, sizeof(buffer), "%08lx %08lx %s %s %s\n",
1641                  (DWORD_PTR)addr, mbi.RegionSize, state, type, prot);
1642         packet_reply_catc(gdbctx, 'O');
1643         packet_reply_hex_to_str(gdbctx, buffer);
1644         packet_reply_close(gdbctx);
1645
1646         if (addr + mbi.RegionSize < addr) /* wrap around ? */
1647             break;
1648         addr += mbi.RegionSize;
1649     }
1650     packet_reply(gdbctx, "OK", 2);
1651 }
1652
1653 static void packet_query_monitor_trace(struct gdb_context* gdbctx,
1654                                        int len, const char* str)
1655 {
1656     char        buffer[128];
1657
1658     if (len == 0)
1659     {
1660         snprintf(buffer, sizeof(buffer), "trace=%x\n", gdbctx->trace);
1661     }
1662     else if (len >= 2 && str[0] == '=')
1663     {
1664         unsigned val = atoi(&str[1]);
1665         snprintf(buffer, sizeof(buffer), "trace: %x => %x\n", gdbctx->trace, val);
1666         gdbctx->trace = val;
1667     }
1668     else
1669     {
1670         /* FIXME: ugly but can use error packet here */
1671         packet_reply_cat(gdbctx, "E00");
1672         return;
1673     }
1674     packet_reply_open(gdbctx);
1675     packet_reply_hex_to_str(gdbctx, buffer);
1676     packet_reply_close(gdbctx);
1677 }
1678
1679 struct query_detail
1680 {
1681     int         with_arg;
1682     const char* name;
1683     size_t      len;
1684     void        (*handler)(struct gdb_context*, int, const char*);
1685 } query_details[] =
1686 {
1687     {0, "wnd",     3, packet_query_monitor_wnd},
1688     {0, "window",  6, packet_query_monitor_wnd},
1689     {0, "proc",    4, packet_query_monitor_process},
1690     {0, "process", 7, packet_query_monitor_process},
1691     {0, "mem",     3, packet_query_monitor_mem},
1692     {1, "trace",   5, packet_query_monitor_trace},
1693     {0, NULL,      0, NULL},
1694 };
1695
1696 static enum packet_return packet_query_remote_command(struct gdb_context* gdbctx,
1697                                                       const char* hxcmd, size_t len)
1698 {
1699     char                        buffer[128];
1700     struct query_detail*        qd;
1701
1702     assert((len & 1) == 0 && len < 2 * sizeof(buffer));
1703     len /= 2;
1704     hex_from(buffer, hxcmd, len);
1705
1706     for (qd = &query_details[0]; qd->name != NULL; qd++)
1707     {
1708         if (len < qd->len || strncmp(buffer, qd->name, qd->len) != 0) continue;
1709         if (!qd->with_arg && len != qd->len) continue;
1710
1711         (qd->handler)(gdbctx, len - qd->len, buffer + qd->len);
1712         return packet_done;
1713     }
1714     return packet_reply_error(gdbctx, EINVAL);
1715 }
1716
1717 static enum packet_return packet_query(struct gdb_context* gdbctx)
1718 {
1719     switch (gdbctx->in_packet[0])
1720     {
1721     case 'f':
1722         if (strncmp(gdbctx->in_packet + 1, "ThreadInfo", gdbctx->in_packet_len - 1) == 0)
1723         {
1724             struct dbg_thread*  thd;
1725
1726             packet_reply_open(gdbctx);
1727             packet_reply_add(gdbctx, "m", 1);
1728             LIST_FOR_EACH_ENTRY(thd, &gdbctx->process->threads, struct dbg_thread, entry)
1729             {
1730                 packet_reply_val(gdbctx, thd->tid, 4);
1731                 if (list_next(&gdbctx->process->threads, &thd->entry) != NULL)
1732                     packet_reply_add(gdbctx, ",", 1);
1733             }
1734             packet_reply_close(gdbctx);
1735             return packet_done;
1736         }
1737         else if (strncmp(gdbctx->in_packet + 1, "ProcessInfo", gdbctx->in_packet_len - 1) == 0)
1738         {
1739             char        result[128];
1740
1741             packet_reply_open(gdbctx);
1742             packet_reply_catc(gdbctx, 'O');
1743             get_process_info(gdbctx, result, sizeof(result));
1744             packet_reply_hex_to_str(gdbctx, result);
1745             packet_reply_close(gdbctx);
1746             return packet_done;
1747         }
1748         break;
1749     case 's':
1750         if (strncmp(gdbctx->in_packet + 1, "ThreadInfo", gdbctx->in_packet_len - 1) == 0)
1751         {
1752             packet_reply(gdbctx, "l", 1);
1753             return packet_done;
1754         }
1755         else if (strncmp(gdbctx->in_packet + 1, "ProcessInfo", gdbctx->in_packet_len - 1) == 0)
1756         {
1757             packet_reply(gdbctx, "l", 1);
1758             return packet_done;
1759         }
1760         break;
1761     case 'C':
1762         if (gdbctx->in_packet_len == 1)
1763         {
1764             struct dbg_thread*  thd;
1765             /* FIXME: doc says 16 bit val ??? */
1766             /* grab first created thread, aka last in list */
1767             assert(gdbctx->process && !list_empty(&gdbctx->process->threads));
1768             thd = LIST_ENTRY(list_tail(&gdbctx->process->threads), struct dbg_thread, entry);
1769             packet_reply_open(gdbctx);
1770             packet_reply_add(gdbctx, "QC", 2);
1771             packet_reply_val(gdbctx, thd->tid, 4);
1772             packet_reply_close(gdbctx);
1773             return packet_done;
1774         }
1775         break;
1776     case 'O':
1777         if (strncmp(gdbctx->in_packet, "Offsets", gdbctx->in_packet_len) == 0)
1778         {
1779             char    buf[64];
1780
1781             snprintf(buf, sizeof(buf),
1782                      "Text=%08lx;Data=%08lx;Bss=%08lx",
1783                      gdbctx->wine_segs[0], gdbctx->wine_segs[1],
1784                      gdbctx->wine_segs[2]);
1785             return packet_reply(gdbctx, buf, -1);
1786         }
1787         break;
1788     case 'R':
1789         if (gdbctx->in_packet_len > 5 && strncmp(gdbctx->in_packet, "Rcmd,", 5) == 0)
1790         {
1791             return packet_query_remote_command(gdbctx, gdbctx->in_packet + 5,
1792                                                gdbctx->in_packet_len - 5);
1793         }
1794         break;
1795     case 'S':
1796         if (strncmp(gdbctx->in_packet, "Symbol::", gdbctx->in_packet_len) == 0)
1797             return packet_ok;
1798         if (strncmp(gdbctx->in_packet, "Supported", gdbctx->in_packet_len) == 0)
1799         {
1800             packet_reply_open(gdbctx);
1801             packet_reply_close(gdbctx);
1802             return packet_done;
1803         }
1804         break;
1805     case 'T':
1806         if (gdbctx->in_packet_len > 15 &&
1807             strncmp(gdbctx->in_packet, "ThreadExtraInfo", 15) == 0 &&
1808             gdbctx->in_packet[15] == ',')
1809         {
1810             unsigned    tid;
1811             char*       end;
1812             char        result[128];
1813
1814             tid = strtol(gdbctx->in_packet + 16, &end, 16);
1815             if (end == NULL) break;
1816             get_thread_info(gdbctx, tid, result, sizeof(result));
1817             packet_reply_open(gdbctx);
1818             packet_reply_hex_to_str(gdbctx, result);
1819             packet_reply_close(gdbctx);
1820             return packet_done;
1821         }
1822         break;
1823     }
1824     if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1825         fprintf(stderr, "Unknown or malformed query %*.*s\n",
1826                 gdbctx->in_packet_len, gdbctx->in_packet_len, gdbctx->in_packet);
1827     return packet_error;
1828 }
1829
1830 static enum packet_return packet_step(struct gdb_context* gdbctx)
1831 {
1832     /* FIXME: add support for address in packet */
1833     assert(gdbctx->in_packet_len == 0);
1834     if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
1835         if (gdbctx->trace & GDBPXY_TRC_COMMAND_FIXME)
1836             fprintf(stderr, "NIY: step on %04x, while last thread is %04x\n",
1837                     gdbctx->exec_thread->tid, dbg_curr_thread->tid);
1838     be_cpu->single_step(&gdbctx->context, TRUE);
1839     resume_debuggee(gdbctx, DBG_CONTINUE);
1840     wait_for_debuggee(gdbctx);
1841     be_cpu->single_step(&gdbctx->context, FALSE);
1842     return packet_reply_status(gdbctx);
1843 }
1844
1845 #if 0
1846 static enum packet_return packet_step_signal(struct gdb_context* gdbctx)
1847 {
1848     unsigned char sig;
1849
1850     /* FIXME: add support for address in packet */
1851     assert(gdbctx->in_packet_len == 2);
1852     if (dbg_curr_thread->tid != gdbctx->exec_thread && gdbctx->exec_thread)
1853         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1854             fprintf(stderr, "NIY: step/sig on %u, while last thread is %u\n",
1855                     gdbctx->exec_thread, DEBUG_CurrThread->tid);
1856     hex_from(&sig, gdbctx->in_packet, 1);
1857     /* cannot change signals on the fly */
1858     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1859         fprintf(stderr, "sigs: %u %u\n", sig, gdbctx->last_sig);
1860     if (sig != gdbctx->last_sig)
1861         return packet_error;
1862     resume_debuggee(gdbctx, DBG_EXCEPTION_NOT_HANDLED);
1863     wait_for_debuggee(gdbctx);
1864     return packet_reply_status(gdbctx);
1865 }
1866 #endif
1867
1868 static enum packet_return packet_thread_alive(struct gdb_context* gdbctx)
1869 {
1870     char*       end;
1871     unsigned    tid;
1872
1873     tid = strtol(gdbctx->in_packet, &end, 16);
1874     if (tid == -1 || tid == 0)
1875         return packet_reply_error(gdbctx, EINVAL);
1876     if (dbg_get_thread(gdbctx->process, tid) != NULL)
1877         return packet_ok;
1878     return packet_reply_error(gdbctx, ESRCH);
1879 }
1880
1881 static enum packet_return packet_remove_breakpoint(struct gdb_context* gdbctx)
1882 {
1883     void*                       addr;
1884     unsigned                    len;
1885     struct gdb_ctx_Xpoint*      xpt;
1886     enum be_xpoint_type         t;
1887
1888     /* FIXME: check packet_len */
1889     if (gdbctx->in_packet[0] < '0' || gdbctx->in_packet[0] > '4' ||
1890         gdbctx->in_packet[1] != ',' ||
1891         sscanf(gdbctx->in_packet + 2, "%p,%x", &addr, &len) != 2)
1892         return packet_error;
1893     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1894         fprintf(stderr, "Remove bp %p[%u] typ=%c\n",
1895                 addr, len, gdbctx->in_packet[0]);
1896     switch (gdbctx->in_packet[0])
1897     {
1898     case '0': t = be_xpoint_break; len = 0; break;
1899     case '1': t = be_xpoint_watch_exec; break;
1900     case '2': t = be_xpoint_watch_read; break;
1901     case '3': t = be_xpoint_watch_write; break;
1902     default: return packet_error;
1903     }
1904     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
1905     {
1906         if (xpt->addr == addr && xpt->type == t)
1907         {
1908             if (be_cpu->remove_Xpoint(gdbctx->process->handle,
1909                                       gdbctx->process->process_io, &gdbctx->context,
1910                                       t, xpt->addr, xpt->val, len))
1911             {
1912                 xpt->type = -1;
1913                 return packet_ok;
1914             }
1915             break;
1916         }
1917     }
1918     return packet_error;
1919 }
1920
1921 static enum packet_return packet_set_breakpoint(struct gdb_context* gdbctx)
1922 {
1923     void*                       addr;
1924     unsigned                    len;
1925     struct gdb_ctx_Xpoint*      xpt;
1926     enum be_xpoint_type         t;
1927
1928     /* FIXME: check packet_len */
1929     if (gdbctx->in_packet[0] < '0' || gdbctx->in_packet[0] > '4' ||
1930         gdbctx->in_packet[1] != ',' ||
1931         sscanf(gdbctx->in_packet + 2, "%p,%x", &addr, &len) != 2)
1932         return packet_error;
1933     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1934         fprintf(stderr, "Set bp %p[%u] typ=%c\n",
1935                 addr, len, gdbctx->in_packet[0]);
1936     switch (gdbctx->in_packet[0])
1937     {
1938     case '0': t = be_xpoint_break; len = 0; break;
1939     case '1': t = be_xpoint_watch_exec; break;
1940     case '2': t = be_xpoint_watch_read; break;
1941     case '3': t = be_xpoint_watch_write; break;
1942     default: return packet_error;
1943     }
1944     /* because of packet command handling, this should be made idempotent */
1945     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
1946     {
1947         if (xpt->addr == addr && xpt->type == t)
1948             return packet_ok; /* nothing to do */
1949     }
1950     /* really set the Xpoint */
1951     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
1952     {
1953         if (xpt->type == -1)
1954         {
1955             if (be_cpu->insert_Xpoint(gdbctx->process->handle,
1956                                       gdbctx->process->process_io, &gdbctx->context, 
1957                                       t, addr, &xpt->val, len))
1958             {
1959                 xpt->addr = addr;
1960                 xpt->type = t;
1961                 return packet_ok;
1962             }
1963             fprintf(stderr, "cannot set xpoint\n");
1964             break;
1965         }
1966     }
1967     /* no more entries... eech */
1968     fprintf(stderr, "Running out of spots for {break|watch}points\n");
1969     return packet_error;
1970 }
1971
1972 /* =============================================== *
1973  *    P A C K E T  I N F R A S T R U C T U R E     *
1974  * =============================================== *
1975  */
1976
1977 struct packet_entry
1978 {
1979     char                key;
1980     enum packet_return  (*handler)(struct gdb_context* gdbctx);
1981 };
1982
1983 static struct packet_entry packet_entries[] =
1984 {
1985         /*{'!', packet_extended}, */
1986         {'?', packet_last_signal},
1987         {'c', packet_continue},
1988         {'C', packet_continue_signal},
1989         {'D', packet_detach},
1990         {'g', packet_read_registers},
1991         {'G', packet_write_registers},
1992         {'k', packet_kill},
1993         {'H', packet_thread},
1994         {'m', packet_read_memory},
1995         {'M', packet_write_memory},
1996         {'p', packet_read_register},
1997         {'P', packet_write_register},
1998         {'q', packet_query},
1999         /* {'Q', packet_set}, */
2000         /* {'R', packet,restart}, only in extended mode ! */
2001         {'s', packet_step},        
2002         /*{'S', packet_step_signal}, hard(er) to implement */
2003         {'T', packet_thread_alive},
2004         {'v', packet_verbose},
2005         {'z', packet_remove_breakpoint},
2006         {'Z', packet_set_breakpoint},
2007 };
2008
2009 static BOOL extract_packets(struct gdb_context* gdbctx)
2010 {
2011     char*               end;
2012     int                 plen;
2013     unsigned char       in_cksum, loc_cksum;
2014     char*               ptr;
2015     enum packet_return  ret = packet_error;
2016     int                 num_packet = 0;
2017
2018     while ((ret & packet_last_f) == 0)
2019     {
2020         if (gdbctx->in_len && (gdbctx->trace & GDBPXY_TRC_LOWLEVEL))
2021             fprintf(stderr, "In-buf: %*.*s\n",
2022                     gdbctx->in_len, gdbctx->in_len, gdbctx->in_buf);
2023         ptr = memchr(gdbctx->in_buf, '$', gdbctx->in_len);
2024         if (ptr == NULL) return FALSE;
2025         if (ptr != gdbctx->in_buf)
2026         {
2027             int glen = ptr - gdbctx->in_buf; /* garbage len */
2028             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2029                 fprintf(stderr, "Removing garbage: %*.*s\n",
2030                         glen, glen, gdbctx->in_buf);
2031             gdbctx->in_len -= glen;
2032             memmove(gdbctx->in_buf, ptr, gdbctx->in_len);
2033         }
2034         end = memchr(gdbctx->in_buf + 1, '#', gdbctx->in_len);
2035         if (end == NULL) return FALSE;
2036         /* no checksum yet */
2037         if (end + 3 > gdbctx->in_buf + gdbctx->in_len) return FALSE;
2038         plen = end - gdbctx->in_buf - 1;
2039         hex_from(&in_cksum, end + 1, 1);
2040         loc_cksum = checksum(gdbctx->in_buf + 1, plen);
2041         if (loc_cksum == in_cksum)
2042         {
2043             if (num_packet == 0) {
2044                 int                 i;
2045                 
2046                 ret = packet_error;
2047                 
2048                 write(gdbctx->sock, "+", 1);
2049                 assert(plen);
2050                 
2051                 /* FIXME: should use bsearch if packet_entries was sorted */
2052                 for (i = 0; i < sizeof(packet_entries)/sizeof(packet_entries[0]); i++)
2053                 {
2054                     if (packet_entries[i].key == gdbctx->in_buf[1]) break;
2055                 }
2056                 if (i == sizeof(packet_entries)/sizeof(packet_entries[0]))
2057                 {
2058                     if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
2059                         fprintf(stderr, "Unknown packet request %*.*s\n",
2060                                 plen, plen, &gdbctx->in_buf[1]);
2061                 }
2062                 else
2063                 {
2064                     gdbctx->in_packet = gdbctx->in_buf + 2;
2065                     gdbctx->in_packet_len = plen - 1;
2066                     if (gdbctx->trace & GDBPXY_TRC_PACKET)
2067                         fprintf(stderr, "Packet: %c%*.*s\n",
2068                                 gdbctx->in_buf[1],
2069                                 gdbctx->in_packet_len, gdbctx->in_packet_len,
2070                                 gdbctx->in_packet);
2071                     ret = (packet_entries[i].handler)(gdbctx);
2072                 }
2073                 switch (ret & ~packet_last_f)
2074                 {
2075                 case packet_error:  packet_reply(gdbctx, "", 0); break;
2076                 case packet_ok:     packet_reply(gdbctx, "OK", 2); break;
2077                 case packet_done:   break;
2078                 }
2079                 if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2080                     fprintf(stderr, "Reply-full: %*.*s\n",
2081                             gdbctx->out_len, gdbctx->out_len, gdbctx->out_buf);
2082                 i = write(gdbctx->sock, gdbctx->out_buf, gdbctx->out_len);
2083                 assert(i == gdbctx->out_len);
2084                 /* if this fails, we'll have to use POLLOUT...
2085                  */
2086                 gdbctx->out_len = 0;
2087                 num_packet++;
2088             }
2089             else 
2090             {
2091                 /* FIXME: if we have in our input buffer more than one packet, 
2092                  * it's very likely that we took too long to answer to a given packet
2093                  * and gdb is sending us again the same packet
2094                  * We simply drop the second packet. This will lower the risk of error, 
2095                  * but there's still some race conditions here
2096                  * A better fix (yet not perfect) would be to have two threads:
2097                  * - one managing the packets for gdb
2098                  * - the second one managing the commands...
2099                  * This would allow us also the reply with the '+' character (Ack of
2100                  * the command) way sooner than what we do now
2101                  */
2102                 if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2103                     fprintf(stderr, "Dropping packet, I was too slow to respond\n");
2104             }
2105         }
2106         else
2107         {
2108             write(gdbctx->sock, "+", 1);
2109             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2110                 fprintf(stderr, "Dropping packet, invalid checksum %d <> %d\n", in_cksum, loc_cksum);
2111         }
2112         gdbctx->in_len -= plen + 4;
2113         memmove(gdbctx->in_buf, end + 3, gdbctx->in_len);
2114     }
2115     return TRUE;
2116 }
2117
2118 static int fetch_data(struct gdb_context* gdbctx)
2119 {
2120     int len, in_len = gdbctx->in_len;
2121
2122     assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
2123     for (;;)
2124     {
2125 #define STEP 128
2126         if (gdbctx->in_len + STEP > gdbctx->in_buf_alloc)
2127             gdbctx->in_buf = packet_realloc(gdbctx->in_buf, gdbctx->in_buf_alloc += STEP);
2128 #undef STEP
2129         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2130             fprintf(stderr, "%d %d %*.*s\n",
2131                     gdbctx->in_len, gdbctx->in_buf_alloc,
2132                     gdbctx->in_len, gdbctx->in_len, gdbctx->in_buf);
2133         len = read(gdbctx->sock, gdbctx->in_buf + gdbctx->in_len, gdbctx->in_buf_alloc - gdbctx->in_len);
2134         if (len <= 0) break;
2135         gdbctx->in_len += len;
2136         assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
2137         if (len < gdbctx->in_buf_alloc - gdbctx->in_len) break;
2138     }
2139     if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2140         fprintf(stderr, "=> %d\n", gdbctx->in_len - in_len);
2141     return gdbctx->in_len - in_len;
2142 }
2143
2144 #define FLAG_NO_START   1
2145 #define FLAG_WITH_XTERM 2
2146
2147 static BOOL gdb_exec(const char* wine_path, unsigned port, unsigned flags)
2148 {
2149     char            buf[MAX_PATH];
2150     int             fd;
2151     const char*     gdb_path;
2152     FILE*           f;
2153
2154     if (!(gdb_path = getenv("WINE_GDB"))) gdb_path = "gdb";
2155     strcpy(buf,"/tmp/winegdb.XXXXXX");
2156     fd = mkstemps(buf, 0);
2157     if (fd == -1) return FALSE;
2158     if ((f = fdopen(fd, "w+")) == NULL) return FALSE;
2159     fprintf(f, "file %s\n", wine_path);
2160     fprintf(f, "target remote localhost:%d\n", ntohs(port));
2161     fprintf(f, "monitor trace=%d\n", GDBPXY_TRC_COMMAND_FIXME);
2162     fprintf(f, "set prompt Wine-gdb>\\ \n");
2163     /* gdb 5.1 seems to require it, won't hurt anyway */
2164     fprintf(f, "sharedlibrary\n");
2165     /* This is needed (but not a decent & final fix)
2166      * Without this, gdb would skip our inter-DLL relay code (because
2167      * we don't have any line number information for the relay code)
2168      * With this, we will stop on first instruction of the stub, and
2169      * reusing step, will get us through the relay stub at the actual
2170      * function we're looking at.
2171      */
2172     fprintf(f, "set step-mode on\n");
2173     /* tell gdb to delete this file when done handling it... */
2174     fprintf(f, "shell rm -f \"%s\"\n", buf);
2175     fclose(f);
2176     if (flags & FLAG_WITH_XTERM)
2177         execlp("xterm", "xterm", "-e", gdb_path, "-x", buf, NULL);
2178     else
2179         execlp(gdb_path, gdb_path, "-x", buf, NULL);
2180     assert(0); /* never reached */
2181     return TRUE;
2182 }
2183
2184 static BOOL gdb_startup(struct gdb_context* gdbctx, DEBUG_EVENT* de, unsigned flags)
2185 {
2186     int                 sock;
2187     struct sockaddr_in  s_addrs;
2188     unsigned int        s_len = sizeof(s_addrs);
2189     struct pollfd       pollfd;
2190     IMAGEHLP_MODULE64   imh_mod;
2191
2192     /* step 1: create socket for gdb connection request */
2193     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
2194     {
2195         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2196             fprintf(stderr, "Can't create socket");
2197         return FALSE;
2198     }
2199
2200     if (listen(sock, 1) == -1 ||
2201         getsockname(sock, (struct sockaddr*)&s_addrs, &s_len) == -1)
2202         return FALSE;
2203
2204     /* step 2: do the process internal creation */
2205     handle_debug_event(gdbctx, de);
2206
2207     /* step3: get the wine loader name */
2208     if (!dbg_get_debuggee_info(gdbctx->process->handle, &imh_mod)) return FALSE;
2209
2210     /* step 4: fire up gdb (if requested) */
2211     if (flags & FLAG_NO_START)
2212         fprintf(stderr, "target remote localhost:%d\n", ntohs(s_addrs.sin_port));
2213     else
2214         switch (fork())
2215         {
2216         case -1: /* error in parent... */
2217             fprintf(stderr, "Cannot create gdb\n");
2218             return FALSE;
2219         default: /* in parent... success */
2220             break;
2221         case 0: /* in child... and alive */
2222             gdb_exec(imh_mod.LoadedImageName, s_addrs.sin_port, flags);
2223             /* if we're here, exec failed, so report failure */
2224             return FALSE;
2225         }
2226
2227     /* step 5: wait for gdb to connect actually */
2228     pollfd.fd = sock;
2229     pollfd.events = POLLIN;
2230     pollfd.revents = 0;
2231
2232     switch (poll(&pollfd, 1, -1))
2233     {
2234     case 1:
2235         if (pollfd.revents & POLLIN)
2236         {
2237             int dummy = 1;
2238             gdbctx->sock = accept(sock, (struct sockaddr*)&s_addrs, &s_len);
2239             if (gdbctx->sock == -1)
2240                 break;
2241             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2242                 fprintf(stderr, "Connected on %d\n", gdbctx->sock);
2243             /* don't keep our small packets too long: send them ASAP back to GDB
2244              * without this, GDB really crawls
2245              */
2246             setsockopt(gdbctx->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&dummy, sizeof(dummy));
2247         }
2248         break;
2249     case 0:
2250         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2251             fprintf(stderr, "Poll for cnx failed (timeout)\n");
2252         return FALSE;
2253     case -1:
2254         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2255             fprintf(stderr, "Poll for cnx failed (error)\n");
2256         return FALSE;
2257     default:
2258         assert(0);
2259     }
2260
2261     close(sock);
2262     return TRUE;
2263 }
2264
2265 static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags)
2266 {
2267     DEBUG_EVENT         de;
2268     int                 i;
2269
2270     gdbctx->sock = -1;
2271     gdbctx->in_buf = NULL;
2272     gdbctx->in_buf_alloc = 0;
2273     gdbctx->in_len = 0;
2274     gdbctx->out_buf = NULL;
2275     gdbctx->out_buf_alloc = 0;
2276     gdbctx->out_len = 0;
2277     gdbctx->out_curr_packet = -1;
2278
2279     gdbctx->exec_thread = gdbctx->other_thread = NULL;
2280     gdbctx->last_sig = 0;
2281     gdbctx->in_trap = FALSE;
2282     gdbctx->trace = /*GDBPXY_TRC_PACKET | GDBPXY_TRC_COMMAND |*/ GDBPXY_TRC_COMMAND_ERROR | GDBPXY_TRC_COMMAND_FIXME | GDBPXY_TRC_WIN32_EVENT;
2283     gdbctx->process = NULL;
2284     for (i = 0; i < NUM_XPOINT; i++)
2285         gdbctx->Xpoints[i].type = -1;
2286     for (i = 0; i < sizeof(gdbctx->wine_segs) / sizeof(gdbctx->wine_segs[0]); i++)
2287         gdbctx->wine_segs[i] = 0;
2288
2289     /* wait for first trap */
2290     while (WaitForDebugEvent(&de, INFINITE))
2291     {
2292         if (de.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT)
2293         {
2294             /* this should be the first event we get,
2295              * and the only one of this type  */
2296             assert(gdbctx->process == NULL && de.dwProcessId == dbg_curr_pid);
2297             /* gdbctx->dwProcessId = pid; */
2298             if (!gdb_startup(gdbctx, &de, flags)) return FALSE;
2299             assert(!gdbctx->in_trap);
2300         }
2301         else
2302         {
2303             handle_debug_event(gdbctx, &de);
2304             if (gdbctx->in_trap) break;
2305         }
2306         ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
2307     }
2308     return TRUE;
2309 }
2310
2311 static int gdb_remote(unsigned flags)
2312 {
2313     struct pollfd       pollfd;
2314     struct gdb_context  gdbctx;
2315     BOOL                doLoop;
2316
2317     for (doLoop = gdb_init_context(&gdbctx, flags); doLoop;)
2318     {
2319         pollfd.fd = gdbctx.sock;
2320         pollfd.events = POLLIN;
2321         pollfd.revents = 0;
2322
2323         switch (poll(&pollfd, 1, -1))
2324         {
2325         case 1:
2326             /* got something */
2327             if (pollfd.revents & (POLLHUP | POLLERR))
2328             {
2329                 if (gdbctx.trace & GDBPXY_TRC_LOWLEVEL)
2330                     fprintf(stderr, "Gdb hung up\n");
2331                 /* kill also debuggee process - questionnable - */
2332                 detach_debuggee(&gdbctx, TRUE);
2333                 doLoop = FALSE;
2334                 break;
2335             }
2336             if ((pollfd.revents & POLLIN) && fetch_data(&gdbctx) > 0)
2337             {
2338                 if (extract_packets(&gdbctx)) doLoop = FALSE;
2339             }
2340             break;
2341         case 0:
2342             /* timeout, should never happen (infinite timeout) */
2343             break;
2344         case -1:
2345             if (gdbctx.trace & GDBPXY_TRC_LOWLEVEL)
2346                 fprintf(stderr, "Poll failed\n");
2347             doLoop = FALSE;
2348             break;
2349         }
2350     }
2351     wait(NULL);
2352     return 0;
2353 }
2354 #endif
2355
2356 int gdb_main(int argc, char* argv[])
2357 {
2358 #ifdef HAVE_POLL
2359     unsigned gdb_flags = 0;
2360
2361     argc--; argv++;
2362     while (argc > 0 && argv[0][0] == '-')
2363     {
2364         if (strcmp(argv[0], "--no-start") == 0)
2365         {
2366             gdb_flags |= FLAG_NO_START;
2367             argc--; argv++;
2368             continue;
2369         }
2370         if (strcmp(argv[0], "--with-xterm") == 0)
2371         {
2372             gdb_flags |= FLAG_WITH_XTERM;
2373             argc--; argv++;
2374             continue;
2375         }
2376         return -1;
2377     }
2378     if (dbg_active_attach(argc, argv) == start_ok ||
2379         dbg_active_launch(argc, argv) == start_ok)
2380         return gdb_remote(gdb_flags);
2381 #else
2382     fprintf(stderr, "GdbProxy mode not supported on this platform\n");
2383 #endif
2384     return -1;
2385 }