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