cmd: Make MOVE work for read-only files.
[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 'C':
1789         if (gdbctx->in_packet_len == 1)
1790         {
1791             struct dbg_thread*  thd;
1792             /* FIXME: doc says 16 bit val ??? */
1793             /* grab first created thread, aka last in list */
1794             assert(gdbctx->process && !list_empty(&gdbctx->process->threads));
1795             thd = LIST_ENTRY(list_tail(&gdbctx->process->threads), struct dbg_thread, entry);
1796             packet_reply_open(gdbctx);
1797             packet_reply_add(gdbctx, "QC", 2);
1798             packet_reply_val(gdbctx, thd->tid, 4);
1799             packet_reply_close(gdbctx);
1800             return packet_done;
1801         }
1802         break;
1803     case 'O':
1804         if (strncmp(gdbctx->in_packet, "Offsets", gdbctx->in_packet_len) == 0)
1805         {
1806             char    buf[64];
1807
1808             snprintf(buf, sizeof(buf),
1809                      "Text=%08lx;Data=%08lx;Bss=%08lx",
1810                      gdbctx->wine_segs[0], gdbctx->wine_segs[1],
1811                      gdbctx->wine_segs[2]);
1812             return packet_reply(gdbctx, buf, -1);
1813         }
1814         break;
1815     case 'R':
1816         if (gdbctx->in_packet_len > 5 && strncmp(gdbctx->in_packet, "Rcmd,", 5) == 0)
1817         {
1818             return packet_query_remote_command(gdbctx, gdbctx->in_packet + 5,
1819                                                gdbctx->in_packet_len - 5);
1820         }
1821         break;
1822     case 'S':
1823         if (strncmp(gdbctx->in_packet, "Symbol::", gdbctx->in_packet_len) == 0)
1824             return packet_ok;
1825         if (strncmp(gdbctx->in_packet, "Supported", 9) == 0)
1826         {
1827             /* no features supported */
1828             packet_reply_open(gdbctx);
1829             packet_reply_close(gdbctx);
1830             return packet_done;
1831         }
1832         break;
1833     case 'T':
1834         if (gdbctx->in_packet_len > 15 &&
1835             strncmp(gdbctx->in_packet, "ThreadExtraInfo", 15) == 0 &&
1836             gdbctx->in_packet[15] == ',')
1837         {
1838             unsigned    tid;
1839             char*       end;
1840             char        result[128];
1841
1842             tid = strtol(gdbctx->in_packet + 16, &end, 16);
1843             if (end == NULL) break;
1844             get_thread_info(gdbctx, tid, result, sizeof(result));
1845             packet_reply_open(gdbctx);
1846             packet_reply_hex_to_str(gdbctx, result);
1847             packet_reply_close(gdbctx);
1848             return packet_done;
1849         }
1850         if (strncmp(gdbctx->in_packet, "TStatus", 7) == 0)
1851         {
1852             /* Tracepoints not supported */
1853             packet_reply_open(gdbctx);
1854             packet_reply_close(gdbctx);
1855             return packet_done;
1856         }
1857         break;
1858     }
1859     if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1860         fprintf(stderr, "Unknown or malformed query %*.*s\n",
1861                 gdbctx->in_packet_len, gdbctx->in_packet_len, gdbctx->in_packet);
1862     return packet_error;
1863 }
1864
1865 static enum packet_return packet_step(struct gdb_context* gdbctx)
1866 {
1867     /* FIXME: add support for address in packet */
1868     assert(gdbctx->in_packet_len == 0);
1869     if (dbg_curr_thread != gdbctx->exec_thread && gdbctx->exec_thread)
1870         if (gdbctx->trace & GDBPXY_TRC_COMMAND_FIXME)
1871             fprintf(stderr, "NIY: step on %04x, while last thread is %04x\n",
1872                     gdbctx->exec_thread->tid, dbg_curr_thread->tid);
1873     be_cpu->single_step(&gdbctx->context, TRUE);
1874     resume_debuggee(gdbctx, DBG_CONTINUE);
1875     wait_for_debuggee(gdbctx);
1876     be_cpu->single_step(&gdbctx->context, FALSE);
1877     return packet_reply_status(gdbctx);
1878 }
1879
1880 #if 0
1881 static enum packet_return packet_step_signal(struct gdb_context* gdbctx)
1882 {
1883     unsigned char sig;
1884
1885     /* FIXME: add support for address in packet */
1886     assert(gdbctx->in_packet_len == 2);
1887     if (dbg_curr_thread->tid != gdbctx->exec_thread && gdbctx->exec_thread)
1888         if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
1889             fprintf(stderr, "NIY: step/sig on %u, while last thread is %u\n",
1890                     gdbctx->exec_thread, DEBUG_CurrThread->tid);
1891     hex_from(&sig, gdbctx->in_packet, 1);
1892     /* cannot change signals on the fly */
1893     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1894         fprintf(stderr, "sigs: %u %u\n", sig, gdbctx->last_sig);
1895     if (sig != gdbctx->last_sig)
1896         return packet_error;
1897     resume_debuggee(gdbctx, DBG_EXCEPTION_NOT_HANDLED);
1898     wait_for_debuggee(gdbctx);
1899     return packet_reply_status(gdbctx);
1900 }
1901 #endif
1902
1903 static enum packet_return packet_thread_alive(struct gdb_context* gdbctx)
1904 {
1905     char*       end;
1906     unsigned    tid;
1907
1908     tid = strtol(gdbctx->in_packet, &end, 16);
1909     if (tid == -1 || tid == 0)
1910         return packet_reply_error(gdbctx, EINVAL);
1911     if (dbg_get_thread(gdbctx->process, tid) != NULL)
1912         return packet_ok;
1913     return packet_reply_error(gdbctx, ESRCH);
1914 }
1915
1916 static enum packet_return packet_remove_breakpoint(struct gdb_context* gdbctx)
1917 {
1918     void*                       addr;
1919     unsigned                    len;
1920     struct gdb_ctx_Xpoint*      xpt;
1921     enum be_xpoint_type         t;
1922
1923     /* FIXME: check packet_len */
1924     if (gdbctx->in_packet[0] < '0' || gdbctx->in_packet[0] > '4' ||
1925         gdbctx->in_packet[1] != ',' ||
1926         sscanf(gdbctx->in_packet + 2, "%p,%x", &addr, &len) != 2)
1927         return packet_error;
1928     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1929         fprintf(stderr, "Remove bp %p[%u] typ=%c\n",
1930                 addr, len, gdbctx->in_packet[0]);
1931     switch (gdbctx->in_packet[0])
1932     {
1933     case '0': t = be_xpoint_break; len = 0; break;
1934     case '1': t = be_xpoint_watch_exec; break;
1935     case '2': t = be_xpoint_watch_read; break;
1936     case '3': t = be_xpoint_watch_write; break;
1937     default: return packet_error;
1938     }
1939     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
1940     {
1941         if (xpt->addr == addr && xpt->type == t)
1942         {
1943             if (be_cpu->remove_Xpoint(gdbctx->process->handle,
1944                                       gdbctx->process->process_io, &gdbctx->context,
1945                                       t, xpt->addr, xpt->val, len))
1946             {
1947                 xpt->type = -1;
1948                 return packet_ok;
1949             }
1950             break;
1951         }
1952     }
1953     return packet_error;
1954 }
1955
1956 static enum packet_return packet_set_breakpoint(struct gdb_context* gdbctx)
1957 {
1958     void*                       addr;
1959     unsigned                    len;
1960     struct gdb_ctx_Xpoint*      xpt;
1961     enum be_xpoint_type         t;
1962
1963     /* FIXME: check packet_len */
1964     if (gdbctx->in_packet[0] < '0' || gdbctx->in_packet[0] > '4' ||
1965         gdbctx->in_packet[1] != ',' ||
1966         sscanf(gdbctx->in_packet + 2, "%p,%x", &addr, &len) != 2)
1967         return packet_error;
1968     if (gdbctx->trace & GDBPXY_TRC_COMMAND)
1969         fprintf(stderr, "Set bp %p[%u] typ=%c\n",
1970                 addr, len, gdbctx->in_packet[0]);
1971     switch (gdbctx->in_packet[0])
1972     {
1973     case '0': t = be_xpoint_break; len = 0; break;
1974     case '1': t = be_xpoint_watch_exec; break;
1975     case '2': t = be_xpoint_watch_read; break;
1976     case '3': t = be_xpoint_watch_write; break;
1977     default: return packet_error;
1978     }
1979     /* because of packet command handling, this should be made idempotent */
1980     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
1981     {
1982         if (xpt->addr == addr && xpt->type == t)
1983             return packet_ok; /* nothing to do */
1984     }
1985     /* really set the Xpoint */
1986     for (xpt = &gdbctx->Xpoints[NUM_XPOINT - 1]; xpt >= gdbctx->Xpoints; xpt--)
1987     {
1988         if (xpt->type == -1)
1989         {
1990             if (be_cpu->insert_Xpoint(gdbctx->process->handle,
1991                                       gdbctx->process->process_io, &gdbctx->context, 
1992                                       t, addr, &xpt->val, len))
1993             {
1994                 xpt->addr = addr;
1995                 xpt->type = t;
1996                 return packet_ok;
1997             }
1998             fprintf(stderr, "cannot set xpoint\n");
1999             break;
2000         }
2001     }
2002     /* no more entries... eech */
2003     fprintf(stderr, "Running out of spots for {break|watch}points\n");
2004     return packet_error;
2005 }
2006
2007 /* =============================================== *
2008  *    P A C K E T  I N F R A S T R U C T U R E     *
2009  * =============================================== *
2010  */
2011
2012 struct packet_entry
2013 {
2014     char                key;
2015     enum packet_return  (*handler)(struct gdb_context* gdbctx);
2016 };
2017
2018 static struct packet_entry packet_entries[] =
2019 {
2020         /*{'!', packet_extended}, */
2021         {'?', packet_last_signal},
2022         {'c', packet_continue},
2023         {'C', packet_continue_signal},
2024         {'D', packet_detach},
2025         {'g', packet_read_registers},
2026         {'G', packet_write_registers},
2027         {'k', packet_kill},
2028         {'H', packet_thread},
2029         {'m', packet_read_memory},
2030         {'M', packet_write_memory},
2031         {'p', packet_read_register},
2032         {'P', packet_write_register},
2033         {'q', packet_query},
2034         /* {'Q', packet_set}, */
2035         /* {'R', packet,restart}, only in extended mode ! */
2036         {'s', packet_step},        
2037         /*{'S', packet_step_signal}, hard(er) to implement */
2038         {'T', packet_thread_alive},
2039         {'v', packet_verbose},
2040         {'z', packet_remove_breakpoint},
2041         {'Z', packet_set_breakpoint},
2042 };
2043
2044 static BOOL extract_packets(struct gdb_context* gdbctx)
2045 {
2046     char*               end;
2047     int                 plen;
2048     unsigned char       in_cksum, loc_cksum;
2049     char*               ptr;
2050     enum packet_return  ret = packet_error;
2051     int                 num_packet = 0;
2052
2053     while ((ret & packet_last_f) == 0)
2054     {
2055         if (gdbctx->in_len && (gdbctx->trace & GDBPXY_TRC_LOWLEVEL))
2056             fprintf(stderr, "In-buf: %*.*s\n",
2057                     gdbctx->in_len, gdbctx->in_len, gdbctx->in_buf);
2058         ptr = memchr(gdbctx->in_buf, '$', gdbctx->in_len);
2059         if (ptr == NULL) return FALSE;
2060         if (ptr != gdbctx->in_buf)
2061         {
2062             int glen = ptr - gdbctx->in_buf; /* garbage len */
2063             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2064                 fprintf(stderr, "Removing garbage: %*.*s\n",
2065                         glen, glen, gdbctx->in_buf);
2066             gdbctx->in_len -= glen;
2067             memmove(gdbctx->in_buf, ptr, gdbctx->in_len);
2068         }
2069         end = memchr(gdbctx->in_buf + 1, '#', gdbctx->in_len);
2070         if (end == NULL) return FALSE;
2071         /* no checksum yet */
2072         if (end + 3 > gdbctx->in_buf + gdbctx->in_len) return FALSE;
2073         plen = end - gdbctx->in_buf - 1;
2074         hex_from(&in_cksum, end + 1, 1);
2075         loc_cksum = checksum(gdbctx->in_buf + 1, plen);
2076         if (loc_cksum == in_cksum)
2077         {
2078             if (num_packet == 0) {
2079                 int                 i;
2080                 
2081                 ret = packet_error;
2082                 
2083                 write(gdbctx->sock, "+", 1);
2084                 assert(plen);
2085                 
2086                 /* FIXME: should use bsearch if packet_entries was sorted */
2087                 for (i = 0; i < sizeof(packet_entries)/sizeof(packet_entries[0]); i++)
2088                 {
2089                     if (packet_entries[i].key == gdbctx->in_buf[1]) break;
2090                 }
2091                 if (i == sizeof(packet_entries)/sizeof(packet_entries[0]))
2092                 {
2093                     if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
2094                         fprintf(stderr, "Unknown packet request %*.*s\n",
2095                                 plen, plen, &gdbctx->in_buf[1]);
2096                 }
2097                 else
2098                 {
2099                     gdbctx->in_packet = gdbctx->in_buf + 2;
2100                     gdbctx->in_packet_len = plen - 1;
2101                     if (gdbctx->trace & GDBPXY_TRC_PACKET)
2102                         fprintf(stderr, "Packet: %c%*.*s\n",
2103                                 gdbctx->in_buf[1],
2104                                 gdbctx->in_packet_len, gdbctx->in_packet_len,
2105                                 gdbctx->in_packet);
2106                     ret = (packet_entries[i].handler)(gdbctx);
2107                 }
2108                 switch (ret & ~packet_last_f)
2109                 {
2110                 case packet_error:  packet_reply(gdbctx, "", 0); break;
2111                 case packet_ok:     packet_reply(gdbctx, "OK", 2); break;
2112                 case packet_done:   break;
2113                 }
2114                 if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2115                     fprintf(stderr, "Reply-full: %*.*s\n",
2116                             gdbctx->out_len, gdbctx->out_len, gdbctx->out_buf);
2117                 i = write(gdbctx->sock, gdbctx->out_buf, gdbctx->out_len);
2118                 assert(i == gdbctx->out_len);
2119                 /* if this fails, we'll have to use POLLOUT...
2120                  */
2121                 gdbctx->out_len = 0;
2122                 num_packet++;
2123             }
2124             else 
2125             {
2126                 /* FIXME: if we have in our input buffer more than one packet, 
2127                  * it's very likely that we took too long to answer to a given packet
2128                  * and gdb is sending us again the same packet
2129                  * We simply drop the second packet. This will lower the risk of error, 
2130                  * but there's still some race conditions here
2131                  * A better fix (yet not perfect) would be to have two threads:
2132                  * - one managing the packets for gdb
2133                  * - the second one managing the commands...
2134                  * This would allow us also the reply with the '+' character (Ack of
2135                  * the command) way sooner than what we do now
2136                  */
2137                 if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2138                     fprintf(stderr, "Dropping packet, I was too slow to respond\n");
2139             }
2140         }
2141         else
2142         {
2143             write(gdbctx->sock, "+", 1);
2144             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2145                 fprintf(stderr, "Dropping packet, invalid checksum %d <> %d\n", in_cksum, loc_cksum);
2146         }
2147         gdbctx->in_len -= plen + 4;
2148         memmove(gdbctx->in_buf, end + 3, gdbctx->in_len);
2149     }
2150     return TRUE;
2151 }
2152
2153 static int fetch_data(struct gdb_context* gdbctx)
2154 {
2155     int len, in_len = gdbctx->in_len;
2156
2157     assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
2158     for (;;)
2159     {
2160 #define STEP 128
2161         if (gdbctx->in_len + STEP > gdbctx->in_buf_alloc)
2162             gdbctx->in_buf = packet_realloc(gdbctx->in_buf, gdbctx->in_buf_alloc += STEP);
2163 #undef STEP
2164         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2165             fprintf(stderr, "%d %d %*.*s\n",
2166                     gdbctx->in_len, gdbctx->in_buf_alloc,
2167                     gdbctx->in_len, gdbctx->in_len, gdbctx->in_buf);
2168         len = read(gdbctx->sock, gdbctx->in_buf + gdbctx->in_len, gdbctx->in_buf_alloc - gdbctx->in_len);
2169         if (len <= 0) break;
2170         gdbctx->in_len += len;
2171         assert(gdbctx->in_len <= gdbctx->in_buf_alloc);
2172         if (len < gdbctx->in_buf_alloc - gdbctx->in_len) break;
2173     }
2174     if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2175         fprintf(stderr, "=> %d\n", gdbctx->in_len - in_len);
2176     return gdbctx->in_len - in_len;
2177 }
2178
2179 #define FLAG_NO_START   1
2180 #define FLAG_WITH_XTERM 2
2181
2182 static BOOL gdb_exec(const char* wine_path, unsigned port, unsigned flags)
2183 {
2184     char            buf[MAX_PATH];
2185     int             fd;
2186     const char*     gdb_path;
2187     FILE*           f;
2188
2189     if (!(gdb_path = getenv("WINE_GDB"))) gdb_path = "gdb";
2190     strcpy(buf,"/tmp/winegdb.XXXXXX");
2191     fd = mkstemps(buf, 0);
2192     if (fd == -1) return FALSE;
2193     if ((f = fdopen(fd, "w+")) == NULL) return FALSE;
2194     fprintf(f, "file %s\n", wine_path);
2195     fprintf(f, "target remote localhost:%d\n", ntohs(port));
2196     fprintf(f, "monitor trace=%d\n", GDBPXY_TRC_COMMAND_FIXME);
2197     fprintf(f, "set prompt Wine-gdb>\\ \n");
2198     /* gdb 5.1 seems to require it, won't hurt anyway */
2199     fprintf(f, "sharedlibrary\n");
2200     /* This is needed (but not a decent & final fix)
2201      * Without this, gdb would skip our inter-DLL relay code (because
2202      * we don't have any line number information for the relay code)
2203      * With this, we will stop on first instruction of the stub, and
2204      * reusing step, will get us through the relay stub at the actual
2205      * function we're looking at.
2206      */
2207     fprintf(f, "set step-mode on\n");
2208     /* tell gdb to delete this file when done handling it... */
2209     fprintf(f, "shell rm -f \"%s\"\n", buf);
2210     fclose(f);
2211     if (flags & FLAG_WITH_XTERM)
2212         execlp("xterm", "xterm", "-e", gdb_path, "-x", buf, NULL);
2213     else
2214         execlp(gdb_path, gdb_path, "-x", buf, NULL);
2215     assert(0); /* never reached */
2216     return TRUE;
2217 }
2218
2219 static BOOL gdb_startup(struct gdb_context* gdbctx, DEBUG_EVENT* de, unsigned flags)
2220 {
2221     int                 sock;
2222     struct sockaddr_in  s_addrs;
2223     unsigned int        s_len = sizeof(s_addrs);
2224     struct pollfd       pollfd;
2225     IMAGEHLP_MODULE64   imh_mod;
2226
2227     /* step 1: create socket for gdb connection request */
2228     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
2229     {
2230         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2231             fprintf(stderr, "Can't create socket");
2232         return FALSE;
2233     }
2234
2235     if (listen(sock, 1) == -1 ||
2236         getsockname(sock, (struct sockaddr*)&s_addrs, &s_len) == -1)
2237         return FALSE;
2238
2239     /* step 2: do the process internal creation */
2240     handle_debug_event(gdbctx, de);
2241
2242     /* step3: get the wine loader name */
2243     if (!dbg_get_debuggee_info(gdbctx->process->handle, &imh_mod)) return FALSE;
2244
2245     /* step 4: fire up gdb (if requested) */
2246     if (flags & FLAG_NO_START)
2247         fprintf(stderr, "target remote localhost:%d\n", ntohs(s_addrs.sin_port));
2248     else
2249         switch (fork())
2250         {
2251         case -1: /* error in parent... */
2252             fprintf(stderr, "Cannot create gdb\n");
2253             return FALSE;
2254         default: /* in parent... success */
2255             signal(SIGINT, SIG_IGN);
2256             break;
2257         case 0: /* in child... and alive */
2258             gdb_exec(imh_mod.LoadedImageName, s_addrs.sin_port, flags);
2259             /* if we're here, exec failed, so report failure */
2260             return FALSE;
2261         }
2262
2263     /* step 5: wait for gdb to connect actually */
2264     pollfd.fd = sock;
2265     pollfd.events = POLLIN;
2266     pollfd.revents = 0;
2267
2268     switch (poll(&pollfd, 1, -1))
2269     {
2270     case 1:
2271         if (pollfd.revents & POLLIN)
2272         {
2273             int dummy = 1;
2274             gdbctx->sock = accept(sock, (struct sockaddr*)&s_addrs, &s_len);
2275             if (gdbctx->sock == -1)
2276                 break;
2277             if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2278                 fprintf(stderr, "Connected on %d\n", gdbctx->sock);
2279             /* don't keep our small packets too long: send them ASAP back to GDB
2280              * without this, GDB really crawls
2281              */
2282             setsockopt(gdbctx->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&dummy, sizeof(dummy));
2283         }
2284         break;
2285     case 0:
2286         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2287             fprintf(stderr, "Poll for cnx failed (timeout)\n");
2288         return FALSE;
2289     case -1:
2290         if (gdbctx->trace & GDBPXY_TRC_LOWLEVEL)
2291             fprintf(stderr, "Poll for cnx failed (error)\n");
2292         return FALSE;
2293     default:
2294         assert(0);
2295     }
2296
2297     close(sock);
2298     return TRUE;
2299 }
2300
2301 static BOOL gdb_init_context(struct gdb_context* gdbctx, unsigned flags)
2302 {
2303     DEBUG_EVENT         de;
2304     int                 i;
2305
2306     gdbctx->sock = -1;
2307     gdbctx->in_buf = NULL;
2308     gdbctx->in_buf_alloc = 0;
2309     gdbctx->in_len = 0;
2310     gdbctx->out_buf = NULL;
2311     gdbctx->out_buf_alloc = 0;
2312     gdbctx->out_len = 0;
2313     gdbctx->out_curr_packet = -1;
2314
2315     gdbctx->exec_thread = gdbctx->other_thread = NULL;
2316     gdbctx->last_sig = 0;
2317     gdbctx->in_trap = FALSE;
2318     gdbctx->trace = /*GDBPXY_TRC_PACKET | GDBPXY_TRC_COMMAND |*/ GDBPXY_TRC_COMMAND_ERROR | GDBPXY_TRC_COMMAND_FIXME | GDBPXY_TRC_WIN32_EVENT;
2319     gdbctx->process = NULL;
2320     for (i = 0; i < NUM_XPOINT; i++)
2321         gdbctx->Xpoints[i].type = -1;
2322     for (i = 0; i < sizeof(gdbctx->wine_segs) / sizeof(gdbctx->wine_segs[0]); i++)
2323         gdbctx->wine_segs[i] = 0;
2324
2325     /* wait for first trap */
2326     while (WaitForDebugEvent(&de, INFINITE))
2327     {
2328         if (de.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT)
2329         {
2330             /* this should be the first event we get,
2331              * and the only one of this type  */
2332             assert(gdbctx->process == NULL && de.dwProcessId == dbg_curr_pid);
2333             /* gdbctx->dwProcessId = pid; */
2334             if (!gdb_startup(gdbctx, &de, flags)) return FALSE;
2335             assert(!gdbctx->in_trap);
2336         }
2337         else
2338         {
2339             handle_debug_event(gdbctx, &de);
2340             if (gdbctx->in_trap) break;
2341         }
2342         ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
2343     }
2344     return TRUE;
2345 }
2346
2347 static int gdb_remote(unsigned flags)
2348 {
2349     struct pollfd       pollfd;
2350     struct gdb_context  gdbctx;
2351     BOOL                doLoop;
2352
2353     for (doLoop = gdb_init_context(&gdbctx, flags); doLoop;)
2354     {
2355         pollfd.fd = gdbctx.sock;
2356         pollfd.events = POLLIN;
2357         pollfd.revents = 0;
2358
2359         switch (poll(&pollfd, 1, -1))
2360         {
2361         case 1:
2362             /* got something */
2363             if (pollfd.revents & (POLLHUP | POLLERR))
2364             {
2365                 if (gdbctx.trace & GDBPXY_TRC_LOWLEVEL)
2366                     fprintf(stderr, "Gdb hung up\n");
2367                 /* kill also debuggee process - questionnable - */
2368                 detach_debuggee(&gdbctx, TRUE);
2369                 doLoop = FALSE;
2370                 break;
2371             }
2372             if ((pollfd.revents & POLLIN) && fetch_data(&gdbctx) > 0)
2373             {
2374                 if (extract_packets(&gdbctx)) doLoop = FALSE;
2375             }
2376             break;
2377         case 0:
2378             /* timeout, should never happen (infinite timeout) */
2379             break;
2380         case -1:
2381             if (gdbctx.trace & GDBPXY_TRC_LOWLEVEL)
2382                 fprintf(stderr, "Poll failed\n");
2383             doLoop = FALSE;
2384             break;
2385         }
2386     }
2387     wait(NULL);
2388     return 0;
2389 }
2390 #endif
2391
2392 int gdb_main(int argc, char* argv[])
2393 {
2394 #ifdef HAVE_POLL
2395     unsigned gdb_flags = 0;
2396
2397     argc--; argv++;
2398     while (argc > 0 && argv[0][0] == '-')
2399     {
2400         if (strcmp(argv[0], "--no-start") == 0)
2401         {
2402             gdb_flags |= FLAG_NO_START;
2403             argc--; argv++;
2404             continue;
2405         }
2406         if (strcmp(argv[0], "--with-xterm") == 0)
2407         {
2408             gdb_flags |= FLAG_WITH_XTERM;
2409             argc--; argv++;
2410             continue;
2411         }
2412         return -1;
2413     }
2414     if (dbg_active_attach(argc, argv) == start_ok ||
2415         dbg_active_launch(argc, argv) == start_ok)
2416         return gdb_remote(gdb_flags);
2417 #else
2418     fprintf(stderr, "GdbProxy mode not supported on this platform\n");
2419 #endif
2420     return -1;
2421 }