blob: 84ce770a043543e6134cfbe566853f7691dbc081 [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
edgar_iglba70a622008-03-14 06:10:42 +0000468/* Resume execution. */
Alex Bennéea346af32020-03-16 17:21:34 +0000469static inline void gdb_continue(void)
edgar_iglba70a622008-03-14 06:10:42 +0000470{
Doug Gale5c9522b2017-12-02 20:30:37 -0500471
edgar_iglba70a622008-03-14 06:10:42 +0000472#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000473 gdbserver_state.running_state = 1;
Doug Gale5c9522b2017-12-02 20:30:37 -0500474 trace_gdbstub_op_continue();
edgar_iglba70a622008-03-14 06:10:42 +0000475#else
Paolo Bonzini26ac7a32013-06-03 17:06:54 +0200476 if (!runstate_needs_reset()) {
Doug Gale5c9522b2017-12-02 20:30:37 -0500477 trace_gdbstub_op_continue();
Paolo Bonzini87f25c12013-05-30 13:20:40 +0200478 vm_start();
479 }
edgar_iglba70a622008-03-14 06:10:42 +0000480#endif
481}
482
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100483/*
484 * Resume execution, per CPU actions. For user-mode emulation it's
485 * equivalent to gdb_continue.
486 */
Alex Bennéea346af32020-03-16 17:21:34 +0000487static int gdb_continue_partial(char *newstates)
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100488{
489 CPUState *cpu;
490 int res = 0;
491#ifdef CONFIG_USER_ONLY
492 /*
493 * This is not exactly accurate, but it's an improvement compared to the
494 * previous situation, where only one CPU would be single-stepped.
495 */
496 CPU_FOREACH(cpu) {
497 if (newstates[cpu->cpu_index] == 's') {
Doug Gale5c9522b2017-12-02 20:30:37 -0500498 trace_gdbstub_op_stepping(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100499 cpu_single_step(cpu, sstep_flags);
500 }
501 }
Alex Bennéea346af32020-03-16 17:21:34 +0000502 gdbserver_state.running_state = 1;
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100503#else
504 int flag = 0;
505
506 if (!runstate_needs_reset()) {
507 if (vm_prepare_start()) {
508 return 0;
509 }
510
511 CPU_FOREACH(cpu) {
512 switch (newstates[cpu->cpu_index]) {
513 case 0:
514 case 1:
515 break; /* nothing to do here */
516 case 's':
Doug Gale5c9522b2017-12-02 20:30:37 -0500517 trace_gdbstub_op_stepping(cpu->cpu_index);
Pavel Dovgalyukfda84582020-10-03 20:13:43 +0300518 cpu_single_step(cpu, get_sstep_flags());
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100519 cpu_resume(cpu);
520 flag = 1;
521 break;
522 case 'c':
Doug Gale5c9522b2017-12-02 20:30:37 -0500523 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100524 cpu_resume(cpu);
525 flag = 1;
526 break;
527 default:
528 res = -1;
529 break;
530 }
531 }
532 }
533 if (flag) {
534 qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
535 }
536#endif
537 return res;
538}
539
Alex Bennéea346af32020-03-16 17:21:34 +0000540static void put_buffer(const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000541{
pbrook4046d912007-01-28 01:53:16 +0000542#ifdef CONFIG_USER_ONLY
bellardb4608c02003-06-27 17:34:32 +0000543 int ret;
544
545 while (len > 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000546 ret = send(gdbserver_state.fd, buf, len, 0);
bellardb4608c02003-06-27 17:34:32 +0000547 if (ret < 0) {
Peter Wu5819e3e2016-06-05 16:35:48 +0200548 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000549 return;
550 } else {
551 buf += ret;
552 len -= ret;
553 }
554 }
pbrook4046d912007-01-28 01:53:16 +0000555#else
Daniel P. Berrange6ab3fc32016-09-06 14:56:04 +0100556 /* XXX this blocks entire thread. Rewrite to use
557 * qemu_chr_fe_write and background I/O callbacks */
Alex Bennéea346af32020-03-16 17:21:34 +0000558 qemu_chr_fe_write_all(&gdbserver_state.chr, buf, len);
pbrook4046d912007-01-28 01:53:16 +0000559#endif
bellardb4608c02003-06-27 17:34:32 +0000560}
561
562static inline int fromhex(int v)
563{
564 if (v >= '0' && v <= '9')
565 return v - '0';
566 else if (v >= 'A' && v <= 'F')
567 return v - 'A' + 10;
568 else if (v >= 'a' && v <= 'f')
569 return v - 'a' + 10;
570 else
571 return 0;
572}
573
574static inline int tohex(int v)
575{
576 if (v < 10)
577 return v + '0';
578 else
579 return v - 10 + 'a';
580}
581
Philippe Mathieu-Daudé90057742018-04-08 11:59:33 -0300582/* writes 2*len+1 bytes in buf */
Alex Bennée308f9e82020-03-16 17:21:35 +0000583static void memtohex(GString *buf, const uint8_t *mem, int len)
bellardb4608c02003-06-27 17:34:32 +0000584{
585 int i, c;
bellardb4608c02003-06-27 17:34:32 +0000586 for(i = 0; i < len; i++) {
587 c = mem[i];
Alex Bennée308f9e82020-03-16 17:21:35 +0000588 g_string_append_c(buf, tohex(c >> 4));
589 g_string_append_c(buf, tohex(c & 0xf));
bellardb4608c02003-06-27 17:34:32 +0000590 }
Alex Bennée308f9e82020-03-16 17:21:35 +0000591 g_string_append_c(buf, '\0');
bellardb4608c02003-06-27 17:34:32 +0000592}
593
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000594static void hextomem(GByteArray *mem, const char *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000595{
596 int i;
597
598 for(i = 0; i < len; i++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000599 guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
600 g_byte_array_append(mem, &byte, 1);
bellardb4608c02003-06-27 17:34:32 +0000601 buf += 2;
602 }
603}
604
Doug Gale5c9522b2017-12-02 20:30:37 -0500605static void hexdump(const char *buf, int len,
606 void (*trace_fn)(size_t ofs, char const *text))
607{
608 char line_buffer[3 * 16 + 4 + 16 + 1];
609
610 size_t i;
611 for (i = 0; i < len || (i & 0xF); ++i) {
612 size_t byte_ofs = i & 15;
613
614 if (byte_ofs == 0) {
615 memset(line_buffer, ' ', 3 * 16 + 4 + 16);
616 line_buffer[3 * 16 + 4 + 16] = 0;
617 }
618
619 size_t col_group = (i >> 2) & 3;
620 size_t hex_col = byte_ofs * 3 + col_group;
621 size_t txt_col = 3 * 16 + 4 + byte_ofs;
622
623 if (i < len) {
624 char value = buf[i];
625
626 line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
627 line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
628 line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
629 ? value
630 : '.';
631 }
632
633 if (byte_ofs == 0xF)
634 trace_fn(i & -16, line_buffer);
635 }
636}
637
bellardb4608c02003-06-27 17:34:32 +0000638/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000639static int put_packet_binary(const char *buf, int len, bool dump)
bellardb4608c02003-06-27 17:34:32 +0000640{
pbrook56aebc82008-10-11 17:55:29 +0000641 int csum, i;
Damien Hedded116e812020-03-16 17:21:53 +0000642 uint8_t footer[3];
bellardb4608c02003-06-27 17:34:32 +0000643
Doug Gale5c9522b2017-12-02 20:30:37 -0500644 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
645 hexdump(buf, len, trace_gdbstub_io_binaryreply);
646 }
647
bellardb4608c02003-06-27 17:34:32 +0000648 for(;;) {
Damien Hedded116e812020-03-16 17:21:53 +0000649 g_byte_array_set_size(gdbserver_state.last_packet, 0);
650 g_byte_array_append(gdbserver_state.last_packet,
651 (const uint8_t *) "$", 1);
652 g_byte_array_append(gdbserver_state.last_packet,
653 (const uint8_t *) buf, len);
bellardb4608c02003-06-27 17:34:32 +0000654 csum = 0;
655 for(i = 0; i < len; i++) {
656 csum += buf[i];
657 }
Damien Hedded116e812020-03-16 17:21:53 +0000658 footer[0] = '#';
659 footer[1] = tohex((csum >> 4) & 0xf);
660 footer[2] = tohex((csum) & 0xf);
661 g_byte_array_append(gdbserver_state.last_packet, footer, 3);
bellardb4608c02003-06-27 17:34:32 +0000662
Damien Hedded116e812020-03-16 17:21:53 +0000663 put_buffer(gdbserver_state.last_packet->data,
664 gdbserver_state.last_packet->len);
bellardb4608c02003-06-27 17:34:32 +0000665
pbrook4046d912007-01-28 01:53:16 +0000666#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000667 i = get_char();
pbrook4046d912007-01-28 01:53:16 +0000668 if (i < 0)
bellardb4608c02003-06-27 17:34:32 +0000669 return -1;
pbrook4046d912007-01-28 01:53:16 +0000670 if (i == '+')
bellardb4608c02003-06-27 17:34:32 +0000671 break;
pbrook4046d912007-01-28 01:53:16 +0000672#else
673 break;
674#endif
bellardb4608c02003-06-27 17:34:32 +0000675 }
676 return 0;
677}
678
pbrook56aebc82008-10-11 17:55:29 +0000679/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000680static int put_packet(const char *buf)
pbrook56aebc82008-10-11 17:55:29 +0000681{
Doug Gale5c9522b2017-12-02 20:30:37 -0500682 trace_gdbstub_io_reply(buf);
pbrook56aebc82008-10-11 17:55:29 +0000683
Alex Bennéea346af32020-03-16 17:21:34 +0000684 return put_packet_binary(buf, strlen(buf), false);
pbrook56aebc82008-10-11 17:55:29 +0000685}
686
Alex Bennée308f9e82020-03-16 17:21:35 +0000687static void put_strbuf(void)
pbrook56aebc82008-10-11 17:55:29 +0000688{
Alex Bennée308f9e82020-03-16 17:21:35 +0000689 put_packet(gdbserver_state.str_buf->str);
690}
691
692/* Encode data using the encoding for 'x' packets. */
693static void memtox(GString *buf, const char *mem, int len)
694{
pbrook56aebc82008-10-11 17:55:29 +0000695 char c;
696
697 while (len--) {
698 c = *(mem++);
699 switch (c) {
700 case '#': case '$': case '*': case '}':
Alex Bennée308f9e82020-03-16 17:21:35 +0000701 g_string_append_c(buf, '}');
702 g_string_append_c(buf, c ^ 0x20);
pbrook56aebc82008-10-11 17:55:29 +0000703 break;
704 default:
Alex Bennée308f9e82020-03-16 17:21:35 +0000705 g_string_append_c(buf, c);
pbrook56aebc82008-10-11 17:55:29 +0000706 break;
707 }
708 }
pbrook56aebc82008-10-11 17:55:29 +0000709}
710
Alex Bennéea346af32020-03-16 17:21:34 +0000711static uint32_t gdb_get_cpu_pid(CPUState *cpu)
Luc Michel1a227332019-01-07 15:23:45 +0000712{
Luc Michel1a227332019-01-07 15:23:45 +0000713 /* TODO: In user mode, we should use the task state PID */
Peter Maydell46f5abc2019-01-29 11:46:06 +0000714 if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
715 /* Return the default process' PID */
Alex Bennéea346af32020-03-16 17:21:34 +0000716 int index = gdbserver_state.process_num - 1;
717 return gdbserver_state.processes[index].pid;
Peter Maydell46f5abc2019-01-29 11:46:06 +0000718 }
719 return cpu->cluster_index + 1;
Luc Michel1a227332019-01-07 15:23:45 +0000720}
721
Alex Bennéea346af32020-03-16 17:21:34 +0000722static GDBProcess *gdb_get_process(uint32_t pid)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000723{
724 int i;
725
726 if (!pid) {
727 /* 0 means any process, we take the first one */
Alex Bennéea346af32020-03-16 17:21:34 +0000728 return &gdbserver_state.processes[0];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000729 }
730
Alex Bennéea346af32020-03-16 17:21:34 +0000731 for (i = 0; i < gdbserver_state.process_num; i++) {
732 if (gdbserver_state.processes[i].pid == pid) {
733 return &gdbserver_state.processes[i];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000734 }
735 }
736
737 return NULL;
738}
739
Alex Bennéea346af32020-03-16 17:21:34 +0000740static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000741{
Alex Bennéea346af32020-03-16 17:21:34 +0000742 return gdb_get_process(gdb_get_cpu_pid(cpu));
Luc Michel7d8c87d2019-01-07 15:23:45 +0000743}
744
745static CPUState *find_cpu(uint32_t thread_id)
746{
747 CPUState *cpu;
748
749 CPU_FOREACH(cpu) {
750 if (cpu_gdb_index(cpu) == thread_id) {
751 return cpu;
752 }
753 }
754
755 return NULL;
756}
757
Alex Bennéea346af32020-03-16 17:21:34 +0000758static CPUState *get_first_cpu_in_process(GDBProcess *process)
Luc Michele40e5202019-01-07 15:23:46 +0000759{
760 CPUState *cpu;
761
762 CPU_FOREACH(cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000763 if (gdb_get_cpu_pid(cpu) == process->pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000764 return cpu;
765 }
766 }
767
768 return NULL;
769}
770
Alex Bennéea346af32020-03-16 17:21:34 +0000771static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000772{
Alex Bennéea346af32020-03-16 17:21:34 +0000773 uint32_t pid = gdb_get_cpu_pid(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000774 cpu = CPU_NEXT(cpu);
775
776 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000777 if (gdb_get_cpu_pid(cpu) == pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000778 break;
779 }
780
781 cpu = CPU_NEXT(cpu);
782 }
783
784 return cpu;
785}
786
Luc Michele40e5202019-01-07 15:23:46 +0000787/* Return the cpu following @cpu, while ignoring unattached processes. */
Alex Bennéea346af32020-03-16 17:21:34 +0000788static CPUState *gdb_next_attached_cpu(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000789{
790 cpu = CPU_NEXT(cpu);
791
792 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000793 if (gdb_get_cpu_process(cpu)->attached) {
Luc Michele40e5202019-01-07 15:23:46 +0000794 break;
795 }
796
797 cpu = CPU_NEXT(cpu);
798 }
799
800 return cpu;
801}
802
803/* Return the first attached cpu */
Alex Bennéea346af32020-03-16 17:21:34 +0000804static CPUState *gdb_first_attached_cpu(void)
Luc Michele40e5202019-01-07 15:23:46 +0000805{
806 CPUState *cpu = first_cpu;
Alex Bennéea346af32020-03-16 17:21:34 +0000807 GDBProcess *process = gdb_get_cpu_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000808
809 if (!process->attached) {
Alex Bennéea346af32020-03-16 17:21:34 +0000810 return gdb_next_attached_cpu(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000811 }
812
813 return cpu;
814}
815
Alex Bennéea346af32020-03-16 17:21:34 +0000816static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
Luc Michelab65eed2019-01-29 11:46:03 +0000817{
818 GDBProcess *process;
819 CPUState *cpu;
820
821 if (!pid && !tid) {
822 /* 0 means any process/thread, we take the first attached one */
Alex Bennéea346af32020-03-16 17:21:34 +0000823 return gdb_first_attached_cpu();
Luc Michelab65eed2019-01-29 11:46:03 +0000824 } else if (pid && !tid) {
825 /* any thread in a specific process */
Alex Bennéea346af32020-03-16 17:21:34 +0000826 process = gdb_get_process(pid);
Luc Michelab65eed2019-01-29 11:46:03 +0000827
828 if (process == NULL) {
829 return NULL;
830 }
831
832 if (!process->attached) {
833 return NULL;
834 }
835
Alex Bennéea346af32020-03-16 17:21:34 +0000836 return get_first_cpu_in_process(process);
Luc Michelab65eed2019-01-29 11:46:03 +0000837 } else {
838 /* a specific thread */
839 cpu = find_cpu(tid);
840
841 if (cpu == NULL) {
842 return NULL;
843 }
844
Alex Bennéea346af32020-03-16 17:21:34 +0000845 process = gdb_get_cpu_process(cpu);
Luc Michelab65eed2019-01-29 11:46:03 +0000846
847 if (pid && process->pid != pid) {
848 return NULL;
849 }
850
851 if (!process->attached) {
852 return NULL;
853 }
854
855 return cpu;
856 }
857}
858
Alex Bennéea346af32020-03-16 17:21:34 +0000859static const char *get_feature_xml(const char *p, const char **newp,
860 GDBProcess *process)
pbrook56aebc82008-10-11 17:55:29 +0000861{
pbrook56aebc82008-10-11 17:55:29 +0000862 size_t len;
863 int i;
864 const char *name;
Alex Bennéea346af32020-03-16 17:21:34 +0000865 CPUState *cpu = get_first_cpu_in_process(process);
Luc Michelc145eea2019-01-07 15:23:46 +0000866 CPUClass *cc = CPU_GET_CLASS(cpu);
pbrook56aebc82008-10-11 17:55:29 +0000867
868 len = 0;
869 while (p[len] && p[len] != ':')
870 len++;
871 *newp = p + len;
872
873 name = NULL;
874 if (strncmp(p, "target.xml", len) == 0) {
Luc Michelc145eea2019-01-07 15:23:46 +0000875 char *buf = process->target_xml;
876 const size_t buf_sz = sizeof(process->target_xml);
pbrook56aebc82008-10-11 17:55:29 +0000877
Luc Michelc145eea2019-01-07 15:23:46 +0000878 /* Generate the XML description for this CPU. */
879 if (!buf[0]) {
880 GDBRegisterState *r;
881
882 pstrcat(buf, buf_sz,
David Hildenbrandb3820e62015-12-03 13:14:41 +0100883 "<?xml version=\"1.0\"?>"
884 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
885 "<target>");
886 if (cc->gdb_arch_name) {
887 gchar *arch = cc->gdb_arch_name(cpu);
Luc Michelc145eea2019-01-07 15:23:46 +0000888 pstrcat(buf, buf_sz, "<architecture>");
889 pstrcat(buf, buf_sz, arch);
890 pstrcat(buf, buf_sz, "</architecture>");
David Hildenbrandb3820e62015-12-03 13:14:41 +0100891 g_free(arch);
892 }
Luc Michelc145eea2019-01-07 15:23:46 +0000893 pstrcat(buf, buf_sz, "<xi:include href=\"");
894 pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
895 pstrcat(buf, buf_sz, "\"/>");
Andreas Färbereac8b352013-06-28 21:11:37 +0200896 for (r = cpu->gdb_regs; r; r = r->next) {
Luc Michelc145eea2019-01-07 15:23:46 +0000897 pstrcat(buf, buf_sz, "<xi:include href=\"");
898 pstrcat(buf, buf_sz, r->xml);
899 pstrcat(buf, buf_sz, "\"/>");
pbrook56aebc82008-10-11 17:55:29 +0000900 }
Luc Michelc145eea2019-01-07 15:23:46 +0000901 pstrcat(buf, buf_sz, "</target>");
pbrook56aebc82008-10-11 17:55:29 +0000902 }
Luc Michelc145eea2019-01-07 15:23:46 +0000903 return buf;
pbrook56aebc82008-10-11 17:55:29 +0000904 }
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100905 if (cc->gdb_get_dynamic_xml) {
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100906 char *xmlname = g_strndup(p, len);
907 const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
908
909 g_free(xmlname);
910 if (xml) {
911 return xml;
912 }
913 }
pbrook56aebc82008-10-11 17:55:29 +0000914 for (i = 0; ; i++) {
915 name = xml_builtin[i][0];
916 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
917 break;
918 }
919 return name ? xml_builtin[i][1] : NULL;
920}
pbrook56aebc82008-10-11 17:55:29 +0000921
Alex Bennéea010bdb2020-03-16 17:21:41 +0000922static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000923{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200924 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200925 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000926 GDBRegisterState *r;
927
Andreas Färbera0e372f2013-06-28 23:18:47 +0200928 if (reg < cc->gdb_num_core_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000929 return cc->gdb_read_register(cpu, buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200930 }
pbrook56aebc82008-10-11 17:55:29 +0000931
Andreas Färbereac8b352013-06-28 21:11:37 +0200932 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000933 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000934 return r->get_reg(env, buf, reg - r->base_reg);
pbrook56aebc82008-10-11 17:55:29 +0000935 }
936 }
937 return 0;
938}
939
Andreas Färber385b9f02013-06-27 18:25:36 +0200940static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000941{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200942 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200943 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000944 GDBRegisterState *r;
945
Andreas Färbera0e372f2013-06-28 23:18:47 +0200946 if (reg < cc->gdb_num_core_regs) {
Andreas Färber5b50e792013-06-29 04:18:45 +0200947 return cc->gdb_write_register(cpu, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200948 }
pbrook56aebc82008-10-11 17:55:29 +0000949
Andreas Färbereac8b352013-06-28 21:11:37 +0200950 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000951 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
952 return r->set_reg(env, mem_buf, reg - r->base_reg);
953 }
954 }
955 return 0;
956}
957
958/* Register a supplemental set of CPU registers. If g_pos is nonzero it
959 specifies the first register number and these registers are included in
960 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
961 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
962 */
963
Andreas Färber22169d42013-06-28 21:27:39 +0200964void gdb_register_coprocessor(CPUState *cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +0000965 gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
Andreas Färber22169d42013-06-28 21:27:39 +0200966 int num_regs, const char *xml, int g_pos)
pbrook56aebc82008-10-11 17:55:29 +0000967{
968 GDBRegisterState *s;
969 GDBRegisterState **p;
pbrook56aebc82008-10-11 17:55:29 +0000970
Andreas Färbereac8b352013-06-28 21:11:37 +0200971 p = &cpu->gdb_regs;
pbrook56aebc82008-10-11 17:55:29 +0000972 while (*p) {
973 /* Check for duplicates. */
974 if (strcmp((*p)->xml, xml) == 0)
975 return;
976 p = &(*p)->next;
977 }
Stefan Weil9643c252011-10-18 22:25:38 +0200978
979 s = g_new0(GDBRegisterState, 1);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200980 s->base_reg = cpu->gdb_num_regs;
Stefan Weil9643c252011-10-18 22:25:38 +0200981 s->num_regs = num_regs;
982 s->get_reg = get_reg;
983 s->set_reg = set_reg;
984 s->xml = xml;
985
pbrook56aebc82008-10-11 17:55:29 +0000986 /* Add to end of list. */
Andreas Färbera0e372f2013-06-28 23:18:47 +0200987 cpu->gdb_num_regs += num_regs;
pbrook56aebc82008-10-11 17:55:29 +0000988 *p = s;
989 if (g_pos) {
990 if (g_pos != s->base_reg) {
Ziyue Yang7ae6c572017-01-18 16:03:29 +0800991 error_report("Error: Bad gdb register numbering for '%s', "
992 "expected %d got %d", xml, g_pos, s->base_reg);
Andreas Färber35143f02013-08-12 18:09:47 +0200993 } else {
994 cpu->gdb_num_g_regs = cpu->gdb_num_regs;
pbrook56aebc82008-10-11 17:55:29 +0000995 }
996 }
997}
998
aliguoria1d1bb32008-11-18 20:07:32 +0000999#ifndef CONFIG_USER_ONLY
Peter Maydell2472b6c2014-09-12 19:04:17 +01001000/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
1001static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
1002{
1003 static const int xlat[] = {
1004 [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
1005 [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
1006 [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1007 };
1008
1009 CPUClass *cc = CPU_GET_CLASS(cpu);
1010 int cputype = xlat[gdbtype];
1011
1012 if (cc->gdb_stop_before_watchpoint) {
1013 cputype |= BP_STOP_BEFORE_ACCESS;
1014 }
1015 return cputype;
1016}
aliguoria1d1bb32008-11-18 20:07:32 +00001017#endif
1018
Jon Doron77f6ce52019-05-29 09:41:35 +03001019static int gdb_breakpoint_insert(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001020{
Andreas Färber182735e2013-05-29 22:29:20 +02001021 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001022 int err = 0;
1023
Andreas Färber62278812013-06-27 17:12:06 +02001024 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001025 return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001026 }
aliguorie22a25c2009-03-12 20:12:48 +00001027
aliguoria1d1bb32008-11-18 20:07:32 +00001028 switch (type) {
1029 case GDB_BREAKPOINT_SW:
1030 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001031 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001032 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
1033 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001034 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001035 }
aliguori880a7572008-11-18 20:30:24 +00001036 }
1037 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001038#ifndef CONFIG_USER_ONLY
1039 case GDB_WATCHPOINT_WRITE:
1040 case GDB_WATCHPOINT_READ:
1041 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001042 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001043 err = cpu_watchpoint_insert(cpu, addr, len,
1044 xlat_gdb_type(cpu, type), NULL);
1045 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001046 break;
Peter Maydell2472b6c2014-09-12 19:04:17 +01001047 }
aliguori880a7572008-11-18 20:30:24 +00001048 }
1049 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001050#endif
1051 default:
1052 return -ENOSYS;
1053 }
1054}
1055
Jon Doron77f6ce52019-05-29 09:41:35 +03001056static int gdb_breakpoint_remove(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001057{
Andreas Färber182735e2013-05-29 22:29:20 +02001058 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001059 int err = 0;
1060
Andreas Färber62278812013-06-27 17:12:06 +02001061 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001062 return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001063 }
aliguorie22a25c2009-03-12 20:12:48 +00001064
aliguoria1d1bb32008-11-18 20:07:32 +00001065 switch (type) {
1066 case GDB_BREAKPOINT_SW:
1067 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001068 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001069 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
1070 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001071 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001072 }
aliguori880a7572008-11-18 20:30:24 +00001073 }
1074 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001075#ifndef CONFIG_USER_ONLY
1076 case GDB_WATCHPOINT_WRITE:
1077 case GDB_WATCHPOINT_READ:
1078 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001079 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001080 err = cpu_watchpoint_remove(cpu, addr, len,
1081 xlat_gdb_type(cpu, type));
aliguori880a7572008-11-18 20:30:24 +00001082 if (err)
1083 break;
1084 }
1085 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001086#endif
1087 default:
1088 return -ENOSYS;
1089 }
1090}
1091
Luc Michel546f3c62019-01-07 15:23:46 +00001092static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
1093{
1094 cpu_breakpoint_remove_all(cpu, BP_GDB);
1095#ifndef CONFIG_USER_ONLY
1096 cpu_watchpoint_remove_all(cpu, BP_GDB);
1097#endif
1098}
1099
Alex Bennéea346af32020-03-16 17:21:34 +00001100static void gdb_process_breakpoint_remove_all(GDBProcess *p)
Luc Michel546f3c62019-01-07 15:23:46 +00001101{
Alex Bennéea346af32020-03-16 17:21:34 +00001102 CPUState *cpu = get_first_cpu_in_process(p);
Luc Michel546f3c62019-01-07 15:23:46 +00001103
1104 while (cpu) {
1105 gdb_cpu_breakpoint_remove_all(cpu);
Alex Bennéea346af32020-03-16 17:21:34 +00001106 cpu = gdb_next_cpu_in_process(cpu);
Luc Michel546f3c62019-01-07 15:23:46 +00001107 }
1108}
1109
aliguori880a7572008-11-18 20:30:24 +00001110static void gdb_breakpoint_remove_all(void)
aliguoria1d1bb32008-11-18 20:07:32 +00001111{
Andreas Färber182735e2013-05-29 22:29:20 +02001112 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001113
aliguorie22a25c2009-03-12 20:12:48 +00001114 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001115 kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
aliguorie22a25c2009-03-12 20:12:48 +00001116 return;
1117 }
1118
Andreas Färberbdc44642013-06-24 23:50:24 +02001119 CPU_FOREACH(cpu) {
Luc Michel546f3c62019-01-07 15:23:46 +00001120 gdb_cpu_breakpoint_remove_all(cpu);
aliguori880a7572008-11-18 20:30:24 +00001121 }
aliguoria1d1bb32008-11-18 20:07:32 +00001122}
1123
Alex Bennéea346af32020-03-16 17:21:34 +00001124static void gdb_set_cpu_pc(target_ulong pc)
aurel32fab9d282009-04-08 21:29:37 +00001125{
Alex Bennéea346af32020-03-16 17:21:34 +00001126 CPUState *cpu = gdbserver_state.c_cpu;
Andreas Färberf45748f2013-06-21 19:09:18 +02001127
1128 cpu_synchronize_state(cpu);
Peter Crosthwaite4a2b24e2015-06-23 20:19:21 -07001129 cpu_set_pc(cpu, pc);
aurel32fab9d282009-04-08 21:29:37 +00001130}
1131
Alex Bennée308f9e82020-03-16 17:21:35 +00001132static void gdb_append_thread_id(CPUState *cpu, GString *buf)
Luc Michel1a227332019-01-07 15:23:45 +00001133{
Alex Bennéea346af32020-03-16 17:21:34 +00001134 if (gdbserver_state.multiprocess) {
Alex Bennée308f9e82020-03-16 17:21:35 +00001135 g_string_append_printf(buf, "p%02x.%02x",
1136 gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001137 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00001138 g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001139 }
Luc Michel1a227332019-01-07 15:23:45 +00001140}
1141
Luc Michel7d8c87d2019-01-07 15:23:45 +00001142typedef enum GDBThreadIdKind {
1143 GDB_ONE_THREAD = 0,
1144 GDB_ALL_THREADS, /* One process, all threads */
1145 GDB_ALL_PROCESSES,
1146 GDB_READ_THREAD_ERR
1147} GDBThreadIdKind;
1148
1149static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
1150 uint32_t *pid, uint32_t *tid)
1151{
1152 unsigned long p, t;
1153 int ret;
1154
1155 if (*buf == 'p') {
1156 buf++;
1157 ret = qemu_strtoul(buf, &buf, 16, &p);
1158
1159 if (ret) {
1160 return GDB_READ_THREAD_ERR;
1161 }
1162
1163 /* Skip '.' */
1164 buf++;
1165 } else {
1166 p = 1;
1167 }
1168
1169 ret = qemu_strtoul(buf, &buf, 16, &t);
1170
1171 if (ret) {
1172 return GDB_READ_THREAD_ERR;
1173 }
1174
1175 *end_buf = buf;
1176
1177 if (p == -1) {
1178 return GDB_ALL_PROCESSES;
1179 }
1180
1181 if (pid) {
1182 *pid = p;
1183 }
1184
1185 if (t == -1) {
1186 return GDB_ALL_THREADS;
1187 }
1188
1189 if (tid) {
1190 *tid = t;
1191 }
1192
1193 return GDB_ONE_THREAD;
1194}
1195
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001196/**
1197 * gdb_handle_vcont - Parses and handles a vCont packet.
1198 * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1199 * a format error, 0 on success.
1200 */
Alex Bennéea346af32020-03-16 17:21:34 +00001201static int gdb_handle_vcont(const char *p)
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001202{
Luc Michele40e5202019-01-07 15:23:46 +00001203 int res, signal = 0;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001204 char cur_action;
1205 char *newstates;
1206 unsigned long tmp;
Luc Michele40e5202019-01-07 15:23:46 +00001207 uint32_t pid, tid;
1208 GDBProcess *process;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001209 CPUState *cpu;
Luc Michelc99ef792019-03-26 12:53:26 +00001210 GDBThreadIdKind kind;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001211#ifdef CONFIG_USER_ONLY
1212 int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1213
1214 CPU_FOREACH(cpu) {
1215 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1216 }
Like Xu5cc87672019-05-19 04:54:21 +08001217#else
1218 MachineState *ms = MACHINE(qdev_get_machine());
1219 unsigned int max_cpus = ms->smp.max_cpus;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001220#endif
1221 /* uninitialised CPUs stay 0 */
1222 newstates = g_new0(char, max_cpus);
1223
1224 /* mark valid CPUs with 1 */
1225 CPU_FOREACH(cpu) {
1226 newstates[cpu->cpu_index] = 1;
1227 }
1228
1229 /*
1230 * res keeps track of what error we are returning, with -ENOTSUP meaning
1231 * that the command is unknown or unsupported, thus returning an empty
1232 * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1233 * or incorrect parameters passed.
1234 */
1235 res = 0;
1236 while (*p) {
1237 if (*p++ != ';') {
1238 res = -ENOTSUP;
1239 goto out;
1240 }
1241
1242 cur_action = *p++;
1243 if (cur_action == 'C' || cur_action == 'S') {
Peter Maydell95a5bef2017-07-20 17:31:30 +01001244 cur_action = qemu_tolower(cur_action);
Peter Maydell3ddd9032020-11-21 21:03:42 +00001245 res = qemu_strtoul(p, &p, 16, &tmp);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001246 if (res) {
1247 goto out;
1248 }
1249 signal = gdb_signal_to_target(tmp);
1250 } else if (cur_action != 'c' && cur_action != 's') {
1251 /* unknown/invalid/unsupported command */
1252 res = -ENOTSUP;
1253 goto out;
1254 }
Luc Michele40e5202019-01-07 15:23:46 +00001255
Luc Michelc99ef792019-03-26 12:53:26 +00001256 if (*p == '\0' || *p == ';') {
1257 /*
1258 * No thread specifier, action is on "all threads". The
1259 * specification is unclear regarding the process to act on. We
1260 * choose all processes.
1261 */
1262 kind = GDB_ALL_PROCESSES;
1263 } else if (*p++ == ':') {
1264 kind = read_thread_id(p, &p, &pid, &tid);
1265 } else {
Luc Michele40e5202019-01-07 15:23:46 +00001266 res = -ENOTSUP;
1267 goto out;
1268 }
1269
Luc Michelc99ef792019-03-26 12:53:26 +00001270 switch (kind) {
Luc Michele40e5202019-01-07 15:23:46 +00001271 case GDB_READ_THREAD_ERR:
1272 res = -EINVAL;
1273 goto out;
1274
1275 case GDB_ALL_PROCESSES:
Alex Bennéea346af32020-03-16 17:21:34 +00001276 cpu = gdb_first_attached_cpu();
Luc Michele40e5202019-01-07 15:23:46 +00001277 while (cpu) {
1278 if (newstates[cpu->cpu_index] == 1) {
1279 newstates[cpu->cpu_index] = cur_action;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001280 }
Luc Michele40e5202019-01-07 15:23:46 +00001281
Alex Bennéea346af32020-03-16 17:21:34 +00001282 cpu = gdb_next_attached_cpu(cpu);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001283 }
Luc Michele40e5202019-01-07 15:23:46 +00001284 break;
1285
1286 case GDB_ALL_THREADS:
Alex Bennéea346af32020-03-16 17:21:34 +00001287 process = gdb_get_process(pid);
Luc Michele40e5202019-01-07 15:23:46 +00001288
1289 if (!process->attached) {
1290 res = -EINVAL;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001291 goto out;
1292 }
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001293
Alex Bennéea346af32020-03-16 17:21:34 +00001294 cpu = get_first_cpu_in_process(process);
Luc Michele40e5202019-01-07 15:23:46 +00001295 while (cpu) {
1296 if (newstates[cpu->cpu_index] == 1) {
1297 newstates[cpu->cpu_index] = cur_action;
1298 }
1299
Alex Bennéea346af32020-03-16 17:21:34 +00001300 cpu = gdb_next_cpu_in_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +00001301 }
1302 break;
1303
1304 case GDB_ONE_THREAD:
Alex Bennéea346af32020-03-16 17:21:34 +00001305 cpu = gdb_get_cpu(pid, tid);
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001306
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001307 /* invalid CPU/thread specified */
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001308 if (!cpu) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001309 res = -EINVAL;
1310 goto out;
1311 }
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001312
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001313 /* only use if no previous match occourred */
1314 if (newstates[cpu->cpu_index] == 1) {
1315 newstates[cpu->cpu_index] = cur_action;
1316 }
Luc Michele40e5202019-01-07 15:23:46 +00001317 break;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001318 }
1319 }
Alex Bennéea346af32020-03-16 17:21:34 +00001320 gdbserver_state.signal = signal;
1321 gdb_continue_partial(newstates);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001322
1323out:
1324 g_free(newstates);
1325
1326 return res;
1327}
1328
Jon Dorond14055d2019-05-29 09:41:29 +03001329typedef union GdbCmdVariant {
1330 const char *data;
1331 uint8_t opcode;
1332 unsigned long val_ul;
1333 unsigned long long val_ull;
1334 struct {
1335 GDBThreadIdKind kind;
1336 uint32_t pid;
1337 uint32_t tid;
1338 } thread_id;
1339} GdbCmdVariant;
1340
Alex Bennée26a16182021-05-25 09:24:14 +01001341#define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
1342
Jon Dorond14055d2019-05-29 09:41:29 +03001343static const char *cmd_next_param(const char *param, const char delimiter)
1344{
1345 static const char all_delimiters[] = ",;:=";
1346 char curr_delimiters[2] = {0};
1347 const char *delimiters;
1348
1349 if (delimiter == '?') {
1350 delimiters = all_delimiters;
1351 } else if (delimiter == '0') {
1352 return strchr(param, '\0');
1353 } else if (delimiter == '.' && *param) {
1354 return param + 1;
1355 } else {
1356 curr_delimiters[0] = delimiter;
1357 delimiters = curr_delimiters;
1358 }
1359
1360 param += strcspn(param, delimiters);
1361 if (*param) {
1362 param++;
1363 }
1364 return param;
1365}
1366
1367static int cmd_parse_params(const char *data, const char *schema,
Alex Bennée26a16182021-05-25 09:24:14 +01001368 GArray *params)
Jon Dorond14055d2019-05-29 09:41:29 +03001369{
Jon Dorond14055d2019-05-29 09:41:29 +03001370 const char *curr_schema, *curr_data;
1371
Alex Bennée26a16182021-05-25 09:24:14 +01001372 g_assert(schema);
1373 g_assert(params->len == 0);
Jon Dorond14055d2019-05-29 09:41:29 +03001374
1375 curr_schema = schema;
Jon Dorond14055d2019-05-29 09:41:29 +03001376 curr_data = data;
1377 while (curr_schema[0] && curr_schema[1] && *curr_data) {
Alex Bennée26a16182021-05-25 09:24:14 +01001378 GdbCmdVariant this_param;
1379
Jon Dorond14055d2019-05-29 09:41:29 +03001380 switch (curr_schema[0]) {
1381 case 'l':
1382 if (qemu_strtoul(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001383 &this_param.val_ul)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001384 return -EINVAL;
1385 }
Jon Dorond14055d2019-05-29 09:41:29 +03001386 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001387 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001388 break;
1389 case 'L':
1390 if (qemu_strtou64(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001391 (uint64_t *)&this_param.val_ull)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001392 return -EINVAL;
1393 }
Jon Dorond14055d2019-05-29 09:41:29 +03001394 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001395 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001396 break;
1397 case 's':
Alex Bennée26a16182021-05-25 09:24:14 +01001398 this_param.data = curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001399 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001400 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001401 break;
1402 case 'o':
Alex Bennée26a16182021-05-25 09:24:14 +01001403 this_param.opcode = *(uint8_t *)curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001404 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001405 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001406 break;
1407 case 't':
Alex Bennée26a16182021-05-25 09:24:14 +01001408 this_param.thread_id.kind =
Jon Dorond14055d2019-05-29 09:41:29 +03001409 read_thread_id(curr_data, &curr_data,
Alex Bennée26a16182021-05-25 09:24:14 +01001410 &this_param.thread_id.pid,
1411 &this_param.thread_id.tid);
Jon Dorond14055d2019-05-29 09:41:29 +03001412 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001413 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001414 break;
1415 case '?':
1416 curr_data = cmd_next_param(curr_data, curr_schema[1]);
1417 break;
1418 default:
1419 return -EINVAL;
1420 }
1421 curr_schema += 2;
1422 }
1423
Jon Dorond14055d2019-05-29 09:41:29 +03001424 return 0;
1425}
1426
Alex Bennée26a16182021-05-25 09:24:14 +01001427typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001428
1429/*
1430 * cmd_startswith -> cmd is compared using startswith
1431 *
1432 *
1433 * schema definitions:
1434 * Each schema parameter entry consists of 2 chars,
1435 * the first char represents the parameter type handling
1436 * the second char represents the delimiter for the next parameter
1437 *
1438 * Currently supported schema types:
1439 * 'l' -> unsigned long (stored in .val_ul)
1440 * 'L' -> unsigned long long (stored in .val_ull)
1441 * 's' -> string (stored in .data)
1442 * 'o' -> single char (stored in .opcode)
1443 * 't' -> thread id (stored in .thread_id)
1444 * '?' -> skip according to delimiter
1445 *
1446 * Currently supported delimiters:
1447 * '?' -> Stop at any delimiter (",;:=\0")
1448 * '0' -> Stop at "\0"
1449 * '.' -> Skip 1 char unless reached "\0"
1450 * Any other value is treated as the delimiter value itself
1451 */
1452typedef struct GdbCmdParseEntry {
1453 GdbCmdHandler handler;
1454 const char *cmd;
1455 bool cmd_startswith;
1456 const char *schema;
1457} GdbCmdParseEntry;
1458
1459static inline int startswith(const char *string, const char *pattern)
1460{
1461 return !strncmp(string, pattern, strlen(pattern));
1462}
1463
Alex Bennéea346af32020-03-16 17:21:34 +00001464static int process_string_cmd(void *user_ctx, const char *data,
Jon Dorond14055d2019-05-29 09:41:29 +03001465 const GdbCmdParseEntry *cmds, int num_cmds)
1466{
Alex Bennée26a16182021-05-25 09:24:14 +01001467 int i;
1468 g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
Jon Dorond14055d2019-05-29 09:41:29 +03001469
1470 if (!cmds) {
1471 return -1;
1472 }
1473
1474 for (i = 0; i < num_cmds; i++) {
1475 const GdbCmdParseEntry *cmd = &cmds[i];
1476 g_assert(cmd->handler && cmd->cmd);
1477
1478 if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1479 (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1480 continue;
1481 }
1482
1483 if (cmd->schema) {
Alex Bennée26a16182021-05-25 09:24:14 +01001484 if (cmd_parse_params(&data[strlen(cmd->cmd)],
1485 cmd->schema, params)) {
1486 return -1;
Jon Dorond14055d2019-05-29 09:41:29 +03001487 }
Jon Dorond14055d2019-05-29 09:41:29 +03001488 }
1489
Alex Bennée26a16182021-05-25 09:24:14 +01001490 cmd->handler(params, user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001491 return 0;
1492 }
1493
1494 return -1;
1495}
1496
Alex Bennéea346af32020-03-16 17:21:34 +00001497static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
Jon Doron3e2c1262019-05-29 09:41:30 +03001498{
1499 if (!data) {
1500 return;
1501 }
1502
Alex Bennée308f9e82020-03-16 17:21:35 +00001503 g_string_set_size(gdbserver_state.str_buf, 0);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001504 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Alex Bennée308f9e82020-03-16 17:21:35 +00001505
Jon Doron3e2c1262019-05-29 09:41:30 +03001506 /* In case there was an error during the command parsing we must
1507 * send a NULL packet to indicate the command is not supported */
Alex Bennéea346af32020-03-16 17:21:34 +00001508 if (process_string_cmd(NULL, data, cmd, 1)) {
1509 put_packet("");
Jon Doron3e2c1262019-05-29 09:41:30 +03001510 }
1511}
1512
Alex Bennée26a16182021-05-25 09:24:14 +01001513static void handle_detach(GArray *params, void *user_ctx)
Jon Doron3e2c1262019-05-29 09:41:30 +03001514{
1515 GDBProcess *process;
Jon Doron3e2c1262019-05-29 09:41:30 +03001516 uint32_t pid = 1;
1517
Alex Bennéea346af32020-03-16 17:21:34 +00001518 if (gdbserver_state.multiprocess) {
Alex Bennée26a16182021-05-25 09:24:14 +01001519 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001520 put_packet("E22");
Jon Doron3e2c1262019-05-29 09:41:30 +03001521 return;
1522 }
1523
Alex Bennée26a16182021-05-25 09:24:14 +01001524 pid = get_param(params, 0)->val_ul;
Jon Doron3e2c1262019-05-29 09:41:30 +03001525 }
1526
Alex Bennéea346af32020-03-16 17:21:34 +00001527 process = gdb_get_process(pid);
1528 gdb_process_breakpoint_remove_all(process);
Jon Doron3e2c1262019-05-29 09:41:30 +03001529 process->attached = false;
1530
Alex Bennéea346af32020-03-16 17:21:34 +00001531 if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1532 gdbserver_state.c_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001533 }
1534
Alex Bennéea346af32020-03-16 17:21:34 +00001535 if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1536 gdbserver_state.g_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001537 }
1538
Alex Bennéea346af32020-03-16 17:21:34 +00001539 if (!gdbserver_state.c_cpu) {
Jon Doron3e2c1262019-05-29 09:41:30 +03001540 /* No more process attached */
1541 gdb_syscall_mode = GDB_SYS_DISABLED;
Alex Bennéea346af32020-03-16 17:21:34 +00001542 gdb_continue();
Jon Doron3e2c1262019-05-29 09:41:30 +03001543 }
Alex Bennéea346af32020-03-16 17:21:34 +00001544 put_packet("OK");
Jon Doron3e2c1262019-05-29 09:41:30 +03001545}
1546
Alex Bennée26a16182021-05-25 09:24:14 +01001547static void handle_thread_alive(GArray *params, void *user_ctx)
Jon Doron44ffded2019-05-29 09:41:31 +03001548{
1549 CPUState *cpu;
1550
Alex Bennée26a16182021-05-25 09:24:14 +01001551 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001552 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001553 return;
1554 }
1555
Alex Bennée26a16182021-05-25 09:24:14 +01001556 if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001557 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001558 return;
1559 }
1560
Alex Bennée26a16182021-05-25 09:24:14 +01001561 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1562 get_param(params, 0)->thread_id.tid);
Jon Doron44ffded2019-05-29 09:41:31 +03001563 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001564 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001565 return;
1566 }
1567
Alex Bennéea346af32020-03-16 17:21:34 +00001568 put_packet("OK");
Jon Doron44ffded2019-05-29 09:41:31 +03001569}
1570
Alex Bennée26a16182021-05-25 09:24:14 +01001571static void handle_continue(GArray *params, void *user_ctx)
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001572{
Alex Bennée26a16182021-05-25 09:24:14 +01001573 if (params->len) {
1574 gdb_set_cpu_pc(get_param(params, 0)->val_ull);
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001575 }
1576
Alex Bennéea346af32020-03-16 17:21:34 +00001577 gdbserver_state.signal = 0;
1578 gdb_continue();
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001579}
1580
Alex Bennée26a16182021-05-25 09:24:14 +01001581static void handle_cont_with_sig(GArray *params, void *user_ctx)
Jon Doronccc47d52019-05-29 09:41:33 +03001582{
1583 unsigned long signal = 0;
1584
1585 /*
1586 * Note: C sig;[addr] is currently unsupported and we simply
1587 * omit the addr parameter
1588 */
Alex Bennée26a16182021-05-25 09:24:14 +01001589 if (params->len) {
1590 signal = get_param(params, 0)->val_ul;
Jon Doronccc47d52019-05-29 09:41:33 +03001591 }
1592
Alex Bennéea346af32020-03-16 17:21:34 +00001593 gdbserver_state.signal = gdb_signal_to_target(signal);
1594 if (gdbserver_state.signal == -1) {
1595 gdbserver_state.signal = 0;
Jon Doronccc47d52019-05-29 09:41:33 +03001596 }
Alex Bennéea346af32020-03-16 17:21:34 +00001597 gdb_continue();
Jon Doronccc47d52019-05-29 09:41:33 +03001598}
1599
Alex Bennée26a16182021-05-25 09:24:14 +01001600static void handle_set_thread(GArray *params, void *user_ctx)
Jon Doron3a9651d2019-05-29 09:41:34 +03001601{
1602 CPUState *cpu;
1603
Alex Bennée26a16182021-05-25 09:24:14 +01001604 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001605 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001606 return;
1607 }
1608
Alex Bennée26a16182021-05-25 09:24:14 +01001609 if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001610 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001611 return;
1612 }
1613
Alex Bennée26a16182021-05-25 09:24:14 +01001614 if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
Alex Bennéea346af32020-03-16 17:21:34 +00001615 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001616 return;
1617 }
1618
Alex Bennée26a16182021-05-25 09:24:14 +01001619 cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1620 get_param(params, 1)->thread_id.tid);
Jon Doron3a9651d2019-05-29 09:41:34 +03001621 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001622 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001623 return;
1624 }
1625
1626 /*
1627 * Note: This command is deprecated and modern gdb's will be using the
1628 * vCont command instead.
1629 */
Alex Bennée26a16182021-05-25 09:24:14 +01001630 switch (get_param(params, 0)->opcode) {
Jon Doron3a9651d2019-05-29 09:41:34 +03001631 case 'c':
Alex Bennéea346af32020-03-16 17:21:34 +00001632 gdbserver_state.c_cpu = cpu;
1633 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001634 break;
1635 case 'g':
Alex Bennéea346af32020-03-16 17:21:34 +00001636 gdbserver_state.g_cpu = cpu;
1637 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001638 break;
1639 default:
Alex Bennéea346af32020-03-16 17:21:34 +00001640 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001641 break;
1642 }
1643}
1644
Alex Bennée26a16182021-05-25 09:24:14 +01001645static void handle_insert_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001646{
1647 int res;
1648
Alex Bennée26a16182021-05-25 09:24:14 +01001649 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001650 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001651 return;
1652 }
1653
Alex Bennée26a16182021-05-25 09:24:14 +01001654 res = gdb_breakpoint_insert(get_param(params, 0)->val_ul,
1655 get_param(params, 1)->val_ull,
1656 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001657 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001658 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001659 return;
1660 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001661 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001662 return;
1663 }
1664
Alex Bennéea346af32020-03-16 17:21:34 +00001665 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001666}
1667
Alex Bennée26a16182021-05-25 09:24:14 +01001668static void handle_remove_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001669{
1670 int res;
1671
Alex Bennée26a16182021-05-25 09:24:14 +01001672 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001673 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001674 return;
1675 }
1676
Alex Bennée26a16182021-05-25 09:24:14 +01001677 res = gdb_breakpoint_remove(get_param(params, 0)->val_ul,
1678 get_param(params, 1)->val_ull,
1679 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001680 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001681 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001682 return;
1683 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001684 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001685 return;
1686 }
1687
Alex Bennéea346af32020-03-16 17:21:34 +00001688 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001689}
1690
Alex Bennée94b2a622019-07-05 14:23:07 +01001691/*
1692 * handle_set/get_reg
1693 *
1694 * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1695 * This works, but can be very slow. Anything new enough to understand
1696 * XML also knows how to use this properly. However to use this we
1697 * need to define a local XML file as well as be talking to a
1698 * reasonably modern gdb. Responding with an empty packet will cause
1699 * the remote gdb to fallback to older methods.
1700 */
1701
Alex Bennée26a16182021-05-25 09:24:14 +01001702static void handle_set_reg(GArray *params, void *user_ctx)
Jon Doron62b33202019-05-29 09:41:36 +03001703{
1704 int reg_size;
1705
1706 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001707 put_packet("");
Jon Doron62b33202019-05-29 09:41:36 +03001708 return;
1709 }
1710
Alex Bennée26a16182021-05-25 09:24:14 +01001711 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001712 put_packet("E22");
Jon Doron62b33202019-05-29 09:41:36 +03001713 return;
1714 }
1715
Alex Bennée26a16182021-05-25 09:24:14 +01001716 reg_size = strlen(get_param(params, 1)->data) / 2;
1717 hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001718 gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
Alex Bennée26a16182021-05-25 09:24:14 +01001719 get_param(params, 0)->val_ull);
Alex Bennéea346af32020-03-16 17:21:34 +00001720 put_packet("OK");
Jon Doron62b33202019-05-29 09:41:36 +03001721}
1722
Alex Bennée26a16182021-05-25 09:24:14 +01001723static void handle_get_reg(GArray *params, void *user_ctx)
Jon Doron5d0e57b2019-05-29 09:41:37 +03001724{
1725 int reg_size;
1726
Jon Doron5d0e57b2019-05-29 09:41:37 +03001727 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001728 put_packet("");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001729 return;
1730 }
1731
Alex Bennée26a16182021-05-25 09:24:14 +01001732 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001733 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001734 return;
1735 }
1736
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001737 reg_size = gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001738 gdbserver_state.mem_buf,
Alex Bennée26a16182021-05-25 09:24:14 +01001739 get_param(params, 0)->val_ull);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001740 if (!reg_size) {
Alex Bennéea346af32020-03-16 17:21:34 +00001741 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001742 return;
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001743 } else {
1744 g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001745 }
1746
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001747 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
Alex Bennée308f9e82020-03-16 17:21:35 +00001748 put_strbuf();
Jon Doron5d0e57b2019-05-29 09:41:37 +03001749}
1750
Alex Bennée26a16182021-05-25 09:24:14 +01001751static void handle_write_mem(GArray *params, void *user_ctx)
Jon Doroncc0ecc72019-05-29 09:41:38 +03001752{
Alex Bennée26a16182021-05-25 09:24:14 +01001753 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001754 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001755 return;
1756 }
1757
1758 /* hextomem() reads 2*len bytes */
Alex Bennée26a16182021-05-25 09:24:14 +01001759 if (get_param(params, 1)->val_ull >
1760 strlen(get_param(params, 2)->data) / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001761 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001762 return;
1763 }
1764
Alex Bennée26a16182021-05-25 09:24:14 +01001765 hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1766 get_param(params, 1)->val_ull);
1767 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1768 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001769 gdbserver_state.mem_buf->data,
1770 gdbserver_state.mem_buf->len, true)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001771 put_packet("E14");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001772 return;
1773 }
1774
Alex Bennéea346af32020-03-16 17:21:34 +00001775 put_packet("OK");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001776}
1777
Alex Bennée26a16182021-05-25 09:24:14 +01001778static void handle_read_mem(GArray *params, void *user_ctx)
Jon Doronda92e232019-05-29 09:41:39 +03001779{
Alex Bennée26a16182021-05-25 09:24:14 +01001780 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001781 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001782 return;
1783 }
1784
1785 /* memtohex() doubles the required space */
Alex Bennée26a16182021-05-25 09:24:14 +01001786 if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001787 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001788 return;
1789 }
1790
Alex Bennée26a16182021-05-25 09:24:14 +01001791 g_byte_array_set_size(gdbserver_state.mem_buf,
1792 get_param(params, 1)->val_ull);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001793
Alex Bennée26a16182021-05-25 09:24:14 +01001794 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1795 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001796 gdbserver_state.mem_buf->data,
1797 gdbserver_state.mem_buf->len, false)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001798 put_packet("E14");
Jon Doronda92e232019-05-29 09:41:39 +03001799 return;
1800 }
1801
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001802 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1803 gdbserver_state.mem_buf->len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001804 put_strbuf();
Jon Doronda92e232019-05-29 09:41:39 +03001805}
1806
Alex Bennée26a16182021-05-25 09:24:14 +01001807static void handle_write_all_regs(GArray *params, void *user_ctx)
Jon Doron287ca122019-05-29 09:41:40 +03001808{
1809 target_ulong addr, len;
1810 uint8_t *registers;
1811 int reg_size;
1812
Alex Bennée26a16182021-05-25 09:24:14 +01001813 if (!params->len) {
Jon Doron287ca122019-05-29 09:41:40 +03001814 return;
1815 }
1816
Alex Bennéea346af32020-03-16 17:21:34 +00001817 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennée26a16182021-05-25 09:24:14 +01001818 len = strlen(get_param(params, 0)->data) / 2;
1819 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001820 registers = gdbserver_state.mem_buf->data;
Alex Bennéea346af32020-03-16 17:21:34 +00001821 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
Jon Doron287ca122019-05-29 09:41:40 +03001822 addr++) {
Alex Bennéea346af32020-03-16 17:21:34 +00001823 reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
Jon Doron287ca122019-05-29 09:41:40 +03001824 len -= reg_size;
1825 registers += reg_size;
1826 }
Alex Bennéea346af32020-03-16 17:21:34 +00001827 put_packet("OK");
Jon Doron287ca122019-05-29 09:41:40 +03001828}
1829
Alex Bennée26a16182021-05-25 09:24:14 +01001830static void handle_read_all_regs(GArray *params, void *user_ctx)
Jon Doron397d1372019-05-29 09:41:41 +03001831{
1832 target_ulong addr, len;
1833
Alex Bennéea346af32020-03-16 17:21:34 +00001834 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennéea010bdb2020-03-16 17:21:41 +00001835 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Jon Doron397d1372019-05-29 09:41:41 +03001836 len = 0;
Alex Bennéea346af32020-03-16 17:21:34 +00001837 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001838 len += gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001839 gdbserver_state.mem_buf,
Jon Doron397d1372019-05-29 09:41:41 +03001840 addr);
1841 }
Alex Bennéea010bdb2020-03-16 17:21:41 +00001842 g_assert(len == gdbserver_state.mem_buf->len);
Jon Doron397d1372019-05-29 09:41:41 +03001843
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001844 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001845 put_strbuf();
Jon Doron397d1372019-05-29 09:41:41 +03001846}
1847
Alex Bennée26a16182021-05-25 09:24:14 +01001848static void handle_file_io(GArray *params, void *user_ctx)
Jon Doron4b20fab2019-05-29 09:41:42 +03001849{
Alex Bennée26a16182021-05-25 09:24:14 +01001850 if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
Jon Doron4b20fab2019-05-29 09:41:42 +03001851 target_ulong ret, err;
1852
Alex Bennée26a16182021-05-25 09:24:14 +01001853 ret = (target_ulong)get_param(params, 0)->val_ull;
1854 if (params->len >= 2) {
1855 err = (target_ulong)get_param(params, 1)->val_ull;
Sandra Loosemorec6ee9522019-08-27 16:33:17 -06001856 } else {
1857 err = 0;
1858 }
Alex Bennéea346af32020-03-16 17:21:34 +00001859 gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1860 gdbserver_state.current_syscall_cb = NULL;
Jon Doron4b20fab2019-05-29 09:41:42 +03001861 }
1862
Alex Bennée26a16182021-05-25 09:24:14 +01001863 if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
Alex Bennéea346af32020-03-16 17:21:34 +00001864 put_packet("T02");
Jon Doron4b20fab2019-05-29 09:41:42 +03001865 return;
1866 }
1867
Alex Bennéea346af32020-03-16 17:21:34 +00001868 gdb_continue();
Jon Doron4b20fab2019-05-29 09:41:42 +03001869}
1870
Alex Bennée26a16182021-05-25 09:24:14 +01001871static void handle_step(GArray *params, void *user_ctx)
Jon Doron933f80d2019-05-29 09:41:43 +03001872{
Alex Bennée26a16182021-05-25 09:24:14 +01001873 if (params->len) {
1874 gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
Jon Doron933f80d2019-05-29 09:41:43 +03001875 }
1876
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001877 cpu_single_step(gdbserver_state.c_cpu, get_sstep_flags());
Alex Bennéea346af32020-03-16 17:21:34 +00001878 gdb_continue();
Jon Doron933f80d2019-05-29 09:41:43 +03001879}
1880
Alex Bennée26a16182021-05-25 09:24:14 +01001881static void handle_backward(GArray *params, void *user_ctx)
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001882{
1883 if (replay_mode != REPLAY_MODE_PLAY) {
1884 put_packet("E22");
1885 }
Alex Bennée26a16182021-05-25 09:24:14 +01001886 if (params->len == 1) {
1887 switch (get_param(params, 0)->opcode) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001888 case 's':
1889 if (replay_reverse_step()) {
1890 gdb_continue();
1891 } else {
1892 put_packet("E14");
1893 }
1894 return;
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03001895 case 'c':
1896 if (replay_reverse_continue()) {
1897 gdb_continue();
1898 } else {
1899 put_packet("E14");
1900 }
1901 return;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001902 }
1903 }
1904
1905 /* Default invalid command */
1906 put_packet("");
1907}
1908
Alex Bennée26a16182021-05-25 09:24:14 +01001909static void handle_v_cont_query(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001910{
Alex Bennéea346af32020-03-16 17:21:34 +00001911 put_packet("vCont;c;C;s;S");
Jon Doron8536ec02019-05-29 09:41:44 +03001912}
1913
Alex Bennée26a16182021-05-25 09:24:14 +01001914static void handle_v_cont(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001915{
1916 int res;
1917
Alex Bennée26a16182021-05-25 09:24:14 +01001918 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001919 return;
1920 }
1921
Alex Bennée26a16182021-05-25 09:24:14 +01001922 res = gdb_handle_vcont(get_param(params, 0)->data);
Jon Doron8536ec02019-05-29 09:41:44 +03001923 if ((res == -EINVAL) || (res == -ERANGE)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001924 put_packet("E22");
Jon Doron8536ec02019-05-29 09:41:44 +03001925 } else if (res) {
Alex Bennéea346af32020-03-16 17:21:34 +00001926 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03001927 }
1928}
1929
Alex Bennée26a16182021-05-25 09:24:14 +01001930static void handle_v_attach(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001931{
1932 GDBProcess *process;
1933 CPUState *cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001934
Alex Bennée308f9e82020-03-16 17:21:35 +00001935 g_string_assign(gdbserver_state.str_buf, "E22");
Alex Bennée26a16182021-05-25 09:24:14 +01001936 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001937 goto cleanup;
1938 }
1939
Alex Bennée26a16182021-05-25 09:24:14 +01001940 process = gdb_get_process(get_param(params, 0)->val_ul);
Jon Doron8536ec02019-05-29 09:41:44 +03001941 if (!process) {
1942 goto cleanup;
1943 }
1944
Alex Bennéea346af32020-03-16 17:21:34 +00001945 cpu = get_first_cpu_in_process(process);
Jon Doron8536ec02019-05-29 09:41:44 +03001946 if (!cpu) {
1947 goto cleanup;
1948 }
1949
1950 process->attached = true;
Alex Bennéea346af32020-03-16 17:21:34 +00001951 gdbserver_state.g_cpu = cpu;
1952 gdbserver_state.c_cpu = cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001953
Alex Bennée308f9e82020-03-16 17:21:35 +00001954 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
1955 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
1956 g_string_append_c(gdbserver_state.str_buf, ';');
Jon Doron8536ec02019-05-29 09:41:44 +03001957cleanup:
Alex Bennée308f9e82020-03-16 17:21:35 +00001958 put_strbuf();
Jon Doron8536ec02019-05-29 09:41:44 +03001959}
1960
Alex Bennée26a16182021-05-25 09:24:14 +01001961static void handle_v_kill(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001962{
1963 /* Kill the target */
Alex Bennéea346af32020-03-16 17:21:34 +00001964 put_packet("OK");
Jon Doron8536ec02019-05-29 09:41:44 +03001965 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00001966 gdb_exit(0);
Jon Doron8536ec02019-05-29 09:41:44 +03001967 exit(0);
1968}
1969
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01001970static const GdbCmdParseEntry gdb_v_commands_table[] = {
Jon Doron8536ec02019-05-29 09:41:44 +03001971 /* Order is important if has same prefix */
1972 {
1973 .handler = handle_v_cont_query,
1974 .cmd = "Cont?",
1975 .cmd_startswith = 1
1976 },
1977 {
1978 .handler = handle_v_cont,
1979 .cmd = "Cont",
1980 .cmd_startswith = 1,
1981 .schema = "s0"
1982 },
1983 {
1984 .handler = handle_v_attach,
1985 .cmd = "Attach;",
1986 .cmd_startswith = 1,
1987 .schema = "l0"
1988 },
1989 {
1990 .handler = handle_v_kill,
1991 .cmd = "Kill;",
1992 .cmd_startswith = 1
1993 },
1994};
1995
Alex Bennée26a16182021-05-25 09:24:14 +01001996static void handle_v_commands(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001997{
Alex Bennée26a16182021-05-25 09:24:14 +01001998 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001999 return;
2000 }
2001
Alex Bennée26a16182021-05-25 09:24:14 +01002002 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron8536ec02019-05-29 09:41:44 +03002003 gdb_v_commands_table,
2004 ARRAY_SIZE(gdb_v_commands_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002005 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03002006 }
2007}
2008
Alex Bennée26a16182021-05-25 09:24:14 +01002009static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002010{
Alex Bennée308f9e82020-03-16 17:21:35 +00002011 g_string_printf(gdbserver_state.str_buf, "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
2012 SSTEP_ENABLE, SSTEP_NOIRQ, SSTEP_NOTIMER);
2013 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002014}
2015
Alex Bennée26a16182021-05-25 09:24:14 +01002016static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002017{
Alex Bennée26a16182021-05-25 09:24:14 +01002018 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002019 return;
2020 }
2021
Alex Bennée26a16182021-05-25 09:24:14 +01002022 sstep_flags = get_param(params, 0)->val_ul;
Alex Bennéea346af32020-03-16 17:21:34 +00002023 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002024}
2025
Alex Bennée26a16182021-05-25 09:24:14 +01002026static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002027{
Alex Bennée308f9e82020-03-16 17:21:35 +00002028 g_string_printf(gdbserver_state.str_buf, "0x%x", sstep_flags);
2029 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002030}
2031
Alex Bennée26a16182021-05-25 09:24:14 +01002032static void handle_query_curr_tid(GArray *params, void *user_ctx)
bellardb4608c02003-06-27 17:34:32 +00002033{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002034 CPUState *cpu;
Luc Michelc145eea2019-01-07 15:23:46 +00002035 GDBProcess *process;
Jon Doron2704efa2019-05-29 09:41:45 +03002036
2037 /*
2038 * "Current thread" remains vague in the spec, so always return
2039 * the first thread of the current process (gdb returns the
2040 * first thread).
2041 */
Alex Bennéea346af32020-03-16 17:21:34 +00002042 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2043 cpu = get_first_cpu_in_process(process);
Alex Bennée308f9e82020-03-16 17:21:35 +00002044 g_string_assign(gdbserver_state.str_buf, "QC");
2045 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2046 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002047}
2048
Alex Bennée26a16182021-05-25 09:24:14 +01002049static void handle_query_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002050{
Alex Bennéea346af32020-03-16 17:21:34 +00002051 if (!gdbserver_state.query_cpu) {
2052 put_packet("l");
Jon Doron2704efa2019-05-29 09:41:45 +03002053 return;
2054 }
2055
Alex Bennée308f9e82020-03-16 17:21:35 +00002056 g_string_assign(gdbserver_state.str_buf, "m");
2057 gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
2058 put_strbuf();
Alex Bennéea346af32020-03-16 17:21:34 +00002059 gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002060}
2061
Alex Bennée26a16182021-05-25 09:24:14 +01002062static void handle_query_first_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002063{
Alex Bennéea346af32020-03-16 17:21:34 +00002064 gdbserver_state.query_cpu = gdb_first_attached_cpu();
Alex Bennée26a16182021-05-25 09:24:14 +01002065 handle_query_threads(params, user_ctx);
Jon Doron2704efa2019-05-29 09:41:45 +03002066}
2067
Alex Bennée26a16182021-05-25 09:24:14 +01002068static void handle_query_thread_extra(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002069{
Alex Bennée308f9e82020-03-16 17:21:35 +00002070 g_autoptr(GString) rs = g_string_new(NULL);
Jon Doron2704efa2019-05-29 09:41:45 +03002071 CPUState *cpu;
Jon Doron2704efa2019-05-29 09:41:45 +03002072
Alex Bennée26a16182021-05-25 09:24:14 +01002073 if (!params->len ||
2074 get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00002075 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002076 return;
2077 }
2078
Alex Bennée26a16182021-05-25 09:24:14 +01002079 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
2080 get_param(params, 0)->thread_id.tid);
Jon Doron2704efa2019-05-29 09:41:45 +03002081 if (!cpu) {
2082 return;
2083 }
2084
2085 cpu_synchronize_state(cpu);
2086
Alex Bennéea346af32020-03-16 17:21:34 +00002087 if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
Jon Doron2704efa2019-05-29 09:41:45 +03002088 /* Print the CPU model and name in multiprocess mode */
2089 ObjectClass *oc = object_get_class(OBJECT(cpu));
2090 const char *cpu_model = object_class_get_name(oc);
Markus Armbruster7a309cc2020-07-14 18:02:00 +02002091 const char *cpu_name =
Denis Plotnikov076b2fa2020-04-03 20:11:44 +01002092 object_get_canonical_path_component(OBJECT(cpu));
Alex Bennée308f9e82020-03-16 17:21:35 +00002093 g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
2094 cpu->halted ? "halted " : "running");
Jon Doron2704efa2019-05-29 09:41:45 +03002095 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002096 g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
Jon Doron2704efa2019-05-29 09:41:45 +03002097 cpu->halted ? "halted " : "running");
2098 }
Alex Bennée308f9e82020-03-16 17:21:35 +00002099 trace_gdbstub_op_extra_info(rs->str);
2100 memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
2101 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002102}
2103
2104#ifdef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002105static void handle_query_offsets(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002106{
2107 TaskState *ts;
2108
Alex Bennéea346af32020-03-16 17:21:34 +00002109 ts = gdbserver_state.c_cpu->opaque;
Alex Bennée308f9e82020-03-16 17:21:35 +00002110 g_string_printf(gdbserver_state.str_buf,
2111 "Text=" TARGET_ABI_FMT_lx
2112 ";Data=" TARGET_ABI_FMT_lx
2113 ";Bss=" TARGET_ABI_FMT_lx,
2114 ts->info->code_offset,
2115 ts->info->data_offset,
2116 ts->info->data_offset);
2117 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002118}
2119#else
Alex Bennée26a16182021-05-25 09:24:14 +01002120static void handle_query_rcmd(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002121{
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002122 const guint8 zero = 0;
Jon Doron2704efa2019-05-29 09:41:45 +03002123 int len;
2124
Alex Bennée26a16182021-05-25 09:24:14 +01002125 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002126 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002127 return;
2128 }
2129
Alex Bennée26a16182021-05-25 09:24:14 +01002130 len = strlen(get_param(params, 0)->data);
Jon Doron2704efa2019-05-29 09:41:45 +03002131 if (len % 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00002132 put_packet("E01");
Jon Doron2704efa2019-05-29 09:41:45 +03002133 return;
2134 }
2135
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002136 g_assert(gdbserver_state.mem_buf->len == 0);
Jon Doron2704efa2019-05-29 09:41:45 +03002137 len = len / 2;
Alex Bennée26a16182021-05-25 09:24:14 +01002138 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002139 g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
2140 qemu_chr_be_write(gdbserver_state.mon_chr, gdbserver_state.mem_buf->data,
2141 gdbserver_state.mem_buf->len);
Alex Bennéea346af32020-03-16 17:21:34 +00002142 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002143}
2144#endif
2145
Alex Bennée26a16182021-05-25 09:24:14 +01002146static void handle_query_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002147{
Andreas Färber5b24c642013-07-07 15:08:22 +02002148 CPUClass *cc;
Jon Doron2704efa2019-05-29 09:41:45 +03002149
Alex Bennée308f9e82020-03-16 17:21:35 +00002150 g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
Jon Doron2704efa2019-05-29 09:41:45 +03002151 cc = CPU_GET_CLASS(first_cpu);
2152 if (cc->gdb_core_xml_file) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002153 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
Jon Doron2704efa2019-05-29 09:41:45 +03002154 }
2155
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002156 if (replay_mode == REPLAY_MODE_PLAY) {
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03002157 g_string_append(gdbserver_state.str_buf,
2158 ";ReverseStep+;ReverseContinue+");
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002159 }
2160
Lirong Yuan51c623b2021-01-08 22:42:42 +00002161#ifdef CONFIG_USER_ONLY
2162 if (gdbserver_state.c_cpu->opaque) {
2163 g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
2164 }
2165#endif
2166
Alex Bennée26a16182021-05-25 09:24:14 +01002167 if (params->len &&
2168 strstr(get_param(params, 0)->data, "multiprocess+")) {
Alex Bennéea346af32020-03-16 17:21:34 +00002169 gdbserver_state.multiprocess = true;
Jon Doron2704efa2019-05-29 09:41:45 +03002170 }
2171
Changbin Du3bc26092020-03-16 17:21:55 +00002172 g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
Alex Bennée308f9e82020-03-16 17:21:35 +00002173 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002174}
2175
Alex Bennée26a16182021-05-25 09:24:14 +01002176static void handle_query_xfer_features(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002177{
2178 GDBProcess *process;
2179 CPUClass *cc;
2180 unsigned long len, total_len, addr;
2181 const char *xml;
bellardb4608c02003-06-27 17:34:32 +00002182 const char *p;
Jon Doron2704efa2019-05-29 09:41:45 +03002183
Alex Bennée26a16182021-05-25 09:24:14 +01002184 if (params->len < 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00002185 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002186 return;
2187 }
2188
Alex Bennéea346af32020-03-16 17:21:34 +00002189 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2190 cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002191 if (!cc->gdb_core_xml_file) {
Alex Bennéea346af32020-03-16 17:21:34 +00002192 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002193 return;
2194 }
2195
2196 gdb_has_xml = true;
Alex Bennée26a16182021-05-25 09:24:14 +01002197 p = get_param(params, 0)->data;
Alex Bennéea346af32020-03-16 17:21:34 +00002198 xml = get_feature_xml(p, &p, process);
Jon Doron2704efa2019-05-29 09:41:45 +03002199 if (!xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00002200 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002201 return;
2202 }
2203
Alex Bennée26a16182021-05-25 09:24:14 +01002204 addr = get_param(params, 1)->val_ul;
2205 len = get_param(params, 2)->val_ul;
Jon Doron2704efa2019-05-29 09:41:45 +03002206 total_len = strlen(xml);
2207 if (addr > total_len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002208 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002209 return;
2210 }
2211
2212 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2213 len = (MAX_PACKET_LENGTH - 5) / 2;
2214 }
2215
2216 if (len < total_len - addr) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002217 g_string_assign(gdbserver_state.str_buf, "m");
2218 memtox(gdbserver_state.str_buf, xml + addr, len);
Jon Doron2704efa2019-05-29 09:41:45 +03002219 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002220 g_string_assign(gdbserver_state.str_buf, "l");
2221 memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
Jon Doron2704efa2019-05-29 09:41:45 +03002222 }
2223
Alex Bennée308f9e82020-03-16 17:21:35 +00002224 put_packet_binary(gdbserver_state.str_buf->str,
2225 gdbserver_state.str_buf->len, true);
Jon Doron2704efa2019-05-29 09:41:45 +03002226}
2227
Lirong Yuan51c623b2021-01-08 22:42:42 +00002228#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
Alex Bennée26a16182021-05-25 09:24:14 +01002229static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
Lirong Yuan51c623b2021-01-08 22:42:42 +00002230{
2231 TaskState *ts;
2232 unsigned long offset, len, saved_auxv, auxv_len;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002233
Alex Bennée26a16182021-05-25 09:24:14 +01002234 if (params->len < 2) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002235 put_packet("E22");
2236 return;
2237 }
2238
Alex Bennée26a16182021-05-25 09:24:14 +01002239 offset = get_param(params, 0)->val_ul;
2240 len = get_param(params, 1)->val_ul;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002241 ts = gdbserver_state.c_cpu->opaque;
2242 saved_auxv = ts->info->saved_auxv;
2243 auxv_len = ts->info->auxv_len;
Richard Henderson6e3dd752021-02-02 13:39:55 +00002244
2245 if (offset >= auxv_len) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002246 put_packet("E00");
2247 return;
2248 }
2249
2250 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2251 len = (MAX_PACKET_LENGTH - 5) / 2;
2252 }
2253
2254 if (len < auxv_len - offset) {
2255 g_string_assign(gdbserver_state.str_buf, "m");
Lirong Yuan51c623b2021-01-08 22:42:42 +00002256 } else {
2257 g_string_assign(gdbserver_state.str_buf, "l");
Richard Henderson6e3dd752021-02-02 13:39:55 +00002258 len = auxv_len - offset;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002259 }
2260
Richard Henderson6e3dd752021-02-02 13:39:55 +00002261 g_byte_array_set_size(gdbserver_state.mem_buf, len);
2262 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2263 gdbserver_state.mem_buf->data, len, false)) {
2264 put_packet("E14");
2265 return;
2266 }
2267
2268 memtox(gdbserver_state.str_buf,
2269 (const char *)gdbserver_state.mem_buf->data, len);
Lirong Yuan51c623b2021-01-08 22:42:42 +00002270 put_packet_binary(gdbserver_state.str_buf->str,
2271 gdbserver_state.str_buf->len, true);
2272}
2273#endif
2274
Alex Bennée26a16182021-05-25 09:24:14 +01002275static void handle_query_attached(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002276{
Alex Bennéea346af32020-03-16 17:21:34 +00002277 put_packet(GDB_ATTACHED);
Jon Doron2704efa2019-05-29 09:41:45 +03002278}
2279
Alex Bennée26a16182021-05-25 09:24:14 +01002280static void handle_query_qemu_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002281{
Alex Bennée308f9e82020-03-16 17:21:35 +00002282 g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
Jon Doronab4752e2019-05-29 09:41:48 +03002283#ifndef CONFIG_USER_ONLY
Alex Bennée308f9e82020-03-16 17:21:35 +00002284 g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
Jon Doronab4752e2019-05-29 09:41:48 +03002285#endif
Alex Bennée308f9e82020-03-16 17:21:35 +00002286 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002287}
2288
Jon Doronab4752e2019-05-29 09:41:48 +03002289#ifndef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002290static void handle_query_qemu_phy_mem_mode(GArray *params,
Jon Doronab4752e2019-05-29 09:41:48 +03002291 void *user_ctx)
2292{
Alex Bennée308f9e82020-03-16 17:21:35 +00002293 g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
2294 put_strbuf();
Jon Doronab4752e2019-05-29 09:41:48 +03002295}
2296
Alex Bennée26a16182021-05-25 09:24:14 +01002297static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
Jon Doronab4752e2019-05-29 09:41:48 +03002298{
Alex Bennée26a16182021-05-25 09:24:14 +01002299 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002300 put_packet("E22");
Jon Doronab4752e2019-05-29 09:41:48 +03002301 return;
2302 }
2303
Alex Bennée26a16182021-05-25 09:24:14 +01002304 if (!get_param(params, 0)->val_ul) {
Jon Doronab4752e2019-05-29 09:41:48 +03002305 phy_memory_mode = 0;
2306 } else {
2307 phy_memory_mode = 1;
2308 }
Alex Bennéea346af32020-03-16 17:21:34 +00002309 put_packet("OK");
Jon Doronab4752e2019-05-29 09:41:48 +03002310}
2311#endif
2312
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002313static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002314 /* Order is important if has same prefix */
2315 {
2316 .handler = handle_query_qemu_sstepbits,
2317 .cmd = "qemu.sstepbits",
2318 },
2319 {
2320 .handler = handle_query_qemu_sstep,
2321 .cmd = "qemu.sstep",
2322 },
2323 {
2324 .handler = handle_set_qemu_sstep,
2325 .cmd = "qemu.sstep=",
2326 .cmd_startswith = 1,
2327 .schema = "l0"
2328 },
2329};
2330
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002331static const GdbCmdParseEntry gdb_gen_query_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002332 {
2333 .handler = handle_query_curr_tid,
2334 .cmd = "C",
2335 },
2336 {
2337 .handler = handle_query_threads,
2338 .cmd = "sThreadInfo",
2339 },
2340 {
2341 .handler = handle_query_first_threads,
2342 .cmd = "fThreadInfo",
2343 },
2344 {
2345 .handler = handle_query_thread_extra,
2346 .cmd = "ThreadExtraInfo,",
2347 .cmd_startswith = 1,
2348 .schema = "t0"
2349 },
2350#ifdef CONFIG_USER_ONLY
2351 {
2352 .handler = handle_query_offsets,
2353 .cmd = "Offsets",
2354 },
2355#else
2356 {
2357 .handler = handle_query_rcmd,
2358 .cmd = "Rcmd,",
2359 .cmd_startswith = 1,
2360 .schema = "s0"
2361 },
2362#endif
2363 {
2364 .handler = handle_query_supported,
2365 .cmd = "Supported:",
2366 .cmd_startswith = 1,
2367 .schema = "s0"
2368 },
2369 {
2370 .handler = handle_query_supported,
2371 .cmd = "Supported",
2372 .schema = "s0"
2373 },
2374 {
2375 .handler = handle_query_xfer_features,
2376 .cmd = "Xfer:features:read:",
2377 .cmd_startswith = 1,
2378 .schema = "s:l,l0"
2379 },
Lirong Yuan51c623b2021-01-08 22:42:42 +00002380#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2381 {
2382 .handler = handle_query_xfer_auxv,
2383 .cmd = "Xfer:auxv:read::",
2384 .cmd_startswith = 1,
2385 .schema = "l,l0"
2386 },
2387#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002388 {
2389 .handler = handle_query_attached,
2390 .cmd = "Attached:",
2391 .cmd_startswith = 1
2392 },
2393 {
2394 .handler = handle_query_attached,
2395 .cmd = "Attached",
2396 },
2397 {
2398 .handler = handle_query_qemu_supported,
2399 .cmd = "qemu.Supported",
2400 },
Jon Doronab4752e2019-05-29 09:41:48 +03002401#ifndef CONFIG_USER_ONLY
2402 {
2403 .handler = handle_query_qemu_phy_mem_mode,
2404 .cmd = "qemu.PhyMemMode",
2405 },
2406#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002407};
2408
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002409static const GdbCmdParseEntry gdb_gen_set_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002410 /* Order is important if has same prefix */
2411 {
2412 .handler = handle_set_qemu_sstep,
2413 .cmd = "qemu.sstep:",
2414 .cmd_startswith = 1,
2415 .schema = "l0"
2416 },
Jon Doronab4752e2019-05-29 09:41:48 +03002417#ifndef CONFIG_USER_ONLY
2418 {
2419 .handler = handle_set_qemu_phy_mem_mode,
2420 .cmd = "qemu.PhyMemMode:",
2421 .cmd_startswith = 1,
2422 .schema = "l0"
2423 },
2424#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002425};
2426
Alex Bennée26a16182021-05-25 09:24:14 +01002427static void handle_gen_query(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002428{
Alex Bennée26a16182021-05-25 09:24:14 +01002429 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002430 return;
2431 }
2432
Alex Bennée26a16182021-05-25 09:24:14 +01002433 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002434 gdb_gen_query_set_common_table,
2435 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2436 return;
2437 }
2438
Alex Bennée26a16182021-05-25 09:24:14 +01002439 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002440 gdb_gen_query_table,
2441 ARRAY_SIZE(gdb_gen_query_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002442 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002443 }
2444}
2445
Alex Bennée26a16182021-05-25 09:24:14 +01002446static void handle_gen_set(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002447{
Alex Bennée26a16182021-05-25 09:24:14 +01002448 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002449 return;
2450 }
2451
Alex Bennée26a16182021-05-25 09:24:14 +01002452 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002453 gdb_gen_query_set_common_table,
2454 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2455 return;
2456 }
2457
Alex Bennée26a16182021-05-25 09:24:14 +01002458 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002459 gdb_gen_set_table,
2460 ARRAY_SIZE(gdb_gen_set_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002461 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002462 }
2463}
2464
Alex Bennée26a16182021-05-25 09:24:14 +01002465static void handle_target_halt(GArray *params, void *user_ctx)
Jon Doron7009d572019-05-29 09:41:46 +03002466{
Alex Bennée308f9e82020-03-16 17:21:35 +00002467 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2468 gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2469 g_string_append_c(gdbserver_state.str_buf, ';');
2470 put_strbuf();
Jon Doron7009d572019-05-29 09:41:46 +03002471 /*
2472 * Remove all the breakpoints when this query is issued,
2473 * because gdb is doing an initial connect and the state
2474 * should be cleaned up.
2475 */
2476 gdb_breakpoint_remove_all();
2477}
2478
Alex Bennéea346af32020-03-16 17:21:34 +00002479static int gdb_handle_packet(const char *line_buf)
Jon Doron2704efa2019-05-29 09:41:45 +03002480{
Jon Doron3e2c1262019-05-29 09:41:30 +03002481 const GdbCmdParseEntry *cmd_parser = NULL;
ths3b46e622007-09-17 08:09:54 +00002482
Doug Gale5c9522b2017-12-02 20:30:37 -05002483 trace_gdbstub_io_command(line_buf);
Alex Bennée118e2262017-07-12 11:52:13 +01002484
Jon Doron3f1cbac2019-05-29 09:41:47 +03002485 switch (line_buf[0]) {
Luc Michel53fd6552019-01-07 15:23:46 +00002486 case '!':
Alex Bennéea346af32020-03-16 17:21:34 +00002487 put_packet("OK");
Luc Michel53fd6552019-01-07 15:23:46 +00002488 break;
bellard858693c2004-03-31 18:52:07 +00002489 case '?':
Jon Doron7009d572019-05-29 09:41:46 +03002490 {
2491 static const GdbCmdParseEntry target_halted_cmd_desc = {
2492 .handler = handle_target_halt,
2493 .cmd = "?",
2494 .cmd_startswith = 1
2495 };
2496 cmd_parser = &target_halted_cmd_desc;
2497 }
bellard858693c2004-03-31 18:52:07 +00002498 break;
2499 case 'c':
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002500 {
2501 static const GdbCmdParseEntry continue_cmd_desc = {
2502 .handler = handle_continue,
2503 .cmd = "c",
2504 .cmd_startswith = 1,
2505 .schema = "L0"
2506 };
2507 cmd_parser = &continue_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002508 }
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002509 break;
edgar_igl1f487ee2008-05-17 22:20:53 +00002510 case 'C':
Jon Doronccc47d52019-05-29 09:41:33 +03002511 {
2512 static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2513 .handler = handle_cont_with_sig,
2514 .cmd = "C",
2515 .cmd_startswith = 1,
2516 .schema = "l0"
2517 };
2518 cmd_parser = &cont_with_sig_cmd_desc;
2519 }
2520 break;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002521 case 'v':
Jon Doron8536ec02019-05-29 09:41:44 +03002522 {
2523 static const GdbCmdParseEntry v_cmd_desc = {
2524 .handler = handle_v_commands,
2525 .cmd = "v",
2526 .cmd_startswith = 1,
2527 .schema = "s0"
2528 };
2529 cmd_parser = &v_cmd_desc;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002530 }
Jon Doron8536ec02019-05-29 09:41:44 +03002531 break;
edgar_igl7d03f822008-05-17 18:58:29 +00002532 case 'k':
2533 /* Kill the target */
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002534 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00002535 gdb_exit(0);
edgar_igl7d03f822008-05-17 18:58:29 +00002536 exit(0);
2537 case 'D':
Jon Doron3e2c1262019-05-29 09:41:30 +03002538 {
2539 static const GdbCmdParseEntry detach_cmd_desc = {
2540 .handler = handle_detach,
2541 .cmd = "D",
2542 .cmd_startswith = 1,
2543 .schema = "?.l0"
2544 };
2545 cmd_parser = &detach_cmd_desc;
Luc Michel546f3c62019-01-07 15:23:46 +00002546 }
edgar_igl7d03f822008-05-17 18:58:29 +00002547 break;
bellard858693c2004-03-31 18:52:07 +00002548 case 's':
Jon Doron933f80d2019-05-29 09:41:43 +03002549 {
2550 static const GdbCmdParseEntry step_cmd_desc = {
2551 .handler = handle_step,
2552 .cmd = "s",
2553 .cmd_startswith = 1,
2554 .schema = "L0"
2555 };
2556 cmd_parser = &step_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002557 }
Jon Doron933f80d2019-05-29 09:41:43 +03002558 break;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002559 case 'b':
2560 {
2561 static const GdbCmdParseEntry backward_cmd_desc = {
2562 .handler = handle_backward,
2563 .cmd = "b",
2564 .cmd_startswith = 1,
2565 .schema = "o0"
2566 };
2567 cmd_parser = &backward_cmd_desc;
2568 }
2569 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002570 case 'F':
2571 {
Jon Doron4b20fab2019-05-29 09:41:42 +03002572 static const GdbCmdParseEntry file_io_cmd_desc = {
2573 .handler = handle_file_io,
2574 .cmd = "F",
2575 .cmd_startswith = 1,
2576 .schema = "L,L,o0"
2577 };
2578 cmd_parser = &file_io_cmd_desc;
pbrooka2d1eba2007-01-28 03:10:55 +00002579 }
2580 break;
bellard858693c2004-03-31 18:52:07 +00002581 case 'g':
Jon Doron397d1372019-05-29 09:41:41 +03002582 {
2583 static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2584 .handler = handle_read_all_regs,
2585 .cmd = "g",
2586 .cmd_startswith = 1
2587 };
2588 cmd_parser = &read_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002589 }
bellard858693c2004-03-31 18:52:07 +00002590 break;
2591 case 'G':
Jon Doron287ca122019-05-29 09:41:40 +03002592 {
2593 static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2594 .handler = handle_write_all_regs,
2595 .cmd = "G",
2596 .cmd_startswith = 1,
2597 .schema = "s0"
2598 };
2599 cmd_parser = &write_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002600 }
bellard858693c2004-03-31 18:52:07 +00002601 break;
2602 case 'm':
Jon Doronda92e232019-05-29 09:41:39 +03002603 {
2604 static const GdbCmdParseEntry read_mem_cmd_desc = {
2605 .handler = handle_read_mem,
2606 .cmd = "m",
2607 .cmd_startswith = 1,
2608 .schema = "L,L0"
2609 };
2610 cmd_parser = &read_mem_cmd_desc;
bellard6f970bd2005-12-05 19:55:19 +00002611 }
bellard858693c2004-03-31 18:52:07 +00002612 break;
2613 case 'M':
Jon Doroncc0ecc72019-05-29 09:41:38 +03002614 {
2615 static const GdbCmdParseEntry write_mem_cmd_desc = {
2616 .handler = handle_write_mem,
2617 .cmd = "M",
2618 .cmd_startswith = 1,
2619 .schema = "L,L:s0"
2620 };
2621 cmd_parser = &write_mem_cmd_desc;
Fabien Chouteau44520db2011-09-08 12:48:16 +02002622 }
bellard858693c2004-03-31 18:52:07 +00002623 break;
pbrook56aebc82008-10-11 17:55:29 +00002624 case 'p':
Jon Doron5d0e57b2019-05-29 09:41:37 +03002625 {
2626 static const GdbCmdParseEntry get_reg_cmd_desc = {
2627 .handler = handle_get_reg,
2628 .cmd = "p",
2629 .cmd_startswith = 1,
2630 .schema = "L0"
2631 };
2632 cmd_parser = &get_reg_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002633 }
2634 break;
2635 case 'P':
Jon Doron62b33202019-05-29 09:41:36 +03002636 {
2637 static const GdbCmdParseEntry set_reg_cmd_desc = {
2638 .handler = handle_set_reg,
2639 .cmd = "P",
2640 .cmd_startswith = 1,
2641 .schema = "L?s0"
2642 };
2643 cmd_parser = &set_reg_cmd_desc;
2644 }
pbrook56aebc82008-10-11 17:55:29 +00002645 break;
bellard858693c2004-03-31 18:52:07 +00002646 case 'Z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002647 {
2648 static const GdbCmdParseEntry insert_bp_cmd_desc = {
2649 .handler = handle_insert_bp,
2650 .cmd = "Z",
2651 .cmd_startswith = 1,
2652 .schema = "l?L?L0"
2653 };
2654 cmd_parser = &insert_bp_cmd_desc;
2655 }
2656 break;
bellard858693c2004-03-31 18:52:07 +00002657 case 'z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002658 {
2659 static const GdbCmdParseEntry remove_bp_cmd_desc = {
2660 .handler = handle_remove_bp,
2661 .cmd = "z",
2662 .cmd_startswith = 1,
2663 .schema = "l?L?L0"
2664 };
2665 cmd_parser = &remove_bp_cmd_desc;
2666 }
bellard858693c2004-03-31 18:52:07 +00002667 break;
aliguori880a7572008-11-18 20:30:24 +00002668 case 'H':
Jon Doron3a9651d2019-05-29 09:41:34 +03002669 {
2670 static const GdbCmdParseEntry set_thread_cmd_desc = {
2671 .handler = handle_set_thread,
2672 .cmd = "H",
2673 .cmd_startswith = 1,
2674 .schema = "o.t0"
2675 };
2676 cmd_parser = &set_thread_cmd_desc;
aliguori880a7572008-11-18 20:30:24 +00002677 }
2678 break;
2679 case 'T':
Jon Doron44ffded2019-05-29 09:41:31 +03002680 {
2681 static const GdbCmdParseEntry thread_alive_cmd_desc = {
2682 .handler = handle_thread_alive,
2683 .cmd = "T",
2684 .cmd_startswith = 1,
2685 .schema = "t0"
2686 };
2687 cmd_parser = &thread_alive_cmd_desc;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002688 }
aliguori880a7572008-11-18 20:30:24 +00002689 break;
pbrook978efd62006-06-17 18:30:42 +00002690 case 'q':
Jon Doron2704efa2019-05-29 09:41:45 +03002691 {
2692 static const GdbCmdParseEntry gen_query_cmd_desc = {
2693 .handler = handle_gen_query,
2694 .cmd = "q",
2695 .cmd_startswith = 1,
2696 .schema = "s0"
2697 };
2698 cmd_parser = &gen_query_cmd_desc;
2699 }
2700 break;
edgar_igl60897d32008-05-09 08:25:14 +00002701 case 'Q':
Jon Doron2704efa2019-05-29 09:41:45 +03002702 {
2703 static const GdbCmdParseEntry gen_set_cmd_desc = {
2704 .handler = handle_gen_set,
2705 .cmd = "Q",
2706 .cmd_startswith = 1,
2707 .schema = "s0"
2708 };
2709 cmd_parser = &gen_set_cmd_desc;
edgar_igl60897d32008-05-09 08:25:14 +00002710 }
Jon Doron2704efa2019-05-29 09:41:45 +03002711 break;
bellard858693c2004-03-31 18:52:07 +00002712 default:
bellard858693c2004-03-31 18:52:07 +00002713 /* put empty packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002714 put_packet("");
bellard858693c2004-03-31 18:52:07 +00002715 break;
2716 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002717
Ramiro Polla2bdec392019-08-05 21:09:01 +02002718 if (cmd_parser) {
Alex Bennéea346af32020-03-16 17:21:34 +00002719 run_cmd_parser(line_buf, cmd_parser);
Ramiro Polla2bdec392019-08-05 21:09:01 +02002720 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002721
bellard858693c2004-03-31 18:52:07 +00002722 return RS_IDLE;
2723}
2724
Andreas Färber64f6b342013-05-27 02:06:09 +02002725void gdb_set_stop_cpu(CPUState *cpu)
aliguori880a7572008-11-18 20:30:24 +00002726{
Alex Bennéea346af32020-03-16 17:21:34 +00002727 GDBProcess *p = gdb_get_cpu_process(cpu);
Luc Michel160d8582019-01-07 15:23:46 +00002728
2729 if (!p->attached) {
2730 /*
2731 * Having a stop CPU corresponding to a process that is not attached
2732 * confuses GDB. So we ignore the request.
2733 */
2734 return;
2735 }
2736
Alex Bennée8d98c442020-03-16 17:21:33 +00002737 gdbserver_state.c_cpu = cpu;
2738 gdbserver_state.g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002739}
2740
bellard1fddef42005-04-17 19:16:13 +00002741#ifndef CONFIG_USER_ONLY
Philippe Mathieu-Daudé538f0492021-01-11 16:20:20 +01002742static void gdb_vm_state_change(void *opaque, bool running, RunState state)
bellard858693c2004-03-31 18:52:07 +00002743{
Alex Bennéea346af32020-03-16 17:21:34 +00002744 CPUState *cpu = gdbserver_state.c_cpu;
Alex Bennée308f9e82020-03-16 17:21:35 +00002745 g_autoptr(GString) buf = g_string_new(NULL);
2746 g_autoptr(GString) tid = g_string_new(NULL);
aliguorid6fc1b32008-11-18 19:55:44 +00002747 const char *type;
bellard858693c2004-03-31 18:52:07 +00002748 int ret;
2749
Alex Bennéea346af32020-03-16 17:21:34 +00002750 if (running || gdbserver_state.state == RS_INACTIVE) {
Meador Ingecdb432b2012-03-15 17:49:45 +00002751 return;
2752 }
2753 /* Is there a GDB syscall waiting to be sent? */
Alex Bennéea346af32020-03-16 17:21:34 +00002754 if (gdbserver_state.current_syscall_cb) {
2755 put_packet(gdbserver_state.syscall_buf);
pbrooka2d1eba2007-01-28 03:10:55 +00002756 return;
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002757 }
Luc Michel95567c22019-01-07 15:23:46 +00002758
2759 if (cpu == NULL) {
2760 /* No process attached */
2761 return;
2762 }
2763
Alex Bennée308f9e82020-03-16 17:21:35 +00002764 gdb_append_thread_id(cpu, tid);
Luc Michel95567c22019-01-07 15:23:46 +00002765
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002766 switch (state) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002767 case RUN_STATE_DEBUG:
Andreas Färberff4700b2013-08-26 18:23:18 +02002768 if (cpu->watchpoint_hit) {
2769 switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
aliguoria1d1bb32008-11-18 20:07:32 +00002770 case BP_MEM_READ:
aliguorid6fc1b32008-11-18 19:55:44 +00002771 type = "r";
2772 break;
aliguoria1d1bb32008-11-18 20:07:32 +00002773 case BP_MEM_ACCESS:
aliguorid6fc1b32008-11-18 19:55:44 +00002774 type = "a";
2775 break;
2776 default:
2777 type = "";
2778 break;
2779 }
Doug Gale5c9522b2017-12-02 20:30:37 -05002780 trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
2781 (target_ulong)cpu->watchpoint_hit->vaddr);
Alex Bennée308f9e82020-03-16 17:21:35 +00002782 g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
2783 GDB_SIGNAL_TRAP, tid->str, type,
2784 (target_ulong)cpu->watchpoint_hit->vaddr);
Andreas Färberff4700b2013-08-26 18:23:18 +02002785 cpu->watchpoint_hit = NULL;
Jan Kiszka425189a2011-03-22 11:02:09 +01002786 goto send_packet;
Doug Gale5c9522b2017-12-02 20:30:37 -05002787 } else {
2788 trace_gdbstub_hit_break();
pbrook6658ffb2007-03-16 23:58:11 +00002789 }
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07002790 tb_flush(cpu);
aurel32ca587a82008-12-18 22:44:13 +00002791 ret = GDB_SIGNAL_TRAP;
Jan Kiszka425189a2011-03-22 11:02:09 +01002792 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002793 case RUN_STATE_PAUSED:
Doug Gale5c9522b2017-12-02 20:30:37 -05002794 trace_gdbstub_hit_paused();
aliguori9781e042009-01-22 17:15:29 +00002795 ret = GDB_SIGNAL_INT;
Jan Kiszka425189a2011-03-22 11:02:09 +01002796 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002797 case RUN_STATE_SHUTDOWN:
Doug Gale5c9522b2017-12-02 20:30:37 -05002798 trace_gdbstub_hit_shutdown();
Jan Kiszka425189a2011-03-22 11:02:09 +01002799 ret = GDB_SIGNAL_QUIT;
2800 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002801 case RUN_STATE_IO_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002802 trace_gdbstub_hit_io_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002803 ret = GDB_SIGNAL_IO;
2804 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002805 case RUN_STATE_WATCHDOG:
Doug Gale5c9522b2017-12-02 20:30:37 -05002806 trace_gdbstub_hit_watchdog();
Jan Kiszka425189a2011-03-22 11:02:09 +01002807 ret = GDB_SIGNAL_ALRM;
2808 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002809 case RUN_STATE_INTERNAL_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002810 trace_gdbstub_hit_internal_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002811 ret = GDB_SIGNAL_ABRT;
2812 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002813 case RUN_STATE_SAVE_VM:
2814 case RUN_STATE_RESTORE_VM:
Jan Kiszka425189a2011-03-22 11:02:09 +01002815 return;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002816 case RUN_STATE_FINISH_MIGRATE:
Jan Kiszka425189a2011-03-22 11:02:09 +01002817 ret = GDB_SIGNAL_XCPU;
2818 break;
2819 default:
Doug Gale5c9522b2017-12-02 20:30:37 -05002820 trace_gdbstub_hit_unknown(state);
Jan Kiszka425189a2011-03-22 11:02:09 +01002821 ret = GDB_SIGNAL_UNKNOWN;
2822 break;
bellardbbeb7b52006-04-23 18:42:15 +00002823 }
Jan Kiszka226d0072015-07-24 18:52:31 +02002824 gdb_set_stop_cpu(cpu);
Alex Bennée308f9e82020-03-16 17:21:35 +00002825 g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002826
2827send_packet:
Alex Bennée308f9e82020-03-16 17:21:35 +00002828 put_packet(buf->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002829
2830 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002831 cpu_single_step(cpu, 0);
bellard858693c2004-03-31 18:52:07 +00002832}
bellard1fddef42005-04-17 19:16:13 +00002833#endif
bellard858693c2004-03-31 18:52:07 +00002834
pbrooka2d1eba2007-01-28 03:10:55 +00002835/* Send a gdb syscall request.
2836 This accepts limited printf-style format specifiers, specifically:
pbrooka87295e2007-05-26 15:09:38 +00002837 %x - target_ulong argument printed in hex.
2838 %lx - 64-bit argument printed in hex.
2839 %s - string pointer (target_ulong) and length (int) pair. */
Peter Maydell19239b32015-09-07 10:39:27 +01002840void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
pbrooka2d1eba2007-01-28 03:10:55 +00002841{
pbrooka2d1eba2007-01-28 03:10:55 +00002842 char *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00002843 char *p_end;
pbrooka2d1eba2007-01-28 03:10:55 +00002844 target_ulong addr;
pbrooka87295e2007-05-26 15:09:38 +00002845 uint64_t i64;
pbrooka2d1eba2007-01-28 03:10:55 +00002846
Alex Bennéea346af32020-03-16 17:21:34 +00002847 if (!gdbserver_state.init) {
pbrooka2d1eba2007-01-28 03:10:55 +00002848 return;
Alex Bennéea346af32020-03-16 17:21:34 +00002849 }
Alex Bennée8d98c442020-03-16 17:21:33 +00002850
2851 gdbserver_state.current_syscall_cb = cb;
pbrooka2d1eba2007-01-28 03:10:55 +00002852#ifndef CONFIG_USER_ONLY
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002853 vm_stop(RUN_STATE_DEBUG);
pbrooka2d1eba2007-01-28 03:10:55 +00002854#endif
Alex Bennée8d98c442020-03-16 17:21:33 +00002855 p = &gdbserver_state.syscall_buf[0];
2856 p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
pbrooka2d1eba2007-01-28 03:10:55 +00002857 *(p++) = 'F';
2858 while (*fmt) {
2859 if (*fmt == '%') {
2860 fmt++;
2861 switch (*fmt++) {
2862 case 'x':
2863 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002864 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
pbrooka2d1eba2007-01-28 03:10:55 +00002865 break;
pbrooka87295e2007-05-26 15:09:38 +00002866 case 'l':
2867 if (*(fmt++) != 'x')
2868 goto bad_format;
2869 i64 = va_arg(va, uint64_t);
Meador Ingecdb432b2012-03-15 17:49:45 +00002870 p += snprintf(p, p_end - p, "%" PRIx64, i64);
pbrooka87295e2007-05-26 15:09:38 +00002871 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002872 case 's':
2873 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002874 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
blueswir1363a37d2008-08-21 17:58:08 +00002875 addr, va_arg(va, int));
pbrooka2d1eba2007-01-28 03:10:55 +00002876 break;
2877 default:
pbrooka87295e2007-05-26 15:09:38 +00002878 bad_format:
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002879 error_report("gdbstub: Bad syscall format string '%s'",
2880 fmt - 1);
pbrooka2d1eba2007-01-28 03:10:55 +00002881 break;
2882 }
2883 } else {
2884 *(p++) = *(fmt++);
2885 }
2886 }
pbrook8a93e022007-08-06 13:19:15 +00002887 *p = 0;
pbrooka2d1eba2007-01-28 03:10:55 +00002888#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +00002889 put_packet(gdbserver_state.syscall_buf);
Peter Maydell4f710862018-05-15 19:19:58 +01002890 /* Return control to gdb for it to process the syscall request.
2891 * Since the protocol requires that gdb hands control back to us
2892 * using a "here are the results" F packet, we don't need to check
2893 * gdb_handlesig's return value (which is the signal to deliver if
2894 * execution was resumed via a continue packet).
2895 */
Alex Bennée8d98c442020-03-16 17:21:33 +00002896 gdb_handlesig(gdbserver_state.c_cpu, 0);
pbrooka2d1eba2007-01-28 03:10:55 +00002897#else
Meador Ingecdb432b2012-03-15 17:49:45 +00002898 /* In this case wait to send the syscall packet until notification that
2899 the CPU has stopped. This must be done because if the packet is sent
2900 now the reply from the syscall request could be received while the CPU
2901 is still in the running state, which can cause packets to be dropped
2902 and state transition 'T' packets to be sent while the syscall is still
2903 being processed. */
Alex Bennée8d98c442020-03-16 17:21:33 +00002904 qemu_cpu_kick(gdbserver_state.c_cpu);
pbrooka2d1eba2007-01-28 03:10:55 +00002905#endif
2906}
2907
Peter Maydell19239b32015-09-07 10:39:27 +01002908void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2909{
2910 va_list va;
2911
2912 va_start(va, fmt);
2913 gdb_do_syscallv(cb, fmt, va);
2914 va_end(va);
2915}
2916
Alex Bennéea346af32020-03-16 17:21:34 +00002917static void gdb_read_byte(uint8_t ch)
bellard858693c2004-03-31 18:52:07 +00002918{
ths60fe76f2007-12-16 03:02:09 +00002919 uint8_t reply;
bellard858693c2004-03-31 18:52:07 +00002920
bellard1fddef42005-04-17 19:16:13 +00002921#ifndef CONFIG_USER_ONLY
Damien Hedded116e812020-03-16 17:21:53 +00002922 if (gdbserver_state.last_packet->len) {
pbrook4046d912007-01-28 01:53:16 +00002923 /* Waiting for a response to the last packet. If we see the start
2924 of a new command then abandon the previous response. */
2925 if (ch == '-') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002926 trace_gdbstub_err_got_nack();
Damien Hedded116e812020-03-16 17:21:53 +00002927 put_buffer(gdbserver_state.last_packet->data,
2928 gdbserver_state.last_packet->len);
Alex Bennée118e2262017-07-12 11:52:13 +01002929 } else if (ch == '+') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002930 trace_gdbstub_io_got_ack();
Alex Bennée118e2262017-07-12 11:52:13 +01002931 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002932 trace_gdbstub_io_got_unexpected(ch);
pbrook4046d912007-01-28 01:53:16 +00002933 }
Alex Bennée118e2262017-07-12 11:52:13 +01002934
Damien Hedded116e812020-03-16 17:21:53 +00002935 if (ch == '+' || ch == '$') {
2936 g_byte_array_set_size(gdbserver_state.last_packet, 0);
2937 }
pbrook4046d912007-01-28 01:53:16 +00002938 if (ch != '$')
2939 return;
2940 }
Luiz Capitulino13548692011-07-29 15:36:43 -03002941 if (runstate_is_running()) {
bellard858693c2004-03-31 18:52:07 +00002942 /* when the CPU is running, we cannot do anything except stop
2943 it when receiving a char */
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002944 vm_stop(RUN_STATE_PAUSED);
ths5fafdf22007-09-16 21:08:06 +00002945 } else
bellard1fddef42005-04-17 19:16:13 +00002946#endif
bellard41625032005-04-24 10:07:11 +00002947 {
Alex Bennéea346af32020-03-16 17:21:34 +00002948 switch(gdbserver_state.state) {
bellard858693c2004-03-31 18:52:07 +00002949 case RS_IDLE:
2950 if (ch == '$') {
Doug Gale4bf43122017-05-01 12:22:10 -04002951 /* start of command packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002952 gdbserver_state.line_buf_index = 0;
2953 gdbserver_state.line_sum = 0;
2954 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002955 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002956 trace_gdbstub_err_garbage(ch);
bellard4c3a88a2003-07-26 12:06:08 +00002957 }
2958 break;
bellard858693c2004-03-31 18:52:07 +00002959 case RS_GETLINE:
Doug Gale4bf43122017-05-01 12:22:10 -04002960 if (ch == '}') {
2961 /* start escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002962 gdbserver_state.state = RS_GETLINE_ESC;
2963 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002964 } else if (ch == '*') {
2965 /* start run length encoding sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002966 gdbserver_state.state = RS_GETLINE_RLE;
2967 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002968 } else if (ch == '#') {
2969 /* end of command, start of checksum*/
Alex Bennéea346af32020-03-16 17:21:34 +00002970 gdbserver_state.state = RS_CHKSUM1;
2971 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale5c9522b2017-12-02 20:30:37 -05002972 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00002973 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00002974 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04002975 /* unescaped command character */
Alex Bennéea346af32020-03-16 17:21:34 +00002976 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
2977 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002978 }
2979 break;
2980 case RS_GETLINE_ESC:
2981 if (ch == '#') {
2982 /* unexpected end of command in escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002983 gdbserver_state.state = RS_CHKSUM1;
2984 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04002985 /* command buffer overrun */
Doug Gale5c9522b2017-12-02 20:30:37 -05002986 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00002987 gdbserver_state.state = RS_IDLE;
Doug Gale4bf43122017-05-01 12:22:10 -04002988 } else {
2989 /* parse escaped character and leave escape state */
Alex Bennéea346af32020-03-16 17:21:34 +00002990 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
2991 gdbserver_state.line_sum += ch;
2992 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002993 }
2994 break;
2995 case RS_GETLINE_RLE:
Markus Armbruster046aba12019-05-14 20:03:08 +02002996 /*
2997 * Run-length encoding is explained in "Debugging with GDB /
2998 * Appendix E GDB Remote Serial Protocol / Overview".
2999 */
3000 if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
Doug Gale4bf43122017-05-01 12:22:10 -04003001 /* invalid RLE count encoding */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003002 trace_gdbstub_err_invalid_repeat(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003003 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003004 } else {
3005 /* decode repeat length */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003006 int repeat = ch - ' ' + 3;
Alex Bennéea346af32020-03-16 17:21:34 +00003007 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003008 /* that many repeats would overrun the command buffer */
Doug Gale5c9522b2017-12-02 20:30:37 -05003009 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003010 gdbserver_state.state = RS_IDLE;
3011 } else if (gdbserver_state.line_buf_index < 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003012 /* got a repeat but we have nothing to repeat */
Doug Gale5c9522b2017-12-02 20:30:37 -05003013 trace_gdbstub_err_invalid_rle();
Alex Bennéea346af32020-03-16 17:21:34 +00003014 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003015 } else {
3016 /* repeat the last character */
Alex Bennéea346af32020-03-16 17:21:34 +00003017 memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
3018 gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
3019 gdbserver_state.line_buf_index += repeat;
3020 gdbserver_state.line_sum += ch;
3021 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003022 }
bellard858693c2004-03-31 18:52:07 +00003023 }
3024 break;
3025 case RS_CHKSUM1:
Doug Gale4bf43122017-05-01 12:22:10 -04003026 /* get high hex digit of checksum */
3027 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003028 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003029 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003030 break;
3031 }
Alex Bennéea346af32020-03-16 17:21:34 +00003032 gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
3033 gdbserver_state.line_csum = fromhex(ch) << 4;
3034 gdbserver_state.state = RS_CHKSUM2;
bellard858693c2004-03-31 18:52:07 +00003035 break;
3036 case RS_CHKSUM2:
Doug Gale4bf43122017-05-01 12:22:10 -04003037 /* get low hex digit of checksum */
3038 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003039 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003040 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003041 break;
bellard858693c2004-03-31 18:52:07 +00003042 }
Alex Bennéea346af32020-03-16 17:21:34 +00003043 gdbserver_state.line_csum |= fromhex(ch);
Doug Gale4bf43122017-05-01 12:22:10 -04003044
Alex Bennéea346af32020-03-16 17:21:34 +00003045 if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
3046 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
Doug Gale4bf43122017-05-01 12:22:10 -04003047 /* send NAK reply */
ths60fe76f2007-12-16 03:02:09 +00003048 reply = '-';
Alex Bennéea346af32020-03-16 17:21:34 +00003049 put_buffer(&reply, 1);
3050 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003051 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003052 /* send ACK reply */
ths60fe76f2007-12-16 03:02:09 +00003053 reply = '+';
Alex Bennéea346af32020-03-16 17:21:34 +00003054 put_buffer(&reply, 1);
3055 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
bellard858693c2004-03-31 18:52:07 +00003056 }
bellardb4608c02003-06-27 17:34:32 +00003057 break;
pbrooka2d1eba2007-01-28 03:10:55 +00003058 default:
3059 abort();
bellardb4608c02003-06-27 17:34:32 +00003060 }
3061 }
bellard858693c2004-03-31 18:52:07 +00003062}
3063
Paul Brook0e1c9c52010-06-16 13:03:51 +01003064/* Tell the remote gdb that the process has exited. */
Alex Bennéead9dcb22021-01-08 22:42:43 +00003065void gdb_exit(int code)
Paul Brook0e1c9c52010-06-16 13:03:51 +01003066{
Paul Brook0e1c9c52010-06-16 13:03:51 +01003067 char buf[4];
3068
Alex Bennée8d98c442020-03-16 17:21:33 +00003069 if (!gdbserver_state.init) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003070 return;
3071 }
3072#ifdef CONFIG_USER_ONLY
Alex Bennéefcedd922020-04-30 20:01:19 +01003073 if (gdbserver_state.socket_path) {
3074 unlink(gdbserver_state.socket_path);
3075 }
Alex Bennéee0a1e202020-04-30 20:01:18 +01003076 if (gdbserver_state.fd < 0) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003077 return;
3078 }
3079#endif
3080
Doug Gale5c9522b2017-12-02 20:30:37 -05003081 trace_gdbstub_op_exiting((uint8_t)code);
3082
Paul Brook0e1c9c52010-06-16 13:03:51 +01003083 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
Alex Bennéea346af32020-03-16 17:21:34 +00003084 put_packet(buf);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003085
3086#ifndef CONFIG_USER_ONLY
Alex Bennée8d98c442020-03-16 17:21:33 +00003087 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003088#endif
Paul Brook0e1c9c52010-06-16 13:03:51 +01003089}
3090
Luc Michel8f468632019-01-07 15:23:45 +00003091/*
3092 * Create the process that will contain all the "orphan" CPUs (that are not
3093 * part of a CPU cluster). Note that if this process contains no CPUs, it won't
3094 * be attachable and thus will be invisible to the user.
3095 */
3096static void create_default_process(GDBState *s)
3097{
3098 GDBProcess *process;
3099 int max_pid = 0;
3100
Alex Bennéea346af32020-03-16 17:21:34 +00003101 if (gdbserver_state.process_num) {
Luc Michel8f468632019-01-07 15:23:45 +00003102 max_pid = s->processes[s->process_num - 1].pid;
3103 }
3104
3105 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3106 process = &s->processes[s->process_num - 1];
3107
3108 /* We need an available PID slot for this process */
3109 assert(max_pid < UINT32_MAX);
3110
3111 process->pid = max_pid + 1;
3112 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003113 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003114}
3115
bellard1fddef42005-04-17 19:16:13 +00003116#ifdef CONFIG_USER_ONLY
3117int
Andreas Färberdb6b81d2013-06-27 19:49:31 +02003118gdb_handlesig(CPUState *cpu, int sig)
bellard1fddef42005-04-17 19:16:13 +00003119{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003120 char buf[256];
3121 int n;
bellard1fddef42005-04-17 19:16:13 +00003122
Alex Bennéee0a1e202020-04-30 20:01:18 +01003123 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003124 return sig;
bellard1fddef42005-04-17 19:16:13 +00003125 }
3126
Andreas Färber5ca666c2013-06-24 19:20:57 +02003127 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02003128 cpu_single_step(cpu, 0);
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07003129 tb_flush(cpu);
bellard1fddef42005-04-17 19:16:13 +00003130
Andreas Färber5ca666c2013-06-24 19:20:57 +02003131 if (sig != 0) {
3132 snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003133 put_packet(buf);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003134 }
3135 /* put_packet() might have detected that the peer terminated the
3136 connection. */
Alex Bennée8d98c442020-03-16 17:21:33 +00003137 if (gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003138 return sig;
3139 }
3140
3141 sig = 0;
Alex Bennée8d98c442020-03-16 17:21:33 +00003142 gdbserver_state.state = RS_IDLE;
3143 gdbserver_state.running_state = 0;
3144 while (gdbserver_state.running_state == 0) {
3145 n = read(gdbserver_state.fd, buf, 256);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003146 if (n > 0) {
3147 int i;
3148
3149 for (i = 0; i < n; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003150 gdb_read_byte(buf[i]);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003151 }
Peter Wu5819e3e2016-06-05 16:35:48 +02003152 } else {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003153 /* XXX: Connection closed. Should probably wait for another
3154 connection before continuing. */
Peter Wu5819e3e2016-06-05 16:35:48 +02003155 if (n == 0) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003156 close(gdbserver_state.fd);
Peter Wu5819e3e2016-06-05 16:35:48 +02003157 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003158 gdbserver_state.fd = -1;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003159 return sig;
bellard1fddef42005-04-17 19:16:13 +00003160 }
Andreas Färber5ca666c2013-06-24 19:20:57 +02003161 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003162 sig = gdbserver_state.signal;
3163 gdbserver_state.signal = 0;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003164 return sig;
bellard1fddef42005-04-17 19:16:13 +00003165}
bellarde9009672005-04-26 20:42:36 +00003166
aurel32ca587a82008-12-18 22:44:13 +00003167/* Tell the remote gdb that the process has exited due to SIG. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01003168void gdb_signalled(CPUArchState *env, int sig)
aurel32ca587a82008-12-18 22:44:13 +00003169{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003170 char buf[4];
aurel32ca587a82008-12-18 22:44:13 +00003171
Alex Bennéee0a1e202020-04-30 20:01:18 +01003172 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003173 return;
3174 }
aurel32ca587a82008-12-18 22:44:13 +00003175
Andreas Färber5ca666c2013-06-24 19:20:57 +02003176 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003177 put_packet(buf);
aurel32ca587a82008-12-18 22:44:13 +00003178}
bellard1fddef42005-04-17 19:16:13 +00003179
Alex Bennéefcedd922020-04-30 20:01:19 +01003180static void gdb_accept_init(int fd)
3181{
3182 init_gdbserver_state();
3183 create_default_process(&gdbserver_state);
3184 gdbserver_state.processes[0].attached = true;
3185 gdbserver_state.c_cpu = gdb_first_attached_cpu();
3186 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
3187 gdbserver_state.fd = fd;
3188 gdb_has_xml = false;
3189}
3190
3191static bool gdb_accept_socket(int gdb_fd)
3192{
3193 int fd;
3194
3195 for(;;) {
3196 fd = accept(gdb_fd, NULL, NULL);
3197 if (fd < 0 && errno != EINTR) {
3198 perror("accept socket");
3199 return false;
3200 } else if (fd >= 0) {
3201 qemu_set_cloexec(fd);
3202 break;
3203 }
3204 }
3205
3206 gdb_accept_init(fd);
3207 return true;
3208}
3209
3210static int gdbserver_open_socket(const char *path)
3211{
3212 struct sockaddr_un sockaddr;
3213 int fd, ret;
3214
3215 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3216 if (fd < 0) {
3217 perror("create socket");
3218 return -1;
3219 }
3220
3221 sockaddr.sun_family = AF_UNIX;
3222 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
3223 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3224 if (ret < 0) {
3225 perror("bind socket");
3226 close(fd);
3227 return -1;
3228 }
3229 ret = listen(fd, 1);
3230 if (ret < 0) {
3231 perror("listen socket");
3232 close(fd);
3233 return -1;
3234 }
3235
3236 return fd;
3237}
3238
3239static bool gdb_accept_tcp(int gdb_fd)
bellard858693c2004-03-31 18:52:07 +00003240{
bellard858693c2004-03-31 18:52:07 +00003241 struct sockaddr_in sockaddr;
3242 socklen_t len;
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09003243 int fd;
bellard858693c2004-03-31 18:52:07 +00003244
3245 for(;;) {
3246 len = sizeof(sockaddr);
Alex Bennéee0a1e202020-04-30 20:01:18 +01003247 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
bellard858693c2004-03-31 18:52:07 +00003248 if (fd < 0 && errno != EINTR) {
3249 perror("accept");
Peter Maydell2f652222018-05-14 18:30:44 +01003250 return false;
bellard858693c2004-03-31 18:52:07 +00003251 } else if (fd >= 0) {
Peter Maydellf5bdd782018-05-14 18:30:43 +01003252 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003253 break;
3254 }
3255 }
3256
3257 /* set short latency */
Peter Maydell2f652222018-05-14 18:30:44 +01003258 if (socket_set_nodelay(fd)) {
3259 perror("setsockopt");
Philippe Mathieu-Daudéead75d82018-05-24 19:34:58 -03003260 close(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003261 return false;
3262 }
ths3b46e622007-09-17 08:09:54 +00003263
Alex Bennéefcedd922020-04-30 20:01:19 +01003264 gdb_accept_init(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003265 return true;
bellard858693c2004-03-31 18:52:07 +00003266}
3267
Alex Bennéefcedd922020-04-30 20:01:19 +01003268static int gdbserver_open_port(int port)
bellard858693c2004-03-31 18:52:07 +00003269{
3270 struct sockaddr_in sockaddr;
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003271 int fd, ret;
bellard858693c2004-03-31 18:52:07 +00003272
3273 fd = socket(PF_INET, SOCK_STREAM, 0);
3274 if (fd < 0) {
3275 perror("socket");
3276 return -1;
3277 }
Peter Maydellf5bdd782018-05-14 18:30:43 +01003278 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003279
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003280 socket_set_fast_reuse(fd);
bellard858693c2004-03-31 18:52:07 +00003281
3282 sockaddr.sin_family = AF_INET;
3283 sockaddr.sin_port = htons(port);
3284 sockaddr.sin_addr.s_addr = 0;
3285 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3286 if (ret < 0) {
3287 perror("bind");
Peter Maydellbb161722011-12-24 23:37:24 +00003288 close(fd);
bellard858693c2004-03-31 18:52:07 +00003289 return -1;
3290 }
Peter Wu96165b92016-05-04 11:32:17 +02003291 ret = listen(fd, 1);
bellard858693c2004-03-31 18:52:07 +00003292 if (ret < 0) {
3293 perror("listen");
Peter Maydellbb161722011-12-24 23:37:24 +00003294 close(fd);
bellard858693c2004-03-31 18:52:07 +00003295 return -1;
3296 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003297
bellard858693c2004-03-31 18:52:07 +00003298 return fd;
3299}
3300
Alex Bennéefcedd922020-04-30 20:01:19 +01003301int gdbserver_start(const char *port_or_path)
bellard858693c2004-03-31 18:52:07 +00003302{
Alex Bennéefcedd922020-04-30 20:01:19 +01003303 int port = g_ascii_strtoull(port_or_path, NULL, 10);
3304 int gdb_fd;
3305
3306 if (port > 0) {
3307 gdb_fd = gdbserver_open_port(port);
3308 } else {
3309 gdb_fd = gdbserver_open_socket(port_or_path);
3310 }
3311
Alex Bennéee0a1e202020-04-30 20:01:18 +01003312 if (gdb_fd < 0) {
bellard858693c2004-03-31 18:52:07 +00003313 return -1;
Alex Bennéee0a1e202020-04-30 20:01:18 +01003314 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003315
3316 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3317 return 0;
3318 } else if (gdb_accept_socket(gdb_fd)) {
3319 gdbserver_state.socket_path = g_strdup(port_or_path);
3320 return 0;
Peter Maydell2f652222018-05-14 18:30:44 +01003321 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003322
3323 /* gone wrong */
3324 close(gdb_fd);
3325 return -1;
bellardb4608c02003-06-27 17:34:32 +00003326}
aurel322b1319c2008-12-18 22:44:04 +00003327
3328/* Disable gdb stub for child processes. */
Peter Crosthwaitef7ec7f72015-06-23 19:31:16 -07003329void gdbserver_fork(CPUState *cpu)
aurel322b1319c2008-12-18 22:44:04 +00003330{
Alex Bennéee0a1e202020-04-30 20:01:18 +01003331 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber75a34032013-09-02 16:57:02 +02003332 return;
3333 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003334 close(gdbserver_state.fd);
3335 gdbserver_state.fd = -1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02003336 cpu_breakpoint_remove_all(cpu, BP_GDB);
Andreas Färber75a34032013-09-02 16:57:02 +02003337 cpu_watchpoint_remove_all(cpu, BP_GDB);
aurel322b1319c2008-12-18 22:44:04 +00003338}
pbrook4046d912007-01-28 01:53:16 +00003339#else
thsaa1f17c2007-07-11 22:48:58 +00003340static int gdb_chr_can_receive(void *opaque)
pbrook4046d912007-01-28 01:53:16 +00003341{
pbrook56aebc82008-10-11 17:55:29 +00003342 /* We can handle an arbitrarily large amount of data.
3343 Pick the maximum packet size, which is as good as anything. */
3344 return MAX_PACKET_LENGTH;
pbrook4046d912007-01-28 01:53:16 +00003345}
3346
thsaa1f17c2007-07-11 22:48:58 +00003347static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
pbrook4046d912007-01-28 01:53:16 +00003348{
pbrook4046d912007-01-28 01:53:16 +00003349 int i;
3350
3351 for (i = 0; i < size; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003352 gdb_read_byte(buf[i]);
pbrook4046d912007-01-28 01:53:16 +00003353 }
3354}
3355
Philippe Mathieu-Daudé083b2662019-12-18 18:20:09 +01003356static void gdb_chr_event(void *opaque, QEMUChrEvent event)
pbrook4046d912007-01-28 01:53:16 +00003357{
Luc Michel970ed902019-01-07 15:23:46 +00003358 int i;
3359 GDBState *s = (GDBState *) opaque;
3360
pbrook4046d912007-01-28 01:53:16 +00003361 switch (event) {
Amit Shahb6b8df52009-10-07 18:31:16 +05303362 case CHR_EVENT_OPENED:
Luc Michel970ed902019-01-07 15:23:46 +00003363 /* Start with first process attached, others detached */
3364 for (i = 0; i < s->process_num; i++) {
3365 s->processes[i].attached = !i;
3366 }
3367
Alex Bennéea346af32020-03-16 17:21:34 +00003368 s->c_cpu = gdb_first_attached_cpu();
Luc Michel970ed902019-01-07 15:23:46 +00003369 s->g_cpu = s->c_cpu;
3370
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003371 vm_stop(RUN_STATE_PAUSED);
Pavel Dovgalyuk56357d82020-10-03 20:14:01 +03003372 replay_gdb_attached();
Andreas Färber5b50e792013-06-29 04:18:45 +02003373 gdb_has_xml = false;
pbrook4046d912007-01-28 01:53:16 +00003374 break;
3375 default:
3376 break;
3377 }
3378}
3379
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003380static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
aliguori8a34a0f2009-03-05 23:01:55 +00003381{
Damien Hedded86b4672020-03-16 17:21:54 +00003382 g_autoptr(GString) hex_buf = g_string_new("O");
3383 memtohex(hex_buf, buf, len);
3384 put_packet(hex_buf->str);
aliguori8a34a0f2009-03-05 23:01:55 +00003385 return len;
3386}
3387
aliguori59030a82009-04-05 18:43:41 +00003388#ifndef _WIN32
3389static void gdb_sigterm_handler(int signal)
3390{
Luiz Capitulino13548692011-07-29 15:36:43 -03003391 if (runstate_is_running()) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003392 vm_stop(RUN_STATE_PAUSED);
Jan Kiszkae07bbac2011-02-09 16:29:40 +01003393 }
aliguori59030a82009-04-05 18:43:41 +00003394}
3395#endif
3396
Marc-André Lureau777357d2016-12-07 18:39:10 +03003397static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
3398 bool *be_opened, Error **errp)
3399{
3400 *be_opened = false;
3401}
3402
3403static void char_gdb_class_init(ObjectClass *oc, void *data)
3404{
3405 ChardevClass *cc = CHARDEV_CLASS(oc);
3406
3407 cc->internal = true;
3408 cc->open = gdb_monitor_open;
3409 cc->chr_write = gdb_monitor_write;
3410}
3411
3412#define TYPE_CHARDEV_GDB "chardev-gdb"
3413
3414static const TypeInfo char_gdb_type_info = {
3415 .name = TYPE_CHARDEV_GDB,
3416 .parent = TYPE_CHARDEV,
3417 .class_init = char_gdb_class_init,
3418};
3419
Luc Michel8f468632019-01-07 15:23:45 +00003420static int find_cpu_clusters(Object *child, void *opaque)
3421{
3422 if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
3423 GDBState *s = (GDBState *) opaque;
3424 CPUClusterState *cluster = CPU_CLUSTER(child);
3425 GDBProcess *process;
3426
3427 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3428
3429 process = &s->processes[s->process_num - 1];
3430
3431 /*
3432 * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
3433 * runtime, we enforce here that the machine does not use a cluster ID
3434 * that would lead to PID 0.
3435 */
3436 assert(cluster->cluster_id != UINT32_MAX);
3437 process->pid = cluster->cluster_id + 1;
3438 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003439 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003440
3441 return 0;
3442 }
3443
3444 return object_child_foreach(child, find_cpu_clusters, opaque);
3445}
3446
3447static int pid_order(const void *a, const void *b)
3448{
3449 GDBProcess *pa = (GDBProcess *) a;
3450 GDBProcess *pb = (GDBProcess *) b;
3451
3452 if (pa->pid < pb->pid) {
3453 return -1;
3454 } else if (pa->pid > pb->pid) {
3455 return 1;
3456 } else {
3457 return 0;
3458 }
3459}
3460
3461static void create_processes(GDBState *s)
3462{
3463 object_child_foreach(object_get_root(), find_cpu_clusters, s);
3464
Alex Bennéea346af32020-03-16 17:21:34 +00003465 if (gdbserver_state.processes) {
Luc Michel8f468632019-01-07 15:23:45 +00003466 /* Sort by PID */
Alex Bennéea346af32020-03-16 17:21:34 +00003467 qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
Luc Michel8f468632019-01-07 15:23:45 +00003468 }
3469
3470 create_default_process(s);
3471}
3472
aliguori59030a82009-04-05 18:43:41 +00003473int gdbserver_start(const char *device)
pbrook4046d912007-01-28 01:53:16 +00003474{
Doug Gale5c9522b2017-12-02 20:30:37 -05003475 trace_gdbstub_op_start(device);
3476
aliguori59030a82009-04-05 18:43:41 +00003477 char gdbstub_device_name[128];
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003478 Chardev *chr = NULL;
3479 Chardev *mon_chr;
pbrook4046d912007-01-28 01:53:16 +00003480
Ziyue Yang508b4ec2017-01-18 16:02:41 +08003481 if (!first_cpu) {
3482 error_report("gdbstub: meaningless to attach gdb to a "
3483 "machine without any CPU.");
3484 return -1;
3485 }
3486
aliguori59030a82009-04-05 18:43:41 +00003487 if (!device)
3488 return -1;
3489 if (strcmp(device, "none") != 0) {
3490 if (strstart(device, "tcp:", NULL)) {
3491 /* enforce required TCP attributes */
3492 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
Paolo Bonzinia9b13152021-02-25 11:47:52 +01003493 "%s,wait=off,nodelay=on,server=on", device);
aliguori59030a82009-04-05 18:43:41 +00003494 device = gdbstub_device_name;
aliguori36556b22009-03-28 18:05:53 +00003495 }
aliguori59030a82009-04-05 18:43:41 +00003496#ifndef _WIN32
3497 else if (strcmp(device, "stdio") == 0) {
3498 struct sigaction act;
pbrookcfc34752007-02-22 01:48:01 +00003499
aliguori59030a82009-04-05 18:43:41 +00003500 memset(&act, 0, sizeof(act));
3501 act.sa_handler = gdb_sigterm_handler;
3502 sigaction(SIGINT, &act, NULL);
3503 }
3504#endif
Marc-André Lureau95e30b22018-08-22 19:19:42 +02003505 /*
3506 * FIXME: it's a bit weird to allow using a mux chardev here
3507 * and implicitly setup a monitor. We may want to break this.
3508 */
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003509 chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
aliguori36556b22009-03-28 18:05:53 +00003510 if (!chr)
3511 return -1;
pbrookcfc34752007-02-22 01:48:01 +00003512 }
3513
Alex Bennée8d98c442020-03-16 17:21:33 +00003514 if (!gdbserver_state.init) {
3515 init_gdbserver_state();
pbrook4046d912007-01-28 01:53:16 +00003516
aliguori36556b22009-03-28 18:05:53 +00003517 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
3518
3519 /* Initialize a monitor terminal for gdb */
Marc-André Lureau777357d2016-12-07 18:39:10 +03003520 mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003521 NULL, NULL, &error_abort);
Kevin Wolf8e9119a2020-02-24 15:30:06 +01003522 monitor_init_hmp(mon_chr, false, &error_abort);
aliguori36556b22009-03-28 18:05:53 +00003523 } else {
Alex Bennée8d98c442020-03-16 17:21:33 +00003524 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
3525 mon_chr = gdbserver_state.mon_chr;
3526 reset_gdbserver_state();
aliguori36556b22009-03-28 18:05:53 +00003527 }
Luc Michel8f468632019-01-07 15:23:45 +00003528
Alex Bennée8d98c442020-03-16 17:21:33 +00003529 create_processes(&gdbserver_state);
Luc Michel8f468632019-01-07 15:23:45 +00003530
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003531 if (chr) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003532 qemu_chr_fe_init(&gdbserver_state.chr, chr, &error_abort);
3533 qemu_chr_fe_set_handlers(&gdbserver_state.chr, gdb_chr_can_receive,
3534 gdb_chr_receive, gdb_chr_event,
3535 NULL, &gdbserver_state, NULL, true);
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003536 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003537 gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
3538 gdbserver_state.mon_chr = mon_chr;
3539 gdbserver_state.current_syscall_cb = NULL;
aliguori8a34a0f2009-03-05 23:01:55 +00003540
pbrook4046d912007-01-28 01:53:16 +00003541 return 0;
3542}
Marc-André Lureau777357d2016-12-07 18:39:10 +03003543
3544static void register_types(void)
3545{
3546 type_register_static(&char_gdb_type_info);
3547}
3548
3549type_init(register_types);
pbrook4046d912007-01-28 01:53:16 +00003550#endif