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_32.html
25 */
26
27 #include "config.h"
28 #include "wine/port.h"
29
30 #include <assert.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <stdarg.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #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 struct be_process_io be_process_gdbproxy_io =
115 {
116 NULL, /* we shouldn't use close_process() in gdbproxy */
117 ReadProcessMemory,
118 WriteProcessMemory
119 };
120
121 /* =============================================== *
122 * B A S I C M A N I P U L A T I O N S *
123 * =============================================== *
124 */
125
126 static inline int hex_from0(char ch)
127 {
128 if (ch >= '' && ch <= '9') return ch - '';
129 if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
130 if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
131
132 assert(0);
133 return 0;
134 }
135
136 static inline unsigned char hex_to0(int x)
137 {
138 assert(x >= 0 && x < 16);
139 return "0123456789abcdef"[x];
140 }
141
142 static int hex_to_int(const char* src, size_t len)
143 {
144 unsigned int returnval = 0;
145 while (len--)
146 {
147 returnval <<= 4;
148 returnval |= hex_from0(*src++);
149 }
150 return returnval;
151 }
152
153 static void hex_from(void* dst, const char* src, size_t len)
154 {
155 unsigned char *p = dst;
156 while (len--)
157 {
158 *p++ = (hex_from0(src[0]) << 4) | hex_from0(src[1]);
159 src += 2;
160 }
161 }
162
163 static void hex_to(char* dst, const void* src, size_t len)
164 {
165 const unsigned char *p = src;
166 while (len--)
167 {
168 *dst++ = hex_to0(*p >> 4);
169 *dst++ = hex_to0(*p & 0x0F);
170 p++;
171 }
172 }
173
174 static unsigned char checksum(const char* ptr, int len)
175 {
176 unsigned cksum = 0;
177
178 while (len-- > 0)
179 cksum += (unsigned char)*ptr++;
180 return cksum;
181 }
182
183 /* =============================================== *
184 * C P U H A N D L E R S *
185 * =============================================== *
186 */
187
188 #ifdef __i386__
189 static size_t cpu_register_map[] = {
190 FIELD_OFFSET(CONTEXT, Eax),
191 FIELD_OFFSET(CONTEXT, Ecx),
192 FIELD_OFFSET(CONTEXT, Edx),
193 FIELD_OFFSET(CONTEXT, Ebx),
194 FIELD_OFFSET(CONTEXT, Esp),
195 FIELD_OFFSET(CONTEXT, Ebp),
196 FIELD_OFFSET(CONTEXT, Esi),
197 FIELD_OFFSET(CONTEXT, Edi),
198 FIELD_OFFSET(CONTEXT, Eip),
199 FIELD_OFFSET(CONTEXT, EFlags),
200 FIELD_OFFSET(CONTEXT, SegCs),
201 FIELD_OFFSET(CONTEXT, SegSs),
202 FIELD_OFFSET(CONTEXT, SegDs),
203 FIELD_OFFSET(CONTEXT, SegEs),
204 FIELD_OFFSET(CONTEXT, SegFs),
205 FIELD_OFFSET(CONTEXT, SegGs),
206 };
207 #elif defined(__powerpc__)
208 static size_t cpu_register_map[] = {
209 FIELD_OFFSET(CONTEXT, Gpr0),
210 FIELD_OFFSET(CONTEXT, Gpr1),
211 FIELD_OFFSET(CONTEXT, Gpr2),
212 FIELD_OFFSET(CONTEXT, Gpr3),
213 FIELD_OFFSET(CONTEXT, Gpr4),
214 FIELD_OFFSET(CONTEXT, Gpr5),
215 FIELD_OFFSET(CONTEXT, Gpr6),
216 FIELD_OFFSET(CONTEXT, Gpr7),
217 FIELD_OFFSET(CONTEXT, Gpr8),
218 FIELD_OFFSET(CONTEXT, Gpr9),
219 FIELD_OFFSET(CONTEXT, Gpr10),
220 FIELD_OFFSET(CONTEXT, Gpr11),
221 FIELD_OFFSET(CONTEXT, Gpr12),
222 FIELD_OFFSET(CONTEXT, Gpr13),
223 FIELD_OFFSET(CONTEXT, Gpr14),
224 FIELD_OFFSET(CONTEXT, Gpr15),
225 FIELD_OFFSET(CONTEXT, Gpr16),
226 FIELD_OFFSET(CONTEXT, Gpr17),
227 FIELD_OFFSET(CONTEXT, Gpr18),
228 FIELD_OFFSET(CONTEXT, Gpr19),
229 FIELD_OFFSET(CONTEXT, Gpr20),
230 FIELD_OFFSET(CONTEXT, Gpr21),
231 FIELD_OFFSET(CONTEXT, Gpr22),
232 FIELD_OFFSET(CONTEXT, Gpr23),
233 FIELD_OFFSET(CONTEXT, Gpr24),
234 FIELD_OFFSET(CONTEXT, Gpr25),
235 FIELD_OFFSET(CONTEXT, Gpr26),
236 FIELD_OFFSET(CONTEXT, Gpr27),
237 FIELD_OFFSET(CONTEXT, Gpr28),
238 FIELD_OFFSET(CONTEXT, Gpr29),
239 FIELD_OFFSET(CONTEXT, Gpr30),
240 FIELD_OFFSET(CONTEXT, Gpr31),
241 FIELD_OFFSET(CONTEXT, Fpr0),
242 FIELD_OFFSET(CONTEXT, Fpr1),
243 FIELD_OFFSET(CONTEXT, Fpr2),
244 FIELD_OFFSET(CONTEXT, Fpr3),
245 FIELD_OFFSET(CONTEXT, Fpr4),
246 FIELD_OFFSET(CONTEXT, Fpr5),
247 FIELD_OFFSET(CONTEXT, Fpr6),
248 FIELD_OFFSET(CONTEXT, Fpr7),
249 FIELD_OFFSET(CONTEXT, Fpr8),
250 FIELD_OFFSET(CONTEXT, Fpr9),
251 FIELD_OFFSET(CONTEXT, Fpr10),
252 FIELD_OFFSET(CONTEXT, Fpr11),
253 FIELD_OFFSET(CONTEXT, Fpr12),
254 FIELD_OFFSET(CONTEXT, Fpr13),
255 FIELD_OFFSET(CONTEXT, Fpr14),
256 FIELD_OFFSET(CONTEXT, Fpr15),
257 FIELD_OFFSET(CONTEXT, Fpr16),
258 FIELD_OFFSET(CONTEXT, Fpr17),
259 FIELD_OFFSET(CONTEXT, Fpr18),
260 FIELD_OFFSET(CONTEXT, Fpr19),
261 FIELD_OFFSET(CONTEXT, Fpr20),
262 FIELD_OFFSET(CONTEXT, Fpr21),
263 FIELD_OFFSET(CONTEXT, Fpr22),
264 FIELD_OFFSET(CONTEXT, Fpr23),
265 FIELD_OFFSET(CONTEXT, Fpr24),
266 FIELD_OFFSET(CONTEXT, Fpr25),
267 FIELD_OFFSET(CONTEXT, Fpr26),
268 FIELD_OFFSET(CONTEXT, Fpr27),
269 FIELD_OFFSET(CONTEXT, Fpr28),
270 FIELD_OFFSET(CONTEXT, Fpr29),
271 FIELD_OFFSET(CONTEXT, Fpr30),
272 FIELD_OFFSET(CONTEXT, Fpr31),
273
274 FIELD_OFFSET(CONTEXT, Iar),
275 FIELD_OFFSET(CONTEXT, Msr),
276 FIELD_OFFSET(CONTEXT, Cr),
277 FIELD_OFFSET(CONTEXT, Lr),
278 FIELD_OFFSET(CONTEXT, Ctr),
279 FIELD_OFFSET(CONTEXT, Xer),
280 /* FIXME: MQ is missing? FIELD_OFFSET(CONTEXT, Mq), */
281 /* see gdb/nlm/ppc.c */
282 };
283 #elif defined(__ALPHA__)
284 static size_t cpu_register_map[] = {
285 FIELD_OFFSET(CONTEXT, IntV0),
286 FIELD_OFFSET(CONTEXT, IntT0),
287 FIELD_OFFSET(CONTEXT, IntT1),
288 FIELD_OFFSET(CONTEXT, IntT2),
289 FIELD_OFFSET(CONTEXT, IntT3),
290 FIELD_OFFSET(CONTEXT, IntT4),
291 FIELD_OFFSET(CONTEXT, IntT5),
292 FIELD_OFFSET(CONTEXT, IntT6),
293 FIELD_OFFSET(CONTEXT, IntT7),
294 FIELD_OFFSET(CONTEXT, IntS0),
295 FIELD_OFFSET(CONTEXT, IntS1),
296 FIELD_OFFSET(CONTEXT, IntS2),
297 FIELD_OFFSET(CONTEXT, IntS3),
298 FIELD_OFFSET(CONTEXT, IntS4),
299 FIELD_OFFSET(CONTEXT, IntS5),
300 FIELD_OFFSET(CONTEXT, IntFp),
301 FIELD_OFFSET(CONTEXT, IntA0),
302 FIELD_OFFSET(CONTEXT, IntA1),
303 FIELD_OFFSET(CONTEXT, IntA2),
304 FIELD_OFFSET(CONTEXT, IntA3),
305 FIELD_OFFSET(CONTEXT, IntA4),
306 FIELD_OFFSET(CONTEXT, IntA5),
307 FIELD_OFFSET(CONTEXT, IntT8),
308 FIELD_OFFSET(CONTEXT, IntT9),
309 FIELD_OFFSET(CONTEXT, IntT10),
310 FIELD_OFFSET(CONTEXT, IntT11),
311 FIELD_OFFSET(CONTEXT, IntRa),
312 FIELD_OFFSET(CONTEXT, IntT12),
313 FIELD_OFFSET(CONTEXT, IntAt),
314 FIELD_OFFSET(CONTEXT, IntGp),
315 FIELD_OFFSET(CONTEXT, IntSp),
316 FIELD_OFFSET(CONTEXT, IntZero),
317 FIELD_OFFSET(CONTEXT, FltF0),
318 FIELD_OFFSET(CONTEXT, FltF1),
319 FIELD_OFFSET(CONTEXT, FltF2),
320 FIELD_OFFSET(CONTEXT, FltF3),
321 FIELD_OFFSET(CONTEXT, FltF4),
322 FIELD_OFFSET(CONTEXT, FltF5),
323 FIELD_OFFSET(CONTEXT, FltF6),
324 FIELD_OFFSET(CONTEXT, FltF7),
325 FIELD_OFFSET(CONTEXT, FltF8),
326 FIELD_OFFSET(CONTEXT, FltF9),
327 FIELD_OFFSET(CONTEXT, FltF10),
328 FIELD_OFFSET(CONTEXT, FltF11),
329 FIELD_OFFSET(CONTEXT, FltF12),
330 FIELD_OFFSET(CONTEXT, FltF13),
331 FIELD_OFFSET(CONTEXT, FltF14),
332 FIELD_OFFSET(CONTEXT, FltF15),
333 FIELD_OFFSET(CONTEXT, FltF16),
334 FIELD_OFFSET(CONTEXT, FltF17),
335 FIELD_OFFSET(CONTEXT, FltF18),
336 FIELD_OFFSET(CONTEXT, FltF19),
337 FIELD_OFFSET(CONTEXT, FltF20),
338 FIELD_OFFSET(CONTEXT, FltF21),
339 FIELD_OFFSET(CONTEXT, FltF22),
340 FIELD_OFFSET(CONTEXT, FltF23),
341 FIELD_OFFSET(CONTEXT, FltF24),
342 FIELD_OFFSET(CONTEXT, FltF25),
343 FIELD_OFFSET(CONTEXT, FltF26),
344 FIELD_OFFSET(CONTEXT, FltF27),
345 FIELD_OFFSET(CONTEXT, FltF28),
346 FIELD_OFFSET(CONTEXT, FltF29),
347 FIELD_OFFSET(CONTEXT, FltF30),
348 FIELD_OFFSET(CONTEXT, FltF31),
349
350 /* FIXME: Didn't look for the right order yet */
351 FIELD_OFFSET(CONTEXT, Fir),
352 FIELD_OFFSET(CONTEXT, Fpcr),
353 FIELD_OFFSET(CONTEXT, SoftFpcr),
354 };
355 #elif defined(__x86_64__)
356 static size_t cpu_register_map[] = {
357 FIELD_OFFSET(CONTEXT, Rax),
358 FIELD_OFFSET(CONTEXT, Rbx),
359 FIELD_OFFSET(CONTEXT, Rcx),
360 FIELD_OFFSET(CONTEXT, Rdx),
361 FIELD_OFFSET(CONTEXT, Rsi),
362 FIELD_OFFSET(CONTEXT, Rdi),
363 FIELD_OFFSET(CONTEXT, Rbp),
364 FIELD_OFFSET(CONTEXT, Rsp),
365 FIELD_OFFSET(CONTEXT, R8),
366 FIELD_OFFSET(CONTEXT, R9),
367 FIELD_OFFSET(CONTEXT, R10),
368 FIELD_OFFSET(CONTEXT, R11),
369 FIELD_OFFSET(CONTEXT, R12),
370 FIELD_OFFSET(CONTEXT, R13),
371 FIELD_OFFSET(CONTEXT, R14),
372 FIELD_OFFSET(CONTEXT, R15),
373 FIELD_OFFSET(CONTEXT, Rip),
374 FIELD_OFFSET(CONTEXT, EFlags),
375 FIELD_OFFSET(CONTEXT, SegCs),
376 FIELD_OFFSET(CONTEXT, SegSs),
377 FIELD_OFFSET(CONTEXT, SegDs),
378 FIELD_OFFSET(CONTEXT, SegEs),
379 FIELD_OFFSET(CONTEXT, SegFs),
380 FIELD_OFFSET(CONTEXT, SegGs),
381 };
382 #else
383 # error Define the registers map for your CPU
384 #endif
385
386 static const size_t cpu_num_regs = (sizeof(cpu_register_map) / sizeof(cpu_register_map[0]));
387
388 static inline unsigned long* cpu_register(CONTEXT* ctx, unsigned idx)
389 {
390 assert(idx < cpu_num_regs);
391 return (unsigned long*)((char*)ctx + cpu_register_map[idx]);
392 }
393
394 /* =============================================== *
395 * W I N 3 2 D E B U G I N T E R F A C E *
396 * =============================================== *
397 */
398
399 static BOOL fetch_context(struct gdb_context* gdbctx, HANDLE h, CONTEXT* ctx)
400 {
401 ctx->ContextFlags = CONTEXT_CONTROL
402 | CONTEXT_INTEGER
403 #ifdef CONTEXT_SEGMENTS
404 | CONTEXT_SEGMENTS
405 #endif
406 #ifdef CONTEXT_DEBUG_REGISTERS
407 | CONTEXT_DEBUG_REGISTERS
408 #endif
409 ;
410 if (!GetThreadContext(h, ctx))
411 {
412 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
413 fprintf(stderr, "Can't get thread's context\n");
414 return FALSE;
415 }
416 return TRUE;
417 }
418
419 static BOOL handle_exception(struct gdb_context* gdbctx, EXCEPTION_DEBUG_INFO* exc)
420 {
421 EXCEPTION_RECORD* rec = &exc->ExceptionRecord;
422 BOOL ret = FALSE;
423
424 switch (rec->ExceptionCode)
425 {
426 case EXCEPTION_ACCESS_VIOLATION:
427 case EXCEPTION_PRIV_INSTRUCTION:
428 case EXCEPTION_STACK_OVERFLOW:
429 case EXCEPTION_GUARD_PAGE:
430 gdbctx->last_sig = SIGSEGV;
431 ret = TRUE;
432 break;
433 case EXCEPTION_DATATYPE_MISALIGNMENT:
434 gdbctx->last_sig = SIGBUS;
435 ret = TRUE;
436 break;
437 case EXCEPTION_SINGLE_STEP:
438 /* fall thru */
439 case EXCEPTION_BREAKPOINT:
440 gdbctx->last_sig = SIGTRAP;
441 ret = TRUE;
442 break;
443 case EXCEPTION_FLT_DENORMAL_OPERAND:
444 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
445 case EXCEPTION_FLT_INEXACT_RESULT:
446 case EXCEPTION_FLT_INVALID_OPERATION:
447 case EXCEPTION_FLT_OVERFLOW:
448 case EXCEPTION_FLT_STACK_CHECK:
449 case EXCEPTION_FLT_UNDERFLOW:
450 gdbctx->last_sig = SIGFPE;
451 ret = TRUE;
452 break;
453 case EXCEPTION_INT_DIVIDE_BY_ZERO:
454 case EXCEPTION_INT_OVERFLOW:
455 gdbctx->last_sig = SIGFPE;
456 ret = TRUE;
457 break;
458 case EXCEPTION_ILLEGAL_INSTRUCTION:
459 gdbctx->last_sig = SIGILL;
460 ret = TRUE;
461 break;
462 case CONTROL_C_EXIT:
463 gdbctx->last_sig = SIGINT;
464 ret = TRUE;
465 break;
466 case STATUS_POSSIBLE_DEADLOCK:
467 gdbctx->last_sig = SIGALRM;
468 ret = TRUE;
469 /* FIXME: we could also add here a O packet with additional information */
470 break;
471 default:
472 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
473 fprintf(stderr, "Unhandled exception code 0x%08x\n", rec->ExceptionCode);
474 gdbctx->last_sig = SIGABRT;
475 ret = TRUE;
476 break;
477 }
478 return ret;
479 }
480
481 static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
482 {
483 char buffer[256];
484
485 dbg_curr_thread = dbg_get_thread(gdbctx->process, de->dwThreadId);
486
487 switch (de->dwDebugEventCode)
488 {
489 case CREATE_PROCESS_DEBUG_EVENT:
490 gdbctx->process = dbg_add_process(&be_process_gdbproxy_io, de->dwProcessId,
491 de->u.CreateProcessInfo.hProcess);
492 if (!gdbctx->process) break;
493 memory_get_string_indirect(gdbctx->process,
494 de->u.CreateProcessInfo.lpImageName,
495 de->u.CreateProcessInfo.fUnicode,
496 buffer, sizeof(buffer));
497 dbg_set_process_name(gdbctx->process, buffer);
498
499 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
500 fprintf(stderr, "%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n",
501 de->dwProcessId, de->dwThreadId,
502 buffer, de->u.CreateProcessInfo.lpImageName,
503 de->u.CreateProcessInfo.lpStartAddress,
504 de->u.CreateProcessInfo.dwDebugInfoFileOffset,
505 de->u.CreateProcessInfo.nDebugInfoSize);
506
507 /* de->u.CreateProcessInfo.lpStartAddress; */
508 if (!SymInitialize(gdbctx->process->handle, NULL, TRUE))
509 fprintf(stderr, "Couldn't initiate DbgHelp\n");
510
511 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
512 fprintf(stderr, "%04x:%04x: create thread I @%p\n",
513 de->dwProcessId, de->dwThreadId,
514 de->u.CreateProcessInfo.lpStartAddress);
515
516 assert(dbg_curr_thread == NULL); /* shouldn't be there */
517 dbg_add_thread(gdbctx->process, de->dwThreadId,
518 de->u.CreateProcessInfo.hThread,
519 de->u.CreateProcessInfo.lpThreadLocalBase);
520 break;
521
522 case LOAD_DLL_DEBUG_EVENT:
523 assert(dbg_curr_thread);
524 memory_get_string_indirect(gdbctx->process,
525 de->u.LoadDll.lpImageName,
526 de->u.LoadDll.fUnicode,
527 buffer, sizeof(buffer));
528 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
529 fprintf(stderr, "%04x:%04x: loads DLL %s @%p (%u<%u>)\n",
530 de->dwProcessId, de->dwThreadId,
531 buffer, de->u.LoadDll.lpBaseOfDll,
532 de->u.LoadDll.dwDebugInfoFileOffset,
533 de->u.LoadDll.nDebugInfoSize);
534 SymLoadModule(gdbctx->process->handle, de->u.LoadDll.hFile, buffer, NULL,
535 (unsigned long)de->u.LoadDll.lpBaseOfDll, 0);
536 break;
537
538 case UNLOAD_DLL_DEBUG_EVENT:
539 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
540 fprintf(stderr, "%08x:%08x: unload DLL @%p\n",
541 de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll);
542 SymUnloadModule(gdbctx->process->handle,
543 (unsigned long)de->u.UnloadDll.lpBaseOfDll);
544 break;
545
546 case EXCEPTION_DEBUG_EVENT:
547 assert(dbg_curr_thread);
548 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
549 fprintf(stderr, "%08x:%08x: exception code=0x%08x\n",
550 de->dwProcessId, de->dwThreadId,
551 de->u.Exception.ExceptionRecord.ExceptionCode);
552
553 if (fetch_context(gdbctx, dbg_curr_thread->handle, &gdbctx->context))
554 {
555 gdbctx->in_trap = handle_exception(gdbctx, &de->u.Exception);
556 }
557 break;
558
559 case CREATE_THREAD_DEBUG_EVENT:
560 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
561 fprintf(stderr, "%08x:%08x: create thread D @%p\n",
562 de->dwProcessId, de->dwThreadId, de->u.CreateThread.lpStartAddress);
563
564 dbg_add_thread(gdbctx->process,
565 de->dwThreadId,
566 de->u.CreateThread.hThread,
567 de->u.CreateThread.lpThreadLocalBase);
568 break;
569
570 case EXIT_THREAD_DEBUG_EVENT:
571 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
572 fprintf(stderr, "%08x:%08x: exit thread (%u)\n",
573 de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
574
575 assert(dbg_curr_thread);
576 if (dbg_curr_thread == gdbctx->exec_thread) gdbctx->exec_thread = NULL;
577 if (dbg_curr_thread == gdbctx->other_thread) gdbctx->other_thread = NULL;
578 dbg_del_thread(dbg_curr_thread);
579 break;
580
581 case EXIT_PROCESS_DEBUG_EVENT:
582 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
583 fprintf(stderr, "%08x:%08x: exit process (%u)\n",
584 de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode);
585
586 dbg_del_process(gdbctx->process);
587 gdbctx->process = NULL;
588 /* now signal gdb that we're done */
589 gdbctx->last_sig = SIGTERM;
590 gdbctx->in_trap = TRUE;
591 break;
592
593 case OUTPUT_DEBUG_STRING_EVENT:
594 assert(dbg_curr_thread);
595 memory_get_string(gdbctx->process,
596 de->u.DebugString.lpDebugStringData, TRUE,
597 de->u.DebugString.fUnicode, buffer, sizeof(buffer));
598 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
599 fprintf(stderr, "%08x:%08x: output debug string (%s)\n",
600 de->dwProcessId, de->dwThreadId, buffer);
601 break;
602
603 case RIP_EVENT:
604 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
605 fprintf(stderr, "%08x:%08x: rip error=%u type=%u\n",
606 de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError,
607 de->u.RipInfo.dwType);
608 break;
609
610 default:
611 if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
612 fprintf(stderr, "%08x:%08x: unknown event (%u)\n",
613 de->dwProcessId, de->dwThreadId, de->dwDebugEventCode);
614 }
615 }
616
617 static void resume_debuggee(struct gdb_context* gdbctx, DWORD cont)
618 {
619 if (dbg_curr_thread)
620 {
621 if (!SetThreadContext(dbg_curr_thread->handle, &gdbctx->context))
622 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
623 fprintf(stderr, "Cannot set context on thread %04x\n", dbg_curr_thread->tid);
624 if (!ContinueDebugEvent(gdbctx->process->pid, dbg_curr_thread->tid, cont))
625 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
626 fprintf(stderr, "Cannot continue on %04x (%x)\n",
627 dbg_curr_thread->tid, cont);
628 }
629 else if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
630 fprintf(stderr, "Cannot find last thread\n");
631 }
632
633
634 static void resume_debuggee_thread(struct gdb_context* gdbctx, DWORD cont, unsigned int threadid)
635 {
636
637 if (dbg_curr_thread)
638 {
639 if(dbg_curr_thread->tid == threadid){
640 /* Windows debug and GDB don't seem to work well here, windows only likes ContinueDebugEvent being used on the reporter of the event */
641 if (!SetThreadContext(dbg_curr_thread->handle, &gdbctx->context))
642 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
643 fprintf(stderr, "Cannot set context on thread %04x\n", dbg_curr_thread->tid);
644 if (!ContinueDebugEvent(gdbctx->process->pid, dbg_curr_thread->tid, cont))
645 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
646 fprintf(stderr, "Cannot continue on %04x (%x)\n",
647 dbg_curr_thread->tid, cont);
648 }
649 }
650 else if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR)
651 fprintf(stderr, "Cannot find last thread\n");
652 }
653
654 static BOOL check_for_interrupt(struct gdb_context* gdbctx)
655 {
656 struct pollfd pollfd;
657 int ret;
658 char pkt;
659
660 pollfd.fd = gdbctx->sock;
661 pollfd.events = POLLIN;
662 pollfd.revents = 0;
663
664 if ((ret = poll(&pollfd, 1, 0)) == 1) {
665 ret = read(gdbctx->sock, &pkt, 1);
666 if (ret != 1) {
667 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR) {
668 fprintf(stderr, "read failed\n");
669 }
670 return FALSE;
671 }
672 if (pkt != '\003') {
673 if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR) {
674 fprintf(stderr, "Unexpected break packet (%c/0x%X)\n", pkt, pkt);
675 }
676 return FALSE;
677 }
678 return TRUE;
679 } else if (ret == -1) {
680 fprintf(stderr, "poll failed\n");
681 }
682 return FALSE;
683 }
684
685 static void wait_for_debuggee(struct gdb_context* gdbctx)
686 {
687 DEBUG_EVENT de;
688
689 gdbctx->in_trap = FALSE;
690 for (;;)
691 {
692 if (!WaitForDebugEvent(&de, 10))
693 {
694 if (GetLastError() == ERROR_SEM_TIMEOUT)
695 {
696 if (check_for_interrupt(gdbctx)) {
697 if (!DebugBreakProcess(gdbctx->process->handle)) {
698 if (gdbctx->trace & GDBPXY_TRC_WIN32_ERROR) {
699 fprintf(stderr, "Failed to break into debugee\n");
700 }
701 break;
702 }
703 WaitForDebugEvent(&de, INFINITE);
704 } else {
705 continue;
706 }
707 } else {
708 break;
709 }
710 }
711 handle_debug_event(gdbctx, &de);
712 assert(!gdbctx->process ||
713 gdbctx->process->pid == 0 ||
714 de.dwProcessId == gdbctx->process->pid);
715 assert(!dbg_curr_thread || de.dwThreadId == dbg_curr_thread->tid);
716 if (gdbctx->in_trap) break;
717 ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
718 }
719 }
720
721 static void detach_debuggee(struct gdb_context* gdbctx, BOOL kill)
722 {
723 be_cpu->single_step(&gdbctx->context, FALSE);
724 resume_debuggee(gdbctx, DBG_CONTINUE);
725 if (!kill)
726 DebugActiveProcessStop(gdbctx->process->pid);
727 dbg_del_process(gdbctx->process);
728 gdbctx->process = NULL;
729 }
730
731 static void get_process_info(struct gdb_context* gdbctx, char* buffer, size_t len)
732 {
733 DWORD status;
734
735 if (!GetExitCodeProcess(gdbctx->process->handle, &status))
736 {
737 strcpy(buffer, "Unknown process");
738 return;
739 }
740 if (status == STILL_ACTIVE)
741 {
742 strcpy(buffer, "Running");
743 }
744 else
745 snprintf(buffer, len, "Terminated (%u)", status);
746
747 switch (GetPriorityClass(gdbctx->process->handle))
748 {
749 case 0: break;
750 #ifdef ABOVE_NORMAL_PRIORITY_CLASS
751 case ABOVE_NORMAL_PRIORITY_CLASS: strcat(buffer, ", above normal priority"); break;
752 #endif
753 #ifdef BELOW_NORMAL_PRIORITY_CLASS
754 case BELOW_NORMAL_PRIORITY_CLASS: strcat(buffer, ", below normal priotity"); break;
755 #endif
756 case HIGH_PRIORITY_CLASS: strcat(buffer, ", high priority"); break;
757 case IDLE_PRIORITY_CLASS: strcat(buffer, ", idle priority"); break;
758 case NORMAL_PRIORITY_CLASS: strcat(buffer, ", normal priority"); break;
759 case REALTIME_PRIORITY_CLASS: strcat(buffer, ", realtime priority"); break;
760 }
761 strcat(buffer, "\n");
762 }
763
764 static void get_thread_info(struct gdb_context* gdbctx, unsigned tid,
765 char* buffer, size_t len)
766 {
767 struct dbg_thread* thd;
768 DWORD status;
769 int prio;
770
771 /* FIXME: use the size of buffer */
772 thd = dbg_get_thread(gdbctx->process, tid);
773 if (thd == NULL)
774 {
775 strcpy(buffer, "No information");
776 return;
777 }
778 if (GetExitCodeThread(thd->handle, &status))
779 {
780 if (status == STILL_ACTIVE)
781 {
782 /* FIXME: this is a bit brutal... some nicer way shall be found */
783 switch (status = SuspendThread(thd->handle))
784 {
785 case -1: break;
786 case 0: strcpy(buffer, "Running"); break;
787 default: snprintf(buffer, len, "Suspended (%u)", status - 1);
788 }
789 ResumeThread(thd->handle);
790 }
791 else
792 snprintf(buffer, len, "Terminated (exit code = %u)", status);
793 }
794 else
795 {
796 strcpy(buffer, "Unknown threadID");
797 }
798 switch (prio = GetThreadPriority(thd->handle))
799 {
800 case THREAD_PRIORITY_ERROR_RETURN: break;
801 case THREAD_PRIORITY_ABOVE_NORMAL: strcat(buffer, ", priority +1 above normal"); break;
802 case THREAD_PRIORITY_BELOW_NORMAL: strcat(buffer, ", priority -1 below normal"); break;
803 case THREAD_PRIORITY_HIGHEST: strcat(buffer, ", priority +2 above normal"); break;
804 case THREAD_PRIORITY_LOWEST: strcat(buffer, ", priority -2 below normal"); break;
805 case THREAD_PRIORITY_IDLE: strcat(buffer, ", priority idle"); break;
806 case THREAD_PRIORITY_NORMAL: strcat(buffer, ", priority normal"); break;
807 case THREAD_PRIORITY_TIME_CRITICAL: strcat(buffer, ", priority time-critical"); break;
808 default: snprintf(buffer + strlen(buffer), len - strlen(buffer), ", priority = %d", prio);
809 }
810 assert(strlen(buffer) < len);
811 }
812
813 /* =============================================== *
814 * P A C K E T U T I L S *
815 * =============================================== *
816 */
817
818 enum packet_return {packet_error = 0x00, packet_ok = 0x01, packet_done = 0x02,
819 packet_last_f = 0x80};
820
821 static void packet_reply_grow(struct gdb_context* gdbctx, size_t size)
822 {
823 if (gdbctx->out_buf_alloc < gdbctx->out_len + size)
824 {
825 gdbctx->out_buf_alloc = ((gdbctx->out_len + size) / 32 + 1) * 32;
826 gdbctx->out_buf = realloc(gdbctx->out_buf, gdbctx->out_buf_alloc);
827 }
828 }
829
830 static void packet_reply_hex_to(struct gdb_context* gdbctx, const void* src, int len)
831 {
832 packet_reply_grow(gdbctx, len * 2);
833 hex_to(&gdbctx->out_buf[gdbctx->out_len], src, len);
834 gdbctx->out_len += len * 2;
835 }
836
837 static inline void packet_reply_hex_to_str(struct gdb_context* gdbctx, const char* src)
838 {
839 packet_reply_hex_to(gdbctx, src, strlen(src));
840 }
841
842 static void packet_reply_val(struct gdb_context* gdbctx, unsigned long val, int len)
843 {
844 int i, shift;
845
846 shift = (len - 1) * 8;
847 packet_reply_grow(gdbctx, len * 2);
848 for (i = 0; i < len; i++, shift -= 8)
849 {
850 gdbctx->out_buf[gdbctx->out_len++] = hex_to0((val >> (shift + 4)) & 0x0F);
851 gdbctx->out_buf[gdbctx->out_len++] = hex_to0((val >> shift ) & 0x0F);
852 }
853 }
854
855 static inline void packet_reply_add(struct gdb_context* gdbctx, const char* str, int len)
856 {
857 packet_reply_grow(gdbctx, len);
858 memcpy(&gdbctx->out_buf[gdbctx->out_len], str, len);
859 gdbctx->out_len += len;
860 }
861
862 static inline void packet_reply_cat(struct gdb_context* gdbctx, const char* str)
863 {
864 packet_reply_add(gdbctx, str, strlen(str));
865 }
866
867 static inline void