blob: 52bde5bdc9754f40b552be4365dfc39e8cabf15e [file] [log] [blame]
bellardb4608c02003-06-27 17:34:32 +00001/*
2 * gdb server stub
ths5fafdf22007-09-16 21:08:06 +00003 *
Alex Bennée42a09592019-07-05 13:28:19 +01004 * This implements a subset of the remote protocol as described in:
5 *
6 * https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html
7 *
bellard34751872005-07-02 14:31:34 +00008 * Copyright (c) 2003-2005 Fabrice Bellard
bellardb4608c02003-06-27 17:34:32 +00009 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
Blue Swirl8167ee82009-07-16 20:47:01 +000021 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Alex Bennée42a09592019-07-05 13:28:19 +010022 *
23 * SPDX-License-Identifier: LGPL-2.0+
bellardb4608c02003-06-27 17:34:32 +000024 */
Markus Armbruster856dfd82019-05-23 16:35:06 +020025
Peter Maydelld38ea872016-01-29 17:50:05 +000026#include "qemu/osdep.h"
Markus Armbrustera8d25322019-05-23 16:35:08 +020027#include "qemu-common.h"
Markus Armbrusterda34e652016-03-14 09:01:28 +010028#include "qapi/error.h"
Ziyue Yang508b4ec2017-01-18 16:02:41 +080029#include "qemu/error-report.h"
Markus Armbruster856dfd82019-05-23 16:35:06 +020030#include "qemu/ctype.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020031#include "qemu/cutils.h"
Markus Armbruster0b8fa322019-05-23 16:35:07 +020032#include "qemu/module.h"
Paolo Bonzini243af022020-02-04 12:20:10 +010033#include "trace/trace-root.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020034#ifdef CONFIG_USER_ONLY
bellard1fddef42005-04-17 19:16:13 +000035#include "qemu.h"
36#else
Paolo Bonzini83c90892012-12-17 18:19:49 +010037#include "monitor/monitor.h"
Marc-André Lureau8228e352017-01-26 17:19:46 +040038#include "chardev/char.h"
Marc-André Lureau4d43a602017-01-26 18:26:44 +040039#include "chardev/char-fe.h"
Paolo Bonzini022c62c2012-12-17 18:19:49 +010040#include "exec/gdbstub.h"
Luc Michel8f468632019-01-07 15:23:45 +000041#include "hw/cpu/cluster.h"
Like Xu5cc87672019-05-19 04:54:21 +080042#include "hw/boards.h"
bellard1fddef42005-04-17 19:16:13 +000043#endif
bellard67b915a2004-03-31 23:37:16 +000044
pbrook56aebc82008-10-11 17:55:29 +000045#define MAX_PACKET_LENGTH 4096
46
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010047#include "qemu/sockets.h"
Vincent Palatinb3946622017-01-10 11:59:55 +010048#include "sysemu/hw_accel.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010049#include "sysemu/kvm.h"
Markus Armbruster54d31232019-08-12 07:23:59 +020050#include "sysemu/runstate.h"
Philippe Mathieu-Daudé6b5fe132021-03-05 13:54:49 +000051#include "semihosting/semihost.h"
Paolo Bonzini63c91552016-03-15 13:18:37 +010052#include "exec/exec-all.h"
Pavel Dovgalyukfda84582020-10-03 20:13:43 +030053#include "sysemu/replay.h"
aurel32ca587a82008-12-18 22:44:13 +000054
Jan Kiszkaa3919382015-02-07 09:38:44 +010055#ifdef CONFIG_USER_ONLY
56#define GDB_ATTACHED "0"
57#else
58#define GDB_ATTACHED "1"
59#endif
60
Jon Doronab4752e2019-05-29 09:41:48 +030061#ifndef CONFIG_USER_ONLY
62static int phy_memory_mode;
63#endif
64
Andreas Färberf3659ee2013-06-27 19:09:09 +020065static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
66 uint8_t *buf, int len, bool is_write)
Fabien Chouteau44520db2011-09-08 12:48:16 +020067{
Jon Doronab4752e2019-05-29 09:41:48 +030068 CPUClass *cc;
Andreas Färberf3659ee2013-06-27 19:09:09 +020069
Jon Doronab4752e2019-05-29 09:41:48 +030070#ifndef CONFIG_USER_ONLY
71 if (phy_memory_mode) {
72 if (is_write) {
73 cpu_physical_memory_write(addr, buf, len);
74 } else {
75 cpu_physical_memory_read(addr, buf, len);
76 }
77 return 0;
78 }
79#endif
80
81 cc = CPU_GET_CLASS(cpu);
Andreas Färberf3659ee2013-06-27 19:09:09 +020082 if (cc->memory_rw_debug) {
83 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
84 }
85 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
Fabien Chouteau44520db2011-09-08 12:48:16 +020086}
aurel32ca587a82008-12-18 22:44:13 +000087
Alex Bennéed2a6c852017-07-12 11:52:14 +010088/* Return the GDB index for a given vCPU state.
89 *
90 * For user mode this is simply the thread id. In system mode GDB
91 * numbers CPUs from 1 as 0 is reserved as an "any cpu" index.
92 */
93static inline int cpu_gdb_index(CPUState *cpu)
94{
95#if defined(CONFIG_USER_ONLY)
Alex Bennéebd88c782017-07-12 11:52:15 +010096 TaskState *ts = (TaskState *) cpu->opaque;
97 return ts->ts_tid;
Alex Bennéed2a6c852017-07-12 11:52:14 +010098#else
99 return cpu->cpu_index + 1;
100#endif
101}
102
aurel32ca587a82008-12-18 22:44:13 +0000103enum {
104 GDB_SIGNAL_0 = 0,
105 GDB_SIGNAL_INT = 2,
Jan Kiszka425189a2011-03-22 11:02:09 +0100106 GDB_SIGNAL_QUIT = 3,
aurel32ca587a82008-12-18 22:44:13 +0000107 GDB_SIGNAL_TRAP = 5,
Jan Kiszka425189a2011-03-22 11:02:09 +0100108 GDB_SIGNAL_ABRT = 6,
109 GDB_SIGNAL_ALRM = 14,
110 GDB_SIGNAL_IO = 23,
111 GDB_SIGNAL_XCPU = 24,
aurel32ca587a82008-12-18 22:44:13 +0000112 GDB_SIGNAL_UNKNOWN = 143
113};
114
115#ifdef CONFIG_USER_ONLY
116
117/* Map target signal numbers to GDB protocol signal numbers and vice
118 * versa. For user emulation's currently supported systems, we can
119 * assume most signals are defined.
120 */
121
122static int gdb_signal_table[] = {
123 0,
124 TARGET_SIGHUP,
125 TARGET_SIGINT,
126 TARGET_SIGQUIT,
127 TARGET_SIGILL,
128 TARGET_SIGTRAP,
129 TARGET_SIGABRT,
130 -1, /* SIGEMT */
131 TARGET_SIGFPE,
132 TARGET_SIGKILL,
133 TARGET_SIGBUS,
134 TARGET_SIGSEGV,
135 TARGET_SIGSYS,
136 TARGET_SIGPIPE,
137 TARGET_SIGALRM,
138 TARGET_SIGTERM,
139 TARGET_SIGURG,
140 TARGET_SIGSTOP,
141 TARGET_SIGTSTP,
142 TARGET_SIGCONT,
143 TARGET_SIGCHLD,
144 TARGET_SIGTTIN,
145 TARGET_SIGTTOU,
146 TARGET_SIGIO,
147 TARGET_SIGXCPU,
148 TARGET_SIGXFSZ,
149 TARGET_SIGVTALRM,
150 TARGET_SIGPROF,
151 TARGET_SIGWINCH,
152 -1, /* SIGLOST */
153 TARGET_SIGUSR1,
154 TARGET_SIGUSR2,
blueswir1c72d5bf2009-01-15 17:27:45 +0000155#ifdef TARGET_SIGPWR
aurel32ca587a82008-12-18 22:44:13 +0000156 TARGET_SIGPWR,
blueswir1c72d5bf2009-01-15 17:27:45 +0000157#else
158 -1,
159#endif
aurel32ca587a82008-12-18 22:44:13 +0000160 -1, /* SIGPOLL */
161 -1,
162 -1,
163 -1,
164 -1,
165 -1,
166 -1,
167 -1,
168 -1,
169 -1,
170 -1,
171 -1,
blueswir1c72d5bf2009-01-15 17:27:45 +0000172#ifdef __SIGRTMIN
aurel32ca587a82008-12-18 22:44:13 +0000173 __SIGRTMIN + 1,
174 __SIGRTMIN + 2,
175 __SIGRTMIN + 3,
176 __SIGRTMIN + 4,
177 __SIGRTMIN + 5,
178 __SIGRTMIN + 6,
179 __SIGRTMIN + 7,
180 __SIGRTMIN + 8,
181 __SIGRTMIN + 9,
182 __SIGRTMIN + 10,
183 __SIGRTMIN + 11,
184 __SIGRTMIN + 12,
185 __SIGRTMIN + 13,
186 __SIGRTMIN + 14,
187 __SIGRTMIN + 15,
188 __SIGRTMIN + 16,
189 __SIGRTMIN + 17,
190 __SIGRTMIN + 18,
191 __SIGRTMIN + 19,
192 __SIGRTMIN + 20,
193 __SIGRTMIN + 21,
194 __SIGRTMIN + 22,
195 __SIGRTMIN + 23,
196 __SIGRTMIN + 24,
197 __SIGRTMIN + 25,
198 __SIGRTMIN + 26,
199 __SIGRTMIN + 27,
200 __SIGRTMIN + 28,
201 __SIGRTMIN + 29,
202 __SIGRTMIN + 30,
203 __SIGRTMIN + 31,
204 -1, /* SIGCANCEL */
205 __SIGRTMIN,
206 __SIGRTMIN + 32,
207 __SIGRTMIN + 33,
208 __SIGRTMIN + 34,
209 __SIGRTMIN + 35,
210 __SIGRTMIN + 36,
211 __SIGRTMIN + 37,
212 __SIGRTMIN + 38,
213 __SIGRTMIN + 39,
214 __SIGRTMIN + 40,
215 __SIGRTMIN + 41,
216 __SIGRTMIN + 42,
217 __SIGRTMIN + 43,
218 __SIGRTMIN + 44,
219 __SIGRTMIN + 45,
220 __SIGRTMIN + 46,
221 __SIGRTMIN + 47,
222 __SIGRTMIN + 48,
223 __SIGRTMIN + 49,
224 __SIGRTMIN + 50,
225 __SIGRTMIN + 51,
226 __SIGRTMIN + 52,
227 __SIGRTMIN + 53,
228 __SIGRTMIN + 54,
229 __SIGRTMIN + 55,
230 __SIGRTMIN + 56,
231 __SIGRTMIN + 57,
232 __SIGRTMIN + 58,
233 __SIGRTMIN + 59,
234 __SIGRTMIN + 60,
235 __SIGRTMIN + 61,
236 __SIGRTMIN + 62,
237 __SIGRTMIN + 63,
238 __SIGRTMIN + 64,
239 __SIGRTMIN + 65,
240 __SIGRTMIN + 66,
241 __SIGRTMIN + 67,
242 __SIGRTMIN + 68,
243 __SIGRTMIN + 69,
244 __SIGRTMIN + 70,
245 __SIGRTMIN + 71,
246 __SIGRTMIN + 72,
247 __SIGRTMIN + 73,
248 __SIGRTMIN + 74,
249 __SIGRTMIN + 75,
250 __SIGRTMIN + 76,
251 __SIGRTMIN + 77,
252 __SIGRTMIN + 78,
253 __SIGRTMIN + 79,
254 __SIGRTMIN + 80,
255 __SIGRTMIN + 81,
256 __SIGRTMIN + 82,
257 __SIGRTMIN + 83,
258 __SIGRTMIN + 84,
259 __SIGRTMIN + 85,
260 __SIGRTMIN + 86,
261 __SIGRTMIN + 87,
262 __SIGRTMIN + 88,
263 __SIGRTMIN + 89,
264 __SIGRTMIN + 90,
265 __SIGRTMIN + 91,
266 __SIGRTMIN + 92,
267 __SIGRTMIN + 93,
268 __SIGRTMIN + 94,
269 __SIGRTMIN + 95,
270 -1, /* SIGINFO */
271 -1, /* UNKNOWN */
272 -1, /* DEFAULT */
273 -1,
274 -1,
275 -1,
276 -1,
277 -1,
278 -1
blueswir1c72d5bf2009-01-15 17:27:45 +0000279#endif
aurel32ca587a82008-12-18 22:44:13 +0000280};
bellard8f447cc2006-06-14 15:21:14 +0000281#else
aurel32ca587a82008-12-18 22:44:13 +0000282/* In system mode we only need SIGINT and SIGTRAP; other signals
283 are not yet supported. */
284
285enum {
286 TARGET_SIGINT = 2,
287 TARGET_SIGTRAP = 5
288};
289
290static int gdb_signal_table[] = {
291 -1,
292 -1,
293 TARGET_SIGINT,
294 -1,
295 -1,
296 TARGET_SIGTRAP
297};
bellard8f447cc2006-06-14 15:21:14 +0000298#endif
bellardb4608c02003-06-27 17:34:32 +0000299
aurel32ca587a82008-12-18 22:44:13 +0000300#ifdef CONFIG_USER_ONLY
301static int target_signal_to_gdb (int sig)
302{
303 int i;
304 for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
305 if (gdb_signal_table[i] == sig)
306 return i;
307 return GDB_SIGNAL_UNKNOWN;
308}
309#endif
310
311static int gdb_signal_to_target (int sig)
312{
313 if (sig < ARRAY_SIZE (gdb_signal_table))
314 return gdb_signal_table[sig];
315 else
316 return -1;
317}
318
pbrook56aebc82008-10-11 17:55:29 +0000319typedef struct GDBRegisterState {
320 int base_reg;
321 int num_regs;
Alex Bennéea010bdb2020-03-16 17:21:41 +0000322 gdb_get_reg_cb get_reg;
323 gdb_set_reg_cb set_reg;
pbrook56aebc82008-10-11 17:55:29 +0000324 const char *xml;
325 struct GDBRegisterState *next;
326} GDBRegisterState;
327
Luc Michel8f468632019-01-07 15:23:45 +0000328typedef struct GDBProcess {
329 uint32_t pid;
330 bool attached;
Luc Michelc145eea2019-01-07 15:23:46 +0000331
332 char target_xml[1024];
Luc Michel8f468632019-01-07 15:23:45 +0000333} GDBProcess;
334
bellard858693c2004-03-31 18:52:07 +0000335enum RSState {
aliguori36556b22009-03-28 18:05:53 +0000336 RS_INACTIVE,
bellard858693c2004-03-31 18:52:07 +0000337 RS_IDLE,
338 RS_GETLINE,
Doug Gale4bf43122017-05-01 12:22:10 -0400339 RS_GETLINE_ESC,
340 RS_GETLINE_RLE,
bellard858693c2004-03-31 18:52:07 +0000341 RS_CHKSUM1,
342 RS_CHKSUM2,
343};
bellard858693c2004-03-31 18:52:07 +0000344typedef struct GDBState {
Alex Bennée8d98c442020-03-16 17:21:33 +0000345 bool init; /* have we been initialised? */
Andreas Färber2e0f2cf2013-06-27 19:19:39 +0200346 CPUState *c_cpu; /* current CPU for step/continue ops */
347 CPUState *g_cpu; /* current CPU for other ops */
Andreas Färber52f34622013-06-27 13:44:40 +0200348 CPUState *query_cpu; /* for q{f|s}ThreadInfo */
bellard41625032005-04-24 10:07:11 +0000349 enum RSState state; /* parsing state */
pbrook56aebc82008-10-11 17:55:29 +0000350 char line_buf[MAX_PACKET_LENGTH];
bellard858693c2004-03-31 18:52:07 +0000351 int line_buf_index;
Doug Gale4bf43122017-05-01 12:22:10 -0400352 int line_sum; /* running checksum */
353 int line_csum; /* checksum at the end of the packet */
Damien Hedded116e812020-03-16 17:21:53 +0000354 GByteArray *last_packet;
edgar_igl1f487ee2008-05-17 22:20:53 +0000355 int signal;
bellard41625032005-04-24 10:07:11 +0000356#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000357 int fd;
Alex Bennéefcedd922020-04-30 20:01:19 +0100358 char *socket_path;
bellard41625032005-04-24 10:07:11 +0000359 int running_state;
pbrook4046d912007-01-28 01:53:16 +0000360#else
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +0300361 CharBackend chr;
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +0300362 Chardev *mon_chr;
bellard41625032005-04-24 10:07:11 +0000363#endif
Luc Michel8f468632019-01-07 15:23:45 +0000364 bool multiprocess;
365 GDBProcess *processes;
366 int process_num;
Meador Ingecdb432b2012-03-15 17:49:45 +0000367 char syscall_buf[256];
368 gdb_syscall_complete_cb current_syscall_cb;
Alex Bennée308f9e82020-03-16 17:21:35 +0000369 GString *str_buf;
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000370 GByteArray *mem_buf;
bellard858693c2004-03-31 18:52:07 +0000371} GDBState;
bellardb4608c02003-06-27 17:34:32 +0000372
edgar_igl60897d32008-05-09 08:25:14 +0000373/* By default use no IRQs and no timers while single stepping so as to
374 * make single stepping like an ICE HW step.
375 */
376static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
377
Pavel Dovgalyukfda84582020-10-03 20:13:43 +0300378/* Retrieves flags for single step mode. */
379static int get_sstep_flags(void)
380{
381 /*
382 * In replay mode all events written into the log should be replayed.
383 * That is why NOIRQ flag is removed in this mode.
384 */
385 if (replay_mode != REPLAY_MODE_NONE) {
386 return SSTEP_ENABLE;
387 } else {
388 return sstep_flags;
389 }
390}
391
Alex Bennée8d98c442020-03-16 17:21:33 +0000392static GDBState gdbserver_state;
393
394static void init_gdbserver_state(void)
395{
396 g_assert(!gdbserver_state.init);
397 memset(&gdbserver_state, 0, sizeof(GDBState));
398 gdbserver_state.init = true;
Alex Bennée308f9e82020-03-16 17:21:35 +0000399 gdbserver_state.str_buf = g_string_new(NULL);
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000400 gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
Damien Hedded116e812020-03-16 17:21:53 +0000401 gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
Alex Bennée8d98c442020-03-16 17:21:33 +0000402}
403
404#ifndef CONFIG_USER_ONLY
405static void reset_gdbserver_state(void)
406{
407 g_free(gdbserver_state.processes);
408 gdbserver_state.processes = NULL;
409 gdbserver_state.process_num = 0;
410}
411#endif
aliguori880a7572008-11-18 20:30:24 +0000412
Andreas Färber5b50e792013-06-29 04:18:45 +0200413bool gdb_has_xml;
pbrook56aebc82008-10-11 17:55:29 +0000414
bellard1fddef42005-04-17 19:16:13 +0000415#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000416
Alex Bennéea346af32020-03-16 17:21:34 +0000417static int get_char(void)
bellardb4608c02003-06-27 17:34:32 +0000418{
419 uint8_t ch;
420 int ret;
421
422 for(;;) {
Alex Bennéea346af32020-03-16 17:21:34 +0000423 ret = qemu_recv(gdbserver_state.fd, &ch, 1, 0);
bellardb4608c02003-06-27 17:34:32 +0000424 if (ret < 0) {
edgar_igl1f487ee2008-05-17 22:20:53 +0000425 if (errno == ECONNRESET)
Alex Bennéea346af32020-03-16 17:21:34 +0000426 gdbserver_state.fd = -1;
Peter Wu5819e3e2016-06-05 16:35:48 +0200427 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000428 return -1;
429 } else if (ret == 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000430 close(gdbserver_state.fd);
431 gdbserver_state.fd = -1;
bellardb4608c02003-06-27 17:34:32 +0000432 return -1;
433 } else {
434 break;
435 }
436 }
437 return ch;
438}
pbrook4046d912007-01-28 01:53:16 +0000439#endif
bellardb4608c02003-06-27 17:34:32 +0000440
blueswir1654efcf2009-04-18 07:29:59 +0000441static enum {
pbrooka2d1eba2007-01-28 03:10:55 +0000442 GDB_SYS_UNKNOWN,
443 GDB_SYS_ENABLED,
444 GDB_SYS_DISABLED,
445} gdb_syscall_mode;
446
Liviu Ionescua38bb072014-12-11 12:07:48 +0000447/* Decide if either remote gdb syscalls or native file IO should be used. */
pbrooka2d1eba2007-01-28 03:10:55 +0000448int use_gdb_syscalls(void)
449{
Leon Alraecfe67ce2015-06-19 14:17:45 +0100450 SemihostingTarget target = semihosting_get_target();
451 if (target == SEMIHOSTING_TARGET_NATIVE) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000452 /* -semihosting-config target=native */
453 return false;
Leon Alraecfe67ce2015-06-19 14:17:45 +0100454 } else if (target == SEMIHOSTING_TARGET_GDB) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000455 /* -semihosting-config target=gdb */
456 return true;
457 }
458
459 /* -semihosting-config target=auto */
460 /* On the first call check if gdb is connected and remember. */
pbrooka2d1eba2007-01-28 03:10:55 +0000461 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
Alex Bennée8d98c442020-03-16 17:21:33 +0000462 gdb_syscall_mode = gdbserver_state.init ?
463 GDB_SYS_ENABLED : GDB_SYS_DISABLED;
pbrooka2d1eba2007-01-28 03:10:55 +0000464 }
465 return gdb_syscall_mode == GDB_SYS_ENABLED;
466}
467
Alex Bennéeed12f5b2021-05-20 18:43:02 +0100468static bool stub_can_reverse(void)
469{
470#ifdef CONFIG_USER_ONLY
471 return false;
472#else
473 return replay_mode == REPLAY_MODE_PLAY;
474#endif
475}
476
edgar_iglba70a622008-03-14 06:10:42 +0000477/* Resume execution. */
Alex Bennéea346af32020-03-16 17:21:34 +0000478static inline void gdb_continue(void)
edgar_iglba70a622008-03-14 06:10:42 +0000479{
Doug Gale5c9522b2017-12-02 20:30:37 -0500480
edgar_iglba70a622008-03-14 06:10:42 +0000481#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000482 gdbserver_state.running_state = 1;
Doug Gale5c9522b2017-12-02 20:30:37 -0500483 trace_gdbstub_op_continue();
edgar_iglba70a622008-03-14 06:10:42 +0000484#else
Paolo Bonzini26ac7a32013-06-03 17:06:54 +0200485 if (!runstate_needs_reset()) {
Doug Gale5c9522b2017-12-02 20:30:37 -0500486 trace_gdbstub_op_continue();
Paolo Bonzini87f25c12013-05-30 13:20:40 +0200487 vm_start();
488 }
edgar_iglba70a622008-03-14 06:10:42 +0000489#endif
490}
491
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100492/*
493 * Resume execution, per CPU actions. For user-mode emulation it's
494 * equivalent to gdb_continue.
495 */
Alex Bennéea346af32020-03-16 17:21:34 +0000496static int gdb_continue_partial(char *newstates)
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100497{
498 CPUState *cpu;
499 int res = 0;
500#ifdef CONFIG_USER_ONLY
501 /*
502 * This is not exactly accurate, but it's an improvement compared to the
503 * previous situation, where only one CPU would be single-stepped.
504 */
505 CPU_FOREACH(cpu) {
506 if (newstates[cpu->cpu_index] == 's') {
Doug Gale5c9522b2017-12-02 20:30:37 -0500507 trace_gdbstub_op_stepping(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100508 cpu_single_step(cpu, sstep_flags);
509 }
510 }
Alex Bennéea346af32020-03-16 17:21:34 +0000511 gdbserver_state.running_state = 1;
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100512#else
513 int flag = 0;
514
515 if (!runstate_needs_reset()) {
516 if (vm_prepare_start()) {
517 return 0;
518 }
519
520 CPU_FOREACH(cpu) {
521 switch (newstates[cpu->cpu_index]) {
522 case 0:
523 case 1:
524 break; /* nothing to do here */
525 case 's':
Doug Gale5c9522b2017-12-02 20:30:37 -0500526 trace_gdbstub_op_stepping(cpu->cpu_index);
Pavel Dovgalyukfda84582020-10-03 20:13:43 +0300527 cpu_single_step(cpu, get_sstep_flags());
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100528 cpu_resume(cpu);
529 flag = 1;
530 break;
531 case 'c':
Doug Gale5c9522b2017-12-02 20:30:37 -0500532 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100533 cpu_resume(cpu);
534 flag = 1;
535 break;
536 default:
537 res = -1;
538 break;
539 }
540 }
541 }
542 if (flag) {
543 qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
544 }
545#endif
546 return res;
547}
548
Alex Bennéea346af32020-03-16 17:21:34 +0000549static void put_buffer(const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000550{
pbrook4046d912007-01-28 01:53:16 +0000551#ifdef CONFIG_USER_ONLY
bellardb4608c02003-06-27 17:34:32 +0000552 int ret;
553
554 while (len > 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000555 ret = send(gdbserver_state.fd, buf, len, 0);
bellardb4608c02003-06-27 17:34:32 +0000556 if (ret < 0) {
Peter Wu5819e3e2016-06-05 16:35:48 +0200557 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000558 return;
559 } else {
560 buf += ret;
561 len -= ret;
562 }
563 }
pbrook4046d912007-01-28 01:53:16 +0000564#else
Daniel P. Berrange6ab3fc32016-09-06 14:56:04 +0100565 /* XXX this blocks entire thread. Rewrite to use
566 * qemu_chr_fe_write and background I/O callbacks */
Alex Bennéea346af32020-03-16 17:21:34 +0000567 qemu_chr_fe_write_all(&gdbserver_state.chr, buf, len);
pbrook4046d912007-01-28 01:53:16 +0000568#endif
bellardb4608c02003-06-27 17:34:32 +0000569}
570
571static inline int fromhex(int v)
572{
573 if (v >= '0' && v <= '9')
574 return v - '0';
575 else if (v >= 'A' && v <= 'F')
576 return v - 'A' + 10;
577 else if (v >= 'a' && v <= 'f')
578 return v - 'a' + 10;
579 else
580 return 0;
581}
582
583static inline int tohex(int v)
584{
585 if (v < 10)
586 return v + '0';
587 else
588 return v - 10 + 'a';
589}
590
Philippe Mathieu-Daudé90057742018-04-08 11:59:33 -0300591/* writes 2*len+1 bytes in buf */
Alex Bennée308f9e82020-03-16 17:21:35 +0000592static void memtohex(GString *buf, const uint8_t *mem, int len)
bellardb4608c02003-06-27 17:34:32 +0000593{
594 int i, c;
bellardb4608c02003-06-27 17:34:32 +0000595 for(i = 0; i < len; i++) {
596 c = mem[i];
Alex Bennée308f9e82020-03-16 17:21:35 +0000597 g_string_append_c(buf, tohex(c >> 4));
598 g_string_append_c(buf, tohex(c & 0xf));
bellardb4608c02003-06-27 17:34:32 +0000599 }
Alex Bennée308f9e82020-03-16 17:21:35 +0000600 g_string_append_c(buf, '\0');
bellardb4608c02003-06-27 17:34:32 +0000601}
602
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000603static void hextomem(GByteArray *mem, const char *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000604{
605 int i;
606
607 for(i = 0; i < len; i++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000608 guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
609 g_byte_array_append(mem, &byte, 1);
bellardb4608c02003-06-27 17:34:32 +0000610 buf += 2;
611 }
612}
613
Doug Gale5c9522b2017-12-02 20:30:37 -0500614static void hexdump(const char *buf, int len,
615 void (*trace_fn)(size_t ofs, char const *text))
616{
617 char line_buffer[3 * 16 + 4 + 16 + 1];
618
619 size_t i;
620 for (i = 0; i < len || (i & 0xF); ++i) {
621 size_t byte_ofs = i & 15;
622
623 if (byte_ofs == 0) {
624 memset(line_buffer, ' ', 3 * 16 + 4 + 16);
625 line_buffer[3 * 16 + 4 + 16] = 0;
626 }
627
628 size_t col_group = (i >> 2) & 3;
629 size_t hex_col = byte_ofs * 3 + col_group;
630 size_t txt_col = 3 * 16 + 4 + byte_ofs;
631
632 if (i < len) {
633 char value = buf[i];
634
635 line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
636 line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
637 line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
638 ? value
639 : '.';
640 }
641
642 if (byte_ofs == 0xF)
643 trace_fn(i & -16, line_buffer);
644 }
645}
646
bellardb4608c02003-06-27 17:34:32 +0000647/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000648static int put_packet_binary(const char *buf, int len, bool dump)
bellardb4608c02003-06-27 17:34:32 +0000649{
pbrook56aebc82008-10-11 17:55:29 +0000650 int csum, i;
Damien Hedded116e812020-03-16 17:21:53 +0000651 uint8_t footer[3];
bellardb4608c02003-06-27 17:34:32 +0000652
Doug Gale5c9522b2017-12-02 20:30:37 -0500653 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
654 hexdump(buf, len, trace_gdbstub_io_binaryreply);
655 }
656
bellardb4608c02003-06-27 17:34:32 +0000657 for(;;) {
Damien Hedded116e812020-03-16 17:21:53 +0000658 g_byte_array_set_size(gdbserver_state.last_packet, 0);
659 g_byte_array_append(gdbserver_state.last_packet,
660 (const uint8_t *) "$", 1);
661 g_byte_array_append(gdbserver_state.last_packet,
662 (const uint8_t *) buf, len);
bellardb4608c02003-06-27 17:34:32 +0000663 csum = 0;
664 for(i = 0; i < len; i++) {
665 csum += buf[i];
666 }
Damien Hedded116e812020-03-16 17:21:53 +0000667 footer[0] = '#';
668 footer[1] = tohex((csum >> 4) & 0xf);
669 footer[2] = tohex((csum) & 0xf);
670 g_byte_array_append(gdbserver_state.last_packet, footer, 3);
bellardb4608c02003-06-27 17:34:32 +0000671
Damien Hedded116e812020-03-16 17:21:53 +0000672 put_buffer(gdbserver_state.last_packet->data,
673 gdbserver_state.last_packet->len);
bellardb4608c02003-06-27 17:34:32 +0000674
pbrook4046d912007-01-28 01:53:16 +0000675#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000676 i = get_char();
pbrook4046d912007-01-28 01:53:16 +0000677 if (i < 0)
bellardb4608c02003-06-27 17:34:32 +0000678 return -1;
pbrook4046d912007-01-28 01:53:16 +0000679 if (i == '+')
bellardb4608c02003-06-27 17:34:32 +0000680 break;
pbrook4046d912007-01-28 01:53:16 +0000681#else
682 break;
683#endif
bellardb4608c02003-06-27 17:34:32 +0000684 }
685 return 0;
686}
687
pbrook56aebc82008-10-11 17:55:29 +0000688/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000689static int put_packet(const char *buf)
pbrook56aebc82008-10-11 17:55:29 +0000690{
Doug Gale5c9522b2017-12-02 20:30:37 -0500691 trace_gdbstub_io_reply(buf);
pbrook56aebc82008-10-11 17:55:29 +0000692
Alex Bennéea346af32020-03-16 17:21:34 +0000693 return put_packet_binary(buf, strlen(buf), false);
pbrook56aebc82008-10-11 17:55:29 +0000694}
695
Alex Bennée308f9e82020-03-16 17:21:35 +0000696static void put_strbuf(void)
pbrook56aebc82008-10-11 17:55:29 +0000697{
Alex Bennée308f9e82020-03-16 17:21:35 +0000698 put_packet(gdbserver_state.str_buf->str);
699}
700
701/* Encode data using the encoding for 'x' packets. */
702static void memtox(GString *buf, const char *mem, int len)
703{
pbrook56aebc82008-10-11 17:55:29 +0000704 char c;
705
706 while (len--) {
707 c = *(mem++);
708 switch (c) {
709 case '#': case '$': case '*': case '}':
Alex Bennée308f9e82020-03-16 17:21:35 +0000710 g_string_append_c(buf, '}');
711 g_string_append_c(buf, c ^ 0x20);
pbrook56aebc82008-10-11 17:55:29 +0000712 break;
713 default:
Alex Bennée308f9e82020-03-16 17:21:35 +0000714 g_string_append_c(buf, c);
pbrook56aebc82008-10-11 17:55:29 +0000715 break;
716 }
717 }
pbrook56aebc82008-10-11 17:55:29 +0000718}
719
Alex Bennéea346af32020-03-16 17:21:34 +0000720static uint32_t gdb_get_cpu_pid(CPUState *cpu)
Luc Michel1a227332019-01-07 15:23:45 +0000721{
Luc Michel1a227332019-01-07 15:23:45 +0000722 /* TODO: In user mode, we should use the task state PID */
Peter Maydell46f5abc2019-01-29 11:46:06 +0000723 if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
724 /* Return the default process' PID */
Alex Bennéea346af32020-03-16 17:21:34 +0000725 int index = gdbserver_state.process_num - 1;
726 return gdbserver_state.processes[index].pid;
Peter Maydell46f5abc2019-01-29 11:46:06 +0000727 }
728 return cpu->cluster_index + 1;
Luc Michel1a227332019-01-07 15:23:45 +0000729}
730
Alex Bennéea346af32020-03-16 17:21:34 +0000731static GDBProcess *gdb_get_process(uint32_t pid)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000732{
733 int i;
734
735 if (!pid) {
736 /* 0 means any process, we take the first one */
Alex Bennéea346af32020-03-16 17:21:34 +0000737 return &gdbserver_state.processes[0];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000738 }
739
Alex Bennéea346af32020-03-16 17:21:34 +0000740 for (i = 0; i < gdbserver_state.process_num; i++) {
741 if (gdbserver_state.processes[i].pid == pid) {
742 return &gdbserver_state.processes[i];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000743 }
744 }
745
746 return NULL;
747}
748
Alex Bennéea346af32020-03-16 17:21:34 +0000749static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000750{
Alex Bennéea346af32020-03-16 17:21:34 +0000751 return gdb_get_process(gdb_get_cpu_pid(cpu));
Luc Michel7d8c87d2019-01-07 15:23:45 +0000752}
753
754static CPUState *find_cpu(uint32_t thread_id)
755{
756 CPUState *cpu;
757
758 CPU_FOREACH(cpu) {
759 if (cpu_gdb_index(cpu) == thread_id) {
760 return cpu;
761 }
762 }
763
764 return NULL;
765}
766
Alex Bennéea346af32020-03-16 17:21:34 +0000767static CPUState *get_first_cpu_in_process(GDBProcess *process)
Luc Michele40e5202019-01-07 15:23:46 +0000768{
769 CPUState *cpu;
770
771 CPU_FOREACH(cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000772 if (gdb_get_cpu_pid(cpu) == process->pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000773 return cpu;
774 }
775 }
776
777 return NULL;
778}
779
Alex Bennéea346af32020-03-16 17:21:34 +0000780static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000781{
Alex Bennéea346af32020-03-16 17:21:34 +0000782 uint32_t pid = gdb_get_cpu_pid(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000783 cpu = CPU_NEXT(cpu);
784
785 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000786 if (gdb_get_cpu_pid(cpu) == pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000787 break;
788 }
789
790 cpu = CPU_NEXT(cpu);
791 }
792
793 return cpu;
794}
795
Luc Michele40e5202019-01-07 15:23:46 +0000796/* Return the cpu following @cpu, while ignoring unattached processes. */
Alex Bennéea346af32020-03-16 17:21:34 +0000797static CPUState *gdb_next_attached_cpu(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000798{
799 cpu = CPU_NEXT(cpu);
800
801 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000802 if (gdb_get_cpu_process(cpu)->attached) {
Luc Michele40e5202019-01-07 15:23:46 +0000803 break;
804 }
805
806 cpu = CPU_NEXT(cpu);
807 }
808
809 return cpu;
810}
811
812/* Return the first attached cpu */
Alex Bennéea346af32020-03-16 17:21:34 +0000813static CPUState *gdb_first_attached_cpu(void)
Luc Michele40e5202019-01-07 15:23:46 +0000814{
815 CPUState *cpu = first_cpu;
Alex Bennéea346af32020-03-16 17:21:34 +0000816 GDBProcess *process = gdb_get_cpu_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000817
818 if (!process->attached) {
Alex Bennéea346af32020-03-16 17:21:34 +0000819 return gdb_next_attached_cpu(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000820 }
821
822 return cpu;
823}
824
Alex Bennéea346af32020-03-16 17:21:34 +0000825static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
Luc Michelab65eed2019-01-29 11:46:03 +0000826{
827 GDBProcess *process;
828 CPUState *cpu;
829
830 if (!pid && !tid) {
831 /* 0 means any process/thread, we take the first attached one */
Alex Bennéea346af32020-03-16 17:21:34 +0000832 return gdb_first_attached_cpu();
Luc Michelab65eed2019-01-29 11:46:03 +0000833 } else if (pid && !tid) {
834 /* any thread in a specific process */
Alex Bennéea346af32020-03-16 17:21:34 +0000835 process = gdb_get_process(pid);
Luc Michelab65eed2019-01-29 11:46:03 +0000836
837 if (process == NULL) {
838 return NULL;
839 }
840
841 if (!process->attached) {
842 return NULL;
843 }
844
Alex Bennéea346af32020-03-16 17:21:34 +0000845 return get_first_cpu_in_process(process);
Luc Michelab65eed2019-01-29 11:46:03 +0000846 } else {
847 /* a specific thread */
848 cpu = find_cpu(tid);
849
850 if (cpu == NULL) {
851 return NULL;
852 }
853
Alex Bennéea346af32020-03-16 17:21:34 +0000854 process = gdb_get_cpu_process(cpu);
Luc Michelab65eed2019-01-29 11:46:03 +0000855
856 if (pid && process->pid != pid) {
857 return NULL;
858 }
859
860 if (!process->attached) {
861 return NULL;
862 }
863
864 return cpu;
865 }
866}
867
Alex Bennéea346af32020-03-16 17:21:34 +0000868static const char *get_feature_xml(const char *p, const char **newp,
869 GDBProcess *process)
pbrook56aebc82008-10-11 17:55:29 +0000870{
pbrook56aebc82008-10-11 17:55:29 +0000871 size_t len;
872 int i;
873 const char *name;
Alex Bennéea346af32020-03-16 17:21:34 +0000874 CPUState *cpu = get_first_cpu_in_process(process);
Luc Michelc145eea2019-01-07 15:23:46 +0000875 CPUClass *cc = CPU_GET_CLASS(cpu);
pbrook56aebc82008-10-11 17:55:29 +0000876
877 len = 0;
878 while (p[len] && p[len] != ':')
879 len++;
880 *newp = p + len;
881
882 name = NULL;
883 if (strncmp(p, "target.xml", len) == 0) {
Luc Michelc145eea2019-01-07 15:23:46 +0000884 char *buf = process->target_xml;
885 const size_t buf_sz = sizeof(process->target_xml);
pbrook56aebc82008-10-11 17:55:29 +0000886
Luc Michelc145eea2019-01-07 15:23:46 +0000887 /* Generate the XML description for this CPU. */
888 if (!buf[0]) {
889 GDBRegisterState *r;
890
891 pstrcat(buf, buf_sz,
David Hildenbrandb3820e62015-12-03 13:14:41 +0100892 "<?xml version=\"1.0\"?>"
893 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
894 "<target>");
895 if (cc->gdb_arch_name) {
896 gchar *arch = cc->gdb_arch_name(cpu);
Luc Michelc145eea2019-01-07 15:23:46 +0000897 pstrcat(buf, buf_sz, "<architecture>");
898 pstrcat(buf, buf_sz, arch);
899 pstrcat(buf, buf_sz, "</architecture>");
David Hildenbrandb3820e62015-12-03 13:14:41 +0100900 g_free(arch);
901 }
Luc Michelc145eea2019-01-07 15:23:46 +0000902 pstrcat(buf, buf_sz, "<xi:include href=\"");
903 pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
904 pstrcat(buf, buf_sz, "\"/>");
Andreas Färbereac8b352013-06-28 21:11:37 +0200905 for (r = cpu->gdb_regs; r; r = r->next) {
Luc Michelc145eea2019-01-07 15:23:46 +0000906 pstrcat(buf, buf_sz, "<xi:include href=\"");
907 pstrcat(buf, buf_sz, r->xml);
908 pstrcat(buf, buf_sz, "\"/>");
pbrook56aebc82008-10-11 17:55:29 +0000909 }
Luc Michelc145eea2019-01-07 15:23:46 +0000910 pstrcat(buf, buf_sz, "</target>");
pbrook56aebc82008-10-11 17:55:29 +0000911 }
Luc Michelc145eea2019-01-07 15:23:46 +0000912 return buf;
pbrook56aebc82008-10-11 17:55:29 +0000913 }
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100914 if (cc->gdb_get_dynamic_xml) {
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100915 char *xmlname = g_strndup(p, len);
916 const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
917
918 g_free(xmlname);
919 if (xml) {
920 return xml;
921 }
922 }
pbrook56aebc82008-10-11 17:55:29 +0000923 for (i = 0; ; i++) {
924 name = xml_builtin[i][0];
925 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
926 break;
927 }
928 return name ? xml_builtin[i][1] : NULL;
929}
pbrook56aebc82008-10-11 17:55:29 +0000930
Alex Bennéea010bdb2020-03-16 17:21:41 +0000931static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000932{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200933 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200934 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000935 GDBRegisterState *r;
936
Andreas Färbera0e372f2013-06-28 23:18:47 +0200937 if (reg < cc->gdb_num_core_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000938 return cc->gdb_read_register(cpu, buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200939 }
pbrook56aebc82008-10-11 17:55:29 +0000940
Andreas Färbereac8b352013-06-28 21:11:37 +0200941 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000942 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000943 return r->get_reg(env, buf, reg - r->base_reg);
pbrook56aebc82008-10-11 17:55:29 +0000944 }
945 }
946 return 0;
947}
948
Andreas Färber385b9f02013-06-27 18:25:36 +0200949static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000950{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200951 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200952 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000953 GDBRegisterState *r;
954
Andreas Färbera0e372f2013-06-28 23:18:47 +0200955 if (reg < cc->gdb_num_core_regs) {
Andreas Färber5b50e792013-06-29 04:18:45 +0200956 return cc->gdb_write_register(cpu, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200957 }
pbrook56aebc82008-10-11 17:55:29 +0000958
Andreas Färbereac8b352013-06-28 21:11:37 +0200959 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000960 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
961 return r->set_reg(env, mem_buf, reg - r->base_reg);
962 }
963 }
964 return 0;
965}
966
967/* Register a supplemental set of CPU registers. If g_pos is nonzero it
968 specifies the first register number and these registers are included in
969 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
970 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
971 */
972
Andreas Färber22169d42013-06-28 21:27:39 +0200973void gdb_register_coprocessor(CPUState *cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +0000974 gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
Andreas Färber22169d42013-06-28 21:27:39 +0200975 int num_regs, const char *xml, int g_pos)
pbrook56aebc82008-10-11 17:55:29 +0000976{
977 GDBRegisterState *s;
978 GDBRegisterState **p;
pbrook56aebc82008-10-11 17:55:29 +0000979
Andreas Färbereac8b352013-06-28 21:11:37 +0200980 p = &cpu->gdb_regs;
pbrook56aebc82008-10-11 17:55:29 +0000981 while (*p) {
982 /* Check for duplicates. */
983 if (strcmp((*p)->xml, xml) == 0)
984 return;
985 p = &(*p)->next;
986 }
Stefan Weil9643c252011-10-18 22:25:38 +0200987
988 s = g_new0(GDBRegisterState, 1);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200989 s->base_reg = cpu->gdb_num_regs;
Stefan Weil9643c252011-10-18 22:25:38 +0200990 s->num_regs = num_regs;
991 s->get_reg = get_reg;
992 s->set_reg = set_reg;
993 s->xml = xml;
994
pbrook56aebc82008-10-11 17:55:29 +0000995 /* Add to end of list. */
Andreas Färbera0e372f2013-06-28 23:18:47 +0200996 cpu->gdb_num_regs += num_regs;
pbrook56aebc82008-10-11 17:55:29 +0000997 *p = s;
998 if (g_pos) {
999 if (g_pos != s->base_reg) {
Ziyue Yang7ae6c572017-01-18 16:03:29 +08001000 error_report("Error: Bad gdb register numbering for '%s', "
1001 "expected %d got %d", xml, g_pos, s->base_reg);
Andreas Färber35143f02013-08-12 18:09:47 +02001002 } else {
1003 cpu->gdb_num_g_regs = cpu->gdb_num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001004 }
1005 }
1006}
1007
aliguoria1d1bb32008-11-18 20:07:32 +00001008#ifndef CONFIG_USER_ONLY
Peter Maydell2472b6c2014-09-12 19:04:17 +01001009/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
1010static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
1011{
1012 static const int xlat[] = {
1013 [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
1014 [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
1015 [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1016 };
1017
1018 CPUClass *cc = CPU_GET_CLASS(cpu);
1019 int cputype = xlat[gdbtype];
1020
1021 if (cc->gdb_stop_before_watchpoint) {
1022 cputype |= BP_STOP_BEFORE_ACCESS;
1023 }
1024 return cputype;
1025}
aliguoria1d1bb32008-11-18 20:07:32 +00001026#endif
1027
Jon Doron77f6ce52019-05-29 09:41:35 +03001028static int gdb_breakpoint_insert(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001029{
Andreas Färber182735e2013-05-29 22:29:20 +02001030 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001031 int err = 0;
1032
Andreas Färber62278812013-06-27 17:12:06 +02001033 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001034 return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001035 }
aliguorie22a25c2009-03-12 20:12:48 +00001036
aliguoria1d1bb32008-11-18 20:07:32 +00001037 switch (type) {
1038 case GDB_BREAKPOINT_SW:
1039 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001040 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001041 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
1042 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001043 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001044 }
aliguori880a7572008-11-18 20:30:24 +00001045 }
1046 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001047#ifndef CONFIG_USER_ONLY
1048 case GDB_WATCHPOINT_WRITE:
1049 case GDB_WATCHPOINT_READ:
1050 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001051 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001052 err = cpu_watchpoint_insert(cpu, addr, len,
1053 xlat_gdb_type(cpu, type), NULL);
1054 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001055 break;
Peter Maydell2472b6c2014-09-12 19:04:17 +01001056 }
aliguori880a7572008-11-18 20:30:24 +00001057 }
1058 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001059#endif
1060 default:
1061 return -ENOSYS;
1062 }
1063}
1064
Jon Doron77f6ce52019-05-29 09:41:35 +03001065static int gdb_breakpoint_remove(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001066{
Andreas Färber182735e2013-05-29 22:29:20 +02001067 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001068 int err = 0;
1069
Andreas Färber62278812013-06-27 17:12:06 +02001070 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001071 return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001072 }
aliguorie22a25c2009-03-12 20:12:48 +00001073
aliguoria1d1bb32008-11-18 20:07:32 +00001074 switch (type) {
1075 case GDB_BREAKPOINT_SW:
1076 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001077 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001078 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
1079 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001080 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001081 }
aliguori880a7572008-11-18 20:30:24 +00001082 }
1083 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001084#ifndef CONFIG_USER_ONLY
1085 case GDB_WATCHPOINT_WRITE:
1086 case GDB_WATCHPOINT_READ:
1087 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001088 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001089 err = cpu_watchpoint_remove(cpu, addr, len,
1090 xlat_gdb_type(cpu, type));
aliguori880a7572008-11-18 20:30:24 +00001091 if (err)
1092 break;
1093 }
1094 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001095#endif
1096 default:
1097 return -ENOSYS;
1098 }
1099}
1100
Luc Michel546f3c62019-01-07 15:23:46 +00001101static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
1102{
1103 cpu_breakpoint_remove_all(cpu, BP_GDB);
1104#ifndef CONFIG_USER_ONLY
1105 cpu_watchpoint_remove_all(cpu, BP_GDB);
1106#endif
1107}
1108
Alex Bennéea346af32020-03-16 17:21:34 +00001109static void gdb_process_breakpoint_remove_all(GDBProcess *p)
Luc Michel546f3c62019-01-07 15:23:46 +00001110{
Alex Bennéea346af32020-03-16 17:21:34 +00001111 CPUState *cpu = get_first_cpu_in_process(p);
Luc Michel546f3c62019-01-07 15:23:46 +00001112
1113 while (cpu) {
1114 gdb_cpu_breakpoint_remove_all(cpu);
Alex Bennéea346af32020-03-16 17:21:34 +00001115 cpu = gdb_next_cpu_in_process(cpu);
Luc Michel546f3c62019-01-07 15:23:46 +00001116 }
1117}
1118
aliguori880a7572008-11-18 20:30:24 +00001119static void gdb_breakpoint_remove_all(void)
aliguoria1d1bb32008-11-18 20:07:32 +00001120{
Andreas Färber182735e2013-05-29 22:29:20 +02001121 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001122
aliguorie22a25c2009-03-12 20:12:48 +00001123 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001124 kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
aliguorie22a25c2009-03-12 20:12:48 +00001125 return;
1126 }
1127
Andreas Färberbdc44642013-06-24 23:50:24 +02001128 CPU_FOREACH(cpu) {
Luc Michel546f3c62019-01-07 15:23:46 +00001129 gdb_cpu_breakpoint_remove_all(cpu);
aliguori880a7572008-11-18 20:30:24 +00001130 }
aliguoria1d1bb32008-11-18 20:07:32 +00001131}
1132
Alex Bennéea346af32020-03-16 17:21:34 +00001133static void gdb_set_cpu_pc(target_ulong pc)
aurel32fab9d282009-04-08 21:29:37 +00001134{
Alex Bennéea346af32020-03-16 17:21:34 +00001135 CPUState *cpu = gdbserver_state.c_cpu;
Andreas Färberf45748f2013-06-21 19:09:18 +02001136
1137 cpu_synchronize_state(cpu);
Peter Crosthwaite4a2b24e2015-06-23 20:19:21 -07001138 cpu_set_pc(cpu, pc);
aurel32fab9d282009-04-08 21:29:37 +00001139}
1140
Alex Bennée308f9e82020-03-16 17:21:35 +00001141static void gdb_append_thread_id(CPUState *cpu, GString *buf)
Luc Michel1a227332019-01-07 15:23:45 +00001142{
Alex Bennéea346af32020-03-16 17:21:34 +00001143 if (gdbserver_state.multiprocess) {
Alex Bennée308f9e82020-03-16 17:21:35 +00001144 g_string_append_printf(buf, "p%02x.%02x",
1145 gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001146 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00001147 g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001148 }
Luc Michel1a227332019-01-07 15:23:45 +00001149}
1150
Luc Michel7d8c87d2019-01-07 15:23:45 +00001151typedef enum GDBThreadIdKind {
1152 GDB_ONE_THREAD = 0,
1153 GDB_ALL_THREADS, /* One process, all threads */
1154 GDB_ALL_PROCESSES,
1155 GDB_READ_THREAD_ERR
1156} GDBThreadIdKind;
1157
1158static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
1159 uint32_t *pid, uint32_t *tid)
1160{
1161 unsigned long p, t;
1162 int ret;
1163
1164 if (*buf == 'p') {
1165 buf++;
1166 ret = qemu_strtoul(buf, &buf, 16, &p);
1167
1168 if (ret) {
1169 return GDB_READ_THREAD_ERR;
1170 }
1171
1172 /* Skip '.' */
1173 buf++;
1174 } else {
1175 p = 1;
1176 }
1177
1178 ret = qemu_strtoul(buf, &buf, 16, &t);
1179
1180 if (ret) {
1181 return GDB_READ_THREAD_ERR;
1182 }
1183
1184 *end_buf = buf;
1185
1186 if (p == -1) {
1187 return GDB_ALL_PROCESSES;
1188 }
1189
1190 if (pid) {
1191 *pid = p;
1192 }
1193
1194 if (t == -1) {
1195 return GDB_ALL_THREADS;
1196 }
1197
1198 if (tid) {
1199 *tid = t;
1200 }
1201
1202 return GDB_ONE_THREAD;
1203}
1204
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001205/**
1206 * gdb_handle_vcont - Parses and handles a vCont packet.
1207 * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1208 * a format error, 0 on success.
1209 */
Alex Bennéea346af32020-03-16 17:21:34 +00001210static int gdb_handle_vcont(const char *p)
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001211{
Luc Michele40e5202019-01-07 15:23:46 +00001212 int res, signal = 0;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001213 char cur_action;
1214 char *newstates;
1215 unsigned long tmp;
Luc Michele40e5202019-01-07 15:23:46 +00001216 uint32_t pid, tid;
1217 GDBProcess *process;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001218 CPUState *cpu;
Luc Michelc99ef792019-03-26 12:53:26 +00001219 GDBThreadIdKind kind;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001220#ifdef CONFIG_USER_ONLY
1221 int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1222
1223 CPU_FOREACH(cpu) {
1224 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1225 }
Like Xu5cc87672019-05-19 04:54:21 +08001226#else
1227 MachineState *ms = MACHINE(qdev_get_machine());
1228 unsigned int max_cpus = ms->smp.max_cpus;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001229#endif
1230 /* uninitialised CPUs stay 0 */
1231 newstates = g_new0(char, max_cpus);
1232
1233 /* mark valid CPUs with 1 */
1234 CPU_FOREACH(cpu) {
1235 newstates[cpu->cpu_index] = 1;
1236 }
1237
1238 /*
1239 * res keeps track of what error we are returning, with -ENOTSUP meaning
1240 * that the command is unknown or unsupported, thus returning an empty
1241 * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1242 * or incorrect parameters passed.
1243 */
1244 res = 0;
1245 while (*p) {
1246 if (*p++ != ';') {
1247 res = -ENOTSUP;
1248 goto out;
1249 }
1250
1251 cur_action = *p++;
1252 if (cur_action == 'C' || cur_action == 'S') {
Peter Maydell95a5bef2017-07-20 17:31:30 +01001253 cur_action = qemu_tolower(cur_action);
Peter Maydell3ddd9032020-11-21 21:03:42 +00001254 res = qemu_strtoul(p, &p, 16, &tmp);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001255 if (res) {
1256 goto out;
1257 }
1258 signal = gdb_signal_to_target(tmp);
1259 } else if (cur_action != 'c' && cur_action != 's') {
1260 /* unknown/invalid/unsupported command */
1261 res = -ENOTSUP;
1262 goto out;
1263 }
Luc Michele40e5202019-01-07 15:23:46 +00001264
Luc Michelc99ef792019-03-26 12:53:26 +00001265 if (*p == '\0' || *p == ';') {
1266 /*
1267 * No thread specifier, action is on "all threads". The
1268 * specification is unclear regarding the process to act on. We
1269 * choose all processes.
1270 */
1271 kind = GDB_ALL_PROCESSES;
1272 } else if (*p++ == ':') {
1273 kind = read_thread_id(p, &p, &pid, &tid);
1274 } else {
Luc Michele40e5202019-01-07 15:23:46 +00001275 res = -ENOTSUP;
1276 goto out;
1277 }
1278
Luc Michelc99ef792019-03-26 12:53:26 +00001279 switch (kind) {
Luc Michele40e5202019-01-07 15:23:46 +00001280 case GDB_READ_THREAD_ERR:
1281 res = -EINVAL;
1282 goto out;
1283
1284 case GDB_ALL_PROCESSES:
Alex Bennéea346af32020-03-16 17:21:34 +00001285 cpu = gdb_first_attached_cpu();
Luc Michele40e5202019-01-07 15:23:46 +00001286 while (cpu) {
1287 if (newstates[cpu->cpu_index] == 1) {
1288 newstates[cpu->cpu_index] = cur_action;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001289 }
Luc Michele40e5202019-01-07 15:23:46 +00001290
Alex Bennéea346af32020-03-16 17:21:34 +00001291 cpu = gdb_next_attached_cpu(cpu);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001292 }
Luc Michele40e5202019-01-07 15:23:46 +00001293 break;
1294
1295 case GDB_ALL_THREADS:
Alex Bennéea346af32020-03-16 17:21:34 +00001296 process = gdb_get_process(pid);
Luc Michele40e5202019-01-07 15:23:46 +00001297
1298 if (!process->attached) {
1299 res = -EINVAL;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001300 goto out;
1301 }
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001302
Alex Bennéea346af32020-03-16 17:21:34 +00001303 cpu = get_first_cpu_in_process(process);
Luc Michele40e5202019-01-07 15:23:46 +00001304 while (cpu) {
1305 if (newstates[cpu->cpu_index] == 1) {
1306 newstates[cpu->cpu_index] = cur_action;
1307 }
1308
Alex Bennéea346af32020-03-16 17:21:34 +00001309 cpu = gdb_next_cpu_in_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +00001310 }
1311 break;
1312
1313 case GDB_ONE_THREAD:
Alex Bennéea346af32020-03-16 17:21:34 +00001314 cpu = gdb_get_cpu(pid, tid);
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001315
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001316 /* invalid CPU/thread specified */
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001317 if (!cpu) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001318 res = -EINVAL;
1319 goto out;
1320 }
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001321
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001322 /* only use if no previous match occourred */
1323 if (newstates[cpu->cpu_index] == 1) {
1324 newstates[cpu->cpu_index] = cur_action;
1325 }
Luc Michele40e5202019-01-07 15:23:46 +00001326 break;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001327 }
1328 }
Alex Bennéea346af32020-03-16 17:21:34 +00001329 gdbserver_state.signal = signal;
1330 gdb_continue_partial(newstates);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001331
1332out:
1333 g_free(newstates);
1334
1335 return res;
1336}
1337
Jon Dorond14055d2019-05-29 09:41:29 +03001338typedef union GdbCmdVariant {
1339 const char *data;
1340 uint8_t opcode;
1341 unsigned long val_ul;
1342 unsigned long long val_ull;
1343 struct {
1344 GDBThreadIdKind kind;
1345 uint32_t pid;
1346 uint32_t tid;
1347 } thread_id;
1348} GdbCmdVariant;
1349
Alex Bennée26a16182021-05-25 09:24:14 +01001350#define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
1351
Jon Dorond14055d2019-05-29 09:41:29 +03001352static const char *cmd_next_param(const char *param, const char delimiter)
1353{
1354 static const char all_delimiters[] = ",;:=";
1355 char curr_delimiters[2] = {0};
1356 const char *delimiters;
1357
1358 if (delimiter == '?') {
1359 delimiters = all_delimiters;
1360 } else if (delimiter == '0') {
1361 return strchr(param, '\0');
1362 } else if (delimiter == '.' && *param) {
1363 return param + 1;
1364 } else {
1365 curr_delimiters[0] = delimiter;
1366 delimiters = curr_delimiters;
1367 }
1368
1369 param += strcspn(param, delimiters);
1370 if (*param) {
1371 param++;
1372 }
1373 return param;
1374}
1375
1376static int cmd_parse_params(const char *data, const char *schema,
Alex Bennée26a16182021-05-25 09:24:14 +01001377 GArray *params)
Jon Dorond14055d2019-05-29 09:41:29 +03001378{
Jon Dorond14055d2019-05-29 09:41:29 +03001379 const char *curr_schema, *curr_data;
1380
Alex Bennée26a16182021-05-25 09:24:14 +01001381 g_assert(schema);
1382 g_assert(params->len == 0);
Jon Dorond14055d2019-05-29 09:41:29 +03001383
1384 curr_schema = schema;
Jon Dorond14055d2019-05-29 09:41:29 +03001385 curr_data = data;
1386 while (curr_schema[0] && curr_schema[1] && *curr_data) {
Alex Bennée26a16182021-05-25 09:24:14 +01001387 GdbCmdVariant this_param;
1388
Jon Dorond14055d2019-05-29 09:41:29 +03001389 switch (curr_schema[0]) {
1390 case 'l':
1391 if (qemu_strtoul(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001392 &this_param.val_ul)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001393 return -EINVAL;
1394 }
Jon Dorond14055d2019-05-29 09:41:29 +03001395 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001396 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001397 break;
1398 case 'L':
1399 if (qemu_strtou64(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001400 (uint64_t *)&this_param.val_ull)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001401 return -EINVAL;
1402 }
Jon Dorond14055d2019-05-29 09:41:29 +03001403 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001404 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001405 break;
1406 case 's':
Alex Bennée26a16182021-05-25 09:24:14 +01001407 this_param.data = curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001408 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001409 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001410 break;
1411 case 'o':
Alex Bennée26a16182021-05-25 09:24:14 +01001412 this_param.opcode = *(uint8_t *)curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001413 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001414 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001415 break;
1416 case 't':
Alex Bennée26a16182021-05-25 09:24:14 +01001417 this_param.thread_id.kind =
Jon Dorond14055d2019-05-29 09:41:29 +03001418 read_thread_id(curr_data, &curr_data,
Alex Bennée26a16182021-05-25 09:24:14 +01001419 &this_param.thread_id.pid,
1420 &this_param.thread_id.tid);
Jon Dorond14055d2019-05-29 09:41:29 +03001421 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001422 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001423 break;
1424 case '?':
1425 curr_data = cmd_next_param(curr_data, curr_schema[1]);
1426 break;
1427 default:
1428 return -EINVAL;
1429 }
1430 curr_schema += 2;
1431 }
1432
Jon Dorond14055d2019-05-29 09:41:29 +03001433 return 0;
1434}
1435
Alex Bennée26a16182021-05-25 09:24:14 +01001436typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001437
1438/*
1439 * cmd_startswith -> cmd is compared using startswith
1440 *
1441 *
1442 * schema definitions:
1443 * Each schema parameter entry consists of 2 chars,
1444 * the first char represents the parameter type handling
1445 * the second char represents the delimiter for the next parameter
1446 *
1447 * Currently supported schema types:
1448 * 'l' -> unsigned long (stored in .val_ul)
1449 * 'L' -> unsigned long long (stored in .val_ull)
1450 * 's' -> string (stored in .data)
1451 * 'o' -> single char (stored in .opcode)
1452 * 't' -> thread id (stored in .thread_id)
1453 * '?' -> skip according to delimiter
1454 *
1455 * Currently supported delimiters:
1456 * '?' -> Stop at any delimiter (",;:=\0")
1457 * '0' -> Stop at "\0"
1458 * '.' -> Skip 1 char unless reached "\0"
1459 * Any other value is treated as the delimiter value itself
1460 */
1461typedef struct GdbCmdParseEntry {
1462 GdbCmdHandler handler;
1463 const char *cmd;
1464 bool cmd_startswith;
1465 const char *schema;
1466} GdbCmdParseEntry;
1467
1468static inline int startswith(const char *string, const char *pattern)
1469{
1470 return !strncmp(string, pattern, strlen(pattern));
1471}
1472
Alex Bennéea346af32020-03-16 17:21:34 +00001473static int process_string_cmd(void *user_ctx, const char *data,
Jon Dorond14055d2019-05-29 09:41:29 +03001474 const GdbCmdParseEntry *cmds, int num_cmds)
1475{
Alex Bennée26a16182021-05-25 09:24:14 +01001476 int i;
1477 g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
Jon Dorond14055d2019-05-29 09:41:29 +03001478
1479 if (!cmds) {
1480 return -1;
1481 }
1482
1483 for (i = 0; i < num_cmds; i++) {
1484 const GdbCmdParseEntry *cmd = &cmds[i];
1485 g_assert(cmd->handler && cmd->cmd);
1486
1487 if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1488 (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1489 continue;
1490 }
1491
1492 if (cmd->schema) {
Alex Bennée26a16182021-05-25 09:24:14 +01001493 if (cmd_parse_params(&data[strlen(cmd->cmd)],
1494 cmd->schema, params)) {
1495 return -1;
Jon Dorond14055d2019-05-29 09:41:29 +03001496 }
Jon Dorond14055d2019-05-29 09:41:29 +03001497 }
1498
Alex Bennée26a16182021-05-25 09:24:14 +01001499 cmd->handler(params, user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001500 return 0;
1501 }
1502
1503 return -1;
1504}
1505
Alex Bennéea346af32020-03-16 17:21:34 +00001506static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
Jon Doron3e2c1262019-05-29 09:41:30 +03001507{
1508 if (!data) {
1509 return;
1510 }
1511
Alex Bennée308f9e82020-03-16 17:21:35 +00001512 g_string_set_size(gdbserver_state.str_buf, 0);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001513 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Alex Bennée308f9e82020-03-16 17:21:35 +00001514
Jon Doron3e2c1262019-05-29 09:41:30 +03001515 /* In case there was an error during the command parsing we must
1516 * send a NULL packet to indicate the command is not supported */
Alex Bennéea346af32020-03-16 17:21:34 +00001517 if (process_string_cmd(NULL, data, cmd, 1)) {
1518 put_packet("");
Jon Doron3e2c1262019-05-29 09:41:30 +03001519 }
1520}
1521
Alex Bennée26a16182021-05-25 09:24:14 +01001522static void handle_detach(GArray *params, void *user_ctx)
Jon Doron3e2c1262019-05-29 09:41:30 +03001523{
1524 GDBProcess *process;
Jon Doron3e2c1262019-05-29 09:41:30 +03001525 uint32_t pid = 1;
1526
Alex Bennéea346af32020-03-16 17:21:34 +00001527 if (gdbserver_state.multiprocess) {
Alex Bennée26a16182021-05-25 09:24:14 +01001528 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001529 put_packet("E22");
Jon Doron3e2c1262019-05-29 09:41:30 +03001530 return;
1531 }
1532
Alex Bennée26a16182021-05-25 09:24:14 +01001533 pid = get_param(params, 0)->val_ul;
Jon Doron3e2c1262019-05-29 09:41:30 +03001534 }
1535
Alex Bennéea346af32020-03-16 17:21:34 +00001536 process = gdb_get_process(pid);
1537 gdb_process_breakpoint_remove_all(process);
Jon Doron3e2c1262019-05-29 09:41:30 +03001538 process->attached = false;
1539
Alex Bennéea346af32020-03-16 17:21:34 +00001540 if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1541 gdbserver_state.c_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001542 }
1543
Alex Bennéea346af32020-03-16 17:21:34 +00001544 if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1545 gdbserver_state.g_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001546 }
1547
Alex Bennéea346af32020-03-16 17:21:34 +00001548 if (!gdbserver_state.c_cpu) {
Jon Doron3e2c1262019-05-29 09:41:30 +03001549 /* No more process attached */
1550 gdb_syscall_mode = GDB_SYS_DISABLED;
Alex Bennéea346af32020-03-16 17:21:34 +00001551 gdb_continue();
Jon Doron3e2c1262019-05-29 09:41:30 +03001552 }
Alex Bennéea346af32020-03-16 17:21:34 +00001553 put_packet("OK");
Jon Doron3e2c1262019-05-29 09:41:30 +03001554}
1555
Alex Bennée26a16182021-05-25 09:24:14 +01001556static void handle_thread_alive(GArray *params, void *user_ctx)
Jon Doron44ffded2019-05-29 09:41:31 +03001557{
1558 CPUState *cpu;
1559
Alex Bennée26a16182021-05-25 09:24:14 +01001560 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001561 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001562 return;
1563 }
1564
Alex Bennée26a16182021-05-25 09:24:14 +01001565 if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001566 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001567 return;
1568 }
1569
Alex Bennée26a16182021-05-25 09:24:14 +01001570 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1571 get_param(params, 0)->thread_id.tid);
Jon Doron44ffded2019-05-29 09:41:31 +03001572 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001573 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001574 return;
1575 }
1576
Alex Bennéea346af32020-03-16 17:21:34 +00001577 put_packet("OK");
Jon Doron44ffded2019-05-29 09:41:31 +03001578}
1579
Alex Bennée26a16182021-05-25 09:24:14 +01001580static void handle_continue(GArray *params, void *user_ctx)
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001581{
Alex Bennée26a16182021-05-25 09:24:14 +01001582 if (params->len) {
1583 gdb_set_cpu_pc(get_param(params, 0)->val_ull);
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001584 }
1585
Alex Bennéea346af32020-03-16 17:21:34 +00001586 gdbserver_state.signal = 0;
1587 gdb_continue();
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001588}
1589
Alex Bennée26a16182021-05-25 09:24:14 +01001590static void handle_cont_with_sig(GArray *params, void *user_ctx)
Jon Doronccc47d52019-05-29 09:41:33 +03001591{
1592 unsigned long signal = 0;
1593
1594 /*
1595 * Note: C sig;[addr] is currently unsupported and we simply
1596 * omit the addr parameter
1597 */
Alex Bennée26a16182021-05-25 09:24:14 +01001598 if (params->len) {
1599 signal = get_param(params, 0)->val_ul;
Jon Doronccc47d52019-05-29 09:41:33 +03001600 }
1601
Alex Bennéea346af32020-03-16 17:21:34 +00001602 gdbserver_state.signal = gdb_signal_to_target(signal);
1603 if (gdbserver_state.signal == -1) {
1604 gdbserver_state.signal = 0;
Jon Doronccc47d52019-05-29 09:41:33 +03001605 }
Alex Bennéea346af32020-03-16 17:21:34 +00001606 gdb_continue();
Jon Doronccc47d52019-05-29 09:41:33 +03001607}
1608
Alex Bennée26a16182021-05-25 09:24:14 +01001609static void handle_set_thread(GArray *params, void *user_ctx)
Jon Doron3a9651d2019-05-29 09:41:34 +03001610{
1611 CPUState *cpu;
1612
Alex Bennée26a16182021-05-25 09:24:14 +01001613 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001614 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001615 return;
1616 }
1617
Alex Bennée26a16182021-05-25 09:24:14 +01001618 if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001619 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001620 return;
1621 }
1622
Alex Bennée26a16182021-05-25 09:24:14 +01001623 if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
Alex Bennéea346af32020-03-16 17:21:34 +00001624 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001625 return;
1626 }
1627
Alex Bennée26a16182021-05-25 09:24:14 +01001628 cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1629 get_param(params, 1)->thread_id.tid);
Jon Doron3a9651d2019-05-29 09:41:34 +03001630 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001631 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001632 return;
1633 }
1634
1635 /*
1636 * Note: This command is deprecated and modern gdb's will be using the
1637 * vCont command instead.
1638 */
Alex Bennée26a16182021-05-25 09:24:14 +01001639 switch (get_param(params, 0)->opcode) {
Jon Doron3a9651d2019-05-29 09:41:34 +03001640 case 'c':
Alex Bennéea346af32020-03-16 17:21:34 +00001641 gdbserver_state.c_cpu = cpu;
1642 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001643 break;
1644 case 'g':
Alex Bennéea346af32020-03-16 17:21:34 +00001645 gdbserver_state.g_cpu = cpu;
1646 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001647 break;
1648 default:
Alex Bennéea346af32020-03-16 17:21:34 +00001649 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001650 break;
1651 }
1652}
1653
Alex Bennée26a16182021-05-25 09:24:14 +01001654static void handle_insert_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001655{
1656 int res;
1657
Alex Bennée26a16182021-05-25 09:24:14 +01001658 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001659 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001660 return;
1661 }
1662
Alex Bennée26a16182021-05-25 09:24:14 +01001663 res = gdb_breakpoint_insert(get_param(params, 0)->val_ul,
1664 get_param(params, 1)->val_ull,
1665 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001666 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001667 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001668 return;
1669 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001670 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001671 return;
1672 }
1673
Alex Bennéea346af32020-03-16 17:21:34 +00001674 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001675}
1676
Alex Bennée26a16182021-05-25 09:24:14 +01001677static void handle_remove_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001678{
1679 int res;
1680
Alex Bennée26a16182021-05-25 09:24:14 +01001681 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001682 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001683 return;
1684 }
1685
Alex Bennée26a16182021-05-25 09:24:14 +01001686 res = gdb_breakpoint_remove(get_param(params, 0)->val_ul,
1687 get_param(params, 1)->val_ull,
1688 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001689 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001690 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001691 return;
1692 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001693 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001694 return;
1695 }
1696
Alex Bennéea346af32020-03-16 17:21:34 +00001697 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001698}
1699
Alex Bennée94b2a622019-07-05 14:23:07 +01001700/*
1701 * handle_set/get_reg
1702 *
1703 * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1704 * This works, but can be very slow. Anything new enough to understand
1705 * XML also knows how to use this properly. However to use this we
1706 * need to define a local XML file as well as be talking to a
1707 * reasonably modern gdb. Responding with an empty packet will cause
1708 * the remote gdb to fallback to older methods.
1709 */
1710
Alex Bennée26a16182021-05-25 09:24:14 +01001711static void handle_set_reg(GArray *params, void *user_ctx)
Jon Doron62b33202019-05-29 09:41:36 +03001712{
1713 int reg_size;
1714
1715 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001716 put_packet("");
Jon Doron62b33202019-05-29 09:41:36 +03001717 return;
1718 }
1719
Alex Bennée26a16182021-05-25 09:24:14 +01001720 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001721 put_packet("E22");
Jon Doron62b33202019-05-29 09:41:36 +03001722 return;
1723 }
1724
Alex Bennée26a16182021-05-25 09:24:14 +01001725 reg_size = strlen(get_param(params, 1)->data) / 2;
1726 hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001727 gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
Alex Bennée26a16182021-05-25 09:24:14 +01001728 get_param(params, 0)->val_ull);
Alex Bennéea346af32020-03-16 17:21:34 +00001729 put_packet("OK");
Jon Doron62b33202019-05-29 09:41:36 +03001730}
1731
Alex Bennée26a16182021-05-25 09:24:14 +01001732static void handle_get_reg(GArray *params, void *user_ctx)
Jon Doron5d0e57b2019-05-29 09:41:37 +03001733{
1734 int reg_size;
1735
Jon Doron5d0e57b2019-05-29 09:41:37 +03001736 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001737 put_packet("");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001738 return;
1739 }
1740
Alex Bennée26a16182021-05-25 09:24:14 +01001741 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001742 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001743 return;
1744 }
1745
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001746 reg_size = gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001747 gdbserver_state.mem_buf,
Alex Bennée26a16182021-05-25 09:24:14 +01001748 get_param(params, 0)->val_ull);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001749 if (!reg_size) {
Alex Bennéea346af32020-03-16 17:21:34 +00001750 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001751 return;
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001752 } else {
1753 g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001754 }
1755
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001756 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
Alex Bennée308f9e82020-03-16 17:21:35 +00001757 put_strbuf();
Jon Doron5d0e57b2019-05-29 09:41:37 +03001758}
1759
Alex Bennée26a16182021-05-25 09:24:14 +01001760static void handle_write_mem(GArray *params, void *user_ctx)
Jon Doroncc0ecc72019-05-29 09:41:38 +03001761{
Alex Bennée26a16182021-05-25 09:24:14 +01001762 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001763 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001764 return;
1765 }
1766
1767 /* hextomem() reads 2*len bytes */
Alex Bennée26a16182021-05-25 09:24:14 +01001768 if (get_param(params, 1)->val_ull >
1769 strlen(get_param(params, 2)->data) / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001770 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001771 return;
1772 }
1773
Alex Bennée26a16182021-05-25 09:24:14 +01001774 hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1775 get_param(params, 1)->val_ull);
1776 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1777 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001778 gdbserver_state.mem_buf->data,
1779 gdbserver_state.mem_buf->len, true)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001780 put_packet("E14");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001781 return;
1782 }
1783
Alex Bennéea346af32020-03-16 17:21:34 +00001784 put_packet("OK");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001785}
1786
Alex Bennée26a16182021-05-25 09:24:14 +01001787static void handle_read_mem(GArray *params, void *user_ctx)
Jon Doronda92e232019-05-29 09:41:39 +03001788{
Alex Bennée26a16182021-05-25 09:24:14 +01001789 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001790 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001791 return;
1792 }
1793
1794 /* memtohex() doubles the required space */
Alex Bennée26a16182021-05-25 09:24:14 +01001795 if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001796 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001797 return;
1798 }
1799
Alex Bennée26a16182021-05-25 09:24:14 +01001800 g_byte_array_set_size(gdbserver_state.mem_buf,
1801 get_param(params, 1)->val_ull);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001802
Alex Bennée26a16182021-05-25 09:24:14 +01001803 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1804 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001805 gdbserver_state.mem_buf->data,
1806 gdbserver_state.mem_buf->len, false)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001807 put_packet("E14");
Jon Doronda92e232019-05-29 09:41:39 +03001808 return;
1809 }
1810
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001811 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1812 gdbserver_state.mem_buf->len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001813 put_strbuf();
Jon Doronda92e232019-05-29 09:41:39 +03001814}
1815
Alex Bennée26a16182021-05-25 09:24:14 +01001816static void handle_write_all_regs(GArray *params, void *user_ctx)
Jon Doron287ca122019-05-29 09:41:40 +03001817{
1818 target_ulong addr, len;
1819 uint8_t *registers;
1820 int reg_size;
1821
Alex Bennée26a16182021-05-25 09:24:14 +01001822 if (!params->len) {
Jon Doron287ca122019-05-29 09:41:40 +03001823 return;
1824 }
1825
Alex Bennéea346af32020-03-16 17:21:34 +00001826 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennée26a16182021-05-25 09:24:14 +01001827 len = strlen(get_param(params, 0)->data) / 2;
1828 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001829 registers = gdbserver_state.mem_buf->data;
Alex Bennéea346af32020-03-16 17:21:34 +00001830 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
Jon Doron287ca122019-05-29 09:41:40 +03001831 addr++) {
Alex Bennéea346af32020-03-16 17:21:34 +00001832 reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
Jon Doron287ca122019-05-29 09:41:40 +03001833 len -= reg_size;
1834 registers += reg_size;
1835 }
Alex Bennéea346af32020-03-16 17:21:34 +00001836 put_packet("OK");
Jon Doron287ca122019-05-29 09:41:40 +03001837}
1838
Alex Bennée26a16182021-05-25 09:24:14 +01001839static void handle_read_all_regs(GArray *params, void *user_ctx)
Jon Doron397d1372019-05-29 09:41:41 +03001840{
1841 target_ulong addr, len;
1842
Alex Bennéea346af32020-03-16 17:21:34 +00001843 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennéea010bdb2020-03-16 17:21:41 +00001844 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Jon Doron397d1372019-05-29 09:41:41 +03001845 len = 0;
Alex Bennéea346af32020-03-16 17:21:34 +00001846 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001847 len += gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001848 gdbserver_state.mem_buf,
Jon Doron397d1372019-05-29 09:41:41 +03001849 addr);
1850 }
Alex Bennéea010bdb2020-03-16 17:21:41 +00001851 g_assert(len == gdbserver_state.mem_buf->len);
Jon Doron397d1372019-05-29 09:41:41 +03001852
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001853 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001854 put_strbuf();
Jon Doron397d1372019-05-29 09:41:41 +03001855}
1856
Alex Bennée26a16182021-05-25 09:24:14 +01001857static void handle_file_io(GArray *params, void *user_ctx)
Jon Doron4b20fab2019-05-29 09:41:42 +03001858{
Alex Bennée26a16182021-05-25 09:24:14 +01001859 if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
Jon Doron4b20fab2019-05-29 09:41:42 +03001860 target_ulong ret, err;
1861
Alex Bennée26a16182021-05-25 09:24:14 +01001862 ret = (target_ulong)get_param(params, 0)->val_ull;
1863 if (params->len >= 2) {
1864 err = (target_ulong)get_param(params, 1)->val_ull;
Sandra Loosemorec6ee9522019-08-27 16:33:17 -06001865 } else {
1866 err = 0;
1867 }
Alex Bennéea346af32020-03-16 17:21:34 +00001868 gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1869 gdbserver_state.current_syscall_cb = NULL;
Jon Doron4b20fab2019-05-29 09:41:42 +03001870 }
1871
Alex Bennée26a16182021-05-25 09:24:14 +01001872 if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
Alex Bennéea346af32020-03-16 17:21:34 +00001873 put_packet("T02");
Jon Doron4b20fab2019-05-29 09:41:42 +03001874 return;
1875 }
1876
Alex Bennéea346af32020-03-16 17:21:34 +00001877 gdb_continue();
Jon Doron4b20fab2019-05-29 09:41:42 +03001878}
1879
Alex Bennée26a16182021-05-25 09:24:14 +01001880static void handle_step(GArray *params, void *user_ctx)
Jon Doron933f80d2019-05-29 09:41:43 +03001881{
Alex Bennée26a16182021-05-25 09:24:14 +01001882 if (params->len) {
1883 gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
Jon Doron933f80d2019-05-29 09:41:43 +03001884 }
1885
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001886 cpu_single_step(gdbserver_state.c_cpu, get_sstep_flags());
Alex Bennéea346af32020-03-16 17:21:34 +00001887 gdb_continue();
Jon Doron933f80d2019-05-29 09:41:43 +03001888}
1889
Alex Bennée26a16182021-05-25 09:24:14 +01001890static void handle_backward(GArray *params, void *user_ctx)
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001891{
Alex Bennéeed12f5b2021-05-20 18:43:02 +01001892 if (!stub_can_reverse()) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001893 put_packet("E22");
1894 }
Alex Bennée26a16182021-05-25 09:24:14 +01001895 if (params->len == 1) {
1896 switch (get_param(params, 0)->opcode) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001897 case 's':
1898 if (replay_reverse_step()) {
1899 gdb_continue();
1900 } else {
1901 put_packet("E14");
1902 }
1903 return;
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03001904 case 'c':
1905 if (replay_reverse_continue()) {
1906 gdb_continue();
1907 } else {
1908 put_packet("E14");
1909 }
1910 return;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001911 }
1912 }
1913
1914 /* Default invalid command */
1915 put_packet("");
1916}
1917
Alex Bennée26a16182021-05-25 09:24:14 +01001918static void handle_v_cont_query(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001919{
Alex Bennéea346af32020-03-16 17:21:34 +00001920 put_packet("vCont;c;C;s;S");
Jon Doron8536ec02019-05-29 09:41:44 +03001921}
1922
Alex Bennée26a16182021-05-25 09:24:14 +01001923static void handle_v_cont(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001924{
1925 int res;
1926
Alex Bennée26a16182021-05-25 09:24:14 +01001927 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001928 return;
1929 }
1930
Alex Bennée26a16182021-05-25 09:24:14 +01001931 res = gdb_handle_vcont(get_param(params, 0)->data);
Jon Doron8536ec02019-05-29 09:41:44 +03001932 if ((res == -EINVAL) || (res == -ERANGE)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001933 put_packet("E22");
Jon Doron8536ec02019-05-29 09:41:44 +03001934 } else if (res) {
Alex Bennéea346af32020-03-16 17:21:34 +00001935 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03001936 }
1937}
1938
Alex Bennée26a16182021-05-25 09:24:14 +01001939static void handle_v_attach(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001940{
1941 GDBProcess *process;
1942 CPUState *cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001943
Alex Bennée308f9e82020-03-16 17:21:35 +00001944 g_string_assign(gdbserver_state.str_buf, "E22");
Alex Bennée26a16182021-05-25 09:24:14 +01001945 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001946 goto cleanup;
1947 }
1948
Alex Bennée26a16182021-05-25 09:24:14 +01001949 process = gdb_get_process(get_param(params, 0)->val_ul);
Jon Doron8536ec02019-05-29 09:41:44 +03001950 if (!process) {
1951 goto cleanup;
1952 }
1953
Alex Bennéea346af32020-03-16 17:21:34 +00001954 cpu = get_first_cpu_in_process(process);
Jon Doron8536ec02019-05-29 09:41:44 +03001955 if (!cpu) {
1956 goto cleanup;
1957 }
1958
1959 process->attached = true;
Alex Bennéea346af32020-03-16 17:21:34 +00001960 gdbserver_state.g_cpu = cpu;
1961 gdbserver_state.c_cpu = cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001962
Alex Bennée308f9e82020-03-16 17:21:35 +00001963 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
1964 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
1965 g_string_append_c(gdbserver_state.str_buf, ';');
Jon Doron8536ec02019-05-29 09:41:44 +03001966cleanup:
Alex Bennée308f9e82020-03-16 17:21:35 +00001967 put_strbuf();
Jon Doron8536ec02019-05-29 09:41:44 +03001968}
1969
Alex Bennée26a16182021-05-25 09:24:14 +01001970static void handle_v_kill(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001971{
1972 /* Kill the target */
Alex Bennéea346af32020-03-16 17:21:34 +00001973 put_packet("OK");
Jon Doron8536ec02019-05-29 09:41:44 +03001974 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00001975 gdb_exit(0);
Jon Doron8536ec02019-05-29 09:41:44 +03001976 exit(0);
1977}
1978
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01001979static const GdbCmdParseEntry gdb_v_commands_table[] = {
Jon Doron8536ec02019-05-29 09:41:44 +03001980 /* Order is important if has same prefix */
1981 {
1982 .handler = handle_v_cont_query,
1983 .cmd = "Cont?",
1984 .cmd_startswith = 1
1985 },
1986 {
1987 .handler = handle_v_cont,
1988 .cmd = "Cont",
1989 .cmd_startswith = 1,
1990 .schema = "s0"
1991 },
1992 {
1993 .handler = handle_v_attach,
1994 .cmd = "Attach;",
1995 .cmd_startswith = 1,
1996 .schema = "l0"
1997 },
1998 {
1999 .handler = handle_v_kill,
2000 .cmd = "Kill;",
2001 .cmd_startswith = 1
2002 },
2003};
2004
Alex Bennée26a16182021-05-25 09:24:14 +01002005static void handle_v_commands(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03002006{
Alex Bennée26a16182021-05-25 09:24:14 +01002007 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03002008 return;
2009 }
2010
Alex Bennée26a16182021-05-25 09:24:14 +01002011 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron8536ec02019-05-29 09:41:44 +03002012 gdb_v_commands_table,
2013 ARRAY_SIZE(gdb_v_commands_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002014 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03002015 }
2016}
2017
Alex Bennée26a16182021-05-25 09:24:14 +01002018static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002019{
Alex Bennée308f9e82020-03-16 17:21:35 +00002020 g_string_printf(gdbserver_state.str_buf, "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
2021 SSTEP_ENABLE, SSTEP_NOIRQ, SSTEP_NOTIMER);
2022 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002023}
2024
Alex Bennée26a16182021-05-25 09:24:14 +01002025static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002026{
Alex Bennée26a16182021-05-25 09:24:14 +01002027 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002028 return;
2029 }
2030
Alex Bennée26a16182021-05-25 09:24:14 +01002031 sstep_flags = get_param(params, 0)->val_ul;
Alex Bennéea346af32020-03-16 17:21:34 +00002032 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002033}
2034
Alex Bennée26a16182021-05-25 09:24:14 +01002035static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002036{
Alex Bennée308f9e82020-03-16 17:21:35 +00002037 g_string_printf(gdbserver_state.str_buf, "0x%x", sstep_flags);
2038 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002039}
2040
Alex Bennée26a16182021-05-25 09:24:14 +01002041static void handle_query_curr_tid(GArray *params, void *user_ctx)
bellardb4608c02003-06-27 17:34:32 +00002042{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002043 CPUState *cpu;
Luc Michelc145eea2019-01-07 15:23:46 +00002044 GDBProcess *process;
Jon Doron2704efa2019-05-29 09:41:45 +03002045
2046 /*
2047 * "Current thread" remains vague in the spec, so always return
2048 * the first thread of the current process (gdb returns the
2049 * first thread).
2050 */
Alex Bennéea346af32020-03-16 17:21:34 +00002051 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2052 cpu = get_first_cpu_in_process(process);
Alex Bennée308f9e82020-03-16 17:21:35 +00002053 g_string_assign(gdbserver_state.str_buf, "QC");
2054 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2055 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002056}
2057
Alex Bennée26a16182021-05-25 09:24:14 +01002058static void handle_query_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002059{
Alex Bennéea346af32020-03-16 17:21:34 +00002060 if (!gdbserver_state.query_cpu) {
2061 put_packet("l");
Jon Doron2704efa2019-05-29 09:41:45 +03002062 return;
2063 }
2064
Alex Bennée308f9e82020-03-16 17:21:35 +00002065 g_string_assign(gdbserver_state.str_buf, "m");
2066 gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
2067 put_strbuf();
Alex Bennéea346af32020-03-16 17:21:34 +00002068 gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002069}
2070
Alex Bennée26a16182021-05-25 09:24:14 +01002071static void handle_query_first_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002072{
Alex Bennéea346af32020-03-16 17:21:34 +00002073 gdbserver_state.query_cpu = gdb_first_attached_cpu();
Alex Bennée26a16182021-05-25 09:24:14 +01002074 handle_query_threads(params, user_ctx);
Jon Doron2704efa2019-05-29 09:41:45 +03002075}
2076
Alex Bennée26a16182021-05-25 09:24:14 +01002077static void handle_query_thread_extra(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002078{
Alex Bennée308f9e82020-03-16 17:21:35 +00002079 g_autoptr(GString) rs = g_string_new(NULL);
Jon Doron2704efa2019-05-29 09:41:45 +03002080 CPUState *cpu;
Jon Doron2704efa2019-05-29 09:41:45 +03002081
Alex Bennée26a16182021-05-25 09:24:14 +01002082 if (!params->len ||
2083 get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00002084 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002085 return;
2086 }
2087
Alex Bennée26a16182021-05-25 09:24:14 +01002088 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
2089 get_param(params, 0)->thread_id.tid);
Jon Doron2704efa2019-05-29 09:41:45 +03002090 if (!cpu) {
2091 return;
2092 }
2093
2094 cpu_synchronize_state(cpu);
2095
Alex Bennéea346af32020-03-16 17:21:34 +00002096 if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
Jon Doron2704efa2019-05-29 09:41:45 +03002097 /* Print the CPU model and name in multiprocess mode */
2098 ObjectClass *oc = object_get_class(OBJECT(cpu));
2099 const char *cpu_model = object_class_get_name(oc);
Markus Armbruster7a309cc2020-07-14 18:02:00 +02002100 const char *cpu_name =
Denis Plotnikov076b2fa2020-04-03 20:11:44 +01002101 object_get_canonical_path_component(OBJECT(cpu));
Alex Bennée308f9e82020-03-16 17:21:35 +00002102 g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
2103 cpu->halted ? "halted " : "running");
Jon Doron2704efa2019-05-29 09:41:45 +03002104 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002105 g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
Jon Doron2704efa2019-05-29 09:41:45 +03002106 cpu->halted ? "halted " : "running");
2107 }
Alex Bennée308f9e82020-03-16 17:21:35 +00002108 trace_gdbstub_op_extra_info(rs->str);
2109 memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
2110 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002111}
2112
2113#ifdef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002114static void handle_query_offsets(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002115{
2116 TaskState *ts;
2117
Alex Bennéea346af32020-03-16 17:21:34 +00002118 ts = gdbserver_state.c_cpu->opaque;
Alex Bennée308f9e82020-03-16 17:21:35 +00002119 g_string_printf(gdbserver_state.str_buf,
2120 "Text=" TARGET_ABI_FMT_lx
2121 ";Data=" TARGET_ABI_FMT_lx
2122 ";Bss=" TARGET_ABI_FMT_lx,
2123 ts->info->code_offset,
2124 ts->info->data_offset,
2125 ts->info->data_offset);
2126 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002127}
2128#else
Alex Bennée26a16182021-05-25 09:24:14 +01002129static void handle_query_rcmd(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002130{
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002131 const guint8 zero = 0;
Jon Doron2704efa2019-05-29 09:41:45 +03002132 int len;
2133
Alex Bennée26a16182021-05-25 09:24:14 +01002134 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002135 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002136 return;
2137 }
2138
Alex Bennée26a16182021-05-25 09:24:14 +01002139 len = strlen(get_param(params, 0)->data);
Jon Doron2704efa2019-05-29 09:41:45 +03002140 if (len % 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00002141 put_packet("E01");
Jon Doron2704efa2019-05-29 09:41:45 +03002142 return;
2143 }
2144
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002145 g_assert(gdbserver_state.mem_buf->len == 0);
Jon Doron2704efa2019-05-29 09:41:45 +03002146 len = len / 2;
Alex Bennée26a16182021-05-25 09:24:14 +01002147 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002148 g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
2149 qemu_chr_be_write(gdbserver_state.mon_chr, gdbserver_state.mem_buf->data,
2150 gdbserver_state.mem_buf->len);
Alex Bennéea346af32020-03-16 17:21:34 +00002151 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002152}
2153#endif
2154
Alex Bennée26a16182021-05-25 09:24:14 +01002155static void handle_query_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002156{
Andreas Färber5b24c642013-07-07 15:08:22 +02002157 CPUClass *cc;
Jon Doron2704efa2019-05-29 09:41:45 +03002158
Alex Bennée308f9e82020-03-16 17:21:35 +00002159 g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
Jon Doron2704efa2019-05-29 09:41:45 +03002160 cc = CPU_GET_CLASS(first_cpu);
2161 if (cc->gdb_core_xml_file) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002162 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
Jon Doron2704efa2019-05-29 09:41:45 +03002163 }
2164
Alex Bennéeed12f5b2021-05-20 18:43:02 +01002165 if (stub_can_reverse()) {
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03002166 g_string_append(gdbserver_state.str_buf,
2167 ";ReverseStep+;ReverseContinue+");
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002168 }
2169
Lirong Yuan51c623b2021-01-08 22:42:42 +00002170#ifdef CONFIG_USER_ONLY
2171 if (gdbserver_state.c_cpu->opaque) {
2172 g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
2173 }
2174#endif
2175
Alex Bennée26a16182021-05-25 09:24:14 +01002176 if (params->len &&
2177 strstr(get_param(params, 0)->data, "multiprocess+")) {
Alex Bennéea346af32020-03-16 17:21:34 +00002178 gdbserver_state.multiprocess = true;
Jon Doron2704efa2019-05-29 09:41:45 +03002179 }
2180
Changbin Du3bc26092020-03-16 17:21:55 +00002181 g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
Alex Bennée308f9e82020-03-16 17:21:35 +00002182 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002183}
2184
Alex Bennée26a16182021-05-25 09:24:14 +01002185static void handle_query_xfer_features(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002186{
2187 GDBProcess *process;
2188 CPUClass *cc;
2189 unsigned long len, total_len, addr;
2190 const char *xml;
bellardb4608c02003-06-27 17:34:32 +00002191 const char *p;
Jon Doron2704efa2019-05-29 09:41:45 +03002192
Alex Bennée26a16182021-05-25 09:24:14 +01002193 if (params->len < 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00002194 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002195 return;
2196 }
2197
Alex Bennéea346af32020-03-16 17:21:34 +00002198 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2199 cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002200 if (!cc->gdb_core_xml_file) {
Alex Bennéea346af32020-03-16 17:21:34 +00002201 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002202 return;
2203 }
2204
2205 gdb_has_xml = true;
Alex Bennée26a16182021-05-25 09:24:14 +01002206 p = get_param(params, 0)->data;
Alex Bennéea346af32020-03-16 17:21:34 +00002207 xml = get_feature_xml(p, &p, process);
Jon Doron2704efa2019-05-29 09:41:45 +03002208 if (!xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00002209 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002210 return;
2211 }
2212
Alex Bennée26a16182021-05-25 09:24:14 +01002213 addr = get_param(params, 1)->val_ul;
2214 len = get_param(params, 2)->val_ul;
Jon Doron2704efa2019-05-29 09:41:45 +03002215 total_len = strlen(xml);
2216 if (addr > total_len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002217 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002218 return;
2219 }
2220
2221 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2222 len = (MAX_PACKET_LENGTH - 5) / 2;
2223 }
2224
2225 if (len < total_len - addr) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002226 g_string_assign(gdbserver_state.str_buf, "m");
2227 memtox(gdbserver_state.str_buf, xml + addr, len);
Jon Doron2704efa2019-05-29 09:41:45 +03002228 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002229 g_string_assign(gdbserver_state.str_buf, "l");
2230 memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
Jon Doron2704efa2019-05-29 09:41:45 +03002231 }
2232
Alex Bennée308f9e82020-03-16 17:21:35 +00002233 put_packet_binary(gdbserver_state.str_buf->str,
2234 gdbserver_state.str_buf->len, true);
Jon Doron2704efa2019-05-29 09:41:45 +03002235}
2236
Lirong Yuan51c623b2021-01-08 22:42:42 +00002237#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
Alex Bennée26a16182021-05-25 09:24:14 +01002238static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
Lirong Yuan51c623b2021-01-08 22:42:42 +00002239{
2240 TaskState *ts;
2241 unsigned long offset, len, saved_auxv, auxv_len;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002242
Alex Bennée26a16182021-05-25 09:24:14 +01002243 if (params->len < 2) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002244 put_packet("E22");
2245 return;
2246 }
2247
Alex Bennée26a16182021-05-25 09:24:14 +01002248 offset = get_param(params, 0)->val_ul;
2249 len = get_param(params, 1)->val_ul;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002250 ts = gdbserver_state.c_cpu->opaque;
2251 saved_auxv = ts->info->saved_auxv;
2252 auxv_len = ts->info->auxv_len;
Richard Henderson6e3dd752021-02-02 13:39:55 +00002253
2254 if (offset >= auxv_len) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002255 put_packet("E00");
2256 return;
2257 }
2258
2259 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2260 len = (MAX_PACKET_LENGTH - 5) / 2;
2261 }
2262
2263 if (len < auxv_len - offset) {
2264 g_string_assign(gdbserver_state.str_buf, "m");
Lirong Yuan51c623b2021-01-08 22:42:42 +00002265 } else {
2266 g_string_assign(gdbserver_state.str_buf, "l");
Richard Henderson6e3dd752021-02-02 13:39:55 +00002267 len = auxv_len - offset;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002268 }
2269
Richard Henderson6e3dd752021-02-02 13:39:55 +00002270 g_byte_array_set_size(gdbserver_state.mem_buf, len);
2271 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2272 gdbserver_state.mem_buf->data, len, false)) {
2273 put_packet("E14");
2274 return;
2275 }
2276
2277 memtox(gdbserver_state.str_buf,
2278 (const char *)gdbserver_state.mem_buf->data, len);
Lirong Yuan51c623b2021-01-08 22:42:42 +00002279 put_packet_binary(gdbserver_state.str_buf->str,
2280 gdbserver_state.str_buf->len, true);
2281}
2282#endif
2283
Alex Bennée26a16182021-05-25 09:24:14 +01002284static void handle_query_attached(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002285{
Alex Bennéea346af32020-03-16 17:21:34 +00002286 put_packet(GDB_ATTACHED);
Jon Doron2704efa2019-05-29 09:41:45 +03002287}
2288
Alex Bennée26a16182021-05-25 09:24:14 +01002289static void handle_query_qemu_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002290{
Alex Bennée308f9e82020-03-16 17:21:35 +00002291 g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
Jon Doronab4752e2019-05-29 09:41:48 +03002292#ifndef CONFIG_USER_ONLY
Alex Bennée308f9e82020-03-16 17:21:35 +00002293 g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
Jon Doronab4752e2019-05-29 09:41:48 +03002294#endif
Alex Bennée308f9e82020-03-16 17:21:35 +00002295 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002296}
2297
Jon Doronab4752e2019-05-29 09:41:48 +03002298#ifndef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002299static void handle_query_qemu_phy_mem_mode(GArray *params,
Jon Doronab4752e2019-05-29 09:41:48 +03002300 void *user_ctx)
2301{
Alex Bennée308f9e82020-03-16 17:21:35 +00002302 g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
2303 put_strbuf();
Jon Doronab4752e2019-05-29 09:41:48 +03002304}
2305
Alex Bennée26a16182021-05-25 09:24:14 +01002306static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
Jon Doronab4752e2019-05-29 09:41:48 +03002307{
Alex Bennée26a16182021-05-25 09:24:14 +01002308 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002309 put_packet("E22");
Jon Doronab4752e2019-05-29 09:41:48 +03002310 return;
2311 }
2312
Alex Bennée26a16182021-05-25 09:24:14 +01002313 if (!get_param(params, 0)->val_ul) {
Jon Doronab4752e2019-05-29 09:41:48 +03002314 phy_memory_mode = 0;
2315 } else {
2316 phy_memory_mode = 1;
2317 }
Alex Bennéea346af32020-03-16 17:21:34 +00002318 put_packet("OK");
Jon Doronab4752e2019-05-29 09:41:48 +03002319}
2320#endif
2321
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002322static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002323 /* Order is important if has same prefix */
2324 {
2325 .handler = handle_query_qemu_sstepbits,
2326 .cmd = "qemu.sstepbits",
2327 },
2328 {
2329 .handler = handle_query_qemu_sstep,
2330 .cmd = "qemu.sstep",
2331 },
2332 {
2333 .handler = handle_set_qemu_sstep,
2334 .cmd = "qemu.sstep=",
2335 .cmd_startswith = 1,
2336 .schema = "l0"
2337 },
2338};
2339
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002340static const GdbCmdParseEntry gdb_gen_query_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002341 {
2342 .handler = handle_query_curr_tid,
2343 .cmd = "C",
2344 },
2345 {
2346 .handler = handle_query_threads,
2347 .cmd = "sThreadInfo",
2348 },
2349 {
2350 .handler = handle_query_first_threads,
2351 .cmd = "fThreadInfo",
2352 },
2353 {
2354 .handler = handle_query_thread_extra,
2355 .cmd = "ThreadExtraInfo,",
2356 .cmd_startswith = 1,
2357 .schema = "t0"
2358 },
2359#ifdef CONFIG_USER_ONLY
2360 {
2361 .handler = handle_query_offsets,
2362 .cmd = "Offsets",
2363 },
2364#else
2365 {
2366 .handler = handle_query_rcmd,
2367 .cmd = "Rcmd,",
2368 .cmd_startswith = 1,
2369 .schema = "s0"
2370 },
2371#endif
2372 {
2373 .handler = handle_query_supported,
2374 .cmd = "Supported:",
2375 .cmd_startswith = 1,
2376 .schema = "s0"
2377 },
2378 {
2379 .handler = handle_query_supported,
2380 .cmd = "Supported",
2381 .schema = "s0"
2382 },
2383 {
2384 .handler = handle_query_xfer_features,
2385 .cmd = "Xfer:features:read:",
2386 .cmd_startswith = 1,
2387 .schema = "s:l,l0"
2388 },
Lirong Yuan51c623b2021-01-08 22:42:42 +00002389#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2390 {
2391 .handler = handle_query_xfer_auxv,
2392 .cmd = "Xfer:auxv:read::",
2393 .cmd_startswith = 1,
2394 .schema = "l,l0"
2395 },
2396#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002397 {
2398 .handler = handle_query_attached,
2399 .cmd = "Attached:",
2400 .cmd_startswith = 1
2401 },
2402 {
2403 .handler = handle_query_attached,
2404 .cmd = "Attached",
2405 },
2406 {
2407 .handler = handle_query_qemu_supported,
2408 .cmd = "qemu.Supported",
2409 },
Jon Doronab4752e2019-05-29 09:41:48 +03002410#ifndef CONFIG_USER_ONLY
2411 {
2412 .handler = handle_query_qemu_phy_mem_mode,
2413 .cmd = "qemu.PhyMemMode",
2414 },
2415#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002416};
2417
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002418static const GdbCmdParseEntry gdb_gen_set_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002419 /* Order is important if has same prefix */
2420 {
2421 .handler = handle_set_qemu_sstep,
2422 .cmd = "qemu.sstep:",
2423 .cmd_startswith = 1,
2424 .schema = "l0"
2425 },
Jon Doronab4752e2019-05-29 09:41:48 +03002426#ifndef CONFIG_USER_ONLY
2427 {
2428 .handler = handle_set_qemu_phy_mem_mode,
2429 .cmd = "qemu.PhyMemMode:",
2430 .cmd_startswith = 1,
2431 .schema = "l0"
2432 },
2433#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002434};
2435
Alex Bennée26a16182021-05-25 09:24:14 +01002436static void handle_gen_query(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002437{
Alex Bennée26a16182021-05-25 09:24:14 +01002438 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002439 return;
2440 }
2441
Alex Bennée26a16182021-05-25 09:24:14 +01002442 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002443 gdb_gen_query_set_common_table,
2444 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2445 return;
2446 }
2447
Alex Bennée26a16182021-05-25 09:24:14 +01002448 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002449 gdb_gen_query_table,
2450 ARRAY_SIZE(gdb_gen_query_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002451 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002452 }
2453}
2454
Alex Bennée26a16182021-05-25 09:24:14 +01002455static void handle_gen_set(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002456{
Alex Bennée26a16182021-05-25 09:24:14 +01002457 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002458 return;
2459 }
2460
Alex Bennée26a16182021-05-25 09:24:14 +01002461 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002462 gdb_gen_query_set_common_table,
2463 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2464 return;
2465 }
2466
Alex Bennée26a16182021-05-25 09:24:14 +01002467 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002468 gdb_gen_set_table,
2469 ARRAY_SIZE(gdb_gen_set_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002470 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002471 }
2472}
2473
Alex Bennée26a16182021-05-25 09:24:14 +01002474static void handle_target_halt(GArray *params, void *user_ctx)
Jon Doron7009d572019-05-29 09:41:46 +03002475{
Alex Bennée308f9e82020-03-16 17:21:35 +00002476 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2477 gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2478 g_string_append_c(gdbserver_state.str_buf, ';');
2479 put_strbuf();
Jon Doron7009d572019-05-29 09:41:46 +03002480 /*
2481 * Remove all the breakpoints when this query is issued,
2482 * because gdb is doing an initial connect and the state
2483 * should be cleaned up.
2484 */
2485 gdb_breakpoint_remove_all();
2486}
2487
Alex Bennéea346af32020-03-16 17:21:34 +00002488static int gdb_handle_packet(const char *line_buf)
Jon Doron2704efa2019-05-29 09:41:45 +03002489{
Jon Doron3e2c1262019-05-29 09:41:30 +03002490 const GdbCmdParseEntry *cmd_parser = NULL;
ths3b46e622007-09-17 08:09:54 +00002491
Doug Gale5c9522b2017-12-02 20:30:37 -05002492 trace_gdbstub_io_command(line_buf);
Alex Bennée118e2262017-07-12 11:52:13 +01002493
Jon Doron3f1cbac2019-05-29 09:41:47 +03002494 switch (line_buf[0]) {
Luc Michel53fd6552019-01-07 15:23:46 +00002495 case '!':
Alex Bennéea346af32020-03-16 17:21:34 +00002496 put_packet("OK");
Luc Michel53fd6552019-01-07 15:23:46 +00002497 break;
bellard858693c2004-03-31 18:52:07 +00002498 case '?':
Jon Doron7009d572019-05-29 09:41:46 +03002499 {
2500 static const GdbCmdParseEntry target_halted_cmd_desc = {
2501 .handler = handle_target_halt,
2502 .cmd = "?",
2503 .cmd_startswith = 1
2504 };
2505 cmd_parser = &target_halted_cmd_desc;
2506 }
bellard858693c2004-03-31 18:52:07 +00002507 break;
2508 case 'c':
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002509 {
2510 static const GdbCmdParseEntry continue_cmd_desc = {
2511 .handler = handle_continue,
2512 .cmd = "c",
2513 .cmd_startswith = 1,
2514 .schema = "L0"
2515 };
2516 cmd_parser = &continue_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002517 }
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002518 break;
edgar_igl1f487ee2008-05-17 22:20:53 +00002519 case 'C':
Jon Doronccc47d52019-05-29 09:41:33 +03002520 {
2521 static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2522 .handler = handle_cont_with_sig,
2523 .cmd = "C",
2524 .cmd_startswith = 1,
2525 .schema = "l0"
2526 };
2527 cmd_parser = &cont_with_sig_cmd_desc;
2528 }
2529 break;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002530 case 'v':
Jon Doron8536ec02019-05-29 09:41:44 +03002531 {
2532 static const GdbCmdParseEntry v_cmd_desc = {
2533 .handler = handle_v_commands,
2534 .cmd = "v",
2535 .cmd_startswith = 1,
2536 .schema = "s0"
2537 };
2538 cmd_parser = &v_cmd_desc;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002539 }
Jon Doron8536ec02019-05-29 09:41:44 +03002540 break;
edgar_igl7d03f822008-05-17 18:58:29 +00002541 case 'k':
2542 /* Kill the target */
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002543 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00002544 gdb_exit(0);
edgar_igl7d03f822008-05-17 18:58:29 +00002545 exit(0);
2546 case 'D':
Jon Doron3e2c1262019-05-29 09:41:30 +03002547 {
2548 static const GdbCmdParseEntry detach_cmd_desc = {
2549 .handler = handle_detach,
2550 .cmd = "D",
2551 .cmd_startswith = 1,
2552 .schema = "?.l0"
2553 };
2554 cmd_parser = &detach_cmd_desc;
Luc Michel546f3c62019-01-07 15:23:46 +00002555 }
edgar_igl7d03f822008-05-17 18:58:29 +00002556 break;
bellard858693c2004-03-31 18:52:07 +00002557 case 's':
Jon Doron933f80d2019-05-29 09:41:43 +03002558 {
2559 static const GdbCmdParseEntry step_cmd_desc = {
2560 .handler = handle_step,
2561 .cmd = "s",
2562 .cmd_startswith = 1,
2563 .schema = "L0"
2564 };
2565 cmd_parser = &step_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002566 }
Jon Doron933f80d2019-05-29 09:41:43 +03002567 break;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002568 case 'b':
2569 {
2570 static const GdbCmdParseEntry backward_cmd_desc = {
2571 .handler = handle_backward,
2572 .cmd = "b",
2573 .cmd_startswith = 1,
2574 .schema = "o0"
2575 };
2576 cmd_parser = &backward_cmd_desc;
2577 }
2578 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002579 case 'F':
2580 {
Jon Doron4b20fab2019-05-29 09:41:42 +03002581 static const GdbCmdParseEntry file_io_cmd_desc = {
2582 .handler = handle_file_io,
2583 .cmd = "F",
2584 .cmd_startswith = 1,
2585 .schema = "L,L,o0"
2586 };
2587 cmd_parser = &file_io_cmd_desc;
pbrooka2d1eba2007-01-28 03:10:55 +00002588 }
2589 break;
bellard858693c2004-03-31 18:52:07 +00002590 case 'g':
Jon Doron397d1372019-05-29 09:41:41 +03002591 {
2592 static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2593 .handler = handle_read_all_regs,
2594 .cmd = "g",
2595 .cmd_startswith = 1
2596 };
2597 cmd_parser = &read_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002598 }
bellard858693c2004-03-31 18:52:07 +00002599 break;
2600 case 'G':
Jon Doron287ca122019-05-29 09:41:40 +03002601 {
2602 static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2603 .handler = handle_write_all_regs,
2604 .cmd = "G",
2605 .cmd_startswith = 1,
2606 .schema = "s0"
2607 };
2608 cmd_parser = &write_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002609 }
bellard858693c2004-03-31 18:52:07 +00002610 break;
2611 case 'm':
Jon Doronda92e232019-05-29 09:41:39 +03002612 {
2613 static const GdbCmdParseEntry read_mem_cmd_desc = {
2614 .handler = handle_read_mem,
2615 .cmd = "m",
2616 .cmd_startswith = 1,
2617 .schema = "L,L0"
2618 };
2619 cmd_parser = &read_mem_cmd_desc;
bellard6f970bd2005-12-05 19:55:19 +00002620 }
bellard858693c2004-03-31 18:52:07 +00002621 break;
2622 case 'M':
Jon Doroncc0ecc72019-05-29 09:41:38 +03002623 {
2624 static const GdbCmdParseEntry write_mem_cmd_desc = {
2625 .handler = handle_write_mem,
2626 .cmd = "M",
2627 .cmd_startswith = 1,
2628 .schema = "L,L:s0"
2629 };
2630 cmd_parser = &write_mem_cmd_desc;
Fabien Chouteau44520db2011-09-08 12:48:16 +02002631 }
bellard858693c2004-03-31 18:52:07 +00002632 break;
pbrook56aebc82008-10-11 17:55:29 +00002633 case 'p':
Jon Doron5d0e57b2019-05-29 09:41:37 +03002634 {
2635 static const GdbCmdParseEntry get_reg_cmd_desc = {
2636 .handler = handle_get_reg,
2637 .cmd = "p",
2638 .cmd_startswith = 1,
2639 .schema = "L0"
2640 };
2641 cmd_parser = &get_reg_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002642 }
2643 break;
2644 case 'P':
Jon Doron62b33202019-05-29 09:41:36 +03002645 {
2646 static const GdbCmdParseEntry set_reg_cmd_desc = {
2647 .handler = handle_set_reg,
2648 .cmd = "P",
2649 .cmd_startswith = 1,
2650 .schema = "L?s0"
2651 };
2652 cmd_parser = &set_reg_cmd_desc;
2653 }
pbrook56aebc82008-10-11 17:55:29 +00002654 break;
bellard858693c2004-03-31 18:52:07 +00002655 case 'Z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002656 {
2657 static const GdbCmdParseEntry insert_bp_cmd_desc = {
2658 .handler = handle_insert_bp,
2659 .cmd = "Z",
2660 .cmd_startswith = 1,
2661 .schema = "l?L?L0"
2662 };
2663 cmd_parser = &insert_bp_cmd_desc;
2664 }
2665 break;
bellard858693c2004-03-31 18:52:07 +00002666 case 'z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002667 {
2668 static const GdbCmdParseEntry remove_bp_cmd_desc = {
2669 .handler = handle_remove_bp,
2670 .cmd = "z",
2671 .cmd_startswith = 1,
2672 .schema = "l?L?L0"
2673 };
2674 cmd_parser = &remove_bp_cmd_desc;
2675 }
bellard858693c2004-03-31 18:52:07 +00002676 break;
aliguori880a7572008-11-18 20:30:24 +00002677 case 'H':
Jon Doron3a9651d2019-05-29 09:41:34 +03002678 {
2679 static const GdbCmdParseEntry set_thread_cmd_desc = {
2680 .handler = handle_set_thread,
2681 .cmd = "H",
2682 .cmd_startswith = 1,
2683 .schema = "o.t0"
2684 };
2685 cmd_parser = &set_thread_cmd_desc;
aliguori880a7572008-11-18 20:30:24 +00002686 }
2687 break;
2688 case 'T':
Jon Doron44ffded2019-05-29 09:41:31 +03002689 {
2690 static const GdbCmdParseEntry thread_alive_cmd_desc = {
2691 .handler = handle_thread_alive,
2692 .cmd = "T",
2693 .cmd_startswith = 1,
2694 .schema = "t0"
2695 };
2696 cmd_parser = &thread_alive_cmd_desc;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002697 }
aliguori880a7572008-11-18 20:30:24 +00002698 break;
pbrook978efd62006-06-17 18:30:42 +00002699 case 'q':
Jon Doron2704efa2019-05-29 09:41:45 +03002700 {
2701 static const GdbCmdParseEntry gen_query_cmd_desc = {
2702 .handler = handle_gen_query,
2703 .cmd = "q",
2704 .cmd_startswith = 1,
2705 .schema = "s0"
2706 };
2707 cmd_parser = &gen_query_cmd_desc;
2708 }
2709 break;
edgar_igl60897d32008-05-09 08:25:14 +00002710 case 'Q':
Jon Doron2704efa2019-05-29 09:41:45 +03002711 {
2712 static const GdbCmdParseEntry gen_set_cmd_desc = {
2713 .handler = handle_gen_set,
2714 .cmd = "Q",
2715 .cmd_startswith = 1,
2716 .schema = "s0"
2717 };
2718 cmd_parser = &gen_set_cmd_desc;
edgar_igl60897d32008-05-09 08:25:14 +00002719 }
Jon Doron2704efa2019-05-29 09:41:45 +03002720 break;
bellard858693c2004-03-31 18:52:07 +00002721 default:
bellard858693c2004-03-31 18:52:07 +00002722 /* put empty packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002723 put_packet("");
bellard858693c2004-03-31 18:52:07 +00002724 break;
2725 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002726
Ramiro Polla2bdec392019-08-05 21:09:01 +02002727 if (cmd_parser) {
Alex Bennéea346af32020-03-16 17:21:34 +00002728 run_cmd_parser(line_buf, cmd_parser);
Ramiro Polla2bdec392019-08-05 21:09:01 +02002729 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002730
bellard858693c2004-03-31 18:52:07 +00002731 return RS_IDLE;
2732}
2733
Andreas Färber64f6b342013-05-27 02:06:09 +02002734void gdb_set_stop_cpu(CPUState *cpu)
aliguori880a7572008-11-18 20:30:24 +00002735{
Alex Bennéea346af32020-03-16 17:21:34 +00002736 GDBProcess *p = gdb_get_cpu_process(cpu);
Luc Michel160d8582019-01-07 15:23:46 +00002737
2738 if (!p->attached) {
2739 /*
2740 * Having a stop CPU corresponding to a process that is not attached
2741 * confuses GDB. So we ignore the request.
2742 */
2743 return;
2744 }
2745
Alex Bennée8d98c442020-03-16 17:21:33 +00002746 gdbserver_state.c_cpu = cpu;
2747 gdbserver_state.g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002748}
2749
bellard1fddef42005-04-17 19:16:13 +00002750#ifndef CONFIG_USER_ONLY
Philippe Mathieu-Daudé538f0492021-01-11 16:20:20 +01002751static void gdb_vm_state_change(void *opaque, bool running, RunState state)
bellard858693c2004-03-31 18:52:07 +00002752{
Alex Bennéea346af32020-03-16 17:21:34 +00002753 CPUState *cpu = gdbserver_state.c_cpu;
Alex Bennée308f9e82020-03-16 17:21:35 +00002754 g_autoptr(GString) buf = g_string_new(NULL);
2755 g_autoptr(GString) tid = g_string_new(NULL);
aliguorid6fc1b32008-11-18 19:55:44 +00002756 const char *type;
bellard858693c2004-03-31 18:52:07 +00002757 int ret;
2758
Alex Bennéea346af32020-03-16 17:21:34 +00002759 if (running || gdbserver_state.state == RS_INACTIVE) {
Meador Ingecdb432b2012-03-15 17:49:45 +00002760 return;
2761 }
2762 /* Is there a GDB syscall waiting to be sent? */
Alex Bennéea346af32020-03-16 17:21:34 +00002763 if (gdbserver_state.current_syscall_cb) {
2764 put_packet(gdbserver_state.syscall_buf);
pbrooka2d1eba2007-01-28 03:10:55 +00002765 return;
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002766 }
Luc Michel95567c22019-01-07 15:23:46 +00002767
2768 if (cpu == NULL) {
2769 /* No process attached */
2770 return;
2771 }
2772
Alex Bennée308f9e82020-03-16 17:21:35 +00002773 gdb_append_thread_id(cpu, tid);
Luc Michel95567c22019-01-07 15:23:46 +00002774
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002775 switch (state) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002776 case RUN_STATE_DEBUG:
Andreas Färberff4700b2013-08-26 18:23:18 +02002777 if (cpu->watchpoint_hit) {
2778 switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
aliguoria1d1bb32008-11-18 20:07:32 +00002779 case BP_MEM_READ:
aliguorid6fc1b32008-11-18 19:55:44 +00002780 type = "r";
2781 break;
aliguoria1d1bb32008-11-18 20:07:32 +00002782 case BP_MEM_ACCESS:
aliguorid6fc1b32008-11-18 19:55:44 +00002783 type = "a";
2784 break;
2785 default:
2786 type = "";
2787 break;
2788 }
Doug Gale5c9522b2017-12-02 20:30:37 -05002789 trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
2790 (target_ulong)cpu->watchpoint_hit->vaddr);
Alex Bennée308f9e82020-03-16 17:21:35 +00002791 g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
2792 GDB_SIGNAL_TRAP, tid->str, type,
2793 (target_ulong)cpu->watchpoint_hit->vaddr);
Andreas Färberff4700b2013-08-26 18:23:18 +02002794 cpu->watchpoint_hit = NULL;
Jan Kiszka425189a2011-03-22 11:02:09 +01002795 goto send_packet;
Doug Gale5c9522b2017-12-02 20:30:37 -05002796 } else {
2797 trace_gdbstub_hit_break();
pbrook6658ffb2007-03-16 23:58:11 +00002798 }
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07002799 tb_flush(cpu);
aurel32ca587a82008-12-18 22:44:13 +00002800 ret = GDB_SIGNAL_TRAP;
Jan Kiszka425189a2011-03-22 11:02:09 +01002801 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002802 case RUN_STATE_PAUSED:
Doug Gale5c9522b2017-12-02 20:30:37 -05002803 trace_gdbstub_hit_paused();
aliguori9781e042009-01-22 17:15:29 +00002804 ret = GDB_SIGNAL_INT;
Jan Kiszka425189a2011-03-22 11:02:09 +01002805 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002806 case RUN_STATE_SHUTDOWN:
Doug Gale5c9522b2017-12-02 20:30:37 -05002807 trace_gdbstub_hit_shutdown();
Jan Kiszka425189a2011-03-22 11:02:09 +01002808 ret = GDB_SIGNAL_QUIT;
2809 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002810 case RUN_STATE_IO_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002811 trace_gdbstub_hit_io_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002812 ret = GDB_SIGNAL_IO;
2813 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002814 case RUN_STATE_WATCHDOG:
Doug Gale5c9522b2017-12-02 20:30:37 -05002815 trace_gdbstub_hit_watchdog();
Jan Kiszka425189a2011-03-22 11:02:09 +01002816 ret = GDB_SIGNAL_ALRM;
2817 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002818 case RUN_STATE_INTERNAL_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002819 trace_gdbstub_hit_internal_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002820 ret = GDB_SIGNAL_ABRT;
2821 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002822 case RUN_STATE_SAVE_VM:
2823 case RUN_STATE_RESTORE_VM:
Jan Kiszka425189a2011-03-22 11:02:09 +01002824 return;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002825 case RUN_STATE_FINISH_MIGRATE:
Jan Kiszka425189a2011-03-22 11:02:09 +01002826 ret = GDB_SIGNAL_XCPU;
2827 break;
2828 default:
Doug Gale5c9522b2017-12-02 20:30:37 -05002829 trace_gdbstub_hit_unknown(state);
Jan Kiszka425189a2011-03-22 11:02:09 +01002830 ret = GDB_SIGNAL_UNKNOWN;
2831 break;
bellardbbeb7b52006-04-23 18:42:15 +00002832 }
Jan Kiszka226d0072015-07-24 18:52:31 +02002833 gdb_set_stop_cpu(cpu);
Alex Bennée308f9e82020-03-16 17:21:35 +00002834 g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002835
2836send_packet:
Alex Bennée308f9e82020-03-16 17:21:35 +00002837 put_packet(buf->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002838
2839 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002840 cpu_single_step(cpu, 0);
bellard858693c2004-03-31 18:52:07 +00002841}
bellard1fddef42005-04-17 19:16:13 +00002842#endif
bellard858693c2004-03-31 18:52:07 +00002843
pbrooka2d1eba2007-01-28 03:10:55 +00002844/* Send a gdb syscall request.
2845 This accepts limited printf-style format specifiers, specifically:
pbrooka87295e2007-05-26 15:09:38 +00002846 %x - target_ulong argument printed in hex.
2847 %lx - 64-bit argument printed in hex.
2848 %s - string pointer (target_ulong) and length (int) pair. */
Peter Maydell19239b32015-09-07 10:39:27 +01002849void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
pbrooka2d1eba2007-01-28 03:10:55 +00002850{
pbrooka2d1eba2007-01-28 03:10:55 +00002851 char *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00002852 char *p_end;
pbrooka2d1eba2007-01-28 03:10:55 +00002853 target_ulong addr;
pbrooka87295e2007-05-26 15:09:38 +00002854 uint64_t i64;
pbrooka2d1eba2007-01-28 03:10:55 +00002855
Alex Bennéea346af32020-03-16 17:21:34 +00002856 if (!gdbserver_state.init) {
pbrooka2d1eba2007-01-28 03:10:55 +00002857 return;
Alex Bennéea346af32020-03-16 17:21:34 +00002858 }
Alex Bennée8d98c442020-03-16 17:21:33 +00002859
2860 gdbserver_state.current_syscall_cb = cb;
pbrooka2d1eba2007-01-28 03:10:55 +00002861#ifndef CONFIG_USER_ONLY
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002862 vm_stop(RUN_STATE_DEBUG);
pbrooka2d1eba2007-01-28 03:10:55 +00002863#endif
Alex Bennée8d98c442020-03-16 17:21:33 +00002864 p = &gdbserver_state.syscall_buf[0];
2865 p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
pbrooka2d1eba2007-01-28 03:10:55 +00002866 *(p++) = 'F';
2867 while (*fmt) {
2868 if (*fmt == '%') {
2869 fmt++;
2870 switch (*fmt++) {
2871 case 'x':
2872 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002873 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
pbrooka2d1eba2007-01-28 03:10:55 +00002874 break;
pbrooka87295e2007-05-26 15:09:38 +00002875 case 'l':
2876 if (*(fmt++) != 'x')
2877 goto bad_format;
2878 i64 = va_arg(va, uint64_t);
Meador Ingecdb432b2012-03-15 17:49:45 +00002879 p += snprintf(p, p_end - p, "%" PRIx64, i64);
pbrooka87295e2007-05-26 15:09:38 +00002880 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002881 case 's':
2882 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002883 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
blueswir1363a37d2008-08-21 17:58:08 +00002884 addr, va_arg(va, int));
pbrooka2d1eba2007-01-28 03:10:55 +00002885 break;
2886 default:
pbrooka87295e2007-05-26 15:09:38 +00002887 bad_format:
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002888 error_report("gdbstub: Bad syscall format string '%s'",
2889 fmt - 1);
pbrooka2d1eba2007-01-28 03:10:55 +00002890 break;
2891 }
2892 } else {
2893 *(p++) = *(fmt++);
2894 }
2895 }
pbrook8a93e022007-08-06 13:19:15 +00002896 *p = 0;
pbrooka2d1eba2007-01-28 03:10:55 +00002897#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +00002898 put_packet(gdbserver_state.syscall_buf);
Peter Maydell4f710862018-05-15 19:19:58 +01002899 /* Return control to gdb for it to process the syscall request.
2900 * Since the protocol requires that gdb hands control back to us
2901 * using a "here are the results" F packet, we don't need to check
2902 * gdb_handlesig's return value (which is the signal to deliver if
2903 * execution was resumed via a continue packet).
2904 */
Alex Bennée8d98c442020-03-16 17:21:33 +00002905 gdb_handlesig(gdbserver_state.c_cpu, 0);
pbrooka2d1eba2007-01-28 03:10:55 +00002906#else
Meador Ingecdb432b2012-03-15 17:49:45 +00002907 /* In this case wait to send the syscall packet until notification that
2908 the CPU has stopped. This must be done because if the packet is sent
2909 now the reply from the syscall request could be received while the CPU
2910 is still in the running state, which can cause packets to be dropped
2911 and state transition 'T' packets to be sent while the syscall is still
2912 being processed. */
Alex Bennée8d98c442020-03-16 17:21:33 +00002913 qemu_cpu_kick(gdbserver_state.c_cpu);
pbrooka2d1eba2007-01-28 03:10:55 +00002914#endif
2915}
2916
Peter Maydell19239b32015-09-07 10:39:27 +01002917void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2918{
2919 va_list va;
2920
2921 va_start(va, fmt);
2922 gdb_do_syscallv(cb, fmt, va);
2923 va_end(va);
2924}
2925
Alex Bennéea346af32020-03-16 17:21:34 +00002926static void gdb_read_byte(uint8_t ch)
bellard858693c2004-03-31 18:52:07 +00002927{
ths60fe76f2007-12-16 03:02:09 +00002928 uint8_t reply;
bellard858693c2004-03-31 18:52:07 +00002929
bellard1fddef42005-04-17 19:16:13 +00002930#ifndef CONFIG_USER_ONLY
Damien Hedded116e812020-03-16 17:21:53 +00002931 if (gdbserver_state.last_packet->len) {
pbrook4046d912007-01-28 01:53:16 +00002932 /* Waiting for a response to the last packet. If we see the start
2933 of a new command then abandon the previous response. */
2934 if (ch == '-') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002935 trace_gdbstub_err_got_nack();
Damien Hedded116e812020-03-16 17:21:53 +00002936 put_buffer(gdbserver_state.last_packet->data,
2937 gdbserver_state.last_packet->len);
Alex Bennée118e2262017-07-12 11:52:13 +01002938 } else if (ch == '+') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002939 trace_gdbstub_io_got_ack();
Alex Bennée118e2262017-07-12 11:52:13 +01002940 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002941 trace_gdbstub_io_got_unexpected(ch);
pbrook4046d912007-01-28 01:53:16 +00002942 }
Alex Bennée118e2262017-07-12 11:52:13 +01002943
Damien Hedded116e812020-03-16 17:21:53 +00002944 if (ch == '+' || ch == '$') {
2945 g_byte_array_set_size(gdbserver_state.last_packet, 0);
2946 }
pbrook4046d912007-01-28 01:53:16 +00002947 if (ch != '$')
2948 return;
2949 }
Luiz Capitulino13548692011-07-29 15:36:43 -03002950 if (runstate_is_running()) {
bellard858693c2004-03-31 18:52:07 +00002951 /* when the CPU is running, we cannot do anything except stop
2952 it when receiving a char */
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002953 vm_stop(RUN_STATE_PAUSED);
ths5fafdf22007-09-16 21:08:06 +00002954 } else
bellard1fddef42005-04-17 19:16:13 +00002955#endif
bellard41625032005-04-24 10:07:11 +00002956 {
Alex Bennéea346af32020-03-16 17:21:34 +00002957 switch(gdbserver_state.state) {
bellard858693c2004-03-31 18:52:07 +00002958 case RS_IDLE:
2959 if (ch == '$') {
Doug Gale4bf43122017-05-01 12:22:10 -04002960 /* start of command packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002961 gdbserver_state.line_buf_index = 0;
2962 gdbserver_state.line_sum = 0;
2963 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002964 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002965 trace_gdbstub_err_garbage(ch);
bellard4c3a88a2003-07-26 12:06:08 +00002966 }
2967 break;
bellard858693c2004-03-31 18:52:07 +00002968 case RS_GETLINE:
Doug Gale4bf43122017-05-01 12:22:10 -04002969 if (ch == '}') {
2970 /* start escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002971 gdbserver_state.state = RS_GETLINE_ESC;
2972 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002973 } else if (ch == '*') {
2974 /* start run length encoding sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002975 gdbserver_state.state = RS_GETLINE_RLE;
2976 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002977 } else if (ch == '#') {
2978 /* end of command, start of checksum*/
Alex Bennéea346af32020-03-16 17:21:34 +00002979 gdbserver_state.state = RS_CHKSUM1;
2980 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale5c9522b2017-12-02 20:30:37 -05002981 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00002982 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00002983 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04002984 /* unescaped command character */
Alex Bennéea346af32020-03-16 17:21:34 +00002985 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
2986 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002987 }
2988 break;
2989 case RS_GETLINE_ESC:
2990 if (ch == '#') {
2991 /* unexpected end of command in escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002992 gdbserver_state.state = RS_CHKSUM1;
2993 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04002994 /* command buffer overrun */
Doug Gale5c9522b2017-12-02 20:30:37 -05002995 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00002996 gdbserver_state.state = RS_IDLE;
Doug Gale4bf43122017-05-01 12:22:10 -04002997 } else {
2998 /* parse escaped character and leave escape state */
Alex Bennéea346af32020-03-16 17:21:34 +00002999 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
3000 gdbserver_state.line_sum += ch;
3001 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003002 }
3003 break;
3004 case RS_GETLINE_RLE:
Markus Armbruster046aba12019-05-14 20:03:08 +02003005 /*
3006 * Run-length encoding is explained in "Debugging with GDB /
3007 * Appendix E GDB Remote Serial Protocol / Overview".
3008 */
3009 if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
Doug Gale4bf43122017-05-01 12:22:10 -04003010 /* invalid RLE count encoding */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003011 trace_gdbstub_err_invalid_repeat(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003012 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003013 } else {
3014 /* decode repeat length */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003015 int repeat = ch - ' ' + 3;
Alex Bennéea346af32020-03-16 17:21:34 +00003016 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003017 /* that many repeats would overrun the command buffer */
Doug Gale5c9522b2017-12-02 20:30:37 -05003018 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003019 gdbserver_state.state = RS_IDLE;
3020 } else if (gdbserver_state.line_buf_index < 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003021 /* got a repeat but we have nothing to repeat */
Doug Gale5c9522b2017-12-02 20:30:37 -05003022 trace_gdbstub_err_invalid_rle();
Alex Bennéea346af32020-03-16 17:21:34 +00003023 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003024 } else {
3025 /* repeat the last character */
Alex Bennéea346af32020-03-16 17:21:34 +00003026 memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
3027 gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
3028 gdbserver_state.line_buf_index += repeat;
3029 gdbserver_state.line_sum += ch;
3030 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003031 }
bellard858693c2004-03-31 18:52:07 +00003032 }
3033 break;
3034 case RS_CHKSUM1:
Doug Gale4bf43122017-05-01 12:22:10 -04003035 /* get high hex digit of checksum */
3036 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003037 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003038 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003039 break;
3040 }
Alex Bennéea346af32020-03-16 17:21:34 +00003041 gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
3042 gdbserver_state.line_csum = fromhex(ch) << 4;
3043 gdbserver_state.state = RS_CHKSUM2;
bellard858693c2004-03-31 18:52:07 +00003044 break;
3045 case RS_CHKSUM2:
Doug Gale4bf43122017-05-01 12:22:10 -04003046 /* get low hex digit of checksum */
3047 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003048 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003049 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003050 break;
bellard858693c2004-03-31 18:52:07 +00003051 }
Alex Bennéea346af32020-03-16 17:21:34 +00003052 gdbserver_state.line_csum |= fromhex(ch);
Doug Gale4bf43122017-05-01 12:22:10 -04003053
Alex Bennéea346af32020-03-16 17:21:34 +00003054 if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
3055 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
Doug Gale4bf43122017-05-01 12:22:10 -04003056 /* send NAK reply */
ths60fe76f2007-12-16 03:02:09 +00003057 reply = '-';
Alex Bennéea346af32020-03-16 17:21:34 +00003058 put_buffer(&reply, 1);
3059 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003060 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003061 /* send ACK reply */
ths60fe76f2007-12-16 03:02:09 +00003062 reply = '+';
Alex Bennéea346af32020-03-16 17:21:34 +00003063 put_buffer(&reply, 1);
3064 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
bellard858693c2004-03-31 18:52:07 +00003065 }
bellardb4608c02003-06-27 17:34:32 +00003066 break;
pbrooka2d1eba2007-01-28 03:10:55 +00003067 default:
3068 abort();
bellardb4608c02003-06-27 17:34:32 +00003069 }
3070 }
bellard858693c2004-03-31 18:52:07 +00003071}
3072
Paul Brook0e1c9c52010-06-16 13:03:51 +01003073/* Tell the remote gdb that the process has exited. */
Alex Bennéead9dcb22021-01-08 22:42:43 +00003074void gdb_exit(int code)
Paul Brook0e1c9c52010-06-16 13:03:51 +01003075{
Paul Brook0e1c9c52010-06-16 13:03:51 +01003076 char buf[4];
3077
Alex Bennée8d98c442020-03-16 17:21:33 +00003078 if (!gdbserver_state.init) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003079 return;
3080 }
3081#ifdef CONFIG_USER_ONLY
Alex Bennéefcedd922020-04-30 20:01:19 +01003082 if (gdbserver_state.socket_path) {
3083 unlink(gdbserver_state.socket_path);
3084 }
Alex Bennéee0a1e202020-04-30 20:01:18 +01003085 if (gdbserver_state.fd < 0) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003086 return;
3087 }
3088#endif
3089
Doug Gale5c9522b2017-12-02 20:30:37 -05003090 trace_gdbstub_op_exiting((uint8_t)code);
3091
Paul Brook0e1c9c52010-06-16 13:03:51 +01003092 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
Alex Bennéea346af32020-03-16 17:21:34 +00003093 put_packet(buf);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003094
3095#ifndef CONFIG_USER_ONLY
Alex Bennée8d98c442020-03-16 17:21:33 +00003096 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003097#endif
Paul Brook0e1c9c52010-06-16 13:03:51 +01003098}
3099
Luc Michel8f468632019-01-07 15:23:45 +00003100/*
3101 * Create the process that will contain all the "orphan" CPUs (that are not
3102 * part of a CPU cluster). Note that if this process contains no CPUs, it won't
3103 * be attachable and thus will be invisible to the user.
3104 */
3105static void create_default_process(GDBState *s)
3106{
3107 GDBProcess *process;
3108 int max_pid = 0;
3109
Alex Bennéea346af32020-03-16 17:21:34 +00003110 if (gdbserver_state.process_num) {
Luc Michel8f468632019-01-07 15:23:45 +00003111 max_pid = s->processes[s->process_num - 1].pid;
3112 }
3113
3114 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3115 process = &s->processes[s->process_num - 1];
3116
3117 /* We need an available PID slot for this process */
3118 assert(max_pid < UINT32_MAX);
3119
3120 process->pid = max_pid + 1;
3121 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003122 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003123}
3124
bellard1fddef42005-04-17 19:16:13 +00003125#ifdef CONFIG_USER_ONLY
3126int
Andreas Färberdb6b81d2013-06-27 19:49:31 +02003127gdb_handlesig(CPUState *cpu, int sig)
bellard1fddef42005-04-17 19:16:13 +00003128{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003129 char buf[256];
3130 int n;
bellard1fddef42005-04-17 19:16:13 +00003131
Alex Bennéee0a1e202020-04-30 20:01:18 +01003132 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003133 return sig;
bellard1fddef42005-04-17 19:16:13 +00003134 }
3135
Andreas Färber5ca666c2013-06-24 19:20:57 +02003136 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02003137 cpu_single_step(cpu, 0);
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07003138 tb_flush(cpu);
bellard1fddef42005-04-17 19:16:13 +00003139
Andreas Färber5ca666c2013-06-24 19:20:57 +02003140 if (sig != 0) {
3141 snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003142 put_packet(buf);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003143 }
3144 /* put_packet() might have detected that the peer terminated the
3145 connection. */
Alex Bennée8d98c442020-03-16 17:21:33 +00003146 if (gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003147 return sig;
3148 }
3149
3150 sig = 0;
Alex Bennée8d98c442020-03-16 17:21:33 +00003151 gdbserver_state.state = RS_IDLE;
3152 gdbserver_state.running_state = 0;
3153 while (gdbserver_state.running_state == 0) {
3154 n = read(gdbserver_state.fd, buf, 256);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003155 if (n > 0) {
3156 int i;
3157
3158 for (i = 0; i < n; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003159 gdb_read_byte(buf[i]);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003160 }
Peter Wu5819e3e2016-06-05 16:35:48 +02003161 } else {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003162 /* XXX: Connection closed. Should probably wait for another
3163 connection before continuing. */
Peter Wu5819e3e2016-06-05 16:35:48 +02003164 if (n == 0) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003165 close(gdbserver_state.fd);
Peter Wu5819e3e2016-06-05 16:35:48 +02003166 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003167 gdbserver_state.fd = -1;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003168 return sig;
bellard1fddef42005-04-17 19:16:13 +00003169 }
Andreas Färber5ca666c2013-06-24 19:20:57 +02003170 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003171 sig = gdbserver_state.signal;
3172 gdbserver_state.signal = 0;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003173 return sig;
bellard1fddef42005-04-17 19:16:13 +00003174}
bellarde9009672005-04-26 20:42:36 +00003175
aurel32ca587a82008-12-18 22:44:13 +00003176/* Tell the remote gdb that the process has exited due to SIG. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01003177void gdb_signalled(CPUArchState *env, int sig)
aurel32ca587a82008-12-18 22:44:13 +00003178{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003179 char buf[4];
aurel32ca587a82008-12-18 22:44:13 +00003180
Alex Bennéee0a1e202020-04-30 20:01:18 +01003181 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003182 return;
3183 }
aurel32ca587a82008-12-18 22:44:13 +00003184
Andreas Färber5ca666c2013-06-24 19:20:57 +02003185 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003186 put_packet(buf);
aurel32ca587a82008-12-18 22:44:13 +00003187}
bellard1fddef42005-04-17 19:16:13 +00003188
Alex Bennéefcedd922020-04-30 20:01:19 +01003189static void gdb_accept_init(int fd)
3190{
3191 init_gdbserver_state();
3192 create_default_process(&gdbserver_state);
3193 gdbserver_state.processes[0].attached = true;
3194 gdbserver_state.c_cpu = gdb_first_attached_cpu();
3195 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
3196 gdbserver_state.fd = fd;
3197 gdb_has_xml = false;
3198}
3199
3200static bool gdb_accept_socket(int gdb_fd)
3201{
3202 int fd;
3203
3204 for(;;) {
3205 fd = accept(gdb_fd, NULL, NULL);
3206 if (fd < 0 && errno != EINTR) {
3207 perror("accept socket");
3208 return false;
3209 } else if (fd >= 0) {
3210 qemu_set_cloexec(fd);
3211 break;
3212 }
3213 }
3214
3215 gdb_accept_init(fd);
3216 return true;
3217}
3218
3219static int gdbserver_open_socket(const char *path)
3220{
3221 struct sockaddr_un sockaddr;
3222 int fd, ret;
3223
3224 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3225 if (fd < 0) {
3226 perror("create socket");
3227 return -1;
3228 }
3229
3230 sockaddr.sun_family = AF_UNIX;
3231 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
3232 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3233 if (ret < 0) {
3234 perror("bind socket");
3235 close(fd);
3236 return -1;
3237 }
3238 ret = listen(fd, 1);
3239 if (ret < 0) {
3240 perror("listen socket");
3241 close(fd);
3242 return -1;
3243 }
3244
3245 return fd;
3246}
3247
3248static bool gdb_accept_tcp(int gdb_fd)
bellard858693c2004-03-31 18:52:07 +00003249{
bellard858693c2004-03-31 18:52:07 +00003250 struct sockaddr_in sockaddr;
3251 socklen_t len;
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09003252 int fd;
bellard858693c2004-03-31 18:52:07 +00003253
3254 for(;;) {
3255 len = sizeof(sockaddr);
Alex Bennéee0a1e202020-04-30 20:01:18 +01003256 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
bellard858693c2004-03-31 18:52:07 +00003257 if (fd < 0 && errno != EINTR) {
3258 perror("accept");
Peter Maydell2f652222018-05-14 18:30:44 +01003259 return false;
bellard858693c2004-03-31 18:52:07 +00003260 } else if (fd >= 0) {
Peter Maydellf5bdd782018-05-14 18:30:43 +01003261 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003262 break;
3263 }
3264 }
3265
3266 /* set short latency */
Peter Maydell2f652222018-05-14 18:30:44 +01003267 if (socket_set_nodelay(fd)) {
3268 perror("setsockopt");
Philippe Mathieu-Daudéead75d82018-05-24 19:34:58 -03003269 close(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003270 return false;
3271 }
ths3b46e622007-09-17 08:09:54 +00003272
Alex Bennéefcedd922020-04-30 20:01:19 +01003273 gdb_accept_init(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003274 return true;
bellard858693c2004-03-31 18:52:07 +00003275}
3276
Alex Bennéefcedd922020-04-30 20:01:19 +01003277static int gdbserver_open_port(int port)
bellard858693c2004-03-31 18:52:07 +00003278{
3279 struct sockaddr_in sockaddr;
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003280 int fd, ret;
bellard858693c2004-03-31 18:52:07 +00003281
3282 fd = socket(PF_INET, SOCK_STREAM, 0);
3283 if (fd < 0) {
3284 perror("socket");
3285 return -1;
3286 }
Peter Maydellf5bdd782018-05-14 18:30:43 +01003287 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003288
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003289 socket_set_fast_reuse(fd);
bellard858693c2004-03-31 18:52:07 +00003290
3291 sockaddr.sin_family = AF_INET;
3292 sockaddr.sin_port = htons(port);
3293 sockaddr.sin_addr.s_addr = 0;
3294 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3295 if (ret < 0) {
3296 perror("bind");
Peter Maydellbb161722011-12-24 23:37:24 +00003297 close(fd);
bellard858693c2004-03-31 18:52:07 +00003298 return -1;
3299 }
Peter Wu96165b92016-05-04 11:32:17 +02003300 ret = listen(fd, 1);
bellard858693c2004-03-31 18:52:07 +00003301 if (ret < 0) {
3302 perror("listen");
Peter Maydellbb161722011-12-24 23:37:24 +00003303 close(fd);
bellard858693c2004-03-31 18:52:07 +00003304 return -1;
3305 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003306
bellard858693c2004-03-31 18:52:07 +00003307 return fd;
3308}
3309
Alex Bennéefcedd922020-04-30 20:01:19 +01003310int gdbserver_start(const char *port_or_path)
bellard858693c2004-03-31 18:52:07 +00003311{
Alex Bennéefcedd922020-04-30 20:01:19 +01003312 int port = g_ascii_strtoull(port_or_path, NULL, 10);
3313 int gdb_fd;
3314
3315 if (port > 0) {
3316 gdb_fd = gdbserver_open_port(port);
3317 } else {
3318 gdb_fd = gdbserver_open_socket(port_or_path);
3319 }
3320
Alex Bennéee0a1e202020-04-30 20:01:18 +01003321 if (gdb_fd < 0) {
bellard858693c2004-03-31 18:52:07 +00003322 return -1;
Alex Bennéee0a1e202020-04-30 20:01:18 +01003323 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003324
3325 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3326 return 0;
3327 } else if (gdb_accept_socket(gdb_fd)) {
3328 gdbserver_state.socket_path = g_strdup(port_or_path);
3329 return 0;
Peter Maydell2f652222018-05-14 18:30:44 +01003330 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003331
3332 /* gone wrong */
3333 close(gdb_fd);
3334 return -1;
bellardb4608c02003-06-27 17:34:32 +00003335}
aurel322b1319c2008-12-18 22:44:04 +00003336
3337/* Disable gdb stub for child processes. */
Peter Crosthwaitef7ec7f72015-06-23 19:31:16 -07003338void gdbserver_fork(CPUState *cpu)
aurel322b1319c2008-12-18 22:44:04 +00003339{
Alex Bennéee0a1e202020-04-30 20:01:18 +01003340 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber75a34032013-09-02 16:57:02 +02003341 return;
3342 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003343 close(gdbserver_state.fd);
3344 gdbserver_state.fd = -1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02003345 cpu_breakpoint_remove_all(cpu, BP_GDB);
Andreas Färber75a34032013-09-02 16:57:02 +02003346 cpu_watchpoint_remove_all(cpu, BP_GDB);
aurel322b1319c2008-12-18 22:44:04 +00003347}
pbrook4046d912007-01-28 01:53:16 +00003348#else
thsaa1f17c2007-07-11 22:48:58 +00003349static int gdb_chr_can_receive(void *opaque)
pbrook4046d912007-01-28 01:53:16 +00003350{
pbrook56aebc82008-10-11 17:55:29 +00003351 /* We can handle an arbitrarily large amount of data.
3352 Pick the maximum packet size, which is as good as anything. */
3353 return MAX_PACKET_LENGTH;
pbrook4046d912007-01-28 01:53:16 +00003354}
3355
thsaa1f17c2007-07-11 22:48:58 +00003356static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
pbrook4046d912007-01-28 01:53:16 +00003357{
pbrook4046d912007-01-28 01:53:16 +00003358 int i;
3359
3360 for (i = 0; i < size; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003361 gdb_read_byte(buf[i]);
pbrook4046d912007-01-28 01:53:16 +00003362 }
3363}
3364
Philippe Mathieu-Daudé083b2662019-12-18 18:20:09 +01003365static void gdb_chr_event(void *opaque, QEMUChrEvent event)
pbrook4046d912007-01-28 01:53:16 +00003366{
Luc Michel970ed902019-01-07 15:23:46 +00003367 int i;
3368 GDBState *s = (GDBState *) opaque;
3369
pbrook4046d912007-01-28 01:53:16 +00003370 switch (event) {
Amit Shahb6b8df52009-10-07 18:31:16 +05303371 case CHR_EVENT_OPENED:
Luc Michel970ed902019-01-07 15:23:46 +00003372 /* Start with first process attached, others detached */
3373 for (i = 0; i < s->process_num; i++) {
3374 s->processes[i].attached = !i;
3375 }
3376
Alex Bennéea346af32020-03-16 17:21:34 +00003377 s->c_cpu = gdb_first_attached_cpu();
Luc Michel970ed902019-01-07 15:23:46 +00003378 s->g_cpu = s->c_cpu;
3379
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003380 vm_stop(RUN_STATE_PAUSED);
Pavel Dovgalyuk56357d82020-10-03 20:14:01 +03003381 replay_gdb_attached();
Andreas Färber5b50e792013-06-29 04:18:45 +02003382 gdb_has_xml = false;
pbrook4046d912007-01-28 01:53:16 +00003383 break;
3384 default:
3385 break;
3386 }
3387}
3388
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003389static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
aliguori8a34a0f2009-03-05 23:01:55 +00003390{
Damien Hedded86b4672020-03-16 17:21:54 +00003391 g_autoptr(GString) hex_buf = g_string_new("O");
3392 memtohex(hex_buf, buf, len);
3393 put_packet(hex_buf->str);
aliguori8a34a0f2009-03-05 23:01:55 +00003394 return len;
3395}
3396
aliguori59030a82009-04-05 18:43:41 +00003397#ifndef _WIN32
3398static void gdb_sigterm_handler(int signal)
3399{
Luiz Capitulino13548692011-07-29 15:36:43 -03003400 if (runstate_is_running()) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003401 vm_stop(RUN_STATE_PAUSED);
Jan Kiszkae07bbac2011-02-09 16:29:40 +01003402 }
aliguori59030a82009-04-05 18:43:41 +00003403}
3404#endif
3405
Marc-André Lureau777357d2016-12-07 18:39:10 +03003406static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
3407 bool *be_opened, Error **errp)
3408{
3409 *be_opened = false;
3410}
3411
3412static void char_gdb_class_init(ObjectClass *oc, void *data)
3413{
3414 ChardevClass *cc = CHARDEV_CLASS(oc);
3415
3416 cc->internal = true;
3417 cc->open = gdb_monitor_open;
3418 cc->chr_write = gdb_monitor_write;
3419}
3420
3421#define TYPE_CHARDEV_GDB "chardev-gdb"
3422
3423static const TypeInfo char_gdb_type_info = {
3424 .name = TYPE_CHARDEV_GDB,
3425 .parent = TYPE_CHARDEV,
3426 .class_init = char_gdb_class_init,
3427};
3428
Luc Michel8f468632019-01-07 15:23:45 +00003429static int find_cpu_clusters(Object *child, void *opaque)
3430{
3431 if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
3432 GDBState *s = (GDBState *) opaque;
3433 CPUClusterState *cluster = CPU_CLUSTER(child);
3434 GDBProcess *process;
3435
3436 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3437
3438 process = &s->processes[s->process_num - 1];
3439
3440 /*
3441 * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
3442 * runtime, we enforce here that the machine does not use a cluster ID
3443 * that would lead to PID 0.
3444 */
3445 assert(cluster->cluster_id != UINT32_MAX);
3446 process->pid = cluster->cluster_id + 1;
3447 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003448 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003449
3450 return 0;
3451 }
3452
3453 return object_child_foreach(child, find_cpu_clusters, opaque);
3454}
3455
3456static int pid_order(const void *a, const void *b)
3457{
3458 GDBProcess *pa = (GDBProcess *) a;
3459 GDBProcess *pb = (GDBProcess *) b;
3460
3461 if (pa->pid < pb->pid) {
3462 return -1;
3463 } else if (pa->pid > pb->pid) {
3464 return 1;
3465 } else {
3466 return 0;
3467 }
3468}
3469
3470static void create_processes(GDBState *s)
3471{
3472 object_child_foreach(object_get_root(), find_cpu_clusters, s);
3473
Alex Bennéea346af32020-03-16 17:21:34 +00003474 if (gdbserver_state.processes) {
Luc Michel8f468632019-01-07 15:23:45 +00003475 /* Sort by PID */
Alex Bennéea346af32020-03-16 17:21:34 +00003476 qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
Luc Michel8f468632019-01-07 15:23:45 +00003477 }
3478
3479 create_default_process(s);
3480}
3481
aliguori59030a82009-04-05 18:43:41 +00003482int gdbserver_start(const char *device)
pbrook4046d912007-01-28 01:53:16 +00003483{
Doug Gale5c9522b2017-12-02 20:30:37 -05003484 trace_gdbstub_op_start(device);
3485
aliguori59030a82009-04-05 18:43:41 +00003486 char gdbstub_device_name[128];
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003487 Chardev *chr = NULL;
3488 Chardev *mon_chr;
pbrook4046d912007-01-28 01:53:16 +00003489
Ziyue Yang508b4ec2017-01-18 16:02:41 +08003490 if (!first_cpu) {
3491 error_report("gdbstub: meaningless to attach gdb to a "
3492 "machine without any CPU.");
3493 return -1;
3494 }
3495
aliguori59030a82009-04-05 18:43:41 +00003496 if (!device)
3497 return -1;
3498 if (strcmp(device, "none") != 0) {
3499 if (strstart(device, "tcp:", NULL)) {
3500 /* enforce required TCP attributes */
3501 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
Paolo Bonzinia9b13152021-02-25 11:47:52 +01003502 "%s,wait=off,nodelay=on,server=on", device);
aliguori59030a82009-04-05 18:43:41 +00003503 device = gdbstub_device_name;
aliguori36556b22009-03-28 18:05:53 +00003504 }
aliguori59030a82009-04-05 18:43:41 +00003505#ifndef _WIN32
3506 else if (strcmp(device, "stdio") == 0) {
3507 struct sigaction act;
pbrookcfc34752007-02-22 01:48:01 +00003508
aliguori59030a82009-04-05 18:43:41 +00003509 memset(&act, 0, sizeof(act));
3510 act.sa_handler = gdb_sigterm_handler;
3511 sigaction(SIGINT, &act, NULL);
3512 }
3513#endif
Marc-André Lureau95e30b22018-08-22 19:19:42 +02003514 /*
3515 * FIXME: it's a bit weird to allow using a mux chardev here
3516 * and implicitly setup a monitor. We may want to break this.
3517 */
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003518 chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
aliguori36556b22009-03-28 18:05:53 +00003519 if (!chr)
3520 return -1;
pbrookcfc34752007-02-22 01:48:01 +00003521 }
3522
Alex Bennée8d98c442020-03-16 17:21:33 +00003523 if (!gdbserver_state.init) {
3524 init_gdbserver_state();
pbrook4046d912007-01-28 01:53:16 +00003525
aliguori36556b22009-03-28 18:05:53 +00003526 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
3527
3528 /* Initialize a monitor terminal for gdb */
Marc-André Lureau777357d2016-12-07 18:39:10 +03003529 mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003530 NULL, NULL, &error_abort);
Kevin Wolf8e9119a2020-02-24 15:30:06 +01003531 monitor_init_hmp(mon_chr, false, &error_abort);
aliguori36556b22009-03-28 18:05:53 +00003532 } else {
Alex Bennée8d98c442020-03-16 17:21:33 +00003533 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
3534 mon_chr = gdbserver_state.mon_chr;
3535 reset_gdbserver_state();
aliguori36556b22009-03-28 18:05:53 +00003536 }
Luc Michel8f468632019-01-07 15:23:45 +00003537
Alex Bennée8d98c442020-03-16 17:21:33 +00003538 create_processes(&gdbserver_state);
Luc Michel8f468632019-01-07 15:23:45 +00003539
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003540 if (chr) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003541 qemu_chr_fe_init(&gdbserver_state.chr, chr, &error_abort);
3542 qemu_chr_fe_set_handlers(&gdbserver_state.chr, gdb_chr_can_receive,
3543 gdb_chr_receive, gdb_chr_event,
3544 NULL, &gdbserver_state, NULL, true);
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003545 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003546 gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
3547 gdbserver_state.mon_chr = mon_chr;
3548 gdbserver_state.current_syscall_cb = NULL;
aliguori8a34a0f2009-03-05 23:01:55 +00003549
pbrook4046d912007-01-28 01:53:16 +00003550 return 0;
3551}
Marc-André Lureau777357d2016-12-07 18:39:10 +03003552
3553static void register_types(void)
3554{
3555 type_register_static(&char_gdb_type_info);
3556}
3557
3558type_init(register_types);
pbrook4046d912007-01-28 01:53:16 +00003559#endif