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