blob: cf869b10e3b74c130823534c486a20c21ddfed75 [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
Peter Maydellebf1b4c2022-06-10 14:32:36 +0100446/*
447 * Return true if there is a GDB currently connected to the stub
448 * and attached to a CPU
449 */
450static bool gdb_attached(void)
451{
452 return gdbserver_state.init && gdbserver_state.c_cpu;
453}
454
blueswir1654efcf2009-04-18 07:29:59 +0000455static enum {
pbrooka2d1eba2007-01-28 03:10:55 +0000456 GDB_SYS_UNKNOWN,
457 GDB_SYS_ENABLED,
458 GDB_SYS_DISABLED,
459} gdb_syscall_mode;
460
Liviu Ionescua38bb072014-12-11 12:07:48 +0000461/* Decide if either remote gdb syscalls or native file IO should be used. */
pbrooka2d1eba2007-01-28 03:10:55 +0000462int use_gdb_syscalls(void)
463{
Leon Alraecfe67ce2015-06-19 14:17:45 +0100464 SemihostingTarget target = semihosting_get_target();
465 if (target == SEMIHOSTING_TARGET_NATIVE) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000466 /* -semihosting-config target=native */
467 return false;
Leon Alraecfe67ce2015-06-19 14:17:45 +0100468 } else if (target == SEMIHOSTING_TARGET_GDB) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000469 /* -semihosting-config target=gdb */
470 return true;
471 }
472
473 /* -semihosting-config target=auto */
474 /* On the first call check if gdb is connected and remember. */
pbrooka2d1eba2007-01-28 03:10:55 +0000475 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
Peter Maydellebf1b4c2022-06-10 14:32:36 +0100476 gdb_syscall_mode = gdb_attached() ? GDB_SYS_ENABLED : GDB_SYS_DISABLED;
pbrooka2d1eba2007-01-28 03:10:55 +0000477 }
478 return gdb_syscall_mode == GDB_SYS_ENABLED;
479}
480
Alex Bennéeed12f5b2021-05-20 18:43:02 +0100481static bool stub_can_reverse(void)
482{
483#ifdef CONFIG_USER_ONLY
484 return false;
485#else
486 return replay_mode == REPLAY_MODE_PLAY;
487#endif
488}
489
edgar_iglba70a622008-03-14 06:10:42 +0000490/* Resume execution. */
Alex Bennéea346af32020-03-16 17:21:34 +0000491static inline void gdb_continue(void)
edgar_iglba70a622008-03-14 06:10:42 +0000492{
Doug Gale5c9522b2017-12-02 20:30:37 -0500493
edgar_iglba70a622008-03-14 06:10:42 +0000494#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000495 gdbserver_state.running_state = 1;
Doug Gale5c9522b2017-12-02 20:30:37 -0500496 trace_gdbstub_op_continue();
edgar_iglba70a622008-03-14 06:10:42 +0000497#else
Paolo Bonzini26ac7a32013-06-03 17:06:54 +0200498 if (!runstate_needs_reset()) {
Doug Gale5c9522b2017-12-02 20:30:37 -0500499 trace_gdbstub_op_continue();
Paolo Bonzini87f25c12013-05-30 13:20:40 +0200500 vm_start();
501 }
edgar_iglba70a622008-03-14 06:10:42 +0000502#endif
503}
504
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100505/*
506 * Resume execution, per CPU actions. For user-mode emulation it's
507 * equivalent to gdb_continue.
508 */
Alex Bennéea346af32020-03-16 17:21:34 +0000509static int gdb_continue_partial(char *newstates)
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100510{
511 CPUState *cpu;
512 int res = 0;
513#ifdef CONFIG_USER_ONLY
514 /*
515 * This is not exactly accurate, but it's an improvement compared to the
516 * previous situation, where only one CPU would be single-stepped.
517 */
518 CPU_FOREACH(cpu) {
519 if (newstates[cpu->cpu_index] == 's') {
Doug Gale5c9522b2017-12-02 20:30:37 -0500520 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100521 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100522 }
523 }
Alex Bennéea346af32020-03-16 17:21:34 +0000524 gdbserver_state.running_state = 1;
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100525#else
526 int flag = 0;
527
528 if (!runstate_needs_reset()) {
Ivan Shcherbakovd7482ff2022-03-02 17:28:33 -0800529 bool step_requested = false;
530 CPU_FOREACH(cpu) {
531 if (newstates[cpu->cpu_index] == 's') {
532 step_requested = true;
533 break;
534 }
535 }
536
537 if (vm_prepare_start(step_requested)) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100538 return 0;
539 }
540
541 CPU_FOREACH(cpu) {
542 switch (newstates[cpu->cpu_index]) {
543 case 0:
544 case 1:
545 break; /* nothing to do here */
546 case 's':
Doug Gale5c9522b2017-12-02 20:30:37 -0500547 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100548 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100549 cpu_resume(cpu);
550 flag = 1;
551 break;
552 case 'c':
Doug Gale5c9522b2017-12-02 20:30:37 -0500553 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100554 cpu_resume(cpu);
555 flag = 1;
556 break;
557 default:
558 res = -1;
559 break;
560 }
561 }
562 }
563 if (flag) {
564 qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
565 }
566#endif
567 return res;
568}
569
Alex Bennéea346af32020-03-16 17:21:34 +0000570static void put_buffer(const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000571{
pbrook4046d912007-01-28 01:53:16 +0000572#ifdef CONFIG_USER_ONLY
bellardb4608c02003-06-27 17:34:32 +0000573 int ret;
574
575 while (len > 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000576 ret = send(gdbserver_state.fd, buf, len, 0);
bellardb4608c02003-06-27 17:34:32 +0000577 if (ret < 0) {
Peter Wu5819e3e2016-06-05 16:35:48 +0200578 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000579 return;
580 } else {
581 buf += ret;
582 len -= ret;
583 }
584 }
pbrook4046d912007-01-28 01:53:16 +0000585#else
Daniel P. Berrange6ab3fc32016-09-06 14:56:04 +0100586 /* XXX this blocks entire thread. Rewrite to use
587 * qemu_chr_fe_write and background I/O callbacks */
Alex Bennéea346af32020-03-16 17:21:34 +0000588 qemu_chr_fe_write_all(&gdbserver_state.chr, buf, len);
pbrook4046d912007-01-28 01:53:16 +0000589#endif
bellardb4608c02003-06-27 17:34:32 +0000590}
591
592static inline int fromhex(int v)
593{
594 if (v >= '0' && v <= '9')
595 return v - '0';
596 else if (v >= 'A' && v <= 'F')
597 return v - 'A' + 10;
598 else if (v >= 'a' && v <= 'f')
599 return v - 'a' + 10;
600 else
601 return 0;
602}
603
604static inline int tohex(int v)
605{
606 if (v < 10)
607 return v + '0';
608 else
609 return v - 10 + 'a';
610}
611
Philippe Mathieu-Daudé90057742018-04-08 11:59:33 -0300612/* writes 2*len+1 bytes in buf */
Alex Bennée308f9e82020-03-16 17:21:35 +0000613static void memtohex(GString *buf, const uint8_t *mem, int len)
bellardb4608c02003-06-27 17:34:32 +0000614{
615 int i, c;
bellardb4608c02003-06-27 17:34:32 +0000616 for(i = 0; i < len; i++) {
617 c = mem[i];
Alex Bennée308f9e82020-03-16 17:21:35 +0000618 g_string_append_c(buf, tohex(c >> 4));
619 g_string_append_c(buf, tohex(c & 0xf));
bellardb4608c02003-06-27 17:34:32 +0000620 }
Alex Bennée308f9e82020-03-16 17:21:35 +0000621 g_string_append_c(buf, '\0');
bellardb4608c02003-06-27 17:34:32 +0000622}
623
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000624static void hextomem(GByteArray *mem, const char *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000625{
626 int i;
627
628 for(i = 0; i < len; i++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000629 guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
630 g_byte_array_append(mem, &byte, 1);
bellardb4608c02003-06-27 17:34:32 +0000631 buf += 2;
632 }
633}
634
Doug Gale5c9522b2017-12-02 20:30:37 -0500635static void hexdump(const char *buf, int len,
636 void (*trace_fn)(size_t ofs, char const *text))
637{
638 char line_buffer[3 * 16 + 4 + 16 + 1];
639
640 size_t i;
641 for (i = 0; i < len || (i & 0xF); ++i) {
642 size_t byte_ofs = i & 15;
643
644 if (byte_ofs == 0) {
645 memset(line_buffer, ' ', 3 * 16 + 4 + 16);
646 line_buffer[3 * 16 + 4 + 16] = 0;
647 }
648
649 size_t col_group = (i >> 2) & 3;
650 size_t hex_col = byte_ofs * 3 + col_group;
651 size_t txt_col = 3 * 16 + 4 + byte_ofs;
652
653 if (i < len) {
654 char value = buf[i];
655
656 line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
657 line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
658 line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
659 ? value
660 : '.';
661 }
662
663 if (byte_ofs == 0xF)
664 trace_fn(i & -16, line_buffer);
665 }
666}
667
bellardb4608c02003-06-27 17:34:32 +0000668/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000669static int put_packet_binary(const char *buf, int len, bool dump)
bellardb4608c02003-06-27 17:34:32 +0000670{
pbrook56aebc82008-10-11 17:55:29 +0000671 int csum, i;
Damien Hedded116e812020-03-16 17:21:53 +0000672 uint8_t footer[3];
bellardb4608c02003-06-27 17:34:32 +0000673
Doug Gale5c9522b2017-12-02 20:30:37 -0500674 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
675 hexdump(buf, len, trace_gdbstub_io_binaryreply);
676 }
677
bellardb4608c02003-06-27 17:34:32 +0000678 for(;;) {
Damien Hedded116e812020-03-16 17:21:53 +0000679 g_byte_array_set_size(gdbserver_state.last_packet, 0);
680 g_byte_array_append(gdbserver_state.last_packet,
681 (const uint8_t *) "$", 1);
682 g_byte_array_append(gdbserver_state.last_packet,
683 (const uint8_t *) buf, len);
bellardb4608c02003-06-27 17:34:32 +0000684 csum = 0;
685 for(i = 0; i < len; i++) {
686 csum += buf[i];
687 }
Damien Hedded116e812020-03-16 17:21:53 +0000688 footer[0] = '#';
689 footer[1] = tohex((csum >> 4) & 0xf);
690 footer[2] = tohex((csum) & 0xf);
691 g_byte_array_append(gdbserver_state.last_packet, footer, 3);
bellardb4608c02003-06-27 17:34:32 +0000692
Damien Hedded116e812020-03-16 17:21:53 +0000693 put_buffer(gdbserver_state.last_packet->data,
694 gdbserver_state.last_packet->len);
bellardb4608c02003-06-27 17:34:32 +0000695
pbrook4046d912007-01-28 01:53:16 +0000696#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000697 i = get_char();
pbrook4046d912007-01-28 01:53:16 +0000698 if (i < 0)
bellardb4608c02003-06-27 17:34:32 +0000699 return -1;
pbrook4046d912007-01-28 01:53:16 +0000700 if (i == '+')
bellardb4608c02003-06-27 17:34:32 +0000701 break;
pbrook4046d912007-01-28 01:53:16 +0000702#else
703 break;
704#endif
bellardb4608c02003-06-27 17:34:32 +0000705 }
706 return 0;
707}
708
pbrook56aebc82008-10-11 17:55:29 +0000709/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000710static int put_packet(const char *buf)
pbrook56aebc82008-10-11 17:55:29 +0000711{
Doug Gale5c9522b2017-12-02 20:30:37 -0500712 trace_gdbstub_io_reply(buf);
pbrook56aebc82008-10-11 17:55:29 +0000713
Alex Bennéea346af32020-03-16 17:21:34 +0000714 return put_packet_binary(buf, strlen(buf), false);
pbrook56aebc82008-10-11 17:55:29 +0000715}
716
Alex Bennée308f9e82020-03-16 17:21:35 +0000717static void put_strbuf(void)
pbrook56aebc82008-10-11 17:55:29 +0000718{
Alex Bennée308f9e82020-03-16 17:21:35 +0000719 put_packet(gdbserver_state.str_buf->str);
720}
721
722/* Encode data using the encoding for 'x' packets. */
723static void memtox(GString *buf, const char *mem, int len)
724{
pbrook56aebc82008-10-11 17:55:29 +0000725 char c;
726
727 while (len--) {
728 c = *(mem++);
729 switch (c) {
730 case '#': case '$': case '*': case '}':
Alex Bennée308f9e82020-03-16 17:21:35 +0000731 g_string_append_c(buf, '}');
732 g_string_append_c(buf, c ^ 0x20);
pbrook56aebc82008-10-11 17:55:29 +0000733 break;
734 default:
Alex Bennée308f9e82020-03-16 17:21:35 +0000735 g_string_append_c(buf, c);
pbrook56aebc82008-10-11 17:55:29 +0000736 break;
737 }
738 }
pbrook56aebc82008-10-11 17:55:29 +0000739}
740
Alex Bennéea346af32020-03-16 17:21:34 +0000741static uint32_t gdb_get_cpu_pid(CPUState *cpu)
Luc Michel1a227332019-01-07 15:23:45 +0000742{
Luc Michel1a227332019-01-07 15:23:45 +0000743 /* TODO: In user mode, we should use the task state PID */
Peter Maydell46f5abc2019-01-29 11:46:06 +0000744 if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
745 /* Return the default process' PID */
Alex Bennéea346af32020-03-16 17:21:34 +0000746 int index = gdbserver_state.process_num - 1;
747 return gdbserver_state.processes[index].pid;
Peter Maydell46f5abc2019-01-29 11:46:06 +0000748 }
749 return cpu->cluster_index + 1;
Luc Michel1a227332019-01-07 15:23:45 +0000750}
751
Alex Bennéea346af32020-03-16 17:21:34 +0000752static GDBProcess *gdb_get_process(uint32_t pid)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000753{
754 int i;
755
756 if (!pid) {
757 /* 0 means any process, we take the first one */
Alex Bennéea346af32020-03-16 17:21:34 +0000758 return &gdbserver_state.processes[0];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000759 }
760
Alex Bennéea346af32020-03-16 17:21:34 +0000761 for (i = 0; i < gdbserver_state.process_num; i++) {
762 if (gdbserver_state.processes[i].pid == pid) {
763 return &gdbserver_state.processes[i];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000764 }
765 }
766
767 return NULL;
768}
769
Alex Bennéea346af32020-03-16 17:21:34 +0000770static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000771{
Alex Bennéea346af32020-03-16 17:21:34 +0000772 return gdb_get_process(gdb_get_cpu_pid(cpu));
Luc Michel7d8c87d2019-01-07 15:23:45 +0000773}
774
775static CPUState *find_cpu(uint32_t thread_id)
776{
777 CPUState *cpu;
778
779 CPU_FOREACH(cpu) {
780 if (cpu_gdb_index(cpu) == thread_id) {
781 return cpu;
782 }
783 }
784
785 return NULL;
786}
787
Alex Bennéea346af32020-03-16 17:21:34 +0000788static CPUState *get_first_cpu_in_process(GDBProcess *process)
Luc Michele40e5202019-01-07 15:23:46 +0000789{
790 CPUState *cpu;
791
792 CPU_FOREACH(cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000793 if (gdb_get_cpu_pid(cpu) == process->pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000794 return cpu;
795 }
796 }
797
798 return NULL;
799}
800
Alex Bennéea346af32020-03-16 17:21:34 +0000801static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000802{
Alex Bennéea346af32020-03-16 17:21:34 +0000803 uint32_t pid = gdb_get_cpu_pid(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000804 cpu = CPU_NEXT(cpu);
805
806 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000807 if (gdb_get_cpu_pid(cpu) == pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000808 break;
809 }
810
811 cpu = CPU_NEXT(cpu);
812 }
813
814 return cpu;
815}
816
Luc Michele40e5202019-01-07 15:23:46 +0000817/* Return the cpu following @cpu, while ignoring unattached processes. */
Alex Bennéea346af32020-03-16 17:21:34 +0000818static CPUState *gdb_next_attached_cpu(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000819{
820 cpu = CPU_NEXT(cpu);
821
822 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000823 if (gdb_get_cpu_process(cpu)->attached) {
Luc Michele40e5202019-01-07 15:23:46 +0000824 break;
825 }
826
827 cpu = CPU_NEXT(cpu);
828 }
829
830 return cpu;
831}
832
833/* Return the first attached cpu */
Alex Bennéea346af32020-03-16 17:21:34 +0000834static CPUState *gdb_first_attached_cpu(void)
Luc Michele40e5202019-01-07 15:23:46 +0000835{
836 CPUState *cpu = first_cpu;
Alex Bennéea346af32020-03-16 17:21:34 +0000837 GDBProcess *process = gdb_get_cpu_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000838
839 if (!process->attached) {
Alex Bennéea346af32020-03-16 17:21:34 +0000840 return gdb_next_attached_cpu(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000841 }
842
843 return cpu;
844}
845
Alex Bennéea346af32020-03-16 17:21:34 +0000846static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
Luc Michelab65eed2019-01-29 11:46:03 +0000847{
848 GDBProcess *process;
849 CPUState *cpu;
850
851 if (!pid && !tid) {
852 /* 0 means any process/thread, we take the first attached one */
Alex Bennéea346af32020-03-16 17:21:34 +0000853 return gdb_first_attached_cpu();
Luc Michelab65eed2019-01-29 11:46:03 +0000854 } else if (pid && !tid) {
855 /* any thread in a specific process */
Alex Bennéea346af32020-03-16 17:21:34 +0000856 process = gdb_get_process(pid);
Luc Michelab65eed2019-01-29 11:46:03 +0000857
858 if (process == NULL) {
859 return NULL;
860 }
861
862 if (!process->attached) {
863 return NULL;
864 }
865
Alex Bennéea346af32020-03-16 17:21:34 +0000866 return get_first_cpu_in_process(process);
Luc Michelab65eed2019-01-29 11:46:03 +0000867 } else {
868 /* a specific thread */
869 cpu = find_cpu(tid);
870
871 if (cpu == NULL) {
872 return NULL;
873 }
874
Alex Bennéea346af32020-03-16 17:21:34 +0000875 process = gdb_get_cpu_process(cpu);
Luc Michelab65eed2019-01-29 11:46:03 +0000876
877 if (pid && process->pid != pid) {
878 return NULL;
879 }
880
881 if (!process->attached) {
882 return NULL;
883 }
884
885 return cpu;
886 }
887}
888
Alex Bennéea346af32020-03-16 17:21:34 +0000889static const char *get_feature_xml(const char *p, const char **newp,
890 GDBProcess *process)
pbrook56aebc82008-10-11 17:55:29 +0000891{
pbrook56aebc82008-10-11 17:55:29 +0000892 size_t len;
893 int i;
894 const char *name;
Alex Bennéea346af32020-03-16 17:21:34 +0000895 CPUState *cpu = get_first_cpu_in_process(process);
Luc Michelc145eea2019-01-07 15:23:46 +0000896 CPUClass *cc = CPU_GET_CLASS(cpu);
pbrook56aebc82008-10-11 17:55:29 +0000897
898 len = 0;
899 while (p[len] && p[len] != ':')
900 len++;
901 *newp = p + len;
902
903 name = NULL;
904 if (strncmp(p, "target.xml", len) == 0) {
Luc Michelc145eea2019-01-07 15:23:46 +0000905 char *buf = process->target_xml;
906 const size_t buf_sz = sizeof(process->target_xml);
pbrook56aebc82008-10-11 17:55:29 +0000907
Luc Michelc145eea2019-01-07 15:23:46 +0000908 /* Generate the XML description for this CPU. */
909 if (!buf[0]) {
910 GDBRegisterState *r;
911
912 pstrcat(buf, buf_sz,
David Hildenbrandb3820e62015-12-03 13:14:41 +0100913 "<?xml version=\"1.0\"?>"
914 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
915 "<target>");
916 if (cc->gdb_arch_name) {
917 gchar *arch = cc->gdb_arch_name(cpu);
Luc Michelc145eea2019-01-07 15:23:46 +0000918 pstrcat(buf, buf_sz, "<architecture>");
919 pstrcat(buf, buf_sz, arch);
920 pstrcat(buf, buf_sz, "</architecture>");
David Hildenbrandb3820e62015-12-03 13:14:41 +0100921 g_free(arch);
922 }
Luc Michelc145eea2019-01-07 15:23:46 +0000923 pstrcat(buf, buf_sz, "<xi:include href=\"");
924 pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
925 pstrcat(buf, buf_sz, "\"/>");
Andreas Färbereac8b352013-06-28 21:11:37 +0200926 for (r = cpu->gdb_regs; r; r = r->next) {
Luc Michelc145eea2019-01-07 15:23:46 +0000927 pstrcat(buf, buf_sz, "<xi:include href=\"");
928 pstrcat(buf, buf_sz, r->xml);
929 pstrcat(buf, buf_sz, "\"/>");
pbrook56aebc82008-10-11 17:55:29 +0000930 }
Luc Michelc145eea2019-01-07 15:23:46 +0000931 pstrcat(buf, buf_sz, "</target>");
pbrook56aebc82008-10-11 17:55:29 +0000932 }
Luc Michelc145eea2019-01-07 15:23:46 +0000933 return buf;
pbrook56aebc82008-10-11 17:55:29 +0000934 }
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100935 if (cc->gdb_get_dynamic_xml) {
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100936 char *xmlname = g_strndup(p, len);
937 const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
938
939 g_free(xmlname);
940 if (xml) {
941 return xml;
942 }
943 }
pbrook56aebc82008-10-11 17:55:29 +0000944 for (i = 0; ; i++) {
945 name = xml_builtin[i][0];
946 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
947 break;
948 }
949 return name ? xml_builtin[i][1] : NULL;
950}
pbrook56aebc82008-10-11 17:55:29 +0000951
Alex Bennéea010bdb2020-03-16 17:21:41 +0000952static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000953{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200954 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200955 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000956 GDBRegisterState *r;
957
Andreas Färbera0e372f2013-06-28 23:18:47 +0200958 if (reg < cc->gdb_num_core_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000959 return cc->gdb_read_register(cpu, buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200960 }
pbrook56aebc82008-10-11 17:55:29 +0000961
Andreas Färbereac8b352013-06-28 21:11:37 +0200962 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000963 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000964 return r->get_reg(env, buf, reg - r->base_reg);
pbrook56aebc82008-10-11 17:55:29 +0000965 }
966 }
967 return 0;
968}
969
Andreas Färber385b9f02013-06-27 18:25:36 +0200970static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000971{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200972 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200973 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000974 GDBRegisterState *r;
975
Andreas Färbera0e372f2013-06-28 23:18:47 +0200976 if (reg < cc->gdb_num_core_regs) {
Andreas Färber5b50e792013-06-29 04:18:45 +0200977 return cc->gdb_write_register(cpu, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200978 }
pbrook56aebc82008-10-11 17:55:29 +0000979
Andreas Färbereac8b352013-06-28 21:11:37 +0200980 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000981 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
982 return r->set_reg(env, mem_buf, reg - r->base_reg);
983 }
984 }
985 return 0;
986}
987
988/* Register a supplemental set of CPU registers. If g_pos is nonzero it
989 specifies the first register number and these registers are included in
990 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
991 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
992 */
993
Andreas Färber22169d42013-06-28 21:27:39 +0200994void gdb_register_coprocessor(CPUState *cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +0000995 gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
Andreas Färber22169d42013-06-28 21:27:39 +0200996 int num_regs, const char *xml, int g_pos)
pbrook56aebc82008-10-11 17:55:29 +0000997{
998 GDBRegisterState *s;
999 GDBRegisterState **p;
pbrook56aebc82008-10-11 17:55:29 +00001000
Andreas Färbereac8b352013-06-28 21:11:37 +02001001 p = &cpu->gdb_regs;
pbrook56aebc82008-10-11 17:55:29 +00001002 while (*p) {
1003 /* Check for duplicates. */
1004 if (strcmp((*p)->xml, xml) == 0)
1005 return;
1006 p = &(*p)->next;
1007 }
Stefan Weil9643c252011-10-18 22:25:38 +02001008
1009 s = g_new0(GDBRegisterState, 1);
Andreas Färbera0e372f2013-06-28 23:18:47 +02001010 s->base_reg = cpu->gdb_num_regs;
Stefan Weil9643c252011-10-18 22:25:38 +02001011 s->num_regs = num_regs;
1012 s->get_reg = get_reg;
1013 s->set_reg = set_reg;
1014 s->xml = xml;
1015
pbrook56aebc82008-10-11 17:55:29 +00001016 /* Add to end of list. */
Andreas Färbera0e372f2013-06-28 23:18:47 +02001017 cpu->gdb_num_regs += num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001018 *p = s;
1019 if (g_pos) {
1020 if (g_pos != s->base_reg) {
Ziyue Yang7ae6c572017-01-18 16:03:29 +08001021 error_report("Error: Bad gdb register numbering for '%s', "
1022 "expected %d got %d", xml, g_pos, s->base_reg);
Andreas Färber35143f02013-08-12 18:09:47 +02001023 } else {
1024 cpu->gdb_num_g_regs = cpu->gdb_num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001025 }
1026 }
1027}
1028
aliguoria1d1bb32008-11-18 20:07:32 +00001029#ifndef CONFIG_USER_ONLY
Peter Maydell2472b6c2014-09-12 19:04:17 +01001030/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
1031static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
1032{
1033 static const int xlat[] = {
1034 [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
1035 [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
1036 [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1037 };
1038
1039 CPUClass *cc = CPU_GET_CLASS(cpu);
1040 int cputype = xlat[gdbtype];
1041
1042 if (cc->gdb_stop_before_watchpoint) {
1043 cputype |= BP_STOP_BEFORE_ACCESS;
1044 }
1045 return cputype;
1046}
aliguoria1d1bb32008-11-18 20:07:32 +00001047#endif
1048
Jon Doron77f6ce52019-05-29 09:41:35 +03001049static int gdb_breakpoint_insert(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001050{
Andreas Färber182735e2013-05-29 22:29:20 +02001051 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001052 int err = 0;
1053
Andreas Färber62278812013-06-27 17:12:06 +02001054 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001055 return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001056 }
aliguorie22a25c2009-03-12 20:12:48 +00001057
aliguoria1d1bb32008-11-18 20:07:32 +00001058 switch (type) {
1059 case GDB_BREAKPOINT_SW:
1060 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001061 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001062 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
1063 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001064 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001065 }
aliguori880a7572008-11-18 20:30:24 +00001066 }
1067 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001068#ifndef CONFIG_USER_ONLY
1069 case GDB_WATCHPOINT_WRITE:
1070 case GDB_WATCHPOINT_READ:
1071 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001072 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001073 err = cpu_watchpoint_insert(cpu, addr, len,
1074 xlat_gdb_type(cpu, type), NULL);
1075 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001076 break;
Peter Maydell2472b6c2014-09-12 19:04:17 +01001077 }
aliguori880a7572008-11-18 20:30:24 +00001078 }
1079 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001080#endif
1081 default:
1082 return -ENOSYS;
1083 }
1084}
1085
Jon Doron77f6ce52019-05-29 09:41:35 +03001086static int gdb_breakpoint_remove(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001087{
Andreas Färber182735e2013-05-29 22:29:20 +02001088 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001089 int err = 0;
1090
Andreas Färber62278812013-06-27 17:12:06 +02001091 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001092 return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001093 }
aliguorie22a25c2009-03-12 20:12:48 +00001094
aliguoria1d1bb32008-11-18 20:07:32 +00001095 switch (type) {
1096 case GDB_BREAKPOINT_SW:
1097 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001098 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001099 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
1100 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001101 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001102 }
aliguori880a7572008-11-18 20:30:24 +00001103 }
1104 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001105#ifndef CONFIG_USER_ONLY
1106 case GDB_WATCHPOINT_WRITE:
1107 case GDB_WATCHPOINT_READ:
1108 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001109 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001110 err = cpu_watchpoint_remove(cpu, addr, len,
1111 xlat_gdb_type(cpu, type));
aliguori880a7572008-11-18 20:30:24 +00001112 if (err)
1113 break;
1114 }
1115 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001116#endif
1117 default:
1118 return -ENOSYS;
1119 }
1120}
1121
Luc Michel546f3c62019-01-07 15:23:46 +00001122static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
1123{
1124 cpu_breakpoint_remove_all(cpu, BP_GDB);
1125#ifndef CONFIG_USER_ONLY
1126 cpu_watchpoint_remove_all(cpu, BP_GDB);
1127#endif
1128}
1129
Alex Bennéea346af32020-03-16 17:21:34 +00001130static void gdb_process_breakpoint_remove_all(GDBProcess *p)
Luc Michel546f3c62019-01-07 15:23:46 +00001131{
Alex Bennéea346af32020-03-16 17:21:34 +00001132 CPUState *cpu = get_first_cpu_in_process(p);
Luc Michel546f3c62019-01-07 15:23:46 +00001133
1134 while (cpu) {
1135 gdb_cpu_breakpoint_remove_all(cpu);
Alex Bennéea346af32020-03-16 17:21:34 +00001136 cpu = gdb_next_cpu_in_process(cpu);
Luc Michel546f3c62019-01-07 15:23:46 +00001137 }
1138}
1139
aliguori880a7572008-11-18 20:30:24 +00001140static void gdb_breakpoint_remove_all(void)
aliguoria1d1bb32008-11-18 20:07:32 +00001141{
Andreas Färber182735e2013-05-29 22:29:20 +02001142 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001143
aliguorie22a25c2009-03-12 20:12:48 +00001144 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001145 kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
aliguorie22a25c2009-03-12 20:12:48 +00001146 return;
1147 }
1148
Andreas Färberbdc44642013-06-24 23:50:24 +02001149 CPU_FOREACH(cpu) {
Luc Michel546f3c62019-01-07 15:23:46 +00001150 gdb_cpu_breakpoint_remove_all(cpu);
aliguori880a7572008-11-18 20:30:24 +00001151 }
aliguoria1d1bb32008-11-18 20:07:32 +00001152}
1153
Alex Bennéea346af32020-03-16 17:21:34 +00001154static void gdb_set_cpu_pc(target_ulong pc)
aurel32fab9d282009-04-08 21:29:37 +00001155{
Alex Bennéea346af32020-03-16 17:21:34 +00001156 CPUState *cpu = gdbserver_state.c_cpu;
Andreas Färberf45748f2013-06-21 19:09:18 +02001157
1158 cpu_synchronize_state(cpu);
Peter Crosthwaite4a2b24e2015-06-23 20:19:21 -07001159 cpu_set_pc(cpu, pc);
aurel32fab9d282009-04-08 21:29:37 +00001160}
1161
Alex Bennée308f9e82020-03-16 17:21:35 +00001162static void gdb_append_thread_id(CPUState *cpu, GString *buf)
Luc Michel1a227332019-01-07 15:23:45 +00001163{
Alex Bennéea346af32020-03-16 17:21:34 +00001164 if (gdbserver_state.multiprocess) {
Alex Bennée308f9e82020-03-16 17:21:35 +00001165 g_string_append_printf(buf, "p%02x.%02x",
1166 gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001167 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00001168 g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001169 }
Luc Michel1a227332019-01-07 15:23:45 +00001170}
1171
Luc Michel7d8c87d2019-01-07 15:23:45 +00001172typedef enum GDBThreadIdKind {
1173 GDB_ONE_THREAD = 0,
1174 GDB_ALL_THREADS, /* One process, all threads */
1175 GDB_ALL_PROCESSES,
1176 GDB_READ_THREAD_ERR
1177} GDBThreadIdKind;
1178
1179static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
1180 uint32_t *pid, uint32_t *tid)
1181{
1182 unsigned long p, t;
1183 int ret;
1184
1185 if (*buf == 'p') {
1186 buf++;
1187 ret = qemu_strtoul(buf, &buf, 16, &p);
1188
1189 if (ret) {
1190 return GDB_READ_THREAD_ERR;
1191 }
1192
1193 /* Skip '.' */
1194 buf++;
1195 } else {
1196 p = 1;
1197 }
1198
1199 ret = qemu_strtoul(buf, &buf, 16, &t);
1200
1201 if (ret) {
1202 return GDB_READ_THREAD_ERR;
1203 }
1204
1205 *end_buf = buf;
1206
1207 if (p == -1) {
1208 return GDB_ALL_PROCESSES;
1209 }
1210
1211 if (pid) {
1212 *pid = p;
1213 }
1214
1215 if (t == -1) {
1216 return GDB_ALL_THREADS;
1217 }
1218
1219 if (tid) {
1220 *tid = t;
1221 }
1222
1223 return GDB_ONE_THREAD;
1224}
1225
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001226/**
1227 * gdb_handle_vcont - Parses and handles a vCont packet.
1228 * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1229 * a format error, 0 on success.
1230 */
Alex Bennéea346af32020-03-16 17:21:34 +00001231static int gdb_handle_vcont(const char *p)
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001232{
Luc Michele40e5202019-01-07 15:23:46 +00001233 int res, signal = 0;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001234 char cur_action;
1235 char *newstates;
1236 unsigned long tmp;
Luc Michele40e5202019-01-07 15:23:46 +00001237 uint32_t pid, tid;
1238 GDBProcess *process;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001239 CPUState *cpu;
Luc Michelc99ef792019-03-26 12:53:26 +00001240 GDBThreadIdKind kind;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001241#ifdef CONFIG_USER_ONLY
1242 int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1243
1244 CPU_FOREACH(cpu) {
1245 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1246 }
Like Xu5cc87672019-05-19 04:54:21 +08001247#else
1248 MachineState *ms = MACHINE(qdev_get_machine());
1249 unsigned int max_cpus = ms->smp.max_cpus;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001250#endif
1251 /* uninitialised CPUs stay 0 */
1252 newstates = g_new0(char, max_cpus);
1253
1254 /* mark valid CPUs with 1 */
1255 CPU_FOREACH(cpu) {
1256 newstates[cpu->cpu_index] = 1;
1257 }
1258
1259 /*
1260 * res keeps track of what error we are returning, with -ENOTSUP meaning
1261 * that the command is unknown or unsupported, thus returning an empty
1262 * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1263 * or incorrect parameters passed.
1264 */
1265 res = 0;
1266 while (*p) {
1267 if (*p++ != ';') {
1268 res = -ENOTSUP;
1269 goto out;
1270 }
1271
1272 cur_action = *p++;
1273 if (cur_action == 'C' || cur_action == 'S') {
Peter Maydell95a5bef2017-07-20 17:31:30 +01001274 cur_action = qemu_tolower(cur_action);
Peter Maydell3ddd9032020-11-21 21:03:42 +00001275 res = qemu_strtoul(p, &p, 16, &tmp);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001276 if (res) {
1277 goto out;
1278 }
1279 signal = gdb_signal_to_target(tmp);
1280 } else if (cur_action != 'c' && cur_action != 's') {
1281 /* unknown/invalid/unsupported command */
1282 res = -ENOTSUP;
1283 goto out;
1284 }
Luc Michele40e5202019-01-07 15:23:46 +00001285
Luc Michelc99ef792019-03-26 12:53:26 +00001286 if (*p == '\0' || *p == ';') {
1287 /*
1288 * No thread specifier, action is on "all threads". The
1289 * specification is unclear regarding the process to act on. We
1290 * choose all processes.
1291 */
1292 kind = GDB_ALL_PROCESSES;
1293 } else if (*p++ == ':') {
1294 kind = read_thread_id(p, &p, &pid, &tid);
1295 } else {
Luc Michele40e5202019-01-07 15:23:46 +00001296 res = -ENOTSUP;
1297 goto out;
1298 }
1299
Luc Michelc99ef792019-03-26 12:53:26 +00001300 switch (kind) {
Luc Michele40e5202019-01-07 15:23:46 +00001301 case GDB_READ_THREAD_ERR:
1302 res = -EINVAL;
1303 goto out;
1304
1305 case GDB_ALL_PROCESSES:
Alex Bennéea346af32020-03-16 17:21:34 +00001306 cpu = gdb_first_attached_cpu();
Luc Michele40e5202019-01-07 15:23:46 +00001307 while (cpu) {
1308 if (newstates[cpu->cpu_index] == 1) {
1309 newstates[cpu->cpu_index] = cur_action;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001310 }
Luc Michele40e5202019-01-07 15:23:46 +00001311
Alex Bennéea346af32020-03-16 17:21:34 +00001312 cpu = gdb_next_attached_cpu(cpu);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001313 }
Luc Michele40e5202019-01-07 15:23:46 +00001314 break;
1315
1316 case GDB_ALL_THREADS:
Alex Bennéea346af32020-03-16 17:21:34 +00001317 process = gdb_get_process(pid);
Luc Michele40e5202019-01-07 15:23:46 +00001318
1319 if (!process->attached) {
1320 res = -EINVAL;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001321 goto out;
1322 }
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001323
Alex Bennéea346af32020-03-16 17:21:34 +00001324 cpu = get_first_cpu_in_process(process);
Luc Michele40e5202019-01-07 15:23:46 +00001325 while (cpu) {
1326 if (newstates[cpu->cpu_index] == 1) {
1327 newstates[cpu->cpu_index] = cur_action;
1328 }
1329
Alex Bennéea346af32020-03-16 17:21:34 +00001330 cpu = gdb_next_cpu_in_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +00001331 }
1332 break;
1333
1334 case GDB_ONE_THREAD:
Alex Bennéea346af32020-03-16 17:21:34 +00001335 cpu = gdb_get_cpu(pid, tid);
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001336
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001337 /* invalid CPU/thread specified */
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001338 if (!cpu) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001339 res = -EINVAL;
1340 goto out;
1341 }
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001342
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001343 /* only use if no previous match occourred */
1344 if (newstates[cpu->cpu_index] == 1) {
1345 newstates[cpu->cpu_index] = cur_action;
1346 }
Luc Michele40e5202019-01-07 15:23:46 +00001347 break;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001348 }
1349 }
Alex Bennéea346af32020-03-16 17:21:34 +00001350 gdbserver_state.signal = signal;
1351 gdb_continue_partial(newstates);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001352
1353out:
1354 g_free(newstates);
1355
1356 return res;
1357}
1358
Jon Dorond14055d2019-05-29 09:41:29 +03001359typedef union GdbCmdVariant {
1360 const char *data;
1361 uint8_t opcode;
1362 unsigned long val_ul;
1363 unsigned long long val_ull;
1364 struct {
1365 GDBThreadIdKind kind;
1366 uint32_t pid;
1367 uint32_t tid;
1368 } thread_id;
1369} GdbCmdVariant;
1370
Alex Bennée26a16182021-05-25 09:24:14 +01001371#define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
1372
Jon Dorond14055d2019-05-29 09:41:29 +03001373static const char *cmd_next_param(const char *param, const char delimiter)
1374{
1375 static const char all_delimiters[] = ",;:=";
1376 char curr_delimiters[2] = {0};
1377 const char *delimiters;
1378
1379 if (delimiter == '?') {
1380 delimiters = all_delimiters;
1381 } else if (delimiter == '0') {
1382 return strchr(param, '\0');
1383 } else if (delimiter == '.' && *param) {
1384 return param + 1;
1385 } else {
1386 curr_delimiters[0] = delimiter;
1387 delimiters = curr_delimiters;
1388 }
1389
1390 param += strcspn(param, delimiters);
1391 if (*param) {
1392 param++;
1393 }
1394 return param;
1395}
1396
1397static int cmd_parse_params(const char *data, const char *schema,
Alex Bennée26a16182021-05-25 09:24:14 +01001398 GArray *params)
Jon Dorond14055d2019-05-29 09:41:29 +03001399{
Jon Dorond14055d2019-05-29 09:41:29 +03001400 const char *curr_schema, *curr_data;
1401
Alex Bennée26a16182021-05-25 09:24:14 +01001402 g_assert(schema);
1403 g_assert(params->len == 0);
Jon Dorond14055d2019-05-29 09:41:29 +03001404
1405 curr_schema = schema;
Jon Dorond14055d2019-05-29 09:41:29 +03001406 curr_data = data;
1407 while (curr_schema[0] && curr_schema[1] && *curr_data) {
Alex Bennée26a16182021-05-25 09:24:14 +01001408 GdbCmdVariant this_param;
1409
Jon Dorond14055d2019-05-29 09:41:29 +03001410 switch (curr_schema[0]) {
1411 case 'l':
1412 if (qemu_strtoul(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001413 &this_param.val_ul)) {
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 'L':
1420 if (qemu_strtou64(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001421 (uint64_t *)&this_param.val_ull)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001422 return -EINVAL;
1423 }
Jon Dorond14055d2019-05-29 09:41:29 +03001424 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001425 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001426 break;
1427 case 's':
Alex Bennée26a16182021-05-25 09:24:14 +01001428 this_param.data = curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001429 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001430 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001431 break;
1432 case 'o':
Alex Bennée26a16182021-05-25 09:24:14 +01001433 this_param.opcode = *(uint8_t *)curr_data;
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 't':
Alex Bennée26a16182021-05-25 09:24:14 +01001438 this_param.thread_id.kind =
Jon Dorond14055d2019-05-29 09:41:29 +03001439 read_thread_id(curr_data, &curr_data,
Alex Bennée26a16182021-05-25 09:24:14 +01001440 &this_param.thread_id.pid,
1441 &this_param.thread_id.tid);
Jon Dorond14055d2019-05-29 09:41:29 +03001442 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001443 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001444 break;
1445 case '?':
1446 curr_data = cmd_next_param(curr_data, curr_schema[1]);
1447 break;
1448 default:
1449 return -EINVAL;
1450 }
1451 curr_schema += 2;
1452 }
1453
Jon Dorond14055d2019-05-29 09:41:29 +03001454 return 0;
1455}
1456
Alex Bennée26a16182021-05-25 09:24:14 +01001457typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001458
1459/*
1460 * cmd_startswith -> cmd is compared using startswith
1461 *
1462 *
1463 * schema definitions:
1464 * Each schema parameter entry consists of 2 chars,
1465 * the first char represents the parameter type handling
1466 * the second char represents the delimiter for the next parameter
1467 *
1468 * Currently supported schema types:
1469 * 'l' -> unsigned long (stored in .val_ul)
1470 * 'L' -> unsigned long long (stored in .val_ull)
1471 * 's' -> string (stored in .data)
1472 * 'o' -> single char (stored in .opcode)
1473 * 't' -> thread id (stored in .thread_id)
1474 * '?' -> skip according to delimiter
1475 *
1476 * Currently supported delimiters:
1477 * '?' -> Stop at any delimiter (",;:=\0")
1478 * '0' -> Stop at "\0"
1479 * '.' -> Skip 1 char unless reached "\0"
1480 * Any other value is treated as the delimiter value itself
1481 */
1482typedef struct GdbCmdParseEntry {
1483 GdbCmdHandler handler;
1484 const char *cmd;
1485 bool cmd_startswith;
1486 const char *schema;
1487} GdbCmdParseEntry;
1488
1489static inline int startswith(const char *string, const char *pattern)
1490{
1491 return !strncmp(string, pattern, strlen(pattern));
1492}
1493
Alex Bennéea346af32020-03-16 17:21:34 +00001494static int process_string_cmd(void *user_ctx, const char *data,
Jon Dorond14055d2019-05-29 09:41:29 +03001495 const GdbCmdParseEntry *cmds, int num_cmds)
1496{
Alex Bennée26a16182021-05-25 09:24:14 +01001497 int i;
1498 g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
Jon Dorond14055d2019-05-29 09:41:29 +03001499
1500 if (!cmds) {
1501 return -1;
1502 }
1503
1504 for (i = 0; i < num_cmds; i++) {
1505 const GdbCmdParseEntry *cmd = &cmds[i];
1506 g_assert(cmd->handler && cmd->cmd);
1507
1508 if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1509 (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1510 continue;
1511 }
1512
1513 if (cmd->schema) {
Alex Bennée26a16182021-05-25 09:24:14 +01001514 if (cmd_parse_params(&data[strlen(cmd->cmd)],
1515 cmd->schema, params)) {
1516 return -1;
Jon Dorond14055d2019-05-29 09:41:29 +03001517 }
Jon Dorond14055d2019-05-29 09:41:29 +03001518 }
1519
Alex Bennée26a16182021-05-25 09:24:14 +01001520 cmd->handler(params, user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001521 return 0;
1522 }
1523
1524 return -1;
1525}
1526
Alex Bennéea346af32020-03-16 17:21:34 +00001527static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
Jon Doron3e2c1262019-05-29 09:41:30 +03001528{
1529 if (!data) {
1530 return;
1531 }
1532
Alex Bennée308f9e82020-03-16 17:21:35 +00001533 g_string_set_size(gdbserver_state.str_buf, 0);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001534 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Alex Bennée308f9e82020-03-16 17:21:35 +00001535
Jon Doron3e2c1262019-05-29 09:41:30 +03001536 /* In case there was an error during the command parsing we must
1537 * send a NULL packet to indicate the command is not supported */
Alex Bennéea346af32020-03-16 17:21:34 +00001538 if (process_string_cmd(NULL, data, cmd, 1)) {
1539 put_packet("");
Jon Doron3e2c1262019-05-29 09:41:30 +03001540 }
1541}
1542
Alex Bennée26a16182021-05-25 09:24:14 +01001543static void handle_detach(GArray *params, void *user_ctx)
Jon Doron3e2c1262019-05-29 09:41:30 +03001544{
1545 GDBProcess *process;
Jon Doron3e2c1262019-05-29 09:41:30 +03001546 uint32_t pid = 1;
1547
Alex Bennéea346af32020-03-16 17:21:34 +00001548 if (gdbserver_state.multiprocess) {
Alex Bennée26a16182021-05-25 09:24:14 +01001549 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001550 put_packet("E22");
Jon Doron3e2c1262019-05-29 09:41:30 +03001551 return;
1552 }
1553
Alex Bennée26a16182021-05-25 09:24:14 +01001554 pid = get_param(params, 0)->val_ul;
Jon Doron3e2c1262019-05-29 09:41:30 +03001555 }
1556
Alex Bennéea346af32020-03-16 17:21:34 +00001557 process = gdb_get_process(pid);
1558 gdb_process_breakpoint_remove_all(process);
Jon Doron3e2c1262019-05-29 09:41:30 +03001559 process->attached = false;
1560
Alex Bennéea346af32020-03-16 17:21:34 +00001561 if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1562 gdbserver_state.c_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001563 }
1564
Alex Bennéea346af32020-03-16 17:21:34 +00001565 if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1566 gdbserver_state.g_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001567 }
1568
Alex Bennéea346af32020-03-16 17:21:34 +00001569 if (!gdbserver_state.c_cpu) {
Jon Doron3e2c1262019-05-29 09:41:30 +03001570 /* No more process attached */
1571 gdb_syscall_mode = GDB_SYS_DISABLED;
Alex Bennéea346af32020-03-16 17:21:34 +00001572 gdb_continue();
Jon Doron3e2c1262019-05-29 09:41:30 +03001573 }
Alex Bennéea346af32020-03-16 17:21:34 +00001574 put_packet("OK");
Jon Doron3e2c1262019-05-29 09:41:30 +03001575}
1576
Alex Bennée26a16182021-05-25 09:24:14 +01001577static void handle_thread_alive(GArray *params, void *user_ctx)
Jon Doron44ffded2019-05-29 09:41:31 +03001578{
1579 CPUState *cpu;
1580
Alex Bennée26a16182021-05-25 09:24:14 +01001581 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001582 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001583 return;
1584 }
1585
Alex Bennée26a16182021-05-25 09:24:14 +01001586 if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001587 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001588 return;
1589 }
1590
Alex Bennée26a16182021-05-25 09:24:14 +01001591 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1592 get_param(params, 0)->thread_id.tid);
Jon Doron44ffded2019-05-29 09:41:31 +03001593 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001594 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001595 return;
1596 }
1597
Alex Bennéea346af32020-03-16 17:21:34 +00001598 put_packet("OK");
Jon Doron44ffded2019-05-29 09:41:31 +03001599}
1600
Alex Bennée26a16182021-05-25 09:24:14 +01001601static void handle_continue(GArray *params, void *user_ctx)
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001602{
Alex Bennée26a16182021-05-25 09:24:14 +01001603 if (params->len) {
1604 gdb_set_cpu_pc(get_param(params, 0)->val_ull);
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001605 }
1606
Alex Bennéea346af32020-03-16 17:21:34 +00001607 gdbserver_state.signal = 0;
1608 gdb_continue();
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001609}
1610
Alex Bennée26a16182021-05-25 09:24:14 +01001611static void handle_cont_with_sig(GArray *params, void *user_ctx)
Jon Doronccc47d52019-05-29 09:41:33 +03001612{
1613 unsigned long signal = 0;
1614
1615 /*
1616 * Note: C sig;[addr] is currently unsupported and we simply
1617 * omit the addr parameter
1618 */
Alex Bennée26a16182021-05-25 09:24:14 +01001619 if (params->len) {
1620 signal = get_param(params, 0)->val_ul;
Jon Doronccc47d52019-05-29 09:41:33 +03001621 }
1622
Alex Bennéea346af32020-03-16 17:21:34 +00001623 gdbserver_state.signal = gdb_signal_to_target(signal);
1624 if (gdbserver_state.signal == -1) {
1625 gdbserver_state.signal = 0;
Jon Doronccc47d52019-05-29 09:41:33 +03001626 }
Alex Bennéea346af32020-03-16 17:21:34 +00001627 gdb_continue();
Jon Doronccc47d52019-05-29 09:41:33 +03001628}
1629
Alex Bennée26a16182021-05-25 09:24:14 +01001630static void handle_set_thread(GArray *params, void *user_ctx)
Jon Doron3a9651d2019-05-29 09:41:34 +03001631{
1632 CPUState *cpu;
1633
Alex Bennée26a16182021-05-25 09:24:14 +01001634 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001635 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001636 return;
1637 }
1638
Alex Bennée26a16182021-05-25 09:24:14 +01001639 if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001640 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001641 return;
1642 }
1643
Alex Bennée26a16182021-05-25 09:24:14 +01001644 if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
Alex Bennéea346af32020-03-16 17:21:34 +00001645 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001646 return;
1647 }
1648
Alex Bennée26a16182021-05-25 09:24:14 +01001649 cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1650 get_param(params, 1)->thread_id.tid);
Jon Doron3a9651d2019-05-29 09:41:34 +03001651 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001652 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001653 return;
1654 }
1655
1656 /*
1657 * Note: This command is deprecated and modern gdb's will be using the
1658 * vCont command instead.
1659 */
Alex Bennée26a16182021-05-25 09:24:14 +01001660 switch (get_param(params, 0)->opcode) {
Jon Doron3a9651d2019-05-29 09:41:34 +03001661 case 'c':
Alex Bennéea346af32020-03-16 17:21:34 +00001662 gdbserver_state.c_cpu = cpu;
1663 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001664 break;
1665 case 'g':
Alex Bennéea346af32020-03-16 17:21:34 +00001666 gdbserver_state.g_cpu = cpu;
1667 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001668 break;
1669 default:
Alex Bennéea346af32020-03-16 17:21:34 +00001670 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001671 break;
1672 }
1673}
1674
Alex Bennée26a16182021-05-25 09:24:14 +01001675static void handle_insert_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001676{
1677 int res;
1678
Alex Bennée26a16182021-05-25 09:24:14 +01001679 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001680 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001681 return;
1682 }
1683
Alex Bennée26a16182021-05-25 09:24:14 +01001684 res = gdb_breakpoint_insert(get_param(params, 0)->val_ul,
1685 get_param(params, 1)->val_ull,
1686 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001687 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001688 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001689 return;
1690 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001691 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001692 return;
1693 }
1694
Alex Bennéea346af32020-03-16 17:21:34 +00001695 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001696}
1697
Alex Bennée26a16182021-05-25 09:24:14 +01001698static void handle_remove_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001699{
1700 int res;
1701
Alex Bennée26a16182021-05-25 09:24:14 +01001702 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001703 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001704 return;
1705 }
1706
Alex Bennée26a16182021-05-25 09:24:14 +01001707 res = gdb_breakpoint_remove(get_param(params, 0)->val_ul,
1708 get_param(params, 1)->val_ull,
1709 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001710 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001711 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001712 return;
1713 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001714 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001715 return;
1716 }
1717
Alex Bennéea346af32020-03-16 17:21:34 +00001718 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001719}
1720
Alex Bennée94b2a622019-07-05 14:23:07 +01001721/*
1722 * handle_set/get_reg
1723 *
1724 * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1725 * This works, but can be very slow. Anything new enough to understand
1726 * XML also knows how to use this properly. However to use this we
1727 * need to define a local XML file as well as be talking to a
1728 * reasonably modern gdb. Responding with an empty packet will cause
1729 * the remote gdb to fallback to older methods.
1730 */
1731
Alex Bennée26a16182021-05-25 09:24:14 +01001732static void handle_set_reg(GArray *params, void *user_ctx)
Jon Doron62b33202019-05-29 09:41:36 +03001733{
1734 int reg_size;
1735
1736 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001737 put_packet("");
Jon Doron62b33202019-05-29 09:41:36 +03001738 return;
1739 }
1740
Alex Bennée26a16182021-05-25 09:24:14 +01001741 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001742 put_packet("E22");
Jon Doron62b33202019-05-29 09:41:36 +03001743 return;
1744 }
1745
Alex Bennée26a16182021-05-25 09:24:14 +01001746 reg_size = strlen(get_param(params, 1)->data) / 2;
1747 hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001748 gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
Alex Bennée26a16182021-05-25 09:24:14 +01001749 get_param(params, 0)->val_ull);
Alex Bennéea346af32020-03-16 17:21:34 +00001750 put_packet("OK");
Jon Doron62b33202019-05-29 09:41:36 +03001751}
1752
Alex Bennée26a16182021-05-25 09:24:14 +01001753static void handle_get_reg(GArray *params, void *user_ctx)
Jon Doron5d0e57b2019-05-29 09:41:37 +03001754{
1755 int reg_size;
1756
Jon Doron5d0e57b2019-05-29 09:41:37 +03001757 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001758 put_packet("");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001759 return;
1760 }
1761
Alex Bennée26a16182021-05-25 09:24:14 +01001762 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001763 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001764 return;
1765 }
1766
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001767 reg_size = gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001768 gdbserver_state.mem_buf,
Alex Bennée26a16182021-05-25 09:24:14 +01001769 get_param(params, 0)->val_ull);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001770 if (!reg_size) {
Alex Bennéea346af32020-03-16 17:21:34 +00001771 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001772 return;
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001773 } else {
1774 g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001775 }
1776
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001777 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
Alex Bennée308f9e82020-03-16 17:21:35 +00001778 put_strbuf();
Jon Doron5d0e57b2019-05-29 09:41:37 +03001779}
1780
Alex Bennée26a16182021-05-25 09:24:14 +01001781static void handle_write_mem(GArray *params, void *user_ctx)
Jon Doroncc0ecc72019-05-29 09:41:38 +03001782{
Alex Bennée26a16182021-05-25 09:24:14 +01001783 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001784 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001785 return;
1786 }
1787
1788 /* hextomem() reads 2*len bytes */
Alex Bennée26a16182021-05-25 09:24:14 +01001789 if (get_param(params, 1)->val_ull >
1790 strlen(get_param(params, 2)->data) / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001791 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001792 return;
1793 }
1794
Alex Bennée26a16182021-05-25 09:24:14 +01001795 hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1796 get_param(params, 1)->val_ull);
1797 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1798 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001799 gdbserver_state.mem_buf->data,
1800 gdbserver_state.mem_buf->len, true)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001801 put_packet("E14");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001802 return;
1803 }
1804
Alex Bennéea346af32020-03-16 17:21:34 +00001805 put_packet("OK");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001806}
1807
Alex Bennée26a16182021-05-25 09:24:14 +01001808static void handle_read_mem(GArray *params, void *user_ctx)
Jon Doronda92e232019-05-29 09:41:39 +03001809{
Alex Bennée26a16182021-05-25 09:24:14 +01001810 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001811 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001812 return;
1813 }
1814
1815 /* memtohex() doubles the required space */
Alex Bennée26a16182021-05-25 09:24:14 +01001816 if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001817 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001818 return;
1819 }
1820
Alex Bennée26a16182021-05-25 09:24:14 +01001821 g_byte_array_set_size(gdbserver_state.mem_buf,
1822 get_param(params, 1)->val_ull);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001823
Alex Bennée26a16182021-05-25 09:24:14 +01001824 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1825 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001826 gdbserver_state.mem_buf->data,
1827 gdbserver_state.mem_buf->len, false)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001828 put_packet("E14");
Jon Doronda92e232019-05-29 09:41:39 +03001829 return;
1830 }
1831
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001832 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1833 gdbserver_state.mem_buf->len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001834 put_strbuf();
Jon Doronda92e232019-05-29 09:41:39 +03001835}
1836
Alex Bennée26a16182021-05-25 09:24:14 +01001837static void handle_write_all_regs(GArray *params, void *user_ctx)
Jon Doron287ca122019-05-29 09:41:40 +03001838{
1839 target_ulong addr, len;
1840 uint8_t *registers;
1841 int reg_size;
1842
Alex Bennée26a16182021-05-25 09:24:14 +01001843 if (!params->len) {
Jon Doron287ca122019-05-29 09:41:40 +03001844 return;
1845 }
1846
Alex Bennéea346af32020-03-16 17:21:34 +00001847 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennée26a16182021-05-25 09:24:14 +01001848 len = strlen(get_param(params, 0)->data) / 2;
1849 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001850 registers = gdbserver_state.mem_buf->data;
Alex Bennéea346af32020-03-16 17:21:34 +00001851 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
Jon Doron287ca122019-05-29 09:41:40 +03001852 addr++) {
Alex Bennéea346af32020-03-16 17:21:34 +00001853 reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
Jon Doron287ca122019-05-29 09:41:40 +03001854 len -= reg_size;
1855 registers += reg_size;
1856 }
Alex Bennéea346af32020-03-16 17:21:34 +00001857 put_packet("OK");
Jon Doron287ca122019-05-29 09:41:40 +03001858}
1859
Alex Bennée26a16182021-05-25 09:24:14 +01001860static void handle_read_all_regs(GArray *params, void *user_ctx)
Jon Doron397d1372019-05-29 09:41:41 +03001861{
1862 target_ulong addr, len;
1863
Alex Bennéea346af32020-03-16 17:21:34 +00001864 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennéea010bdb2020-03-16 17:21:41 +00001865 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Jon Doron397d1372019-05-29 09:41:41 +03001866 len = 0;
Alex Bennéea346af32020-03-16 17:21:34 +00001867 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001868 len += gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001869 gdbserver_state.mem_buf,
Jon Doron397d1372019-05-29 09:41:41 +03001870 addr);
1871 }
Alex Bennéea010bdb2020-03-16 17:21:41 +00001872 g_assert(len == gdbserver_state.mem_buf->len);
Jon Doron397d1372019-05-29 09:41:41 +03001873
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001874 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001875 put_strbuf();
Jon Doron397d1372019-05-29 09:41:41 +03001876}
1877
Alex Bennée26a16182021-05-25 09:24:14 +01001878static void handle_file_io(GArray *params, void *user_ctx)
Jon Doron4b20fab2019-05-29 09:41:42 +03001879{
Alex Bennée26a16182021-05-25 09:24:14 +01001880 if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
Richard Henderson64c8c6a2022-04-29 16:21:43 -07001881 uint64_t ret;
1882 int err;
Jon Doron4b20fab2019-05-29 09:41:42 +03001883
Richard Henderson64c8c6a2022-04-29 16:21:43 -07001884 ret = get_param(params, 0)->val_ull;
Alex Bennée26a16182021-05-25 09:24:14 +01001885 if (params->len >= 2) {
Richard Henderson64c8c6a2022-04-29 16:21:43 -07001886 err = get_param(params, 1)->val_ull;
Sandra Loosemorec6ee9522019-08-27 16:33:17 -06001887 } else {
1888 err = 0;
1889 }
Richard Hendersonc805e112022-06-07 12:38:26 -07001890
1891 /* Convert GDB error numbers back to host error numbers. */
1892#define E(X) case GDB_E##X: err = E##X; break
1893 switch (err) {
1894 case 0:
1895 break;
1896 E(PERM);
1897 E(NOENT);
1898 E(INTR);
1899 E(BADF);
1900 E(ACCES);
1901 E(FAULT);
1902 E(BUSY);
1903 E(EXIST);
1904 E(NODEV);
1905 E(NOTDIR);
1906 E(ISDIR);
1907 E(INVAL);
1908 E(NFILE);
1909 E(MFILE);
1910 E(FBIG);
1911 E(NOSPC);
1912 E(SPIPE);
1913 E(ROFS);
1914 E(NAMETOOLONG);
1915 default:
1916 err = EINVAL;
1917 break;
1918 }
1919#undef E
1920
Alex Bennéea346af32020-03-16 17:21:34 +00001921 gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1922 gdbserver_state.current_syscall_cb = NULL;
Jon Doron4b20fab2019-05-29 09:41:42 +03001923 }
1924
Alex Bennée26a16182021-05-25 09:24:14 +01001925 if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
Alex Bennéea346af32020-03-16 17:21:34 +00001926 put_packet("T02");
Jon Doron4b20fab2019-05-29 09:41:42 +03001927 return;
1928 }
1929
Alex Bennéea346af32020-03-16 17:21:34 +00001930 gdb_continue();
Jon Doron4b20fab2019-05-29 09:41:42 +03001931}
1932
Alex Bennée26a16182021-05-25 09:24:14 +01001933static void handle_step(GArray *params, void *user_ctx)
Jon Doron933f80d2019-05-29 09:41:43 +03001934{
Alex Bennée26a16182021-05-25 09:24:14 +01001935 if (params->len) {
1936 gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
Jon Doron933f80d2019-05-29 09:41:43 +03001937 }
1938
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001939 cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
Alex Bennéea346af32020-03-16 17:21:34 +00001940 gdb_continue();
Jon Doron933f80d2019-05-29 09:41:43 +03001941}
1942
Alex Bennée26a16182021-05-25 09:24:14 +01001943static void handle_backward(GArray *params, void *user_ctx)
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001944{
Alex Bennéeed12f5b2021-05-20 18:43:02 +01001945 if (!stub_can_reverse()) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001946 put_packet("E22");
1947 }
Alex Bennée26a16182021-05-25 09:24:14 +01001948 if (params->len == 1) {
1949 switch (get_param(params, 0)->opcode) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001950 case 's':
1951 if (replay_reverse_step()) {
1952 gdb_continue();
1953 } else {
1954 put_packet("E14");
1955 }
1956 return;
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03001957 case 'c':
1958 if (replay_reverse_continue()) {
1959 gdb_continue();
1960 } else {
1961 put_packet("E14");
1962 }
1963 return;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001964 }
1965 }
1966
1967 /* Default invalid command */
1968 put_packet("");
1969}
1970
Alex Bennée26a16182021-05-25 09:24:14 +01001971static void handle_v_cont_query(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001972{
Alex Bennéea346af32020-03-16 17:21:34 +00001973 put_packet("vCont;c;C;s;S");
Jon Doron8536ec02019-05-29 09:41:44 +03001974}
1975
Alex Bennée26a16182021-05-25 09:24:14 +01001976static void handle_v_cont(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001977{
1978 int res;
1979
Alex Bennée26a16182021-05-25 09:24:14 +01001980 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001981 return;
1982 }
1983
Alex Bennée26a16182021-05-25 09:24:14 +01001984 res = gdb_handle_vcont(get_param(params, 0)->data);
Jon Doron8536ec02019-05-29 09:41:44 +03001985 if ((res == -EINVAL) || (res == -ERANGE)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001986 put_packet("E22");
Jon Doron8536ec02019-05-29 09:41:44 +03001987 } else if (res) {
Alex Bennéea346af32020-03-16 17:21:34 +00001988 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03001989 }
1990}
1991
Alex Bennée26a16182021-05-25 09:24:14 +01001992static void handle_v_attach(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001993{
1994 GDBProcess *process;
1995 CPUState *cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001996
Alex Bennée308f9e82020-03-16 17:21:35 +00001997 g_string_assign(gdbserver_state.str_buf, "E22");
Alex Bennée26a16182021-05-25 09:24:14 +01001998 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001999 goto cleanup;
2000 }
2001
Alex Bennée26a16182021-05-25 09:24:14 +01002002 process = gdb_get_process(get_param(params, 0)->val_ul);
Jon Doron8536ec02019-05-29 09:41:44 +03002003 if (!process) {
2004 goto cleanup;
2005 }
2006
Alex Bennéea346af32020-03-16 17:21:34 +00002007 cpu = get_first_cpu_in_process(process);
Jon Doron8536ec02019-05-29 09:41:44 +03002008 if (!cpu) {
2009 goto cleanup;
2010 }
2011
2012 process->attached = true;
Alex Bennéea346af32020-03-16 17:21:34 +00002013 gdbserver_state.g_cpu = cpu;
2014 gdbserver_state.c_cpu = cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03002015
Alex Bennée308f9e82020-03-16 17:21:35 +00002016 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2017 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2018 g_string_append_c(gdbserver_state.str_buf, ';');
Jon Doron8536ec02019-05-29 09:41:44 +03002019cleanup:
Alex Bennée308f9e82020-03-16 17:21:35 +00002020 put_strbuf();
Jon Doron8536ec02019-05-29 09:41:44 +03002021}
2022
Alex Bennée26a16182021-05-25 09:24:14 +01002023static void handle_v_kill(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03002024{
2025 /* Kill the target */
Alex Bennéea346af32020-03-16 17:21:34 +00002026 put_packet("OK");
Jon Doron8536ec02019-05-29 09:41:44 +03002027 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00002028 gdb_exit(0);
Jon Doron8536ec02019-05-29 09:41:44 +03002029 exit(0);
2030}
2031
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002032static const GdbCmdParseEntry gdb_v_commands_table[] = {
Jon Doron8536ec02019-05-29 09:41:44 +03002033 /* Order is important if has same prefix */
2034 {
2035 .handler = handle_v_cont_query,
2036 .cmd = "Cont?",
2037 .cmd_startswith = 1
2038 },
2039 {
2040 .handler = handle_v_cont,
2041 .cmd = "Cont",
2042 .cmd_startswith = 1,
2043 .schema = "s0"
2044 },
2045 {
2046 .handler = handle_v_attach,
2047 .cmd = "Attach;",
2048 .cmd_startswith = 1,
2049 .schema = "l0"
2050 },
2051 {
2052 .handler = handle_v_kill,
2053 .cmd = "Kill;",
2054 .cmd_startswith = 1
2055 },
2056};
2057
Alex Bennée26a16182021-05-25 09:24:14 +01002058static void handle_v_commands(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03002059{
Alex Bennée26a16182021-05-25 09:24:14 +01002060 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03002061 return;
2062 }
2063
Alex Bennée26a16182021-05-25 09:24:14 +01002064 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron8536ec02019-05-29 09:41:44 +03002065 gdb_v_commands_table,
2066 ARRAY_SIZE(gdb_v_commands_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002067 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03002068 }
2069}
2070
Alex Bennée26a16182021-05-25 09:24:14 +01002071static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002072{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002073 g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
2074
2075 if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
2076 g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
2077 SSTEP_NOIRQ);
2078 }
2079
2080 if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
2081 g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
2082 SSTEP_NOTIMER);
2083 }
2084
Alex Bennée308f9e82020-03-16 17:21:35 +00002085 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002086}
2087
Alex Bennée26a16182021-05-25 09:24:14 +01002088static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002089{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002090 int new_sstep_flags;
2091
Alex Bennée26a16182021-05-25 09:24:14 +01002092 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002093 return;
2094 }
2095
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002096 new_sstep_flags = get_param(params, 0)->val_ul;
2097
2098 if (new_sstep_flags & ~gdbserver_state.supported_sstep_flags) {
2099 put_packet("E22");
2100 return;
2101 }
2102
2103 gdbserver_state.sstep_flags = new_sstep_flags;
Alex Bennéea346af32020-03-16 17:21:34 +00002104 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002105}
2106
Alex Bennée26a16182021-05-25 09:24:14 +01002107static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002108{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002109 g_string_printf(gdbserver_state.str_buf, "0x%x",
2110 gdbserver_state.sstep_flags);
Alex Bennée308f9e82020-03-16 17:21:35 +00002111 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002112}
2113
Alex Bennée26a16182021-05-25 09:24:14 +01002114static void handle_query_curr_tid(GArray *params, void *user_ctx)
bellardb4608c02003-06-27 17:34:32 +00002115{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002116 CPUState *cpu;
Luc Michelc145eea2019-01-07 15:23:46 +00002117 GDBProcess *process;
Jon Doron2704efa2019-05-29 09:41:45 +03002118
2119 /*
2120 * "Current thread" remains vague in the spec, so always return
2121 * the first thread of the current process (gdb returns the
2122 * first thread).
2123 */
Alex Bennéea346af32020-03-16 17:21:34 +00002124 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2125 cpu = get_first_cpu_in_process(process);
Alex Bennée308f9e82020-03-16 17:21:35 +00002126 g_string_assign(gdbserver_state.str_buf, "QC");
2127 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2128 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002129}
2130
Alex Bennée26a16182021-05-25 09:24:14 +01002131static void handle_query_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002132{
Alex Bennéea346af32020-03-16 17:21:34 +00002133 if (!gdbserver_state.query_cpu) {
2134 put_packet("l");
Jon Doron2704efa2019-05-29 09:41:45 +03002135 return;
2136 }
2137
Alex Bennée308f9e82020-03-16 17:21:35 +00002138 g_string_assign(gdbserver_state.str_buf, "m");
2139 gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
2140 put_strbuf();
Alex Bennéea346af32020-03-16 17:21:34 +00002141 gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002142}
2143
Alex Bennée26a16182021-05-25 09:24:14 +01002144static void handle_query_first_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002145{
Alex Bennéea346af32020-03-16 17:21:34 +00002146 gdbserver_state.query_cpu = gdb_first_attached_cpu();
Alex Bennée26a16182021-05-25 09:24:14 +01002147 handle_query_threads(params, user_ctx);
Jon Doron2704efa2019-05-29 09:41:45 +03002148}
2149
Alex Bennée26a16182021-05-25 09:24:14 +01002150static void handle_query_thread_extra(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002151{
Alex Bennée308f9e82020-03-16 17:21:35 +00002152 g_autoptr(GString) rs = g_string_new(NULL);
Jon Doron2704efa2019-05-29 09:41:45 +03002153 CPUState *cpu;
Jon Doron2704efa2019-05-29 09:41:45 +03002154
Alex Bennée26a16182021-05-25 09:24:14 +01002155 if (!params->len ||
2156 get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00002157 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002158 return;
2159 }
2160
Alex Bennée26a16182021-05-25 09:24:14 +01002161 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
2162 get_param(params, 0)->thread_id.tid);
Jon Doron2704efa2019-05-29 09:41:45 +03002163 if (!cpu) {
2164 return;
2165 }
2166
2167 cpu_synchronize_state(cpu);
2168
Alex Bennéea346af32020-03-16 17:21:34 +00002169 if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
Jon Doron2704efa2019-05-29 09:41:45 +03002170 /* Print the CPU model and name in multiprocess mode */
2171 ObjectClass *oc = object_get_class(OBJECT(cpu));
2172 const char *cpu_model = object_class_get_name(oc);
Markus Armbruster7a309cc2020-07-14 18:02:00 +02002173 const char *cpu_name =
Denis Plotnikov076b2fa2020-04-03 20:11:44 +01002174 object_get_canonical_path_component(OBJECT(cpu));
Alex Bennée308f9e82020-03-16 17:21:35 +00002175 g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
2176 cpu->halted ? "halted " : "running");
Jon Doron2704efa2019-05-29 09:41:45 +03002177 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002178 g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
Jon Doron2704efa2019-05-29 09:41:45 +03002179 cpu->halted ? "halted " : "running");
2180 }
Alex Bennée308f9e82020-03-16 17:21:35 +00002181 trace_gdbstub_op_extra_info(rs->str);
2182 memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
2183 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002184}
2185
2186#ifdef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002187static void handle_query_offsets(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002188{
2189 TaskState *ts;
2190
Alex Bennéea346af32020-03-16 17:21:34 +00002191 ts = gdbserver_state.c_cpu->opaque;
Alex Bennée308f9e82020-03-16 17:21:35 +00002192 g_string_printf(gdbserver_state.str_buf,
2193 "Text=" TARGET_ABI_FMT_lx
2194 ";Data=" TARGET_ABI_FMT_lx
2195 ";Bss=" TARGET_ABI_FMT_lx,
2196 ts->info->code_offset,
2197 ts->info->data_offset,
2198 ts->info->data_offset);
2199 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002200}
2201#else
Alex Bennée26a16182021-05-25 09:24:14 +01002202static void handle_query_rcmd(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002203{
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002204 const guint8 zero = 0;
Jon Doron2704efa2019-05-29 09:41:45 +03002205 int len;
2206
Alex Bennée26a16182021-05-25 09:24:14 +01002207 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002208 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002209 return;
2210 }
2211
Alex Bennée26a16182021-05-25 09:24:14 +01002212 len = strlen(get_param(params, 0)->data);
Jon Doron2704efa2019-05-29 09:41:45 +03002213 if (len % 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00002214 put_packet("E01");
Jon Doron2704efa2019-05-29 09:41:45 +03002215 return;
2216 }
2217
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002218 g_assert(gdbserver_state.mem_buf->len == 0);
Jon Doron2704efa2019-05-29 09:41:45 +03002219 len = len / 2;
Alex Bennée26a16182021-05-25 09:24:14 +01002220 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002221 g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
2222 qemu_chr_be_write(gdbserver_state.mon_chr, gdbserver_state.mem_buf->data,
2223 gdbserver_state.mem_buf->len);
Alex Bennéea346af32020-03-16 17:21:34 +00002224 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002225}
2226#endif
2227
Alex Bennée26a16182021-05-25 09:24:14 +01002228static void handle_query_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002229{
Andreas Färber5b24c642013-07-07 15:08:22 +02002230 CPUClass *cc;
Jon Doron2704efa2019-05-29 09:41:45 +03002231
Alex Bennée308f9e82020-03-16 17:21:35 +00002232 g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
Jon Doron2704efa2019-05-29 09:41:45 +03002233 cc = CPU_GET_CLASS(first_cpu);
2234 if (cc->gdb_core_xml_file) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002235 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
Jon Doron2704efa2019-05-29 09:41:45 +03002236 }
2237
Alex Bennéeed12f5b2021-05-20 18:43:02 +01002238 if (stub_can_reverse()) {
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03002239 g_string_append(gdbserver_state.str_buf,
2240 ";ReverseStep+;ReverseContinue+");
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002241 }
2242
Lirong Yuan51c623b2021-01-08 22:42:42 +00002243#ifdef CONFIG_USER_ONLY
2244 if (gdbserver_state.c_cpu->opaque) {
2245 g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
2246 }
2247#endif
2248
Alex Bennée26a16182021-05-25 09:24:14 +01002249 if (params->len &&
2250 strstr(get_param(params, 0)->data, "multiprocess+")) {
Alex Bennéea346af32020-03-16 17:21:34 +00002251 gdbserver_state.multiprocess = true;
Jon Doron2704efa2019-05-29 09:41:45 +03002252 }
2253
Changbin Du3bc26092020-03-16 17:21:55 +00002254 g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
Alex Bennée308f9e82020-03-16 17:21:35 +00002255 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002256}
2257
Alex Bennée26a16182021-05-25 09:24:14 +01002258static void handle_query_xfer_features(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002259{
2260 GDBProcess *process;
2261 CPUClass *cc;
2262 unsigned long len, total_len, addr;
2263 const char *xml;
bellardb4608c02003-06-27 17:34:32 +00002264 const char *p;
Jon Doron2704efa2019-05-29 09:41:45 +03002265
Alex Bennée26a16182021-05-25 09:24:14 +01002266 if (params->len < 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00002267 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002268 return;
2269 }
2270
Alex Bennéea346af32020-03-16 17:21:34 +00002271 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2272 cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002273 if (!cc->gdb_core_xml_file) {
Alex Bennéea346af32020-03-16 17:21:34 +00002274 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002275 return;
2276 }
2277
2278 gdb_has_xml = true;
Alex Bennée26a16182021-05-25 09:24:14 +01002279 p = get_param(params, 0)->data;
Alex Bennéea346af32020-03-16 17:21:34 +00002280 xml = get_feature_xml(p, &p, process);
Jon Doron2704efa2019-05-29 09:41:45 +03002281 if (!xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00002282 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002283 return;
2284 }
2285
Alex Bennée26a16182021-05-25 09:24:14 +01002286 addr = get_param(params, 1)->val_ul;
2287 len = get_param(params, 2)->val_ul;
Jon Doron2704efa2019-05-29 09:41:45 +03002288 total_len = strlen(xml);
2289 if (addr > total_len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002290 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002291 return;
2292 }
2293
2294 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2295 len = (MAX_PACKET_LENGTH - 5) / 2;
2296 }
2297
2298 if (len < total_len - addr) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002299 g_string_assign(gdbserver_state.str_buf, "m");
2300 memtox(gdbserver_state.str_buf, xml + addr, len);
Jon Doron2704efa2019-05-29 09:41:45 +03002301 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002302 g_string_assign(gdbserver_state.str_buf, "l");
2303 memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
Jon Doron2704efa2019-05-29 09:41:45 +03002304 }
2305
Alex Bennée308f9e82020-03-16 17:21:35 +00002306 put_packet_binary(gdbserver_state.str_buf->str,
2307 gdbserver_state.str_buf->len, true);
Jon Doron2704efa2019-05-29 09:41:45 +03002308}
2309
Lirong Yuan51c623b2021-01-08 22:42:42 +00002310#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
Alex Bennée26a16182021-05-25 09:24:14 +01002311static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
Lirong Yuan51c623b2021-01-08 22:42:42 +00002312{
2313 TaskState *ts;
2314 unsigned long offset, len, saved_auxv, auxv_len;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002315
Alex Bennée26a16182021-05-25 09:24:14 +01002316 if (params->len < 2) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002317 put_packet("E22");
2318 return;
2319 }
2320
Alex Bennée26a16182021-05-25 09:24:14 +01002321 offset = get_param(params, 0)->val_ul;
2322 len = get_param(params, 1)->val_ul;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002323 ts = gdbserver_state.c_cpu->opaque;
2324 saved_auxv = ts->info->saved_auxv;
2325 auxv_len = ts->info->auxv_len;
Richard Henderson6e3dd752021-02-02 13:39:55 +00002326
2327 if (offset >= auxv_len) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002328 put_packet("E00");
2329 return;
2330 }
2331
2332 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2333 len = (MAX_PACKET_LENGTH - 5) / 2;
2334 }
2335
2336 if (len < auxv_len - offset) {
2337 g_string_assign(gdbserver_state.str_buf, "m");
Lirong Yuan51c623b2021-01-08 22:42:42 +00002338 } else {
2339 g_string_assign(gdbserver_state.str_buf, "l");
Richard Henderson6e3dd752021-02-02 13:39:55 +00002340 len = auxv_len - offset;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002341 }
2342
Richard Henderson6e3dd752021-02-02 13:39:55 +00002343 g_byte_array_set_size(gdbserver_state.mem_buf, len);
2344 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2345 gdbserver_state.mem_buf->data, len, false)) {
2346 put_packet("E14");
2347 return;
2348 }
2349
2350 memtox(gdbserver_state.str_buf,
2351 (const char *)gdbserver_state.mem_buf->data, len);
Lirong Yuan51c623b2021-01-08 22:42:42 +00002352 put_packet_binary(gdbserver_state.str_buf->str,
2353 gdbserver_state.str_buf->len, true);
2354}
2355#endif
2356
Alex Bennée26a16182021-05-25 09:24:14 +01002357static void handle_query_attached(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002358{
Alex Bennéea346af32020-03-16 17:21:34 +00002359 put_packet(GDB_ATTACHED);
Jon Doron2704efa2019-05-29 09:41:45 +03002360}
2361
Alex Bennée26a16182021-05-25 09:24:14 +01002362static void handle_query_qemu_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002363{
Alex Bennée308f9e82020-03-16 17:21:35 +00002364 g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
Jon Doronab4752e2019-05-29 09:41:48 +03002365#ifndef CONFIG_USER_ONLY
Alex Bennée308f9e82020-03-16 17:21:35 +00002366 g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
Jon Doronab4752e2019-05-29 09:41:48 +03002367#endif
Alex Bennée308f9e82020-03-16 17:21:35 +00002368 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002369}
2370
Jon Doronab4752e2019-05-29 09:41:48 +03002371#ifndef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002372static void handle_query_qemu_phy_mem_mode(GArray *params,
Jon Doronab4752e2019-05-29 09:41:48 +03002373 void *user_ctx)
2374{
Alex Bennée308f9e82020-03-16 17:21:35 +00002375 g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
2376 put_strbuf();
Jon Doronab4752e2019-05-29 09:41:48 +03002377}
2378
Alex Bennée26a16182021-05-25 09:24:14 +01002379static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
Jon Doronab4752e2019-05-29 09:41:48 +03002380{
Alex Bennée26a16182021-05-25 09:24:14 +01002381 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002382 put_packet("E22");
Jon Doronab4752e2019-05-29 09:41:48 +03002383 return;
2384 }
2385
Alex Bennée26a16182021-05-25 09:24:14 +01002386 if (!get_param(params, 0)->val_ul) {
Jon Doronab4752e2019-05-29 09:41:48 +03002387 phy_memory_mode = 0;
2388 } else {
2389 phy_memory_mode = 1;
2390 }
Alex Bennéea346af32020-03-16 17:21:34 +00002391 put_packet("OK");
Jon Doronab4752e2019-05-29 09:41:48 +03002392}
2393#endif
2394
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002395static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002396 /* Order is important if has same prefix */
2397 {
2398 .handler = handle_query_qemu_sstepbits,
2399 .cmd = "qemu.sstepbits",
2400 },
2401 {
2402 .handler = handle_query_qemu_sstep,
2403 .cmd = "qemu.sstep",
2404 },
2405 {
2406 .handler = handle_set_qemu_sstep,
2407 .cmd = "qemu.sstep=",
2408 .cmd_startswith = 1,
2409 .schema = "l0"
2410 },
2411};
2412
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002413static const GdbCmdParseEntry gdb_gen_query_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002414 {
2415 .handler = handle_query_curr_tid,
2416 .cmd = "C",
2417 },
2418 {
2419 .handler = handle_query_threads,
2420 .cmd = "sThreadInfo",
2421 },
2422 {
2423 .handler = handle_query_first_threads,
2424 .cmd = "fThreadInfo",
2425 },
2426 {
2427 .handler = handle_query_thread_extra,
2428 .cmd = "ThreadExtraInfo,",
2429 .cmd_startswith = 1,
2430 .schema = "t0"
2431 },
2432#ifdef CONFIG_USER_ONLY
2433 {
2434 .handler = handle_query_offsets,
2435 .cmd = "Offsets",
2436 },
2437#else
2438 {
2439 .handler = handle_query_rcmd,
2440 .cmd = "Rcmd,",
2441 .cmd_startswith = 1,
2442 .schema = "s0"
2443 },
2444#endif
2445 {
2446 .handler = handle_query_supported,
2447 .cmd = "Supported:",
2448 .cmd_startswith = 1,
2449 .schema = "s0"
2450 },
2451 {
2452 .handler = handle_query_supported,
2453 .cmd = "Supported",
2454 .schema = "s0"
2455 },
2456 {
2457 .handler = handle_query_xfer_features,
2458 .cmd = "Xfer:features:read:",
2459 .cmd_startswith = 1,
2460 .schema = "s:l,l0"
2461 },
Lirong Yuan51c623b2021-01-08 22:42:42 +00002462#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2463 {
2464 .handler = handle_query_xfer_auxv,
2465 .cmd = "Xfer:auxv:read::",
2466 .cmd_startswith = 1,
2467 .schema = "l,l0"
2468 },
2469#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002470 {
2471 .handler = handle_query_attached,
2472 .cmd = "Attached:",
2473 .cmd_startswith = 1
2474 },
2475 {
2476 .handler = handle_query_attached,
2477 .cmd = "Attached",
2478 },
2479 {
2480 .handler = handle_query_qemu_supported,
2481 .cmd = "qemu.Supported",
2482 },
Jon Doronab4752e2019-05-29 09:41:48 +03002483#ifndef CONFIG_USER_ONLY
2484 {
2485 .handler = handle_query_qemu_phy_mem_mode,
2486 .cmd = "qemu.PhyMemMode",
2487 },
2488#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002489};
2490
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002491static const GdbCmdParseEntry gdb_gen_set_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002492 /* Order is important if has same prefix */
2493 {
2494 .handler = handle_set_qemu_sstep,
2495 .cmd = "qemu.sstep:",
2496 .cmd_startswith = 1,
2497 .schema = "l0"
2498 },
Jon Doronab4752e2019-05-29 09:41:48 +03002499#ifndef CONFIG_USER_ONLY
2500 {
2501 .handler = handle_set_qemu_phy_mem_mode,
2502 .cmd = "qemu.PhyMemMode:",
2503 .cmd_startswith = 1,
2504 .schema = "l0"
2505 },
2506#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002507};
2508
Alex Bennée26a16182021-05-25 09:24:14 +01002509static void handle_gen_query(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002510{
Alex Bennée26a16182021-05-25 09:24:14 +01002511 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002512 return;
2513 }
2514
Alex Bennée26a16182021-05-25 09:24:14 +01002515 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002516 gdb_gen_query_set_common_table,
2517 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2518 return;
2519 }
2520
Alex Bennée26a16182021-05-25 09:24:14 +01002521 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002522 gdb_gen_query_table,
2523 ARRAY_SIZE(gdb_gen_query_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002524 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002525 }
2526}
2527
Alex Bennée26a16182021-05-25 09:24:14 +01002528static void handle_gen_set(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002529{
Alex Bennée26a16182021-05-25 09:24:14 +01002530 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002531 return;
2532 }
2533
Alex Bennée26a16182021-05-25 09:24:14 +01002534 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002535 gdb_gen_query_set_common_table,
2536 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2537 return;
2538 }
2539
Alex Bennée26a16182021-05-25 09:24:14 +01002540 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002541 gdb_gen_set_table,
2542 ARRAY_SIZE(gdb_gen_set_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002543 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002544 }
2545}
2546
Alex Bennée26a16182021-05-25 09:24:14 +01002547static void handle_target_halt(GArray *params, void *user_ctx)
Jon Doron7009d572019-05-29 09:41:46 +03002548{
Alex Bennée308f9e82020-03-16 17:21:35 +00002549 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2550 gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2551 g_string_append_c(gdbserver_state.str_buf, ';');
2552 put_strbuf();
Jon Doron7009d572019-05-29 09:41:46 +03002553 /*
2554 * Remove all the breakpoints when this query is issued,
2555 * because gdb is doing an initial connect and the state
2556 * should be cleaned up.
2557 */
2558 gdb_breakpoint_remove_all();
2559}
2560
Alex Bennéea346af32020-03-16 17:21:34 +00002561static int gdb_handle_packet(const char *line_buf)
Jon Doron2704efa2019-05-29 09:41:45 +03002562{
Jon Doron3e2c1262019-05-29 09:41:30 +03002563 const GdbCmdParseEntry *cmd_parser = NULL;
ths3b46e622007-09-17 08:09:54 +00002564
Doug Gale5c9522b2017-12-02 20:30:37 -05002565 trace_gdbstub_io_command(line_buf);
Alex Bennée118e2262017-07-12 11:52:13 +01002566
Jon Doron3f1cbac2019-05-29 09:41:47 +03002567 switch (line_buf[0]) {
Luc Michel53fd6552019-01-07 15:23:46 +00002568 case '!':
Alex Bennéea346af32020-03-16 17:21:34 +00002569 put_packet("OK");
Luc Michel53fd6552019-01-07 15:23:46 +00002570 break;
bellard858693c2004-03-31 18:52:07 +00002571 case '?':
Jon Doron7009d572019-05-29 09:41:46 +03002572 {
2573 static const GdbCmdParseEntry target_halted_cmd_desc = {
2574 .handler = handle_target_halt,
2575 .cmd = "?",
2576 .cmd_startswith = 1
2577 };
2578 cmd_parser = &target_halted_cmd_desc;
2579 }
bellard858693c2004-03-31 18:52:07 +00002580 break;
2581 case 'c':
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002582 {
2583 static const GdbCmdParseEntry continue_cmd_desc = {
2584 .handler = handle_continue,
2585 .cmd = "c",
2586 .cmd_startswith = 1,
2587 .schema = "L0"
2588 };
2589 cmd_parser = &continue_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002590 }
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002591 break;
edgar_igl1f487ee2008-05-17 22:20:53 +00002592 case 'C':
Jon Doronccc47d52019-05-29 09:41:33 +03002593 {
2594 static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2595 .handler = handle_cont_with_sig,
2596 .cmd = "C",
2597 .cmd_startswith = 1,
2598 .schema = "l0"
2599 };
2600 cmd_parser = &cont_with_sig_cmd_desc;
2601 }
2602 break;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002603 case 'v':
Jon Doron8536ec02019-05-29 09:41:44 +03002604 {
2605 static const GdbCmdParseEntry v_cmd_desc = {
2606 .handler = handle_v_commands,
2607 .cmd = "v",
2608 .cmd_startswith = 1,
2609 .schema = "s0"
2610 };
2611 cmd_parser = &v_cmd_desc;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002612 }
Jon Doron8536ec02019-05-29 09:41:44 +03002613 break;
edgar_igl7d03f822008-05-17 18:58:29 +00002614 case 'k':
2615 /* Kill the target */
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002616 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00002617 gdb_exit(0);
edgar_igl7d03f822008-05-17 18:58:29 +00002618 exit(0);
2619 case 'D':
Jon Doron3e2c1262019-05-29 09:41:30 +03002620 {
2621 static const GdbCmdParseEntry detach_cmd_desc = {
2622 .handler = handle_detach,
2623 .cmd = "D",
2624 .cmd_startswith = 1,
2625 .schema = "?.l0"
2626 };
2627 cmd_parser = &detach_cmd_desc;
Luc Michel546f3c62019-01-07 15:23:46 +00002628 }
edgar_igl7d03f822008-05-17 18:58:29 +00002629 break;
bellard858693c2004-03-31 18:52:07 +00002630 case 's':
Jon Doron933f80d2019-05-29 09:41:43 +03002631 {
2632 static const GdbCmdParseEntry step_cmd_desc = {
2633 .handler = handle_step,
2634 .cmd = "s",
2635 .cmd_startswith = 1,
2636 .schema = "L0"
2637 };
2638 cmd_parser = &step_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002639 }
Jon Doron933f80d2019-05-29 09:41:43 +03002640 break;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002641 case 'b':
2642 {
2643 static const GdbCmdParseEntry backward_cmd_desc = {
2644 .handler = handle_backward,
2645 .cmd = "b",
2646 .cmd_startswith = 1,
2647 .schema = "o0"
2648 };
2649 cmd_parser = &backward_cmd_desc;
2650 }
2651 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002652 case 'F':
2653 {
Jon Doron4b20fab2019-05-29 09:41:42 +03002654 static const GdbCmdParseEntry file_io_cmd_desc = {
2655 .handler = handle_file_io,
2656 .cmd = "F",
2657 .cmd_startswith = 1,
2658 .schema = "L,L,o0"
2659 };
2660 cmd_parser = &file_io_cmd_desc;
pbrooka2d1eba2007-01-28 03:10:55 +00002661 }
2662 break;
bellard858693c2004-03-31 18:52:07 +00002663 case 'g':
Jon Doron397d1372019-05-29 09:41:41 +03002664 {
2665 static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2666 .handler = handle_read_all_regs,
2667 .cmd = "g",
2668 .cmd_startswith = 1
2669 };
2670 cmd_parser = &read_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002671 }
bellard858693c2004-03-31 18:52:07 +00002672 break;
2673 case 'G':
Jon Doron287ca122019-05-29 09:41:40 +03002674 {
2675 static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2676 .handler = handle_write_all_regs,
2677 .cmd = "G",
2678 .cmd_startswith = 1,
2679 .schema = "s0"
2680 };
2681 cmd_parser = &write_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002682 }
bellard858693c2004-03-31 18:52:07 +00002683 break;
2684 case 'm':
Jon Doronda92e232019-05-29 09:41:39 +03002685 {
2686 static const GdbCmdParseEntry read_mem_cmd_desc = {
2687 .handler = handle_read_mem,
2688 .cmd = "m",
2689 .cmd_startswith = 1,
2690 .schema = "L,L0"
2691 };
2692 cmd_parser = &read_mem_cmd_desc;
bellard6f970bd2005-12-05 19:55:19 +00002693 }
bellard858693c2004-03-31 18:52:07 +00002694 break;
2695 case 'M':
Jon Doroncc0ecc72019-05-29 09:41:38 +03002696 {
2697 static const GdbCmdParseEntry write_mem_cmd_desc = {
2698 .handler = handle_write_mem,
2699 .cmd = "M",
2700 .cmd_startswith = 1,
2701 .schema = "L,L:s0"
2702 };
2703 cmd_parser = &write_mem_cmd_desc;
Fabien Chouteau44520db2011-09-08 12:48:16 +02002704 }
bellard858693c2004-03-31 18:52:07 +00002705 break;
pbrook56aebc82008-10-11 17:55:29 +00002706 case 'p':
Jon Doron5d0e57b2019-05-29 09:41:37 +03002707 {
2708 static const GdbCmdParseEntry get_reg_cmd_desc = {
2709 .handler = handle_get_reg,
2710 .cmd = "p",
2711 .cmd_startswith = 1,
2712 .schema = "L0"
2713 };
2714 cmd_parser = &get_reg_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002715 }
2716 break;
2717 case 'P':
Jon Doron62b33202019-05-29 09:41:36 +03002718 {
2719 static const GdbCmdParseEntry set_reg_cmd_desc = {
2720 .handler = handle_set_reg,
2721 .cmd = "P",
2722 .cmd_startswith = 1,
2723 .schema = "L?s0"
2724 };
2725 cmd_parser = &set_reg_cmd_desc;
2726 }
pbrook56aebc82008-10-11 17:55:29 +00002727 break;
bellard858693c2004-03-31 18:52:07 +00002728 case 'Z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002729 {
2730 static const GdbCmdParseEntry insert_bp_cmd_desc = {
2731 .handler = handle_insert_bp,
2732 .cmd = "Z",
2733 .cmd_startswith = 1,
2734 .schema = "l?L?L0"
2735 };
2736 cmd_parser = &insert_bp_cmd_desc;
2737 }
2738 break;
bellard858693c2004-03-31 18:52:07 +00002739 case 'z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002740 {
2741 static const GdbCmdParseEntry remove_bp_cmd_desc = {
2742 .handler = handle_remove_bp,
2743 .cmd = "z",
2744 .cmd_startswith = 1,
2745 .schema = "l?L?L0"
2746 };
2747 cmd_parser = &remove_bp_cmd_desc;
2748 }
bellard858693c2004-03-31 18:52:07 +00002749 break;
aliguori880a7572008-11-18 20:30:24 +00002750 case 'H':
Jon Doron3a9651d2019-05-29 09:41:34 +03002751 {
2752 static const GdbCmdParseEntry set_thread_cmd_desc = {
2753 .handler = handle_set_thread,
2754 .cmd = "H",
2755 .cmd_startswith = 1,
2756 .schema = "o.t0"
2757 };
2758 cmd_parser = &set_thread_cmd_desc;
aliguori880a7572008-11-18 20:30:24 +00002759 }
2760 break;
2761 case 'T':
Jon Doron44ffded2019-05-29 09:41:31 +03002762 {
2763 static const GdbCmdParseEntry thread_alive_cmd_desc = {
2764 .handler = handle_thread_alive,
2765 .cmd = "T",
2766 .cmd_startswith = 1,
2767 .schema = "t0"
2768 };
2769 cmd_parser = &thread_alive_cmd_desc;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002770 }
aliguori880a7572008-11-18 20:30:24 +00002771 break;
pbrook978efd62006-06-17 18:30:42 +00002772 case 'q':
Jon Doron2704efa2019-05-29 09:41:45 +03002773 {
2774 static const GdbCmdParseEntry gen_query_cmd_desc = {
2775 .handler = handle_gen_query,
2776 .cmd = "q",
2777 .cmd_startswith = 1,
2778 .schema = "s0"
2779 };
2780 cmd_parser = &gen_query_cmd_desc;
2781 }
2782 break;
edgar_igl60897d32008-05-09 08:25:14 +00002783 case 'Q':
Jon Doron2704efa2019-05-29 09:41:45 +03002784 {
2785 static const GdbCmdParseEntry gen_set_cmd_desc = {
2786 .handler = handle_gen_set,
2787 .cmd = "Q",
2788 .cmd_startswith = 1,
2789 .schema = "s0"
2790 };
2791 cmd_parser = &gen_set_cmd_desc;
edgar_igl60897d32008-05-09 08:25:14 +00002792 }
Jon Doron2704efa2019-05-29 09:41:45 +03002793 break;
bellard858693c2004-03-31 18:52:07 +00002794 default:
bellard858693c2004-03-31 18:52:07 +00002795 /* put empty packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002796 put_packet("");
bellard858693c2004-03-31 18:52:07 +00002797 break;
2798 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002799
Ramiro Polla2bdec392019-08-05 21:09:01 +02002800 if (cmd_parser) {
Alex Bennéea346af32020-03-16 17:21:34 +00002801 run_cmd_parser(line_buf, cmd_parser);
Ramiro Polla2bdec392019-08-05 21:09:01 +02002802 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002803
bellard858693c2004-03-31 18:52:07 +00002804 return RS_IDLE;
2805}
2806
Andreas Färber64f6b342013-05-27 02:06:09 +02002807void gdb_set_stop_cpu(CPUState *cpu)
aliguori880a7572008-11-18 20:30:24 +00002808{
Alex Bennéea346af32020-03-16 17:21:34 +00002809 GDBProcess *p = gdb_get_cpu_process(cpu);
Luc Michel160d8582019-01-07 15:23:46 +00002810
2811 if (!p->attached) {
2812 /*
2813 * Having a stop CPU corresponding to a process that is not attached
2814 * confuses GDB. So we ignore the request.
2815 */
2816 return;
2817 }
2818
Alex Bennée8d98c442020-03-16 17:21:33 +00002819 gdbserver_state.c_cpu = cpu;
2820 gdbserver_state.g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002821}
2822
bellard1fddef42005-04-17 19:16:13 +00002823#ifndef CONFIG_USER_ONLY
Philippe Mathieu-Daudé538f0492021-01-11 16:20:20 +01002824static void gdb_vm_state_change(void *opaque, bool running, RunState state)
bellard858693c2004-03-31 18:52:07 +00002825{
Alex Bennéea346af32020-03-16 17:21:34 +00002826 CPUState *cpu = gdbserver_state.c_cpu;
Alex Bennée308f9e82020-03-16 17:21:35 +00002827 g_autoptr(GString) buf = g_string_new(NULL);
2828 g_autoptr(GString) tid = g_string_new(NULL);
aliguorid6fc1b32008-11-18 19:55:44 +00002829 const char *type;
bellard858693c2004-03-31 18:52:07 +00002830 int ret;
2831
Alex Bennéea346af32020-03-16 17:21:34 +00002832 if (running || gdbserver_state.state == RS_INACTIVE) {
Meador Ingecdb432b2012-03-15 17:49:45 +00002833 return;
2834 }
2835 /* Is there a GDB syscall waiting to be sent? */
Alex Bennéea346af32020-03-16 17:21:34 +00002836 if (gdbserver_state.current_syscall_cb) {
2837 put_packet(gdbserver_state.syscall_buf);
pbrooka2d1eba2007-01-28 03:10:55 +00002838 return;
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002839 }
Luc Michel95567c22019-01-07 15:23:46 +00002840
2841 if (cpu == NULL) {
2842 /* No process attached */
2843 return;
2844 }
2845
Alex Bennée308f9e82020-03-16 17:21:35 +00002846 gdb_append_thread_id(cpu, tid);
Luc Michel95567c22019-01-07 15:23:46 +00002847
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002848 switch (state) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002849 case RUN_STATE_DEBUG:
Andreas Färberff4700b2013-08-26 18:23:18 +02002850 if (cpu->watchpoint_hit) {
2851 switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
aliguoria1d1bb32008-11-18 20:07:32 +00002852 case BP_MEM_READ:
aliguorid6fc1b32008-11-18 19:55:44 +00002853 type = "r";
2854 break;
aliguoria1d1bb32008-11-18 20:07:32 +00002855 case BP_MEM_ACCESS:
aliguorid6fc1b32008-11-18 19:55:44 +00002856 type = "a";
2857 break;
2858 default:
2859 type = "";
2860 break;
2861 }
Doug Gale5c9522b2017-12-02 20:30:37 -05002862 trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
2863 (target_ulong)cpu->watchpoint_hit->vaddr);
Alex Bennée308f9e82020-03-16 17:21:35 +00002864 g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
2865 GDB_SIGNAL_TRAP, tid->str, type,
2866 (target_ulong)cpu->watchpoint_hit->vaddr);
Andreas Färberff4700b2013-08-26 18:23:18 +02002867 cpu->watchpoint_hit = NULL;
Jan Kiszka425189a2011-03-22 11:02:09 +01002868 goto send_packet;
Doug Gale5c9522b2017-12-02 20:30:37 -05002869 } else {
2870 trace_gdbstub_hit_break();
pbrook6658ffb2007-03-16 23:58:11 +00002871 }
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07002872 tb_flush(cpu);
aurel32ca587a82008-12-18 22:44:13 +00002873 ret = GDB_SIGNAL_TRAP;
Jan Kiszka425189a2011-03-22 11:02:09 +01002874 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002875 case RUN_STATE_PAUSED:
Doug Gale5c9522b2017-12-02 20:30:37 -05002876 trace_gdbstub_hit_paused();
aliguori9781e042009-01-22 17:15:29 +00002877 ret = GDB_SIGNAL_INT;
Jan Kiszka425189a2011-03-22 11:02:09 +01002878 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002879 case RUN_STATE_SHUTDOWN:
Doug Gale5c9522b2017-12-02 20:30:37 -05002880 trace_gdbstub_hit_shutdown();
Jan Kiszka425189a2011-03-22 11:02:09 +01002881 ret = GDB_SIGNAL_QUIT;
2882 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002883 case RUN_STATE_IO_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002884 trace_gdbstub_hit_io_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002885 ret = GDB_SIGNAL_IO;
2886 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002887 case RUN_STATE_WATCHDOG:
Doug Gale5c9522b2017-12-02 20:30:37 -05002888 trace_gdbstub_hit_watchdog();
Jan Kiszka425189a2011-03-22 11:02:09 +01002889 ret = GDB_SIGNAL_ALRM;
2890 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002891 case RUN_STATE_INTERNAL_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002892 trace_gdbstub_hit_internal_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002893 ret = GDB_SIGNAL_ABRT;
2894 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002895 case RUN_STATE_SAVE_VM:
2896 case RUN_STATE_RESTORE_VM:
Jan Kiszka425189a2011-03-22 11:02:09 +01002897 return;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002898 case RUN_STATE_FINISH_MIGRATE:
Jan Kiszka425189a2011-03-22 11:02:09 +01002899 ret = GDB_SIGNAL_XCPU;
2900 break;
2901 default:
Doug Gale5c9522b2017-12-02 20:30:37 -05002902 trace_gdbstub_hit_unknown(state);
Jan Kiszka425189a2011-03-22 11:02:09 +01002903 ret = GDB_SIGNAL_UNKNOWN;
2904 break;
bellardbbeb7b52006-04-23 18:42:15 +00002905 }
Jan Kiszka226d0072015-07-24 18:52:31 +02002906 gdb_set_stop_cpu(cpu);
Alex Bennée308f9e82020-03-16 17:21:35 +00002907 g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002908
2909send_packet:
Alex Bennée308f9e82020-03-16 17:21:35 +00002910 put_packet(buf->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002911
2912 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002913 cpu_single_step(cpu, 0);
bellard858693c2004-03-31 18:52:07 +00002914}
bellard1fddef42005-04-17 19:16:13 +00002915#endif
bellard858693c2004-03-31 18:52:07 +00002916
pbrooka2d1eba2007-01-28 03:10:55 +00002917/* Send a gdb syscall request.
2918 This accepts limited printf-style format specifiers, specifically:
pbrooka87295e2007-05-26 15:09:38 +00002919 %x - target_ulong argument printed in hex.
2920 %lx - 64-bit argument printed in hex.
2921 %s - string pointer (target_ulong) and length (int) pair. */
Peter Maydell19239b32015-09-07 10:39:27 +01002922void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
pbrooka2d1eba2007-01-28 03:10:55 +00002923{
pbrooka2d1eba2007-01-28 03:10:55 +00002924 char *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00002925 char *p_end;
pbrooka2d1eba2007-01-28 03:10:55 +00002926 target_ulong addr;
pbrooka87295e2007-05-26 15:09:38 +00002927 uint64_t i64;
pbrooka2d1eba2007-01-28 03:10:55 +00002928
Peter Maydellebf1b4c2022-06-10 14:32:36 +01002929 if (!gdb_attached()) {
pbrooka2d1eba2007-01-28 03:10:55 +00002930 return;
Alex Bennéea346af32020-03-16 17:21:34 +00002931 }
Alex Bennée8d98c442020-03-16 17:21:33 +00002932
2933 gdbserver_state.current_syscall_cb = cb;
pbrooka2d1eba2007-01-28 03:10:55 +00002934#ifndef CONFIG_USER_ONLY
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002935 vm_stop(RUN_STATE_DEBUG);
pbrooka2d1eba2007-01-28 03:10:55 +00002936#endif
Alex Bennée8d98c442020-03-16 17:21:33 +00002937 p = &gdbserver_state.syscall_buf[0];
2938 p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
pbrooka2d1eba2007-01-28 03:10:55 +00002939 *(p++) = 'F';
2940 while (*fmt) {
2941 if (*fmt == '%') {
2942 fmt++;
2943 switch (*fmt++) {
2944 case 'x':
2945 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002946 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
pbrooka2d1eba2007-01-28 03:10:55 +00002947 break;
pbrooka87295e2007-05-26 15:09:38 +00002948 case 'l':
2949 if (*(fmt++) != 'x')
2950 goto bad_format;
2951 i64 = va_arg(va, uint64_t);
Meador Ingecdb432b2012-03-15 17:49:45 +00002952 p += snprintf(p, p_end - p, "%" PRIx64, i64);
pbrooka87295e2007-05-26 15:09:38 +00002953 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002954 case 's':
2955 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002956 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
blueswir1363a37d2008-08-21 17:58:08 +00002957 addr, va_arg(va, int));
pbrooka2d1eba2007-01-28 03:10:55 +00002958 break;
2959 default:
pbrooka87295e2007-05-26 15:09:38 +00002960 bad_format:
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002961 error_report("gdbstub: Bad syscall format string '%s'",
2962 fmt - 1);
pbrooka2d1eba2007-01-28 03:10:55 +00002963 break;
2964 }
2965 } else {
2966 *(p++) = *(fmt++);
2967 }
2968 }
pbrook8a93e022007-08-06 13:19:15 +00002969 *p = 0;
pbrooka2d1eba2007-01-28 03:10:55 +00002970#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +00002971 put_packet(gdbserver_state.syscall_buf);
Peter Maydell4f710862018-05-15 19:19:58 +01002972 /* Return control to gdb for it to process the syscall request.
2973 * Since the protocol requires that gdb hands control back to us
2974 * using a "here are the results" F packet, we don't need to check
2975 * gdb_handlesig's return value (which is the signal to deliver if
2976 * execution was resumed via a continue packet).
2977 */
Alex Bennée8d98c442020-03-16 17:21:33 +00002978 gdb_handlesig(gdbserver_state.c_cpu, 0);
pbrooka2d1eba2007-01-28 03:10:55 +00002979#else
Meador Ingecdb432b2012-03-15 17:49:45 +00002980 /* In this case wait to send the syscall packet until notification that
2981 the CPU has stopped. This must be done because if the packet is sent
2982 now the reply from the syscall request could be received while the CPU
2983 is still in the running state, which can cause packets to be dropped
2984 and state transition 'T' packets to be sent while the syscall is still
2985 being processed. */
Alex Bennée8d98c442020-03-16 17:21:33 +00002986 qemu_cpu_kick(gdbserver_state.c_cpu);
pbrooka2d1eba2007-01-28 03:10:55 +00002987#endif
2988}
2989
Peter Maydell19239b32015-09-07 10:39:27 +01002990void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2991{
2992 va_list va;
2993
2994 va_start(va, fmt);
2995 gdb_do_syscallv(cb, fmt, va);
2996 va_end(va);
2997}
2998
Alex Bennéea346af32020-03-16 17:21:34 +00002999static void gdb_read_byte(uint8_t ch)
bellard858693c2004-03-31 18:52:07 +00003000{
ths60fe76f2007-12-16 03:02:09 +00003001 uint8_t reply;
bellard858693c2004-03-31 18:52:07 +00003002
bellard1fddef42005-04-17 19:16:13 +00003003#ifndef CONFIG_USER_ONLY
Damien Hedded116e812020-03-16 17:21:53 +00003004 if (gdbserver_state.last_packet->len) {
pbrook4046d912007-01-28 01:53:16 +00003005 /* Waiting for a response to the last packet. If we see the start
3006 of a new command then abandon the previous response. */
3007 if (ch == '-') {
Doug Gale5c9522b2017-12-02 20:30:37 -05003008 trace_gdbstub_err_got_nack();
Damien Hedded116e812020-03-16 17:21:53 +00003009 put_buffer(gdbserver_state.last_packet->data,
3010 gdbserver_state.last_packet->len);
Alex Bennée118e2262017-07-12 11:52:13 +01003011 } else if (ch == '+') {
Doug Gale5c9522b2017-12-02 20:30:37 -05003012 trace_gdbstub_io_got_ack();
Alex Bennée118e2262017-07-12 11:52:13 +01003013 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003014 trace_gdbstub_io_got_unexpected(ch);
pbrook4046d912007-01-28 01:53:16 +00003015 }
Alex Bennée118e2262017-07-12 11:52:13 +01003016
Damien Hedded116e812020-03-16 17:21:53 +00003017 if (ch == '+' || ch == '$') {
3018 g_byte_array_set_size(gdbserver_state.last_packet, 0);
3019 }
pbrook4046d912007-01-28 01:53:16 +00003020 if (ch != '$')
3021 return;
3022 }
Luiz Capitulino13548692011-07-29 15:36:43 -03003023 if (runstate_is_running()) {
bellard858693c2004-03-31 18:52:07 +00003024 /* when the CPU is running, we cannot do anything except stop
3025 it when receiving a char */
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003026 vm_stop(RUN_STATE_PAUSED);
ths5fafdf22007-09-16 21:08:06 +00003027 } else
bellard1fddef42005-04-17 19:16:13 +00003028#endif
bellard41625032005-04-24 10:07:11 +00003029 {
Alex Bennéea346af32020-03-16 17:21:34 +00003030 switch(gdbserver_state.state) {
bellard858693c2004-03-31 18:52:07 +00003031 case RS_IDLE:
3032 if (ch == '$') {
Doug Gale4bf43122017-05-01 12:22:10 -04003033 /* start of command packet */
Alex Bennéea346af32020-03-16 17:21:34 +00003034 gdbserver_state.line_buf_index = 0;
3035 gdbserver_state.line_sum = 0;
3036 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003037 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003038 trace_gdbstub_err_garbage(ch);
bellard4c3a88a2003-07-26 12:06:08 +00003039 }
3040 break;
bellard858693c2004-03-31 18:52:07 +00003041 case RS_GETLINE:
Doug Gale4bf43122017-05-01 12:22:10 -04003042 if (ch == '}') {
3043 /* start escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003044 gdbserver_state.state = RS_GETLINE_ESC;
3045 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003046 } else if (ch == '*') {
3047 /* start run length encoding sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003048 gdbserver_state.state = RS_GETLINE_RLE;
3049 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003050 } else if (ch == '#') {
3051 /* end of command, start of checksum*/
Alex Bennéea346af32020-03-16 17:21:34 +00003052 gdbserver_state.state = RS_CHKSUM1;
3053 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale5c9522b2017-12-02 20:30:37 -05003054 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003055 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003056 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003057 /* unescaped command character */
Alex Bennéea346af32020-03-16 17:21:34 +00003058 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
3059 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003060 }
3061 break;
3062 case RS_GETLINE_ESC:
3063 if (ch == '#') {
3064 /* unexpected end of command in escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003065 gdbserver_state.state = RS_CHKSUM1;
3066 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003067 /* command buffer overrun */
Doug Gale5c9522b2017-12-02 20:30:37 -05003068 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003069 gdbserver_state.state = RS_IDLE;
Doug Gale4bf43122017-05-01 12:22:10 -04003070 } else {
3071 /* parse escaped character and leave escape state */
Alex Bennéea346af32020-03-16 17:21:34 +00003072 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
3073 gdbserver_state.line_sum += ch;
3074 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003075 }
3076 break;
3077 case RS_GETLINE_RLE:
Markus Armbruster046aba12019-05-14 20:03:08 +02003078 /*
3079 * Run-length encoding is explained in "Debugging with GDB /
3080 * Appendix E GDB Remote Serial Protocol / Overview".
3081 */
3082 if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
Doug Gale4bf43122017-05-01 12:22:10 -04003083 /* invalid RLE count encoding */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003084 trace_gdbstub_err_invalid_repeat(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003085 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003086 } else {
3087 /* decode repeat length */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003088 int repeat = ch - ' ' + 3;
Alex Bennéea346af32020-03-16 17:21:34 +00003089 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003090 /* that many repeats would overrun the command buffer */
Doug Gale5c9522b2017-12-02 20:30:37 -05003091 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003092 gdbserver_state.state = RS_IDLE;
3093 } else if (gdbserver_state.line_buf_index < 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003094 /* got a repeat but we have nothing to repeat */
Doug Gale5c9522b2017-12-02 20:30:37 -05003095 trace_gdbstub_err_invalid_rle();
Alex Bennéea346af32020-03-16 17:21:34 +00003096 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003097 } else {
3098 /* repeat the last character */
Alex Bennéea346af32020-03-16 17:21:34 +00003099 memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
3100 gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
3101 gdbserver_state.line_buf_index += repeat;
3102 gdbserver_state.line_sum += ch;
3103 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003104 }
bellard858693c2004-03-31 18:52:07 +00003105 }
3106 break;
3107 case RS_CHKSUM1:
Doug Gale4bf43122017-05-01 12:22:10 -04003108 /* get high hex digit of checksum */
3109 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003110 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003111 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003112 break;
3113 }
Alex Bennéea346af32020-03-16 17:21:34 +00003114 gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
3115 gdbserver_state.line_csum = fromhex(ch) << 4;
3116 gdbserver_state.state = RS_CHKSUM2;
bellard858693c2004-03-31 18:52:07 +00003117 break;
3118 case RS_CHKSUM2:
Doug Gale4bf43122017-05-01 12:22:10 -04003119 /* get low hex digit of checksum */
3120 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003121 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003122 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003123 break;
bellard858693c2004-03-31 18:52:07 +00003124 }
Alex Bennéea346af32020-03-16 17:21:34 +00003125 gdbserver_state.line_csum |= fromhex(ch);
Doug Gale4bf43122017-05-01 12:22:10 -04003126
Alex Bennéea346af32020-03-16 17:21:34 +00003127 if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
3128 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
Doug Gale4bf43122017-05-01 12:22:10 -04003129 /* send NAK reply */
ths60fe76f2007-12-16 03:02:09 +00003130 reply = '-';
Alex Bennéea346af32020-03-16 17:21:34 +00003131 put_buffer(&reply, 1);
3132 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003133 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003134 /* send ACK reply */
ths60fe76f2007-12-16 03:02:09 +00003135 reply = '+';
Alex Bennéea346af32020-03-16 17:21:34 +00003136 put_buffer(&reply, 1);
3137 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
bellard858693c2004-03-31 18:52:07 +00003138 }
bellardb4608c02003-06-27 17:34:32 +00003139 break;
pbrooka2d1eba2007-01-28 03:10:55 +00003140 default:
3141 abort();
bellardb4608c02003-06-27 17:34:32 +00003142 }
3143 }
bellard858693c2004-03-31 18:52:07 +00003144}
3145
Paul Brook0e1c9c52010-06-16 13:03:51 +01003146/* Tell the remote gdb that the process has exited. */
Alex Bennéead9dcb22021-01-08 22:42:43 +00003147void gdb_exit(int code)
Paul Brook0e1c9c52010-06-16 13:03:51 +01003148{
Paul Brook0e1c9c52010-06-16 13:03:51 +01003149 char buf[4];
3150
Alex Bennée8d98c442020-03-16 17:21:33 +00003151 if (!gdbserver_state.init) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003152 return;
3153 }
3154#ifdef CONFIG_USER_ONLY
Alex Bennéefcedd922020-04-30 20:01:19 +01003155 if (gdbserver_state.socket_path) {
3156 unlink(gdbserver_state.socket_path);
3157 }
Alex Bennéee0a1e202020-04-30 20:01:18 +01003158 if (gdbserver_state.fd < 0) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003159 return;
3160 }
3161#endif
3162
Doug Gale5c9522b2017-12-02 20:30:37 -05003163 trace_gdbstub_op_exiting((uint8_t)code);
3164
Paul Brook0e1c9c52010-06-16 13:03:51 +01003165 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
Alex Bennéea346af32020-03-16 17:21:34 +00003166 put_packet(buf);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003167
3168#ifndef CONFIG_USER_ONLY
Alex Bennée8d98c442020-03-16 17:21:33 +00003169 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003170#endif
Paul Brook0e1c9c52010-06-16 13:03:51 +01003171}
3172
Luc Michel8f468632019-01-07 15:23:45 +00003173/*
3174 * Create the process that will contain all the "orphan" CPUs (that are not
3175 * part of a CPU cluster). Note that if this process contains no CPUs, it won't
3176 * be attachable and thus will be invisible to the user.
3177 */
3178static void create_default_process(GDBState *s)
3179{
3180 GDBProcess *process;
3181 int max_pid = 0;
3182
Alex Bennéea346af32020-03-16 17:21:34 +00003183 if (gdbserver_state.process_num) {
Luc Michel8f468632019-01-07 15:23:45 +00003184 max_pid = s->processes[s->process_num - 1].pid;
3185 }
3186
3187 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3188 process = &s->processes[s->process_num - 1];
3189
3190 /* We need an available PID slot for this process */
3191 assert(max_pid < UINT32_MAX);
3192
3193 process->pid = max_pid + 1;
3194 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003195 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003196}
3197
bellard1fddef42005-04-17 19:16:13 +00003198#ifdef CONFIG_USER_ONLY
3199int
Andreas Färberdb6b81d2013-06-27 19:49:31 +02003200gdb_handlesig(CPUState *cpu, int sig)
bellard1fddef42005-04-17 19:16:13 +00003201{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003202 char buf[256];
3203 int n;
bellard1fddef42005-04-17 19:16:13 +00003204
Alex Bennéee0a1e202020-04-30 20:01:18 +01003205 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003206 return sig;
bellard1fddef42005-04-17 19:16:13 +00003207 }
3208
Andreas Färber5ca666c2013-06-24 19:20:57 +02003209 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02003210 cpu_single_step(cpu, 0);
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07003211 tb_flush(cpu);
bellard1fddef42005-04-17 19:16:13 +00003212
Andreas Färber5ca666c2013-06-24 19:20:57 +02003213 if (sig != 0) {
Pavel Labath4a82be72021-10-26 11:22:34 +01003214 gdb_set_stop_cpu(cpu);
3215 g_string_printf(gdbserver_state.str_buf,
3216 "T%02xthread:", target_signal_to_gdb(sig));
3217 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
3218 g_string_append_c(gdbserver_state.str_buf, ';');
3219 put_strbuf();
Andreas Färber5ca666c2013-06-24 19:20:57 +02003220 }
3221 /* put_packet() might have detected that the peer terminated the
3222 connection. */
Alex Bennée8d98c442020-03-16 17:21:33 +00003223 if (gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003224 return sig;
3225 }
3226
3227 sig = 0;
Alex Bennée8d98c442020-03-16 17:21:33 +00003228 gdbserver_state.state = RS_IDLE;
3229 gdbserver_state.running_state = 0;
3230 while (gdbserver_state.running_state == 0) {
3231 n = read(gdbserver_state.fd, buf, 256);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003232 if (n > 0) {
3233 int i;
3234
3235 for (i = 0; i < n; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003236 gdb_read_byte(buf[i]);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003237 }
Peter Wu5819e3e2016-06-05 16:35:48 +02003238 } else {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003239 /* XXX: Connection closed. Should probably wait for another
3240 connection before continuing. */
Peter Wu5819e3e2016-06-05 16:35:48 +02003241 if (n == 0) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003242 close(gdbserver_state.fd);
Peter Wu5819e3e2016-06-05 16:35:48 +02003243 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003244 gdbserver_state.fd = -1;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003245 return sig;
bellard1fddef42005-04-17 19:16:13 +00003246 }
Andreas Färber5ca666c2013-06-24 19:20:57 +02003247 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003248 sig = gdbserver_state.signal;
3249 gdbserver_state.signal = 0;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003250 return sig;
bellard1fddef42005-04-17 19:16:13 +00003251}
bellarde9009672005-04-26 20:42:36 +00003252
aurel32ca587a82008-12-18 22:44:13 +00003253/* Tell the remote gdb that the process has exited due to SIG. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01003254void gdb_signalled(CPUArchState *env, int sig)
aurel32ca587a82008-12-18 22:44:13 +00003255{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003256 char buf[4];
aurel32ca587a82008-12-18 22:44:13 +00003257
Alex Bennéee0a1e202020-04-30 20:01:18 +01003258 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003259 return;
3260 }
aurel32ca587a82008-12-18 22:44:13 +00003261
Andreas Färber5ca666c2013-06-24 19:20:57 +02003262 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003263 put_packet(buf);
aurel32ca587a82008-12-18 22:44:13 +00003264}
bellard1fddef42005-04-17 19:16:13 +00003265
Alex Bennéefcedd922020-04-30 20:01:19 +01003266static void gdb_accept_init(int fd)
3267{
3268 init_gdbserver_state();
3269 create_default_process(&gdbserver_state);
3270 gdbserver_state.processes[0].attached = true;
3271 gdbserver_state.c_cpu = gdb_first_attached_cpu();
3272 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
3273 gdbserver_state.fd = fd;
3274 gdb_has_xml = false;
3275}
3276
3277static bool gdb_accept_socket(int gdb_fd)
3278{
3279 int fd;
3280
3281 for(;;) {
3282 fd = accept(gdb_fd, NULL, NULL);
3283 if (fd < 0 && errno != EINTR) {
3284 perror("accept socket");
3285 return false;
3286 } else if (fd >= 0) {
3287 qemu_set_cloexec(fd);
3288 break;
3289 }
3290 }
3291
3292 gdb_accept_init(fd);
3293 return true;
3294}
3295
3296static int gdbserver_open_socket(const char *path)
3297{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003298 struct sockaddr_un sockaddr = {};
Alex Bennéefcedd922020-04-30 20:01:19 +01003299 int fd, ret;
3300
3301 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3302 if (fd < 0) {
3303 perror("create socket");
3304 return -1;
3305 }
3306
3307 sockaddr.sun_family = AF_UNIX;
3308 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
3309 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3310 if (ret < 0) {
3311 perror("bind socket");
3312 close(fd);
3313 return -1;
3314 }
3315 ret = listen(fd, 1);
3316 if (ret < 0) {
3317 perror("listen socket");
3318 close(fd);
3319 return -1;
3320 }
3321
3322 return fd;
3323}
3324
3325static bool gdb_accept_tcp(int gdb_fd)
bellard858693c2004-03-31 18:52:07 +00003326{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003327 struct sockaddr_in sockaddr = {};
bellard858693c2004-03-31 18:52:07 +00003328 socklen_t len;
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09003329 int fd;
bellard858693c2004-03-31 18:52:07 +00003330
3331 for(;;) {
3332 len = sizeof(sockaddr);
Alex Bennéee0a1e202020-04-30 20:01:18 +01003333 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
bellard858693c2004-03-31 18:52:07 +00003334 if (fd < 0 && errno != EINTR) {
3335 perror("accept");
Peter Maydell2f652222018-05-14 18:30:44 +01003336 return false;
bellard858693c2004-03-31 18:52:07 +00003337 } else if (fd >= 0) {
Peter Maydellf5bdd782018-05-14 18:30:43 +01003338 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003339 break;
3340 }
3341 }
3342
3343 /* set short latency */
Peter Maydell2f652222018-05-14 18:30:44 +01003344 if (socket_set_nodelay(fd)) {
3345 perror("setsockopt");
Philippe Mathieu-Daudéead75d82018-05-24 19:34:58 -03003346 close(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003347 return false;
3348 }
ths3b46e622007-09-17 08:09:54 +00003349
Alex Bennéefcedd922020-04-30 20:01:19 +01003350 gdb_accept_init(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003351 return true;
bellard858693c2004-03-31 18:52:07 +00003352}
3353
Alex Bennéefcedd922020-04-30 20:01:19 +01003354static int gdbserver_open_port(int port)
bellard858693c2004-03-31 18:52:07 +00003355{
3356 struct sockaddr_in sockaddr;
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003357 int fd, ret;
bellard858693c2004-03-31 18:52:07 +00003358
3359 fd = socket(PF_INET, SOCK_STREAM, 0);
3360 if (fd < 0) {
3361 perror("socket");
3362 return -1;
3363 }
Peter Maydellf5bdd782018-05-14 18:30:43 +01003364 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003365
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003366 socket_set_fast_reuse(fd);
bellard858693c2004-03-31 18:52:07 +00003367
3368 sockaddr.sin_family = AF_INET;
3369 sockaddr.sin_port = htons(port);
3370 sockaddr.sin_addr.s_addr = 0;
3371 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3372 if (ret < 0) {
3373 perror("bind");
Peter Maydellbb161722011-12-24 23:37:24 +00003374 close(fd);
bellard858693c2004-03-31 18:52:07 +00003375 return -1;
3376 }
Peter Wu96165b92016-05-04 11:32:17 +02003377 ret = listen(fd, 1);
bellard858693c2004-03-31 18:52:07 +00003378 if (ret < 0) {
3379 perror("listen");
Peter Maydellbb161722011-12-24 23:37:24 +00003380 close(fd);
bellard858693c2004-03-31 18:52:07 +00003381 return -1;
3382 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003383
bellard858693c2004-03-31 18:52:07 +00003384 return fd;
3385}
3386
Alex Bennéefcedd922020-04-30 20:01:19 +01003387int gdbserver_start(const char *port_or_path)
bellard858693c2004-03-31 18:52:07 +00003388{
Alex Bennéefcedd922020-04-30 20:01:19 +01003389 int port = g_ascii_strtoull(port_or_path, NULL, 10);
3390 int gdb_fd;
3391
3392 if (port > 0) {
3393 gdb_fd = gdbserver_open_port(port);
3394 } else {
3395 gdb_fd = gdbserver_open_socket(port_or_path);
3396 }
3397
Alex Bennéee0a1e202020-04-30 20:01:18 +01003398 if (gdb_fd < 0) {
bellard858693c2004-03-31 18:52:07 +00003399 return -1;
Alex Bennéee0a1e202020-04-30 20:01:18 +01003400 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003401
3402 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3403 return 0;
3404 } else if (gdb_accept_socket(gdb_fd)) {
3405 gdbserver_state.socket_path = g_strdup(port_or_path);
3406 return 0;
Peter Maydell2f652222018-05-14 18:30:44 +01003407 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003408
3409 /* gone wrong */
3410 close(gdb_fd);
3411 return -1;
bellardb4608c02003-06-27 17:34:32 +00003412}
aurel322b1319c2008-12-18 22:44:04 +00003413
3414/* Disable gdb stub for child processes. */
Peter Crosthwaitef7ec7f72015-06-23 19:31:16 -07003415void gdbserver_fork(CPUState *cpu)
aurel322b1319c2008-12-18 22:44:04 +00003416{
Alex Bennéee0a1e202020-04-30 20:01:18 +01003417 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber75a34032013-09-02 16:57:02 +02003418 return;
3419 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003420 close(gdbserver_state.fd);
3421 gdbserver_state.fd = -1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02003422 cpu_breakpoint_remove_all(cpu, BP_GDB);
Andreas Färber75a34032013-09-02 16:57:02 +02003423 cpu_watchpoint_remove_all(cpu, BP_GDB);
aurel322b1319c2008-12-18 22:44:04 +00003424}
pbrook4046d912007-01-28 01:53:16 +00003425#else
thsaa1f17c2007-07-11 22:48:58 +00003426static int gdb_chr_can_receive(void *opaque)
pbrook4046d912007-01-28 01:53:16 +00003427{
pbrook56aebc82008-10-11 17:55:29 +00003428 /* We can handle an arbitrarily large amount of data.
3429 Pick the maximum packet size, which is as good as anything. */
3430 return MAX_PACKET_LENGTH;
pbrook4046d912007-01-28 01:53:16 +00003431}
3432
thsaa1f17c2007-07-11 22:48:58 +00003433static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
pbrook4046d912007-01-28 01:53:16 +00003434{
pbrook4046d912007-01-28 01:53:16 +00003435 int i;
3436
3437 for (i = 0; i < size; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003438 gdb_read_byte(buf[i]);
pbrook4046d912007-01-28 01:53:16 +00003439 }
3440}
3441
Philippe Mathieu-Daudé083b2662019-12-18 18:20:09 +01003442static void gdb_chr_event(void *opaque, QEMUChrEvent event)
pbrook4046d912007-01-28 01:53:16 +00003443{
Luc Michel970ed902019-01-07 15:23:46 +00003444 int i;
3445 GDBState *s = (GDBState *) opaque;
3446
pbrook4046d912007-01-28 01:53:16 +00003447 switch (event) {
Amit Shahb6b8df52009-10-07 18:31:16 +05303448 case CHR_EVENT_OPENED:
Luc Michel970ed902019-01-07 15:23:46 +00003449 /* Start with first process attached, others detached */
3450 for (i = 0; i < s->process_num; i++) {
3451 s->processes[i].attached = !i;
3452 }
3453
Alex Bennéea346af32020-03-16 17:21:34 +00003454 s->c_cpu = gdb_first_attached_cpu();
Luc Michel970ed902019-01-07 15:23:46 +00003455 s->g_cpu = s->c_cpu;
3456
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003457 vm_stop(RUN_STATE_PAUSED);
Pavel Dovgalyuk56357d82020-10-03 20:14:01 +03003458 replay_gdb_attached();
Andreas Färber5b50e792013-06-29 04:18:45 +02003459 gdb_has_xml = false;
pbrook4046d912007-01-28 01:53:16 +00003460 break;
3461 default:
3462 break;
3463 }
3464}
3465
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003466static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
aliguori8a34a0f2009-03-05 23:01:55 +00003467{
Damien Hedded86b4672020-03-16 17:21:54 +00003468 g_autoptr(GString) hex_buf = g_string_new("O");
3469 memtohex(hex_buf, buf, len);
3470 put_packet(hex_buf->str);
aliguori8a34a0f2009-03-05 23:01:55 +00003471 return len;
3472}
3473
aliguori59030a82009-04-05 18:43:41 +00003474#ifndef _WIN32
3475static void gdb_sigterm_handler(int signal)
3476{
Luiz Capitulino13548692011-07-29 15:36:43 -03003477 if (runstate_is_running()) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003478 vm_stop(RUN_STATE_PAUSED);
Jan Kiszkae07bbac2011-02-09 16:29:40 +01003479 }
aliguori59030a82009-04-05 18:43:41 +00003480}
3481#endif
3482
Marc-André Lureau777357d2016-12-07 18:39:10 +03003483static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
3484 bool *be_opened, Error **errp)
3485{
3486 *be_opened = false;
3487}
3488
3489static void char_gdb_class_init(ObjectClass *oc, void *data)
3490{
3491 ChardevClass *cc = CHARDEV_CLASS(oc);
3492
3493 cc->internal = true;
3494 cc->open = gdb_monitor_open;
3495 cc->chr_write = gdb_monitor_write;
3496}
3497
3498#define TYPE_CHARDEV_GDB "chardev-gdb"
3499
3500static const TypeInfo char_gdb_type_info = {
3501 .name = TYPE_CHARDEV_GDB,
3502 .parent = TYPE_CHARDEV,
3503 .class_init = char_gdb_class_init,
3504};
3505
Luc Michel8f468632019-01-07 15:23:45 +00003506static int find_cpu_clusters(Object *child, void *opaque)
3507{
3508 if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
3509 GDBState *s = (GDBState *) opaque;
3510 CPUClusterState *cluster = CPU_CLUSTER(child);
3511 GDBProcess *process;
3512
3513 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3514
3515 process = &s->processes[s->process_num - 1];
3516
3517 /*
3518 * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
3519 * runtime, we enforce here that the machine does not use a cluster ID
3520 * that would lead to PID 0.
3521 */
3522 assert(cluster->cluster_id != UINT32_MAX);
3523 process->pid = cluster->cluster_id + 1;
3524 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003525 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003526
3527 return 0;
3528 }
3529
3530 return object_child_foreach(child, find_cpu_clusters, opaque);
3531}
3532
3533static int pid_order(const void *a, const void *b)
3534{
3535 GDBProcess *pa = (GDBProcess *) a;
3536 GDBProcess *pb = (GDBProcess *) b;
3537
3538 if (pa->pid < pb->pid) {
3539 return -1;
3540 } else if (pa->pid > pb->pid) {
3541 return 1;
3542 } else {
3543 return 0;
3544 }
3545}
3546
3547static void create_processes(GDBState *s)
3548{
3549 object_child_foreach(object_get_root(), find_cpu_clusters, s);
3550
Alex Bennéea346af32020-03-16 17:21:34 +00003551 if (gdbserver_state.processes) {
Luc Michel8f468632019-01-07 15:23:45 +00003552 /* Sort by PID */
Alex Bennéea346af32020-03-16 17:21:34 +00003553 qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
Luc Michel8f468632019-01-07 15:23:45 +00003554 }
3555
3556 create_default_process(s);
3557}
3558
aliguori59030a82009-04-05 18:43:41 +00003559int gdbserver_start(const char *device)
pbrook4046d912007-01-28 01:53:16 +00003560{
Doug Gale5c9522b2017-12-02 20:30:37 -05003561 trace_gdbstub_op_start(device);
3562
aliguori59030a82009-04-05 18:43:41 +00003563 char gdbstub_device_name[128];
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003564 Chardev *chr = NULL;
3565 Chardev *mon_chr;
pbrook4046d912007-01-28 01:53:16 +00003566
Ziyue Yang508b4ec2017-01-18 16:02:41 +08003567 if (!first_cpu) {
3568 error_report("gdbstub: meaningless to attach gdb to a "
3569 "machine without any CPU.");
3570 return -1;
3571 }
3572
Maxim Levitsky12bc5b42021-11-11 12:06:03 +01003573 if (kvm_enabled() && !kvm_supports_guest_debug()) {
3574 error_report("gdbstub: KVM doesn't support guest debugging");
3575 return -1;
3576 }
3577
aliguori59030a82009-04-05 18:43:41 +00003578 if (!device)
3579 return -1;
3580 if (strcmp(device, "none") != 0) {
3581 if (strstart(device, "tcp:", NULL)) {
3582 /* enforce required TCP attributes */
3583 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
Paolo Bonzinia9b13152021-02-25 11:47:52 +01003584 "%s,wait=off,nodelay=on,server=on", device);
aliguori59030a82009-04-05 18:43:41 +00003585 device = gdbstub_device_name;
aliguori36556b22009-03-28 18:05:53 +00003586 }
aliguori59030a82009-04-05 18:43:41 +00003587#ifndef _WIN32
3588 else if (strcmp(device, "stdio") == 0) {
3589 struct sigaction act;
pbrookcfc34752007-02-22 01:48:01 +00003590
aliguori59030a82009-04-05 18:43:41 +00003591 memset(&act, 0, sizeof(act));
3592 act.sa_handler = gdb_sigterm_handler;
3593 sigaction(SIGINT, &act, NULL);
3594 }
3595#endif
Marc-André Lureau95e30b22018-08-22 19:19:42 +02003596 /*
3597 * FIXME: it's a bit weird to allow using a mux chardev here
3598 * and implicitly setup a monitor. We may want to break this.
3599 */
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003600 chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
aliguori36556b22009-03-28 18:05:53 +00003601 if (!chr)
3602 return -1;
pbrookcfc34752007-02-22 01:48:01 +00003603 }
3604
Alex Bennée8d98c442020-03-16 17:21:33 +00003605 if (!gdbserver_state.init) {
3606 init_gdbserver_state();
pbrook4046d912007-01-28 01:53:16 +00003607
aliguori36556b22009-03-28 18:05:53 +00003608 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
3609
3610 /* Initialize a monitor terminal for gdb */
Marc-André Lureau777357d2016-12-07 18:39:10 +03003611 mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003612 NULL, NULL, &error_abort);
Kevin Wolf8e9119a2020-02-24 15:30:06 +01003613 monitor_init_hmp(mon_chr, false, &error_abort);
aliguori36556b22009-03-28 18:05:53 +00003614 } else {
Alex Bennée8d98c442020-03-16 17:21:33 +00003615 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
3616 mon_chr = gdbserver_state.mon_chr;
3617 reset_gdbserver_state();
aliguori36556b22009-03-28 18:05:53 +00003618 }
Luc Michel8f468632019-01-07 15:23:45 +00003619
Alex Bennée8d98c442020-03-16 17:21:33 +00003620 create_processes(&gdbserver_state);
Luc Michel8f468632019-01-07 15:23:45 +00003621
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003622 if (chr) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003623 qemu_chr_fe_init(&gdbserver_state.chr, chr, &error_abort);
3624 qemu_chr_fe_set_handlers(&gdbserver_state.chr, gdb_chr_can_receive,
3625 gdb_chr_receive, gdb_chr_event,
3626 NULL, &gdbserver_state, NULL, true);
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003627 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003628 gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
3629 gdbserver_state.mon_chr = mon_chr;
3630 gdbserver_state.current_syscall_cb = NULL;
aliguori8a34a0f2009-03-05 23:01:55 +00003631
pbrook4046d912007-01-28 01:53:16 +00003632 return 0;
3633}
Marc-André Lureau777357d2016-12-07 18:39:10 +03003634
3635static void register_types(void)
3636{
3637 type_register_static(&char_gdb_type_info);
3638}
3639
3640type_init(register_types);
pbrook4046d912007-01-28 01:53:16 +00003641#endif