blob: a3ff8702cefb6fad0965f568a35c6cda9fee32a0 [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 Armbrusterda34e652016-03-14 09:01:28 +010027#include "qapi/error.h"
Ziyue Yang508b4ec2017-01-18 16:02:41 +080028#include "qemu/error-report.h"
Markus Armbruster856dfd82019-05-23 16:35:06 +020029#include "qemu/ctype.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020030#include "qemu/cutils.h"
Markus Armbruster0b8fa322019-05-23 16:35:07 +020031#include "qemu/module.h"
Paolo Bonzini243af022020-02-04 12:20:10 +010032#include "trace/trace-root.h"
Peter Maydell85b4fa02021-09-08 16:44:04 +010033#include "exec/gdbstub.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"
Luc Michel8f468632019-01-07 15:23:45 +000040#include "hw/cpu/cluster.h"
Like Xu5cc87672019-05-19 04:54:21 +080041#include "hw/boards.h"
bellard1fddef42005-04-17 19:16:13 +000042#endif
bellard67b915a2004-03-31 23:37:16 +000043
pbrook56aebc82008-10-11 17:55:29 +000044#define MAX_PACKET_LENGTH 4096
45
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010046#include "qemu/sockets.h"
Vincent Palatinb3946622017-01-10 11:59:55 +010047#include "sysemu/hw_accel.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010048#include "sysemu/kvm.h"
Markus Armbruster54d31232019-08-12 07:23:59 +020049#include "sysemu/runstate.h"
Philippe Mathieu-Daudé6b5fe132021-03-05 13:54:49 +000050#include "semihosting/semihost.h"
Paolo Bonzini63c91552016-03-15 13:18:37 +010051#include "exec/exec-all.h"
Pavel Dovgalyukfda84582020-10-03 20:13:43 +030052#include "sysemu/replay.h"
aurel32ca587a82008-12-18 22:44:13 +000053
Jan Kiszkaa3919382015-02-07 09:38:44 +010054#ifdef CONFIG_USER_ONLY
55#define GDB_ATTACHED "0"
56#else
57#define GDB_ATTACHED "1"
58#endif
59
Jon Doronab4752e2019-05-29 09:41:48 +030060#ifndef CONFIG_USER_ONLY
61static int phy_memory_mode;
62#endif
63
Andreas Färberf3659ee2013-06-27 19:09:09 +020064static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
65 uint8_t *buf, int len, bool is_write)
Fabien Chouteau44520db2011-09-08 12:48:16 +020066{
Jon Doronab4752e2019-05-29 09:41:48 +030067 CPUClass *cc;
Andreas Färberf3659ee2013-06-27 19:09:09 +020068
Jon Doronab4752e2019-05-29 09:41:48 +030069#ifndef CONFIG_USER_ONLY
70 if (phy_memory_mode) {
71 if (is_write) {
72 cpu_physical_memory_write(addr, buf, len);
73 } else {
74 cpu_physical_memory_read(addr, buf, len);
75 }
76 return 0;
77 }
78#endif
79
80 cc = CPU_GET_CLASS(cpu);
Andreas Färberf3659ee2013-06-27 19:09:09 +020081 if (cc->memory_rw_debug) {
82 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
83 }
84 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
Fabien Chouteau44520db2011-09-08 12:48:16 +020085}
aurel32ca587a82008-12-18 22:44:13 +000086
Alex Bennéed2a6c852017-07-12 11:52:14 +010087/* Return the GDB index for a given vCPU state.
88 *
89 * For user mode this is simply the thread id. In system mode GDB
90 * numbers CPUs from 1 as 0 is reserved as an "any cpu" index.
91 */
92static inline int cpu_gdb_index(CPUState *cpu)
93{
94#if defined(CONFIG_USER_ONLY)
Alex Bennéebd88c782017-07-12 11:52:15 +010095 TaskState *ts = (TaskState *) cpu->opaque;
Alex Bennéea8e537f2021-11-29 14:09:29 +000096 return ts ? ts->ts_tid : -1;
Alex Bennéed2a6c852017-07-12 11:52:14 +010097#else
98 return cpu->cpu_index + 1;
99#endif
100}
101
aurel32ca587a82008-12-18 22:44:13 +0000102enum {
103 GDB_SIGNAL_0 = 0,
104 GDB_SIGNAL_INT = 2,
Jan Kiszka425189a2011-03-22 11:02:09 +0100105 GDB_SIGNAL_QUIT = 3,
aurel32ca587a82008-12-18 22:44:13 +0000106 GDB_SIGNAL_TRAP = 5,
Jan Kiszka425189a2011-03-22 11:02:09 +0100107 GDB_SIGNAL_ABRT = 6,
108 GDB_SIGNAL_ALRM = 14,
109 GDB_SIGNAL_IO = 23,
110 GDB_SIGNAL_XCPU = 24,
aurel32ca587a82008-12-18 22:44:13 +0000111 GDB_SIGNAL_UNKNOWN = 143
112};
113
114#ifdef CONFIG_USER_ONLY
115
116/* Map target signal numbers to GDB protocol signal numbers and vice
117 * versa. For user emulation's currently supported systems, we can
118 * assume most signals are defined.
119 */
120
121static int gdb_signal_table[] = {
122 0,
123 TARGET_SIGHUP,
124 TARGET_SIGINT,
125 TARGET_SIGQUIT,
126 TARGET_SIGILL,
127 TARGET_SIGTRAP,
128 TARGET_SIGABRT,
129 -1, /* SIGEMT */
130 TARGET_SIGFPE,
131 TARGET_SIGKILL,
132 TARGET_SIGBUS,
133 TARGET_SIGSEGV,
134 TARGET_SIGSYS,
135 TARGET_SIGPIPE,
136 TARGET_SIGALRM,
137 TARGET_SIGTERM,
138 TARGET_SIGURG,
139 TARGET_SIGSTOP,
140 TARGET_SIGTSTP,
141 TARGET_SIGCONT,
142 TARGET_SIGCHLD,
143 TARGET_SIGTTIN,
144 TARGET_SIGTTOU,
145 TARGET_SIGIO,
146 TARGET_SIGXCPU,
147 TARGET_SIGXFSZ,
148 TARGET_SIGVTALRM,
149 TARGET_SIGPROF,
150 TARGET_SIGWINCH,
151 -1, /* SIGLOST */
152 TARGET_SIGUSR1,
153 TARGET_SIGUSR2,
blueswir1c72d5bf2009-01-15 17:27:45 +0000154#ifdef TARGET_SIGPWR
aurel32ca587a82008-12-18 22:44:13 +0000155 TARGET_SIGPWR,
blueswir1c72d5bf2009-01-15 17:27:45 +0000156#else
157 -1,
158#endif
aurel32ca587a82008-12-18 22:44:13 +0000159 -1, /* SIGPOLL */
160 -1,
161 -1,
162 -1,
163 -1,
164 -1,
165 -1,
166 -1,
167 -1,
168 -1,
169 -1,
170 -1,
blueswir1c72d5bf2009-01-15 17:27:45 +0000171#ifdef __SIGRTMIN
aurel32ca587a82008-12-18 22:44:13 +0000172 __SIGRTMIN + 1,
173 __SIGRTMIN + 2,
174 __SIGRTMIN + 3,
175 __SIGRTMIN + 4,
176 __SIGRTMIN + 5,
177 __SIGRTMIN + 6,
178 __SIGRTMIN + 7,
179 __SIGRTMIN + 8,
180 __SIGRTMIN + 9,
181 __SIGRTMIN + 10,
182 __SIGRTMIN + 11,
183 __SIGRTMIN + 12,
184 __SIGRTMIN + 13,
185 __SIGRTMIN + 14,
186 __SIGRTMIN + 15,
187 __SIGRTMIN + 16,
188 __SIGRTMIN + 17,
189 __SIGRTMIN + 18,
190 __SIGRTMIN + 19,
191 __SIGRTMIN + 20,
192 __SIGRTMIN + 21,
193 __SIGRTMIN + 22,
194 __SIGRTMIN + 23,
195 __SIGRTMIN + 24,
196 __SIGRTMIN + 25,
197 __SIGRTMIN + 26,
198 __SIGRTMIN + 27,
199 __SIGRTMIN + 28,
200 __SIGRTMIN + 29,
201 __SIGRTMIN + 30,
202 __SIGRTMIN + 31,
203 -1, /* SIGCANCEL */
204 __SIGRTMIN,
205 __SIGRTMIN + 32,
206 __SIGRTMIN + 33,
207 __SIGRTMIN + 34,
208 __SIGRTMIN + 35,
209 __SIGRTMIN + 36,
210 __SIGRTMIN + 37,
211 __SIGRTMIN + 38,
212 __SIGRTMIN + 39,
213 __SIGRTMIN + 40,
214 __SIGRTMIN + 41,
215 __SIGRTMIN + 42,
216 __SIGRTMIN + 43,
217 __SIGRTMIN + 44,
218 __SIGRTMIN + 45,
219 __SIGRTMIN + 46,
220 __SIGRTMIN + 47,
221 __SIGRTMIN + 48,
222 __SIGRTMIN + 49,
223 __SIGRTMIN + 50,
224 __SIGRTMIN + 51,
225 __SIGRTMIN + 52,
226 __SIGRTMIN + 53,
227 __SIGRTMIN + 54,
228 __SIGRTMIN + 55,
229 __SIGRTMIN + 56,
230 __SIGRTMIN + 57,
231 __SIGRTMIN + 58,
232 __SIGRTMIN + 59,
233 __SIGRTMIN + 60,
234 __SIGRTMIN + 61,
235 __SIGRTMIN + 62,
236 __SIGRTMIN + 63,
237 __SIGRTMIN + 64,
238 __SIGRTMIN + 65,
239 __SIGRTMIN + 66,
240 __SIGRTMIN + 67,
241 __SIGRTMIN + 68,
242 __SIGRTMIN + 69,
243 __SIGRTMIN + 70,
244 __SIGRTMIN + 71,
245 __SIGRTMIN + 72,
246 __SIGRTMIN + 73,
247 __SIGRTMIN + 74,
248 __SIGRTMIN + 75,
249 __SIGRTMIN + 76,
250 __SIGRTMIN + 77,
251 __SIGRTMIN + 78,
252 __SIGRTMIN + 79,
253 __SIGRTMIN + 80,
254 __SIGRTMIN + 81,
255 __SIGRTMIN + 82,
256 __SIGRTMIN + 83,
257 __SIGRTMIN + 84,
258 __SIGRTMIN + 85,
259 __SIGRTMIN + 86,
260 __SIGRTMIN + 87,
261 __SIGRTMIN + 88,
262 __SIGRTMIN + 89,
263 __SIGRTMIN + 90,
264 __SIGRTMIN + 91,
265 __SIGRTMIN + 92,
266 __SIGRTMIN + 93,
267 __SIGRTMIN + 94,
268 __SIGRTMIN + 95,
269 -1, /* SIGINFO */
270 -1, /* UNKNOWN */
271 -1, /* DEFAULT */
272 -1,
273 -1,
274 -1,
275 -1,
276 -1,
277 -1
blueswir1c72d5bf2009-01-15 17:27:45 +0000278#endif
aurel32ca587a82008-12-18 22:44:13 +0000279};
bellard8f447cc2006-06-14 15:21:14 +0000280#else
aurel32ca587a82008-12-18 22:44:13 +0000281/* In system mode we only need SIGINT and SIGTRAP; other signals
282 are not yet supported. */
283
284enum {
285 TARGET_SIGINT = 2,
286 TARGET_SIGTRAP = 5
287};
288
289static int gdb_signal_table[] = {
290 -1,
291 -1,
292 TARGET_SIGINT,
293 -1,
294 -1,
295 TARGET_SIGTRAP
296};
bellard8f447cc2006-06-14 15:21:14 +0000297#endif
bellardb4608c02003-06-27 17:34:32 +0000298
aurel32ca587a82008-12-18 22:44:13 +0000299#ifdef CONFIG_USER_ONLY
300static int target_signal_to_gdb (int sig)
301{
302 int i;
303 for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
304 if (gdb_signal_table[i] == sig)
305 return i;
306 return GDB_SIGNAL_UNKNOWN;
307}
308#endif
309
310static int gdb_signal_to_target (int sig)
311{
312 if (sig < ARRAY_SIZE (gdb_signal_table))
313 return gdb_signal_table[sig];
314 else
315 return -1;
316}
317
pbrook56aebc82008-10-11 17:55:29 +0000318typedef struct GDBRegisterState {
319 int base_reg;
320 int num_regs;
Alex Bennéea010bdb2020-03-16 17:21:41 +0000321 gdb_get_reg_cb get_reg;
322 gdb_set_reg_cb set_reg;
pbrook56aebc82008-10-11 17:55:29 +0000323 const char *xml;
324 struct GDBRegisterState *next;
325} GDBRegisterState;
326
Luc Michel8f468632019-01-07 15:23:45 +0000327typedef struct GDBProcess {
328 uint32_t pid;
329 bool attached;
Luc Michelc145eea2019-01-07 15:23:46 +0000330
331 char target_xml[1024];
Luc Michel8f468632019-01-07 15:23:45 +0000332} GDBProcess;
333
bellard858693c2004-03-31 18:52:07 +0000334enum RSState {
aliguori36556b22009-03-28 18:05:53 +0000335 RS_INACTIVE,
bellard858693c2004-03-31 18:52:07 +0000336 RS_IDLE,
337 RS_GETLINE,
Doug Gale4bf43122017-05-01 12:22:10 -0400338 RS_GETLINE_ESC,
339 RS_GETLINE_RLE,
bellard858693c2004-03-31 18:52:07 +0000340 RS_CHKSUM1,
341 RS_CHKSUM2,
342};
bellard858693c2004-03-31 18:52:07 +0000343typedef struct GDBState {
Alex Bennée8d98c442020-03-16 17:21:33 +0000344 bool init; /* have we been initialised? */
Andreas Färber2e0f2cf2013-06-27 19:19:39 +0200345 CPUState *c_cpu; /* current CPU for step/continue ops */
346 CPUState *g_cpu; /* current CPU for other ops */
Andreas Färber52f34622013-06-27 13:44:40 +0200347 CPUState *query_cpu; /* for q{f|s}ThreadInfo */
bellard41625032005-04-24 10:07:11 +0000348 enum RSState state; /* parsing state */
pbrook56aebc82008-10-11 17:55:29 +0000349 char line_buf[MAX_PACKET_LENGTH];
bellard858693c2004-03-31 18:52:07 +0000350 int line_buf_index;
Doug Gale4bf43122017-05-01 12:22:10 -0400351 int line_sum; /* running checksum */
352 int line_csum; /* checksum at the end of the packet */
Damien Hedded116e812020-03-16 17:21:53 +0000353 GByteArray *last_packet;
edgar_igl1f487ee2008-05-17 22:20:53 +0000354 int signal;
bellard41625032005-04-24 10:07:11 +0000355#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000356 int fd;
Alex Bennéefcedd922020-04-30 20:01:19 +0100357 char *socket_path;
bellard41625032005-04-24 10:07:11 +0000358 int running_state;
pbrook4046d912007-01-28 01:53:16 +0000359#else
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +0300360 CharBackend chr;
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +0300361 Chardev *mon_chr;
bellard41625032005-04-24 10:07:11 +0000362#endif
Luc Michel8f468632019-01-07 15:23:45 +0000363 bool multiprocess;
364 GDBProcess *processes;
365 int process_num;
Meador Ingecdb432b2012-03-15 17:49:45 +0000366 char syscall_buf[256];
367 gdb_syscall_complete_cb current_syscall_cb;
Alex Bennée308f9e82020-03-16 17:21:35 +0000368 GString *str_buf;
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000369 GByteArray *mem_buf;
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100370 int sstep_flags;
371 int supported_sstep_flags;
bellard858693c2004-03-31 18:52:07 +0000372} GDBState;
bellardb4608c02003-06-27 17:34:32 +0000373
Alex Bennée8d98c442020-03-16 17:21:33 +0000374static GDBState gdbserver_state;
375
376static void init_gdbserver_state(void)
377{
378 g_assert(!gdbserver_state.init);
379 memset(&gdbserver_state, 0, sizeof(GDBState));
380 gdbserver_state.init = true;
Alex Bennée308f9e82020-03-16 17:21:35 +0000381 gdbserver_state.str_buf = g_string_new(NULL);
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000382 gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
Damien Hedded116e812020-03-16 17:21:53 +0000383 gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100384
385 /*
386 * In replay mode all events will come from the log and can't be
387 * suppressed otherwise we would break determinism. However as those
388 * events are tied to the number of executed instructions we won't see
389 * them occurring every time we single step.
390 */
391 if (replay_mode != REPLAY_MODE_NONE) {
392 gdbserver_state.supported_sstep_flags = SSTEP_ENABLE;
Maxim Levitsky12bc5b42021-11-11 12:06:03 +0100393 } else if (kvm_enabled()) {
394 gdbserver_state.supported_sstep_flags = kvm_get_supported_sstep_flags();
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100395 } else {
396 gdbserver_state.supported_sstep_flags =
397 SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
398 }
399
400 /*
401 * By default use no IRQs and no timers while single stepping so as to
402 * make single stepping like an ICE HW step.
403 */
Maxim Levitsky12bc5b42021-11-11 12:06:03 +0100404 gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
405 gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100406
Alex Bennée8d98c442020-03-16 17:21:33 +0000407}
408
409#ifndef CONFIG_USER_ONLY
410static void reset_gdbserver_state(void)
411{
412 g_free(gdbserver_state.processes);
413 gdbserver_state.processes = NULL;
414 gdbserver_state.process_num = 0;
415}
416#endif
aliguori880a7572008-11-18 20:30:24 +0000417
Andreas Färber5b50e792013-06-29 04:18:45 +0200418bool gdb_has_xml;
pbrook56aebc82008-10-11 17:55:29 +0000419
bellard1fddef42005-04-17 19:16:13 +0000420#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000421
Alex Bennéea346af32020-03-16 17:21:34 +0000422static int get_char(void)
bellardb4608c02003-06-27 17:34:32 +0000423{
424 uint8_t ch;
425 int ret;
426
427 for(;;) {
Marc-André Lureaue7b79422022-02-19 01:34:50 +0400428 ret = recv(gdbserver_state.fd, &ch, 1, 0);
bellardb4608c02003-06-27 17:34:32 +0000429 if (ret < 0) {
edgar_igl1f487ee2008-05-17 22:20:53 +0000430 if (errno == ECONNRESET)
Alex Bennéea346af32020-03-16 17:21:34 +0000431 gdbserver_state.fd = -1;
Peter Wu5819e3e2016-06-05 16:35:48 +0200432 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000433 return -1;
434 } else if (ret == 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000435 close(gdbserver_state.fd);
436 gdbserver_state.fd = -1;
bellardb4608c02003-06-27 17:34:32 +0000437 return -1;
438 } else {
439 break;
440 }
441 }
442 return ch;
443}
pbrook4046d912007-01-28 01:53:16 +0000444#endif
bellardb4608c02003-06-27 17:34:32 +0000445
blueswir1654efcf2009-04-18 07:29:59 +0000446static enum {
pbrooka2d1eba2007-01-28 03:10:55 +0000447 GDB_SYS_UNKNOWN,
448 GDB_SYS_ENABLED,
449 GDB_SYS_DISABLED,
450} gdb_syscall_mode;
451
Liviu Ionescua38bb072014-12-11 12:07:48 +0000452/* Decide if either remote gdb syscalls or native file IO should be used. */
pbrooka2d1eba2007-01-28 03:10:55 +0000453int use_gdb_syscalls(void)
454{
Leon Alraecfe67ce2015-06-19 14:17:45 +0100455 SemihostingTarget target = semihosting_get_target();
456 if (target == SEMIHOSTING_TARGET_NATIVE) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000457 /* -semihosting-config target=native */
458 return false;
Leon Alraecfe67ce2015-06-19 14:17:45 +0100459 } else if (target == SEMIHOSTING_TARGET_GDB) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000460 /* -semihosting-config target=gdb */
461 return true;
462 }
463
464 /* -semihosting-config target=auto */
465 /* On the first call check if gdb is connected and remember. */
pbrooka2d1eba2007-01-28 03:10:55 +0000466 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
Alex Bennée8d98c442020-03-16 17:21:33 +0000467 gdb_syscall_mode = gdbserver_state.init ?
468 GDB_SYS_ENABLED : GDB_SYS_DISABLED;
pbrooka2d1eba2007-01-28 03:10:55 +0000469 }
470 return gdb_syscall_mode == GDB_SYS_ENABLED;
471}
472
Alex Bennéeed12f5b2021-05-20 18:43:02 +0100473static bool stub_can_reverse(void)
474{
475#ifdef CONFIG_USER_ONLY
476 return false;
477#else
478 return replay_mode == REPLAY_MODE_PLAY;
479#endif
480}
481
edgar_iglba70a622008-03-14 06:10:42 +0000482/* Resume execution. */
Alex Bennéea346af32020-03-16 17:21:34 +0000483static inline void gdb_continue(void)
edgar_iglba70a622008-03-14 06:10:42 +0000484{
Doug Gale5c9522b2017-12-02 20:30:37 -0500485
edgar_iglba70a622008-03-14 06:10:42 +0000486#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000487 gdbserver_state.running_state = 1;
Doug Gale5c9522b2017-12-02 20:30:37 -0500488 trace_gdbstub_op_continue();
edgar_iglba70a622008-03-14 06:10:42 +0000489#else
Paolo Bonzini26ac7a32013-06-03 17:06:54 +0200490 if (!runstate_needs_reset()) {
Doug Gale5c9522b2017-12-02 20:30:37 -0500491 trace_gdbstub_op_continue();
Paolo Bonzini87f25c12013-05-30 13:20:40 +0200492 vm_start();
493 }
edgar_iglba70a622008-03-14 06:10:42 +0000494#endif
495}
496
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100497/*
498 * Resume execution, per CPU actions. For user-mode emulation it's
499 * equivalent to gdb_continue.
500 */
Alex Bennéea346af32020-03-16 17:21:34 +0000501static int gdb_continue_partial(char *newstates)
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100502{
503 CPUState *cpu;
504 int res = 0;
505#ifdef CONFIG_USER_ONLY
506 /*
507 * This is not exactly accurate, but it's an improvement compared to the
508 * previous situation, where only one CPU would be single-stepped.
509 */
510 CPU_FOREACH(cpu) {
511 if (newstates[cpu->cpu_index] == 's') {
Doug Gale5c9522b2017-12-02 20:30:37 -0500512 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100513 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100514 }
515 }
Alex Bennéea346af32020-03-16 17:21:34 +0000516 gdbserver_state.running_state = 1;
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100517#else
518 int flag = 0;
519
520 if (!runstate_needs_reset()) {
Ivan Shcherbakovd7482ff2022-03-02 17:28:33 -0800521 bool step_requested = false;
522 CPU_FOREACH(cpu) {
523 if (newstates[cpu->cpu_index] == 's') {
524 step_requested = true;
525 break;
526 }
527 }
528
529 if (vm_prepare_start(step_requested)) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100530 return 0;
531 }
532
533 CPU_FOREACH(cpu) {
534 switch (newstates[cpu->cpu_index]) {
535 case 0:
536 case 1:
537 break; /* nothing to do here */
538 case 's':
Doug Gale5c9522b2017-12-02 20:30:37 -0500539 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100540 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100541 cpu_resume(cpu);
542 flag = 1;
543 break;
544 case 'c':
Doug Gale5c9522b2017-12-02 20:30:37 -0500545 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100546 cpu_resume(cpu);
547 flag = 1;
548 break;
549 default:
550 res = -1;
551 break;
552 }
553 }
554 }
555 if (flag) {
556 qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
557 }
558#endif
559 return res;
560}
561
Alex Bennéea346af32020-03-16 17:21:34 +0000562static void put_buffer(const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000563{
pbrook4046d912007-01-28 01:53:16 +0000564#ifdef CONFIG_USER_ONLY
bellardb4608c02003-06-27 17:34:32 +0000565 int ret;
566
567 while (len > 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000568 ret = send(gdbserver_state.fd, buf, len, 0);
bellardb4608c02003-06-27 17:34:32 +0000569 if (ret < 0) {
Peter Wu5819e3e2016-06-05 16:35:48 +0200570 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000571 return;
572 } else {
573 buf += ret;
574 len -= ret;
575 }
576 }
pbrook4046d912007-01-28 01:53:16 +0000577#else
Daniel P. Berrange6ab3fc32016-09-06 14:56:04 +0100578 /* XXX this blocks entire thread. Rewrite to use
579 * qemu_chr_fe_write and background I/O callbacks */
Alex Bennéea346af32020-03-16 17:21:34 +0000580 qemu_chr_fe_write_all(&gdbserver_state.chr, buf, len);
pbrook4046d912007-01-28 01:53:16 +0000581#endif
bellardb4608c02003-06-27 17:34:32 +0000582}
583
584static inline int fromhex(int v)
585{
586 if (v >= '0' && v <= '9')
587 return v - '0';
588 else if (v >= 'A' && v <= 'F')
589 return v - 'A' + 10;
590 else if (v >= 'a' && v <= 'f')
591 return v - 'a' + 10;
592 else
593 return 0;
594}
595
596static inline int tohex(int v)
597{
598 if (v < 10)
599 return v + '0';
600 else
601 return v - 10 + 'a';
602}
603
Philippe Mathieu-Daudé90057742018-04-08 11:59:33 -0300604/* writes 2*len+1 bytes in buf */
Alex Bennée308f9e82020-03-16 17:21:35 +0000605static void memtohex(GString *buf, const uint8_t *mem, int len)
bellardb4608c02003-06-27 17:34:32 +0000606{
607 int i, c;
bellardb4608c02003-06-27 17:34:32 +0000608 for(i = 0; i < len; i++) {
609 c = mem[i];
Alex Bennée308f9e82020-03-16 17:21:35 +0000610 g_string_append_c(buf, tohex(c >> 4));
611 g_string_append_c(buf, tohex(c & 0xf));
bellardb4608c02003-06-27 17:34:32 +0000612 }
Alex Bennée308f9e82020-03-16 17:21:35 +0000613 g_string_append_c(buf, '\0');
bellardb4608c02003-06-27 17:34:32 +0000614}
615
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000616static void hextomem(GByteArray *mem, const char *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000617{
618 int i;
619
620 for(i = 0; i < len; i++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000621 guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
622 g_byte_array_append(mem, &byte, 1);
bellardb4608c02003-06-27 17:34:32 +0000623 buf += 2;
624 }
625}
626
Doug Gale5c9522b2017-12-02 20:30:37 -0500627static void hexdump(const char *buf, int len,
628 void (*trace_fn)(size_t ofs, char const *text))
629{
630 char line_buffer[3 * 16 + 4 + 16 + 1];
631
632 size_t i;
633 for (i = 0; i < len || (i & 0xF); ++i) {
634 size_t byte_ofs = i & 15;
635
636 if (byte_ofs == 0) {
637 memset(line_buffer, ' ', 3 * 16 + 4 + 16);
638 line_buffer[3 * 16 + 4 + 16] = 0;
639 }
640
641 size_t col_group = (i >> 2) & 3;
642 size_t hex_col = byte_ofs * 3 + col_group;
643 size_t txt_col = 3 * 16 + 4 + byte_ofs;
644
645 if (i < len) {
646 char value = buf[i];
647
648 line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
649 line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
650 line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
651 ? value
652 : '.';
653 }
654
655 if (byte_ofs == 0xF)
656 trace_fn(i & -16, line_buffer);
657 }
658}
659
bellardb4608c02003-06-27 17:34:32 +0000660/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000661static int put_packet_binary(const char *buf, int len, bool dump)
bellardb4608c02003-06-27 17:34:32 +0000662{
pbrook56aebc82008-10-11 17:55:29 +0000663 int csum, i;
Damien Hedded116e812020-03-16 17:21:53 +0000664 uint8_t footer[3];
bellardb4608c02003-06-27 17:34:32 +0000665
Doug Gale5c9522b2017-12-02 20:30:37 -0500666 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
667 hexdump(buf, len, trace_gdbstub_io_binaryreply);
668 }
669
bellardb4608c02003-06-27 17:34:32 +0000670 for(;;) {
Damien Hedded116e812020-03-16 17:21:53 +0000671 g_byte_array_set_size(gdbserver_state.last_packet, 0);
672 g_byte_array_append(gdbserver_state.last_packet,
673 (const uint8_t *) "$", 1);
674 g_byte_array_append(gdbserver_state.last_packet,
675 (const uint8_t *) buf, len);
bellardb4608c02003-06-27 17:34:32 +0000676 csum = 0;
677 for(i = 0; i < len; i++) {
678 csum += buf[i];
679 }
Damien Hedded116e812020-03-16 17:21:53 +0000680 footer[0] = '#';
681 footer[1] = tohex((csum >> 4) & 0xf);
682 footer[2] = tohex((csum) & 0xf);
683 g_byte_array_append(gdbserver_state.last_packet, footer, 3);
bellardb4608c02003-06-27 17:34:32 +0000684
Damien Hedded116e812020-03-16 17:21:53 +0000685 put_buffer(gdbserver_state.last_packet->data,
686 gdbserver_state.last_packet->len);
bellardb4608c02003-06-27 17:34:32 +0000687
pbrook4046d912007-01-28 01:53:16 +0000688#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000689 i = get_char();
pbrook4046d912007-01-28 01:53:16 +0000690 if (i < 0)
bellardb4608c02003-06-27 17:34:32 +0000691 return -1;
pbrook4046d912007-01-28 01:53:16 +0000692 if (i == '+')
bellardb4608c02003-06-27 17:34:32 +0000693 break;
pbrook4046d912007-01-28 01:53:16 +0000694#else
695 break;
696#endif
bellardb4608c02003-06-27 17:34:32 +0000697 }
698 return 0;
699}
700
pbrook56aebc82008-10-11 17:55:29 +0000701/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000702static int put_packet(const char *buf)
pbrook56aebc82008-10-11 17:55:29 +0000703{
Doug Gale5c9522b2017-12-02 20:30:37 -0500704 trace_gdbstub_io_reply(buf);
pbrook56aebc82008-10-11 17:55:29 +0000705
Alex Bennéea346af32020-03-16 17:21:34 +0000706 return put_packet_binary(buf, strlen(buf), false);
pbrook56aebc82008-10-11 17:55:29 +0000707}
708
Alex Bennée308f9e82020-03-16 17:21:35 +0000709static void put_strbuf(void)
pbrook56aebc82008-10-11 17:55:29 +0000710{
Alex Bennée308f9e82020-03-16 17:21:35 +0000711 put_packet(gdbserver_state.str_buf->str);
712}
713
714/* Encode data using the encoding for 'x' packets. */
715static void memtox(GString *buf, const char *mem, int len)
716{
pbrook56aebc82008-10-11 17:55:29 +0000717 char c;
718
719 while (len--) {
720 c = *(mem++);
721 switch (c) {
722 case '#': case '$': case '*': case '}':
Alex Bennée308f9e82020-03-16 17:21:35 +0000723 g_string_append_c(buf, '}');
724 g_string_append_c(buf, c ^ 0x20);
pbrook56aebc82008-10-11 17:55:29 +0000725 break;
726 default:
Alex Bennée308f9e82020-03-16 17:21:35 +0000727 g_string_append_c(buf, c);
pbrook56aebc82008-10-11 17:55:29 +0000728 break;
729 }
730 }
pbrook56aebc82008-10-11 17:55:29 +0000731}
732
Alex Bennéea346af32020-03-16 17:21:34 +0000733static uint32_t gdb_get_cpu_pid(CPUState *cpu)
Luc Michel1a227332019-01-07 15:23:45 +0000734{
Luc Michel1a227332019-01-07 15:23:45 +0000735 /* TODO: In user mode, we should use the task state PID */
Peter Maydell46f5abc2019-01-29 11:46:06 +0000736 if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
737 /* Return the default process' PID */
Alex Bennéea346af32020-03-16 17:21:34 +0000738 int index = gdbserver_state.process_num - 1;
739 return gdbserver_state.processes[index].pid;
Peter Maydell46f5abc2019-01-29 11:46:06 +0000740 }
741 return cpu->cluster_index + 1;
Luc Michel1a227332019-01-07 15:23:45 +0000742}
743
Alex Bennéea346af32020-03-16 17:21:34 +0000744static GDBProcess *gdb_get_process(uint32_t pid)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000745{
746 int i;
747
748 if (!pid) {
749 /* 0 means any process, we take the first one */
Alex Bennéea346af32020-03-16 17:21:34 +0000750 return &gdbserver_state.processes[0];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000751 }
752
Alex Bennéea346af32020-03-16 17:21:34 +0000753 for (i = 0; i < gdbserver_state.process_num; i++) {
754 if (gdbserver_state.processes[i].pid == pid) {
755 return &gdbserver_state.processes[i];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000756 }
757 }
758
759 return NULL;
760}
761
Alex Bennéea346af32020-03-16 17:21:34 +0000762static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000763{
Alex Bennéea346af32020-03-16 17:21:34 +0000764 return gdb_get_process(gdb_get_cpu_pid(cpu));
Luc Michel7d8c87d2019-01-07 15:23:45 +0000765}
766
767static CPUState *find_cpu(uint32_t thread_id)
768{
769 CPUState *cpu;
770
771 CPU_FOREACH(cpu) {
772 if (cpu_gdb_index(cpu) == thread_id) {
773 return cpu;
774 }
775 }
776
777 return NULL;
778}
779
Alex Bennéea346af32020-03-16 17:21:34 +0000780static CPUState *get_first_cpu_in_process(GDBProcess *process)
Luc Michele40e5202019-01-07 15:23:46 +0000781{
782 CPUState *cpu;
783
784 CPU_FOREACH(cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000785 if (gdb_get_cpu_pid(cpu) == process->pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000786 return cpu;
787 }
788 }
789
790 return NULL;
791}
792
Alex Bennéea346af32020-03-16 17:21:34 +0000793static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000794{
Alex Bennéea346af32020-03-16 17:21:34 +0000795 uint32_t pid = gdb_get_cpu_pid(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000796 cpu = CPU_NEXT(cpu);
797
798 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000799 if (gdb_get_cpu_pid(cpu) == pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000800 break;
801 }
802
803 cpu = CPU_NEXT(cpu);
804 }
805
806 return cpu;
807}
808
Luc Michele40e5202019-01-07 15:23:46 +0000809/* Return the cpu following @cpu, while ignoring unattached processes. */
Alex Bennéea346af32020-03-16 17:21:34 +0000810static CPUState *gdb_next_attached_cpu(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000811{
812 cpu = CPU_NEXT(cpu);
813
814 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000815 if (gdb_get_cpu_process(cpu)->attached) {
Luc Michele40e5202019-01-07 15:23:46 +0000816 break;
817 }
818
819 cpu = CPU_NEXT(cpu);
820 }
821
822 return cpu;
823}
824
825/* Return the first attached cpu */
Alex Bennéea346af32020-03-16 17:21:34 +0000826static CPUState *gdb_first_attached_cpu(void)
Luc Michele40e5202019-01-07 15:23:46 +0000827{
828 CPUState *cpu = first_cpu;
Alex Bennéea346af32020-03-16 17:21:34 +0000829 GDBProcess *process = gdb_get_cpu_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000830
831 if (!process->attached) {
Alex Bennéea346af32020-03-16 17:21:34 +0000832 return gdb_next_attached_cpu(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000833 }
834
835 return cpu;
836}
837
Alex Bennéea346af32020-03-16 17:21:34 +0000838static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
Luc Michelab65eed2019-01-29 11:46:03 +0000839{
840 GDBProcess *process;
841 CPUState *cpu;
842
843 if (!pid && !tid) {
844 /* 0 means any process/thread, we take the first attached one */
Alex Bennéea346af32020-03-16 17:21:34 +0000845 return gdb_first_attached_cpu();
Luc Michelab65eed2019-01-29 11:46:03 +0000846 } else if (pid && !tid) {
847 /* any thread in a specific process */
Alex Bennéea346af32020-03-16 17:21:34 +0000848 process = gdb_get_process(pid);
Luc Michelab65eed2019-01-29 11:46:03 +0000849
850 if (process == NULL) {
851 return NULL;
852 }
853
854 if (!process->attached) {
855 return NULL;
856 }
857
Alex Bennéea346af32020-03-16 17:21:34 +0000858 return get_first_cpu_in_process(process);
Luc Michelab65eed2019-01-29 11:46:03 +0000859 } else {
860 /* a specific thread */
861 cpu = find_cpu(tid);
862
863 if (cpu == NULL) {
864 return NULL;
865 }
866
Alex Bennéea346af32020-03-16 17:21:34 +0000867 process = gdb_get_cpu_process(cpu);
Luc Michelab65eed2019-01-29 11:46:03 +0000868
869 if (pid && process->pid != pid) {
870 return NULL;
871 }
872
873 if (!process->attached) {
874 return NULL;
875 }
876
877 return cpu;
878 }
879}
880
Alex Bennéea346af32020-03-16 17:21:34 +0000881static const char *get_feature_xml(const char *p, const char **newp,
882 GDBProcess *process)
pbrook56aebc82008-10-11 17:55:29 +0000883{
pbrook56aebc82008-10-11 17:55:29 +0000884 size_t len;
885 int i;
886 const char *name;
Alex Bennéea346af32020-03-16 17:21:34 +0000887 CPUState *cpu = get_first_cpu_in_process(process);
Luc Michelc145eea2019-01-07 15:23:46 +0000888 CPUClass *cc = CPU_GET_CLASS(cpu);
pbrook56aebc82008-10-11 17:55:29 +0000889
890 len = 0;
891 while (p[len] && p[len] != ':')
892 len++;
893 *newp = p + len;
894
895 name = NULL;
896 if (strncmp(p, "target.xml", len) == 0) {
Luc Michelc145eea2019-01-07 15:23:46 +0000897 char *buf = process->target_xml;
898 const size_t buf_sz = sizeof(process->target_xml);
pbrook56aebc82008-10-11 17:55:29 +0000899
Luc Michelc145eea2019-01-07 15:23:46 +0000900 /* Generate the XML description for this CPU. */
901 if (!buf[0]) {
902 GDBRegisterState *r;
903
904 pstrcat(buf, buf_sz,
David Hildenbrandb3820e62015-12-03 13:14:41 +0100905 "<?xml version=\"1.0\"?>"
906 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
907 "<target>");
908 if (cc->gdb_arch_name) {
909 gchar *arch = cc->gdb_arch_name(cpu);
Luc Michelc145eea2019-01-07 15:23:46 +0000910 pstrcat(buf, buf_sz, "<architecture>");
911 pstrcat(buf, buf_sz, arch);
912 pstrcat(buf, buf_sz, "</architecture>");
David Hildenbrandb3820e62015-12-03 13:14:41 +0100913 g_free(arch);
914 }
Luc Michelc145eea2019-01-07 15:23:46 +0000915 pstrcat(buf, buf_sz, "<xi:include href=\"");
916 pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
917 pstrcat(buf, buf_sz, "\"/>");
Andreas Färbereac8b352013-06-28 21:11:37 +0200918 for (r = cpu->gdb_regs; r; r = r->next) {
Luc Michelc145eea2019-01-07 15:23:46 +0000919 pstrcat(buf, buf_sz, "<xi:include href=\"");
920 pstrcat(buf, buf_sz, r->xml);
921 pstrcat(buf, buf_sz, "\"/>");
pbrook56aebc82008-10-11 17:55:29 +0000922 }
Luc Michelc145eea2019-01-07 15:23:46 +0000923 pstrcat(buf, buf_sz, "</target>");
pbrook56aebc82008-10-11 17:55:29 +0000924 }
Luc Michelc145eea2019-01-07 15:23:46 +0000925 return buf;
pbrook56aebc82008-10-11 17:55:29 +0000926 }
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100927 if (cc->gdb_get_dynamic_xml) {
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100928 char *xmlname = g_strndup(p, len);
929 const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
930
931 g_free(xmlname);
932 if (xml) {
933 return xml;
934 }
935 }
pbrook56aebc82008-10-11 17:55:29 +0000936 for (i = 0; ; i++) {
937 name = xml_builtin[i][0];
938 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
939 break;
940 }
941 return name ? xml_builtin[i][1] : NULL;
942}
pbrook56aebc82008-10-11 17:55:29 +0000943
Alex Bennéea010bdb2020-03-16 17:21:41 +0000944static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000945{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200946 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200947 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000948 GDBRegisterState *r;
949
Andreas Färbera0e372f2013-06-28 23:18:47 +0200950 if (reg < cc->gdb_num_core_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000951 return cc->gdb_read_register(cpu, buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200952 }
pbrook56aebc82008-10-11 17:55:29 +0000953
Andreas Färbereac8b352013-06-28 21:11:37 +0200954 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000955 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000956 return r->get_reg(env, buf, reg - r->base_reg);
pbrook56aebc82008-10-11 17:55:29 +0000957 }
958 }
959 return 0;
960}
961
Andreas Färber385b9f02013-06-27 18:25:36 +0200962static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000963{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200964 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200965 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000966 GDBRegisterState *r;
967
Andreas Färbera0e372f2013-06-28 23:18:47 +0200968 if (reg < cc->gdb_num_core_regs) {
Andreas Färber5b50e792013-06-29 04:18:45 +0200969 return cc->gdb_write_register(cpu, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200970 }
pbrook56aebc82008-10-11 17:55:29 +0000971
Andreas Färbereac8b352013-06-28 21:11:37 +0200972 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000973 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
974 return r->set_reg(env, mem_buf, reg - r->base_reg);
975 }
976 }
977 return 0;
978}
979
980/* Register a supplemental set of CPU registers. If g_pos is nonzero it
981 specifies the first register number and these registers are included in
982 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
983 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
984 */
985
Andreas Färber22169d42013-06-28 21:27:39 +0200986void gdb_register_coprocessor(CPUState *cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +0000987 gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
Andreas Färber22169d42013-06-28 21:27:39 +0200988 int num_regs, const char *xml, int g_pos)
pbrook56aebc82008-10-11 17:55:29 +0000989{
990 GDBRegisterState *s;
991 GDBRegisterState **p;
pbrook56aebc82008-10-11 17:55:29 +0000992
Andreas Färbereac8b352013-06-28 21:11:37 +0200993 p = &cpu->gdb_regs;
pbrook56aebc82008-10-11 17:55:29 +0000994 while (*p) {
995 /* Check for duplicates. */
996 if (strcmp((*p)->xml, xml) == 0)
997 return;
998 p = &(*p)->next;
999 }
Stefan Weil9643c252011-10-18 22:25:38 +02001000
1001 s = g_new0(GDBRegisterState, 1);
Andreas Färbera0e372f2013-06-28 23:18:47 +02001002 s->base_reg = cpu->gdb_num_regs;
Stefan Weil9643c252011-10-18 22:25:38 +02001003 s->num_regs = num_regs;
1004 s->get_reg = get_reg;
1005 s->set_reg = set_reg;
1006 s->xml = xml;
1007
pbrook56aebc82008-10-11 17:55:29 +00001008 /* Add to end of list. */
Andreas Färbera0e372f2013-06-28 23:18:47 +02001009 cpu->gdb_num_regs += num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001010 *p = s;
1011 if (g_pos) {
1012 if (g_pos != s->base_reg) {
Ziyue Yang7ae6c572017-01-18 16:03:29 +08001013 error_report("Error: Bad gdb register numbering for '%s', "
1014 "expected %d got %d", xml, g_pos, s->base_reg);
Andreas Färber35143f02013-08-12 18:09:47 +02001015 } else {
1016 cpu->gdb_num_g_regs = cpu->gdb_num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001017 }
1018 }
1019}
1020
aliguoria1d1bb32008-11-18 20:07:32 +00001021#ifndef CONFIG_USER_ONLY
Peter Maydell2472b6c2014-09-12 19:04:17 +01001022/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
1023static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
1024{
1025 static const int xlat[] = {
1026 [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
1027 [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
1028 [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1029 };
1030
1031 CPUClass *cc = CPU_GET_CLASS(cpu);
1032 int cputype = xlat[gdbtype];
1033
1034 if (cc->gdb_stop_before_watchpoint) {
1035 cputype |= BP_STOP_BEFORE_ACCESS;
1036 }
1037 return cputype;
1038}
aliguoria1d1bb32008-11-18 20:07:32 +00001039#endif
1040
Jon Doron77f6ce52019-05-29 09:41:35 +03001041static int gdb_breakpoint_insert(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001042{
Andreas Färber182735e2013-05-29 22:29:20 +02001043 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001044 int err = 0;
1045
Andreas Färber62278812013-06-27 17:12:06 +02001046 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001047 return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001048 }
aliguorie22a25c2009-03-12 20:12:48 +00001049
aliguoria1d1bb32008-11-18 20:07:32 +00001050 switch (type) {
1051 case GDB_BREAKPOINT_SW:
1052 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001053 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001054 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
1055 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001056 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001057 }
aliguori880a7572008-11-18 20:30:24 +00001058 }
1059 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001060#ifndef CONFIG_USER_ONLY
1061 case GDB_WATCHPOINT_WRITE:
1062 case GDB_WATCHPOINT_READ:
1063 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001064 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001065 err = cpu_watchpoint_insert(cpu, addr, len,
1066 xlat_gdb_type(cpu, type), NULL);
1067 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001068 break;
Peter Maydell2472b6c2014-09-12 19:04:17 +01001069 }
aliguori880a7572008-11-18 20:30:24 +00001070 }
1071 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001072#endif
1073 default:
1074 return -ENOSYS;
1075 }
1076}
1077
Jon Doron77f6ce52019-05-29 09:41:35 +03001078static int gdb_breakpoint_remove(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001079{
Andreas Färber182735e2013-05-29 22:29:20 +02001080 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001081 int err = 0;
1082
Andreas Färber62278812013-06-27 17:12:06 +02001083 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001084 return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001085 }
aliguorie22a25c2009-03-12 20:12:48 +00001086
aliguoria1d1bb32008-11-18 20:07:32 +00001087 switch (type) {
1088 case GDB_BREAKPOINT_SW:
1089 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001090 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001091 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
1092 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001093 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001094 }
aliguori880a7572008-11-18 20:30:24 +00001095 }
1096 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001097#ifndef CONFIG_USER_ONLY
1098 case GDB_WATCHPOINT_WRITE:
1099 case GDB_WATCHPOINT_READ:
1100 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001101 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001102 err = cpu_watchpoint_remove(cpu, addr, len,
1103 xlat_gdb_type(cpu, type));
aliguori880a7572008-11-18 20:30:24 +00001104 if (err)
1105 break;
1106 }
1107 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001108#endif
1109 default:
1110 return -ENOSYS;
1111 }
1112}
1113
Luc Michel546f3c62019-01-07 15:23:46 +00001114static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
1115{
1116 cpu_breakpoint_remove_all(cpu, BP_GDB);
1117#ifndef CONFIG_USER_ONLY
1118 cpu_watchpoint_remove_all(cpu, BP_GDB);
1119#endif
1120}
1121
Alex Bennéea346af32020-03-16 17:21:34 +00001122static void gdb_process_breakpoint_remove_all(GDBProcess *p)
Luc Michel546f3c62019-01-07 15:23:46 +00001123{
Alex Bennéea346af32020-03-16 17:21:34 +00001124 CPUState *cpu = get_first_cpu_in_process(p);
Luc Michel546f3c62019-01-07 15:23:46 +00001125
1126 while (cpu) {
1127 gdb_cpu_breakpoint_remove_all(cpu);
Alex Bennéea346af32020-03-16 17:21:34 +00001128 cpu = gdb_next_cpu_in_process(cpu);
Luc Michel546f3c62019-01-07 15:23:46 +00001129 }
1130}
1131
aliguori880a7572008-11-18 20:30:24 +00001132static void gdb_breakpoint_remove_all(void)
aliguoria1d1bb32008-11-18 20:07:32 +00001133{
Andreas Färber182735e2013-05-29 22:29:20 +02001134 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001135
aliguorie22a25c2009-03-12 20:12:48 +00001136 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001137 kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
aliguorie22a25c2009-03-12 20:12:48 +00001138 return;
1139 }
1140
Andreas Färberbdc44642013-06-24 23:50:24 +02001141 CPU_FOREACH(cpu) {
Luc Michel546f3c62019-01-07 15:23:46 +00001142 gdb_cpu_breakpoint_remove_all(cpu);
aliguori880a7572008-11-18 20:30:24 +00001143 }
aliguoria1d1bb32008-11-18 20:07:32 +00001144}
1145
Alex Bennéea346af32020-03-16 17:21:34 +00001146static void gdb_set_cpu_pc(target_ulong pc)
aurel32fab9d282009-04-08 21:29:37 +00001147{
Alex Bennéea346af32020-03-16 17:21:34 +00001148 CPUState *cpu = gdbserver_state.c_cpu;
Andreas Färberf45748f2013-06-21 19:09:18 +02001149
1150 cpu_synchronize_state(cpu);
Peter Crosthwaite4a2b24e2015-06-23 20:19:21 -07001151 cpu_set_pc(cpu, pc);
aurel32fab9d282009-04-08 21:29:37 +00001152}
1153
Alex Bennée308f9e82020-03-16 17:21:35 +00001154static void gdb_append_thread_id(CPUState *cpu, GString *buf)
Luc Michel1a227332019-01-07 15:23:45 +00001155{
Alex Bennéea346af32020-03-16 17:21:34 +00001156 if (gdbserver_state.multiprocess) {
Alex Bennée308f9e82020-03-16 17:21:35 +00001157 g_string_append_printf(buf, "p%02x.%02x",
1158 gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001159 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00001160 g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001161 }
Luc Michel1a227332019-01-07 15:23:45 +00001162}
1163
Luc Michel7d8c87d2019-01-07 15:23:45 +00001164typedef enum GDBThreadIdKind {
1165 GDB_ONE_THREAD = 0,
1166 GDB_ALL_THREADS, /* One process, all threads */
1167 GDB_ALL_PROCESSES,
1168 GDB_READ_THREAD_ERR
1169} GDBThreadIdKind;
1170
1171static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
1172 uint32_t *pid, uint32_t *tid)
1173{
1174 unsigned long p, t;
1175 int ret;
1176
1177 if (*buf == 'p') {
1178 buf++;
1179 ret = qemu_strtoul(buf, &buf, 16, &p);
1180
1181 if (ret) {
1182 return GDB_READ_THREAD_ERR;
1183 }
1184
1185 /* Skip '.' */
1186 buf++;
1187 } else {
1188 p = 1;
1189 }
1190
1191 ret = qemu_strtoul(buf, &buf, 16, &t);
1192
1193 if (ret) {
1194 return GDB_READ_THREAD_ERR;
1195 }
1196
1197 *end_buf = buf;
1198
1199 if (p == -1) {
1200 return GDB_ALL_PROCESSES;
1201 }
1202
1203 if (pid) {
1204 *pid = p;
1205 }
1206
1207 if (t == -1) {
1208 return GDB_ALL_THREADS;
1209 }
1210
1211 if (tid) {
1212 *tid = t;
1213 }
1214
1215 return GDB_ONE_THREAD;
1216}
1217
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001218/**
1219 * gdb_handle_vcont - Parses and handles a vCont packet.
1220 * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1221 * a format error, 0 on success.
1222 */
Alex Bennéea346af32020-03-16 17:21:34 +00001223static int gdb_handle_vcont(const char *p)
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001224{
Luc Michele40e5202019-01-07 15:23:46 +00001225 int res, signal = 0;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001226 char cur_action;
1227 char *newstates;
1228 unsigned long tmp;
Luc Michele40e5202019-01-07 15:23:46 +00001229 uint32_t pid, tid;
1230 GDBProcess *process;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001231 CPUState *cpu;
Luc Michelc99ef792019-03-26 12:53:26 +00001232 GDBThreadIdKind kind;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001233#ifdef CONFIG_USER_ONLY
1234 int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1235
1236 CPU_FOREACH(cpu) {
1237 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1238 }
Like Xu5cc87672019-05-19 04:54:21 +08001239#else
1240 MachineState *ms = MACHINE(qdev_get_machine());
1241 unsigned int max_cpus = ms->smp.max_cpus;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001242#endif
1243 /* uninitialised CPUs stay 0 */
1244 newstates = g_new0(char, max_cpus);
1245
1246 /* mark valid CPUs with 1 */
1247 CPU_FOREACH(cpu) {
1248 newstates[cpu->cpu_index] = 1;
1249 }
1250
1251 /*
1252 * res keeps track of what error we are returning, with -ENOTSUP meaning
1253 * that the command is unknown or unsupported, thus returning an empty
1254 * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1255 * or incorrect parameters passed.
1256 */
1257 res = 0;
1258 while (*p) {
1259 if (*p++ != ';') {
1260 res = -ENOTSUP;
1261 goto out;
1262 }
1263
1264 cur_action = *p++;
1265 if (cur_action == 'C' || cur_action == 'S') {
Peter Maydell95a5bef2017-07-20 17:31:30 +01001266 cur_action = qemu_tolower(cur_action);
Peter Maydell3ddd9032020-11-21 21:03:42 +00001267 res = qemu_strtoul(p, &p, 16, &tmp);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001268 if (res) {
1269 goto out;
1270 }
1271 signal = gdb_signal_to_target(tmp);
1272 } else if (cur_action != 'c' && cur_action != 's') {
1273 /* unknown/invalid/unsupported command */
1274 res = -ENOTSUP;
1275 goto out;
1276 }
Luc Michele40e5202019-01-07 15:23:46 +00001277
Luc Michelc99ef792019-03-26 12:53:26 +00001278 if (*p == '\0' || *p == ';') {
1279 /*
1280 * No thread specifier, action is on "all threads". The
1281 * specification is unclear regarding the process to act on. We
1282 * choose all processes.
1283 */
1284 kind = GDB_ALL_PROCESSES;
1285 } else if (*p++ == ':') {
1286 kind = read_thread_id(p, &p, &pid, &tid);
1287 } else {
Luc Michele40e5202019-01-07 15:23:46 +00001288 res = -ENOTSUP;
1289 goto out;
1290 }
1291
Luc Michelc99ef792019-03-26 12:53:26 +00001292 switch (kind) {
Luc Michele40e5202019-01-07 15:23:46 +00001293 case GDB_READ_THREAD_ERR:
1294 res = -EINVAL;
1295 goto out;
1296
1297 case GDB_ALL_PROCESSES:
Alex Bennéea346af32020-03-16 17:21:34 +00001298 cpu = gdb_first_attached_cpu();
Luc Michele40e5202019-01-07 15:23:46 +00001299 while (cpu) {
1300 if (newstates[cpu->cpu_index] == 1) {
1301 newstates[cpu->cpu_index] = cur_action;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001302 }
Luc Michele40e5202019-01-07 15:23:46 +00001303
Alex Bennéea346af32020-03-16 17:21:34 +00001304 cpu = gdb_next_attached_cpu(cpu);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001305 }
Luc Michele40e5202019-01-07 15:23:46 +00001306 break;
1307
1308 case GDB_ALL_THREADS:
Alex Bennéea346af32020-03-16 17:21:34 +00001309 process = gdb_get_process(pid);
Luc Michele40e5202019-01-07 15:23:46 +00001310
1311 if (!process->attached) {
1312 res = -EINVAL;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001313 goto out;
1314 }
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001315
Alex Bennéea346af32020-03-16 17:21:34 +00001316 cpu = get_first_cpu_in_process(process);
Luc Michele40e5202019-01-07 15:23:46 +00001317 while (cpu) {
1318 if (newstates[cpu->cpu_index] == 1) {
1319 newstates[cpu->cpu_index] = cur_action;
1320 }
1321
Alex Bennéea346af32020-03-16 17:21:34 +00001322 cpu = gdb_next_cpu_in_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +00001323 }
1324 break;
1325
1326 case GDB_ONE_THREAD:
Alex Bennéea346af32020-03-16 17:21:34 +00001327 cpu = gdb_get_cpu(pid, tid);
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001328
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001329 /* invalid CPU/thread specified */
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001330 if (!cpu) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001331 res = -EINVAL;
1332 goto out;
1333 }
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001334
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001335 /* only use if no previous match occourred */
1336 if (newstates[cpu->cpu_index] == 1) {
1337 newstates[cpu->cpu_index] = cur_action;
1338 }
Luc Michele40e5202019-01-07 15:23:46 +00001339 break;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001340 }
1341 }
Alex Bennéea346af32020-03-16 17:21:34 +00001342 gdbserver_state.signal = signal;
1343 gdb_continue_partial(newstates);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001344
1345out:
1346 g_free(newstates);
1347
1348 return res;
1349}
1350
Jon Dorond14055d2019-05-29 09:41:29 +03001351typedef union GdbCmdVariant {
1352 const char *data;
1353 uint8_t opcode;
1354 unsigned long val_ul;
1355 unsigned long long val_ull;
1356 struct {
1357 GDBThreadIdKind kind;
1358 uint32_t pid;
1359 uint32_t tid;
1360 } thread_id;
1361} GdbCmdVariant;
1362
Alex Bennée26a16182021-05-25 09:24:14 +01001363#define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
1364
Jon Dorond14055d2019-05-29 09:41:29 +03001365static const char *cmd_next_param(const char *param, const char delimiter)
1366{
1367 static const char all_delimiters[] = ",;:=";
1368 char curr_delimiters[2] = {0};
1369 const char *delimiters;
1370
1371 if (delimiter == '?') {
1372 delimiters = all_delimiters;
1373 } else if (delimiter == '0') {
1374 return strchr(param, '\0');
1375 } else if (delimiter == '.' && *param) {
1376 return param + 1;
1377 } else {
1378 curr_delimiters[0] = delimiter;
1379 delimiters = curr_delimiters;
1380 }
1381
1382 param += strcspn(param, delimiters);
1383 if (*param) {
1384 param++;
1385 }
1386 return param;
1387}
1388
1389static int cmd_parse_params(const char *data, const char *schema,
Alex Bennée26a16182021-05-25 09:24:14 +01001390 GArray *params)
Jon Dorond14055d2019-05-29 09:41:29 +03001391{
Jon Dorond14055d2019-05-29 09:41:29 +03001392 const char *curr_schema, *curr_data;
1393
Alex Bennée26a16182021-05-25 09:24:14 +01001394 g_assert(schema);
1395 g_assert(params->len == 0);
Jon Dorond14055d2019-05-29 09:41:29 +03001396
1397 curr_schema = schema;
Jon Dorond14055d2019-05-29 09:41:29 +03001398 curr_data = data;
1399 while (curr_schema[0] && curr_schema[1] && *curr_data) {
Alex Bennée26a16182021-05-25 09:24:14 +01001400 GdbCmdVariant this_param;
1401
Jon Dorond14055d2019-05-29 09:41:29 +03001402 switch (curr_schema[0]) {
1403 case 'l':
1404 if (qemu_strtoul(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001405 &this_param.val_ul)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001406 return -EINVAL;
1407 }
Jon Dorond14055d2019-05-29 09:41:29 +03001408 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001409 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001410 break;
1411 case 'L':
1412 if (qemu_strtou64(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001413 (uint64_t *)&this_param.val_ull)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001414 return -EINVAL;
1415 }
Jon Dorond14055d2019-05-29 09:41:29 +03001416 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001417 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001418 break;
1419 case 's':
Alex Bennée26a16182021-05-25 09:24:14 +01001420 this_param.data = curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001421 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001422 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001423 break;
1424 case 'o':
Alex Bennée26a16182021-05-25 09:24:14 +01001425 this_param.opcode = *(uint8_t *)curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001426 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001427 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001428 break;
1429 case 't':
Alex Bennée26a16182021-05-25 09:24:14 +01001430 this_param.thread_id.kind =
Jon Dorond14055d2019-05-29 09:41:29 +03001431 read_thread_id(curr_data, &curr_data,
Alex Bennée26a16182021-05-25 09:24:14 +01001432 &this_param.thread_id.pid,
1433 &this_param.thread_id.tid);
Jon Dorond14055d2019-05-29 09:41:29 +03001434 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001435 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001436 break;
1437 case '?':
1438 curr_data = cmd_next_param(curr_data, curr_schema[1]);
1439 break;
1440 default:
1441 return -EINVAL;
1442 }
1443 curr_schema += 2;
1444 }
1445
Jon Dorond14055d2019-05-29 09:41:29 +03001446 return 0;
1447}
1448
Alex Bennée26a16182021-05-25 09:24:14 +01001449typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001450
1451/*
1452 * cmd_startswith -> cmd is compared using startswith
1453 *
1454 *
1455 * schema definitions:
1456 * Each schema parameter entry consists of 2 chars,
1457 * the first char represents the parameter type handling
1458 * the second char represents the delimiter for the next parameter
1459 *
1460 * Currently supported schema types:
1461 * 'l' -> unsigned long (stored in .val_ul)
1462 * 'L' -> unsigned long long (stored in .val_ull)
1463 * 's' -> string (stored in .data)
1464 * 'o' -> single char (stored in .opcode)
1465 * 't' -> thread id (stored in .thread_id)
1466 * '?' -> skip according to delimiter
1467 *
1468 * Currently supported delimiters:
1469 * '?' -> Stop at any delimiter (",;:=\0")
1470 * '0' -> Stop at "\0"
1471 * '.' -> Skip 1 char unless reached "\0"
1472 * Any other value is treated as the delimiter value itself
1473 */
1474typedef struct GdbCmdParseEntry {
1475 GdbCmdHandler handler;
1476 const char *cmd;
1477 bool cmd_startswith;
1478 const char *schema;
1479} GdbCmdParseEntry;
1480
1481static inline int startswith(const char *string, const char *pattern)
1482{
1483 return !strncmp(string, pattern, strlen(pattern));
1484}
1485
Alex Bennéea346af32020-03-16 17:21:34 +00001486static int process_string_cmd(void *user_ctx, const char *data,
Jon Dorond14055d2019-05-29 09:41:29 +03001487 const GdbCmdParseEntry *cmds, int num_cmds)
1488{
Alex Bennée26a16182021-05-25 09:24:14 +01001489 int i;
1490 g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
Jon Dorond14055d2019-05-29 09:41:29 +03001491
1492 if (!cmds) {
1493 return -1;
1494 }
1495
1496 for (i = 0; i < num_cmds; i++) {
1497 const GdbCmdParseEntry *cmd = &cmds[i];
1498 g_assert(cmd->handler && cmd->cmd);
1499
1500 if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1501 (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1502 continue;
1503 }
1504
1505 if (cmd->schema) {
Alex Bennée26a16182021-05-25 09:24:14 +01001506 if (cmd_parse_params(&data[strlen(cmd->cmd)],
1507 cmd->schema, params)) {
1508 return -1;
Jon Dorond14055d2019-05-29 09:41:29 +03001509 }
Jon Dorond14055d2019-05-29 09:41:29 +03001510 }
1511
Alex Bennée26a16182021-05-25 09:24:14 +01001512 cmd->handler(params, user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001513 return 0;
1514 }
1515
1516 return -1;
1517}
1518
Alex Bennéea346af32020-03-16 17:21:34 +00001519static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
Jon Doron3e2c1262019-05-29 09:41:30 +03001520{
1521 if (!data) {
1522 return;
1523 }
1524
Alex Bennée308f9e82020-03-16 17:21:35 +00001525 g_string_set_size(gdbserver_state.str_buf, 0);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001526 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Alex Bennée308f9e82020-03-16 17:21:35 +00001527
Jon Doron3e2c1262019-05-29 09:41:30 +03001528 /* In case there was an error during the command parsing we must
1529 * send a NULL packet to indicate the command is not supported */
Alex Bennéea346af32020-03-16 17:21:34 +00001530 if (process_string_cmd(NULL, data, cmd, 1)) {
1531 put_packet("");
Jon Doron3e2c1262019-05-29 09:41:30 +03001532 }
1533}
1534
Alex Bennée26a16182021-05-25 09:24:14 +01001535static void handle_detach(GArray *params, void *user_ctx)
Jon Doron3e2c1262019-05-29 09:41:30 +03001536{
1537 GDBProcess *process;
Jon Doron3e2c1262019-05-29 09:41:30 +03001538 uint32_t pid = 1;
1539
Alex Bennéea346af32020-03-16 17:21:34 +00001540 if (gdbserver_state.multiprocess) {
Alex Bennée26a16182021-05-25 09:24:14 +01001541 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001542 put_packet("E22");
Jon Doron3e2c1262019-05-29 09:41:30 +03001543 return;
1544 }
1545
Alex Bennée26a16182021-05-25 09:24:14 +01001546 pid = get_param(params, 0)->val_ul;
Jon Doron3e2c1262019-05-29 09:41:30 +03001547 }
1548
Alex Bennéea346af32020-03-16 17:21:34 +00001549 process = gdb_get_process(pid);
1550 gdb_process_breakpoint_remove_all(process);
Jon Doron3e2c1262019-05-29 09:41:30 +03001551 process->attached = false;
1552
Alex Bennéea346af32020-03-16 17:21:34 +00001553 if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1554 gdbserver_state.c_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001555 }
1556
Alex Bennéea346af32020-03-16 17:21:34 +00001557 if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1558 gdbserver_state.g_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001559 }
1560
Alex Bennéea346af32020-03-16 17:21:34 +00001561 if (!gdbserver_state.c_cpu) {
Jon Doron3e2c1262019-05-29 09:41:30 +03001562 /* No more process attached */
1563 gdb_syscall_mode = GDB_SYS_DISABLED;
Alex Bennéea346af32020-03-16 17:21:34 +00001564 gdb_continue();
Jon Doron3e2c1262019-05-29 09:41:30 +03001565 }
Alex Bennéea346af32020-03-16 17:21:34 +00001566 put_packet("OK");
Jon Doron3e2c1262019-05-29 09:41:30 +03001567}
1568
Alex Bennée26a16182021-05-25 09:24:14 +01001569static void handle_thread_alive(GArray *params, void *user_ctx)
Jon Doron44ffded2019-05-29 09:41:31 +03001570{
1571 CPUState *cpu;
1572
Alex Bennée26a16182021-05-25 09:24:14 +01001573 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001574 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001575 return;
1576 }
1577
Alex Bennée26a16182021-05-25 09:24:14 +01001578 if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001579 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001580 return;
1581 }
1582
Alex Bennée26a16182021-05-25 09:24:14 +01001583 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1584 get_param(params, 0)->thread_id.tid);
Jon Doron44ffded2019-05-29 09:41:31 +03001585 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001586 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001587 return;
1588 }
1589
Alex Bennéea346af32020-03-16 17:21:34 +00001590 put_packet("OK");
Jon Doron44ffded2019-05-29 09:41:31 +03001591}
1592
Alex Bennée26a16182021-05-25 09:24:14 +01001593static void handle_continue(GArray *params, void *user_ctx)
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001594{
Alex Bennée26a16182021-05-25 09:24:14 +01001595 if (params->len) {
1596 gdb_set_cpu_pc(get_param(params, 0)->val_ull);
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001597 }
1598
Alex Bennéea346af32020-03-16 17:21:34 +00001599 gdbserver_state.signal = 0;
1600 gdb_continue();
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001601}
1602
Alex Bennée26a16182021-05-25 09:24:14 +01001603static void handle_cont_with_sig(GArray *params, void *user_ctx)
Jon Doronccc47d52019-05-29 09:41:33 +03001604{
1605 unsigned long signal = 0;
1606
1607 /*
1608 * Note: C sig;[addr] is currently unsupported and we simply
1609 * omit the addr parameter
1610 */
Alex Bennée26a16182021-05-25 09:24:14 +01001611 if (params->len) {
1612 signal = get_param(params, 0)->val_ul;
Jon Doronccc47d52019-05-29 09:41:33 +03001613 }
1614
Alex Bennéea346af32020-03-16 17:21:34 +00001615 gdbserver_state.signal = gdb_signal_to_target(signal);
1616 if (gdbserver_state.signal == -1) {
1617 gdbserver_state.signal = 0;
Jon Doronccc47d52019-05-29 09:41:33 +03001618 }
Alex Bennéea346af32020-03-16 17:21:34 +00001619 gdb_continue();
Jon Doronccc47d52019-05-29 09:41:33 +03001620}
1621
Alex Bennée26a16182021-05-25 09:24:14 +01001622static void handle_set_thread(GArray *params, void *user_ctx)
Jon Doron3a9651d2019-05-29 09:41:34 +03001623{
1624 CPUState *cpu;
1625
Alex Bennée26a16182021-05-25 09:24:14 +01001626 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001627 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001628 return;
1629 }
1630
Alex Bennée26a16182021-05-25 09:24:14 +01001631 if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001632 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001633 return;
1634 }
1635
Alex Bennée26a16182021-05-25 09:24:14 +01001636 if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
Alex Bennéea346af32020-03-16 17:21:34 +00001637 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001638 return;
1639 }
1640
Alex Bennée26a16182021-05-25 09:24:14 +01001641 cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1642 get_param(params, 1)->thread_id.tid);
Jon Doron3a9651d2019-05-29 09:41:34 +03001643 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001644 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001645 return;
1646 }
1647
1648 /*
1649 * Note: This command is deprecated and modern gdb's will be using the
1650 * vCont command instead.
1651 */
Alex Bennée26a16182021-05-25 09:24:14 +01001652 switch (get_param(params, 0)->opcode) {
Jon Doron3a9651d2019-05-29 09:41:34 +03001653 case 'c':
Alex Bennéea346af32020-03-16 17:21:34 +00001654 gdbserver_state.c_cpu = cpu;
1655 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001656 break;
1657 case 'g':
Alex Bennéea346af32020-03-16 17:21:34 +00001658 gdbserver_state.g_cpu = cpu;
1659 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001660 break;
1661 default:
Alex Bennéea346af32020-03-16 17:21:34 +00001662 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001663 break;
1664 }
1665}
1666
Alex Bennée26a16182021-05-25 09:24:14 +01001667static void handle_insert_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001668{
1669 int res;
1670
Alex Bennée26a16182021-05-25 09:24:14 +01001671 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001672 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001673 return;
1674 }
1675
Alex Bennée26a16182021-05-25 09:24:14 +01001676 res = gdb_breakpoint_insert(get_param(params, 0)->val_ul,
1677 get_param(params, 1)->val_ull,
1678 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001679 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001680 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001681 return;
1682 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001683 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001684 return;
1685 }
1686
Alex Bennéea346af32020-03-16 17:21:34 +00001687 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001688}
1689
Alex Bennée26a16182021-05-25 09:24:14 +01001690static void handle_remove_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001691{
1692 int res;
1693
Alex Bennée26a16182021-05-25 09:24:14 +01001694 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001695 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001696 return;
1697 }
1698
Alex Bennée26a16182021-05-25 09:24:14 +01001699 res = gdb_breakpoint_remove(get_param(params, 0)->val_ul,
1700 get_param(params, 1)->val_ull,
1701 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001702 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001703 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001704 return;
1705 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001706 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001707 return;
1708 }
1709
Alex Bennéea346af32020-03-16 17:21:34 +00001710 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001711}
1712
Alex Bennée94b2a622019-07-05 14:23:07 +01001713/*
1714 * handle_set/get_reg
1715 *
1716 * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1717 * This works, but can be very slow. Anything new enough to understand
1718 * XML also knows how to use this properly. However to use this we
1719 * need to define a local XML file as well as be talking to a
1720 * reasonably modern gdb. Responding with an empty packet will cause
1721 * the remote gdb to fallback to older methods.
1722 */
1723
Alex Bennée26a16182021-05-25 09:24:14 +01001724static void handle_set_reg(GArray *params, void *user_ctx)
Jon Doron62b33202019-05-29 09:41:36 +03001725{
1726 int reg_size;
1727
1728 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001729 put_packet("");
Jon Doron62b33202019-05-29 09:41:36 +03001730 return;
1731 }
1732
Alex Bennée26a16182021-05-25 09:24:14 +01001733 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001734 put_packet("E22");
Jon Doron62b33202019-05-29 09:41:36 +03001735 return;
1736 }
1737
Alex Bennée26a16182021-05-25 09:24:14 +01001738 reg_size = strlen(get_param(params, 1)->data) / 2;
1739 hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001740 gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
Alex Bennée26a16182021-05-25 09:24:14 +01001741 get_param(params, 0)->val_ull);
Alex Bennéea346af32020-03-16 17:21:34 +00001742 put_packet("OK");
Jon Doron62b33202019-05-29 09:41:36 +03001743}
1744
Alex Bennée26a16182021-05-25 09:24:14 +01001745static void handle_get_reg(GArray *params, void *user_ctx)
Jon Doron5d0e57b2019-05-29 09:41:37 +03001746{
1747 int reg_size;
1748
Jon Doron5d0e57b2019-05-29 09:41:37 +03001749 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001750 put_packet("");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001751 return;
1752 }
1753
Alex Bennée26a16182021-05-25 09:24:14 +01001754 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001755 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001756 return;
1757 }
1758
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001759 reg_size = gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001760 gdbserver_state.mem_buf,
Alex Bennée26a16182021-05-25 09:24:14 +01001761 get_param(params, 0)->val_ull);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001762 if (!reg_size) {
Alex Bennéea346af32020-03-16 17:21:34 +00001763 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001764 return;
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001765 } else {
1766 g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001767 }
1768
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001769 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
Alex Bennée308f9e82020-03-16 17:21:35 +00001770 put_strbuf();
Jon Doron5d0e57b2019-05-29 09:41:37 +03001771}
1772
Alex Bennée26a16182021-05-25 09:24:14 +01001773static void handle_write_mem(GArray *params, void *user_ctx)
Jon Doroncc0ecc72019-05-29 09:41:38 +03001774{
Alex Bennée26a16182021-05-25 09:24:14 +01001775 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001776 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001777 return;
1778 }
1779
1780 /* hextomem() reads 2*len bytes */
Alex Bennée26a16182021-05-25 09:24:14 +01001781 if (get_param(params, 1)->val_ull >
1782 strlen(get_param(params, 2)->data) / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001783 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001784 return;
1785 }
1786
Alex Bennée26a16182021-05-25 09:24:14 +01001787 hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1788 get_param(params, 1)->val_ull);
1789 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1790 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001791 gdbserver_state.mem_buf->data,
1792 gdbserver_state.mem_buf->len, true)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001793 put_packet("E14");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001794 return;
1795 }
1796
Alex Bennéea346af32020-03-16 17:21:34 +00001797 put_packet("OK");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001798}
1799
Alex Bennée26a16182021-05-25 09:24:14 +01001800static void handle_read_mem(GArray *params, void *user_ctx)
Jon Doronda92e232019-05-29 09:41:39 +03001801{
Alex Bennée26a16182021-05-25 09:24:14 +01001802 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001803 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001804 return;
1805 }
1806
1807 /* memtohex() doubles the required space */
Alex Bennée26a16182021-05-25 09:24:14 +01001808 if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001809 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001810 return;
1811 }
1812
Alex Bennée26a16182021-05-25 09:24:14 +01001813 g_byte_array_set_size(gdbserver_state.mem_buf,
1814 get_param(params, 1)->val_ull);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001815
Alex Bennée26a16182021-05-25 09:24:14 +01001816 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1817 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001818 gdbserver_state.mem_buf->data,
1819 gdbserver_state.mem_buf->len, false)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001820 put_packet("E14");
Jon Doronda92e232019-05-29 09:41:39 +03001821 return;
1822 }
1823
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001824 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1825 gdbserver_state.mem_buf->len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001826 put_strbuf();
Jon Doronda92e232019-05-29 09:41:39 +03001827}
1828
Alex Bennée26a16182021-05-25 09:24:14 +01001829static void handle_write_all_regs(GArray *params, void *user_ctx)
Jon Doron287ca122019-05-29 09:41:40 +03001830{
1831 target_ulong addr, len;
1832 uint8_t *registers;
1833 int reg_size;
1834
Alex Bennée26a16182021-05-25 09:24:14 +01001835 if (!params->len) {
Jon Doron287ca122019-05-29 09:41:40 +03001836 return;
1837 }
1838
Alex Bennéea346af32020-03-16 17:21:34 +00001839 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennée26a16182021-05-25 09:24:14 +01001840 len = strlen(get_param(params, 0)->data) / 2;
1841 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001842 registers = gdbserver_state.mem_buf->data;
Alex Bennéea346af32020-03-16 17:21:34 +00001843 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
Jon Doron287ca122019-05-29 09:41:40 +03001844 addr++) {
Alex Bennéea346af32020-03-16 17:21:34 +00001845 reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
Jon Doron287ca122019-05-29 09:41:40 +03001846 len -= reg_size;
1847 registers += reg_size;
1848 }
Alex Bennéea346af32020-03-16 17:21:34 +00001849 put_packet("OK");
Jon Doron287ca122019-05-29 09:41:40 +03001850}
1851
Alex Bennée26a16182021-05-25 09:24:14 +01001852static void handle_read_all_regs(GArray *params, void *user_ctx)
Jon Doron397d1372019-05-29 09:41:41 +03001853{
1854 target_ulong addr, len;
1855
Alex Bennéea346af32020-03-16 17:21:34 +00001856 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennéea010bdb2020-03-16 17:21:41 +00001857 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Jon Doron397d1372019-05-29 09:41:41 +03001858 len = 0;
Alex Bennéea346af32020-03-16 17:21:34 +00001859 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001860 len += gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001861 gdbserver_state.mem_buf,
Jon Doron397d1372019-05-29 09:41:41 +03001862 addr);
1863 }
Alex Bennéea010bdb2020-03-16 17:21:41 +00001864 g_assert(len == gdbserver_state.mem_buf->len);
Jon Doron397d1372019-05-29 09:41:41 +03001865
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001866 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001867 put_strbuf();
Jon Doron397d1372019-05-29 09:41:41 +03001868}
1869
Alex Bennée26a16182021-05-25 09:24:14 +01001870static void handle_file_io(GArray *params, void *user_ctx)
Jon Doron4b20fab2019-05-29 09:41:42 +03001871{
Alex Bennée26a16182021-05-25 09:24:14 +01001872 if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
Jon Doron4b20fab2019-05-29 09:41:42 +03001873 target_ulong ret, err;
1874
Alex Bennée26a16182021-05-25 09:24:14 +01001875 ret = (target_ulong)get_param(params, 0)->val_ull;
1876 if (params->len >= 2) {
1877 err = (target_ulong)get_param(params, 1)->val_ull;
Sandra Loosemorec6ee9522019-08-27 16:33:17 -06001878 } else {
1879 err = 0;
1880 }
Alex Bennéea346af32020-03-16 17:21:34 +00001881 gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1882 gdbserver_state.current_syscall_cb = NULL;
Jon Doron4b20fab2019-05-29 09:41:42 +03001883 }
1884
Alex Bennée26a16182021-05-25 09:24:14 +01001885 if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
Alex Bennéea346af32020-03-16 17:21:34 +00001886 put_packet("T02");
Jon Doron4b20fab2019-05-29 09:41:42 +03001887 return;
1888 }
1889
Alex Bennéea346af32020-03-16 17:21:34 +00001890 gdb_continue();
Jon Doron4b20fab2019-05-29 09:41:42 +03001891}
1892
Alex Bennée26a16182021-05-25 09:24:14 +01001893static void handle_step(GArray *params, void *user_ctx)
Jon Doron933f80d2019-05-29 09:41:43 +03001894{
Alex Bennée26a16182021-05-25 09:24:14 +01001895 if (params->len) {
1896 gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
Jon Doron933f80d2019-05-29 09:41:43 +03001897 }
1898
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001899 cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
Alex Bennéea346af32020-03-16 17:21:34 +00001900 gdb_continue();
Jon Doron933f80d2019-05-29 09:41:43 +03001901}
1902
Alex Bennée26a16182021-05-25 09:24:14 +01001903static void handle_backward(GArray *params, void *user_ctx)
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001904{
Alex Bennéeed12f5b2021-05-20 18:43:02 +01001905 if (!stub_can_reverse()) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001906 put_packet("E22");
1907 }
Alex Bennée26a16182021-05-25 09:24:14 +01001908 if (params->len == 1) {
1909 switch (get_param(params, 0)->opcode) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001910 case 's':
1911 if (replay_reverse_step()) {
1912 gdb_continue();
1913 } else {
1914 put_packet("E14");
1915 }
1916 return;
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03001917 case 'c':
1918 if (replay_reverse_continue()) {
1919 gdb_continue();
1920 } else {
1921 put_packet("E14");
1922 }
1923 return;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001924 }
1925 }
1926
1927 /* Default invalid command */
1928 put_packet("");
1929}
1930
Alex Bennée26a16182021-05-25 09:24:14 +01001931static void handle_v_cont_query(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001932{
Alex Bennéea346af32020-03-16 17:21:34 +00001933 put_packet("vCont;c;C;s;S");
Jon Doron8536ec02019-05-29 09:41:44 +03001934}
1935
Alex Bennée26a16182021-05-25 09:24:14 +01001936static void handle_v_cont(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001937{
1938 int res;
1939
Alex Bennée26a16182021-05-25 09:24:14 +01001940 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001941 return;
1942 }
1943
Alex Bennée26a16182021-05-25 09:24:14 +01001944 res = gdb_handle_vcont(get_param(params, 0)->data);
Jon Doron8536ec02019-05-29 09:41:44 +03001945 if ((res == -EINVAL) || (res == -ERANGE)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001946 put_packet("E22");
Jon Doron8536ec02019-05-29 09:41:44 +03001947 } else if (res) {
Alex Bennéea346af32020-03-16 17:21:34 +00001948 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03001949 }
1950}
1951
Alex Bennée26a16182021-05-25 09:24:14 +01001952static void handle_v_attach(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001953{
1954 GDBProcess *process;
1955 CPUState *cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001956
Alex Bennée308f9e82020-03-16 17:21:35 +00001957 g_string_assign(gdbserver_state.str_buf, "E22");
Alex Bennée26a16182021-05-25 09:24:14 +01001958 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001959 goto cleanup;
1960 }
1961
Alex Bennée26a16182021-05-25 09:24:14 +01001962 process = gdb_get_process(get_param(params, 0)->val_ul);
Jon Doron8536ec02019-05-29 09:41:44 +03001963 if (!process) {
1964 goto cleanup;
1965 }
1966
Alex Bennéea346af32020-03-16 17:21:34 +00001967 cpu = get_first_cpu_in_process(process);
Jon Doron8536ec02019-05-29 09:41:44 +03001968 if (!cpu) {
1969 goto cleanup;
1970 }
1971
1972 process->attached = true;
Alex Bennéea346af32020-03-16 17:21:34 +00001973 gdbserver_state.g_cpu = cpu;
1974 gdbserver_state.c_cpu = cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001975
Alex Bennée308f9e82020-03-16 17:21:35 +00001976 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
1977 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
1978 g_string_append_c(gdbserver_state.str_buf, ';');
Jon Doron8536ec02019-05-29 09:41:44 +03001979cleanup:
Alex Bennée308f9e82020-03-16 17:21:35 +00001980 put_strbuf();
Jon Doron8536ec02019-05-29 09:41:44 +03001981}
1982
Alex Bennée26a16182021-05-25 09:24:14 +01001983static void handle_v_kill(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001984{
1985 /* Kill the target */
Alex Bennéea346af32020-03-16 17:21:34 +00001986 put_packet("OK");
Jon Doron8536ec02019-05-29 09:41:44 +03001987 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00001988 gdb_exit(0);
Jon Doron8536ec02019-05-29 09:41:44 +03001989 exit(0);
1990}
1991
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01001992static const GdbCmdParseEntry gdb_v_commands_table[] = {
Jon Doron8536ec02019-05-29 09:41:44 +03001993 /* Order is important if has same prefix */
1994 {
1995 .handler = handle_v_cont_query,
1996 .cmd = "Cont?",
1997 .cmd_startswith = 1
1998 },
1999 {
2000 .handler = handle_v_cont,
2001 .cmd = "Cont",
2002 .cmd_startswith = 1,
2003 .schema = "s0"
2004 },
2005 {
2006 .handler = handle_v_attach,
2007 .cmd = "Attach;",
2008 .cmd_startswith = 1,
2009 .schema = "l0"
2010 },
2011 {
2012 .handler = handle_v_kill,
2013 .cmd = "Kill;",
2014 .cmd_startswith = 1
2015 },
2016};
2017
Alex Bennée26a16182021-05-25 09:24:14 +01002018static void handle_v_commands(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03002019{
Alex Bennée26a16182021-05-25 09:24:14 +01002020 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03002021 return;
2022 }
2023
Alex Bennée26a16182021-05-25 09:24:14 +01002024 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron8536ec02019-05-29 09:41:44 +03002025 gdb_v_commands_table,
2026 ARRAY_SIZE(gdb_v_commands_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002027 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03002028 }
2029}
2030
Alex Bennée26a16182021-05-25 09:24:14 +01002031static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002032{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002033 g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
2034
2035 if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
2036 g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
2037 SSTEP_NOIRQ);
2038 }
2039
2040 if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
2041 g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
2042 SSTEP_NOTIMER);
2043 }
2044
Alex Bennée308f9e82020-03-16 17:21:35 +00002045 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002046}
2047
Alex Bennée26a16182021-05-25 09:24:14 +01002048static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002049{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002050 int new_sstep_flags;
2051
Alex Bennée26a16182021-05-25 09:24:14 +01002052 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002053 return;
2054 }
2055
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002056 new_sstep_flags = get_param(params, 0)->val_ul;
2057
2058 if (new_sstep_flags & ~gdbserver_state.supported_sstep_flags) {
2059 put_packet("E22");
2060 return;
2061 }
2062
2063 gdbserver_state.sstep_flags = new_sstep_flags;
Alex Bennéea346af32020-03-16 17:21:34 +00002064 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002065}
2066
Alex Bennée26a16182021-05-25 09:24:14 +01002067static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002068{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002069 g_string_printf(gdbserver_state.str_buf, "0x%x",
2070 gdbserver_state.sstep_flags);
Alex Bennée308f9e82020-03-16 17:21:35 +00002071 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002072}
2073
Alex Bennée26a16182021-05-25 09:24:14 +01002074static void handle_query_curr_tid(GArray *params, void *user_ctx)
bellardb4608c02003-06-27 17:34:32 +00002075{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002076 CPUState *cpu;
Luc Michelc145eea2019-01-07 15:23:46 +00002077 GDBProcess *process;
Jon Doron2704efa2019-05-29 09:41:45 +03002078
2079 /*
2080 * "Current thread" remains vague in the spec, so always return
2081 * the first thread of the current process (gdb returns the
2082 * first thread).
2083 */
Alex Bennéea346af32020-03-16 17:21:34 +00002084 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2085 cpu = get_first_cpu_in_process(process);
Alex Bennée308f9e82020-03-16 17:21:35 +00002086 g_string_assign(gdbserver_state.str_buf, "QC");
2087 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2088 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002089}
2090
Alex Bennée26a16182021-05-25 09:24:14 +01002091static void handle_query_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002092{
Alex Bennéea346af32020-03-16 17:21:34 +00002093 if (!gdbserver_state.query_cpu) {
2094 put_packet("l");
Jon Doron2704efa2019-05-29 09:41:45 +03002095 return;
2096 }
2097
Alex Bennée308f9e82020-03-16 17:21:35 +00002098 g_string_assign(gdbserver_state.str_buf, "m");
2099 gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
2100 put_strbuf();
Alex Bennéea346af32020-03-16 17:21:34 +00002101 gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002102}
2103
Alex Bennée26a16182021-05-25 09:24:14 +01002104static void handle_query_first_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002105{
Alex Bennéea346af32020-03-16 17:21:34 +00002106 gdbserver_state.query_cpu = gdb_first_attached_cpu();
Alex Bennée26a16182021-05-25 09:24:14 +01002107 handle_query_threads(params, user_ctx);
Jon Doron2704efa2019-05-29 09:41:45 +03002108}
2109
Alex Bennée26a16182021-05-25 09:24:14 +01002110static void handle_query_thread_extra(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002111{
Alex Bennée308f9e82020-03-16 17:21:35 +00002112 g_autoptr(GString) rs = g_string_new(NULL);
Jon Doron2704efa2019-05-29 09:41:45 +03002113 CPUState *cpu;
Jon Doron2704efa2019-05-29 09:41:45 +03002114
Alex Bennée26a16182021-05-25 09:24:14 +01002115 if (!params->len ||
2116 get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00002117 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002118 return;
2119 }
2120
Alex Bennée26a16182021-05-25 09:24:14 +01002121 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
2122 get_param(params, 0)->thread_id.tid);
Jon Doron2704efa2019-05-29 09:41:45 +03002123 if (!cpu) {
2124 return;
2125 }
2126
2127 cpu_synchronize_state(cpu);
2128
Alex Bennéea346af32020-03-16 17:21:34 +00002129 if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
Jon Doron2704efa2019-05-29 09:41:45 +03002130 /* Print the CPU model and name in multiprocess mode */
2131 ObjectClass *oc = object_get_class(OBJECT(cpu));
2132 const char *cpu_model = object_class_get_name(oc);
Markus Armbruster7a309cc2020-07-14 18:02:00 +02002133 const char *cpu_name =
Denis Plotnikov076b2fa2020-04-03 20:11:44 +01002134 object_get_canonical_path_component(OBJECT(cpu));
Alex Bennée308f9e82020-03-16 17:21:35 +00002135 g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
2136 cpu->halted ? "halted " : "running");
Jon Doron2704efa2019-05-29 09:41:45 +03002137 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002138 g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
Jon Doron2704efa2019-05-29 09:41:45 +03002139 cpu->halted ? "halted " : "running");
2140 }
Alex Bennée308f9e82020-03-16 17:21:35 +00002141 trace_gdbstub_op_extra_info(rs->str);
2142 memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
2143 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002144}
2145
2146#ifdef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002147static void handle_query_offsets(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002148{
2149 TaskState *ts;
2150
Alex Bennéea346af32020-03-16 17:21:34 +00002151 ts = gdbserver_state.c_cpu->opaque;
Alex Bennée308f9e82020-03-16 17:21:35 +00002152 g_string_printf(gdbserver_state.str_buf,
2153 "Text=" TARGET_ABI_FMT_lx
2154 ";Data=" TARGET_ABI_FMT_lx
2155 ";Bss=" TARGET_ABI_FMT_lx,
2156 ts->info->code_offset,
2157 ts->info->data_offset,
2158 ts->info->data_offset);
2159 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002160}
2161#else
Alex Bennée26a16182021-05-25 09:24:14 +01002162static void handle_query_rcmd(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002163{
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002164 const guint8 zero = 0;
Jon Doron2704efa2019-05-29 09:41:45 +03002165 int len;
2166
Alex Bennée26a16182021-05-25 09:24:14 +01002167 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002168 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002169 return;
2170 }
2171
Alex Bennée26a16182021-05-25 09:24:14 +01002172 len = strlen(get_param(params, 0)->data);
Jon Doron2704efa2019-05-29 09:41:45 +03002173 if (len % 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00002174 put_packet("E01");
Jon Doron2704efa2019-05-29 09:41:45 +03002175 return;
2176 }
2177
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002178 g_assert(gdbserver_state.mem_buf->len == 0);
Jon Doron2704efa2019-05-29 09:41:45 +03002179 len = len / 2;
Alex Bennée26a16182021-05-25 09:24:14 +01002180 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002181 g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
2182 qemu_chr_be_write(gdbserver_state.mon_chr, gdbserver_state.mem_buf->data,
2183 gdbserver_state.mem_buf->len);
Alex Bennéea346af32020-03-16 17:21:34 +00002184 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002185}
2186#endif
2187
Alex Bennée26a16182021-05-25 09:24:14 +01002188static void handle_query_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002189{
Andreas Färber5b24c642013-07-07 15:08:22 +02002190 CPUClass *cc;
Jon Doron2704efa2019-05-29 09:41:45 +03002191
Alex Bennée308f9e82020-03-16 17:21:35 +00002192 g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
Jon Doron2704efa2019-05-29 09:41:45 +03002193 cc = CPU_GET_CLASS(first_cpu);
2194 if (cc->gdb_core_xml_file) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002195 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
Jon Doron2704efa2019-05-29 09:41:45 +03002196 }
2197
Alex Bennéeed12f5b2021-05-20 18:43:02 +01002198 if (stub_can_reverse()) {
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03002199 g_string_append(gdbserver_state.str_buf,
2200 ";ReverseStep+;ReverseContinue+");
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002201 }
2202
Lirong Yuan51c623b2021-01-08 22:42:42 +00002203#ifdef CONFIG_USER_ONLY
2204 if (gdbserver_state.c_cpu->opaque) {
2205 g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
2206 }
2207#endif
2208
Alex Bennée26a16182021-05-25 09:24:14 +01002209 if (params->len &&
2210 strstr(get_param(params, 0)->data, "multiprocess+")) {
Alex Bennéea346af32020-03-16 17:21:34 +00002211 gdbserver_state.multiprocess = true;
Jon Doron2704efa2019-05-29 09:41:45 +03002212 }
2213
Changbin Du3bc26092020-03-16 17:21:55 +00002214 g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
Alex Bennée308f9e82020-03-16 17:21:35 +00002215 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002216}
2217
Alex Bennée26a16182021-05-25 09:24:14 +01002218static void handle_query_xfer_features(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002219{
2220 GDBProcess *process;
2221 CPUClass *cc;
2222 unsigned long len, total_len, addr;
2223 const char *xml;
bellardb4608c02003-06-27 17:34:32 +00002224 const char *p;
Jon Doron2704efa2019-05-29 09:41:45 +03002225
Alex Bennée26a16182021-05-25 09:24:14 +01002226 if (params->len < 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00002227 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002228 return;
2229 }
2230
Alex Bennéea346af32020-03-16 17:21:34 +00002231 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2232 cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002233 if (!cc->gdb_core_xml_file) {
Alex Bennéea346af32020-03-16 17:21:34 +00002234 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002235 return;
2236 }
2237
2238 gdb_has_xml = true;
Alex Bennée26a16182021-05-25 09:24:14 +01002239 p = get_param(params, 0)->data;
Alex Bennéea346af32020-03-16 17:21:34 +00002240 xml = get_feature_xml(p, &p, process);
Jon Doron2704efa2019-05-29 09:41:45 +03002241 if (!xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00002242 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002243 return;
2244 }
2245
Alex Bennée26a16182021-05-25 09:24:14 +01002246 addr = get_param(params, 1)->val_ul;
2247 len = get_param(params, 2)->val_ul;
Jon Doron2704efa2019-05-29 09:41:45 +03002248 total_len = strlen(xml);
2249 if (addr > total_len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002250 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002251 return;
2252 }
2253
2254 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2255 len = (MAX_PACKET_LENGTH - 5) / 2;
2256 }
2257
2258 if (len < total_len - addr) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002259 g_string_assign(gdbserver_state.str_buf, "m");
2260 memtox(gdbserver_state.str_buf, xml + addr, len);
Jon Doron2704efa2019-05-29 09:41:45 +03002261 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002262 g_string_assign(gdbserver_state.str_buf, "l");
2263 memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
Jon Doron2704efa2019-05-29 09:41:45 +03002264 }
2265
Alex Bennée308f9e82020-03-16 17:21:35 +00002266 put_packet_binary(gdbserver_state.str_buf->str,
2267 gdbserver_state.str_buf->len, true);
Jon Doron2704efa2019-05-29 09:41:45 +03002268}
2269
Lirong Yuan51c623b2021-01-08 22:42:42 +00002270#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
Alex Bennée26a16182021-05-25 09:24:14 +01002271static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
Lirong Yuan51c623b2021-01-08 22:42:42 +00002272{
2273 TaskState *ts;
2274 unsigned long offset, len, saved_auxv, auxv_len;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002275
Alex Bennée26a16182021-05-25 09:24:14 +01002276 if (params->len < 2) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002277 put_packet("E22");
2278 return;
2279 }
2280
Alex Bennée26a16182021-05-25 09:24:14 +01002281 offset = get_param(params, 0)->val_ul;
2282 len = get_param(params, 1)->val_ul;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002283 ts = gdbserver_state.c_cpu->opaque;
2284 saved_auxv = ts->info->saved_auxv;
2285 auxv_len = ts->info->auxv_len;
Richard Henderson6e3dd752021-02-02 13:39:55 +00002286
2287 if (offset >= auxv_len) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002288 put_packet("E00");
2289 return;
2290 }
2291
2292 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2293 len = (MAX_PACKET_LENGTH - 5) / 2;
2294 }
2295
2296 if (len < auxv_len - offset) {
2297 g_string_assign(gdbserver_state.str_buf, "m");
Lirong Yuan51c623b2021-01-08 22:42:42 +00002298 } else {
2299 g_string_assign(gdbserver_state.str_buf, "l");
Richard Henderson6e3dd752021-02-02 13:39:55 +00002300 len = auxv_len - offset;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002301 }
2302
Richard Henderson6e3dd752021-02-02 13:39:55 +00002303 g_byte_array_set_size(gdbserver_state.mem_buf, len);
2304 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2305 gdbserver_state.mem_buf->data, len, false)) {
2306 put_packet("E14");
2307 return;
2308 }
2309
2310 memtox(gdbserver_state.str_buf,
2311 (const char *)gdbserver_state.mem_buf->data, len);
Lirong Yuan51c623b2021-01-08 22:42:42 +00002312 put_packet_binary(gdbserver_state.str_buf->str,
2313 gdbserver_state.str_buf->len, true);
2314}
2315#endif
2316
Alex Bennée26a16182021-05-25 09:24:14 +01002317static void handle_query_attached(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002318{
Alex Bennéea346af32020-03-16 17:21:34 +00002319 put_packet(GDB_ATTACHED);
Jon Doron2704efa2019-05-29 09:41:45 +03002320}
2321
Alex Bennée26a16182021-05-25 09:24:14 +01002322static void handle_query_qemu_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002323{
Alex Bennée308f9e82020-03-16 17:21:35 +00002324 g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
Jon Doronab4752e2019-05-29 09:41:48 +03002325#ifndef CONFIG_USER_ONLY
Alex Bennée308f9e82020-03-16 17:21:35 +00002326 g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
Jon Doronab4752e2019-05-29 09:41:48 +03002327#endif
Alex Bennée308f9e82020-03-16 17:21:35 +00002328 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002329}
2330
Jon Doronab4752e2019-05-29 09:41:48 +03002331#ifndef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002332static void handle_query_qemu_phy_mem_mode(GArray *params,
Jon Doronab4752e2019-05-29 09:41:48 +03002333 void *user_ctx)
2334{
Alex Bennée308f9e82020-03-16 17:21:35 +00002335 g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
2336 put_strbuf();
Jon Doronab4752e2019-05-29 09:41:48 +03002337}
2338
Alex Bennée26a16182021-05-25 09:24:14 +01002339static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
Jon Doronab4752e2019-05-29 09:41:48 +03002340{
Alex Bennée26a16182021-05-25 09:24:14 +01002341 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002342 put_packet("E22");
Jon Doronab4752e2019-05-29 09:41:48 +03002343 return;
2344 }
2345
Alex Bennée26a16182021-05-25 09:24:14 +01002346 if (!get_param(params, 0)->val_ul) {
Jon Doronab4752e2019-05-29 09:41:48 +03002347 phy_memory_mode = 0;
2348 } else {
2349 phy_memory_mode = 1;
2350 }
Alex Bennéea346af32020-03-16 17:21:34 +00002351 put_packet("OK");
Jon Doronab4752e2019-05-29 09:41:48 +03002352}
2353#endif
2354
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002355static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002356 /* Order is important if has same prefix */
2357 {
2358 .handler = handle_query_qemu_sstepbits,
2359 .cmd = "qemu.sstepbits",
2360 },
2361 {
2362 .handler = handle_query_qemu_sstep,
2363 .cmd = "qemu.sstep",
2364 },
2365 {
2366 .handler = handle_set_qemu_sstep,
2367 .cmd = "qemu.sstep=",
2368 .cmd_startswith = 1,
2369 .schema = "l0"
2370 },
2371};
2372
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002373static const GdbCmdParseEntry gdb_gen_query_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002374 {
2375 .handler = handle_query_curr_tid,
2376 .cmd = "C",
2377 },
2378 {
2379 .handler = handle_query_threads,
2380 .cmd = "sThreadInfo",
2381 },
2382 {
2383 .handler = handle_query_first_threads,
2384 .cmd = "fThreadInfo",
2385 },
2386 {
2387 .handler = handle_query_thread_extra,
2388 .cmd = "ThreadExtraInfo,",
2389 .cmd_startswith = 1,
2390 .schema = "t0"
2391 },
2392#ifdef CONFIG_USER_ONLY
2393 {
2394 .handler = handle_query_offsets,
2395 .cmd = "Offsets",
2396 },
2397#else
2398 {
2399 .handler = handle_query_rcmd,
2400 .cmd = "Rcmd,",
2401 .cmd_startswith = 1,
2402 .schema = "s0"
2403 },
2404#endif
2405 {
2406 .handler = handle_query_supported,
2407 .cmd = "Supported:",
2408 .cmd_startswith = 1,
2409 .schema = "s0"
2410 },
2411 {
2412 .handler = handle_query_supported,
2413 .cmd = "Supported",
2414 .schema = "s0"
2415 },
2416 {
2417 .handler = handle_query_xfer_features,
2418 .cmd = "Xfer:features:read:",
2419 .cmd_startswith = 1,
2420 .schema = "s:l,l0"
2421 },
Lirong Yuan51c623b2021-01-08 22:42:42 +00002422#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2423 {
2424 .handler = handle_query_xfer_auxv,
2425 .cmd = "Xfer:auxv:read::",
2426 .cmd_startswith = 1,
2427 .schema = "l,l0"
2428 },
2429#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002430 {
2431 .handler = handle_query_attached,
2432 .cmd = "Attached:",
2433 .cmd_startswith = 1
2434 },
2435 {
2436 .handler = handle_query_attached,
2437 .cmd = "Attached",
2438 },
2439 {
2440 .handler = handle_query_qemu_supported,
2441 .cmd = "qemu.Supported",
2442 },
Jon Doronab4752e2019-05-29 09:41:48 +03002443#ifndef CONFIG_USER_ONLY
2444 {
2445 .handler = handle_query_qemu_phy_mem_mode,
2446 .cmd = "qemu.PhyMemMode",
2447 },
2448#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002449};
2450
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002451static const GdbCmdParseEntry gdb_gen_set_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002452 /* Order is important if has same prefix */
2453 {
2454 .handler = handle_set_qemu_sstep,
2455 .cmd = "qemu.sstep:",
2456 .cmd_startswith = 1,
2457 .schema = "l0"
2458 },
Jon Doronab4752e2019-05-29 09:41:48 +03002459#ifndef CONFIG_USER_ONLY
2460 {
2461 .handler = handle_set_qemu_phy_mem_mode,
2462 .cmd = "qemu.PhyMemMode:",
2463 .cmd_startswith = 1,
2464 .schema = "l0"
2465 },
2466#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002467};
2468
Alex Bennée26a16182021-05-25 09:24:14 +01002469static void handle_gen_query(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002470{
Alex Bennée26a16182021-05-25 09:24:14 +01002471 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002472 return;
2473 }
2474
Alex Bennée26a16182021-05-25 09:24:14 +01002475 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002476 gdb_gen_query_set_common_table,
2477 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2478 return;
2479 }
2480
Alex Bennée26a16182021-05-25 09:24:14 +01002481 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002482 gdb_gen_query_table,
2483 ARRAY_SIZE(gdb_gen_query_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002484 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002485 }
2486}
2487
Alex Bennée26a16182021-05-25 09:24:14 +01002488static void handle_gen_set(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002489{
Alex Bennée26a16182021-05-25 09:24:14 +01002490 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002491 return;
2492 }
2493
Alex Bennée26a16182021-05-25 09:24:14 +01002494 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002495 gdb_gen_query_set_common_table,
2496 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2497 return;
2498 }
2499
Alex Bennée26a16182021-05-25 09:24:14 +01002500 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002501 gdb_gen_set_table,
2502 ARRAY_SIZE(gdb_gen_set_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002503 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002504 }
2505}
2506
Alex Bennée26a16182021-05-25 09:24:14 +01002507static void handle_target_halt(GArray *params, void *user_ctx)
Jon Doron7009d572019-05-29 09:41:46 +03002508{
Alex Bennée308f9e82020-03-16 17:21:35 +00002509 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2510 gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2511 g_string_append_c(gdbserver_state.str_buf, ';');
2512 put_strbuf();
Jon Doron7009d572019-05-29 09:41:46 +03002513 /*
2514 * Remove all the breakpoints when this query is issued,
2515 * because gdb is doing an initial connect and the state
2516 * should be cleaned up.
2517 */
2518 gdb_breakpoint_remove_all();
2519}
2520
Alex Bennéea346af32020-03-16 17:21:34 +00002521static int gdb_handle_packet(const char *line_buf)
Jon Doron2704efa2019-05-29 09:41:45 +03002522{
Jon Doron3e2c1262019-05-29 09:41:30 +03002523 const GdbCmdParseEntry *cmd_parser = NULL;
ths3b46e622007-09-17 08:09:54 +00002524
Doug Gale5c9522b2017-12-02 20:30:37 -05002525 trace_gdbstub_io_command(line_buf);
Alex Bennée118e2262017-07-12 11:52:13 +01002526
Jon Doron3f1cbac2019-05-29 09:41:47 +03002527 switch (line_buf[0]) {
Luc Michel53fd6552019-01-07 15:23:46 +00002528 case '!':
Alex Bennéea346af32020-03-16 17:21:34 +00002529 put_packet("OK");
Luc Michel53fd6552019-01-07 15:23:46 +00002530 break;
bellard858693c2004-03-31 18:52:07 +00002531 case '?':
Jon Doron7009d572019-05-29 09:41:46 +03002532 {
2533 static const GdbCmdParseEntry target_halted_cmd_desc = {
2534 .handler = handle_target_halt,
2535 .cmd = "?",
2536 .cmd_startswith = 1
2537 };
2538 cmd_parser = &target_halted_cmd_desc;
2539 }
bellard858693c2004-03-31 18:52:07 +00002540 break;
2541 case 'c':
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002542 {
2543 static const GdbCmdParseEntry continue_cmd_desc = {
2544 .handler = handle_continue,
2545 .cmd = "c",
2546 .cmd_startswith = 1,
2547 .schema = "L0"
2548 };
2549 cmd_parser = &continue_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002550 }
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002551 break;
edgar_igl1f487ee2008-05-17 22:20:53 +00002552 case 'C':
Jon Doronccc47d52019-05-29 09:41:33 +03002553 {
2554 static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2555 .handler = handle_cont_with_sig,
2556 .cmd = "C",
2557 .cmd_startswith = 1,
2558 .schema = "l0"
2559 };
2560 cmd_parser = &cont_with_sig_cmd_desc;
2561 }
2562 break;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002563 case 'v':
Jon Doron8536ec02019-05-29 09:41:44 +03002564 {
2565 static const GdbCmdParseEntry v_cmd_desc = {
2566 .handler = handle_v_commands,
2567 .cmd = "v",
2568 .cmd_startswith = 1,
2569 .schema = "s0"
2570 };
2571 cmd_parser = &v_cmd_desc;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002572 }
Jon Doron8536ec02019-05-29 09:41:44 +03002573 break;
edgar_igl7d03f822008-05-17 18:58:29 +00002574 case 'k':
2575 /* Kill the target */
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002576 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00002577 gdb_exit(0);
edgar_igl7d03f822008-05-17 18:58:29 +00002578 exit(0);
2579 case 'D':
Jon Doron3e2c1262019-05-29 09:41:30 +03002580 {
2581 static const GdbCmdParseEntry detach_cmd_desc = {
2582 .handler = handle_detach,
2583 .cmd = "D",
2584 .cmd_startswith = 1,
2585 .schema = "?.l0"
2586 };
2587 cmd_parser = &detach_cmd_desc;
Luc Michel546f3c62019-01-07 15:23:46 +00002588 }
edgar_igl7d03f822008-05-17 18:58:29 +00002589 break;
bellard858693c2004-03-31 18:52:07 +00002590 case 's':
Jon Doron933f80d2019-05-29 09:41:43 +03002591 {
2592 static const GdbCmdParseEntry step_cmd_desc = {
2593 .handler = handle_step,
2594 .cmd = "s",
2595 .cmd_startswith = 1,
2596 .schema = "L0"
2597 };
2598 cmd_parser = &step_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002599 }
Jon Doron933f80d2019-05-29 09:41:43 +03002600 break;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002601 case 'b':
2602 {
2603 static const GdbCmdParseEntry backward_cmd_desc = {
2604 .handler = handle_backward,
2605 .cmd = "b",
2606 .cmd_startswith = 1,
2607 .schema = "o0"
2608 };
2609 cmd_parser = &backward_cmd_desc;
2610 }
2611 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002612 case 'F':
2613 {
Jon Doron4b20fab2019-05-29 09:41:42 +03002614 static const GdbCmdParseEntry file_io_cmd_desc = {
2615 .handler = handle_file_io,
2616 .cmd = "F",
2617 .cmd_startswith = 1,
2618 .schema = "L,L,o0"
2619 };
2620 cmd_parser = &file_io_cmd_desc;
pbrooka2d1eba2007-01-28 03:10:55 +00002621 }
2622 break;
bellard858693c2004-03-31 18:52:07 +00002623 case 'g':
Jon Doron397d1372019-05-29 09:41:41 +03002624 {
2625 static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2626 .handler = handle_read_all_regs,
2627 .cmd = "g",
2628 .cmd_startswith = 1
2629 };
2630 cmd_parser = &read_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002631 }
bellard858693c2004-03-31 18:52:07 +00002632 break;
2633 case 'G':
Jon Doron287ca122019-05-29 09:41:40 +03002634 {
2635 static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2636 .handler = handle_write_all_regs,
2637 .cmd = "G",
2638 .cmd_startswith = 1,
2639 .schema = "s0"
2640 };
2641 cmd_parser = &write_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002642 }
bellard858693c2004-03-31 18:52:07 +00002643 break;
2644 case 'm':
Jon Doronda92e232019-05-29 09:41:39 +03002645 {
2646 static const GdbCmdParseEntry read_mem_cmd_desc = {
2647 .handler = handle_read_mem,
2648 .cmd = "m",
2649 .cmd_startswith = 1,
2650 .schema = "L,L0"
2651 };
2652 cmd_parser = &read_mem_cmd_desc;
bellard6f970bd2005-12-05 19:55:19 +00002653 }
bellard858693c2004-03-31 18:52:07 +00002654 break;
2655 case 'M':
Jon Doroncc0ecc72019-05-29 09:41:38 +03002656 {
2657 static const GdbCmdParseEntry write_mem_cmd_desc = {
2658 .handler = handle_write_mem,
2659 .cmd = "M",
2660 .cmd_startswith = 1,
2661 .schema = "L,L:s0"
2662 };
2663 cmd_parser = &write_mem_cmd_desc;
Fabien Chouteau44520db2011-09-08 12:48:16 +02002664 }
bellard858693c2004-03-31 18:52:07 +00002665 break;
pbrook56aebc82008-10-11 17:55:29 +00002666 case 'p':
Jon Doron5d0e57b2019-05-29 09:41:37 +03002667 {
2668 static const GdbCmdParseEntry get_reg_cmd_desc = {
2669 .handler = handle_get_reg,
2670 .cmd = "p",
2671 .cmd_startswith = 1,
2672 .schema = "L0"
2673 };
2674 cmd_parser = &get_reg_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002675 }
2676 break;
2677 case 'P':
Jon Doron62b33202019-05-29 09:41:36 +03002678 {
2679 static const GdbCmdParseEntry set_reg_cmd_desc = {
2680 .handler = handle_set_reg,
2681 .cmd = "P",
2682 .cmd_startswith = 1,
2683 .schema = "L?s0"
2684 };
2685 cmd_parser = &set_reg_cmd_desc;
2686 }
pbrook56aebc82008-10-11 17:55:29 +00002687 break;
bellard858693c2004-03-31 18:52:07 +00002688 case 'Z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002689 {
2690 static const GdbCmdParseEntry insert_bp_cmd_desc = {
2691 .handler = handle_insert_bp,
2692 .cmd = "Z",
2693 .cmd_startswith = 1,
2694 .schema = "l?L?L0"
2695 };
2696 cmd_parser = &insert_bp_cmd_desc;
2697 }
2698 break;
bellard858693c2004-03-31 18:52:07 +00002699 case 'z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002700 {
2701 static const GdbCmdParseEntry remove_bp_cmd_desc = {
2702 .handler = handle_remove_bp,
2703 .cmd = "z",
2704 .cmd_startswith = 1,
2705 .schema = "l?L?L0"
2706 };
2707 cmd_parser = &remove_bp_cmd_desc;
2708 }
bellard858693c2004-03-31 18:52:07 +00002709 break;
aliguori880a7572008-11-18 20:30:24 +00002710 case 'H':
Jon Doron3a9651d2019-05-29 09:41:34 +03002711 {
2712 static const GdbCmdParseEntry set_thread_cmd_desc = {
2713 .handler = handle_set_thread,
2714 .cmd = "H",
2715 .cmd_startswith = 1,
2716 .schema = "o.t0"
2717 };
2718 cmd_parser = &set_thread_cmd_desc;
aliguori880a7572008-11-18 20:30:24 +00002719 }
2720 break;
2721 case 'T':
Jon Doron44ffded2019-05-29 09:41:31 +03002722 {
2723 static const GdbCmdParseEntry thread_alive_cmd_desc = {
2724 .handler = handle_thread_alive,
2725 .cmd = "T",
2726 .cmd_startswith = 1,
2727 .schema = "t0"
2728 };
2729 cmd_parser = &thread_alive_cmd_desc;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002730 }
aliguori880a7572008-11-18 20:30:24 +00002731 break;
pbrook978efd62006-06-17 18:30:42 +00002732 case 'q':
Jon Doron2704efa2019-05-29 09:41:45 +03002733 {
2734 static const GdbCmdParseEntry gen_query_cmd_desc = {
2735 .handler = handle_gen_query,
2736 .cmd = "q",
2737 .cmd_startswith = 1,
2738 .schema = "s0"
2739 };
2740 cmd_parser = &gen_query_cmd_desc;
2741 }
2742 break;
edgar_igl60897d32008-05-09 08:25:14 +00002743 case 'Q':
Jon Doron2704efa2019-05-29 09:41:45 +03002744 {
2745 static const GdbCmdParseEntry gen_set_cmd_desc = {
2746 .handler = handle_gen_set,
2747 .cmd = "Q",
2748 .cmd_startswith = 1,
2749 .schema = "s0"
2750 };
2751 cmd_parser = &gen_set_cmd_desc;
edgar_igl60897d32008-05-09 08:25:14 +00002752 }
Jon Doron2704efa2019-05-29 09:41:45 +03002753 break;
bellard858693c2004-03-31 18:52:07 +00002754 default:
bellard858693c2004-03-31 18:52:07 +00002755 /* put empty packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002756 put_packet("");
bellard858693c2004-03-31 18:52:07 +00002757 break;
2758 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002759
Ramiro Polla2bdec392019-08-05 21:09:01 +02002760 if (cmd_parser) {
Alex Bennéea346af32020-03-16 17:21:34 +00002761 run_cmd_parser(line_buf, cmd_parser);
Ramiro Polla2bdec392019-08-05 21:09:01 +02002762 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002763
bellard858693c2004-03-31 18:52:07 +00002764 return RS_IDLE;
2765}
2766
Andreas Färber64f6b342013-05-27 02:06:09 +02002767void gdb_set_stop_cpu(CPUState *cpu)
aliguori880a7572008-11-18 20:30:24 +00002768{
Alex Bennéea346af32020-03-16 17:21:34 +00002769 GDBProcess *p = gdb_get_cpu_process(cpu);
Luc Michel160d8582019-01-07 15:23:46 +00002770
2771 if (!p->attached) {
2772 /*
2773 * Having a stop CPU corresponding to a process that is not attached
2774 * confuses GDB. So we ignore the request.
2775 */
2776 return;
2777 }
2778
Alex Bennée8d98c442020-03-16 17:21:33 +00002779 gdbserver_state.c_cpu = cpu;
2780 gdbserver_state.g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002781}
2782
bellard1fddef42005-04-17 19:16:13 +00002783#ifndef CONFIG_USER_ONLY
Philippe Mathieu-Daudé538f0492021-01-11 16:20:20 +01002784static void gdb_vm_state_change(void *opaque, bool running, RunState state)
bellard858693c2004-03-31 18:52:07 +00002785{
Alex Bennéea346af32020-03-16 17:21:34 +00002786 CPUState *cpu = gdbserver_state.c_cpu;
Alex Bennée308f9e82020-03-16 17:21:35 +00002787 g_autoptr(GString) buf = g_string_new(NULL);
2788 g_autoptr(GString) tid = g_string_new(NULL);
aliguorid6fc1b32008-11-18 19:55:44 +00002789 const char *type;
bellard858693c2004-03-31 18:52:07 +00002790 int ret;
2791
Alex Bennéea346af32020-03-16 17:21:34 +00002792 if (running || gdbserver_state.state == RS_INACTIVE) {
Meador Ingecdb432b2012-03-15 17:49:45 +00002793 return;
2794 }
2795 /* Is there a GDB syscall waiting to be sent? */
Alex Bennéea346af32020-03-16 17:21:34 +00002796 if (gdbserver_state.current_syscall_cb) {
2797 put_packet(gdbserver_state.syscall_buf);
pbrooka2d1eba2007-01-28 03:10:55 +00002798 return;
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002799 }
Luc Michel95567c22019-01-07 15:23:46 +00002800
2801 if (cpu == NULL) {
2802 /* No process attached */
2803 return;
2804 }
2805
Alex Bennée308f9e82020-03-16 17:21:35 +00002806 gdb_append_thread_id(cpu, tid);
Luc Michel95567c22019-01-07 15:23:46 +00002807
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002808 switch (state) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002809 case RUN_STATE_DEBUG:
Andreas Färberff4700b2013-08-26 18:23:18 +02002810 if (cpu->watchpoint_hit) {
2811 switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
aliguoria1d1bb32008-11-18 20:07:32 +00002812 case BP_MEM_READ:
aliguorid6fc1b32008-11-18 19:55:44 +00002813 type = "r";
2814 break;
aliguoria1d1bb32008-11-18 20:07:32 +00002815 case BP_MEM_ACCESS:
aliguorid6fc1b32008-11-18 19:55:44 +00002816 type = "a";
2817 break;
2818 default:
2819 type = "";
2820 break;
2821 }
Doug Gale5c9522b2017-12-02 20:30:37 -05002822 trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
2823 (target_ulong)cpu->watchpoint_hit->vaddr);
Alex Bennée308f9e82020-03-16 17:21:35 +00002824 g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
2825 GDB_SIGNAL_TRAP, tid->str, type,
2826 (target_ulong)cpu->watchpoint_hit->vaddr);
Andreas Färberff4700b2013-08-26 18:23:18 +02002827 cpu->watchpoint_hit = NULL;
Jan Kiszka425189a2011-03-22 11:02:09 +01002828 goto send_packet;
Doug Gale5c9522b2017-12-02 20:30:37 -05002829 } else {
2830 trace_gdbstub_hit_break();
pbrook6658ffb2007-03-16 23:58:11 +00002831 }
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07002832 tb_flush(cpu);
aurel32ca587a82008-12-18 22:44:13 +00002833 ret = GDB_SIGNAL_TRAP;
Jan Kiszka425189a2011-03-22 11:02:09 +01002834 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002835 case RUN_STATE_PAUSED:
Doug Gale5c9522b2017-12-02 20:30:37 -05002836 trace_gdbstub_hit_paused();
aliguori9781e042009-01-22 17:15:29 +00002837 ret = GDB_SIGNAL_INT;
Jan Kiszka425189a2011-03-22 11:02:09 +01002838 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002839 case RUN_STATE_SHUTDOWN:
Doug Gale5c9522b2017-12-02 20:30:37 -05002840 trace_gdbstub_hit_shutdown();
Jan Kiszka425189a2011-03-22 11:02:09 +01002841 ret = GDB_SIGNAL_QUIT;
2842 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002843 case RUN_STATE_IO_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002844 trace_gdbstub_hit_io_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002845 ret = GDB_SIGNAL_IO;
2846 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002847 case RUN_STATE_WATCHDOG:
Doug Gale5c9522b2017-12-02 20:30:37 -05002848 trace_gdbstub_hit_watchdog();
Jan Kiszka425189a2011-03-22 11:02:09 +01002849 ret = GDB_SIGNAL_ALRM;
2850 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002851 case RUN_STATE_INTERNAL_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002852 trace_gdbstub_hit_internal_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002853 ret = GDB_SIGNAL_ABRT;
2854 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002855 case RUN_STATE_SAVE_VM:
2856 case RUN_STATE_RESTORE_VM:
Jan Kiszka425189a2011-03-22 11:02:09 +01002857 return;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002858 case RUN_STATE_FINISH_MIGRATE:
Jan Kiszka425189a2011-03-22 11:02:09 +01002859 ret = GDB_SIGNAL_XCPU;
2860 break;
2861 default:
Doug Gale5c9522b2017-12-02 20:30:37 -05002862 trace_gdbstub_hit_unknown(state);
Jan Kiszka425189a2011-03-22 11:02:09 +01002863 ret = GDB_SIGNAL_UNKNOWN;
2864 break;
bellardbbeb7b52006-04-23 18:42:15 +00002865 }
Jan Kiszka226d0072015-07-24 18:52:31 +02002866 gdb_set_stop_cpu(cpu);
Alex Bennée308f9e82020-03-16 17:21:35 +00002867 g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002868
2869send_packet:
Alex Bennée308f9e82020-03-16 17:21:35 +00002870 put_packet(buf->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002871
2872 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002873 cpu_single_step(cpu, 0);
bellard858693c2004-03-31 18:52:07 +00002874}
bellard1fddef42005-04-17 19:16:13 +00002875#endif
bellard858693c2004-03-31 18:52:07 +00002876
pbrooka2d1eba2007-01-28 03:10:55 +00002877/* Send a gdb syscall request.
2878 This accepts limited printf-style format specifiers, specifically:
pbrooka87295e2007-05-26 15:09:38 +00002879 %x - target_ulong argument printed in hex.
2880 %lx - 64-bit argument printed in hex.
2881 %s - string pointer (target_ulong) and length (int) pair. */
Peter Maydell19239b32015-09-07 10:39:27 +01002882void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
pbrooka2d1eba2007-01-28 03:10:55 +00002883{
pbrooka2d1eba2007-01-28 03:10:55 +00002884 char *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00002885 char *p_end;
pbrooka2d1eba2007-01-28 03:10:55 +00002886 target_ulong addr;
pbrooka87295e2007-05-26 15:09:38 +00002887 uint64_t i64;
pbrooka2d1eba2007-01-28 03:10:55 +00002888
Alex Bennéea346af32020-03-16 17:21:34 +00002889 if (!gdbserver_state.init) {
pbrooka2d1eba2007-01-28 03:10:55 +00002890 return;
Alex Bennéea346af32020-03-16 17:21:34 +00002891 }
Alex Bennée8d98c442020-03-16 17:21:33 +00002892
2893 gdbserver_state.current_syscall_cb = cb;
pbrooka2d1eba2007-01-28 03:10:55 +00002894#ifndef CONFIG_USER_ONLY
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002895 vm_stop(RUN_STATE_DEBUG);
pbrooka2d1eba2007-01-28 03:10:55 +00002896#endif
Alex Bennée8d98c442020-03-16 17:21:33 +00002897 p = &gdbserver_state.syscall_buf[0];
2898 p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
pbrooka2d1eba2007-01-28 03:10:55 +00002899 *(p++) = 'F';
2900 while (*fmt) {
2901 if (*fmt == '%') {
2902 fmt++;
2903 switch (*fmt++) {
2904 case 'x':
2905 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002906 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
pbrooka2d1eba2007-01-28 03:10:55 +00002907 break;
pbrooka87295e2007-05-26 15:09:38 +00002908 case 'l':
2909 if (*(fmt++) != 'x')
2910 goto bad_format;
2911 i64 = va_arg(va, uint64_t);
Meador Ingecdb432b2012-03-15 17:49:45 +00002912 p += snprintf(p, p_end - p, "%" PRIx64, i64);
pbrooka87295e2007-05-26 15:09:38 +00002913 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002914 case 's':
2915 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002916 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
blueswir1363a37d2008-08-21 17:58:08 +00002917 addr, va_arg(va, int));
pbrooka2d1eba2007-01-28 03:10:55 +00002918 break;
2919 default:
pbrooka87295e2007-05-26 15:09:38 +00002920 bad_format:
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002921 error_report("gdbstub: Bad syscall format string '%s'",
2922 fmt - 1);
pbrooka2d1eba2007-01-28 03:10:55 +00002923 break;
2924 }
2925 } else {
2926 *(p++) = *(fmt++);
2927 }
2928 }
pbrook8a93e022007-08-06 13:19:15 +00002929 *p = 0;
pbrooka2d1eba2007-01-28 03:10:55 +00002930#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +00002931 put_packet(gdbserver_state.syscall_buf);
Peter Maydell4f710862018-05-15 19:19:58 +01002932 /* Return control to gdb for it to process the syscall request.
2933 * Since the protocol requires that gdb hands control back to us
2934 * using a "here are the results" F packet, we don't need to check
2935 * gdb_handlesig's return value (which is the signal to deliver if
2936 * execution was resumed via a continue packet).
2937 */
Alex Bennée8d98c442020-03-16 17:21:33 +00002938 gdb_handlesig(gdbserver_state.c_cpu, 0);
pbrooka2d1eba2007-01-28 03:10:55 +00002939#else
Meador Ingecdb432b2012-03-15 17:49:45 +00002940 /* In this case wait to send the syscall packet until notification that
2941 the CPU has stopped. This must be done because if the packet is sent
2942 now the reply from the syscall request could be received while the CPU
2943 is still in the running state, which can cause packets to be dropped
2944 and state transition 'T' packets to be sent while the syscall is still
2945 being processed. */
Alex Bennée8d98c442020-03-16 17:21:33 +00002946 qemu_cpu_kick(gdbserver_state.c_cpu);
pbrooka2d1eba2007-01-28 03:10:55 +00002947#endif
2948}
2949
Peter Maydell19239b32015-09-07 10:39:27 +01002950void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2951{
2952 va_list va;
2953
2954 va_start(va, fmt);
2955 gdb_do_syscallv(cb, fmt, va);
2956 va_end(va);
2957}
2958
Alex Bennéea346af32020-03-16 17:21:34 +00002959static void gdb_read_byte(uint8_t ch)
bellard858693c2004-03-31 18:52:07 +00002960{
ths60fe76f2007-12-16 03:02:09 +00002961 uint8_t reply;
bellard858693c2004-03-31 18:52:07 +00002962
bellard1fddef42005-04-17 19:16:13 +00002963#ifndef CONFIG_USER_ONLY
Damien Hedded116e812020-03-16 17:21:53 +00002964 if (gdbserver_state.last_packet->len) {
pbrook4046d912007-01-28 01:53:16 +00002965 /* Waiting for a response to the last packet. If we see the start
2966 of a new command then abandon the previous response. */
2967 if (ch == '-') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002968 trace_gdbstub_err_got_nack();
Damien Hedded116e812020-03-16 17:21:53 +00002969 put_buffer(gdbserver_state.last_packet->data,
2970 gdbserver_state.last_packet->len);
Alex Bennée118e2262017-07-12 11:52:13 +01002971 } else if (ch == '+') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002972 trace_gdbstub_io_got_ack();
Alex Bennée118e2262017-07-12 11:52:13 +01002973 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002974 trace_gdbstub_io_got_unexpected(ch);
pbrook4046d912007-01-28 01:53:16 +00002975 }
Alex Bennée118e2262017-07-12 11:52:13 +01002976
Damien Hedded116e812020-03-16 17:21:53 +00002977 if (ch == '+' || ch == '$') {
2978 g_byte_array_set_size(gdbserver_state.last_packet, 0);
2979 }
pbrook4046d912007-01-28 01:53:16 +00002980 if (ch != '$')
2981 return;
2982 }
Luiz Capitulino13548692011-07-29 15:36:43 -03002983 if (runstate_is_running()) {
bellard858693c2004-03-31 18:52:07 +00002984 /* when the CPU is running, we cannot do anything except stop
2985 it when receiving a char */
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002986 vm_stop(RUN_STATE_PAUSED);
ths5fafdf22007-09-16 21:08:06 +00002987 } else
bellard1fddef42005-04-17 19:16:13 +00002988#endif
bellard41625032005-04-24 10:07:11 +00002989 {
Alex Bennéea346af32020-03-16 17:21:34 +00002990 switch(gdbserver_state.state) {
bellard858693c2004-03-31 18:52:07 +00002991 case RS_IDLE:
2992 if (ch == '$') {
Doug Gale4bf43122017-05-01 12:22:10 -04002993 /* start of command packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002994 gdbserver_state.line_buf_index = 0;
2995 gdbserver_state.line_sum = 0;
2996 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002997 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002998 trace_gdbstub_err_garbage(ch);
bellard4c3a88a2003-07-26 12:06:08 +00002999 }
3000 break;
bellard858693c2004-03-31 18:52:07 +00003001 case RS_GETLINE:
Doug Gale4bf43122017-05-01 12:22:10 -04003002 if (ch == '}') {
3003 /* start escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003004 gdbserver_state.state = RS_GETLINE_ESC;
3005 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003006 } else if (ch == '*') {
3007 /* start run length encoding sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003008 gdbserver_state.state = RS_GETLINE_RLE;
3009 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003010 } else if (ch == '#') {
3011 /* end of command, start of checksum*/
Alex Bennéea346af32020-03-16 17:21:34 +00003012 gdbserver_state.state = RS_CHKSUM1;
3013 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale5c9522b2017-12-02 20:30:37 -05003014 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003015 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003016 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003017 /* unescaped command character */
Alex Bennéea346af32020-03-16 17:21:34 +00003018 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
3019 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003020 }
3021 break;
3022 case RS_GETLINE_ESC:
3023 if (ch == '#') {
3024 /* unexpected end of command in escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003025 gdbserver_state.state = RS_CHKSUM1;
3026 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003027 /* command buffer overrun */
Doug Gale5c9522b2017-12-02 20:30:37 -05003028 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003029 gdbserver_state.state = RS_IDLE;
Doug Gale4bf43122017-05-01 12:22:10 -04003030 } else {
3031 /* parse escaped character and leave escape state */
Alex Bennéea346af32020-03-16 17:21:34 +00003032 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
3033 gdbserver_state.line_sum += ch;
3034 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003035 }
3036 break;
3037 case RS_GETLINE_RLE:
Markus Armbruster046aba12019-05-14 20:03:08 +02003038 /*
3039 * Run-length encoding is explained in "Debugging with GDB /
3040 * Appendix E GDB Remote Serial Protocol / Overview".
3041 */
3042 if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
Doug Gale4bf43122017-05-01 12:22:10 -04003043 /* invalid RLE count encoding */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003044 trace_gdbstub_err_invalid_repeat(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003045 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003046 } else {
3047 /* decode repeat length */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003048 int repeat = ch - ' ' + 3;
Alex Bennéea346af32020-03-16 17:21:34 +00003049 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003050 /* that many repeats would overrun the command buffer */
Doug Gale5c9522b2017-12-02 20:30:37 -05003051 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003052 gdbserver_state.state = RS_IDLE;
3053 } else if (gdbserver_state.line_buf_index < 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003054 /* got a repeat but we have nothing to repeat */
Doug Gale5c9522b2017-12-02 20:30:37 -05003055 trace_gdbstub_err_invalid_rle();
Alex Bennéea346af32020-03-16 17:21:34 +00003056 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003057 } else {
3058 /* repeat the last character */
Alex Bennéea346af32020-03-16 17:21:34 +00003059 memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
3060 gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
3061 gdbserver_state.line_buf_index += repeat;
3062 gdbserver_state.line_sum += ch;
3063 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003064 }
bellard858693c2004-03-31 18:52:07 +00003065 }
3066 break;
3067 case RS_CHKSUM1:
Doug Gale4bf43122017-05-01 12:22:10 -04003068 /* get high hex digit of checksum */
3069 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003070 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003071 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003072 break;
3073 }
Alex Bennéea346af32020-03-16 17:21:34 +00003074 gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
3075 gdbserver_state.line_csum = fromhex(ch) << 4;
3076 gdbserver_state.state = RS_CHKSUM2;
bellard858693c2004-03-31 18:52:07 +00003077 break;
3078 case RS_CHKSUM2:
Doug Gale4bf43122017-05-01 12:22:10 -04003079 /* get low hex digit of checksum */
3080 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003081 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003082 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003083 break;
bellard858693c2004-03-31 18:52:07 +00003084 }
Alex Bennéea346af32020-03-16 17:21:34 +00003085 gdbserver_state.line_csum |= fromhex(ch);
Doug Gale4bf43122017-05-01 12:22:10 -04003086
Alex Bennéea346af32020-03-16 17:21:34 +00003087 if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
3088 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
Doug Gale4bf43122017-05-01 12:22:10 -04003089 /* send NAK reply */
ths60fe76f2007-12-16 03:02:09 +00003090 reply = '-';
Alex Bennéea346af32020-03-16 17:21:34 +00003091 put_buffer(&reply, 1);
3092 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003093 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003094 /* send ACK reply */
ths60fe76f2007-12-16 03:02:09 +00003095 reply = '+';
Alex Bennéea346af32020-03-16 17:21:34 +00003096 put_buffer(&reply, 1);
3097 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
bellard858693c2004-03-31 18:52:07 +00003098 }
bellardb4608c02003-06-27 17:34:32 +00003099 break;
pbrooka2d1eba2007-01-28 03:10:55 +00003100 default:
3101 abort();
bellardb4608c02003-06-27 17:34:32 +00003102 }
3103 }
bellard858693c2004-03-31 18:52:07 +00003104}
3105
Paul Brook0e1c9c52010-06-16 13:03:51 +01003106/* Tell the remote gdb that the process has exited. */
Alex Bennéead9dcb22021-01-08 22:42:43 +00003107void gdb_exit(int code)
Paul Brook0e1c9c52010-06-16 13:03:51 +01003108{
Paul Brook0e1c9c52010-06-16 13:03:51 +01003109 char buf[4];
3110
Alex Bennée8d98c442020-03-16 17:21:33 +00003111 if (!gdbserver_state.init) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003112 return;
3113 }
3114#ifdef CONFIG_USER_ONLY
Alex Bennéefcedd922020-04-30 20:01:19 +01003115 if (gdbserver_state.socket_path) {
3116 unlink(gdbserver_state.socket_path);
3117 }
Alex Bennéee0a1e202020-04-30 20:01:18 +01003118 if (gdbserver_state.fd < 0) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003119 return;
3120 }
3121#endif
3122
Doug Gale5c9522b2017-12-02 20:30:37 -05003123 trace_gdbstub_op_exiting((uint8_t)code);
3124
Paul Brook0e1c9c52010-06-16 13:03:51 +01003125 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
Alex Bennéea346af32020-03-16 17:21:34 +00003126 put_packet(buf);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003127
3128#ifndef CONFIG_USER_ONLY
Alex Bennée8d98c442020-03-16 17:21:33 +00003129 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003130#endif
Paul Brook0e1c9c52010-06-16 13:03:51 +01003131}
3132
Luc Michel8f468632019-01-07 15:23:45 +00003133/*
3134 * Create the process that will contain all the "orphan" CPUs (that are not
3135 * part of a CPU cluster). Note that if this process contains no CPUs, it won't
3136 * be attachable and thus will be invisible to the user.
3137 */
3138static void create_default_process(GDBState *s)
3139{
3140 GDBProcess *process;
3141 int max_pid = 0;
3142
Alex Bennéea346af32020-03-16 17:21:34 +00003143 if (gdbserver_state.process_num) {
Luc Michel8f468632019-01-07 15:23:45 +00003144 max_pid = s->processes[s->process_num - 1].pid;
3145 }
3146
3147 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3148 process = &s->processes[s->process_num - 1];
3149
3150 /* We need an available PID slot for this process */
3151 assert(max_pid < UINT32_MAX);
3152
3153 process->pid = max_pid + 1;
3154 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003155 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003156}
3157
bellard1fddef42005-04-17 19:16:13 +00003158#ifdef CONFIG_USER_ONLY
3159int
Andreas Färberdb6b81d2013-06-27 19:49:31 +02003160gdb_handlesig(CPUState *cpu, int sig)
bellard1fddef42005-04-17 19:16:13 +00003161{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003162 char buf[256];
3163 int n;
bellard1fddef42005-04-17 19:16:13 +00003164
Alex Bennéee0a1e202020-04-30 20:01:18 +01003165 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003166 return sig;
bellard1fddef42005-04-17 19:16:13 +00003167 }
3168
Andreas Färber5ca666c2013-06-24 19:20:57 +02003169 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02003170 cpu_single_step(cpu, 0);
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07003171 tb_flush(cpu);
bellard1fddef42005-04-17 19:16:13 +00003172
Andreas Färber5ca666c2013-06-24 19:20:57 +02003173 if (sig != 0) {
Pavel Labath4a82be72021-10-26 11:22:34 +01003174 gdb_set_stop_cpu(cpu);
3175 g_string_printf(gdbserver_state.str_buf,
3176 "T%02xthread:", target_signal_to_gdb(sig));
3177 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
3178 g_string_append_c(gdbserver_state.str_buf, ';');
3179 put_strbuf();
Andreas Färber5ca666c2013-06-24 19:20:57 +02003180 }
3181 /* put_packet() might have detected that the peer terminated the
3182 connection. */
Alex Bennée8d98c442020-03-16 17:21:33 +00003183 if (gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003184 return sig;
3185 }
3186
3187 sig = 0;
Alex Bennée8d98c442020-03-16 17:21:33 +00003188 gdbserver_state.state = RS_IDLE;
3189 gdbserver_state.running_state = 0;
3190 while (gdbserver_state.running_state == 0) {
3191 n = read(gdbserver_state.fd, buf, 256);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003192 if (n > 0) {
3193 int i;
3194
3195 for (i = 0; i < n; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003196 gdb_read_byte(buf[i]);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003197 }
Peter Wu5819e3e2016-06-05 16:35:48 +02003198 } else {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003199 /* XXX: Connection closed. Should probably wait for another
3200 connection before continuing. */
Peter Wu5819e3e2016-06-05 16:35:48 +02003201 if (n == 0) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003202 close(gdbserver_state.fd);
Peter Wu5819e3e2016-06-05 16:35:48 +02003203 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003204 gdbserver_state.fd = -1;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003205 return sig;
bellard1fddef42005-04-17 19:16:13 +00003206 }
Andreas Färber5ca666c2013-06-24 19:20:57 +02003207 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003208 sig = gdbserver_state.signal;
3209 gdbserver_state.signal = 0;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003210 return sig;
bellard1fddef42005-04-17 19:16:13 +00003211}
bellarde9009672005-04-26 20:42:36 +00003212
aurel32ca587a82008-12-18 22:44:13 +00003213/* Tell the remote gdb that the process has exited due to SIG. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01003214void gdb_signalled(CPUArchState *env, int sig)
aurel32ca587a82008-12-18 22:44:13 +00003215{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003216 char buf[4];
aurel32ca587a82008-12-18 22:44:13 +00003217
Alex Bennéee0a1e202020-04-30 20:01:18 +01003218 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003219 return;
3220 }
aurel32ca587a82008-12-18 22:44:13 +00003221
Andreas Färber5ca666c2013-06-24 19:20:57 +02003222 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003223 put_packet(buf);
aurel32ca587a82008-12-18 22:44:13 +00003224}
bellard1fddef42005-04-17 19:16:13 +00003225
Alex Bennéefcedd922020-04-30 20:01:19 +01003226static void gdb_accept_init(int fd)
3227{
3228 init_gdbserver_state();
3229 create_default_process(&gdbserver_state);
3230 gdbserver_state.processes[0].attached = true;
3231 gdbserver_state.c_cpu = gdb_first_attached_cpu();
3232 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
3233 gdbserver_state.fd = fd;
3234 gdb_has_xml = false;
3235}
3236
3237static bool gdb_accept_socket(int gdb_fd)
3238{
3239 int fd;
3240
3241 for(;;) {
3242 fd = accept(gdb_fd, NULL, NULL);
3243 if (fd < 0 && errno != EINTR) {
3244 perror("accept socket");
3245 return false;
3246 } else if (fd >= 0) {
3247 qemu_set_cloexec(fd);
3248 break;
3249 }
3250 }
3251
3252 gdb_accept_init(fd);
3253 return true;
3254}
3255
3256static int gdbserver_open_socket(const char *path)
3257{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003258 struct sockaddr_un sockaddr = {};
Alex Bennéefcedd922020-04-30 20:01:19 +01003259 int fd, ret;
3260
3261 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3262 if (fd < 0) {
3263 perror("create socket");
3264 return -1;
3265 }
3266
3267 sockaddr.sun_family = AF_UNIX;
3268 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
3269 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3270 if (ret < 0) {
3271 perror("bind socket");
3272 close(fd);
3273 return -1;
3274 }
3275 ret = listen(fd, 1);
3276 if (ret < 0) {
3277 perror("listen socket");
3278 close(fd);
3279 return -1;
3280 }
3281
3282 return fd;
3283}
3284
3285static bool gdb_accept_tcp(int gdb_fd)
bellard858693c2004-03-31 18:52:07 +00003286{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003287 struct sockaddr_in sockaddr = {};
bellard858693c2004-03-31 18:52:07 +00003288 socklen_t len;
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09003289 int fd;
bellard858693c2004-03-31 18:52:07 +00003290
3291 for(;;) {
3292 len = sizeof(sockaddr);
Alex Bennéee0a1e202020-04-30 20:01:18 +01003293 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
bellard858693c2004-03-31 18:52:07 +00003294 if (fd < 0 && errno != EINTR) {
3295 perror("accept");
Peter Maydell2f652222018-05-14 18:30:44 +01003296 return false;
bellard858693c2004-03-31 18:52:07 +00003297 } else if (fd >= 0) {
Peter Maydellf5bdd782018-05-14 18:30:43 +01003298 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003299 break;
3300 }
3301 }
3302
3303 /* set short latency */
Peter Maydell2f652222018-05-14 18:30:44 +01003304 if (socket_set_nodelay(fd)) {
3305 perror("setsockopt");
Philippe Mathieu-Daudéead75d82018-05-24 19:34:58 -03003306 close(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003307 return false;
3308 }
ths3b46e622007-09-17 08:09:54 +00003309
Alex Bennéefcedd922020-04-30 20:01:19 +01003310 gdb_accept_init(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003311 return true;
bellard858693c2004-03-31 18:52:07 +00003312}
3313
Alex Bennéefcedd922020-04-30 20:01:19 +01003314static int gdbserver_open_port(int port)
bellard858693c2004-03-31 18:52:07 +00003315{
3316 struct sockaddr_in sockaddr;
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003317 int fd, ret;
bellard858693c2004-03-31 18:52:07 +00003318
3319 fd = socket(PF_INET, SOCK_STREAM, 0);
3320 if (fd < 0) {
3321 perror("socket");
3322 return -1;
3323 }
Peter Maydellf5bdd782018-05-14 18:30:43 +01003324 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003325
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003326 socket_set_fast_reuse(fd);
bellard858693c2004-03-31 18:52:07 +00003327
3328 sockaddr.sin_family = AF_INET;
3329 sockaddr.sin_port = htons(port);
3330 sockaddr.sin_addr.s_addr = 0;
3331 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3332 if (ret < 0) {
3333 perror("bind");
Peter Maydellbb161722011-12-24 23:37:24 +00003334 close(fd);
bellard858693c2004-03-31 18:52:07 +00003335 return -1;
3336 }
Peter Wu96165b92016-05-04 11:32:17 +02003337 ret = listen(fd, 1);
bellard858693c2004-03-31 18:52:07 +00003338 if (ret < 0) {
3339 perror("listen");
Peter Maydellbb161722011-12-24 23:37:24 +00003340 close(fd);
bellard858693c2004-03-31 18:52:07 +00003341 return -1;
3342 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003343
bellard858693c2004-03-31 18:52:07 +00003344 return fd;
3345}
3346
Alex Bennéefcedd922020-04-30 20:01:19 +01003347int gdbserver_start(const char *port_or_path)
bellard858693c2004-03-31 18:52:07 +00003348{
Alex Bennéefcedd922020-04-30 20:01:19 +01003349 int port = g_ascii_strtoull(port_or_path, NULL, 10);
3350 int gdb_fd;
3351
3352 if (port > 0) {
3353 gdb_fd = gdbserver_open_port(port);
3354 } else {
3355 gdb_fd = gdbserver_open_socket(port_or_path);
3356 }
3357
Alex Bennéee0a1e202020-04-30 20:01:18 +01003358 if (gdb_fd < 0) {
bellard858693c2004-03-31 18:52:07 +00003359 return -1;
Alex Bennéee0a1e202020-04-30 20:01:18 +01003360 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003361
3362 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3363 return 0;
3364 } else if (gdb_accept_socket(gdb_fd)) {
3365 gdbserver_state.socket_path = g_strdup(port_or_path);
3366 return 0;
Peter Maydell2f652222018-05-14 18:30:44 +01003367 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003368
3369 /* gone wrong */
3370 close(gdb_fd);
3371 return -1;
bellardb4608c02003-06-27 17:34:32 +00003372}
aurel322b1319c2008-12-18 22:44:04 +00003373
3374/* Disable gdb stub for child processes. */
Peter Crosthwaitef7ec7f72015-06-23 19:31:16 -07003375void gdbserver_fork(CPUState *cpu)
aurel322b1319c2008-12-18 22:44:04 +00003376{
Alex Bennéee0a1e202020-04-30 20:01:18 +01003377 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber75a34032013-09-02 16:57:02 +02003378 return;
3379 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003380 close(gdbserver_state.fd);
3381 gdbserver_state.fd = -1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02003382 cpu_breakpoint_remove_all(cpu, BP_GDB);
Andreas Färber75a34032013-09-02 16:57:02 +02003383 cpu_watchpoint_remove_all(cpu, BP_GDB);
aurel322b1319c2008-12-18 22:44:04 +00003384}
pbrook4046d912007-01-28 01:53:16 +00003385#else
thsaa1f17c2007-07-11 22:48:58 +00003386static int gdb_chr_can_receive(void *opaque)
pbrook4046d912007-01-28 01:53:16 +00003387{
pbrook56aebc82008-10-11 17:55:29 +00003388 /* We can handle an arbitrarily large amount of data.
3389 Pick the maximum packet size, which is as good as anything. */
3390 return MAX_PACKET_LENGTH;
pbrook4046d912007-01-28 01:53:16 +00003391}
3392
thsaa1f17c2007-07-11 22:48:58 +00003393static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
pbrook4046d912007-01-28 01:53:16 +00003394{
pbrook4046d912007-01-28 01:53:16 +00003395 int i;
3396
3397 for (i = 0; i < size; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003398 gdb_read_byte(buf[i]);
pbrook4046d912007-01-28 01:53:16 +00003399 }
3400}
3401
Philippe Mathieu-Daudé083b2662019-12-18 18:20:09 +01003402static void gdb_chr_event(void *opaque, QEMUChrEvent event)
pbrook4046d912007-01-28 01:53:16 +00003403{
Luc Michel970ed902019-01-07 15:23:46 +00003404 int i;
3405 GDBState *s = (GDBState *) opaque;
3406
pbrook4046d912007-01-28 01:53:16 +00003407 switch (event) {
Amit Shahb6b8df52009-10-07 18:31:16 +05303408 case CHR_EVENT_OPENED:
Luc Michel970ed902019-01-07 15:23:46 +00003409 /* Start with first process attached, others detached */
3410 for (i = 0; i < s->process_num; i++) {
3411 s->processes[i].attached = !i;
3412 }
3413
Alex Bennéea346af32020-03-16 17:21:34 +00003414 s->c_cpu = gdb_first_attached_cpu();
Luc Michel970ed902019-01-07 15:23:46 +00003415 s->g_cpu = s->c_cpu;
3416
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003417 vm_stop(RUN_STATE_PAUSED);
Pavel Dovgalyuk56357d82020-10-03 20:14:01 +03003418 replay_gdb_attached();
Andreas Färber5b50e792013-06-29 04:18:45 +02003419 gdb_has_xml = false;
pbrook4046d912007-01-28 01:53:16 +00003420 break;
3421 default:
3422 break;
3423 }
3424}
3425
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003426static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
aliguori8a34a0f2009-03-05 23:01:55 +00003427{
Damien Hedded86b4672020-03-16 17:21:54 +00003428 g_autoptr(GString) hex_buf = g_string_new("O");
3429 memtohex(hex_buf, buf, len);
3430 put_packet(hex_buf->str);
aliguori8a34a0f2009-03-05 23:01:55 +00003431 return len;
3432}
3433
aliguori59030a82009-04-05 18:43:41 +00003434#ifndef _WIN32
3435static void gdb_sigterm_handler(int signal)
3436{
Luiz Capitulino13548692011-07-29 15:36:43 -03003437 if (runstate_is_running()) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003438 vm_stop(RUN_STATE_PAUSED);
Jan Kiszkae07bbac2011-02-09 16:29:40 +01003439 }
aliguori59030a82009-04-05 18:43:41 +00003440}
3441#endif
3442
Marc-André Lureau777357d2016-12-07 18:39:10 +03003443static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
3444 bool *be_opened, Error **errp)
3445{
3446 *be_opened = false;
3447}
3448
3449static void char_gdb_class_init(ObjectClass *oc, void *data)
3450{
3451 ChardevClass *cc = CHARDEV_CLASS(oc);
3452
3453 cc->internal = true;
3454 cc->open = gdb_monitor_open;
3455 cc->chr_write = gdb_monitor_write;
3456}
3457
3458#define TYPE_CHARDEV_GDB "chardev-gdb"
3459
3460static const TypeInfo char_gdb_type_info = {
3461 .name = TYPE_CHARDEV_GDB,
3462 .parent = TYPE_CHARDEV,
3463 .class_init = char_gdb_class_init,
3464};
3465
Luc Michel8f468632019-01-07 15:23:45 +00003466static int find_cpu_clusters(Object *child, void *opaque)
3467{
3468 if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
3469 GDBState *s = (GDBState *) opaque;
3470 CPUClusterState *cluster = CPU_CLUSTER(child);
3471 GDBProcess *process;
3472
3473 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3474
3475 process = &s->processes[s->process_num - 1];
3476
3477 /*
3478 * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
3479 * runtime, we enforce here that the machine does not use a cluster ID
3480 * that would lead to PID 0.
3481 */
3482 assert(cluster->cluster_id != UINT32_MAX);
3483 process->pid = cluster->cluster_id + 1;
3484 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003485 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003486
3487 return 0;
3488 }
3489
3490 return object_child_foreach(child, find_cpu_clusters, opaque);
3491}
3492
3493static int pid_order(const void *a, const void *b)
3494{
3495 GDBProcess *pa = (GDBProcess *) a;
3496 GDBProcess *pb = (GDBProcess *) b;
3497
3498 if (pa->pid < pb->pid) {
3499 return -1;
3500 } else if (pa->pid > pb->pid) {
3501 return 1;
3502 } else {
3503 return 0;
3504 }
3505}
3506
3507static void create_processes(GDBState *s)
3508{
3509 object_child_foreach(object_get_root(), find_cpu_clusters, s);
3510
Alex Bennéea346af32020-03-16 17:21:34 +00003511 if (gdbserver_state.processes) {
Luc Michel8f468632019-01-07 15:23:45 +00003512 /* Sort by PID */
Alex Bennéea346af32020-03-16 17:21:34 +00003513 qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
Luc Michel8f468632019-01-07 15:23:45 +00003514 }
3515
3516 create_default_process(s);
3517}
3518
aliguori59030a82009-04-05 18:43:41 +00003519int gdbserver_start(const char *device)
pbrook4046d912007-01-28 01:53:16 +00003520{
Doug Gale5c9522b2017-12-02 20:30:37 -05003521 trace_gdbstub_op_start(device);
3522
aliguori59030a82009-04-05 18:43:41 +00003523 char gdbstub_device_name[128];
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003524 Chardev *chr = NULL;
3525 Chardev *mon_chr;
pbrook4046d912007-01-28 01:53:16 +00003526
Ziyue Yang508b4ec2017-01-18 16:02:41 +08003527 if (!first_cpu) {
3528 error_report("gdbstub: meaningless to attach gdb to a "
3529 "machine without any CPU.");
3530 return -1;
3531 }
3532
Maxim Levitsky12bc5b42021-11-11 12:06:03 +01003533 if (kvm_enabled() && !kvm_supports_guest_debug()) {
3534 error_report("gdbstub: KVM doesn't support guest debugging");
3535 return -1;
3536 }
3537
aliguori59030a82009-04-05 18:43:41 +00003538 if (!device)
3539 return -1;
3540 if (strcmp(device, "none") != 0) {
3541 if (strstart(device, "tcp:", NULL)) {
3542 /* enforce required TCP attributes */
3543 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
Paolo Bonzinia9b13152021-02-25 11:47:52 +01003544 "%s,wait=off,nodelay=on,server=on", device);
aliguori59030a82009-04-05 18:43:41 +00003545 device = gdbstub_device_name;
aliguori36556b22009-03-28 18:05:53 +00003546 }
aliguori59030a82009-04-05 18:43:41 +00003547#ifndef _WIN32
3548 else if (strcmp(device, "stdio") == 0) {
3549 struct sigaction act;
pbrookcfc34752007-02-22 01:48:01 +00003550
aliguori59030a82009-04-05 18:43:41 +00003551 memset(&act, 0, sizeof(act));
3552 act.sa_handler = gdb_sigterm_handler;
3553 sigaction(SIGINT, &act, NULL);
3554 }
3555#endif
Marc-André Lureau95e30b22018-08-22 19:19:42 +02003556 /*
3557 * FIXME: it's a bit weird to allow using a mux chardev here
3558 * and implicitly setup a monitor. We may want to break this.
3559 */
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003560 chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
aliguori36556b22009-03-28 18:05:53 +00003561 if (!chr)
3562 return -1;
pbrookcfc34752007-02-22 01:48:01 +00003563 }
3564
Alex Bennée8d98c442020-03-16 17:21:33 +00003565 if (!gdbserver_state.init) {
3566 init_gdbserver_state();
pbrook4046d912007-01-28 01:53:16 +00003567
aliguori36556b22009-03-28 18:05:53 +00003568 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
3569
3570 /* Initialize a monitor terminal for gdb */
Marc-André Lureau777357d2016-12-07 18:39:10 +03003571 mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003572 NULL, NULL, &error_abort);
Kevin Wolf8e9119a2020-02-24 15:30:06 +01003573 monitor_init_hmp(mon_chr, false, &error_abort);
aliguori36556b22009-03-28 18:05:53 +00003574 } else {
Alex Bennée8d98c442020-03-16 17:21:33 +00003575 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
3576 mon_chr = gdbserver_state.mon_chr;
3577 reset_gdbserver_state();
aliguori36556b22009-03-28 18:05:53 +00003578 }
Luc Michel8f468632019-01-07 15:23:45 +00003579
Alex Bennée8d98c442020-03-16 17:21:33 +00003580 create_processes(&gdbserver_state);
Luc Michel8f468632019-01-07 15:23:45 +00003581
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003582 if (chr) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003583 qemu_chr_fe_init(&gdbserver_state.chr, chr, &error_abort);
3584 qemu_chr_fe_set_handlers(&gdbserver_state.chr, gdb_chr_can_receive,
3585 gdb_chr_receive, gdb_chr_event,
3586 NULL, &gdbserver_state, NULL, true);
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003587 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003588 gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
3589 gdbserver_state.mon_chr = mon_chr;
3590 gdbserver_state.current_syscall_cb = NULL;
aliguori8a34a0f2009-03-05 23:01:55 +00003591
pbrook4046d912007-01-28 01:53:16 +00003592 return 0;
3593}
Marc-André Lureau777357d2016-12-07 18:39:10 +03003594
3595static void register_types(void)
3596{
3597 type_register_static(&char_gdb_type_info);
3598}
3599
3600type_init(register_types);
pbrook4046d912007-01-28 01:53:16 +00003601#endif