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