blob: c858b7f2b64b462a3395acaa58793dba26a0431a [file] [log] [blame]
bellardb4608c02003-06-27 17:34:32 +00001/*
2 * gdb server stub
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard34751872005-07-02 14:31:34 +00004 * Copyright (c) 2003-2005 Fabrice Bellard
bellardb4608c02003-06-27 17:34:32 +00005 *
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
Blue Swirl8167ee82009-07-16 20:47:01 +000017 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
bellardb4608c02003-06-27 17:34:32 +000018 */
pbrook978efd62006-06-17 18:30:42 +000019#include "config.h"
pbrook56aebc82008-10-11 17:55:29 +000020#include "qemu-common.h"
bellard1fddef42005-04-17 19:16:13 +000021#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>
pbrook978efd62006-06-17 18:30:42 +000028#include <fcntl.h>
bellard1fddef42005-04-17 19:16:13 +000029
30#include "qemu.h"
31#else
Paolo Bonzini83c90892012-12-17 18:19:49 +010032#include "monitor/monitor.h"
Paolo Bonzinidccfcd02013-04-08 16:55:25 +020033#include "sysemu/char.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010034#include "sysemu/sysemu.h"
Paolo Bonzini022c62c2012-12-17 18:19:49 +010035#include "exec/gdbstub.h"
bellard1fddef42005-04-17 19:16:13 +000036#endif
bellard67b915a2004-03-31 23:37:16 +000037
pbrook56aebc82008-10-11 17:55:29 +000038#define MAX_PACKET_LENGTH 4096
39
Blue Swirl2b41f102011-06-19 20:38:22 +000040#include "cpu.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010041#include "qemu/sockets.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010042#include "sysemu/kvm.h"
Richard Henderson6ee77b12012-08-23 10:44:45 -070043#include "qemu/bitops.h"
aurel32ca587a82008-12-18 22:44:13 +000044
Andreas Färberf3659ee2013-06-27 19:09:09 +020045static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
46 uint8_t *buf, int len, bool is_write)
Fabien Chouteau44520db2011-09-08 12:48:16 +020047{
Andreas Färberf3659ee2013-06-27 19:09:09 +020048 CPUClass *cc = CPU_GET_CLASS(cpu);
49
50 if (cc->memory_rw_debug) {
51 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
52 }
53 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
Fabien Chouteau44520db2011-09-08 12:48:16 +020054}
aurel32ca587a82008-12-18 22:44:13 +000055
56enum {
57 GDB_SIGNAL_0 = 0,
58 GDB_SIGNAL_INT = 2,
Jan Kiszka425189a2011-03-22 11:02:09 +010059 GDB_SIGNAL_QUIT = 3,
aurel32ca587a82008-12-18 22:44:13 +000060 GDB_SIGNAL_TRAP = 5,
Jan Kiszka425189a2011-03-22 11:02:09 +010061 GDB_SIGNAL_ABRT = 6,
62 GDB_SIGNAL_ALRM = 14,
63 GDB_SIGNAL_IO = 23,
64 GDB_SIGNAL_XCPU = 24,
aurel32ca587a82008-12-18 22:44:13 +000065 GDB_SIGNAL_UNKNOWN = 143
66};
67
68#ifdef CONFIG_USER_ONLY
69
70/* Map target signal numbers to GDB protocol signal numbers and vice
71 * versa. For user emulation's currently supported systems, we can
72 * assume most signals are defined.
73 */
74
75static int gdb_signal_table[] = {
76 0,
77 TARGET_SIGHUP,
78 TARGET_SIGINT,
79 TARGET_SIGQUIT,
80 TARGET_SIGILL,
81 TARGET_SIGTRAP,
82 TARGET_SIGABRT,
83 -1, /* SIGEMT */
84 TARGET_SIGFPE,
85 TARGET_SIGKILL,
86 TARGET_SIGBUS,
87 TARGET_SIGSEGV,
88 TARGET_SIGSYS,
89 TARGET_SIGPIPE,
90 TARGET_SIGALRM,
91 TARGET_SIGTERM,
92 TARGET_SIGURG,
93 TARGET_SIGSTOP,
94 TARGET_SIGTSTP,
95 TARGET_SIGCONT,
96 TARGET_SIGCHLD,
97 TARGET_SIGTTIN,
98 TARGET_SIGTTOU,
99 TARGET_SIGIO,
100 TARGET_SIGXCPU,
101 TARGET_SIGXFSZ,
102 TARGET_SIGVTALRM,
103 TARGET_SIGPROF,
104 TARGET_SIGWINCH,
105 -1, /* SIGLOST */
106 TARGET_SIGUSR1,
107 TARGET_SIGUSR2,
blueswir1c72d5bf2009-01-15 17:27:45 +0000108#ifdef TARGET_SIGPWR
aurel32ca587a82008-12-18 22:44:13 +0000109 TARGET_SIGPWR,
blueswir1c72d5bf2009-01-15 17:27:45 +0000110#else
111 -1,
112#endif
aurel32ca587a82008-12-18 22:44:13 +0000113 -1, /* SIGPOLL */
114 -1,
115 -1,
116 -1,
117 -1,
118 -1,
119 -1,
120 -1,
121 -1,
122 -1,
123 -1,
124 -1,
blueswir1c72d5bf2009-01-15 17:27:45 +0000125#ifdef __SIGRTMIN
aurel32ca587a82008-12-18 22:44:13 +0000126 __SIGRTMIN + 1,
127 __SIGRTMIN + 2,
128 __SIGRTMIN + 3,
129 __SIGRTMIN + 4,
130 __SIGRTMIN + 5,
131 __SIGRTMIN + 6,
132 __SIGRTMIN + 7,
133 __SIGRTMIN + 8,
134 __SIGRTMIN + 9,
135 __SIGRTMIN + 10,
136 __SIGRTMIN + 11,
137 __SIGRTMIN + 12,
138 __SIGRTMIN + 13,
139 __SIGRTMIN + 14,
140 __SIGRTMIN + 15,
141 __SIGRTMIN + 16,
142 __SIGRTMIN + 17,
143 __SIGRTMIN + 18,
144 __SIGRTMIN + 19,
145 __SIGRTMIN + 20,
146 __SIGRTMIN + 21,
147 __SIGRTMIN + 22,
148 __SIGRTMIN + 23,
149 __SIGRTMIN + 24,
150 __SIGRTMIN + 25,
151 __SIGRTMIN + 26,
152 __SIGRTMIN + 27,
153 __SIGRTMIN + 28,
154 __SIGRTMIN + 29,
155 __SIGRTMIN + 30,
156 __SIGRTMIN + 31,
157 -1, /* SIGCANCEL */
158 __SIGRTMIN,
159 __SIGRTMIN + 32,
160 __SIGRTMIN + 33,
161 __SIGRTMIN + 34,
162 __SIGRTMIN + 35,
163 __SIGRTMIN + 36,
164 __SIGRTMIN + 37,
165 __SIGRTMIN + 38,
166 __SIGRTMIN + 39,
167 __SIGRTMIN + 40,
168 __SIGRTMIN + 41,
169 __SIGRTMIN + 42,
170 __SIGRTMIN + 43,
171 __SIGRTMIN + 44,
172 __SIGRTMIN + 45,
173 __SIGRTMIN + 46,
174 __SIGRTMIN + 47,
175 __SIGRTMIN + 48,
176 __SIGRTMIN + 49,
177 __SIGRTMIN + 50,
178 __SIGRTMIN + 51,
179 __SIGRTMIN + 52,
180 __SIGRTMIN + 53,
181 __SIGRTMIN + 54,
182 __SIGRTMIN + 55,
183 __SIGRTMIN + 56,
184 __SIGRTMIN + 57,
185 __SIGRTMIN + 58,
186 __SIGRTMIN + 59,
187 __SIGRTMIN + 60,
188 __SIGRTMIN + 61,
189 __SIGRTMIN + 62,
190 __SIGRTMIN + 63,
191 __SIGRTMIN + 64,
192 __SIGRTMIN + 65,
193 __SIGRTMIN + 66,
194 __SIGRTMIN + 67,
195 __SIGRTMIN + 68,
196 __SIGRTMIN + 69,
197 __SIGRTMIN + 70,
198 __SIGRTMIN + 71,
199 __SIGRTMIN + 72,
200 __SIGRTMIN + 73,
201 __SIGRTMIN + 74,
202 __SIGRTMIN + 75,
203 __SIGRTMIN + 76,
204 __SIGRTMIN + 77,
205 __SIGRTMIN + 78,
206 __SIGRTMIN + 79,
207 __SIGRTMIN + 80,
208 __SIGRTMIN + 81,
209 __SIGRTMIN + 82,
210 __SIGRTMIN + 83,
211 __SIGRTMIN + 84,
212 __SIGRTMIN + 85,
213 __SIGRTMIN + 86,
214 __SIGRTMIN + 87,
215 __SIGRTMIN + 88,
216 __SIGRTMIN + 89,
217 __SIGRTMIN + 90,
218 __SIGRTMIN + 91,
219 __SIGRTMIN + 92,
220 __SIGRTMIN + 93,
221 __SIGRTMIN + 94,
222 __SIGRTMIN + 95,
223 -1, /* SIGINFO */
224 -1, /* UNKNOWN */
225 -1, /* DEFAULT */
226 -1,
227 -1,
228 -1,
229 -1,
230 -1,
231 -1
blueswir1c72d5bf2009-01-15 17:27:45 +0000232#endif
aurel32ca587a82008-12-18 22:44:13 +0000233};
bellard8f447cc2006-06-14 15:21:14 +0000234#else
aurel32ca587a82008-12-18 22:44:13 +0000235/* In system mode we only need SIGINT and SIGTRAP; other signals
236 are not yet supported. */
237
238enum {
239 TARGET_SIGINT = 2,
240 TARGET_SIGTRAP = 5
241};
242
243static int gdb_signal_table[] = {
244 -1,
245 -1,
246 TARGET_SIGINT,
247 -1,
248 -1,
249 TARGET_SIGTRAP
250};
bellard8f447cc2006-06-14 15:21:14 +0000251#endif
bellardb4608c02003-06-27 17:34:32 +0000252
aurel32ca587a82008-12-18 22:44:13 +0000253#ifdef CONFIG_USER_ONLY
254static int target_signal_to_gdb (int sig)
255{
256 int i;
257 for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
258 if (gdb_signal_table[i] == sig)
259 return i;
260 return GDB_SIGNAL_UNKNOWN;
261}
262#endif
263
264static int gdb_signal_to_target (int sig)
265{
266 if (sig < ARRAY_SIZE (gdb_signal_table))
267 return gdb_signal_table[sig];
268 else
269 return -1;
270}
271
bellard4abe6152003-07-26 18:01:58 +0000272//#define DEBUG_GDB
bellardb4608c02003-06-27 17:34:32 +0000273
pbrook56aebc82008-10-11 17:55:29 +0000274typedef struct GDBRegisterState {
275 int base_reg;
276 int num_regs;
277 gdb_reg_cb get_reg;
278 gdb_reg_cb set_reg;
279 const char *xml;
280 struct GDBRegisterState *next;
281} GDBRegisterState;
282
bellard858693c2004-03-31 18:52:07 +0000283enum RSState {
aliguori36556b22009-03-28 18:05:53 +0000284 RS_INACTIVE,
bellard858693c2004-03-31 18:52:07 +0000285 RS_IDLE,
286 RS_GETLINE,
287 RS_CHKSUM1,
288 RS_CHKSUM2,
289};
bellard858693c2004-03-31 18:52:07 +0000290typedef struct GDBState {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +0200291 CPUState *c_cpu; /* current CPU for step/continue ops */
292 CPUState *g_cpu; /* current CPU for other ops */
Andreas Färber52f34622013-06-27 13:44:40 +0200293 CPUState *query_cpu; /* for q{f|s}ThreadInfo */
bellard41625032005-04-24 10:07:11 +0000294 enum RSState state; /* parsing state */
pbrook56aebc82008-10-11 17:55:29 +0000295 char line_buf[MAX_PACKET_LENGTH];
bellard858693c2004-03-31 18:52:07 +0000296 int line_buf_index;
297 int line_csum;
pbrook56aebc82008-10-11 17:55:29 +0000298 uint8_t last_packet[MAX_PACKET_LENGTH + 4];
pbrook4046d912007-01-28 01:53:16 +0000299 int last_packet_len;
edgar_igl1f487ee2008-05-17 22:20:53 +0000300 int signal;
bellard41625032005-04-24 10:07:11 +0000301#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000302 int fd;
bellard41625032005-04-24 10:07:11 +0000303 int running_state;
pbrook4046d912007-01-28 01:53:16 +0000304#else
305 CharDriverState *chr;
aliguori8a34a0f2009-03-05 23:01:55 +0000306 CharDriverState *mon_chr;
bellard41625032005-04-24 10:07:11 +0000307#endif
Meador Ingecdb432b2012-03-15 17:49:45 +0000308 char syscall_buf[256];
309 gdb_syscall_complete_cb current_syscall_cb;
bellard858693c2004-03-31 18:52:07 +0000310} GDBState;
bellardb4608c02003-06-27 17:34:32 +0000311
edgar_igl60897d32008-05-09 08:25:14 +0000312/* By default use no IRQs and no timers while single stepping so as to
313 * make single stepping like an ICE HW step.
314 */
315static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
316
aliguori880a7572008-11-18 20:30:24 +0000317static GDBState *gdbserver_state;
318
pbrook56aebc82008-10-11 17:55:29 +0000319/* This is an ugly hack to cope with both new and old gdb.
320 If gdb sends qXfer:features:read then assume we're talking to a newish
321 gdb that understands target descriptions. */
322static int gdb_has_xml;
323
bellard1fddef42005-04-17 19:16:13 +0000324#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000325/* XXX: This is not thread safe. Do we care? */
326static int gdbserver_fd = -1;
327
bellard858693c2004-03-31 18:52:07 +0000328static int get_char(GDBState *s)
bellardb4608c02003-06-27 17:34:32 +0000329{
330 uint8_t ch;
331 int ret;
332
333 for(;;) {
Blue Swirl00aa0042011-07-23 20:04:29 +0000334 ret = qemu_recv(s->fd, &ch, 1, 0);
bellardb4608c02003-06-27 17:34:32 +0000335 if (ret < 0) {
edgar_igl1f487ee2008-05-17 22:20:53 +0000336 if (errno == ECONNRESET)
337 s->fd = -1;
bellardb4608c02003-06-27 17:34:32 +0000338 if (errno != EINTR && errno != EAGAIN)
339 return -1;
340 } else if (ret == 0) {
edgar_igl1f487ee2008-05-17 22:20:53 +0000341 close(s->fd);
342 s->fd = -1;
bellardb4608c02003-06-27 17:34:32 +0000343 return -1;
344 } else {
345 break;
346 }
347 }
348 return ch;
349}
pbrook4046d912007-01-28 01:53:16 +0000350#endif
bellardb4608c02003-06-27 17:34:32 +0000351
blueswir1654efcf2009-04-18 07:29:59 +0000352static enum {
pbrooka2d1eba2007-01-28 03:10:55 +0000353 GDB_SYS_UNKNOWN,
354 GDB_SYS_ENABLED,
355 GDB_SYS_DISABLED,
356} gdb_syscall_mode;
357
358/* If gdb is connected when the first semihosting syscall occurs then use
359 remote gdb syscalls. Otherwise use native file IO. */
360int use_gdb_syscalls(void)
361{
362 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
aliguori880a7572008-11-18 20:30:24 +0000363 gdb_syscall_mode = (gdbserver_state ? GDB_SYS_ENABLED
364 : GDB_SYS_DISABLED);
pbrooka2d1eba2007-01-28 03:10:55 +0000365 }
366 return gdb_syscall_mode == GDB_SYS_ENABLED;
367}
368
edgar_iglba70a622008-03-14 06:10:42 +0000369/* Resume execution. */
370static inline void gdb_continue(GDBState *s)
371{
372#ifdef CONFIG_USER_ONLY
373 s->running_state = 1;
374#else
Paolo Bonzinibc7d0e62013-06-03 17:06:55 +0200375 if (runstate_check(RUN_STATE_GUEST_PANICKED)) {
376 runstate_set(RUN_STATE_DEBUG);
377 }
Paolo Bonzini26ac7a32013-06-03 17:06:54 +0200378 if (!runstate_needs_reset()) {
Paolo Bonzini87f25c12013-05-30 13:20:40 +0200379 vm_start();
380 }
edgar_iglba70a622008-03-14 06:10:42 +0000381#endif
382}
383
bellard858693c2004-03-31 18:52:07 +0000384static void put_buffer(GDBState *s, const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000385{
pbrook4046d912007-01-28 01:53:16 +0000386#ifdef CONFIG_USER_ONLY
bellardb4608c02003-06-27 17:34:32 +0000387 int ret;
388
389 while (len > 0) {
bellard8f447cc2006-06-14 15:21:14 +0000390 ret = send(s->fd, buf, len, 0);
bellardb4608c02003-06-27 17:34:32 +0000391 if (ret < 0) {
392 if (errno != EINTR && errno != EAGAIN)
393 return;
394 } else {
395 buf += ret;
396 len -= ret;
397 }
398 }
pbrook4046d912007-01-28 01:53:16 +0000399#else
Anthony Liguori2cc6e0a2011-08-15 11:17:28 -0500400 qemu_chr_fe_write(s->chr, buf, len);
pbrook4046d912007-01-28 01:53:16 +0000401#endif
bellardb4608c02003-06-27 17:34:32 +0000402}
403
404static inline int fromhex(int v)
405{
406 if (v >= '0' && v <= '9')
407 return v - '0';
408 else if (v >= 'A' && v <= 'F')
409 return v - 'A' + 10;
410 else if (v >= 'a' && v <= 'f')
411 return v - 'a' + 10;
412 else
413 return 0;
414}
415
416static inline int tohex(int v)
417{
418 if (v < 10)
419 return v + '0';
420 else
421 return v - 10 + 'a';
422}
423
424static void memtohex(char *buf, const uint8_t *mem, int len)
425{
426 int i, c;
427 char *q;
428 q = buf;
429 for(i = 0; i < len; i++) {
430 c = mem[i];
431 *q++ = tohex(c >> 4);
432 *q++ = tohex(c & 0xf);
433 }
434 *q = '\0';
435}
436
437static void hextomem(uint8_t *mem, const char *buf, int len)
438{
439 int i;
440
441 for(i = 0; i < len; i++) {
442 mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
443 buf += 2;
444 }
445}
446
bellardb4608c02003-06-27 17:34:32 +0000447/* return -1 if error, 0 if OK */
pbrook56aebc82008-10-11 17:55:29 +0000448static int put_packet_binary(GDBState *s, const char *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000449{
pbrook56aebc82008-10-11 17:55:29 +0000450 int csum, i;
ths60fe76f2007-12-16 03:02:09 +0000451 uint8_t *p;
bellardb4608c02003-06-27 17:34:32 +0000452
bellardb4608c02003-06-27 17:34:32 +0000453 for(;;) {
pbrook4046d912007-01-28 01:53:16 +0000454 p = s->last_packet;
455 *(p++) = '$';
pbrook4046d912007-01-28 01:53:16 +0000456 memcpy(p, buf, len);
457 p += len;
bellardb4608c02003-06-27 17:34:32 +0000458 csum = 0;
459 for(i = 0; i < len; i++) {
460 csum += buf[i];
461 }
pbrook4046d912007-01-28 01:53:16 +0000462 *(p++) = '#';
463 *(p++) = tohex((csum >> 4) & 0xf);
464 *(p++) = tohex((csum) & 0xf);
bellardb4608c02003-06-27 17:34:32 +0000465
pbrook4046d912007-01-28 01:53:16 +0000466 s->last_packet_len = p - s->last_packet;
thsffe8ab82007-12-16 03:16:05 +0000467 put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
bellardb4608c02003-06-27 17:34:32 +0000468
pbrook4046d912007-01-28 01:53:16 +0000469#ifdef CONFIG_USER_ONLY
470 i = get_char(s);
471 if (i < 0)
bellardb4608c02003-06-27 17:34:32 +0000472 return -1;
pbrook4046d912007-01-28 01:53:16 +0000473 if (i == '+')
bellardb4608c02003-06-27 17:34:32 +0000474 break;
pbrook4046d912007-01-28 01:53:16 +0000475#else
476 break;
477#endif
bellardb4608c02003-06-27 17:34:32 +0000478 }
479 return 0;
480}
481
pbrook56aebc82008-10-11 17:55:29 +0000482/* return -1 if error, 0 if OK */
483static int put_packet(GDBState *s, const char *buf)
484{
485#ifdef DEBUG_GDB
486 printf("reply='%s'\n", buf);
487#endif
488
489 return put_packet_binary(s, buf, strlen(buf));
490}
491
492/* The GDB remote protocol transfers values in target byte order. This means
493 we can use the raw memory access routines to access the value buffer.
494 Conveniently, these also handle the case where the buffer is mis-aligned.
495 */
496#define GET_REG8(val) do { \
497 stb_p(mem_buf, val); \
498 return 1; \
499 } while(0)
500#define GET_REG16(val) do { \
501 stw_p(mem_buf, val); \
502 return 2; \
503 } while(0)
504#define GET_REG32(val) do { \
505 stl_p(mem_buf, val); \
506 return 4; \
507 } while(0)
508#define GET_REG64(val) do { \
509 stq_p(mem_buf, val); \
510 return 8; \
511 } while(0)
512
513#if TARGET_LONG_BITS == 64
514#define GET_REGL(val) GET_REG64(val)
515#define ldtul_p(addr) ldq_p(addr)
516#else
517#define GET_REGL(val) GET_REG32(val)
518#define ldtul_p(addr) ldl_p(addr)
519#endif
520
edgar_iglfde3fd62008-05-09 08:50:01 +0000521#if defined(TARGET_I386)
balrog5ad265e2007-10-31 00:21:35 +0000522
Andreas Färberf20f9df2013-07-07 12:07:54 +0200523#include "target-i386/gdbstub.c"
bellard6da41ea2004-01-04 15:48:38 +0000524
bellard9e62fd72004-01-05 22:49:06 +0000525#elif defined (TARGET_PPC)
pbrook56aebc82008-10-11 17:55:29 +0000526
aurel32e571cb42009-01-24 15:07:42 +0000527#if defined (TARGET_PPC64)
528#define GDB_CORE_XML "power64-core.xml"
529#else
530#define GDB_CORE_XML "power-core.xml"
531#endif
pbrook56aebc82008-10-11 17:55:29 +0000532
Andreas Färber0980bfa2013-07-07 12:26:33 +0200533#include "target-ppc/gdbstub.c"
pbrook56aebc82008-10-11 17:55:29 +0000534
bellarde95c8d52004-09-30 22:22:08 +0000535#elif defined (TARGET_SPARC)
bellarde95c8d52004-09-30 22:22:08 +0000536
pbrook56aebc82008-10-11 17:55:29 +0000537#ifdef TARGET_ABI32
538#define GET_REGA(val) GET_REG32(val)
539#else
540#define GET_REGA(val) GET_REGL(val)
541#endif
542
Andreas Färberf3840912012-02-20 06:44:56 +0100543static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
pbrook56aebc82008-10-11 17:55:29 +0000544{
545 if (n < 8) {
546 /* g0..g7 */
547 GET_REGA(env->gregs[n]);
bellarde95c8d52004-09-30 22:22:08 +0000548 }
pbrook56aebc82008-10-11 17:55:29 +0000549 if (n < 32) {
550 /* register window */
551 GET_REGA(env->regwptr[n - 8]);
bellarde95c8d52004-09-30 22:22:08 +0000552 }
pbrook56aebc82008-10-11 17:55:29 +0000553#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
554 if (n < 64) {
555 /* fprs */
Richard Henderson30038fd2011-10-17 10:42:49 -0700556 if (n & 1) {
557 GET_REG32(env->fpr[(n - 32) / 2].l.lower);
558 } else {
559 GET_REG32(env->fpr[(n - 32) / 2].l.upper);
560 }
bellarde95c8d52004-09-30 22:22:08 +0000561 }
562 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
pbrook56aebc82008-10-11 17:55:29 +0000563 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200564 case 64:
565 GET_REGA(env->y);
566 case 65:
567 GET_REGA(cpu_get_psr(env));
568 case 66:
569 GET_REGA(env->wim);
570 case 67:
571 GET_REGA(env->tbr);
572 case 68:
573 GET_REGA(env->pc);
574 case 69:
575 GET_REGA(env->npc);
576 case 70:
577 GET_REGA(env->fsr);
578 case 71:
579 GET_REGA(0); /* csr */
580 default:
581 GET_REGA(0);
bellard34751872005-07-02 14:31:34 +0000582 }
bellard34751872005-07-02 14:31:34 +0000583#else
pbrook56aebc82008-10-11 17:55:29 +0000584 if (n < 64) {
585 /* f0-f31 */
Richard Henderson30038fd2011-10-17 10:42:49 -0700586 if (n & 1) {
587 GET_REG32(env->fpr[(n - 32) / 2].l.lower);
588 } else {
589 GET_REG32(env->fpr[(n - 32) / 2].l.upper);
590 }
bellard34751872005-07-02 14:31:34 +0000591 }
pbrook56aebc82008-10-11 17:55:29 +0000592 if (n < 80) {
593 /* f32-f62 (double width, even numbers only) */
Richard Henderson30038fd2011-10-17 10:42:49 -0700594 GET_REG64(env->fpr[(n - 32) / 2].ll);
pbrook56aebc82008-10-11 17:55:29 +0000595 }
596 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200597 case 80:
598 GET_REGL(env->pc);
599 case 81:
600 GET_REGL(env->npc);
601 case 82:
602 GET_REGL((cpu_get_ccr(env) << 32) |
603 ((env->asi & 0xff) << 24) |
604 ((env->pstate & 0xfff) << 8) |
605 cpu_get_cwp64(env));
606 case 83:
607 GET_REGL(env->fsr);
608 case 84:
609 GET_REGL(env->fprs);
610 case 85:
611 GET_REGL(env->y);
pbrook56aebc82008-10-11 17:55:29 +0000612 }
bellard34751872005-07-02 14:31:34 +0000613#endif
pbrook56aebc82008-10-11 17:55:29 +0000614 return 0;
bellarde95c8d52004-09-30 22:22:08 +0000615}
616
Andreas Färberf3840912012-02-20 06:44:56 +0100617static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
bellarde95c8d52004-09-30 22:22:08 +0000618{
pbrook56aebc82008-10-11 17:55:29 +0000619#if defined(TARGET_ABI32)
620 abi_ulong tmp;
621
622 tmp = ldl_p(mem_buf);
blueswir196d19122008-06-07 08:03:05 +0000623#else
pbrook56aebc82008-10-11 17:55:29 +0000624 target_ulong tmp;
625
626 tmp = ldtul_p(mem_buf);
blueswir196d19122008-06-07 08:03:05 +0000627#endif
bellarde95c8d52004-09-30 22:22:08 +0000628
pbrook56aebc82008-10-11 17:55:29 +0000629 if (n < 8) {
630 /* g0..g7 */
631 env->gregs[n] = tmp;
632 } else if (n < 32) {
633 /* register window */
634 env->regwptr[n - 8] = tmp;
bellarde95c8d52004-09-30 22:22:08 +0000635 }
pbrook56aebc82008-10-11 17:55:29 +0000636#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
637 else if (n < 64) {
638 /* fprs */
Richard Henderson30038fd2011-10-17 10:42:49 -0700639 /* f0-f31 */
640 if (n & 1) {
641 env->fpr[(n - 32) / 2].l.lower = tmp;
642 } else {
643 env->fpr[(n - 32) / 2].l.upper = tmp;
644 }
pbrook56aebc82008-10-11 17:55:29 +0000645 } else {
646 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
647 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200648 case 64:
649 env->y = tmp;
650 break;
651 case 65:
652 cpu_put_psr(env, tmp);
653 break;
654 case 66:
655 env->wim = tmp;
656 break;
657 case 67:
658 env->tbr = tmp;
659 break;
660 case 68:
661 env->pc = tmp;
662 break;
663 case 69:
664 env->npc = tmp;
665 break;
666 case 70:
667 env->fsr = tmp;
668 break;
669 default:
670 return 0;
pbrook56aebc82008-10-11 17:55:29 +0000671 }
bellarde95c8d52004-09-30 22:22:08 +0000672 }
pbrook56aebc82008-10-11 17:55:29 +0000673 return 4;
bellard34751872005-07-02 14:31:34 +0000674#else
pbrook56aebc82008-10-11 17:55:29 +0000675 else if (n < 64) {
676 /* f0-f31 */
Richard Henderson30038fd2011-10-17 10:42:49 -0700677 tmp = ldl_p(mem_buf);
678 if (n & 1) {
679 env->fpr[(n - 32) / 2].l.lower = tmp;
680 } else {
681 env->fpr[(n - 32) / 2].l.upper = tmp;
682 }
pbrook56aebc82008-10-11 17:55:29 +0000683 return 4;
684 } else if (n < 80) {
685 /* f32-f62 (double width, even numbers only) */
Richard Henderson30038fd2011-10-17 10:42:49 -0700686 env->fpr[(n - 32) / 2].ll = tmp;
pbrook56aebc82008-10-11 17:55:29 +0000687 } else {
688 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200689 case 80:
690 env->pc = tmp;
691 break;
692 case 81:
693 env->npc = tmp;
694 break;
pbrook56aebc82008-10-11 17:55:29 +0000695 case 82:
Blue Swirl5a834bb2010-05-09 20:19:04 +0000696 cpu_put_ccr(env, tmp >> 32);
Andreas Färber47d74ef2013-07-07 11:17:26 +0200697 env->asi = (tmp >> 24) & 0xff;
698 env->pstate = (tmp >> 8) & 0xfff;
Blue Swirl5a834bb2010-05-09 20:19:04 +0000699 cpu_put_cwp64(env, tmp & 0xff);
Andreas Färber47d74ef2013-07-07 11:17:26 +0200700 break;
701 case 83:
702 env->fsr = tmp;
703 break;
704 case 84:
705 env->fprs = tmp;
706 break;
707 case 85:
708 env->y = tmp;
709 break;
710 default:
711 return 0;
pbrook56aebc82008-10-11 17:55:29 +0000712 }
bellard34751872005-07-02 14:31:34 +0000713 }
pbrook56aebc82008-10-11 17:55:29 +0000714 return 8;
bellard34751872005-07-02 14:31:34 +0000715#endif
bellard9e62fd72004-01-05 22:49:06 +0000716}
bellard1fddef42005-04-17 19:16:13 +0000717#elif defined (TARGET_ARM)
pbrook56aebc82008-10-11 17:55:29 +0000718
719/* Old gdb always expect FPA registers. Newer (xml-aware) gdb only expect
720 whatever the target description contains. Due to a historical mishap
721 the FPA registers appear in between core integer regs and the CPSR.
722 We hack round this by giving the FPA regs zero size when talking to a
723 newer gdb. */
pbrook56aebc82008-10-11 17:55:29 +0000724#define GDB_CORE_XML "arm-core.xml"
725
Andreas Färberf3840912012-02-20 06:44:56 +0100726static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n)
bellard1fddef42005-04-17 19:16:13 +0000727{
pbrook56aebc82008-10-11 17:55:29 +0000728 if (n < 16) {
729 /* Core integer register. */
730 GET_REG32(env->regs[n]);
731 }
732 if (n < 24) {
733 /* FPA registers. */
Andreas Färber47d74ef2013-07-07 11:17:26 +0200734 if (gdb_has_xml) {
pbrook56aebc82008-10-11 17:55:29 +0000735 return 0;
Andreas Färber47d74ef2013-07-07 11:17:26 +0200736 }
pbrook56aebc82008-10-11 17:55:29 +0000737 memset(mem_buf, 0, 12);
738 return 12;
739 }
740 switch (n) {
741 case 24:
742 /* FPA status register. */
Andreas Färber47d74ef2013-07-07 11:17:26 +0200743 if (gdb_has_xml) {
pbrook56aebc82008-10-11 17:55:29 +0000744 return 0;
Andreas Färber47d74ef2013-07-07 11:17:26 +0200745 }
pbrook56aebc82008-10-11 17:55:29 +0000746 GET_REG32(0);
747 case 25:
748 /* CPSR */
749 GET_REG32(cpsr_read(env));
750 }
751 /* Unknown register. */
752 return 0;
bellard1fddef42005-04-17 19:16:13 +0000753}
754
Andreas Färberf3840912012-02-20 06:44:56 +0100755static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n)
bellard1fddef42005-04-17 19:16:13 +0000756{
pbrook56aebc82008-10-11 17:55:29 +0000757 uint32_t tmp;
bellard1fddef42005-04-17 19:16:13 +0000758
pbrook56aebc82008-10-11 17:55:29 +0000759 tmp = ldl_p(mem_buf);
760
761 /* Mask out low bit of PC to workaround gdb bugs. This will probably
762 cause problems if we ever implement the Jazelle DBX extensions. */
Andreas Färber47d74ef2013-07-07 11:17:26 +0200763 if (n == 15) {
pbrook56aebc82008-10-11 17:55:29 +0000764 tmp &= ~1;
Andreas Färber47d74ef2013-07-07 11:17:26 +0200765 }
pbrook56aebc82008-10-11 17:55:29 +0000766
767 if (n < 16) {
768 /* Core integer register. */
769 env->regs[n] = tmp;
770 return 4;
771 }
772 if (n < 24) { /* 16-23 */
773 /* FPA registers (ignored). */
Andreas Färber47d74ef2013-07-07 11:17:26 +0200774 if (gdb_has_xml) {
pbrook56aebc82008-10-11 17:55:29 +0000775 return 0;
Andreas Färber47d74ef2013-07-07 11:17:26 +0200776 }
pbrook56aebc82008-10-11 17:55:29 +0000777 return 12;
778 }
779 switch (n) {
780 case 24:
781 /* FPA status register (ignored). */
Andreas Färber47d74ef2013-07-07 11:17:26 +0200782 if (gdb_has_xml) {
pbrook56aebc82008-10-11 17:55:29 +0000783 return 0;
Andreas Färber47d74ef2013-07-07 11:17:26 +0200784 }
pbrook56aebc82008-10-11 17:55:29 +0000785 return 4;
786 case 25:
787 /* CPSR */
Andreas Färber47d74ef2013-07-07 11:17:26 +0200788 cpsr_write(env, tmp, 0xffffffff);
pbrook56aebc82008-10-11 17:55:29 +0000789 return 4;
790 }
791 /* Unknown register. */
792 return 0;
bellard1fddef42005-04-17 19:16:13 +0000793}
pbrook56aebc82008-10-11 17:55:29 +0000794
pbrooke6e59062006-10-22 00:18:54 +0000795#elif defined (TARGET_M68K)
pbrook56aebc82008-10-11 17:55:29 +0000796
pbrook56aebc82008-10-11 17:55:29 +0000797#define GDB_CORE_XML "cf-core.xml"
798
Andreas Färberf3840912012-02-20 06:44:56 +0100799static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n)
pbrooke6e59062006-10-22 00:18:54 +0000800{
pbrook56aebc82008-10-11 17:55:29 +0000801 if (n < 8) {
802 /* D0-D7 */
803 GET_REG32(env->dregs[n]);
804 } else if (n < 16) {
805 /* A0-A7 */
806 GET_REG32(env->aregs[n - 8]);
807 } else {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200808 switch (n) {
809 case 16:
810 GET_REG32(env->sr);
811 case 17:
812 GET_REG32(env->pc);
pbrook56aebc82008-10-11 17:55:29 +0000813 }
pbrooke6e59062006-10-22 00:18:54 +0000814 }
pbrook56aebc82008-10-11 17:55:29 +0000815 /* FP registers not included here because they vary between
816 ColdFire and m68k. Use XML bits for these. */
817 return 0;
pbrooke6e59062006-10-22 00:18:54 +0000818}
819
Andreas Färberf3840912012-02-20 06:44:56 +0100820static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n)
pbrooke6e59062006-10-22 00:18:54 +0000821{
pbrook56aebc82008-10-11 17:55:29 +0000822 uint32_t tmp;
pbrooke6e59062006-10-22 00:18:54 +0000823
pbrook56aebc82008-10-11 17:55:29 +0000824 tmp = ldl_p(mem_buf);
825
826 if (n < 8) {
827 /* D0-D7 */
828 env->dregs[n] = tmp;
Kazu Hiratab3d6b952010-01-14 09:08:00 -0800829 } else if (n < 16) {
pbrook56aebc82008-10-11 17:55:29 +0000830 /* A0-A7 */
831 env->aregs[n - 8] = tmp;
832 } else {
833 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200834 case 16:
835 env->sr = tmp;
836 break;
837 case 17:
838 env->pc = tmp;
839 break;
840 default:
841 return 0;
pbrook56aebc82008-10-11 17:55:29 +0000842 }
pbrooke6e59062006-10-22 00:18:54 +0000843 }
pbrook56aebc82008-10-11 17:55:29 +0000844 return 4;
pbrooke6e59062006-10-22 00:18:54 +0000845}
bellard6f970bd2005-12-05 19:55:19 +0000846#elif defined (TARGET_MIPS)
pbrook56aebc82008-10-11 17:55:29 +0000847
Andreas Färberf3840912012-02-20 06:44:56 +0100848static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
bellard6f970bd2005-12-05 19:55:19 +0000849{
pbrook56aebc82008-10-11 17:55:29 +0000850 if (n < 32) {
851 GET_REGL(env->active_tc.gpr[n]);
852 }
853 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
854 if (n >= 38 && n < 70) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200855 if (env->CP0_Status & (1 << CP0St_FR)) {
856 GET_REGL(env->active_fpu.fpr[n - 38].d);
857 } else {
858 GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
859 }
pbrook56aebc82008-10-11 17:55:29 +0000860 }
861 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200862 case 70:
863 GET_REGL((int32_t)env->active_fpu.fcr31);
864 case 71:
865 GET_REGL((int32_t)env->active_fpu.fcr0);
pbrook56aebc82008-10-11 17:55:29 +0000866 }
867 }
868 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200869 case 32:
870 GET_REGL((int32_t)env->CP0_Status);
871 case 33:
872 GET_REGL(env->active_tc.LO[0]);
873 case 34:
874 GET_REGL(env->active_tc.HI[0]);
875 case 35:
876 GET_REGL(env->CP0_BadVAddr);
877 case 36:
878 GET_REGL((int32_t)env->CP0_Cause);
879 case 37:
880 GET_REGL(env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16));
881 case 72:
882 GET_REGL(0); /* fp */
883 case 89:
884 GET_REGL((int32_t)env->CP0_PRid);
pbrook56aebc82008-10-11 17:55:29 +0000885 }
886 if (n >= 73 && n <= 88) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200887 /* 16 embedded regs. */
888 GET_REGL(0);
pbrook56aebc82008-10-11 17:55:29 +0000889 }
ths36d23952007-02-28 22:37:42 +0000890
pbrook56aebc82008-10-11 17:55:29 +0000891 return 0;
bellard6f970bd2005-12-05 19:55:19 +0000892}
893
ths8e33c082006-12-11 19:22:27 +0000894/* convert MIPS rounding mode in FCR31 to IEEE library */
Andreas Färber47d74ef2013-07-07 11:17:26 +0200895static unsigned int ieee_rm[] = {
ths8e33c082006-12-11 19:22:27 +0000896 float_round_nearest_even,
897 float_round_to_zero,
898 float_round_up,
899 float_round_down
Andreas Färber47d74ef2013-07-07 11:17:26 +0200900};
ths8e33c082006-12-11 19:22:27 +0000901#define RESTORE_ROUNDING_MODE \
Andreas Färber47d74ef2013-07-07 11:17:26 +0200902 set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \
903 &env->active_fpu.fp_status)
ths8e33c082006-12-11 19:22:27 +0000904
Andreas Färberf3840912012-02-20 06:44:56 +0100905static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
bellard6f970bd2005-12-05 19:55:19 +0000906{
pbrook56aebc82008-10-11 17:55:29 +0000907 target_ulong tmp;
bellard6f970bd2005-12-05 19:55:19 +0000908
pbrook56aebc82008-10-11 17:55:29 +0000909 tmp = ldtul_p(mem_buf);
bellard6f970bd2005-12-05 19:55:19 +0000910
pbrook56aebc82008-10-11 17:55:29 +0000911 if (n < 32) {
912 env->active_tc.gpr[n] = tmp;
913 return sizeof(target_ulong);
914 }
915 if (env->CP0_Config1 & (1 << CP0C1_FP)
916 && n >= 38 && n < 73) {
917 if (n < 70) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200918 if (env->CP0_Status & (1 << CP0St_FR)) {
919 env->active_fpu.fpr[n - 38].d = tmp;
920 } else {
921 env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
922 }
pbrook56aebc82008-10-11 17:55:29 +0000923 }
924 switch (n) {
925 case 70:
926 env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
927 /* set rounding mode */
928 RESTORE_ROUNDING_MODE;
pbrook56aebc82008-10-11 17:55:29 +0000929 break;
Andreas Färber47d74ef2013-07-07 11:17:26 +0200930 case 71:
931 env->active_fpu.fcr0 = tmp;
932 break;
pbrook56aebc82008-10-11 17:55:29 +0000933 }
934 return sizeof(target_ulong);
935 }
936 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +0200937 case 32:
938 env->CP0_Status = tmp;
939 break;
940 case 33:
941 env->active_tc.LO[0] = tmp;
942 break;
943 case 34:
944 env->active_tc.HI[0] = tmp;
945 break;
946 case 35:
947 env->CP0_BadVAddr = tmp;
948 break;
949 case 36:
950 env->CP0_Cause = tmp;
951 break;
Nathan Froydff1d1972009-12-08 08:06:30 -0800952 case 37:
953 env->active_tc.PC = tmp & ~(target_ulong)1;
954 if (tmp & 1) {
955 env->hflags |= MIPS_HFLAG_M16;
956 } else {
957 env->hflags &= ~(MIPS_HFLAG_M16);
958 }
959 break;
Andreas Färber47d74ef2013-07-07 11:17:26 +0200960 case 72: /* fp, ignored */
961 break;
962 default:
963 if (n > 89) {
964 return 0;
965 }
966 /* Other registers are readonly. Ignore writes. */
967 break;
pbrook56aebc82008-10-11 17:55:29 +0000968 }
969
970 return sizeof(target_ulong);
bellard6f970bd2005-12-05 19:55:19 +0000971}
Jia Liufc043552012-07-20 15:50:50 +0800972#elif defined(TARGET_OPENRISC)
973
Jia Liufc043552012-07-20 15:50:50 +0800974static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
975{
976 if (n < 32) {
977 GET_REG32(env->gpr[n]);
978 } else {
979 switch (n) {
980 case 32: /* PPC */
981 GET_REG32(env->ppc);
Jia Liufc043552012-07-20 15:50:50 +0800982
983 case 33: /* NPC */
984 GET_REG32(env->npc);
Jia Liufc043552012-07-20 15:50:50 +0800985
986 case 34: /* SR */
987 GET_REG32(env->sr);
Jia Liufc043552012-07-20 15:50:50 +0800988
989 default:
990 break;
991 }
992 }
993 return 0;
994}
995
996static int cpu_gdb_write_register(CPUOpenRISCState *env,
997 uint8_t *mem_buf, int n)
998{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200999 OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
1000 CPUClass *cc = CPU_GET_CLASS(cpu);
Jia Liufc043552012-07-20 15:50:50 +08001001 uint32_t tmp;
1002
Andreas Färbera0e372f2013-06-28 23:18:47 +02001003 if (n > cc->gdb_num_core_regs) {
Jia Liufc043552012-07-20 15:50:50 +08001004 return 0;
1005 }
1006
1007 tmp = ldl_p(mem_buf);
1008
1009 if (n < 32) {
1010 env->gpr[n] = tmp;
1011 } else {
1012 switch (n) {
1013 case 32: /* PPC */
1014 env->ppc = tmp;
1015 break;
1016
1017 case 33: /* NPC */
1018 env->npc = tmp;
1019 break;
1020
1021 case 34: /* SR */
1022 env->sr = tmp;
1023 break;
1024
1025 default:
1026 break;
1027 }
1028 }
1029 return 4;
1030}
bellardfdf9b3e2006-04-27 21:07:38 +00001031#elif defined (TARGET_SH4)
ths6ef99fc2007-05-13 16:36:24 +00001032
1033/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
pbrook56aebc82008-10-11 17:55:29 +00001034/* FIXME: We should use XML for this. */
ths6ef99fc2007-05-13 16:36:24 +00001035
Andreas Färberf3840912012-02-20 06:44:56 +01001036static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
bellardfdf9b3e2006-04-27 21:07:38 +00001037{
Aurelien Jarnoeca5c302012-09-16 13:12:21 +02001038 switch (n) {
1039 case 0 ... 7:
pbrook56aebc82008-10-11 17:55:29 +00001040 if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
1041 GET_REGL(env->gregs[n + 16]);
1042 } else {
1043 GET_REGL(env->gregs[n]);
1044 }
Aurelien Jarnoeca5c302012-09-16 13:12:21 +02001045 case 8 ... 15:
takasi-y@ops.dti.ne.jpe192a452010-02-18 00:53:29 +09001046 GET_REGL(env->gregs[n]);
Aurelien Jarnoeca5c302012-09-16 13:12:21 +02001047 case 16:
1048 GET_REGL(env->pc);
1049 case 17:
1050 GET_REGL(env->pr);
1051 case 18:
1052 GET_REGL(env->gbr);
1053 case 19:
1054 GET_REGL(env->vbr);
1055 case 20:
1056 GET_REGL(env->mach);
1057 case 21:
1058 GET_REGL(env->macl);
1059 case 22:
1060 GET_REGL(env->sr);
1061 case 23:
1062 GET_REGL(env->fpul);
1063 case 24:
1064 GET_REGL(env->fpscr);
1065 case 25 ... 40:
1066 if (env->fpscr & FPSCR_FR) {
1067 stfl_p(mem_buf, env->fregs[n - 9]);
1068 } else {
1069 stfl_p(mem_buf, env->fregs[n - 25]);
1070 }
1071 return 4;
1072 case 41:
1073 GET_REGL(env->ssr);
1074 case 42:
1075 GET_REGL(env->spc);
1076 case 43 ... 50:
1077 GET_REGL(env->gregs[n - 43]);
1078 case 51 ... 58:
1079 GET_REGL(env->gregs[n - (51 - 16)]);
pbrook56aebc82008-10-11 17:55:29 +00001080 }
bellardfdf9b3e2006-04-27 21:07:38 +00001081
pbrook56aebc82008-10-11 17:55:29 +00001082 return 0;
bellardfdf9b3e2006-04-27 21:07:38 +00001083}
1084
Andreas Färberf3840912012-02-20 06:44:56 +01001085static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
bellardfdf9b3e2006-04-27 21:07:38 +00001086{
pbrook56aebc82008-10-11 17:55:29 +00001087 switch (n) {
Aurelien Jarnoeca5c302012-09-16 13:12:21 +02001088 case 0 ... 7:
1089 if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
1090 env->gregs[n + 16] = ldl_p(mem_buf);
1091 } else {
1092 env->gregs[n] = ldl_p(mem_buf);
1093 }
1094 break;
1095 case 8 ... 15:
1096 env->gregs[n] = ldl_p(mem_buf);
1097 break;
1098 case 16:
1099 env->pc = ldl_p(mem_buf);
1100 break;
1101 case 17:
1102 env->pr = ldl_p(mem_buf);
1103 break;
1104 case 18:
1105 env->gbr = ldl_p(mem_buf);
1106 break;
1107 case 19:
1108 env->vbr = ldl_p(mem_buf);
1109 break;
1110 case 20:
1111 env->mach = ldl_p(mem_buf);
1112 break;
1113 case 21:
1114 env->macl = ldl_p(mem_buf);
1115 break;
1116 case 22:
1117 env->sr = ldl_p(mem_buf);
1118 break;
1119 case 23:
1120 env->fpul = ldl_p(mem_buf);
1121 break;
1122 case 24:
1123 env->fpscr = ldl_p(mem_buf);
1124 break;
1125 case 25 ... 40:
1126 if (env->fpscr & FPSCR_FR) {
1127 env->fregs[n - 9] = ldfl_p(mem_buf);
1128 } else {
1129 env->fregs[n - 25] = ldfl_p(mem_buf);
1130 }
1131 break;
1132 case 41:
1133 env->ssr = ldl_p(mem_buf);
1134 break;
1135 case 42:
1136 env->spc = ldl_p(mem_buf);
1137 break;
1138 case 43 ... 50:
1139 env->gregs[n - 43] = ldl_p(mem_buf);
1140 break;
1141 case 51 ... 58:
1142 env->gregs[n - (51 - 16)] = ldl_p(mem_buf);
1143 break;
Andreas Färber47d74ef2013-07-07 11:17:26 +02001144 default:
1145 return 0;
pbrook56aebc82008-10-11 17:55:29 +00001146 }
1147
1148 return 4;
bellardfdf9b3e2006-04-27 21:07:38 +00001149}
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001150#elif defined (TARGET_MICROBLAZE)
1151
Andreas Färberf3840912012-02-20 06:44:56 +01001152static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001153{
1154 if (n < 32) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001155 GET_REG32(env->regs[n]);
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001156 } else {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001157 GET_REG32(env->sregs[n - 32]);
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001158 }
1159 return 0;
1160}
1161
Andreas Färberf3840912012-02-20 06:44:56 +01001162static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001163{
Andreas Färbera0e372f2013-06-28 23:18:47 +02001164 MicroBlazeCPU *cpu = mb_env_get_cpu(env);
1165 CPUClass *cc = CPU_GET_CLASS(cpu);
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001166 uint32_t tmp;
1167
Andreas Färbera0e372f2013-06-28 23:18:47 +02001168 if (n > cc->gdb_num_core_regs) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001169 return 0;
1170 }
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001171
1172 tmp = ldl_p(mem_buf);
1173
1174 if (n < 32) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001175 env->regs[n] = tmp;
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001176 } else {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001177 env->sregs[n - 32] = tmp;
Edgar E. Iglesiasd74d6a92009-05-20 20:16:31 +02001178 }
1179 return 4;
1180}
thsf1ccf902007-10-08 13:16:14 +00001181#elif defined (TARGET_CRIS)
1182
Edgar E. Iglesias4a0b59f2010-02-20 19:51:56 +01001183static int
Andreas Färberf3840912012-02-20 06:44:56 +01001184read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n)
Edgar E. Iglesias4a0b59f2010-02-20 19:51:56 +01001185{
1186 if (n < 15) {
1187 GET_REG32(env->regs[n]);
1188 }
1189
1190 if (n == 15) {
1191 GET_REG32(env->pc);
1192 }
1193
1194 if (n < 32) {
1195 switch (n) {
1196 case 16:
1197 GET_REG8(env->pregs[n - 16]);
Edgar E. Iglesias4a0b59f2010-02-20 19:51:56 +01001198 case 17:
1199 GET_REG8(env->pregs[n - 16]);
Edgar E. Iglesias4a0b59f2010-02-20 19:51:56 +01001200 case 20:
1201 case 21:
1202 GET_REG16(env->pregs[n - 16]);
Edgar E. Iglesias4a0b59f2010-02-20 19:51:56 +01001203 default:
1204 if (n >= 23) {
1205 GET_REG32(env->pregs[n - 16]);
1206 }
1207 break;
1208 }
1209 }
1210 return 0;
1211}
1212
Andreas Färberf3840912012-02-20 06:44:56 +01001213static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n)
thsf1ccf902007-10-08 13:16:14 +00001214{
pbrook56aebc82008-10-11 17:55:29 +00001215 uint8_t srs;
1216
Andreas Färber47d74ef2013-07-07 11:17:26 +02001217 if (env->pregs[PR_VR] < 32) {
Edgar E. Iglesias4a0b59f2010-02-20 19:51:56 +01001218 return read_register_crisv10(env, mem_buf, n);
Andreas Färber47d74ef2013-07-07 11:17:26 +02001219 }
Edgar E. Iglesias4a0b59f2010-02-20 19:51:56 +01001220
pbrook56aebc82008-10-11 17:55:29 +00001221 srs = env->pregs[PR_SRS];
1222 if (n < 16) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001223 GET_REG32(env->regs[n]);
pbrook56aebc82008-10-11 17:55:29 +00001224 }
1225
1226 if (n >= 21 && n < 32) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001227 GET_REG32(env->pregs[n - 16]);
pbrook56aebc82008-10-11 17:55:29 +00001228 }
1229 if (n >= 33 && n < 49) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001230 GET_REG32(env->sregs[srs][n - 33]);
pbrook56aebc82008-10-11 17:55:29 +00001231 }
1232 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001233 case 16:
1234 GET_REG8(env->pregs[0]);
1235 case 17:
1236 GET_REG8(env->pregs[1]);
1237 case 18:
1238 GET_REG32(env->pregs[2]);
1239 case 19:
1240 GET_REG8(srs);
1241 case 20:
1242 GET_REG16(env->pregs[4]);
1243 case 32:
1244 GET_REG32(env->pc);
pbrook56aebc82008-10-11 17:55:29 +00001245 }
1246
1247 return 0;
thsf1ccf902007-10-08 13:16:14 +00001248}
1249
Andreas Färberf3840912012-02-20 06:44:56 +01001250static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n)
thsf1ccf902007-10-08 13:16:14 +00001251{
pbrook56aebc82008-10-11 17:55:29 +00001252 uint32_t tmp;
thsf1ccf902007-10-08 13:16:14 +00001253
Andreas Färber47d74ef2013-07-07 11:17:26 +02001254 if (n > 49) {
1255 return 0;
1256 }
thsf1ccf902007-10-08 13:16:14 +00001257
pbrook56aebc82008-10-11 17:55:29 +00001258 tmp = ldl_p(mem_buf);
thsf1ccf902007-10-08 13:16:14 +00001259
pbrook56aebc82008-10-11 17:55:29 +00001260 if (n < 16) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001261 env->regs[n] = tmp;
pbrook56aebc82008-10-11 17:55:29 +00001262 }
thsf1ccf902007-10-08 13:16:14 +00001263
edgar_igld7b69672008-10-11 19:32:21 +00001264 if (n >= 21 && n < 32) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001265 env->pregs[n - 16] = tmp;
edgar_igld7b69672008-10-11 19:32:21 +00001266 }
1267
1268 /* FIXME: Should support function regs be writable? */
pbrook56aebc82008-10-11 17:55:29 +00001269 switch (n) {
Andreas Färber47d74ef2013-07-07 11:17:26 +02001270 case 16:
1271 return 1;
1272 case 17:
1273 return 1;
1274 case 18:
1275 env->pregs[PR_PID] = tmp;
1276 break;
1277 case 19:
1278 return 1;
1279 case 20:
1280 return 2;
1281 case 32:
1282 env->pc = tmp;
1283 break;
pbrook56aebc82008-10-11 17:55:29 +00001284 }
thsf1ccf902007-10-08 13:16:14 +00001285
pbrook56aebc82008-10-11 17:55:29 +00001286 return 4;
thsf1ccf902007-10-08 13:16:14 +00001287}
aurel3219bf5172008-12-07 23:26:32 +00001288#elif defined (TARGET_ALPHA)
1289
Andreas Färberf3840912012-02-20 06:44:56 +01001290static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
aurel3219bf5172008-12-07 23:26:32 +00001291{
Richard Henderson7c5a90d2009-12-31 11:54:01 -08001292 uint64_t val;
1293 CPU_DoubleU d;
aurel3219bf5172008-12-07 23:26:32 +00001294
Richard Henderson7c5a90d2009-12-31 11:54:01 -08001295 switch (n) {
1296 case 0 ... 30:
1297 val = env->ir[n];
1298 break;
1299 case 32 ... 62:
1300 d.d = env->fir[n - 32];
1301 val = d.ll;
1302 break;
1303 case 63:
1304 val = cpu_alpha_load_fpcr(env);
1305 break;
1306 case 64:
1307 val = env->pc;
1308 break;
1309 case 66:
1310 val = env->unique;
1311 break;
1312 case 31:
1313 case 65:
1314 /* 31 really is the zero register; 65 is unassigned in the
1315 gdb protocol, but is still required to occupy 8 bytes. */
1316 val = 0;
1317 break;
1318 default:
1319 return 0;
aurel3219bf5172008-12-07 23:26:32 +00001320 }
Richard Henderson7c5a90d2009-12-31 11:54:01 -08001321 GET_REGL(val);
aurel3219bf5172008-12-07 23:26:32 +00001322}
1323
Andreas Färberf3840912012-02-20 06:44:56 +01001324static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
aurel3219bf5172008-12-07 23:26:32 +00001325{
Richard Henderson7c5a90d2009-12-31 11:54:01 -08001326 target_ulong tmp = ldtul_p(mem_buf);
1327 CPU_DoubleU d;
aurel3219bf5172008-12-07 23:26:32 +00001328
Richard Henderson7c5a90d2009-12-31 11:54:01 -08001329 switch (n) {
1330 case 0 ... 30:
aurel3219bf5172008-12-07 23:26:32 +00001331 env->ir[n] = tmp;
Richard Henderson7c5a90d2009-12-31 11:54:01 -08001332 break;
1333 case 32 ... 62:
1334 d.ll = tmp;
1335 env->fir[n - 32] = d.d;
1336 break;
1337 case 63:
1338 cpu_alpha_store_fpcr(env, tmp);
1339 break;
1340 case 64:
1341 env->pc = tmp;
1342 break;
1343 case 66:
1344 env->unique = tmp;
1345 break;
1346 case 31:
1347 case 65:
1348 /* 31 really is the zero register; 65 is unassigned in the
1349 gdb protocol, but is still required to occupy 8 bytes. */
1350 break;
1351 default:
1352 return 0;
aurel3219bf5172008-12-07 23:26:32 +00001353 }
aurel3219bf5172008-12-07 23:26:32 +00001354 return 8;
1355}
Alexander Grafafcb0e42009-12-05 12:44:29 +01001356#elif defined (TARGET_S390X)
1357
Andreas Färberf3840912012-02-20 06:44:56 +01001358static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n)
Alexander Grafafcb0e42009-12-05 12:44:29 +01001359{
Richard Henderson6ee77b12012-08-23 10:44:45 -07001360 uint64_t val;
1361 int cc_op;
1362
Alexander Grafafcb0e42009-12-05 12:44:29 +01001363 switch (n) {
Richard Henderson6ee77b12012-08-23 10:44:45 -07001364 case S390_PSWM_REGNUM:
1365 cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr);
1366 val = deposit64(env->psw.mask, 44, 2, cc_op);
1367 GET_REGL(val);
Richard Henderson6ee77b12012-08-23 10:44:45 -07001368 case S390_PSWA_REGNUM:
1369 GET_REGL(env->psw.addr);
Richard Henderson6ee77b12012-08-23 10:44:45 -07001370 case S390_R0_REGNUM ... S390_R15_REGNUM:
1371 GET_REGL(env->regs[n-S390_R0_REGNUM]);
Richard Henderson6ee77b12012-08-23 10:44:45 -07001372 case S390_A0_REGNUM ... S390_A15_REGNUM:
1373 GET_REG32(env->aregs[n-S390_A0_REGNUM]);
Richard Henderson6ee77b12012-08-23 10:44:45 -07001374 case S390_FPC_REGNUM:
1375 GET_REG32(env->fpc);
Richard Henderson6ee77b12012-08-23 10:44:45 -07001376 case S390_F0_REGNUM ... S390_F15_REGNUM:
1377 GET_REG64(env->fregs[n-S390_F0_REGNUM].ll);
Alexander Grafafcb0e42009-12-05 12:44:29 +01001378 }
1379
1380 return 0;
1381}
1382
Andreas Färberf3840912012-02-20 06:44:56 +01001383static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
Alexander Grafafcb0e42009-12-05 12:44:29 +01001384{
1385 target_ulong tmpl;
1386 uint32_t tmp32;
1387 int r = 8;
1388 tmpl = ldtul_p(mem_buf);
1389 tmp32 = ldl_p(mem_buf);
1390
1391 switch (n) {
Richard Henderson6ee77b12012-08-23 10:44:45 -07001392 case S390_PSWM_REGNUM:
1393 env->psw.mask = tmpl;
1394 env->cc_op = extract64(tmpl, 44, 2);
1395 break;
1396 case S390_PSWA_REGNUM:
1397 env->psw.addr = tmpl;
1398 break;
1399 case S390_R0_REGNUM ... S390_R15_REGNUM:
1400 env->regs[n-S390_R0_REGNUM] = tmpl;
1401 break;
1402 case S390_A0_REGNUM ... S390_A15_REGNUM:
1403 env->aregs[n-S390_A0_REGNUM] = tmp32;
1404 r = 4;
1405 break;
1406 case S390_FPC_REGNUM:
1407 env->fpc = tmp32;
1408 r = 4;
1409 break;
1410 case S390_F0_REGNUM ... S390_F15_REGNUM:
1411 env->fregs[n-S390_F0_REGNUM].ll = tmpl;
1412 break;
1413 default:
1414 return 0;
Alexander Grafafcb0e42009-12-05 12:44:29 +01001415 }
Alexander Grafafcb0e42009-12-05 12:44:29 +01001416 return r;
1417}
Michael Walle0c45d3d2011-02-17 23:45:06 +01001418#elif defined (TARGET_LM32)
1419
Paolo Bonzini0d09e412013-02-05 17:06:20 +01001420#include "hw/lm32/lm32_pic.h"
Michael Walle0c45d3d2011-02-17 23:45:06 +01001421
Andreas Färberf3840912012-02-20 06:44:56 +01001422static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
Michael Walle0c45d3d2011-02-17 23:45:06 +01001423{
1424 if (n < 32) {
1425 GET_REG32(env->regs[n]);
1426 } else {
1427 switch (n) {
1428 case 32:
1429 GET_REG32(env->pc);
Michael Walle0c45d3d2011-02-17 23:45:06 +01001430 /* FIXME: put in right exception ID */
1431 case 33:
1432 GET_REG32(0);
Michael Walle0c45d3d2011-02-17 23:45:06 +01001433 case 34:
1434 GET_REG32(env->eba);
Michael Walle0c45d3d2011-02-17 23:45:06 +01001435 case 35:
1436 GET_REG32(env->deba);
Michael Walle0c45d3d2011-02-17 23:45:06 +01001437 case 36:
1438 GET_REG32(env->ie);
Michael Walle0c45d3d2011-02-17 23:45:06 +01001439 case 37:
1440 GET_REG32(lm32_pic_get_im(env->pic_state));
Michael Walle0c45d3d2011-02-17 23:45:06 +01001441 case 38:
1442 GET_REG32(lm32_pic_get_ip(env->pic_state));
Michael Walle0c45d3d2011-02-17 23:45:06 +01001443 }
1444 }
1445 return 0;
1446}
1447
Andreas Färberf3840912012-02-20 06:44:56 +01001448static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
Michael Walle0c45d3d2011-02-17 23:45:06 +01001449{
Andreas Färbera0e372f2013-06-28 23:18:47 +02001450 LM32CPU *cpu = lm32_env_get_cpu(env);
1451 CPUClass *cc = CPU_GET_CLASS(cpu);
Michael Walle0c45d3d2011-02-17 23:45:06 +01001452 uint32_t tmp;
1453
Andreas Färbera0e372f2013-06-28 23:18:47 +02001454 if (n > cc->gdb_num_core_regs) {
Michael Walle0c45d3d2011-02-17 23:45:06 +01001455 return 0;
1456 }
1457
1458 tmp = ldl_p(mem_buf);
1459
1460 if (n < 32) {
1461 env->regs[n] = tmp;
1462 } else {
1463 switch (n) {
1464 case 32:
1465 env->pc = tmp;
1466 break;
1467 case 34:
1468 env->eba = tmp;
1469 break;
1470 case 35:
1471 env->deba = tmp;
1472 break;
1473 case 36:
1474 env->ie = tmp;
1475 break;
1476 case 37:
1477 lm32_pic_set_im(env->pic_state, tmp);
1478 break;
1479 case 38:
1480 lm32_pic_set_ip(env->pic_state, tmp);
1481 break;
1482 }
1483 }
1484 return 4;
1485}
Max Filippovccfcaba2011-09-06 03:55:52 +04001486#elif defined(TARGET_XTENSA)
1487
Andreas Färberf3840912012-02-20 06:44:56 +01001488static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
Max Filippovccfcaba2011-09-06 03:55:52 +04001489{
1490 const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
1491
1492 if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
1493 return 0;
1494 }
1495
1496 switch (reg->type) {
1497 case 9: /*pc*/
1498 GET_REG32(env->pc);
Max Filippovccfcaba2011-09-06 03:55:52 +04001499
1500 case 1: /*ar*/
1501 xtensa_sync_phys_from_window(env);
1502 GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]);
Max Filippovccfcaba2011-09-06 03:55:52 +04001503
1504 case 2: /*SR*/
1505 GET_REG32(env->sregs[reg->targno & 0xff]);
Max Filippovccfcaba2011-09-06 03:55:52 +04001506
1507 case 3: /*UR*/
1508 GET_REG32(env->uregs[reg->targno & 0xff]);
Max Filippovccfcaba2011-09-06 03:55:52 +04001509
Max Filippovdd519cb2012-09-19 04:23:54 +04001510 case 4: /*f*/
1511 GET_REG32(float32_val(env->fregs[reg->targno & 0x0f]));
Max Filippovdd519cb2012-09-19 04:23:54 +04001512
Max Filippovccfcaba2011-09-06 03:55:52 +04001513 case 8: /*a*/
1514 GET_REG32(env->regs[reg->targno & 0x0f]);
Max Filippovccfcaba2011-09-06 03:55:52 +04001515
1516 default:
1517 qemu_log("%s from reg %d of unsupported type %d\n",
Andreas Färber47d74ef2013-07-07 11:17:26 +02001518 __func__, n, reg->type);
Max Filippovccfcaba2011-09-06 03:55:52 +04001519 return 0;
1520 }
1521}
1522
Andreas Färberf3840912012-02-20 06:44:56 +01001523static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
Max Filippovccfcaba2011-09-06 03:55:52 +04001524{
1525 uint32_t tmp;
1526 const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
1527
1528 if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
1529 return 0;
1530 }
1531
1532 tmp = ldl_p(mem_buf);
1533
1534 switch (reg->type) {
1535 case 9: /*pc*/
1536 env->pc = tmp;
1537 break;
1538
1539 case 1: /*ar*/
1540 env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
1541 xtensa_sync_window_from_phys(env);
1542 break;
1543
1544 case 2: /*SR*/
1545 env->sregs[reg->targno & 0xff] = tmp;
1546 break;
1547
1548 case 3: /*UR*/
1549 env->uregs[reg->targno & 0xff] = tmp;
1550 break;
1551
Max Filippovdd519cb2012-09-19 04:23:54 +04001552 case 4: /*f*/
1553 env->fregs[reg->targno & 0x0f] = make_float32(tmp);
1554 break;
1555
Max Filippovccfcaba2011-09-06 03:55:52 +04001556 case 8: /*a*/
1557 env->regs[reg->targno & 0x0f] = tmp;
1558 break;
1559
1560 default:
1561 qemu_log("%s to reg %d of unsupported type %d\n",
Andreas Färber47d74ef2013-07-07 11:17:26 +02001562 __func__, n, reg->type);
Max Filippovccfcaba2011-09-06 03:55:52 +04001563 return 0;
1564 }
1565
1566 return 4;
1567}
bellard1fddef42005-04-17 19:16:13 +00001568#else
pbrook56aebc82008-10-11 17:55:29 +00001569
Andreas Färber9349b4f2012-03-14 01:38:32 +01001570static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n)
bellard6da41ea2004-01-04 15:48:38 +00001571{
1572 return 0;
1573}
1574
Andreas Färber9349b4f2012-03-14 01:38:32 +01001575static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n)
bellard6da41ea2004-01-04 15:48:38 +00001576{
pbrook56aebc82008-10-11 17:55:29 +00001577 return 0;
bellard6da41ea2004-01-04 15:48:38 +00001578}
1579
1580#endif
bellardb4608c02003-06-27 17:34:32 +00001581
pbrook56aebc82008-10-11 17:55:29 +00001582#ifdef GDB_CORE_XML
1583/* Encode data using the encoding for 'x' packets. */
1584static int memtox(char *buf, const char *mem, int len)
1585{
1586 char *p = buf;
1587 char c;
1588
1589 while (len--) {
1590 c = *(mem++);
1591 switch (c) {
1592 case '#': case '$': case '*': case '}':
1593 *(p++) = '}';
1594 *(p++) = c ^ 0x20;
1595 break;
1596 default:
1597 *(p++) = c;
1598 break;
1599 }
1600 }
1601 return p - buf;
1602}
1603
aurel323faf7782008-12-07 23:26:17 +00001604static const char *get_feature_xml(const char *p, const char **newp)
pbrook56aebc82008-10-11 17:55:29 +00001605{
pbrook56aebc82008-10-11 17:55:29 +00001606 size_t len;
1607 int i;
1608 const char *name;
1609 static char target_xml[1024];
1610
1611 len = 0;
1612 while (p[len] && p[len] != ':')
1613 len++;
1614 *newp = p + len;
1615
1616 name = NULL;
1617 if (strncmp(p, "target.xml", len) == 0) {
1618 /* Generate the XML description for this CPU. */
1619 if (!target_xml[0]) {
1620 GDBRegisterState *r;
Andreas Färbereac8b352013-06-28 21:11:37 +02001621 CPUState *cpu = first_cpu;
pbrook56aebc82008-10-11 17:55:29 +00001622
blueswir15b3715b2008-10-25 11:18:12 +00001623 snprintf(target_xml, sizeof(target_xml),
1624 "<?xml version=\"1.0\"?>"
1625 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
1626 "<target>"
1627 "<xi:include href=\"%s\"/>",
1628 GDB_CORE_XML);
pbrook56aebc82008-10-11 17:55:29 +00001629
Andreas Färbereac8b352013-06-28 21:11:37 +02001630 for (r = cpu->gdb_regs; r; r = r->next) {
blueswir12dc766d2009-04-13 16:06:19 +00001631 pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
1632 pstrcat(target_xml, sizeof(target_xml), r->xml);
1633 pstrcat(target_xml, sizeof(target_xml), "\"/>");
pbrook56aebc82008-10-11 17:55:29 +00001634 }
blueswir12dc766d2009-04-13 16:06:19 +00001635 pstrcat(target_xml, sizeof(target_xml), "</target>");
pbrook56aebc82008-10-11 17:55:29 +00001636 }
1637 return target_xml;
1638 }
1639 for (i = 0; ; i++) {
1640 name = xml_builtin[i][0];
1641 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
1642 break;
1643 }
1644 return name ? xml_builtin[i][1] : NULL;
1645}
1646#endif
1647
Andreas Färber385b9f02013-06-27 18:25:36 +02001648static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +00001649{
Andreas Färbera0e372f2013-06-28 23:18:47 +02001650 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +02001651 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +00001652 GDBRegisterState *r;
1653
Andreas Färbera0e372f2013-06-28 23:18:47 +02001654 if (reg < cc->gdb_num_core_regs) {
pbrook56aebc82008-10-11 17:55:29 +00001655 return cpu_gdb_read_register(env, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +02001656 }
pbrook56aebc82008-10-11 17:55:29 +00001657
Andreas Färbereac8b352013-06-28 21:11:37 +02001658 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +00001659 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
1660 return r->get_reg(env, mem_buf, reg - r->base_reg);
1661 }
1662 }
1663 return 0;
1664}
1665
Andreas Färber385b9f02013-06-27 18:25:36 +02001666static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +00001667{
Andreas Färbera0e372f2013-06-28 23:18:47 +02001668 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +02001669 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +00001670 GDBRegisterState *r;
1671
Andreas Färbera0e372f2013-06-28 23:18:47 +02001672 if (reg < cc->gdb_num_core_regs) {
pbrook56aebc82008-10-11 17:55:29 +00001673 return cpu_gdb_write_register(env, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +02001674 }
pbrook56aebc82008-10-11 17:55:29 +00001675
Andreas Färbereac8b352013-06-28 21:11:37 +02001676 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +00001677 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
1678 return r->set_reg(env, mem_buf, reg - r->base_reg);
1679 }
1680 }
1681 return 0;
1682}
1683
1684/* Register a supplemental set of CPU registers. If g_pos is nonzero it
1685 specifies the first register number and these registers are included in
1686 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
1687 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
1688 */
1689
Andreas Färber22169d42013-06-28 21:27:39 +02001690void gdb_register_coprocessor(CPUState *cpu,
1691 gdb_reg_cb get_reg, gdb_reg_cb set_reg,
1692 int num_regs, const char *xml, int g_pos)
pbrook56aebc82008-10-11 17:55:29 +00001693{
1694 GDBRegisterState *s;
1695 GDBRegisterState **p;
pbrook56aebc82008-10-11 17:55:29 +00001696
Andreas Färbereac8b352013-06-28 21:11:37 +02001697 p = &cpu->gdb_regs;
pbrook56aebc82008-10-11 17:55:29 +00001698 while (*p) {
1699 /* Check for duplicates. */
1700 if (strcmp((*p)->xml, xml) == 0)
1701 return;
1702 p = &(*p)->next;
1703 }
Stefan Weil9643c252011-10-18 22:25:38 +02001704
1705 s = g_new0(GDBRegisterState, 1);
Andreas Färbera0e372f2013-06-28 23:18:47 +02001706 s->base_reg = cpu->gdb_num_regs;
Stefan Weil9643c252011-10-18 22:25:38 +02001707 s->num_regs = num_regs;
1708 s->get_reg = get_reg;
1709 s->set_reg = set_reg;
1710 s->xml = xml;
1711
pbrook56aebc82008-10-11 17:55:29 +00001712 /* Add to end of list. */
Andreas Färbera0e372f2013-06-28 23:18:47 +02001713 cpu->gdb_num_regs += num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001714 *p = s;
1715 if (g_pos) {
1716 if (g_pos != s->base_reg) {
1717 fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
1718 "Expected %d got %d\n", xml, g_pos, s->base_reg);
pbrook56aebc82008-10-11 17:55:29 +00001719 }
1720 }
1721}
1722
aliguoria1d1bb32008-11-18 20:07:32 +00001723#ifndef CONFIG_USER_ONLY
1724static const int xlat_gdb_type[] = {
1725 [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
1726 [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
1727 [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1728};
1729#endif
1730
aliguori880a7572008-11-18 20:30:24 +00001731static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
aliguoria1d1bb32008-11-18 20:07:32 +00001732{
Andreas Färber182735e2013-05-29 22:29:20 +02001733 CPUState *cpu;
Andreas Färber9349b4f2012-03-14 01:38:32 +01001734 CPUArchState *env;
aliguori880a7572008-11-18 20:30:24 +00001735 int err = 0;
1736
Andreas Färber62278812013-06-27 17:12:06 +02001737 if (kvm_enabled()) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001738 return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001739 }
aliguorie22a25c2009-03-12 20:12:48 +00001740
aliguoria1d1bb32008-11-18 20:07:32 +00001741 switch (type) {
1742 case GDB_BREAKPOINT_SW:
1743 case GDB_BREAKPOINT_HW:
Andreas Färber182735e2013-05-29 22:29:20 +02001744 for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
1745 env = cpu->env_ptr;
aliguori880a7572008-11-18 20:30:24 +00001746 err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
1747 if (err)
1748 break;
1749 }
1750 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001751#ifndef CONFIG_USER_ONLY
1752 case GDB_WATCHPOINT_WRITE:
1753 case GDB_WATCHPOINT_READ:
1754 case GDB_WATCHPOINT_ACCESS:
Andreas Färber182735e2013-05-29 22:29:20 +02001755 for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
1756 env = cpu->env_ptr;
aliguori880a7572008-11-18 20:30:24 +00001757 err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
1758 NULL);
1759 if (err)
1760 break;
1761 }
1762 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001763#endif
1764 default:
1765 return -ENOSYS;
1766 }
1767}
1768
aliguori880a7572008-11-18 20:30:24 +00001769static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
aliguoria1d1bb32008-11-18 20:07:32 +00001770{
Andreas Färber182735e2013-05-29 22:29:20 +02001771 CPUState *cpu;
Andreas Färber9349b4f2012-03-14 01:38:32 +01001772 CPUArchState *env;
aliguori880a7572008-11-18 20:30:24 +00001773 int err = 0;
1774
Andreas Färber62278812013-06-27 17:12:06 +02001775 if (kvm_enabled()) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001776 return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001777 }
aliguorie22a25c2009-03-12 20:12:48 +00001778
aliguoria1d1bb32008-11-18 20:07:32 +00001779 switch (type) {
1780 case GDB_BREAKPOINT_SW:
1781 case GDB_BREAKPOINT_HW:
Andreas Färber182735e2013-05-29 22:29:20 +02001782 for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
1783 env = cpu->env_ptr;
aliguori880a7572008-11-18 20:30:24 +00001784 err = cpu_breakpoint_remove(env, addr, BP_GDB);
1785 if (err)
1786 break;
1787 }
1788 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001789#ifndef CONFIG_USER_ONLY
1790 case GDB_WATCHPOINT_WRITE:
1791 case GDB_WATCHPOINT_READ:
1792 case GDB_WATCHPOINT_ACCESS:
Andreas Färber182735e2013-05-29 22:29:20 +02001793 for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
1794 env = cpu->env_ptr;
aliguori880a7572008-11-18 20:30:24 +00001795 err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
1796 if (err)
1797 break;
1798 }
1799 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001800#endif
1801 default:
1802 return -ENOSYS;
1803 }
1804}
1805
aliguori880a7572008-11-18 20:30:24 +00001806static void gdb_breakpoint_remove_all(void)
aliguoria1d1bb32008-11-18 20:07:32 +00001807{
Andreas Färber182735e2013-05-29 22:29:20 +02001808 CPUState *cpu;
Andreas Färber9349b4f2012-03-14 01:38:32 +01001809 CPUArchState *env;
aliguori880a7572008-11-18 20:30:24 +00001810
aliguorie22a25c2009-03-12 20:12:48 +00001811 if (kvm_enabled()) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001812 kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
aliguorie22a25c2009-03-12 20:12:48 +00001813 return;
1814 }
1815
Andreas Färber182735e2013-05-29 22:29:20 +02001816 for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
1817 env = cpu->env_ptr;
aliguori880a7572008-11-18 20:30:24 +00001818 cpu_breakpoint_remove_all(env, BP_GDB);
aliguoria1d1bb32008-11-18 20:07:32 +00001819#ifndef CONFIG_USER_ONLY
aliguori880a7572008-11-18 20:30:24 +00001820 cpu_watchpoint_remove_all(env, BP_GDB);
aliguoria1d1bb32008-11-18 20:07:32 +00001821#endif
aliguori880a7572008-11-18 20:30:24 +00001822 }
aliguoria1d1bb32008-11-18 20:07:32 +00001823}
1824
aurel32fab9d282009-04-08 21:29:37 +00001825static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
1826{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001827 CPUState *cpu = s->c_cpu;
Andreas Färberf45748f2013-06-21 19:09:18 +02001828 CPUClass *cc = CPU_GET_CLASS(cpu);
1829
1830 cpu_synchronize_state(cpu);
1831 if (cc->set_pc) {
1832 cc->set_pc(cpu, pc);
Nathan Froydff1d1972009-12-08 08:06:30 -08001833 }
aurel32fab9d282009-04-08 21:29:37 +00001834}
1835
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001836static CPUState *find_cpu(uint32_t thread_id)
Nathan Froyd1e9fa732009-06-03 11:33:08 -07001837{
Andreas Färber0d342822012-12-17 07:12:13 +01001838 CPUState *cpu;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07001839
Andreas Färber182735e2013-05-29 22:29:20 +02001840 for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
Andreas Färberaa48dd92013-07-09 20:50:52 +02001841 if (cpu_index(cpu) == thread_id) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001842 return cpu;
Andreas Färberaa48dd92013-07-09 20:50:52 +02001843 }
Nathan Froyd1e9fa732009-06-03 11:33:08 -07001844 }
Andreas Färberaa48dd92013-07-09 20:50:52 +02001845
1846 return NULL;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07001847}
1848
aliguori880a7572008-11-18 20:30:24 +00001849static int gdb_handle_packet(GDBState *s, const char *line_buf)
bellardb4608c02003-06-27 17:34:32 +00001850{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001851 CPUState *cpu;
bellardb4608c02003-06-27 17:34:32 +00001852 const char *p;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07001853 uint32_t thread;
1854 int ch, reg_size, type, res;
pbrook56aebc82008-10-11 17:55:29 +00001855 char buf[MAX_PACKET_LENGTH];
1856 uint8_t mem_buf[MAX_PACKET_LENGTH];
1857 uint8_t *registers;
bellard9d9754a2006-06-25 15:32:37 +00001858 target_ulong addr, len;
ths3b46e622007-09-17 08:09:54 +00001859
bellard858693c2004-03-31 18:52:07 +00001860#ifdef DEBUG_GDB
1861 printf("command='%s'\n", line_buf);
bellard4c3a88a2003-07-26 12:06:08 +00001862#endif
bellard858693c2004-03-31 18:52:07 +00001863 p = line_buf;
1864 ch = *p++;
1865 switch(ch) {
1866 case '?':
bellard1fddef42005-04-17 19:16:13 +00001867 /* TODO: Make this return the correct value for user-mode. */
aurel32ca587a82008-12-18 22:44:13 +00001868 snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001869 cpu_index(s->c_cpu));
bellard858693c2004-03-31 18:52:07 +00001870 put_packet(s, buf);
edgar_igl7d03f822008-05-17 18:58:29 +00001871 /* Remove all the breakpoints when this query is issued,
1872 * because gdb is doing and initial connect and the state
1873 * should be cleaned up.
1874 */
aliguori880a7572008-11-18 20:30:24 +00001875 gdb_breakpoint_remove_all();
bellard858693c2004-03-31 18:52:07 +00001876 break;
1877 case 'c':
1878 if (*p != '\0') {
bellard9d9754a2006-06-25 15:32:37 +00001879 addr = strtoull(p, (char **)&p, 16);
aurel32fab9d282009-04-08 21:29:37 +00001880 gdb_set_cpu_pc(s, addr);
bellard858693c2004-03-31 18:52:07 +00001881 }
aurel32ca587a82008-12-18 22:44:13 +00001882 s->signal = 0;
edgar_iglba70a622008-03-14 06:10:42 +00001883 gdb_continue(s);
bellard41625032005-04-24 10:07:11 +00001884 return RS_IDLE;
edgar_igl1f487ee2008-05-17 22:20:53 +00001885 case 'C':
aurel32ca587a82008-12-18 22:44:13 +00001886 s->signal = gdb_signal_to_target (strtoul(p, (char **)&p, 16));
1887 if (s->signal == -1)
1888 s->signal = 0;
edgar_igl1f487ee2008-05-17 22:20:53 +00001889 gdb_continue(s);
1890 return RS_IDLE;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02001891 case 'v':
1892 if (strncmp(p, "Cont", 4) == 0) {
1893 int res_signal, res_thread;
1894
1895 p += 4;
1896 if (*p == '?') {
1897 put_packet(s, "vCont;c;C;s;S");
1898 break;
1899 }
1900 res = 0;
1901 res_signal = 0;
1902 res_thread = 0;
1903 while (*p) {
1904 int action, signal;
1905
1906 if (*p++ != ';') {
1907 res = 0;
1908 break;
1909 }
1910 action = *p++;
1911 signal = 0;
1912 if (action == 'C' || action == 'S') {
1913 signal = strtoul(p, (char **)&p, 16);
1914 } else if (action != 'c' && action != 's') {
1915 res = 0;
1916 break;
1917 }
1918 thread = 0;
1919 if (*p == ':') {
1920 thread = strtoull(p+1, (char **)&p, 16);
1921 }
1922 action = tolower(action);
1923 if (res == 0 || (res == 'c' && action == 's')) {
1924 res = action;
1925 res_signal = signal;
1926 res_thread = thread;
1927 }
1928 }
1929 if (res) {
1930 if (res_thread != -1 && res_thread != 0) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001931 cpu = find_cpu(res_thread);
1932 if (cpu == NULL) {
Jan Kiszkadd32aa12009-06-27 09:53:51 +02001933 put_packet(s, "E22");
1934 break;
1935 }
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001936 s->c_cpu = cpu;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02001937 }
1938 if (res == 's') {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001939 cpu_single_step(s->c_cpu, sstep_flags);
Jan Kiszkadd32aa12009-06-27 09:53:51 +02001940 }
1941 s->signal = res_signal;
1942 gdb_continue(s);
1943 return RS_IDLE;
1944 }
1945 break;
1946 } else {
1947 goto unknown_command;
1948 }
edgar_igl7d03f822008-05-17 18:58:29 +00001949 case 'k':
Jan Kiszka00e94db2012-03-06 18:32:35 +01001950#ifdef CONFIG_USER_ONLY
edgar_igl7d03f822008-05-17 18:58:29 +00001951 /* Kill the target */
1952 fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
1953 exit(0);
Jan Kiszka00e94db2012-03-06 18:32:35 +01001954#endif
edgar_igl7d03f822008-05-17 18:58:29 +00001955 case 'D':
1956 /* Detach packet */
aliguori880a7572008-11-18 20:30:24 +00001957 gdb_breakpoint_remove_all();
Daniel Gutson7ea06da2010-02-26 14:13:50 -03001958 gdb_syscall_mode = GDB_SYS_DISABLED;
edgar_igl7d03f822008-05-17 18:58:29 +00001959 gdb_continue(s);
1960 put_packet(s, "OK");
1961 break;
bellard858693c2004-03-31 18:52:07 +00001962 case 's':
1963 if (*p != '\0') {
ths8fac5802007-07-12 10:05:07 +00001964 addr = strtoull(p, (char **)&p, 16);
aurel32fab9d282009-04-08 21:29:37 +00001965 gdb_set_cpu_pc(s, addr);
bellard858693c2004-03-31 18:52:07 +00001966 }
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001967 cpu_single_step(s->c_cpu, sstep_flags);
edgar_iglba70a622008-03-14 06:10:42 +00001968 gdb_continue(s);
bellard41625032005-04-24 10:07:11 +00001969 return RS_IDLE;
pbrooka2d1eba2007-01-28 03:10:55 +00001970 case 'F':
1971 {
1972 target_ulong ret;
1973 target_ulong err;
1974
1975 ret = strtoull(p, (char **)&p, 16);
1976 if (*p == ',') {
1977 p++;
1978 err = strtoull(p, (char **)&p, 16);
1979 } else {
1980 err = 0;
1981 }
1982 if (*p == ',')
1983 p++;
1984 type = *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00001985 if (s->current_syscall_cb) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001986 s->current_syscall_cb(s->c_cpu, ret, err);
Meador Ingecdb432b2012-03-15 17:49:45 +00001987 s->current_syscall_cb = NULL;
1988 }
pbrooka2d1eba2007-01-28 03:10:55 +00001989 if (type == 'C') {
1990 put_packet(s, "T02");
1991 } else {
edgar_iglba70a622008-03-14 06:10:42 +00001992 gdb_continue(s);
pbrooka2d1eba2007-01-28 03:10:55 +00001993 }
1994 }
1995 break;
bellard858693c2004-03-31 18:52:07 +00001996 case 'g':
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001997 cpu_synchronize_state(s->g_cpu);
pbrook56aebc82008-10-11 17:55:29 +00001998 len = 0;
Andreas Färbera0e372f2013-06-28 23:18:47 +02001999 for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002000 reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
pbrook56aebc82008-10-11 17:55:29 +00002001 len += reg_size;
2002 }
2003 memtohex(buf, mem_buf, len);
bellard858693c2004-03-31 18:52:07 +00002004 put_packet(s, buf);
2005 break;
2006 case 'G':
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002007 cpu_synchronize_state(s->g_cpu);
pbrook56aebc82008-10-11 17:55:29 +00002008 registers = mem_buf;
bellard858693c2004-03-31 18:52:07 +00002009 len = strlen(p) / 2;
2010 hextomem((uint8_t *)registers, p, len);
Andreas Färbera0e372f2013-06-28 23:18:47 +02002011 for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002012 reg_size = gdb_write_register(s->g_cpu, registers, addr);
pbrook56aebc82008-10-11 17:55:29 +00002013 len -= reg_size;
2014 registers += reg_size;
2015 }
bellard858693c2004-03-31 18:52:07 +00002016 put_packet(s, "OK");
2017 break;
2018 case 'm':
bellard9d9754a2006-06-25 15:32:37 +00002019 addr = strtoull(p, (char **)&p, 16);
bellard858693c2004-03-31 18:52:07 +00002020 if (*p == ',')
2021 p++;
bellard9d9754a2006-06-25 15:32:37 +00002022 len = strtoull(p, NULL, 16);
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002023 if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) {
bellard6f970bd2005-12-05 19:55:19 +00002024 put_packet (s, "E14");
2025 } else {
2026 memtohex(buf, mem_buf, len);
2027 put_packet(s, buf);
2028 }
bellard858693c2004-03-31 18:52:07 +00002029 break;
2030 case 'M':
bellard9d9754a2006-06-25 15:32:37 +00002031 addr = strtoull(p, (char **)&p, 16);
bellard858693c2004-03-31 18:52:07 +00002032 if (*p == ',')
2033 p++;
bellard9d9754a2006-06-25 15:32:37 +00002034 len = strtoull(p, (char **)&p, 16);
bellardb328f872005-01-17 22:03:16 +00002035 if (*p == ':')
bellard858693c2004-03-31 18:52:07 +00002036 p++;
2037 hextomem(mem_buf, p, len);
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002038 if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
Andreas Färberf3659ee2013-06-27 19:09:09 +02002039 true) != 0) {
bellard905f20b2005-04-26 21:09:55 +00002040 put_packet(s, "E14");
Fabien Chouteau44520db2011-09-08 12:48:16 +02002041 } else {
bellard858693c2004-03-31 18:52:07 +00002042 put_packet(s, "OK");
Fabien Chouteau44520db2011-09-08 12:48:16 +02002043 }
bellard858693c2004-03-31 18:52:07 +00002044 break;
pbrook56aebc82008-10-11 17:55:29 +00002045 case 'p':
2046 /* Older gdb are really dumb, and don't use 'g' if 'p' is avaialable.
2047 This works, but can be very slow. Anything new enough to
2048 understand XML also knows how to use this properly. */
2049 if (!gdb_has_xml)
2050 goto unknown_command;
2051 addr = strtoull(p, (char **)&p, 16);
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002052 reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);
pbrook56aebc82008-10-11 17:55:29 +00002053 if (reg_size) {
2054 memtohex(buf, mem_buf, reg_size);
2055 put_packet(s, buf);
2056 } else {
2057 put_packet(s, "E14");
2058 }
2059 break;
2060 case 'P':
2061 if (!gdb_has_xml)
2062 goto unknown_command;
2063 addr = strtoull(p, (char **)&p, 16);
2064 if (*p == '=')
2065 p++;
2066 reg_size = strlen(p) / 2;
2067 hextomem(mem_buf, p, reg_size);
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002068 gdb_write_register(s->g_cpu, mem_buf, addr);
pbrook56aebc82008-10-11 17:55:29 +00002069 put_packet(s, "OK");
2070 break;
bellard858693c2004-03-31 18:52:07 +00002071 case 'Z':
bellard858693c2004-03-31 18:52:07 +00002072 case 'z':
2073 type = strtoul(p, (char **)&p, 16);
2074 if (*p == ',')
2075 p++;
bellard9d9754a2006-06-25 15:32:37 +00002076 addr = strtoull(p, (char **)&p, 16);
bellard858693c2004-03-31 18:52:07 +00002077 if (*p == ',')
2078 p++;
bellard9d9754a2006-06-25 15:32:37 +00002079 len = strtoull(p, (char **)&p, 16);
aliguoria1d1bb32008-11-18 20:07:32 +00002080 if (ch == 'Z')
aliguori880a7572008-11-18 20:30:24 +00002081 res = gdb_breakpoint_insert(addr, len, type);
aliguoria1d1bb32008-11-18 20:07:32 +00002082 else
aliguori880a7572008-11-18 20:30:24 +00002083 res = gdb_breakpoint_remove(addr, len, type);
aliguoria1d1bb32008-11-18 20:07:32 +00002084 if (res >= 0)
2085 put_packet(s, "OK");
2086 else if (res == -ENOSYS)
pbrook0f459d12008-06-09 00:20:13 +00002087 put_packet(s, "");
aliguoria1d1bb32008-11-18 20:07:32 +00002088 else
2089 put_packet(s, "E22");
bellard858693c2004-03-31 18:52:07 +00002090 break;
aliguori880a7572008-11-18 20:30:24 +00002091 case 'H':
2092 type = *p++;
2093 thread = strtoull(p, (char **)&p, 16);
2094 if (thread == -1 || thread == 0) {
2095 put_packet(s, "OK");
2096 break;
2097 }
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002098 cpu = find_cpu(thread);
2099 if (cpu == NULL) {
aliguori880a7572008-11-18 20:30:24 +00002100 put_packet(s, "E22");
2101 break;
2102 }
2103 switch (type) {
2104 case 'c':
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002105 s->c_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002106 put_packet(s, "OK");
2107 break;
2108 case 'g':
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002109 s->g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002110 put_packet(s, "OK");
2111 break;
2112 default:
2113 put_packet(s, "E22");
2114 break;
2115 }
2116 break;
2117 case 'T':
2118 thread = strtoull(p, (char **)&p, 16);
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002119 cpu = find_cpu(thread);
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002120
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002121 if (cpu != NULL) {
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002122 put_packet(s, "OK");
2123 } else {
aliguori880a7572008-11-18 20:30:24 +00002124 put_packet(s, "E22");
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002125 }
aliguori880a7572008-11-18 20:30:24 +00002126 break;
pbrook978efd62006-06-17 18:30:42 +00002127 case 'q':
edgar_igl60897d32008-05-09 08:25:14 +00002128 case 'Q':
2129 /* parse any 'q' packets here */
2130 if (!strcmp(p,"qemu.sstepbits")) {
2131 /* Query Breakpoint bit definitions */
blueswir1363a37d2008-08-21 17:58:08 +00002132 snprintf(buf, sizeof(buf), "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
2133 SSTEP_ENABLE,
2134 SSTEP_NOIRQ,
2135 SSTEP_NOTIMER);
edgar_igl60897d32008-05-09 08:25:14 +00002136 put_packet(s, buf);
2137 break;
2138 } else if (strncmp(p,"qemu.sstep",10) == 0) {
2139 /* Display or change the sstep_flags */
2140 p += 10;
2141 if (*p != '=') {
2142 /* Display current setting */
blueswir1363a37d2008-08-21 17:58:08 +00002143 snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
edgar_igl60897d32008-05-09 08:25:14 +00002144 put_packet(s, buf);
2145 break;
2146 }
2147 p++;
2148 type = strtoul(p, (char **)&p, 16);
2149 sstep_flags = type;
2150 put_packet(s, "OK");
2151 break;
aliguori880a7572008-11-18 20:30:24 +00002152 } else if (strcmp(p,"C") == 0) {
2153 /* "Current thread" remains vague in the spec, so always return
2154 * the first CPU (gdb returns the first thread). */
2155 put_packet(s, "QC1");
2156 break;
2157 } else if (strcmp(p,"fThreadInfo") == 0) {
Andreas Färber52f34622013-06-27 13:44:40 +02002158 s->query_cpu = first_cpu;
aliguori880a7572008-11-18 20:30:24 +00002159 goto report_cpuinfo;
2160 } else if (strcmp(p,"sThreadInfo") == 0) {
2161 report_cpuinfo:
2162 if (s->query_cpu) {
Andreas Färber52f34622013-06-27 13:44:40 +02002163 snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
aliguori880a7572008-11-18 20:30:24 +00002164 put_packet(s, buf);
Andreas Färber52f34622013-06-27 13:44:40 +02002165 s->query_cpu = s->query_cpu->next_cpu;
aliguori880a7572008-11-18 20:30:24 +00002166 } else
2167 put_packet(s, "l");
2168 break;
2169 } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
2170 thread = strtoull(p+16, (char **)&p, 16);
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002171 cpu = find_cpu(thread);
2172 if (cpu != NULL) {
Andreas Färbercb446ec2013-05-01 14:24:52 +02002173 cpu_synchronize_state(cpu);
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002174 len = snprintf((char *)mem_buf, sizeof(mem_buf),
Andreas Färber55e5c282012-12-17 06:18:02 +01002175 "CPU#%d [%s]", cpu->cpu_index,
Andreas Färber259186a2013-01-17 18:51:17 +01002176 cpu->halted ? "halted " : "running");
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002177 memtohex(buf, mem_buf, len);
2178 put_packet(s, buf);
2179 }
aliguori880a7572008-11-18 20:30:24 +00002180 break;
edgar_igl60897d32008-05-09 08:25:14 +00002181 }
blueswir10b8a9882009-03-07 10:51:36 +00002182#ifdef CONFIG_USER_ONLY
edgar_igl60897d32008-05-09 08:25:14 +00002183 else if (strncmp(p, "Offsets", 7) == 0) {
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002184 CPUArchState *env = s->c_cpu->env_ptr;
2185 TaskState *ts = env->opaque;
pbrook978efd62006-06-17 18:30:42 +00002186
blueswir1363a37d2008-08-21 17:58:08 +00002187 snprintf(buf, sizeof(buf),
2188 "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
2189 ";Bss=" TARGET_ABI_FMT_lx,
2190 ts->info->code_offset,
2191 ts->info->data_offset,
2192 ts->info->data_offset);
pbrook978efd62006-06-17 18:30:42 +00002193 put_packet(s, buf);
2194 break;
2195 }
blueswir10b8a9882009-03-07 10:51:36 +00002196#else /* !CONFIG_USER_ONLY */
aliguori8a34a0f2009-03-05 23:01:55 +00002197 else if (strncmp(p, "Rcmd,", 5) == 0) {
2198 int len = strlen(p + 5);
2199
2200 if ((len % 2) != 0) {
2201 put_packet(s, "E01");
2202 break;
2203 }
2204 hextomem(mem_buf, p + 5, len);
2205 len = len / 2;
2206 mem_buf[len++] = 0;
Anthony Liguorifa5efcc2011-08-15 11:17:30 -05002207 qemu_chr_be_write(s->mon_chr, mem_buf, len);
aliguori8a34a0f2009-03-05 23:01:55 +00002208 put_packet(s, "OK");
2209 break;
2210 }
blueswir10b8a9882009-03-07 10:51:36 +00002211#endif /* !CONFIG_USER_ONLY */
pbrook56aebc82008-10-11 17:55:29 +00002212 if (strncmp(p, "Supported", 9) == 0) {
blueswir15b3715b2008-10-25 11:18:12 +00002213 snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
pbrook56aebc82008-10-11 17:55:29 +00002214#ifdef GDB_CORE_XML
blueswir12dc766d2009-04-13 16:06:19 +00002215 pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
pbrook56aebc82008-10-11 17:55:29 +00002216#endif
2217 put_packet(s, buf);
2218 break;
2219 }
2220#ifdef GDB_CORE_XML
2221 if (strncmp(p, "Xfer:features:read:", 19) == 0) {
2222 const char *xml;
2223 target_ulong total_len;
2224
2225 gdb_has_xml = 1;
2226 p += 19;
aliguori880a7572008-11-18 20:30:24 +00002227 xml = get_feature_xml(p, &p);
pbrook56aebc82008-10-11 17:55:29 +00002228 if (!xml) {
blueswir15b3715b2008-10-25 11:18:12 +00002229 snprintf(buf, sizeof(buf), "E00");
pbrook56aebc82008-10-11 17:55:29 +00002230 put_packet(s, buf);
2231 break;
2232 }
2233
2234 if (*p == ':')
2235 p++;
2236 addr = strtoul(p, (char **)&p, 16);
2237 if (*p == ',')
2238 p++;
2239 len = strtoul(p, (char **)&p, 16);
2240
2241 total_len = strlen(xml);
2242 if (addr > total_len) {
blueswir15b3715b2008-10-25 11:18:12 +00002243 snprintf(buf, sizeof(buf), "E00");
pbrook56aebc82008-10-11 17:55:29 +00002244 put_packet(s, buf);
2245 break;
2246 }
2247 if (len > (MAX_PACKET_LENGTH - 5) / 2)
2248 len = (MAX_PACKET_LENGTH - 5) / 2;
2249 if (len < total_len - addr) {
2250 buf[0] = 'm';
2251 len = memtox(buf + 1, xml + addr, len);
2252 } else {
2253 buf[0] = 'l';
2254 len = memtox(buf + 1, xml + addr, total_len - addr);
2255 }
2256 put_packet_binary(s, buf, len + 1);
2257 break;
2258 }
2259#endif
2260 /* Unrecognised 'q' command. */
2261 goto unknown_command;
2262
bellard858693c2004-03-31 18:52:07 +00002263 default:
pbrook56aebc82008-10-11 17:55:29 +00002264 unknown_command:
bellard858693c2004-03-31 18:52:07 +00002265 /* put empty packet */
2266 buf[0] = '\0';
2267 put_packet(s, buf);
2268 break;
2269 }
2270 return RS_IDLE;
2271}
2272
Andreas Färber64f6b342013-05-27 02:06:09 +02002273void gdb_set_stop_cpu(CPUState *cpu)
aliguori880a7572008-11-18 20:30:24 +00002274{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002275 gdbserver_state->c_cpu = cpu;
2276 gdbserver_state->g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002277}
2278
bellard1fddef42005-04-17 19:16:13 +00002279#ifndef CONFIG_USER_ONLY
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002280static void gdb_vm_state_change(void *opaque, int running, RunState state)
bellard858693c2004-03-31 18:52:07 +00002281{
aliguori880a7572008-11-18 20:30:24 +00002282 GDBState *s = gdbserver_state;
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002283 CPUArchState *env = s->c_cpu->env_ptr;
2284 CPUState *cpu = s->c_cpu;
bellard858693c2004-03-31 18:52:07 +00002285 char buf[256];
aliguorid6fc1b32008-11-18 19:55:44 +00002286 const char *type;
bellard858693c2004-03-31 18:52:07 +00002287 int ret;
2288
Meador Ingecdb432b2012-03-15 17:49:45 +00002289 if (running || s->state == RS_INACTIVE) {
2290 return;
2291 }
2292 /* Is there a GDB syscall waiting to be sent? */
2293 if (s->current_syscall_cb) {
2294 put_packet(s, s->syscall_buf);
pbrooka2d1eba2007-01-28 03:10:55 +00002295 return;
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002296 }
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002297 switch (state) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002298 case RUN_STATE_DEBUG:
aliguori880a7572008-11-18 20:30:24 +00002299 if (env->watchpoint_hit) {
2300 switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
aliguoria1d1bb32008-11-18 20:07:32 +00002301 case BP_MEM_READ:
aliguorid6fc1b32008-11-18 19:55:44 +00002302 type = "r";
2303 break;
aliguoria1d1bb32008-11-18 20:07:32 +00002304 case BP_MEM_ACCESS:
aliguorid6fc1b32008-11-18 19:55:44 +00002305 type = "a";
2306 break;
2307 default:
2308 type = "";
2309 break;
2310 }
aliguori880a7572008-11-18 20:30:24 +00002311 snprintf(buf, sizeof(buf),
2312 "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
Andreas Färber0d342822012-12-17 07:12:13 +01002313 GDB_SIGNAL_TRAP, cpu_index(cpu), type,
aliguori880a7572008-11-18 20:30:24 +00002314 env->watchpoint_hit->vaddr);
aliguori880a7572008-11-18 20:30:24 +00002315 env->watchpoint_hit = NULL;
Jan Kiszka425189a2011-03-22 11:02:09 +01002316 goto send_packet;
pbrook6658ffb2007-03-16 23:58:11 +00002317 }
Jan Kiszka425189a2011-03-22 11:02:09 +01002318 tb_flush(env);
aurel32ca587a82008-12-18 22:44:13 +00002319 ret = GDB_SIGNAL_TRAP;
Jan Kiszka425189a2011-03-22 11:02:09 +01002320 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002321 case RUN_STATE_PAUSED:
aliguori9781e042009-01-22 17:15:29 +00002322 ret = GDB_SIGNAL_INT;
Jan Kiszka425189a2011-03-22 11:02:09 +01002323 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002324 case RUN_STATE_SHUTDOWN:
Jan Kiszka425189a2011-03-22 11:02:09 +01002325 ret = GDB_SIGNAL_QUIT;
2326 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002327 case RUN_STATE_IO_ERROR:
Jan Kiszka425189a2011-03-22 11:02:09 +01002328 ret = GDB_SIGNAL_IO;
2329 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002330 case RUN_STATE_WATCHDOG:
Jan Kiszka425189a2011-03-22 11:02:09 +01002331 ret = GDB_SIGNAL_ALRM;
2332 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002333 case RUN_STATE_INTERNAL_ERROR:
Jan Kiszka425189a2011-03-22 11:02:09 +01002334 ret = GDB_SIGNAL_ABRT;
2335 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002336 case RUN_STATE_SAVE_VM:
2337 case RUN_STATE_RESTORE_VM:
Jan Kiszka425189a2011-03-22 11:02:09 +01002338 return;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002339 case RUN_STATE_FINISH_MIGRATE:
Jan Kiszka425189a2011-03-22 11:02:09 +01002340 ret = GDB_SIGNAL_XCPU;
2341 break;
2342 default:
2343 ret = GDB_SIGNAL_UNKNOWN;
2344 break;
bellardbbeb7b52006-04-23 18:42:15 +00002345 }
Andreas Färber0d342822012-12-17 07:12:13 +01002346 snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu));
Jan Kiszka425189a2011-03-22 11:02:09 +01002347
2348send_packet:
bellard858693c2004-03-31 18:52:07 +00002349 put_packet(s, buf);
Jan Kiszka425189a2011-03-22 11:02:09 +01002350
2351 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002352 cpu_single_step(cpu, 0);
bellard858693c2004-03-31 18:52:07 +00002353}
bellard1fddef42005-04-17 19:16:13 +00002354#endif
bellard858693c2004-03-31 18:52:07 +00002355
pbrooka2d1eba2007-01-28 03:10:55 +00002356/* Send a gdb syscall request.
2357 This accepts limited printf-style format specifiers, specifically:
pbrooka87295e2007-05-26 15:09:38 +00002358 %x - target_ulong argument printed in hex.
2359 %lx - 64-bit argument printed in hex.
2360 %s - string pointer (target_ulong) and length (int) pair. */
blueswir17ccfb2e2008-09-14 06:45:34 +00002361void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
pbrooka2d1eba2007-01-28 03:10:55 +00002362{
2363 va_list va;
pbrooka2d1eba2007-01-28 03:10:55 +00002364 char *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00002365 char *p_end;
pbrooka2d1eba2007-01-28 03:10:55 +00002366 target_ulong addr;
pbrooka87295e2007-05-26 15:09:38 +00002367 uint64_t i64;
pbrooka2d1eba2007-01-28 03:10:55 +00002368 GDBState *s;
2369
aliguori880a7572008-11-18 20:30:24 +00002370 s = gdbserver_state;
pbrooka2d1eba2007-01-28 03:10:55 +00002371 if (!s)
2372 return;
Meador Ingecdb432b2012-03-15 17:49:45 +00002373 s->current_syscall_cb = cb;
pbrooka2d1eba2007-01-28 03:10:55 +00002374#ifndef CONFIG_USER_ONLY
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002375 vm_stop(RUN_STATE_DEBUG);
pbrooka2d1eba2007-01-28 03:10:55 +00002376#endif
pbrooka2d1eba2007-01-28 03:10:55 +00002377 va_start(va, fmt);
Meador Ingecdb432b2012-03-15 17:49:45 +00002378 p = s->syscall_buf;
2379 p_end = &s->syscall_buf[sizeof(s->syscall_buf)];
pbrooka2d1eba2007-01-28 03:10:55 +00002380 *(p++) = 'F';
2381 while (*fmt) {
2382 if (*fmt == '%') {
2383 fmt++;
2384 switch (*fmt++) {
2385 case 'x':
2386 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002387 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
pbrooka2d1eba2007-01-28 03:10:55 +00002388 break;
pbrooka87295e2007-05-26 15:09:38 +00002389 case 'l':
2390 if (*(fmt++) != 'x')
2391 goto bad_format;
2392 i64 = va_arg(va, uint64_t);
Meador Ingecdb432b2012-03-15 17:49:45 +00002393 p += snprintf(p, p_end - p, "%" PRIx64, i64);
pbrooka87295e2007-05-26 15:09:38 +00002394 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002395 case 's':
2396 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002397 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
blueswir1363a37d2008-08-21 17:58:08 +00002398 addr, va_arg(va, int));
pbrooka2d1eba2007-01-28 03:10:55 +00002399 break;
2400 default:
pbrooka87295e2007-05-26 15:09:38 +00002401 bad_format:
pbrooka2d1eba2007-01-28 03:10:55 +00002402 fprintf(stderr, "gdbstub: Bad syscall format string '%s'\n",
2403 fmt - 1);
2404 break;
2405 }
2406 } else {
2407 *(p++) = *(fmt++);
2408 }
2409 }
pbrook8a93e022007-08-06 13:19:15 +00002410 *p = 0;
pbrooka2d1eba2007-01-28 03:10:55 +00002411 va_end(va);
pbrooka2d1eba2007-01-28 03:10:55 +00002412#ifdef CONFIG_USER_ONLY
Meador Ingecdb432b2012-03-15 17:49:45 +00002413 put_packet(s, s->syscall_buf);
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002414 gdb_handlesig(s->c_cpu, 0);
pbrooka2d1eba2007-01-28 03:10:55 +00002415#else
Meador Ingecdb432b2012-03-15 17:49:45 +00002416 /* In this case wait to send the syscall packet until notification that
2417 the CPU has stopped. This must be done because if the packet is sent
2418 now the reply from the syscall request could be received while the CPU
2419 is still in the running state, which can cause packets to be dropped
2420 and state transition 'T' packets to be sent while the syscall is still
2421 being processed. */
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002422 cpu_exit(s->c_cpu);
pbrooka2d1eba2007-01-28 03:10:55 +00002423#endif
2424}
2425
bellard6a00d602005-11-21 23:25:50 +00002426static void gdb_read_byte(GDBState *s, int ch)
bellard858693c2004-03-31 18:52:07 +00002427{
2428 int i, csum;
ths60fe76f2007-12-16 03:02:09 +00002429 uint8_t reply;
bellard858693c2004-03-31 18:52:07 +00002430
bellard1fddef42005-04-17 19:16:13 +00002431#ifndef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +00002432 if (s->last_packet_len) {
2433 /* Waiting for a response to the last packet. If we see the start
2434 of a new command then abandon the previous response. */
2435 if (ch == '-') {
2436#ifdef DEBUG_GDB
2437 printf("Got NACK, retransmitting\n");
2438#endif
thsffe8ab82007-12-16 03:16:05 +00002439 put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
pbrook4046d912007-01-28 01:53:16 +00002440 }
2441#ifdef DEBUG_GDB
2442 else if (ch == '+')
2443 printf("Got ACK\n");
2444 else
2445 printf("Got '%c' when expecting ACK/NACK\n", ch);
2446#endif
2447 if (ch == '+' || ch == '$')
2448 s->last_packet_len = 0;
2449 if (ch != '$')
2450 return;
2451 }
Luiz Capitulino13548692011-07-29 15:36:43 -03002452 if (runstate_is_running()) {
bellard858693c2004-03-31 18:52:07 +00002453 /* when the CPU is running, we cannot do anything except stop
2454 it when receiving a char */
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002455 vm_stop(RUN_STATE_PAUSED);
ths5fafdf22007-09-16 21:08:06 +00002456 } else
bellard1fddef42005-04-17 19:16:13 +00002457#endif
bellard41625032005-04-24 10:07:11 +00002458 {
bellard858693c2004-03-31 18:52:07 +00002459 switch(s->state) {
2460 case RS_IDLE:
2461 if (ch == '$') {
2462 s->line_buf_index = 0;
2463 s->state = RS_GETLINE;
bellard4c3a88a2003-07-26 12:06:08 +00002464 }
2465 break;
bellard858693c2004-03-31 18:52:07 +00002466 case RS_GETLINE:
2467 if (ch == '#') {
2468 s->state = RS_CHKSUM1;
2469 } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
2470 s->state = RS_IDLE;
2471 } else {
2472 s->line_buf[s->line_buf_index++] = ch;
2473 }
2474 break;
2475 case RS_CHKSUM1:
2476 s->line_buf[s->line_buf_index] = '\0';
2477 s->line_csum = fromhex(ch) << 4;
2478 s->state = RS_CHKSUM2;
2479 break;
2480 case RS_CHKSUM2:
2481 s->line_csum |= fromhex(ch);
2482 csum = 0;
2483 for(i = 0; i < s->line_buf_index; i++) {
2484 csum += s->line_buf[i];
2485 }
2486 if (s->line_csum != (csum & 0xff)) {
ths60fe76f2007-12-16 03:02:09 +00002487 reply = '-';
2488 put_buffer(s, &reply, 1);
bellard858693c2004-03-31 18:52:07 +00002489 s->state = RS_IDLE;
2490 } else {
ths60fe76f2007-12-16 03:02:09 +00002491 reply = '+';
2492 put_buffer(s, &reply, 1);
aliguori880a7572008-11-18 20:30:24 +00002493 s->state = gdb_handle_packet(s, s->line_buf);
bellard858693c2004-03-31 18:52:07 +00002494 }
bellardb4608c02003-06-27 17:34:32 +00002495 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002496 default:
2497 abort();
bellardb4608c02003-06-27 17:34:32 +00002498 }
2499 }
bellard858693c2004-03-31 18:52:07 +00002500}
2501
Paul Brook0e1c9c52010-06-16 13:03:51 +01002502/* Tell the remote gdb that the process has exited. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01002503void gdb_exit(CPUArchState *env, int code)
Paul Brook0e1c9c52010-06-16 13:03:51 +01002504{
2505 GDBState *s;
2506 char buf[4];
2507
2508 s = gdbserver_state;
2509 if (!s) {
2510 return;
2511 }
2512#ifdef CONFIG_USER_ONLY
2513 if (gdbserver_fd < 0 || s->fd < 0) {
2514 return;
2515 }
2516#endif
2517
2518 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
2519 put_packet(s, buf);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01002520
2521#ifndef CONFIG_USER_ONLY
2522 if (s->chr) {
Anthony Liguori70f24fb2011-08-15 11:17:38 -05002523 qemu_chr_delete(s->chr);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01002524 }
2525#endif
Paul Brook0e1c9c52010-06-16 13:03:51 +01002526}
2527
bellard1fddef42005-04-17 19:16:13 +00002528#ifdef CONFIG_USER_ONLY
2529int
aurel32ca587a82008-12-18 22:44:13 +00002530gdb_queuesig (void)
2531{
2532 GDBState *s;
2533
2534 s = gdbserver_state;
2535
2536 if (gdbserver_fd < 0 || s->fd < 0)
2537 return 0;
2538 else
2539 return 1;
2540}
2541
2542int
Andreas Färberdb6b81d2013-06-27 19:49:31 +02002543gdb_handlesig(CPUState *cpu, int sig)
bellard1fddef42005-04-17 19:16:13 +00002544{
Andreas Färberdb6b81d2013-06-27 19:49:31 +02002545 CPUArchState *env = cpu->env_ptr;
Andreas Färber5ca666c2013-06-24 19:20:57 +02002546 GDBState *s;
2547 char buf[256];
2548 int n;
bellard1fddef42005-04-17 19:16:13 +00002549
Andreas Färber5ca666c2013-06-24 19:20:57 +02002550 s = gdbserver_state;
2551 if (gdbserver_fd < 0 || s->fd < 0) {
2552 return sig;
bellard1fddef42005-04-17 19:16:13 +00002553 }
2554
Andreas Färber5ca666c2013-06-24 19:20:57 +02002555 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002556 cpu_single_step(cpu, 0);
Andreas Färber5ca666c2013-06-24 19:20:57 +02002557 tb_flush(env);
bellard1fddef42005-04-17 19:16:13 +00002558
Andreas Färber5ca666c2013-06-24 19:20:57 +02002559 if (sig != 0) {
2560 snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig));
2561 put_packet(s, buf);
2562 }
2563 /* put_packet() might have detected that the peer terminated the
2564 connection. */
2565 if (s->fd < 0) {
2566 return sig;
2567 }
2568
2569 sig = 0;
2570 s->state = RS_IDLE;
2571 s->running_state = 0;
2572 while (s->running_state == 0) {
2573 n = read(s->fd, buf, 256);
2574 if (n > 0) {
2575 int i;
2576
2577 for (i = 0; i < n; i++) {
2578 gdb_read_byte(s, buf[i]);
2579 }
2580 } else if (n == 0 || errno != EAGAIN) {
2581 /* XXX: Connection closed. Should probably wait for another
2582 connection before continuing. */
2583 return sig;
bellard1fddef42005-04-17 19:16:13 +00002584 }
Andreas Färber5ca666c2013-06-24 19:20:57 +02002585 }
2586 sig = s->signal;
2587 s->signal = 0;
2588 return sig;
bellard1fddef42005-04-17 19:16:13 +00002589}
bellarde9009672005-04-26 20:42:36 +00002590
aurel32ca587a82008-12-18 22:44:13 +00002591/* Tell the remote gdb that the process has exited due to SIG. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01002592void gdb_signalled(CPUArchState *env, int sig)
aurel32ca587a82008-12-18 22:44:13 +00002593{
Andreas Färber5ca666c2013-06-24 19:20:57 +02002594 GDBState *s;
2595 char buf[4];
aurel32ca587a82008-12-18 22:44:13 +00002596
Andreas Färber5ca666c2013-06-24 19:20:57 +02002597 s = gdbserver_state;
2598 if (gdbserver_fd < 0 || s->fd < 0) {
2599 return;
2600 }
aurel32ca587a82008-12-18 22:44:13 +00002601
Andreas Färber5ca666c2013-06-24 19:20:57 +02002602 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
2603 put_packet(s, buf);
aurel32ca587a82008-12-18 22:44:13 +00002604}
bellard1fddef42005-04-17 19:16:13 +00002605
aliguori880a7572008-11-18 20:30:24 +00002606static void gdb_accept(void)
bellard858693c2004-03-31 18:52:07 +00002607{
2608 GDBState *s;
2609 struct sockaddr_in sockaddr;
2610 socklen_t len;
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09002611 int fd;
bellard858693c2004-03-31 18:52:07 +00002612
2613 for(;;) {
2614 len = sizeof(sockaddr);
2615 fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
2616 if (fd < 0 && errno != EINTR) {
2617 perror("accept");
2618 return;
2619 } else if (fd >= 0) {
Kevin Wolf40ff6d72009-12-02 12:24:42 +01002620#ifndef _WIN32
2621 fcntl(fd, F_SETFD, FD_CLOEXEC);
2622#endif
bellard858693c2004-03-31 18:52:07 +00002623 break;
2624 }
2625 }
2626
2627 /* set short latency */
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09002628 socket_set_nodelay(fd);
ths3b46e622007-09-17 08:09:54 +00002629
Anthony Liguori7267c092011-08-20 22:09:37 -05002630 s = g_malloc0(sizeof(GDBState));
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002631 s->c_cpu = first_cpu;
2632 s->g_cpu = first_cpu;
bellard858693c2004-03-31 18:52:07 +00002633 s->fd = fd;
pbrook56aebc82008-10-11 17:55:29 +00002634 gdb_has_xml = 0;
bellard858693c2004-03-31 18:52:07 +00002635
aliguori880a7572008-11-18 20:30:24 +00002636 gdbserver_state = s;
pbrooka2d1eba2007-01-28 03:10:55 +00002637
bellard858693c2004-03-31 18:52:07 +00002638 fcntl(fd, F_SETFL, O_NONBLOCK);
bellard858693c2004-03-31 18:52:07 +00002639}
2640
2641static int gdbserver_open(int port)
2642{
2643 struct sockaddr_in sockaddr;
2644 int fd, val, ret;
2645
2646 fd = socket(PF_INET, SOCK_STREAM, 0);
2647 if (fd < 0) {
2648 perror("socket");
2649 return -1;
2650 }
Kevin Wolf40ff6d72009-12-02 12:24:42 +01002651#ifndef _WIN32
2652 fcntl(fd, F_SETFD, FD_CLOEXEC);
2653#endif
bellard858693c2004-03-31 18:52:07 +00002654
2655 /* allow fast reuse */
2656 val = 1;
Stefan Weil9957fc72013-03-08 19:58:32 +01002657 qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
bellard858693c2004-03-31 18:52:07 +00002658
2659 sockaddr.sin_family = AF_INET;
2660 sockaddr.sin_port = htons(port);
2661 sockaddr.sin_addr.s_addr = 0;
2662 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
2663 if (ret < 0) {
2664 perror("bind");
Peter Maydellbb161722011-12-24 23:37:24 +00002665 close(fd);
bellard858693c2004-03-31 18:52:07 +00002666 return -1;
2667 }
2668 ret = listen(fd, 0);
2669 if (ret < 0) {
2670 perror("listen");
Peter Maydellbb161722011-12-24 23:37:24 +00002671 close(fd);
bellard858693c2004-03-31 18:52:07 +00002672 return -1;
2673 }
bellard858693c2004-03-31 18:52:07 +00002674 return fd;
2675}
2676
2677int gdbserver_start(int port)
2678{
2679 gdbserver_fd = gdbserver_open(port);
2680 if (gdbserver_fd < 0)
2681 return -1;
2682 /* accept connections */
aliguori880a7572008-11-18 20:30:24 +00002683 gdb_accept();
bellardb4608c02003-06-27 17:34:32 +00002684 return 0;
2685}
aurel322b1319c2008-12-18 22:44:04 +00002686
2687/* Disable gdb stub for child processes. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01002688void gdbserver_fork(CPUArchState *env)
aurel322b1319c2008-12-18 22:44:04 +00002689{
2690 GDBState *s = gdbserver_state;
edgar_igl9f6164d2009-01-07 10:22:28 +00002691 if (gdbserver_fd < 0 || s->fd < 0)
aurel322b1319c2008-12-18 22:44:04 +00002692 return;
2693 close(s->fd);
2694 s->fd = -1;
2695 cpu_breakpoint_remove_all(env, BP_GDB);
2696 cpu_watchpoint_remove_all(env, BP_GDB);
2697}
pbrook4046d912007-01-28 01:53:16 +00002698#else
thsaa1f17c2007-07-11 22:48:58 +00002699static int gdb_chr_can_receive(void *opaque)
pbrook4046d912007-01-28 01:53:16 +00002700{
pbrook56aebc82008-10-11 17:55:29 +00002701 /* We can handle an arbitrarily large amount of data.
2702 Pick the maximum packet size, which is as good as anything. */
2703 return MAX_PACKET_LENGTH;
pbrook4046d912007-01-28 01:53:16 +00002704}
2705
thsaa1f17c2007-07-11 22:48:58 +00002706static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
pbrook4046d912007-01-28 01:53:16 +00002707{
pbrook4046d912007-01-28 01:53:16 +00002708 int i;
2709
2710 for (i = 0; i < size; i++) {
aliguori880a7572008-11-18 20:30:24 +00002711 gdb_read_byte(gdbserver_state, buf[i]);
pbrook4046d912007-01-28 01:53:16 +00002712 }
2713}
2714
2715static void gdb_chr_event(void *opaque, int event)
2716{
2717 switch (event) {
Amit Shahb6b8df52009-10-07 18:31:16 +05302718 case CHR_EVENT_OPENED:
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002719 vm_stop(RUN_STATE_PAUSED);
pbrook56aebc82008-10-11 17:55:29 +00002720 gdb_has_xml = 0;
pbrook4046d912007-01-28 01:53:16 +00002721 break;
2722 default:
2723 break;
2724 }
2725}
2726
aliguori8a34a0f2009-03-05 23:01:55 +00002727static void gdb_monitor_output(GDBState *s, const char *msg, int len)
2728{
2729 char buf[MAX_PACKET_LENGTH];
2730
2731 buf[0] = 'O';
2732 if (len > (MAX_PACKET_LENGTH/2) - 1)
2733 len = (MAX_PACKET_LENGTH/2) - 1;
2734 memtohex(buf + 1, (uint8_t *)msg, len);
2735 put_packet(s, buf);
2736}
2737
2738static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len)
2739{
2740 const char *p = (const char *)buf;
2741 int max_sz;
2742
2743 max_sz = (sizeof(gdbserver_state->last_packet) - 2) / 2;
2744 for (;;) {
2745 if (len <= max_sz) {
2746 gdb_monitor_output(gdbserver_state, p, len);
2747 break;
2748 }
2749 gdb_monitor_output(gdbserver_state, p, max_sz);
2750 p += max_sz;
2751 len -= max_sz;
2752 }
2753 return len;
2754}
2755
aliguori59030a82009-04-05 18:43:41 +00002756#ifndef _WIN32
2757static void gdb_sigterm_handler(int signal)
2758{
Luiz Capitulino13548692011-07-29 15:36:43 -03002759 if (runstate_is_running()) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002760 vm_stop(RUN_STATE_PAUSED);
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002761 }
aliguori59030a82009-04-05 18:43:41 +00002762}
2763#endif
2764
2765int gdbserver_start(const char *device)
pbrook4046d912007-01-28 01:53:16 +00002766{
2767 GDBState *s;
aliguori59030a82009-04-05 18:43:41 +00002768 char gdbstub_device_name[128];
aliguori36556b22009-03-28 18:05:53 +00002769 CharDriverState *chr = NULL;
2770 CharDriverState *mon_chr;
pbrook4046d912007-01-28 01:53:16 +00002771
aliguori59030a82009-04-05 18:43:41 +00002772 if (!device)
2773 return -1;
2774 if (strcmp(device, "none") != 0) {
2775 if (strstart(device, "tcp:", NULL)) {
2776 /* enforce required TCP attributes */
2777 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
2778 "%s,nowait,nodelay,server", device);
2779 device = gdbstub_device_name;
aliguori36556b22009-03-28 18:05:53 +00002780 }
aliguori59030a82009-04-05 18:43:41 +00002781#ifndef _WIN32
2782 else if (strcmp(device, "stdio") == 0) {
2783 struct sigaction act;
pbrookcfc34752007-02-22 01:48:01 +00002784
aliguori59030a82009-04-05 18:43:41 +00002785 memset(&act, 0, sizeof(act));
2786 act.sa_handler = gdb_sigterm_handler;
2787 sigaction(SIGINT, &act, NULL);
2788 }
2789#endif
Anthony Liguori27143a42011-08-15 11:17:36 -05002790 chr = qemu_chr_new("gdb", device, NULL);
aliguori36556b22009-03-28 18:05:53 +00002791 if (!chr)
2792 return -1;
2793
Hans de Goede456d6062013-03-27 20:29:40 +01002794 qemu_chr_fe_claim_no_fail(chr);
aliguori36556b22009-03-28 18:05:53 +00002795 qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
2796 gdb_chr_event, NULL);
pbrookcfc34752007-02-22 01:48:01 +00002797 }
2798
aliguori36556b22009-03-28 18:05:53 +00002799 s = gdbserver_state;
2800 if (!s) {
Anthony Liguori7267c092011-08-20 22:09:37 -05002801 s = g_malloc0(sizeof(GDBState));
aliguori36556b22009-03-28 18:05:53 +00002802 gdbserver_state = s;
pbrook4046d912007-01-28 01:53:16 +00002803
aliguori36556b22009-03-28 18:05:53 +00002804 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
2805
2806 /* Initialize a monitor terminal for gdb */
Anthony Liguori7267c092011-08-20 22:09:37 -05002807 mon_chr = g_malloc0(sizeof(*mon_chr));
aliguori36556b22009-03-28 18:05:53 +00002808 mon_chr->chr_write = gdb_monitor_write;
2809 monitor_init(mon_chr, 0);
2810 } else {
2811 if (s->chr)
Anthony Liguori70f24fb2011-08-15 11:17:38 -05002812 qemu_chr_delete(s->chr);
aliguori36556b22009-03-28 18:05:53 +00002813 mon_chr = s->mon_chr;
2814 memset(s, 0, sizeof(GDBState));
2815 }
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002816 s->c_cpu = first_cpu;
2817 s->g_cpu = first_cpu;
pbrook4046d912007-01-28 01:53:16 +00002818 s->chr = chr;
aliguori36556b22009-03-28 18:05:53 +00002819 s->state = chr ? RS_IDLE : RS_INACTIVE;
2820 s->mon_chr = mon_chr;
Meador Ingecdb432b2012-03-15 17:49:45 +00002821 s->current_syscall_cb = NULL;
aliguori8a34a0f2009-03-05 23:01:55 +00002822
pbrook4046d912007-01-28 01:53:16 +00002823 return 0;
2824}
2825#endif