blob: 023572001919b937ad108b63417cbc6ff8fa3350 [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001/*
2 * gdb server stub
3 *
4 * Copyright (c) 2003-2005 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
David 'Digit' Turner92518662010-05-10 23:26:01 -070017 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080018 */
19#include "config.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070020#include "qemu-common.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080021#ifdef CONFIG_USER_ONLY
22#include <stdlib.h>
23#include <stdio.h>
24#include <stdarg.h>
25#include <string.h>
26#include <errno.h>
27#include <unistd.h>
28#include <fcntl.h>
29
30#include "qemu.h"
31#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070032#include "monitor.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080033#include "qemu-char.h"
34#include "sysemu.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080035#include "gdbstub.h"
36#endif
37
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070038#define MAX_PACKET_LENGTH 4096
39
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080040#include "qemu_socket.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070041#include "kvm.h"
42
43
44enum {
45 GDB_SIGNAL_0 = 0,
46 GDB_SIGNAL_INT = 2,
47 GDB_SIGNAL_TRAP = 5,
48 GDB_SIGNAL_UNKNOWN = 143
49};
50
51#ifdef CONFIG_USER_ONLY
52
53/* Map target signal numbers to GDB protocol signal numbers and vice
54 * versa. For user emulation's currently supported systems, we can
55 * assume most signals are defined.
56 */
57
58static int gdb_signal_table[] = {
59 0,
60 TARGET_SIGHUP,
61 TARGET_SIGINT,
62 TARGET_SIGQUIT,
63 TARGET_SIGILL,
64 TARGET_SIGTRAP,
65 TARGET_SIGABRT,
66 -1, /* SIGEMT */
67 TARGET_SIGFPE,
68 TARGET_SIGKILL,
69 TARGET_SIGBUS,
70 TARGET_SIGSEGV,
71 TARGET_SIGSYS,
72 TARGET_SIGPIPE,
73 TARGET_SIGALRM,
74 TARGET_SIGTERM,
75 TARGET_SIGURG,
76 TARGET_SIGSTOP,
77 TARGET_SIGTSTP,
78 TARGET_SIGCONT,
79 TARGET_SIGCHLD,
80 TARGET_SIGTTIN,
81 TARGET_SIGTTOU,
82 TARGET_SIGIO,
83 TARGET_SIGXCPU,
84 TARGET_SIGXFSZ,
85 TARGET_SIGVTALRM,
86 TARGET_SIGPROF,
87 TARGET_SIGWINCH,
88 -1, /* SIGLOST */
89 TARGET_SIGUSR1,
90 TARGET_SIGUSR2,
91#ifdef TARGET_SIGPWR
92 TARGET_SIGPWR,
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080093#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070094 -1,
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080095#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070096 -1, /* SIGPOLL */
97 -1,
98 -1,
99 -1,
100 -1,
101 -1,
102 -1,
103 -1,
104 -1,
105 -1,
106 -1,
107 -1,
108#ifdef __SIGRTMIN
109 __SIGRTMIN + 1,
110 __SIGRTMIN + 2,
111 __SIGRTMIN + 3,
112 __SIGRTMIN + 4,
113 __SIGRTMIN + 5,
114 __SIGRTMIN + 6,
115 __SIGRTMIN + 7,
116 __SIGRTMIN + 8,
117 __SIGRTMIN + 9,
118 __SIGRTMIN + 10,
119 __SIGRTMIN + 11,
120 __SIGRTMIN + 12,
121 __SIGRTMIN + 13,
122 __SIGRTMIN + 14,
123 __SIGRTMIN + 15,
124 __SIGRTMIN + 16,
125 __SIGRTMIN + 17,
126 __SIGRTMIN + 18,
127 __SIGRTMIN + 19,
128 __SIGRTMIN + 20,
129 __SIGRTMIN + 21,
130 __SIGRTMIN + 22,
131 __SIGRTMIN + 23,
132 __SIGRTMIN + 24,
133 __SIGRTMIN + 25,
134 __SIGRTMIN + 26,
135 __SIGRTMIN + 27,
136 __SIGRTMIN + 28,
137 __SIGRTMIN + 29,
138 __SIGRTMIN + 30,
139 __SIGRTMIN + 31,
140 -1, /* SIGCANCEL */
141 __SIGRTMIN,
142 __SIGRTMIN + 32,
143 __SIGRTMIN + 33,
144 __SIGRTMIN + 34,
145 __SIGRTMIN + 35,
146 __SIGRTMIN + 36,
147 __SIGRTMIN + 37,
148 __SIGRTMIN + 38,
149 __SIGRTMIN + 39,
150 __SIGRTMIN + 40,
151 __SIGRTMIN + 41,
152 __SIGRTMIN + 42,
153 __SIGRTMIN + 43,
154 __SIGRTMIN + 44,
155 __SIGRTMIN + 45,
156 __SIGRTMIN + 46,
157 __SIGRTMIN + 47,
158 __SIGRTMIN + 48,
159 __SIGRTMIN + 49,
160 __SIGRTMIN + 50,
161 __SIGRTMIN + 51,
162 __SIGRTMIN + 52,
163 __SIGRTMIN + 53,
164 __SIGRTMIN + 54,
165 __SIGRTMIN + 55,
166 __SIGRTMIN + 56,
167 __SIGRTMIN + 57,
168 __SIGRTMIN + 58,
169 __SIGRTMIN + 59,
170 __SIGRTMIN + 60,
171 __SIGRTMIN + 61,
172 __SIGRTMIN + 62,
173 __SIGRTMIN + 63,
174 __SIGRTMIN + 64,
175 __SIGRTMIN + 65,
176 __SIGRTMIN + 66,
177 __SIGRTMIN + 67,
178 __SIGRTMIN + 68,
179 __SIGRTMIN + 69,
180 __SIGRTMIN + 70,
181 __SIGRTMIN + 71,
182 __SIGRTMIN + 72,
183 __SIGRTMIN + 73,
184 __SIGRTMIN + 74,
185 __SIGRTMIN + 75,
186 __SIGRTMIN + 76,
187 __SIGRTMIN + 77,
188 __SIGRTMIN + 78,
189 __SIGRTMIN + 79,
190 __SIGRTMIN + 80,
191 __SIGRTMIN + 81,
192 __SIGRTMIN + 82,
193 __SIGRTMIN + 83,
194 __SIGRTMIN + 84,
195 __SIGRTMIN + 85,
196 __SIGRTMIN + 86,
197 __SIGRTMIN + 87,
198 __SIGRTMIN + 88,
199 __SIGRTMIN + 89,
200 __SIGRTMIN + 90,
201 __SIGRTMIN + 91,
202 __SIGRTMIN + 92,
203 __SIGRTMIN + 93,
204 __SIGRTMIN + 94,
205 __SIGRTMIN + 95,
206 -1, /* SIGINFO */
207 -1, /* UNKNOWN */
208 -1, /* DEFAULT */
209 -1,
210 -1,
211 -1,
212 -1,
213 -1,
214 -1
215#endif
216};
217#else
218/* In system mode we only need SIGINT and SIGTRAP; other signals
219 are not yet supported. */
220
221enum {
222 TARGET_SIGINT = 2,
223 TARGET_SIGTRAP = 5
224};
225
226static int gdb_signal_table[] = {
227 -1,
228 -1,
229 TARGET_SIGINT,
230 -1,
231 -1,
232 TARGET_SIGTRAP
233};
234#endif
235
236#ifdef CONFIG_USER_ONLY
237static int target_signal_to_gdb (int sig)
238{
239 int i;
240 for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
241 if (gdb_signal_table[i] == sig)
242 return i;
243 return GDB_SIGNAL_UNKNOWN;
244}
245#endif
246
247static int gdb_signal_to_target (int sig)
248{
249 if (sig < ARRAY_SIZE (gdb_signal_table))
250 return gdb_signal_table[sig];
251 else
252 return -1;
253}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800254
255//#define DEBUG_GDB
256
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700257typedef struct GDBRegisterState {
258 int base_reg;
259 int num_regs;
260 gdb_reg_cb get_reg;
261 gdb_reg_cb set_reg;
262 const char *xml;
263 struct GDBRegisterState *next;
264} GDBRegisterState;
265
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800266enum RSState {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700267 RS_INACTIVE,
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800268 RS_IDLE,
269 RS_GETLINE,
270 RS_CHKSUM1,
271 RS_CHKSUM2,
272 RS_SYSCALL,
273};
274typedef struct GDBState {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700275 CPUState *c_cpu; /* current CPU for step/continue ops */
276 CPUState *g_cpu; /* current CPU for other ops */
277 CPUState *query_cpu; /* for q{f|s}ThreadInfo */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800278 enum RSState state; /* parsing state */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700279 char line_buf[MAX_PACKET_LENGTH];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800280 int line_buf_index;
281 int line_csum;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700282 uint8_t last_packet[MAX_PACKET_LENGTH + 4];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800283 int last_packet_len;
284 int signal;
285#ifdef CONFIG_USER_ONLY
286 int fd;
287 int running_state;
288#else
289 CharDriverState *chr;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700290 CharDriverState *mon_chr;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800291#endif
292} GDBState;
293
294/* By default use no IRQs and no timers while single stepping so as to
295 * make single stepping like an ICE HW step.
296 */
297static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
298
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700299static GDBState *gdbserver_state;
300
301/* This is an ugly hack to cope with both new and old gdb.
302 If gdb sends qXfer:features:read then assume we're talking to a newish
303 gdb that understands target descriptions. */
304static int gdb_has_xml;
305
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800306#ifdef CONFIG_USER_ONLY
307/* XXX: This is not thread safe. Do we care? */
308static int gdbserver_fd = -1;
309
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800310static int get_char(GDBState *s)
311{
312 uint8_t ch;
313 int ret;
314
315 for(;;) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700316 ret = recv(s->fd, &ch, 1, 0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800317 if (ret < 0) {
318 if (errno == ECONNRESET)
319 s->fd = -1;
320 if (errno != EINTR && errno != EAGAIN)
321 return -1;
322 } else if (ret == 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700323 close(s->fd);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800324 s->fd = -1;
325 return -1;
326 } else {
327 break;
328 }
329 }
330 return ch;
331}
332#endif
333
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800334static gdb_syscall_complete_cb gdb_current_syscall_cb;
335
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700336static enum {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800337 GDB_SYS_UNKNOWN,
338 GDB_SYS_ENABLED,
339 GDB_SYS_DISABLED,
340} gdb_syscall_mode;
341
342/* If gdb is connected when the first semihosting syscall occurs then use
343 remote gdb syscalls. Otherwise use native file IO. */
344int use_gdb_syscalls(void)
345{
346 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700347 gdb_syscall_mode = (gdbserver_state ? GDB_SYS_ENABLED
348 : GDB_SYS_DISABLED);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800349 }
350 return gdb_syscall_mode == GDB_SYS_ENABLED;
351}
352
353/* Resume execution. */
354static inline void gdb_continue(GDBState *s)
355{
356#ifdef CONFIG_USER_ONLY
357 s->running_state = 1;
358#else
359 vm_start();
360#endif
361}
362
363static void put_buffer(GDBState *s, const uint8_t *buf, int len)
364{
365#ifdef CONFIG_USER_ONLY
366 int ret;
367
368 while (len > 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700369 ret = send(s->fd, buf, len, 0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800370 if (ret < 0) {
371 if (errno != EINTR && errno != EAGAIN)
372 return;
373 } else {
374 buf += ret;
375 len -= ret;
376 }
377 }
378#else
379 qemu_chr_write(s->chr, buf, len);
380#endif
381}
382
383static inline int fromhex(int v)
384{
385 if (v >= '0' && v <= '9')
386 return v - '0';
387 else if (v >= 'A' && v <= 'F')
388 return v - 'A' + 10;
389 else if (v >= 'a' && v <= 'f')
390 return v - 'a' + 10;
391 else
392 return 0;
393}
394
395static inline int tohex(int v)
396{
397 if (v < 10)
398 return v + '0';
399 else
400 return v - 10 + 'a';
401}
402
403static void memtohex(char *buf, const uint8_t *mem, int len)
404{
405 int i, c;
406 char *q;
407 q = buf;
408 for(i = 0; i < len; i++) {
409 c = mem[i];
410 *q++ = tohex(c >> 4);
411 *q++ = tohex(c & 0xf);
412 }
413 *q = '\0';
414}
415
416static void hextomem(uint8_t *mem, const char *buf, int len)
417{
418 int i;
419
420 for(i = 0; i < len; i++) {
421 mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
422 buf += 2;
423 }
424}
425
426/* return -1 if error, 0 if OK */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700427static int put_packet_binary(GDBState *s, const char *buf, int len)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800428{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700429 int csum, i;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800430 uint8_t *p;
431
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800432 for(;;) {
433 p = s->last_packet;
434 *(p++) = '$';
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800435 memcpy(p, buf, len);
436 p += len;
437 csum = 0;
438 for(i = 0; i < len; i++) {
439 csum += buf[i];
440 }
441 *(p++) = '#';
442 *(p++) = tohex((csum >> 4) & 0xf);
443 *(p++) = tohex((csum) & 0xf);
444
445 s->last_packet_len = p - s->last_packet;
446 put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
447
448#ifdef CONFIG_USER_ONLY
449 i = get_char(s);
450 if (i < 0)
451 return -1;
452 if (i == '+')
453 break;
454#else
455 break;
456#endif
457 }
458 return 0;
459}
460
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700461/* return -1 if error, 0 if OK */
462static int put_packet(GDBState *s, const char *buf)
463{
464#ifdef DEBUG_GDB
465 printf("reply='%s'\n", buf);
466#endif
467
468 return put_packet_binary(s, buf, strlen(buf));
469}
470
471/* The GDB remote protocol transfers values in target byte order. This means
472 we can use the raw memory access routines to access the value buffer.
473 Conveniently, these also handle the case where the buffer is mis-aligned.
474 */
475#define GET_REG8(val) do { \
476 stb_p(mem_buf, val); \
477 return 1; \
478 } while(0)
479#define GET_REG16(val) do { \
480 stw_p(mem_buf, val); \
481 return 2; \
482 } while(0)
483#define GET_REG32(val) do { \
484 stl_p(mem_buf, val); \
485 return 4; \
486 } while(0)
487#define GET_REG64(val) do { \
488 stq_p(mem_buf, val); \
489 return 8; \
490 } while(0)
491
492#if TARGET_LONG_BITS == 64
493#define GET_REGL(val) GET_REG64(val)
494#define ldtul_p(addr) ldq_p(addr)
495#else
496#define GET_REGL(val) GET_REG32(val)
497#define ldtul_p(addr) ldl_p(addr)
498#endif
499
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800500#if defined(TARGET_I386)
501
502#ifdef TARGET_X86_64
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700503static const int gpr_map[16] = {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800504 R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP,
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700505 8, 9, 10, 11, 12, 13, 14, 15
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800506};
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800507#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700508static const int gpr_map[8] = {0, 1, 2, 3, 4, 5, 6, 7};
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800509#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700510
511#define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25)
512
513static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
514{
515 if (n < CPU_NB_REGS) {
516 GET_REGL(env->regs[gpr_map[n]]);
517 } else if (n >= CPU_NB_REGS + 8 && n < CPU_NB_REGS + 16) {
518 /* FIXME: byteswap float values. */
519#ifdef USE_X86LDOUBLE
520 memcpy(mem_buf, &env->fpregs[n - (CPU_NB_REGS + 8)], 10);
521#else
522 memset(mem_buf, 0, 10);
523#endif
524 return 10;
525 } else if (n >= CPU_NB_REGS + 24) {
526 n -= CPU_NB_REGS + 24;
527 if (n < CPU_NB_REGS) {
528 stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0));
529 stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1));
530 return 16;
531 } else if (n == CPU_NB_REGS) {
532 GET_REG32(env->mxcsr);
533 }
534 } else {
535 n -= CPU_NB_REGS;
536 switch (n) {
537 case 0: GET_REGL(env->eip);
538 case 1: GET_REG32(env->eflags);
539 case 2: GET_REG32(env->segs[R_CS].selector);
540 case 3: GET_REG32(env->segs[R_SS].selector);
541 case 4: GET_REG32(env->segs[R_DS].selector);
542 case 5: GET_REG32(env->segs[R_ES].selector);
543 case 6: GET_REG32(env->segs[R_FS].selector);
544 case 7: GET_REG32(env->segs[R_GS].selector);
545 /* 8...15 x87 regs. */
546 case 16: GET_REG32(env->fpuc);
547 case 17: GET_REG32((env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11);
548 case 18: GET_REG32(0); /* ftag */
549 case 19: GET_REG32(0); /* fiseg */
550 case 20: GET_REG32(0); /* fioff */
551 case 21: GET_REG32(0); /* foseg */
552 case 22: GET_REG32(0); /* fooff */
553 case 23: GET_REG32(0); /* fop */
554 /* 24+ xmm regs. */
555 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800556 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700557 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800558}
559
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700560static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int i)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800561{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700562 uint32_t tmp;
563
564 if (i < CPU_NB_REGS) {
565 env->regs[gpr_map[i]] = ldtul_p(mem_buf);
566 return sizeof(target_ulong);
567 } else if (i >= CPU_NB_REGS + 8 && i < CPU_NB_REGS + 16) {
568 i -= CPU_NB_REGS + 8;
569#ifdef USE_X86LDOUBLE
570 memcpy(&env->fpregs[i], mem_buf, 10);
571#endif
572 return 10;
573 } else if (i >= CPU_NB_REGS + 24) {
574 i -= CPU_NB_REGS + 24;
575 if (i < CPU_NB_REGS) {
576 env->xmm_regs[i].XMM_Q(0) = ldq_p(mem_buf);
577 env->xmm_regs[i].XMM_Q(1) = ldq_p(mem_buf + 8);
578 return 16;
579 } else if (i == CPU_NB_REGS) {
580 env->mxcsr = ldl_p(mem_buf);
581 return 4;
582 }
583 } else {
584 i -= CPU_NB_REGS;
585 switch (i) {
586 case 0: env->eip = ldtul_p(mem_buf); return sizeof(target_ulong);
587 case 1: env->eflags = ldl_p(mem_buf); return 4;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800588#if defined(CONFIG_USER_ONLY)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700589#define LOAD_SEG(index, sreg)\
590 tmp = ldl_p(mem_buf);\
591 if (tmp != env->segs[sreg].selector)\
592 cpu_x86_load_seg(env, sreg, tmp);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800593#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700594/* FIXME: Honor segment registers. Needs to avoid raising an exception
595 when the selector is invalid. */
596#define LOAD_SEG(index, sreg) do {} while(0)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800597#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700598 case 2: LOAD_SEG(10, R_CS); return 4;
599 case 3: LOAD_SEG(11, R_SS); return 4;
600 case 4: LOAD_SEG(12, R_DS); return 4;
601 case 5: LOAD_SEG(13, R_ES); return 4;
602 case 6: LOAD_SEG(14, R_FS); return 4;
603 case 7: LOAD_SEG(15, R_GS); return 4;
604 /* 8...15 x87 regs. */
605 case 16: env->fpuc = ldl_p(mem_buf); return 4;
606 case 17:
607 tmp = ldl_p(mem_buf);
608 env->fpstt = (tmp >> 11) & 7;
609 env->fpus = tmp & ~0x3800;
610 return 4;
611 case 18: /* ftag */ return 4;
612 case 19: /* fiseg */ return 4;
613 case 20: /* fioff */ return 4;
614 case 21: /* foseg */ return 4;
615 case 22: /* fooff */ return 4;
616 case 23: /* fop */ return 4;
617 /* 24+ xmm regs. */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800618 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800619 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700620 /* Unrecognised register. */
621 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800622}
623
624#elif defined (TARGET_PPC)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700625
626/* Old gdb always expects FP registers. Newer (xml-aware) gdb only
627 expects whatever the target description contains. Due to a
628 historical mishap the FP registers appear in between core integer
629 regs and PC, MSR, CR, and so forth. We hack round this by giving the
630 FP regs zero size when talking to a newer gdb. */
631#define NUM_CORE_REGS 71
632#if defined (TARGET_PPC64)
633#define GDB_CORE_XML "power64-core.xml"
634#else
635#define GDB_CORE_XML "power-core.xml"
636#endif
637
638static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800639{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700640 if (n < 32) {
641 /* gprs */
642 GET_REGL(env->gpr[n]);
643 } else if (n < 64) {
644 /* fprs */
645 if (gdb_has_xml)
646 return 0;
647 stfq_p(mem_buf, env->fpr[n-32]);
648 return 8;
649 } else {
650 switch (n) {
651 case 64: GET_REGL(env->nip);
652 case 65: GET_REGL(env->msr);
653 case 66:
654 {
655 uint32_t cr = 0;
656 int i;
657 for (i = 0; i < 8; i++)
658 cr |= env->crf[i] << (32 - ((i + 1) * 4));
659 GET_REG32(cr);
660 }
661 case 67: GET_REGL(env->lr);
662 case 68: GET_REGL(env->ctr);
663 case 69: GET_REGL(env->xer);
664 case 70:
665 {
666 if (gdb_has_xml)
667 return 0;
668 GET_REG32(0); /* fpscr */
669 }
670 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800671 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700672 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800673}
674
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700675static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800676{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700677 if (n < 32) {
678 /* gprs */
679 env->gpr[n] = ldtul_p(mem_buf);
680 return sizeof(target_ulong);
681 } else if (n < 64) {
682 /* fprs */
683 if (gdb_has_xml)
684 return 0;
685 env->fpr[n-32] = ldfq_p(mem_buf);
686 return 8;
687 } else {
688 switch (n) {
689 case 64:
690 env->nip = ldtul_p(mem_buf);
691 return sizeof(target_ulong);
692 case 65:
693 ppc_store_msr(env, ldtul_p(mem_buf));
694 return sizeof(target_ulong);
695 case 66:
696 {
697 uint32_t cr = ldl_p(mem_buf);
698 int i;
699 for (i = 0; i < 8; i++)
700 env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
701 return 4;
702 }
703 case 67:
704 env->lr = ldtul_p(mem_buf);
705 return sizeof(target_ulong);
706 case 68:
707 env->ctr = ldtul_p(mem_buf);
708 return sizeof(target_ulong);
709 case 69:
710 env->xer = ldtul_p(mem_buf);
711 return sizeof(target_ulong);
712 case 70:
713 /* fpscr */
714 if (gdb_has_xml)
715 return 0;
716 return 4;
717 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800718 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700719 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800720}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700721
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800722#elif defined (TARGET_SPARC)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800723
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700724#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
725#define NUM_CORE_REGS 86
726#else
727#define NUM_CORE_REGS 72
728#endif
729
730#ifdef TARGET_ABI32
731#define GET_REGA(val) GET_REG32(val)
732#else
733#define GET_REGA(val) GET_REGL(val)
734#endif
735
736static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
737{
738 if (n < 8) {
739 /* g0..g7 */
740 GET_REGA(env->gregs[n]);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800741 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700742 if (n < 32) {
743 /* register window */
744 GET_REGA(env->regwptr[n - 8]);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800745 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700746#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
747 if (n < 64) {
748 /* fprs */
749 GET_REG32(*((uint32_t *)&env->fpr[n - 32]));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800750 }
751 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700752 switch (n) {
753 case 64: GET_REGA(env->y);
754 case 65: GET_REGA(GET_PSR(env));
755 case 66: GET_REGA(env->wim);
756 case 67: GET_REGA(env->tbr);
757 case 68: GET_REGA(env->pc);
758 case 69: GET_REGA(env->npc);
759 case 70: GET_REGA(env->fsr);
760 case 71: GET_REGA(0); /* csr */
761 default: GET_REGA(0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800762 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800763#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700764 if (n < 64) {
765 /* f0-f31 */
766 GET_REG32(*((uint32_t *)&env->fpr[n - 32]));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800767 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700768 if (n < 80) {
769 /* f32-f62 (double width, even numbers only) */
770 uint64_t val;
771
772 val = (uint64_t)*((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) << 32;
773 val |= *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]);
774 GET_REG64(val);
775 }
776 switch (n) {
777 case 80: GET_REGL(env->pc);
778 case 81: GET_REGL(env->npc);
779 case 82: GET_REGL(((uint64_t)GET_CCR(env) << 32) |
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800780 ((env->asi & 0xff) << 24) |
781 ((env->pstate & 0xfff) << 8) |
782 GET_CWP64(env));
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700783 case 83: GET_REGL(env->fsr);
784 case 84: GET_REGL(env->fprs);
785 case 85: GET_REGL(env->y);
786 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800787#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700788 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800789}
790
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700791static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800792{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700793#if defined(TARGET_ABI32)
794 abi_ulong tmp;
795
796 tmp = ldl_p(mem_buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800797#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700798 target_ulong tmp;
799
800 tmp = ldtul_p(mem_buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800801#endif
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800802
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700803 if (n < 8) {
804 /* g0..g7 */
805 env->gregs[n] = tmp;
806 } else if (n < 32) {
807 /* register window */
808 env->regwptr[n - 8] = tmp;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800809 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700810#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
811 else if (n < 64) {
812 /* fprs */
813 *((uint32_t *)&env->fpr[n - 32]) = tmp;
814 } else {
815 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
816 switch (n) {
817 case 64: env->y = tmp; break;
818 case 65: PUT_PSR(env, tmp); break;
819 case 66: env->wim = tmp; break;
820 case 67: env->tbr = tmp; break;
821 case 68: env->pc = tmp; break;
822 case 69: env->npc = tmp; break;
823 case 70: env->fsr = tmp; break;
824 default: return 0;
825 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800826 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700827 return 4;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800828#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700829 else if (n < 64) {
830 /* f0-f31 */
831 env->fpr[n] = ldfl_p(mem_buf);
832 return 4;
833 } else if (n < 80) {
834 /* f32-f62 (double width, even numbers only) */
835 *((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) = tmp >> 32;
836 *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]) = tmp;
837 } else {
838 switch (n) {
839 case 80: env->pc = tmp; break;
840 case 81: env->npc = tmp; break;
841 case 82:
842 PUT_CCR(env, tmp >> 32);
843 env->asi = (tmp >> 24) & 0xff;
844 env->pstate = (tmp >> 8) & 0xfff;
845 PUT_CWP64(env, tmp & 0xff);
846 break;
847 case 83: env->fsr = tmp; break;
848 case 84: env->fprs = tmp; break;
849 case 85: env->y = tmp; break;
850 default: return 0;
851 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800852 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700853 return 8;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800854#endif
855}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800856#elif defined (TARGET_ARM)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700857
858/* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect
859 whatever the target description contains. Due to a historical mishap
860 the FPA registers appear in between core integer regs and the CPSR.
861 We hack round this by giving the FPA regs zero size when talking to a
862 newer gdb. */
863#define NUM_CORE_REGS 26
864#define GDB_CORE_XML "arm-core.xml"
865
866static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800867{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700868 if (n < 16) {
869 /* Core integer register. */
870 GET_REG32(env->regs[n]);
871 }
872 if (n < 24) {
873 /* FPA registers. */
874 if (gdb_has_xml)
875 return 0;
876 memset(mem_buf, 0, 12);
877 return 12;
878 }
879 switch (n) {
880 case 24:
881 /* FPA status register. */
882 if (gdb_has_xml)
883 return 0;
884 GET_REG32(0);
885 case 25:
886 /* CPSR */
887 GET_REG32(cpsr_read(env));
888 }
889 /* Unknown register. */
890 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800891}
892
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700893static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800894{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700895 uint32_t tmp;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800896
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700897 tmp = ldl_p(mem_buf);
898
899 /* Mask out low bit of PC to workaround gdb bugs. This will probably
900 cause problems if we ever implement the Jazelle DBX extensions. */
901 if (n == 15)
902 tmp &= ~1;
903
904 if (n < 16) {
905 /* Core integer register. */
906 env->regs[n] = tmp;
907 return 4;
908 }
909 if (n < 24) { /* 16-23 */
910 /* FPA registers (ignored). */
911 if (gdb_has_xml)
912 return 0;
913 return 12;
914 }
915 switch (n) {
916 case 24:
917 /* FPA status register (ignored). */
918 if (gdb_has_xml)
919 return 0;
920 return 4;
921 case 25:
922 /* CPSR */
923 cpsr_write (env, tmp, 0xffffffff);
924 return 4;
925 }
926 /* Unknown register. */
927 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800928}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700929
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800930#elif defined (TARGET_M68K)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700931
932#define NUM_CORE_REGS 18
933
934#define GDB_CORE_XML "cf-core.xml"
935
936static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800937{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700938 if (n < 8) {
939 /* D0-D7 */
940 GET_REG32(env->dregs[n]);
941 } else if (n < 16) {
942 /* A0-A7 */
943 GET_REG32(env->aregs[n - 8]);
944 } else {
945 switch (n) {
946 case 16: GET_REG32(env->sr);
947 case 17: GET_REG32(env->pc);
948 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800949 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700950 /* FP registers not included here because they vary between
951 ColdFire and m68k. Use XML bits for these. */
952 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800953}
954
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700955static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800956{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700957 uint32_t tmp;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800958
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700959 tmp = ldl_p(mem_buf);
960
961 if (n < 8) {
962 /* D0-D7 */
963 env->dregs[n] = tmp;
964 } else if (n < 8) {
965 /* A0-A7 */
966 env->aregs[n - 8] = tmp;
967 } else {
968 switch (n) {
969 case 16: env->sr = tmp; break;
970 case 17: env->pc = tmp; break;
971 default: return 0;
972 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800973 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700974 return 4;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800975}
976#elif defined (TARGET_MIPS)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700977
978#define NUM_CORE_REGS 73
979
980static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800981{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700982 if (n < 32) {
983 GET_REGL(env->active_tc.gpr[n]);
984 }
985 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
986 if (n >= 38 && n < 70) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800987 if (env->CP0_Status & (1 << CP0St_FR))
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700988 GET_REGL(env->active_fpu.fpr[n - 38].d);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800989 else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700990 GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
991 }
992 switch (n) {
993 case 70: GET_REGL((int32_t)env->active_fpu.fcr31);
994 case 71: GET_REGL((int32_t)env->active_fpu.fcr0);
995 }
996 }
997 switch (n) {
998 case 32: GET_REGL((int32_t)env->CP0_Status);
999 case 33: GET_REGL(env->active_tc.LO[0]);
1000 case 34: GET_REGL(env->active_tc.HI[0]);
1001 case 35: GET_REGL(env->CP0_BadVAddr);
1002 case 36: GET_REGL((int32_t)env->CP0_Cause);
1003 case 37: GET_REGL(env->active_tc.PC);
1004 case 72: GET_REGL(0); /* fp */
1005 case 89: GET_REGL((int32_t)env->CP0_PRid);
1006 }
1007 if (n >= 73 && n <= 88) {
1008 /* 16 embedded regs. */
1009 GET_REGL(0);
1010 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001011
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001012 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001013}
1014
1015/* convert MIPS rounding mode in FCR31 to IEEE library */
1016static unsigned int ieee_rm[] =
1017 {
1018 float_round_nearest_even,
1019 float_round_to_zero,
1020 float_round_up,
1021 float_round_down
1022 };
1023#define RESTORE_ROUNDING_MODE \
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001024 set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001025
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001026static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001027{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001028 target_ulong tmp;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001029
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001030 tmp = ldtul_p(mem_buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001031
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001032 if (n < 32) {
1033 env->active_tc.gpr[n] = tmp;
1034 return sizeof(target_ulong);
1035 }
1036 if (env->CP0_Config1 & (1 << CP0C1_FP)
1037 && n >= 38 && n < 73) {
1038 if (n < 70) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001039 if (env->CP0_Status & (1 << CP0St_FR))
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001040 env->active_fpu.fpr[n - 38].d = tmp;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001041 else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001042 env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
1043 }
1044 switch (n) {
1045 case 70:
1046 env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
1047 /* set rounding mode */
1048 RESTORE_ROUNDING_MODE;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001049#ifndef CONFIG_SOFTFLOAT
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001050 /* no floating point exception for native float */
1051 SET_FP_ENABLE(env->active_fpu.fcr31, 0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001052#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001053 break;
1054 case 71: env->active_fpu.fcr0 = tmp; break;
1055 }
1056 return sizeof(target_ulong);
1057 }
1058 switch (n) {
1059 case 32: env->CP0_Status = tmp; break;
1060 case 33: env->active_tc.LO[0] = tmp; break;
1061 case 34: env->active_tc.HI[0] = tmp; break;
1062 case 35: env->CP0_BadVAddr = tmp; break;
1063 case 36: env->CP0_Cause = tmp; break;
1064 case 37: env->active_tc.PC = tmp; break;
1065 case 72: /* fp, ignored */ break;
1066 default:
1067 if (n > 89)
1068 return 0;
1069 /* Other registers are readonly. Ignore writes. */
1070 break;
1071 }
1072
1073 return sizeof(target_ulong);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001074}
1075#elif defined (TARGET_SH4)
1076
1077/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001078/* FIXME: We should use XML for this. */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001079
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001080#define NUM_CORE_REGS 59
1081
1082static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001083{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001084 if (n < 8) {
1085 if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
1086 GET_REGL(env->gregs[n + 16]);
1087 } else {
1088 GET_REGL(env->gregs[n]);
1089 }
1090 } else if (n < 16) {
1091 GET_REGL(env->gregs[n - 8]);
1092 } else if (n >= 25 && n < 41) {
1093 GET_REGL(env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
1094 } else if (n >= 43 && n < 51) {
1095 GET_REGL(env->gregs[n - 43]);
1096 } else if (n >= 51 && n < 59) {
1097 GET_REGL(env->gregs[n - (51 - 16)]);
1098 }
1099 switch (n) {
1100 case 16: GET_REGL(env->pc);
1101 case 17: GET_REGL(env->pr);
1102 case 18: GET_REGL(env->gbr);
1103 case 19: GET_REGL(env->vbr);
1104 case 20: GET_REGL(env->mach);
1105 case 21: GET_REGL(env->macl);
1106 case 22: GET_REGL(env->sr);
1107 case 23: GET_REGL(env->fpul);
1108 case 24: GET_REGL(env->fpscr);
1109 case 41: GET_REGL(env->ssr);
1110 case 42: GET_REGL(env->spc);
1111 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001112
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001113 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001114}
1115
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001116static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001117{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001118 uint32_t tmp;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001119
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001120 tmp = ldl_p(mem_buf);
1121
1122 if (n < 8) {
1123 if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
1124 env->gregs[n + 16] = tmp;
1125 } else {
1126 env->gregs[n] = tmp;
1127 }
1128 return 4;
1129 } else if (n < 16) {
1130 env->gregs[n - 8] = tmp;
1131 return 4;
1132 } else if (n >= 25 && n < 41) {
1133 env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)] = tmp;
1134 } else if (n >= 43 && n < 51) {
1135 env->gregs[n - 43] = tmp;
1136 return 4;
1137 } else if (n >= 51 && n < 59) {
1138 env->gregs[n - (51 - 16)] = tmp;
1139 return 4;
1140 }
1141 switch (n) {
1142 case 16: env->pc = tmp;
1143 case 17: env->pr = tmp;
1144 case 18: env->gbr = tmp;
1145 case 19: env->vbr = tmp;
1146 case 20: env->mach = tmp;
1147 case 21: env->macl = tmp;
1148 case 22: env->sr = tmp;
1149 case 23: env->fpul = tmp;
1150 case 24: env->fpscr = tmp;
1151 case 41: env->ssr = tmp;
1152 case 42: env->spc = tmp;
1153 default: return 0;
1154 }
1155
1156 return 4;
1157}
1158#elif defined (TARGET_MICROBLAZE)
1159
1160#define NUM_CORE_REGS (32 + 5)
1161
1162static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
1163{
1164 if (n < 32) {
1165 GET_REG32(env->regs[n]);
1166 } else {
1167 GET_REG32(env->sregs[n - 32]);
1168 }
1169 return 0;
1170}
1171
1172static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
1173{
1174 uint32_t tmp;
1175
1176 if (n > NUM_CORE_REGS)
1177 return 0;
1178
1179 tmp = ldl_p(mem_buf);
1180
1181 if (n < 32) {
1182 env->regs[n] = tmp;
1183 } else {
1184 env->sregs[n - 32] = tmp;
1185 }
1186 return 4;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001187}
1188#elif defined (TARGET_CRIS)
1189
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001190#define NUM_CORE_REGS 49
1191
1192static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001193{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001194 uint8_t srs;
1195
1196 srs = env->pregs[PR_SRS];
1197 if (n < 16) {
1198 GET_REG32(env->regs[n]);
1199 }
1200
1201 if (n >= 21 && n < 32) {
1202 GET_REG32(env->pregs[n - 16]);
1203 }
1204 if (n >= 33 && n < 49) {
1205 GET_REG32(env->sregs[srs][n - 33]);
1206 }
1207 switch (n) {
1208 case 16: GET_REG8(env->pregs[0]);
1209 case 17: GET_REG8(env->pregs[1]);
1210 case 18: GET_REG32(env->pregs[2]);
1211 case 19: GET_REG8(srs);
1212 case 20: GET_REG16(env->pregs[4]);
1213 case 32: GET_REG32(env->pc);
1214 }
1215
1216 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001217}
1218
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001219static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001220{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001221 uint32_t tmp;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001222
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001223 if (n > 49)
1224 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001225
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001226 tmp = ldl_p(mem_buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001227
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001228 if (n < 16) {
1229 env->regs[n] = tmp;
1230 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001231
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001232 if (n >= 21 && n < 32) {
1233 env->pregs[n - 16] = tmp;
1234 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001235
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001236 /* FIXME: Should support function regs be writable? */
1237 switch (n) {
1238 case 16: return 1;
1239 case 17: return 1;
1240 case 18: env->pregs[PR_PID] = tmp; break;
1241 case 19: return 1;
1242 case 20: return 2;
1243 case 32: env->pc = tmp; break;
1244 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001245
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001246 return 4;
1247}
1248#elif defined (TARGET_ALPHA)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001249
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001250#define NUM_CORE_REGS 65
1251
1252static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
1253{
1254 if (n < 31) {
1255 GET_REGL(env->ir[n]);
1256 }
1257 else if (n == 31) {
1258 GET_REGL(0);
1259 }
1260 else if (n<63) {
1261 uint64_t val;
1262
1263 val=*((uint64_t *)&env->fir[n-32]);
1264 GET_REGL(val);
1265 }
1266 else if (n==63) {
1267 GET_REGL(env->fpcr);
1268 }
1269 else if (n==64) {
1270 GET_REGL(env->pc);
1271 }
1272 else {
1273 GET_REGL(0);
1274 }
1275
1276 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001277}
1278
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001279static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001280{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001281 target_ulong tmp;
1282 tmp = ldtul_p(mem_buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001283
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001284 if (n < 31) {
1285 env->ir[n] = tmp;
1286 }
1287
1288 if (n > 31 && n < 63) {
1289 env->fir[n - 32] = ldfl_p(mem_buf);
1290 }
1291
1292 if (n == 64 ) {
1293 env->pc=tmp;
1294 }
1295
1296 return 8;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001297}
1298#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001299
1300#define NUM_CORE_REGS 0
1301
1302static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001303{
1304 return 0;
1305}
1306
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001307static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001308{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001309 return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001310}
1311
1312#endif
1313
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001314static int num_g_regs = NUM_CORE_REGS;
1315
1316#ifdef GDB_CORE_XML
1317/* Encode data using the encoding for 'x' packets. */
1318static int memtox(char *buf, const char *mem, int len)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001319{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001320 char *p = buf;
1321 char c;
1322
1323 while (len--) {
1324 c = *(mem++);
1325 switch (c) {
1326 case '#': case '$': case '*': case '}':
1327 *(p++) = '}';
1328 *(p++) = c ^ 0x20;
1329 break;
1330 default:
1331 *(p++) = c;
1332 break;
1333 }
1334 }
1335 return p - buf;
1336}
1337
1338static const char *get_feature_xml(const char *p, const char **newp)
1339{
1340 extern const char *const xml_builtin[][2];
1341 size_t len;
1342 int i;
1343 const char *name;
1344 static char target_xml[1024];
1345
1346 len = 0;
1347 while (p[len] && p[len] != ':')
1348 len++;
1349 *newp = p + len;
1350
1351 name = NULL;
1352 if (strncmp(p, "target.xml", len) == 0) {
1353 /* Generate the XML description for this CPU. */
1354 if (!target_xml[0]) {
1355 GDBRegisterState *r;
1356
1357 snprintf(target_xml, sizeof(target_xml),
1358 "<?xml version=\"1.0\"?>"
1359 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
1360 "<target>"
1361 "<xi:include href=\"%s\"/>",
1362 GDB_CORE_XML);
1363
1364 for (r = first_cpu->gdb_regs; r; r = r->next) {
1365 pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
1366 pstrcat(target_xml, sizeof(target_xml), r->xml);
1367 pstrcat(target_xml, sizeof(target_xml), "\"/>");
1368 }
1369 pstrcat(target_xml, sizeof(target_xml), "</target>");
1370 }
1371 return target_xml;
1372 }
1373 for (i = 0; ; i++) {
1374 name = xml_builtin[i][0];
1375 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
1376 break;
1377 }
1378 return name ? xml_builtin[i][1] : NULL;
1379}
1380#endif
1381
1382static int gdb_read_register(CPUState *env, uint8_t *mem_buf, int reg)
1383{
1384 GDBRegisterState *r;
1385
1386 if (reg < NUM_CORE_REGS)
1387 return cpu_gdb_read_register(env, mem_buf, reg);
1388
1389 for (r = env->gdb_regs; r; r = r->next) {
1390 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
1391 return r->get_reg(env, mem_buf, reg - r->base_reg);
1392 }
1393 }
1394 return 0;
1395}
1396
1397static int gdb_write_register(CPUState *env, uint8_t *mem_buf, int reg)
1398{
1399 GDBRegisterState *r;
1400
1401 if (reg < NUM_CORE_REGS)
1402 return cpu_gdb_write_register(env, mem_buf, reg);
1403
1404 for (r = env->gdb_regs; r; r = r->next) {
1405 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
1406 return r->set_reg(env, mem_buf, reg - r->base_reg);
1407 }
1408 }
1409 return 0;
1410}
1411
1412/* Register a supplemental set of CPU registers. If g_pos is nonzero it
1413 specifies the first register number and these registers are included in
1414 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
1415 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
1416 */
1417
1418void gdb_register_coprocessor(CPUState * env,
1419 gdb_reg_cb get_reg, gdb_reg_cb set_reg,
1420 int num_regs, const char *xml, int g_pos)
1421{
1422 GDBRegisterState *s;
1423 GDBRegisterState **p;
1424 static int last_reg = NUM_CORE_REGS;
1425
1426 s = (GDBRegisterState *)qemu_mallocz(sizeof(GDBRegisterState));
1427 s->base_reg = last_reg;
1428 s->num_regs = num_regs;
1429 s->get_reg = get_reg;
1430 s->set_reg = set_reg;
1431 s->xml = xml;
1432 p = &env->gdb_regs;
1433 while (*p) {
1434 /* Check for duplicates. */
1435 if (strcmp((*p)->xml, xml) == 0)
1436 return;
1437 p = &(*p)->next;
1438 }
1439 /* Add to end of list. */
1440 last_reg += num_regs;
1441 *p = s;
1442 if (g_pos) {
1443 if (g_pos != s->base_reg) {
1444 fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
1445 "Expected %d got %d\n", xml, g_pos, s->base_reg);
1446 } else {
1447 num_g_regs = last_reg;
1448 }
1449 }
1450}
1451
1452#ifndef CONFIG_USER_ONLY
1453static const int xlat_gdb_type[] = {
1454 [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
1455 [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
1456 [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1457};
1458#endif
1459
1460static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
1461{
1462 CPUState *env;
1463 int err = 0;
1464
1465 if (kvm_enabled())
1466 return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
1467
1468 switch (type) {
1469 case GDB_BREAKPOINT_SW:
1470 case GDB_BREAKPOINT_HW:
1471 for (env = first_cpu; env != NULL; env = env->next_cpu) {
1472 err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
1473 if (err)
1474 break;
1475 }
1476 return err;
1477#ifndef CONFIG_USER_ONLY
1478 case GDB_WATCHPOINT_WRITE:
1479 case GDB_WATCHPOINT_READ:
1480 case GDB_WATCHPOINT_ACCESS:
1481 for (env = first_cpu; env != NULL; env = env->next_cpu) {
1482 err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
1483 NULL);
1484 if (err)
1485 break;
1486 }
1487 return err;
1488#endif
1489 default:
1490 return -ENOSYS;
1491 }
1492}
1493
1494static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
1495{
1496 CPUState *env;
1497 int err = 0;
1498
1499 if (kvm_enabled())
1500 return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
1501
1502 switch (type) {
1503 case GDB_BREAKPOINT_SW:
1504 case GDB_BREAKPOINT_HW:
1505 for (env = first_cpu; env != NULL; env = env->next_cpu) {
1506 err = cpu_breakpoint_remove(env, addr, BP_GDB);
1507 if (err)
1508 break;
1509 }
1510 return err;
1511#ifndef CONFIG_USER_ONLY
1512 case GDB_WATCHPOINT_WRITE:
1513 case GDB_WATCHPOINT_READ:
1514 case GDB_WATCHPOINT_ACCESS:
1515 for (env = first_cpu; env != NULL; env = env->next_cpu) {
1516 err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
1517 if (err)
1518 break;
1519 }
1520 return err;
1521#endif
1522 default:
1523 return -ENOSYS;
1524 }
1525}
1526
1527static void gdb_breakpoint_remove_all(void)
1528{
1529 CPUState *env;
1530
1531 if (kvm_enabled()) {
1532 kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
1533 return;
1534 }
1535
1536 for (env = first_cpu; env != NULL; env = env->next_cpu) {
1537 cpu_breakpoint_remove_all(env, BP_GDB);
1538#ifndef CONFIG_USER_ONLY
1539 cpu_watchpoint_remove_all(env, BP_GDB);
1540#endif
1541 }
1542}
1543
1544static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
1545{
1546#if defined(TARGET_I386)
1547 s->c_cpu->eip = pc;
1548 cpu_synchronize_state(s->c_cpu, 1);
1549#elif defined (TARGET_PPC)
1550 s->c_cpu->nip = pc;
1551#elif defined (TARGET_SPARC)
1552 s->c_cpu->pc = pc;
1553 s->c_cpu->npc = pc + 4;
1554#elif defined (TARGET_ARM)
1555 s->c_cpu->regs[15] = pc;
1556#elif defined (TARGET_SH4)
1557 s->c_cpu->pc = pc;
1558#elif defined (TARGET_MIPS)
1559 s->c_cpu->active_tc.PC = pc;
1560#elif defined (TARGET_MICROBLAZE)
1561 s->c_cpu->sregs[SR_PC] = pc;
1562#elif defined (TARGET_CRIS)
1563 s->c_cpu->pc = pc;
1564#elif defined (TARGET_ALPHA)
1565 s->c_cpu->pc = pc;
1566#endif
1567}
1568
1569static inline int gdb_id(CPUState *env)
1570{
1571#if defined(CONFIG_USER_ONLY) && defined(USE_NPTL)
1572 return env->host_tid;
1573#else
1574 return env->cpu_index + 1;
1575#endif
1576}
1577
1578static CPUState *find_cpu(uint32_t thread_id)
1579{
1580 CPUState *env;
1581
1582 for (env = first_cpu; env != NULL; env = env->next_cpu) {
1583 if (gdb_id(env) == thread_id) {
1584 return env;
1585 }
1586 }
1587
1588 return NULL;
1589}
1590
1591static int gdb_handle_packet(GDBState *s, const char *line_buf)
1592{
1593 CPUState *env;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001594 const char *p;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001595 uint32_t thread;
1596 int ch, reg_size, type, res;
1597 char buf[MAX_PACKET_LENGTH];
1598 uint8_t mem_buf[MAX_PACKET_LENGTH];
1599 uint8_t *registers;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001600 target_ulong addr, len;
1601
1602#ifdef DEBUG_GDB
1603 printf("command='%s'\n", line_buf);
1604#endif
1605 p = line_buf;
1606 ch = *p++;
1607 switch(ch) {
1608 case '?':
1609 /* TODO: Make this return the correct value for user-mode. */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001610 snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
1611 gdb_id(s->c_cpu));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001612 put_packet(s, buf);
1613 /* Remove all the breakpoints when this query is issued,
1614 * because gdb is doing and initial connect and the state
1615 * should be cleaned up.
1616 */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001617 gdb_breakpoint_remove_all();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001618 break;
1619 case 'c':
1620 if (*p != '\0') {
1621 addr = strtoull(p, (char **)&p, 16);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001622 gdb_set_cpu_pc(s, addr);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001623 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001624 s->signal = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001625 gdb_continue(s);
1626 return RS_IDLE;
1627 case 'C':
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001628 s->signal = gdb_signal_to_target (strtoul(p, (char **)&p, 16));
1629 if (s->signal == -1)
1630 s->signal = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001631 gdb_continue(s);
1632 return RS_IDLE;
1633 case 'k':
1634 /* Kill the target */
1635 fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
1636 exit(0);
1637 case 'D':
1638 /* Detach packet */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001639 gdb_breakpoint_remove_all();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001640 gdb_continue(s);
1641 put_packet(s, "OK");
1642 break;
1643 case 's':
1644 if (*p != '\0') {
1645 addr = strtoull(p, (char **)&p, 16);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001646 gdb_set_cpu_pc(s, addr);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001647 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001648 cpu_single_step(s->c_cpu, sstep_flags);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001649 gdb_continue(s);
1650 return RS_IDLE;
1651 case 'F':
1652 {
1653 target_ulong ret;
1654 target_ulong err;
1655
1656 ret = strtoull(p, (char **)&p, 16);
1657 if (*p == ',') {
1658 p++;
1659 err = strtoull(p, (char **)&p, 16);
1660 } else {
1661 err = 0;
1662 }
1663 if (*p == ',')
1664 p++;
1665 type = *p;
1666 if (gdb_current_syscall_cb)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001667 gdb_current_syscall_cb(s->c_cpu, ret, err);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001668 if (type == 'C') {
1669 put_packet(s, "T02");
1670 } else {
1671 gdb_continue(s);
1672 }
1673 }
1674 break;
1675 case 'g':
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001676 cpu_synchronize_state(s->g_cpu, 0);
1677 len = 0;
1678 for (addr = 0; addr < num_g_regs; addr++) {
1679 reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
1680 len += reg_size;
1681 }
1682 memtohex(buf, mem_buf, len);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001683 put_packet(s, buf);
1684 break;
1685 case 'G':
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001686 registers = mem_buf;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001687 len = strlen(p) / 2;
1688 hextomem((uint8_t *)registers, p, len);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001689 for (addr = 0; addr < num_g_regs && len > 0; addr++) {
1690 reg_size = gdb_write_register(s->g_cpu, registers, addr);
1691 len -= reg_size;
1692 registers += reg_size;
1693 }
1694 cpu_synchronize_state(s->g_cpu, 1);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001695 put_packet(s, "OK");
1696 break;
1697 case 'm':
1698 addr = strtoull(p, (char **)&p, 16);
1699 if (*p == ',')
1700 p++;
1701 len = strtoull(p, NULL, 16);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001702 if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001703 put_packet (s, "E14");
1704 } else {
1705 memtohex(buf, mem_buf, len);
1706 put_packet(s, buf);
1707 }
1708 break;
1709 case 'M':
1710 addr = strtoull(p, (char **)&p, 16);
1711 if (*p == ',')
1712 p++;
1713 len = strtoull(p, (char **)&p, 16);
1714 if (*p == ':')
1715 p++;
1716 hextomem(mem_buf, p, len);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001717 if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001718 put_packet(s, "E14");
1719 else
1720 put_packet(s, "OK");
1721 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001722 case 'p':
1723 /* Older gdb are really dumb, and don't use 'g' if 'p' is avaialable.
1724 This works, but can be very slow. Anything new enough to
1725 understand XML also knows how to use this properly. */
1726 if (!gdb_has_xml)
1727 goto unknown_command;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001728 addr = strtoull(p, (char **)&p, 16);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001729 reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);
1730 if (reg_size) {
1731 memtohex(buf, mem_buf, reg_size);
1732 put_packet(s, buf);
1733 } else {
1734 put_packet(s, "E14");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001735 }
1736 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001737 case 'P':
1738 if (!gdb_has_xml)
1739 goto unknown_command;
1740 addr = strtoull(p, (char **)&p, 16);
1741 if (*p == '=')
1742 p++;
1743 reg_size = strlen(p) / 2;
1744 hextomem(mem_buf, p, reg_size);
1745 gdb_write_register(s->g_cpu, mem_buf, addr);
1746 put_packet(s, "OK");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001747 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001748 case 'Z':
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001749 case 'z':
1750 type = strtoul(p, (char **)&p, 16);
1751 if (*p == ',')
1752 p++;
1753 addr = strtoull(p, (char **)&p, 16);
1754 if (*p == ',')
1755 p++;
1756 len = strtoull(p, (char **)&p, 16);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001757 if (ch == 'Z')
1758 res = gdb_breakpoint_insert(addr, len, type);
1759 else
1760 res = gdb_breakpoint_remove(addr, len, type);
1761 if (res >= 0)
1762 put_packet(s, "OK");
1763 else if (res == -ENOSYS)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001764 put_packet(s, "");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001765 else
1766 put_packet(s, "E22");
1767 break;
1768 case 'H':
1769 type = *p++;
1770 thread = strtoull(p, (char **)&p, 16);
1771 if (thread == -1 || thread == 0) {
1772 put_packet(s, "OK");
1773 break;
1774 }
1775 env = find_cpu(thread);
1776 if (env == NULL) {
1777 put_packet(s, "E22");
1778 break;
1779 }
1780 switch (type) {
1781 case 'c':
1782 s->c_cpu = env;
1783 put_packet(s, "OK");
1784 break;
1785 case 'g':
1786 s->g_cpu = env;
1787 put_packet(s, "OK");
1788 break;
1789 default:
1790 put_packet(s, "E22");
1791 break;
1792 }
1793 break;
1794 case 'T':
1795 thread = strtoull(p, (char **)&p, 16);
1796 env = find_cpu(thread);
1797
1798 if (env != NULL) {
1799 put_packet(s, "OK");
1800 } else {
1801 put_packet(s, "E22");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001802 }
1803 break;
1804 case 'q':
1805 case 'Q':
1806 /* parse any 'q' packets here */
1807 if (!strcmp(p,"qemu.sstepbits")) {
1808 /* Query Breakpoint bit definitions */
1809 snprintf(buf, sizeof(buf), "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
1810 SSTEP_ENABLE,
1811 SSTEP_NOIRQ,
1812 SSTEP_NOTIMER);
1813 put_packet(s, buf);
1814 break;
1815 } else if (strncmp(p,"qemu.sstep",10) == 0) {
1816 /* Display or change the sstep_flags */
1817 p += 10;
1818 if (*p != '=') {
1819 /* Display current setting */
1820 snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
1821 put_packet(s, buf);
1822 break;
1823 }
1824 p++;
1825 type = strtoul(p, (char **)&p, 16);
1826 sstep_flags = type;
1827 put_packet(s, "OK");
1828 break;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001829 } else if (strcmp(p,"C") == 0) {
1830 /* "Current thread" remains vague in the spec, so always return
1831 * the first CPU (gdb returns the first thread). */
1832 put_packet(s, "QC1");
1833 break;
1834 } else if (strcmp(p,"fThreadInfo") == 0) {
1835 s->query_cpu = first_cpu;
1836 goto report_cpuinfo;
1837 } else if (strcmp(p,"sThreadInfo") == 0) {
1838 report_cpuinfo:
1839 if (s->query_cpu) {
1840 snprintf(buf, sizeof(buf), "m%x", gdb_id(s->query_cpu));
1841 put_packet(s, buf);
1842 s->query_cpu = s->query_cpu->next_cpu;
1843 } else
1844 put_packet(s, "l");
1845 break;
1846 } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
1847 thread = strtoull(p+16, (char **)&p, 16);
1848 env = find_cpu(thread);
1849 if (env != NULL) {
1850 cpu_synchronize_state(env, 0);
1851 len = snprintf((char *)mem_buf, sizeof(mem_buf),
1852 "CPU#%d [%s]", env->cpu_index,
1853 env->halted ? "halted " : "running");
1854 memtohex(buf, mem_buf, len);
1855 put_packet(s, buf);
1856 }
1857 break;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001858 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001859#ifdef CONFIG_USER_ONLY
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001860 else if (strncmp(p, "Offsets", 7) == 0) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001861 TaskState *ts = s->c_cpu->opaque;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001862
1863 snprintf(buf, sizeof(buf),
1864 "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
1865 ";Bss=" TARGET_ABI_FMT_lx,
1866 ts->info->code_offset,
1867 ts->info->data_offset,
1868 ts->info->data_offset);
1869 put_packet(s, buf);
1870 break;
1871 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001872#else /* !CONFIG_USER_ONLY */
1873 else if (strncmp(p, "Rcmd,", 5) == 0) {
1874 int len = strlen(p + 5);
1875
1876 if ((len % 2) != 0) {
1877 put_packet(s, "E01");
1878 break;
1879 }
1880 hextomem(mem_buf, p + 5, len);
1881 len = len / 2;
1882 mem_buf[len++] = 0;
1883 qemu_chr_read(s->mon_chr, mem_buf, len);
1884 put_packet(s, "OK");
1885 break;
1886 }
1887#endif /* !CONFIG_USER_ONLY */
1888 if (strncmp(p, "Supported", 9) == 0) {
1889 snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
1890#ifdef GDB_CORE_XML
1891 pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001892#endif
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001893 put_packet(s, buf);
1894 break;
1895 }
1896#ifdef GDB_CORE_XML
1897 if (strncmp(p, "Xfer:features:read:", 19) == 0) {
1898 const char *xml;
1899 target_ulong total_len;
1900
1901 gdb_has_xml = 1;
1902 p += 19;
1903 xml = get_feature_xml(p, &p);
1904 if (!xml) {
1905 snprintf(buf, sizeof(buf), "E00");
1906 put_packet(s, buf);
1907 break;
1908 }
1909
1910 if (*p == ':')
1911 p++;
1912 addr = strtoul(p, (char **)&p, 16);
1913 if (*p == ',')
1914 p++;
1915 len = strtoul(p, (char **)&p, 16);
1916
1917 total_len = strlen(xml);
1918 if (addr > total_len) {
1919 snprintf(buf, sizeof(buf), "E00");
1920 put_packet(s, buf);
1921 break;
1922 }
1923 if (len > (MAX_PACKET_LENGTH - 5) / 2)
1924 len = (MAX_PACKET_LENGTH - 5) / 2;
1925 if (len < total_len - addr) {
1926 buf[0] = 'm';
1927 len = memtox(buf + 1, xml + addr, len);
1928 } else {
1929 buf[0] = 'l';
1930 len = memtox(buf + 1, xml + addr, total_len - addr);
1931 }
1932 put_packet_binary(s, buf, len + 1);
1933 break;
1934 }
1935#endif
1936 /* Unrecognised 'q' command. */
1937 goto unknown_command;
1938
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001939 default:
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001940 unknown_command:
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001941 /* put empty packet */
1942 buf[0] = '\0';
1943 put_packet(s, buf);
1944 break;
1945 }
1946 return RS_IDLE;
1947}
1948
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001949void gdb_set_stop_cpu(CPUState *env)
1950{
1951 gdbserver_state->c_cpu = env;
1952 gdbserver_state->g_cpu = env;
1953}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001954
1955#ifndef CONFIG_USER_ONLY
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001956static void gdb_vm_state_change(void *opaque, int running, int reason)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001957{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001958 GDBState *s = gdbserver_state;
1959 CPUState *env = s->c_cpu;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001960 char buf[256];
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001961 const char *type;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001962 int ret;
1963
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001964 if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) ||
1965 s->state == RS_INACTIVE || s->state == RS_SYSCALL)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001966 return;
1967
1968 /* disable single step if it was enable */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001969 cpu_single_step(env, 0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001970
1971 if (reason == EXCP_DEBUG) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001972 if (env->watchpoint_hit) {
1973 switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
1974 case BP_MEM_READ:
1975 type = "r";
1976 break;
1977 case BP_MEM_ACCESS:
1978 type = "a";
1979 break;
1980 default:
1981 type = "";
1982 break;
1983 }
1984 snprintf(buf, sizeof(buf),
1985 "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
1986 GDB_SIGNAL_TRAP, gdb_id(env), type,
1987 env->watchpoint_hit->vaddr);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001988 put_packet(s, buf);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001989 env->watchpoint_hit = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001990 return;
1991 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001992 tb_flush(env);
1993 ret = GDB_SIGNAL_TRAP;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001994 } else {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001995 ret = GDB_SIGNAL_INT;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001996 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001997 snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, gdb_id(env));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001998 put_packet(s, buf);
1999}
2000#endif
2001
2002/* Send a gdb syscall request.
2003 This accepts limited printf-style format specifiers, specifically:
2004 %x - target_ulong argument printed in hex.
2005 %lx - 64-bit argument printed in hex.
2006 %s - string pointer (target_ulong) and length (int) pair. */
2007void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2008{
2009 va_list va;
2010 char buf[256];
2011 char *p;
2012 target_ulong addr;
2013 uint64_t i64;
2014 GDBState *s;
2015
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002016 s = gdbserver_state;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002017 if (!s)
2018 return;
2019 gdb_current_syscall_cb = cb;
2020 s->state = RS_SYSCALL;
2021#ifndef CONFIG_USER_ONLY
2022 vm_stop(EXCP_DEBUG);
2023#endif
2024 s->state = RS_IDLE;
2025 va_start(va, fmt);
2026 p = buf;
2027 *(p++) = 'F';
2028 while (*fmt) {
2029 if (*fmt == '%') {
2030 fmt++;
2031 switch (*fmt++) {
2032 case 'x':
2033 addr = va_arg(va, target_ulong);
2034 p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx, addr);
2035 break;
2036 case 'l':
2037 if (*(fmt++) != 'x')
2038 goto bad_format;
2039 i64 = va_arg(va, uint64_t);
2040 p += snprintf(p, &buf[sizeof(buf)] - p, "%" PRIx64, i64);
2041 break;
2042 case 's':
2043 addr = va_arg(va, target_ulong);
2044 p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx "/%x",
2045 addr, va_arg(va, int));
2046 break;
2047 default:
2048 bad_format:
2049 fprintf(stderr, "gdbstub: Bad syscall format string '%s'\n",
2050 fmt - 1);
2051 break;
2052 }
2053 } else {
2054 *(p++) = *(fmt++);
2055 }
2056 }
2057 *p = 0;
2058 va_end(va);
2059 put_packet(s, buf);
2060#ifdef CONFIG_USER_ONLY
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002061 gdb_handlesig(s->c_cpu, 0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002062#else
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002063 cpu_exit(s->c_cpu);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002064#endif
2065}
2066
2067static void gdb_read_byte(GDBState *s, int ch)
2068{
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002069 int i, csum;
2070 uint8_t reply;
2071
2072#ifndef CONFIG_USER_ONLY
2073 if (s->last_packet_len) {
2074 /* Waiting for a response to the last packet. If we see the start
2075 of a new command then abandon the previous response. */
2076 if (ch == '-') {
2077#ifdef DEBUG_GDB
2078 printf("Got NACK, retransmitting\n");
2079#endif
2080 put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
2081 }
2082#ifdef DEBUG_GDB
2083 else if (ch == '+')
2084 printf("Got ACK\n");
2085 else
2086 printf("Got '%c' when expecting ACK/NACK\n", ch);
2087#endif
2088 if (ch == '+' || ch == '$')
2089 s->last_packet_len = 0;
2090 if (ch != '$')
2091 return;
2092 }
2093 if (vm_running) {
2094 /* when the CPU is running, we cannot do anything except stop
2095 it when receiving a char */
2096 vm_stop(EXCP_INTERRUPT);
2097 } else
2098#endif
2099 {
2100 switch(s->state) {
2101 case RS_IDLE:
2102 if (ch == '$') {
2103 s->line_buf_index = 0;
2104 s->state = RS_GETLINE;
2105 }
2106 break;
2107 case RS_GETLINE:
2108 if (ch == '#') {
2109 s->state = RS_CHKSUM1;
2110 } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
2111 s->state = RS_IDLE;
2112 } else {
2113 s->line_buf[s->line_buf_index++] = ch;
2114 }
2115 break;
2116 case RS_CHKSUM1:
2117 s->line_buf[s->line_buf_index] = '\0';
2118 s->line_csum = fromhex(ch) << 4;
2119 s->state = RS_CHKSUM2;
2120 break;
2121 case RS_CHKSUM2:
2122 s->line_csum |= fromhex(ch);
2123 csum = 0;
2124 for(i = 0; i < s->line_buf_index; i++) {
2125 csum += s->line_buf[i];
2126 }
2127 if (s->line_csum != (csum & 0xff)) {
2128 reply = '-';
2129 put_buffer(s, &reply, 1);
2130 s->state = RS_IDLE;
2131 } else {
2132 reply = '+';
2133 put_buffer(s, &reply, 1);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002134 s->state = gdb_handle_packet(s, s->line_buf);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002135 }
2136 break;
2137 default:
2138 abort();
2139 }
2140 }
2141}
2142
2143#ifdef CONFIG_USER_ONLY
2144int
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002145gdb_queuesig (void)
2146{
2147 GDBState *s;
2148
2149 s = gdbserver_state;
2150
2151 if (gdbserver_fd < 0 || s->fd < 0)
2152 return 0;
2153 else
2154 return 1;
2155}
2156
2157int
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002158gdb_handlesig (CPUState *env, int sig)
2159{
2160 GDBState *s;
2161 char buf[256];
2162 int n;
2163
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002164 s = gdbserver_state;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002165 if (gdbserver_fd < 0 || s->fd < 0)
2166 return sig;
2167
2168 /* disable single step if it was enabled */
2169 cpu_single_step(env, 0);
2170 tb_flush(env);
2171
2172 if (sig != 0)
2173 {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002174 snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002175 put_packet(s, buf);
2176 }
2177 /* put_packet() might have detected that the peer terminated the
2178 connection. */
2179 if (s->fd < 0)
2180 return sig;
2181
2182 sig = 0;
2183 s->state = RS_IDLE;
2184 s->running_state = 0;
2185 while (s->running_state == 0) {
2186 n = read (s->fd, buf, 256);
2187 if (n > 0)
2188 {
2189 int i;
2190
2191 for (i = 0; i < n; i++)
2192 gdb_read_byte (s, buf[i]);
2193 }
2194 else if (n == 0 || errno != EAGAIN)
2195 {
2196 /* XXX: Connection closed. Should probably wait for annother
2197 connection before continuing. */
2198 return sig;
2199 }
2200 }
2201 sig = s->signal;
2202 s->signal = 0;
2203 return sig;
2204}
2205
2206/* Tell the remote gdb that the process has exited. */
2207void gdb_exit(CPUState *env, int code)
2208{
2209 GDBState *s;
2210 char buf[4];
2211
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002212 s = gdbserver_state;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002213 if (gdbserver_fd < 0 || s->fd < 0)
2214 return;
2215
2216 snprintf(buf, sizeof(buf), "W%02x", code);
2217 put_packet(s, buf);
2218}
2219
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002220/* Tell the remote gdb that the process has exited due to SIG. */
2221void gdb_signalled(CPUState *env, int sig)
2222{
2223 GDBState *s;
2224 char buf[4];
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002225
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002226 s = gdbserver_state;
2227 if (gdbserver_fd < 0 || s->fd < 0)
2228 return;
2229
2230 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
2231 put_packet(s, buf);
2232}
2233
2234static void gdb_accept(void)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002235{
2236 GDBState *s;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002237 struct sockaddr_in sockaddr;
2238 socklen_t len;
2239 int val, fd;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002240
2241 for(;;) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002242 len = sizeof(sockaddr);
2243 fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
2244 if (fd < 0 && errno != EINTR) {
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002245 perror("accept");
2246 return;
2247 } else if (fd >= 0) {
2248 break;
2249 }
2250 }
2251
2252 /* set short latency */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002253 val = 1;
2254 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
2255
2256 s = qemu_mallocz(sizeof(GDBState));
2257 s->c_cpu = first_cpu;
2258 s->g_cpu = first_cpu;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002259 s->fd = fd;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002260 gdb_has_xml = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002261
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002262 gdbserver_state = s;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002263
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002264 fcntl(fd, F_SETFL, O_NONBLOCK);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002265}
2266
2267static int gdbserver_open(int port)
2268{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002269 struct sockaddr_in sockaddr;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002270 int fd, val, ret;
2271
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002272 fd = socket(PF_INET, SOCK_STREAM, 0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002273 if (fd < 0) {
2274 perror("socket");
2275 return -1;
2276 }
2277
2278 /* allow fast reuse */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002279 val = 1;
2280 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002281
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002282 sockaddr.sin_family = AF_INET;
2283 sockaddr.sin_port = htons(port);
2284 sockaddr.sin_addr.s_addr = 0;
2285 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002286 if (ret < 0) {
2287 perror("bind");
2288 return -1;
2289 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002290 ret = listen(fd, 0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002291 if (ret < 0) {
2292 perror("listen");
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002293 return -1;
2294 }
2295 return fd;
2296}
2297
2298int gdbserver_start(int port)
2299{
2300 gdbserver_fd = gdbserver_open(port);
2301 if (gdbserver_fd < 0)
2302 return -1;
2303 /* accept connections */
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002304 gdb_accept();
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002305 return 0;
2306}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002307
2308/* Disable gdb stub for child processes. */
2309void gdbserver_fork(CPUState *env)
2310{
2311 GDBState *s = gdbserver_state;
2312 if (gdbserver_fd < 0 || s->fd < 0)
2313 return;
2314 close(s->fd);
2315 s->fd = -1;
2316 cpu_breakpoint_remove_all(env, BP_GDB);
2317 cpu_watchpoint_remove_all(env, BP_GDB);
2318}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002319#else
2320static int gdb_chr_can_receive(void *opaque)
2321{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002322 /* We can handle an arbitrarily large amount of data.
2323 Pick the maximum packet size, which is as good as anything. */
2324 return MAX_PACKET_LENGTH;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002325}
2326
2327static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
2328{
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002329 int i;
2330
2331 for (i = 0; i < size; i++) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002332 gdb_read_byte(gdbserver_state, buf[i]);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002333 }
2334}
2335
2336static void gdb_chr_event(void *opaque, int event)
2337{
2338 switch (event) {
David 'Digit' Turnera5d41202010-05-10 18:37:10 -07002339 case CHR_EVENT_OPENED:
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002340 vm_stop(EXCP_INTERRUPT);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002341 gdb_has_xml = 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002342 break;
2343 default:
2344 break;
2345 }
2346}
2347
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002348static void gdb_monitor_output(GDBState *s, const char *msg, int len)
2349{
2350 char buf[MAX_PACKET_LENGTH];
2351
2352 buf[0] = 'O';
2353 if (len > (MAX_PACKET_LENGTH/2) - 1)
2354 len = (MAX_PACKET_LENGTH/2) - 1;
2355 memtohex(buf + 1, (uint8_t *)msg, len);
2356 put_packet(s, buf);
2357}
2358
2359static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len)
2360{
2361 const char *p = (const char *)buf;
2362 int max_sz;
2363
2364 max_sz = (sizeof(gdbserver_state->last_packet) - 2) / 2;
2365 for (;;) {
2366 if (len <= max_sz) {
2367 gdb_monitor_output(gdbserver_state, p, len);
2368 break;
2369 }
2370 gdb_monitor_output(gdbserver_state, p, max_sz);
2371 p += max_sz;
2372 len -= max_sz;
2373 }
2374 return len;
2375}
2376
2377#ifndef _WIN32
2378static void gdb_sigterm_handler(int signal)
2379{
2380 if (vm_running)
2381 vm_stop(EXCP_INTERRUPT);
2382}
2383#endif
2384
2385int gdbserver_start(const char *device)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002386{
2387 GDBState *s;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002388 char gdbstub_device_name[128];
2389 CharDriverState *chr = NULL;
2390 CharDriverState *mon_chr;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002391
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002392 if (!device)
2393 return -1;
2394 if (strcmp(device, "none") != 0) {
2395 if (strstart(device, "tcp:", NULL)) {
2396 /* enforce required TCP attributes */
2397 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
2398 "%s,nowait,nodelay,server", device);
2399 device = gdbstub_device_name;
2400 }
2401#ifndef _WIN32
2402 else if (strcmp(device, "stdio") == 0) {
2403 struct sigaction act;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002404
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002405 memset(&act, 0, sizeof(act));
2406 act.sa_handler = gdb_sigterm_handler;
2407 sigaction(SIGINT, &act, NULL);
2408 }
2409#endif
2410 chr = qemu_chr_open("gdb", device, NULL);
2411 if (!chr)
2412 return -1;
2413
2414 qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
2415 gdb_chr_event, NULL);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002416 }
2417
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002418 s = gdbserver_state;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002419 if (!s) {
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002420 s = qemu_mallocz(sizeof(GDBState));
2421 gdbserver_state = s;
2422
2423 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
2424
2425 /* Initialize a monitor terminal for gdb */
2426 mon_chr = qemu_mallocz(sizeof(*mon_chr));
2427 mon_chr->chr_write = gdb_monitor_write;
2428 monitor_init(mon_chr, 0);
2429 } else {
2430 if (s->chr)
2431 qemu_chr_close(s->chr);
2432 mon_chr = s->mon_chr;
2433 memset(s, 0, sizeof(GDBState));
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002434 }
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002435 s->c_cpu = first_cpu;
2436 s->g_cpu = first_cpu;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002437 s->chr = chr;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07002438 s->state = chr ? RS_IDLE : RS_INACTIVE;
2439 s->mon_chr = mon_chr;
2440
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08002441 return 0;
2442}
2443#endif