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