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