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