blob: 3c14c6a03831dffb77847ea4d7559d7561413f2f [file] [log] [blame]
bellardb4608c02003-06-27 17:34:32 +00001/*
2 * gdb server stub
ths5fafdf22007-09-16 21:08:06 +00003 *
Alex Bennée42a09592019-07-05 13:28:19 +01004 * This implements a subset of the remote protocol as described in:
5 *
6 * https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html
7 *
bellard34751872005-07-02 14:31:34 +00008 * Copyright (c) 2003-2005 Fabrice Bellard
bellardb4608c02003-06-27 17:34:32 +00009 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
Blue Swirl8167ee82009-07-16 20:47:01 +000021 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Alex Bennée42a09592019-07-05 13:28:19 +010022 *
23 * SPDX-License-Identifier: LGPL-2.0+
bellardb4608c02003-06-27 17:34:32 +000024 */
Markus Armbruster856dfd82019-05-23 16:35:06 +020025
Peter Maydelld38ea872016-01-29 17:50:05 +000026#include "qemu/osdep.h"
Markus Armbrustera8d25322019-05-23 16:35:08 +020027#include "qemu-common.h"
Markus Armbrusterda34e652016-03-14 09:01:28 +010028#include "qapi/error.h"
Ziyue Yang508b4ec2017-01-18 16:02:41 +080029#include "qemu/error-report.h"
Markus Armbruster856dfd82019-05-23 16:35:06 +020030#include "qemu/ctype.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020031#include "qemu/cutils.h"
Markus Armbruster0b8fa322019-05-23 16:35:07 +020032#include "qemu/module.h"
Paolo Bonzini243af022020-02-04 12:20:10 +010033#include "trace/trace-root.h"
Peter Maydell85b4fa02021-09-08 16:44:04 +010034#include "exec/gdbstub.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020035#ifdef CONFIG_USER_ONLY
bellard1fddef42005-04-17 19:16:13 +000036#include "qemu.h"
37#else
Paolo Bonzini83c90892012-12-17 18:19:49 +010038#include "monitor/monitor.h"
Marc-André Lureau8228e352017-01-26 17:19:46 +040039#include "chardev/char.h"
Marc-André Lureau4d43a602017-01-26 18:26:44 +040040#include "chardev/char-fe.h"
Luc Michel8f468632019-01-07 15:23:45 +000041#include "hw/cpu/cluster.h"
Like Xu5cc87672019-05-19 04:54:21 +080042#include "hw/boards.h"
bellard1fddef42005-04-17 19:16:13 +000043#endif
bellard67b915a2004-03-31 23:37:16 +000044
pbrook56aebc82008-10-11 17:55:29 +000045#define MAX_PACKET_LENGTH 4096
46
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010047#include "qemu/sockets.h"
Vincent Palatinb3946622017-01-10 11:59:55 +010048#include "sysemu/hw_accel.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010049#include "sysemu/kvm.h"
Markus Armbruster54d31232019-08-12 07:23:59 +020050#include "sysemu/runstate.h"
Philippe Mathieu-Daudé6b5fe132021-03-05 13:54:49 +000051#include "semihosting/semihost.h"
Paolo Bonzini63c91552016-03-15 13:18:37 +010052#include "exec/exec-all.h"
Pavel Dovgalyukfda84582020-10-03 20:13:43 +030053#include "sysemu/replay.h"
aurel32ca587a82008-12-18 22:44:13 +000054
Jan Kiszkaa3919382015-02-07 09:38:44 +010055#ifdef CONFIG_USER_ONLY
56#define GDB_ATTACHED "0"
57#else
58#define GDB_ATTACHED "1"
59#endif
60
Jon Doronab4752e2019-05-29 09:41:48 +030061#ifndef CONFIG_USER_ONLY
62static int phy_memory_mode;
63#endif
64
Andreas Färberf3659ee2013-06-27 19:09:09 +020065static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
66 uint8_t *buf, int len, bool is_write)
Fabien Chouteau44520db2011-09-08 12:48:16 +020067{
Jon Doronab4752e2019-05-29 09:41:48 +030068 CPUClass *cc;
Andreas Färberf3659ee2013-06-27 19:09:09 +020069
Jon Doronab4752e2019-05-29 09:41:48 +030070#ifndef CONFIG_USER_ONLY
71 if (phy_memory_mode) {
72 if (is_write) {
73 cpu_physical_memory_write(addr, buf, len);
74 } else {
75 cpu_physical_memory_read(addr, buf, len);
76 }
77 return 0;
78 }
79#endif
80
81 cc = CPU_GET_CLASS(cpu);
Andreas Färberf3659ee2013-06-27 19:09:09 +020082 if (cc->memory_rw_debug) {
83 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
84 }
85 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
Fabien Chouteau44520db2011-09-08 12:48:16 +020086}
aurel32ca587a82008-12-18 22:44:13 +000087
Alex Bennéed2a6c852017-07-12 11:52:14 +010088/* Return the GDB index for a given vCPU state.
89 *
90 * For user mode this is simply the thread id. In system mode GDB
91 * numbers CPUs from 1 as 0 is reserved as an "any cpu" index.
92 */
93static inline int cpu_gdb_index(CPUState *cpu)
94{
95#if defined(CONFIG_USER_ONLY)
Alex Bennéebd88c782017-07-12 11:52:15 +010096 TaskState *ts = (TaskState *) cpu->opaque;
Alex Bennéea8e537f2021-11-29 14:09:29 +000097 return ts ? ts->ts_tid : -1;
Alex Bennéed2a6c852017-07-12 11:52:14 +010098#else
99 return cpu->cpu_index + 1;
100#endif
101}
102
aurel32ca587a82008-12-18 22:44:13 +0000103enum {
104 GDB_SIGNAL_0 = 0,
105 GDB_SIGNAL_INT = 2,
Jan Kiszka425189a2011-03-22 11:02:09 +0100106 GDB_SIGNAL_QUIT = 3,
aurel32ca587a82008-12-18 22:44:13 +0000107 GDB_SIGNAL_TRAP = 5,
Jan Kiszka425189a2011-03-22 11:02:09 +0100108 GDB_SIGNAL_ABRT = 6,
109 GDB_SIGNAL_ALRM = 14,
110 GDB_SIGNAL_IO = 23,
111 GDB_SIGNAL_XCPU = 24,
aurel32ca587a82008-12-18 22:44:13 +0000112 GDB_SIGNAL_UNKNOWN = 143
113};
114
115#ifdef CONFIG_USER_ONLY
116
117/* Map target signal numbers to GDB protocol signal numbers and vice
118 * versa. For user emulation's currently supported systems, we can
119 * assume most signals are defined.
120 */
121
122static int gdb_signal_table[] = {
123 0,
124 TARGET_SIGHUP,
125 TARGET_SIGINT,
126 TARGET_SIGQUIT,
127 TARGET_SIGILL,
128 TARGET_SIGTRAP,
129 TARGET_SIGABRT,
130 -1, /* SIGEMT */
131 TARGET_SIGFPE,
132 TARGET_SIGKILL,
133 TARGET_SIGBUS,
134 TARGET_SIGSEGV,
135 TARGET_SIGSYS,
136 TARGET_SIGPIPE,
137 TARGET_SIGALRM,
138 TARGET_SIGTERM,
139 TARGET_SIGURG,
140 TARGET_SIGSTOP,
141 TARGET_SIGTSTP,
142 TARGET_SIGCONT,
143 TARGET_SIGCHLD,
144 TARGET_SIGTTIN,
145 TARGET_SIGTTOU,
146 TARGET_SIGIO,
147 TARGET_SIGXCPU,
148 TARGET_SIGXFSZ,
149 TARGET_SIGVTALRM,
150 TARGET_SIGPROF,
151 TARGET_SIGWINCH,
152 -1, /* SIGLOST */
153 TARGET_SIGUSR1,
154 TARGET_SIGUSR2,
blueswir1c72d5bf2009-01-15 17:27:45 +0000155#ifdef TARGET_SIGPWR
aurel32ca587a82008-12-18 22:44:13 +0000156 TARGET_SIGPWR,
blueswir1c72d5bf2009-01-15 17:27:45 +0000157#else
158 -1,
159#endif
aurel32ca587a82008-12-18 22:44:13 +0000160 -1, /* SIGPOLL */
161 -1,
162 -1,
163 -1,
164 -1,
165 -1,
166 -1,
167 -1,
168 -1,
169 -1,
170 -1,
171 -1,
blueswir1c72d5bf2009-01-15 17:27:45 +0000172#ifdef __SIGRTMIN
aurel32ca587a82008-12-18 22:44:13 +0000173 __SIGRTMIN + 1,
174 __SIGRTMIN + 2,
175 __SIGRTMIN + 3,
176 __SIGRTMIN + 4,
177 __SIGRTMIN + 5,
178 __SIGRTMIN + 6,
179 __SIGRTMIN + 7,
180 __SIGRTMIN + 8,
181 __SIGRTMIN + 9,
182 __SIGRTMIN + 10,
183 __SIGRTMIN + 11,
184 __SIGRTMIN + 12,
185 __SIGRTMIN + 13,
186 __SIGRTMIN + 14,
187 __SIGRTMIN + 15,
188 __SIGRTMIN + 16,
189 __SIGRTMIN + 17,
190 __SIGRTMIN + 18,
191 __SIGRTMIN + 19,
192 __SIGRTMIN + 20,
193 __SIGRTMIN + 21,
194 __SIGRTMIN + 22,
195 __SIGRTMIN + 23,
196 __SIGRTMIN + 24,
197 __SIGRTMIN + 25,
198 __SIGRTMIN + 26,
199 __SIGRTMIN + 27,
200 __SIGRTMIN + 28,
201 __SIGRTMIN + 29,
202 __SIGRTMIN + 30,
203 __SIGRTMIN + 31,
204 -1, /* SIGCANCEL */
205 __SIGRTMIN,
206 __SIGRTMIN + 32,
207 __SIGRTMIN + 33,
208 __SIGRTMIN + 34,
209 __SIGRTMIN + 35,
210 __SIGRTMIN + 36,
211 __SIGRTMIN + 37,
212 __SIGRTMIN + 38,
213 __SIGRTMIN + 39,
214 __SIGRTMIN + 40,
215 __SIGRTMIN + 41,
216 __SIGRTMIN + 42,
217 __SIGRTMIN + 43,
218 __SIGRTMIN + 44,
219 __SIGRTMIN + 45,
220 __SIGRTMIN + 46,
221 __SIGRTMIN + 47,
222 __SIGRTMIN + 48,
223 __SIGRTMIN + 49,
224 __SIGRTMIN + 50,
225 __SIGRTMIN + 51,
226 __SIGRTMIN + 52,
227 __SIGRTMIN + 53,
228 __SIGRTMIN + 54,
229 __SIGRTMIN + 55,
230 __SIGRTMIN + 56,
231 __SIGRTMIN + 57,
232 __SIGRTMIN + 58,
233 __SIGRTMIN + 59,
234 __SIGRTMIN + 60,
235 __SIGRTMIN + 61,
236 __SIGRTMIN + 62,
237 __SIGRTMIN + 63,
238 __SIGRTMIN + 64,
239 __SIGRTMIN + 65,
240 __SIGRTMIN + 66,
241 __SIGRTMIN + 67,
242 __SIGRTMIN + 68,
243 __SIGRTMIN + 69,
244 __SIGRTMIN + 70,
245 __SIGRTMIN + 71,
246 __SIGRTMIN + 72,
247 __SIGRTMIN + 73,
248 __SIGRTMIN + 74,
249 __SIGRTMIN + 75,
250 __SIGRTMIN + 76,
251 __SIGRTMIN + 77,
252 __SIGRTMIN + 78,
253 __SIGRTMIN + 79,
254 __SIGRTMIN + 80,
255 __SIGRTMIN + 81,
256 __SIGRTMIN + 82,
257 __SIGRTMIN + 83,
258 __SIGRTMIN + 84,
259 __SIGRTMIN + 85,
260 __SIGRTMIN + 86,
261 __SIGRTMIN + 87,
262 __SIGRTMIN + 88,
263 __SIGRTMIN + 89,
264 __SIGRTMIN + 90,
265 __SIGRTMIN + 91,
266 __SIGRTMIN + 92,
267 __SIGRTMIN + 93,
268 __SIGRTMIN + 94,
269 __SIGRTMIN + 95,
270 -1, /* SIGINFO */
271 -1, /* UNKNOWN */
272 -1, /* DEFAULT */
273 -1,
274 -1,
275 -1,
276 -1,
277 -1,
278 -1
blueswir1c72d5bf2009-01-15 17:27:45 +0000279#endif
aurel32ca587a82008-12-18 22:44:13 +0000280};
bellard8f447cc2006-06-14 15:21:14 +0000281#else
aurel32ca587a82008-12-18 22:44:13 +0000282/* In system mode we only need SIGINT and SIGTRAP; other signals
283 are not yet supported. */
284
285enum {
286 TARGET_SIGINT = 2,
287 TARGET_SIGTRAP = 5
288};
289
290static int gdb_signal_table[] = {
291 -1,
292 -1,
293 TARGET_SIGINT,
294 -1,
295 -1,
296 TARGET_SIGTRAP
297};
bellard8f447cc2006-06-14 15:21:14 +0000298#endif
bellardb4608c02003-06-27 17:34:32 +0000299
aurel32ca587a82008-12-18 22:44:13 +0000300#ifdef CONFIG_USER_ONLY
301static int target_signal_to_gdb (int sig)
302{
303 int i;
304 for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
305 if (gdb_signal_table[i] == sig)
306 return i;
307 return GDB_SIGNAL_UNKNOWN;
308}
309#endif
310
311static int gdb_signal_to_target (int sig)
312{
313 if (sig < ARRAY_SIZE (gdb_signal_table))
314 return gdb_signal_table[sig];
315 else
316 return -1;
317}
318
pbrook56aebc82008-10-11 17:55:29 +0000319typedef struct GDBRegisterState {
320 int base_reg;
321 int num_regs;
Alex Bennéea010bdb2020-03-16 17:21:41 +0000322 gdb_get_reg_cb get_reg;
323 gdb_set_reg_cb set_reg;
pbrook56aebc82008-10-11 17:55:29 +0000324 const char *xml;
325 struct GDBRegisterState *next;
326} GDBRegisterState;
327
Luc Michel8f468632019-01-07 15:23:45 +0000328typedef struct GDBProcess {
329 uint32_t pid;
330 bool attached;
Luc Michelc145eea2019-01-07 15:23:46 +0000331
332 char target_xml[1024];
Luc Michel8f468632019-01-07 15:23:45 +0000333} GDBProcess;
334
bellard858693c2004-03-31 18:52:07 +0000335enum RSState {
aliguori36556b22009-03-28 18:05:53 +0000336 RS_INACTIVE,
bellard858693c2004-03-31 18:52:07 +0000337 RS_IDLE,
338 RS_GETLINE,
Doug Gale4bf43122017-05-01 12:22:10 -0400339 RS_GETLINE_ESC,
340 RS_GETLINE_RLE,
bellard858693c2004-03-31 18:52:07 +0000341 RS_CHKSUM1,
342 RS_CHKSUM2,
343};
bellard858693c2004-03-31 18:52:07 +0000344typedef struct GDBState {
Alex Bennée8d98c442020-03-16 17:21:33 +0000345 bool init; /* have we been initialised? */
Andreas Färber2e0f2cf2013-06-27 19:19:39 +0200346 CPUState *c_cpu; /* current CPU for step/continue ops */
347 CPUState *g_cpu; /* current CPU for other ops */
Andreas Färber52f34622013-06-27 13:44:40 +0200348 CPUState *query_cpu; /* for q{f|s}ThreadInfo */
bellard41625032005-04-24 10:07:11 +0000349 enum RSState state; /* parsing state */
pbrook56aebc82008-10-11 17:55:29 +0000350 char line_buf[MAX_PACKET_LENGTH];
bellard858693c2004-03-31 18:52:07 +0000351 int line_buf_index;
Doug Gale4bf43122017-05-01 12:22:10 -0400352 int line_sum; /* running checksum */
353 int line_csum; /* checksum at the end of the packet */
Damien Hedded116e812020-03-16 17:21:53 +0000354 GByteArray *last_packet;
edgar_igl1f487ee2008-05-17 22:20:53 +0000355 int signal;
bellard41625032005-04-24 10:07:11 +0000356#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000357 int fd;
Alex Bennéefcedd922020-04-30 20:01:19 +0100358 char *socket_path;
bellard41625032005-04-24 10:07:11 +0000359 int running_state;
pbrook4046d912007-01-28 01:53:16 +0000360#else
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +0300361 CharBackend chr;
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +0300362 Chardev *mon_chr;
bellard41625032005-04-24 10:07:11 +0000363#endif
Luc Michel8f468632019-01-07 15:23:45 +0000364 bool multiprocess;
365 GDBProcess *processes;
366 int process_num;
Meador Ingecdb432b2012-03-15 17:49:45 +0000367 char syscall_buf[256];
368 gdb_syscall_complete_cb current_syscall_cb;
Alex Bennée308f9e82020-03-16 17:21:35 +0000369 GString *str_buf;
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000370 GByteArray *mem_buf;
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100371 int sstep_flags;
372 int supported_sstep_flags;
bellard858693c2004-03-31 18:52:07 +0000373} GDBState;
bellardb4608c02003-06-27 17:34:32 +0000374
Alex Bennée8d98c442020-03-16 17:21:33 +0000375static GDBState gdbserver_state;
376
377static void init_gdbserver_state(void)
378{
379 g_assert(!gdbserver_state.init);
380 memset(&gdbserver_state, 0, sizeof(GDBState));
381 gdbserver_state.init = true;
Alex Bennée308f9e82020-03-16 17:21:35 +0000382 gdbserver_state.str_buf = g_string_new(NULL);
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000383 gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
Damien Hedded116e812020-03-16 17:21:53 +0000384 gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100385
386 /*
387 * In replay mode all events will come from the log and can't be
388 * suppressed otherwise we would break determinism. However as those
389 * events are tied to the number of executed instructions we won't see
390 * them occurring every time we single step.
391 */
392 if (replay_mode != REPLAY_MODE_NONE) {
393 gdbserver_state.supported_sstep_flags = SSTEP_ENABLE;
Maxim Levitsky12bc5b42021-11-11 12:06:03 +0100394 } else if (kvm_enabled()) {
395 gdbserver_state.supported_sstep_flags = kvm_get_supported_sstep_flags();
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100396 } else {
397 gdbserver_state.supported_sstep_flags =
398 SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
399 }
400
401 /*
402 * By default use no IRQs and no timers while single stepping so as to
403 * make single stepping like an ICE HW step.
404 */
Maxim Levitsky12bc5b42021-11-11 12:06:03 +0100405 gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
406 gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100407
Alex Bennée8d98c442020-03-16 17:21:33 +0000408}
409
410#ifndef CONFIG_USER_ONLY
411static void reset_gdbserver_state(void)
412{
413 g_free(gdbserver_state.processes);
414 gdbserver_state.processes = NULL;
415 gdbserver_state.process_num = 0;
416}
417#endif
aliguori880a7572008-11-18 20:30:24 +0000418
Andreas Färber5b50e792013-06-29 04:18:45 +0200419bool gdb_has_xml;
pbrook56aebc82008-10-11 17:55:29 +0000420
bellard1fddef42005-04-17 19:16:13 +0000421#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000422
Alex Bennéea346af32020-03-16 17:21:34 +0000423static int get_char(void)
bellardb4608c02003-06-27 17:34:32 +0000424{
425 uint8_t ch;
426 int ret;
427
428 for(;;) {
Alex Bennéea346af32020-03-16 17:21:34 +0000429 ret = qemu_recv(gdbserver_state.fd, &ch, 1, 0);
bellardb4608c02003-06-27 17:34:32 +0000430 if (ret < 0) {
edgar_igl1f487ee2008-05-17 22:20:53 +0000431 if (errno == ECONNRESET)
Alex Bennéea346af32020-03-16 17:21:34 +0000432 gdbserver_state.fd = -1;
Peter Wu5819e3e2016-06-05 16:35:48 +0200433 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000434 return -1;
435 } else if (ret == 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000436 close(gdbserver_state.fd);
437 gdbserver_state.fd = -1;
bellardb4608c02003-06-27 17:34:32 +0000438 return -1;
439 } else {
440 break;
441 }
442 }
443 return ch;
444}
pbrook4046d912007-01-28 01:53:16 +0000445#endif
bellardb4608c02003-06-27 17:34:32 +0000446
blueswir1654efcf2009-04-18 07:29:59 +0000447static enum {
pbrooka2d1eba2007-01-28 03:10:55 +0000448 GDB_SYS_UNKNOWN,
449 GDB_SYS_ENABLED,
450 GDB_SYS_DISABLED,
451} gdb_syscall_mode;
452
Liviu Ionescua38bb072014-12-11 12:07:48 +0000453/* Decide if either remote gdb syscalls or native file IO should be used. */
pbrooka2d1eba2007-01-28 03:10:55 +0000454int use_gdb_syscalls(void)
455{
Leon Alraecfe67ce2015-06-19 14:17:45 +0100456 SemihostingTarget target = semihosting_get_target();
457 if (target == SEMIHOSTING_TARGET_NATIVE) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000458 /* -semihosting-config target=native */
459 return false;
Leon Alraecfe67ce2015-06-19 14:17:45 +0100460 } else if (target == SEMIHOSTING_TARGET_GDB) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000461 /* -semihosting-config target=gdb */
462 return true;
463 }
464
465 /* -semihosting-config target=auto */
466 /* On the first call check if gdb is connected and remember. */
pbrooka2d1eba2007-01-28 03:10:55 +0000467 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
Alex Bennée8d98c442020-03-16 17:21:33 +0000468 gdb_syscall_mode = gdbserver_state.init ?
469 GDB_SYS_ENABLED : GDB_SYS_DISABLED;
pbrooka2d1eba2007-01-28 03:10:55 +0000470 }
471 return gdb_syscall_mode == GDB_SYS_ENABLED;
472}
473
Alex Bennéeed12f5b2021-05-20 18:43:02 +0100474static bool stub_can_reverse(void)
475{
476#ifdef CONFIG_USER_ONLY
477 return false;
478#else
479 return replay_mode == REPLAY_MODE_PLAY;
480#endif
481}
482
edgar_iglba70a622008-03-14 06:10:42 +0000483/* Resume execution. */
Alex Bennéea346af32020-03-16 17:21:34 +0000484static inline void gdb_continue(void)
edgar_iglba70a622008-03-14 06:10:42 +0000485{
Doug Gale5c9522b2017-12-02 20:30:37 -0500486
edgar_iglba70a622008-03-14 06:10:42 +0000487#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000488 gdbserver_state.running_state = 1;
Doug Gale5c9522b2017-12-02 20:30:37 -0500489 trace_gdbstub_op_continue();
edgar_iglba70a622008-03-14 06:10:42 +0000490#else
Paolo Bonzini26ac7a32013-06-03 17:06:54 +0200491 if (!runstate_needs_reset()) {
Doug Gale5c9522b2017-12-02 20:30:37 -0500492 trace_gdbstub_op_continue();
Paolo Bonzini87f25c12013-05-30 13:20:40 +0200493 vm_start();
494 }
edgar_iglba70a622008-03-14 06:10:42 +0000495#endif
496}
497
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100498/*
499 * Resume execution, per CPU actions. For user-mode emulation it's
500 * equivalent to gdb_continue.
501 */
Alex Bennéea346af32020-03-16 17:21:34 +0000502static int gdb_continue_partial(char *newstates)
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100503{
504 CPUState *cpu;
505 int res = 0;
506#ifdef CONFIG_USER_ONLY
507 /*
508 * This is not exactly accurate, but it's an improvement compared to the
509 * previous situation, where only one CPU would be single-stepped.
510 */
511 CPU_FOREACH(cpu) {
512 if (newstates[cpu->cpu_index] == 's') {
Doug Gale5c9522b2017-12-02 20:30:37 -0500513 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100514 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100515 }
516 }
Alex Bennéea346af32020-03-16 17:21:34 +0000517 gdbserver_state.running_state = 1;
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100518#else
519 int flag = 0;
520
521 if (!runstate_needs_reset()) {
522 if (vm_prepare_start()) {
523 return 0;
524 }
525
526 CPU_FOREACH(cpu) {
527 switch (newstates[cpu->cpu_index]) {
528 case 0:
529 case 1:
530 break; /* nothing to do here */
531 case 's':
Doug Gale5c9522b2017-12-02 20:30:37 -0500532 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100533 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100534 cpu_resume(cpu);
535 flag = 1;
536 break;
537 case 'c':
Doug Gale5c9522b2017-12-02 20:30:37 -0500538 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100539 cpu_resume(cpu);
540 flag = 1;
541 break;
542 default:
543 res = -1;
544 break;
545 }
546 }
547 }
548 if (flag) {
549 qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
550 }
551#endif
552 return res;
553}
554
Alex Bennéea346af32020-03-16 17:21:34 +0000555static void put_buffer(const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000556{
pbrook4046d912007-01-28 01:53:16 +0000557#ifdef CONFIG_USER_ONLY
bellardb4608c02003-06-27 17:34:32 +0000558 int ret;
559
560 while (len > 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000561 ret = send(gdbserver_state.fd, buf, len, 0);
bellardb4608c02003-06-27 17:34:32 +0000562 if (ret < 0) {
Peter Wu5819e3e2016-06-05 16:35:48 +0200563 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000564 return;
565 } else {
566 buf += ret;
567 len -= ret;
568 }
569 }
pbrook4046d912007-01-28 01:53:16 +0000570#else
Daniel P. Berrange6ab3fc32016-09-06 14:56:04 +0100571 /* XXX this blocks entire thread. Rewrite to use
572 * qemu_chr_fe_write and background I/O callbacks */
Alex Bennéea346af32020-03-16 17:21:34 +0000573 qemu_chr_fe_write_all(&gdbserver_state.chr, buf, len);
pbrook4046d912007-01-28 01:53:16 +0000574#endif
bellardb4608c02003-06-27 17:34:32 +0000575}
576
577static inline int fromhex(int v)
578{
579 if (v >= '0' && v <= '9')
580 return v - '0';
581 else if (v >= 'A' && v <= 'F')
582 return v - 'A' + 10;
583 else if (v >= 'a' && v <= 'f')
584 return v - 'a' + 10;
585 else
586 return 0;
587}
588
589static inline int tohex(int v)
590{
591 if (v < 10)
592 return v + '0';
593 else
594 return v - 10 + 'a';
595}
596
Philippe Mathieu-Daudé90057742018-04-08 11:59:33 -0300597/* writes 2*len+1 bytes in buf */
Alex Bennée308f9e82020-03-16 17:21:35 +0000598static void memtohex(GString *buf, const uint8_t *mem, int len)
bellardb4608c02003-06-27 17:34:32 +0000599{
600 int i, c;
bellardb4608c02003-06-27 17:34:32 +0000601 for(i = 0; i < len; i++) {
602 c = mem[i];
Alex Bennée308f9e82020-03-16 17:21:35 +0000603 g_string_append_c(buf, tohex(c >> 4));
604 g_string_append_c(buf, tohex(c & 0xf));
bellardb4608c02003-06-27 17:34:32 +0000605 }
Alex Bennée308f9e82020-03-16 17:21:35 +0000606 g_string_append_c(buf, '\0');
bellardb4608c02003-06-27 17:34:32 +0000607}
608
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000609static void hextomem(GByteArray *mem, const char *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000610{
611 int i;
612
613 for(i = 0; i < len; i++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000614 guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
615 g_byte_array_append(mem, &byte, 1);
bellardb4608c02003-06-27 17:34:32 +0000616 buf += 2;
617 }
618}
619
Doug Gale5c9522b2017-12-02 20:30:37 -0500620static void hexdump(const char *buf, int len,
621 void (*trace_fn)(size_t ofs, char const *text))
622{
623 char line_buffer[3 * 16 + 4 + 16 + 1];
624
625 size_t i;
626 for (i = 0; i < len || (i & 0xF); ++i) {
627 size_t byte_ofs = i & 15;
628
629 if (byte_ofs == 0) {
630 memset(line_buffer, ' ', 3 * 16 + 4 + 16);
631 line_buffer[3 * 16 + 4 + 16] = 0;
632 }
633
634 size_t col_group = (i >> 2) & 3;
635 size_t hex_col = byte_ofs * 3 + col_group;
636 size_t txt_col = 3 * 16 + 4 + byte_ofs;
637
638 if (i < len) {
639 char value = buf[i];
640
641 line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
642 line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
643 line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
644 ? value
645 : '.';
646 }
647
648 if (byte_ofs == 0xF)
649 trace_fn(i & -16, line_buffer);
650 }
651}
652
bellardb4608c02003-06-27 17:34:32 +0000653/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000654static int put_packet_binary(const char *buf, int len, bool dump)
bellardb4608c02003-06-27 17:34:32 +0000655{
pbrook56aebc82008-10-11 17:55:29 +0000656 int csum, i;
Damien Hedded116e812020-03-16 17:21:53 +0000657 uint8_t footer[3];
bellardb4608c02003-06-27 17:34:32 +0000658
Doug Gale5c9522b2017-12-02 20:30:37 -0500659 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
660 hexdump(buf, len, trace_gdbstub_io_binaryreply);
661 }
662
bellardb4608c02003-06-27 17:34:32 +0000663 for(;;) {
Damien Hedded116e812020-03-16 17:21:53 +0000664 g_byte_array_set_size(gdbserver_state.last_packet, 0);
665 g_byte_array_append(gdbserver_state.last_packet,
666 (const uint8_t *) "$", 1);
667 g_byte_array_append(gdbserver_state.last_packet,
668 (const uint8_t *) buf, len);
bellardb4608c02003-06-27 17:34:32 +0000669 csum = 0;
670 for(i = 0; i < len; i++) {
671 csum += buf[i];
672 }
Damien Hedded116e812020-03-16 17:21:53 +0000673 footer[0] = '#';
674 footer[1] = tohex((csum >> 4) & 0xf);
675 footer[2] = tohex((csum) & 0xf);
676 g_byte_array_append(gdbserver_state.last_packet, footer, 3);
bellardb4608c02003-06-27 17:34:32 +0000677
Damien Hedded116e812020-03-16 17:21:53 +0000678 put_buffer(gdbserver_state.last_packet->data,
679 gdbserver_state.last_packet->len);
bellardb4608c02003-06-27 17:34:32 +0000680
pbrook4046d912007-01-28 01:53:16 +0000681#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000682 i = get_char();
pbrook4046d912007-01-28 01:53:16 +0000683 if (i < 0)
bellardb4608c02003-06-27 17:34:32 +0000684 return -1;
pbrook4046d912007-01-28 01:53:16 +0000685 if (i == '+')
bellardb4608c02003-06-27 17:34:32 +0000686 break;
pbrook4046d912007-01-28 01:53:16 +0000687#else
688 break;
689#endif
bellardb4608c02003-06-27 17:34:32 +0000690 }
691 return 0;
692}
693
pbrook56aebc82008-10-11 17:55:29 +0000694/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000695static int put_packet(const char *buf)
pbrook56aebc82008-10-11 17:55:29 +0000696{
Doug Gale5c9522b2017-12-02 20:30:37 -0500697 trace_gdbstub_io_reply(buf);
pbrook56aebc82008-10-11 17:55:29 +0000698
Alex Bennéea346af32020-03-16 17:21:34 +0000699 return put_packet_binary(buf, strlen(buf), false);
pbrook56aebc82008-10-11 17:55:29 +0000700}
701
Alex Bennée308f9e82020-03-16 17:21:35 +0000702static void put_strbuf(void)
pbrook56aebc82008-10-11 17:55:29 +0000703{
Alex Bennée308f9e82020-03-16 17:21:35 +0000704 put_packet(gdbserver_state.str_buf->str);
705}
706
707/* Encode data using the encoding for 'x' packets. */
708static void memtox(GString *buf, const char *mem, int len)
709{
pbrook56aebc82008-10-11 17:55:29 +0000710 char c;
711
712 while (len--) {
713 c = *(mem++);
714 switch (c) {
715 case '#': case '$': case '*': case '}':
Alex Bennée308f9e82020-03-16 17:21:35 +0000716 g_string_append_c(buf, '}');
717 g_string_append_c(buf, c ^ 0x20);
pbrook56aebc82008-10-11 17:55:29 +0000718 break;
719 default:
Alex Bennée308f9e82020-03-16 17:21:35 +0000720 g_string_append_c(buf, c);
pbrook56aebc82008-10-11 17:55:29 +0000721 break;
722 }
723 }
pbrook56aebc82008-10-11 17:55:29 +0000724}
725
Alex Bennéea346af32020-03-16 17:21:34 +0000726static uint32_t gdb_get_cpu_pid(CPUState *cpu)
Luc Michel1a227332019-01-07 15:23:45 +0000727{
Luc Michel1a227332019-01-07 15:23:45 +0000728 /* TODO: In user mode, we should use the task state PID */
Peter Maydell46f5abc2019-01-29 11:46:06 +0000729 if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
730 /* Return the default process' PID */
Alex Bennéea346af32020-03-16 17:21:34 +0000731 int index = gdbserver_state.process_num - 1;
732 return gdbserver_state.processes[index].pid;
Peter Maydell46f5abc2019-01-29 11:46:06 +0000733 }
734 return cpu->cluster_index + 1;
Luc Michel1a227332019-01-07 15:23:45 +0000735}
736
Alex Bennéea346af32020-03-16 17:21:34 +0000737static GDBProcess *gdb_get_process(uint32_t pid)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000738{
739 int i;
740
741 if (!pid) {
742 /* 0 means any process, we take the first one */
Alex Bennéea346af32020-03-16 17:21:34 +0000743 return &gdbserver_state.processes[0];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000744 }
745
Alex Bennéea346af32020-03-16 17:21:34 +0000746 for (i = 0; i < gdbserver_state.process_num; i++) {
747 if (gdbserver_state.processes[i].pid == pid) {
748 return &gdbserver_state.processes[i];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000749 }
750 }
751
752 return NULL;
753}
754
Alex Bennéea346af32020-03-16 17:21:34 +0000755static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000756{
Alex Bennéea346af32020-03-16 17:21:34 +0000757 return gdb_get_process(gdb_get_cpu_pid(cpu));
Luc Michel7d8c87d2019-01-07 15:23:45 +0000758}
759
760static CPUState *find_cpu(uint32_t thread_id)
761{
762 CPUState *cpu;
763
764 CPU_FOREACH(cpu) {
765 if (cpu_gdb_index(cpu) == thread_id) {
766 return cpu;
767 }
768 }
769
770 return NULL;
771}
772
Alex Bennéea346af32020-03-16 17:21:34 +0000773static CPUState *get_first_cpu_in_process(GDBProcess *process)
Luc Michele40e5202019-01-07 15:23:46 +0000774{
775 CPUState *cpu;
776
777 CPU_FOREACH(cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000778 if (gdb_get_cpu_pid(cpu) == process->pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000779 return cpu;
780 }
781 }
782
783 return NULL;
784}
785
Alex Bennéea346af32020-03-16 17:21:34 +0000786static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000787{
Alex Bennéea346af32020-03-16 17:21:34 +0000788 uint32_t pid = gdb_get_cpu_pid(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000789 cpu = CPU_NEXT(cpu);
790
791 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000792 if (gdb_get_cpu_pid(cpu) == pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000793 break;
794 }
795
796 cpu = CPU_NEXT(cpu);
797 }
798
799 return cpu;
800}
801
Luc Michele40e5202019-01-07 15:23:46 +0000802/* Return the cpu following @cpu, while ignoring unattached processes. */
Alex Bennéea346af32020-03-16 17:21:34 +0000803static CPUState *gdb_next_attached_cpu(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000804{
805 cpu = CPU_NEXT(cpu);
806
807 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000808 if (gdb_get_cpu_process(cpu)->attached) {
Luc Michele40e5202019-01-07 15:23:46 +0000809 break;
810 }
811
812 cpu = CPU_NEXT(cpu);
813 }
814
815 return cpu;
816}
817
818/* Return the first attached cpu */
Alex Bennéea346af32020-03-16 17:21:34 +0000819static CPUState *gdb_first_attached_cpu(void)
Luc Michele40e5202019-01-07 15:23:46 +0000820{
821 CPUState *cpu = first_cpu;
Alex Bennéea346af32020-03-16 17:21:34 +0000822 GDBProcess *process = gdb_get_cpu_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000823
824 if (!process->attached) {
Alex Bennéea346af32020-03-16 17:21:34 +0000825 return gdb_next_attached_cpu(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000826 }
827
828 return cpu;
829}
830
Alex Bennéea346af32020-03-16 17:21:34 +0000831static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
Luc Michelab65eed2019-01-29 11:46:03 +0000832{
833 GDBProcess *process;
834 CPUState *cpu;
835
836 if (!pid && !tid) {
837 /* 0 means any process/thread, we take the first attached one */
Alex Bennéea346af32020-03-16 17:21:34 +0000838 return gdb_first_attached_cpu();
Luc Michelab65eed2019-01-29 11:46:03 +0000839 } else if (pid && !tid) {
840 /* any thread in a specific process */
Alex Bennéea346af32020-03-16 17:21:34 +0000841 process = gdb_get_process(pid);
Luc Michelab65eed2019-01-29 11:46:03 +0000842
843 if (process == NULL) {
844 return NULL;
845 }
846
847 if (!process->attached) {
848 return NULL;
849 }
850
Alex Bennéea346af32020-03-16 17:21:34 +0000851 return get_first_cpu_in_process(process);
Luc Michelab65eed2019-01-29 11:46:03 +0000852 } else {
853 /* a specific thread */
854 cpu = find_cpu(tid);
855
856 if (cpu == NULL) {
857 return NULL;
858 }
859
Alex Bennéea346af32020-03-16 17:21:34 +0000860 process = gdb_get_cpu_process(cpu);
Luc Michelab65eed2019-01-29 11:46:03 +0000861
862 if (pid && process->pid != pid) {
863 return NULL;
864 }
865
866 if (!process->attached) {
867 return NULL;
868 }
869
870 return cpu;
871 }
872}
873
Alex Bennéea346af32020-03-16 17:21:34 +0000874static const char *get_feature_xml(const char *p, const char **newp,
875 GDBProcess *process)
pbrook56aebc82008-10-11 17:55:29 +0000876{
pbrook56aebc82008-10-11 17:55:29 +0000877 size_t len;
878 int i;
879 const char *name;
Alex Bennéea346af32020-03-16 17:21:34 +0000880 CPUState *cpu = get_first_cpu_in_process(process);
Luc Michelc145eea2019-01-07 15:23:46 +0000881 CPUClass *cc = CPU_GET_CLASS(cpu);
pbrook56aebc82008-10-11 17:55:29 +0000882
883 len = 0;
884 while (p[len] && p[len] != ':')
885 len++;
886 *newp = p + len;
887
888 name = NULL;
889 if (strncmp(p, "target.xml", len) == 0) {
Luc Michelc145eea2019-01-07 15:23:46 +0000890 char *buf = process->target_xml;
891 const size_t buf_sz = sizeof(process->target_xml);
pbrook56aebc82008-10-11 17:55:29 +0000892
Luc Michelc145eea2019-01-07 15:23:46 +0000893 /* Generate the XML description for this CPU. */
894 if (!buf[0]) {
895 GDBRegisterState *r;
896
897 pstrcat(buf, buf_sz,
David Hildenbrandb3820e62015-12-03 13:14:41 +0100898 "<?xml version=\"1.0\"?>"
899 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
900 "<target>");
901 if (cc->gdb_arch_name) {
902 gchar *arch = cc->gdb_arch_name(cpu);
Luc Michelc145eea2019-01-07 15:23:46 +0000903 pstrcat(buf, buf_sz, "<architecture>");
904 pstrcat(buf, buf_sz, arch);
905 pstrcat(buf, buf_sz, "</architecture>");
David Hildenbrandb3820e62015-12-03 13:14:41 +0100906 g_free(arch);
907 }
Luc Michelc145eea2019-01-07 15:23:46 +0000908 pstrcat(buf, buf_sz, "<xi:include href=\"");
909 pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
910 pstrcat(buf, buf_sz, "\"/>");
Andreas Färbereac8b352013-06-28 21:11:37 +0200911 for (r = cpu->gdb_regs; r; r = r->next) {
Luc Michelc145eea2019-01-07 15:23:46 +0000912 pstrcat(buf, buf_sz, "<xi:include href=\"");
913 pstrcat(buf, buf_sz, r->xml);
914 pstrcat(buf, buf_sz, "\"/>");
pbrook56aebc82008-10-11 17:55:29 +0000915 }
Luc Michelc145eea2019-01-07 15:23:46 +0000916 pstrcat(buf, buf_sz, "</target>");
pbrook56aebc82008-10-11 17:55:29 +0000917 }
Luc Michelc145eea2019-01-07 15:23:46 +0000918 return buf;
pbrook56aebc82008-10-11 17:55:29 +0000919 }
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100920 if (cc->gdb_get_dynamic_xml) {
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100921 char *xmlname = g_strndup(p, len);
922 const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
923
924 g_free(xmlname);
925 if (xml) {
926 return xml;
927 }
928 }
pbrook56aebc82008-10-11 17:55:29 +0000929 for (i = 0; ; i++) {
930 name = xml_builtin[i][0];
931 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
932 break;
933 }
934 return name ? xml_builtin[i][1] : NULL;
935}
pbrook56aebc82008-10-11 17:55:29 +0000936
Alex Bennéea010bdb2020-03-16 17:21:41 +0000937static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000938{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200939 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200940 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000941 GDBRegisterState *r;
942
Andreas Färbera0e372f2013-06-28 23:18:47 +0200943 if (reg < cc->gdb_num_core_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000944 return cc->gdb_read_register(cpu, buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200945 }
pbrook56aebc82008-10-11 17:55:29 +0000946
Andreas Färbereac8b352013-06-28 21:11:37 +0200947 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000948 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000949 return r->get_reg(env, buf, reg - r->base_reg);
pbrook56aebc82008-10-11 17:55:29 +0000950 }
951 }
952 return 0;
953}
954
Andreas Färber385b9f02013-06-27 18:25:36 +0200955static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000956{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200957 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200958 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000959 GDBRegisterState *r;
960
Andreas Färbera0e372f2013-06-28 23:18:47 +0200961 if (reg < cc->gdb_num_core_regs) {
Andreas Färber5b50e792013-06-29 04:18:45 +0200962 return cc->gdb_write_register(cpu, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200963 }
pbrook56aebc82008-10-11 17:55:29 +0000964
Andreas Färbereac8b352013-06-28 21:11:37 +0200965 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000966 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
967 return r->set_reg(env, mem_buf, reg - r->base_reg);
968 }
969 }
970 return 0;
971}
972
973/* Register a supplemental set of CPU registers. If g_pos is nonzero it
974 specifies the first register number and these registers are included in
975 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
976 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
977 */
978
Andreas Färber22169d42013-06-28 21:27:39 +0200979void gdb_register_coprocessor(CPUState *cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +0000980 gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
Andreas Färber22169d42013-06-28 21:27:39 +0200981 int num_regs, const char *xml, int g_pos)
pbrook56aebc82008-10-11 17:55:29 +0000982{
983 GDBRegisterState *s;
984 GDBRegisterState **p;
pbrook56aebc82008-10-11 17:55:29 +0000985
Andreas Färbereac8b352013-06-28 21:11:37 +0200986 p = &cpu->gdb_regs;
pbrook56aebc82008-10-11 17:55:29 +0000987 while (*p) {
988 /* Check for duplicates. */
989 if (strcmp((*p)->xml, xml) == 0)
990 return;
991 p = &(*p)->next;
992 }
Stefan Weil9643c252011-10-18 22:25:38 +0200993
994 s = g_new0(GDBRegisterState, 1);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200995 s->base_reg = cpu->gdb_num_regs;
Stefan Weil9643c252011-10-18 22:25:38 +0200996 s->num_regs = num_regs;
997 s->get_reg = get_reg;
998 s->set_reg = set_reg;
999 s->xml = xml;
1000
pbrook56aebc82008-10-11 17:55:29 +00001001 /* Add to end of list. */
Andreas Färbera0e372f2013-06-28 23:18:47 +02001002 cpu->gdb_num_regs += num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001003 *p = s;
1004 if (g_pos) {
1005 if (g_pos != s->base_reg) {
Ziyue Yang7ae6c572017-01-18 16:03:29 +08001006 error_report("Error: Bad gdb register numbering for '%s', "
1007 "expected %d got %d", xml, g_pos, s->base_reg);
Andreas Färber35143f02013-08-12 18:09:47 +02001008 } else {
1009 cpu->gdb_num_g_regs = cpu->gdb_num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001010 }
1011 }
1012}
1013
aliguoria1d1bb32008-11-18 20:07:32 +00001014#ifndef CONFIG_USER_ONLY
Peter Maydell2472b6c2014-09-12 19:04:17 +01001015/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
1016static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
1017{
1018 static const int xlat[] = {
1019 [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
1020 [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
1021 [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1022 };
1023
1024 CPUClass *cc = CPU_GET_CLASS(cpu);
1025 int cputype = xlat[gdbtype];
1026
1027 if (cc->gdb_stop_before_watchpoint) {
1028 cputype |= BP_STOP_BEFORE_ACCESS;
1029 }
1030 return cputype;
1031}
aliguoria1d1bb32008-11-18 20:07:32 +00001032#endif
1033
Jon Doron77f6ce52019-05-29 09:41:35 +03001034static int gdb_breakpoint_insert(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001035{
Andreas Färber182735e2013-05-29 22:29:20 +02001036 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001037 int err = 0;
1038
Andreas Färber62278812013-06-27 17:12:06 +02001039 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001040 return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001041 }
aliguorie22a25c2009-03-12 20:12:48 +00001042
aliguoria1d1bb32008-11-18 20:07:32 +00001043 switch (type) {
1044 case GDB_BREAKPOINT_SW:
1045 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001046 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001047 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
1048 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001049 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001050 }
aliguori880a7572008-11-18 20:30:24 +00001051 }
1052 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001053#ifndef CONFIG_USER_ONLY
1054 case GDB_WATCHPOINT_WRITE:
1055 case GDB_WATCHPOINT_READ:
1056 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001057 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001058 err = cpu_watchpoint_insert(cpu, addr, len,
1059 xlat_gdb_type(cpu, type), NULL);
1060 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001061 break;
Peter Maydell2472b6c2014-09-12 19:04:17 +01001062 }
aliguori880a7572008-11-18 20:30:24 +00001063 }
1064 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001065#endif
1066 default:
1067 return -ENOSYS;
1068 }
1069}
1070
Jon Doron77f6ce52019-05-29 09:41:35 +03001071static int gdb_breakpoint_remove(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001072{
Andreas Färber182735e2013-05-29 22:29:20 +02001073 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001074 int err = 0;
1075
Andreas Färber62278812013-06-27 17:12:06 +02001076 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001077 return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001078 }
aliguorie22a25c2009-03-12 20:12:48 +00001079
aliguoria1d1bb32008-11-18 20:07:32 +00001080 switch (type) {
1081 case GDB_BREAKPOINT_SW:
1082 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001083 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001084 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
1085 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001086 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001087 }
aliguori880a7572008-11-18 20:30:24 +00001088 }
1089 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001090#ifndef CONFIG_USER_ONLY
1091 case GDB_WATCHPOINT_WRITE:
1092 case GDB_WATCHPOINT_READ:
1093 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001094 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001095 err = cpu_watchpoint_remove(cpu, addr, len,
1096 xlat_gdb_type(cpu, type));
aliguori880a7572008-11-18 20:30:24 +00001097 if (err)
1098 break;
1099 }
1100 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001101#endif
1102 default:
1103 return -ENOSYS;
1104 }
1105}
1106
Luc Michel546f3c62019-01-07 15:23:46 +00001107static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
1108{
1109 cpu_breakpoint_remove_all(cpu, BP_GDB);
1110#ifndef CONFIG_USER_ONLY
1111 cpu_watchpoint_remove_all(cpu, BP_GDB);
1112#endif
1113}
1114
Alex Bennéea346af32020-03-16 17:21:34 +00001115static void gdb_process_breakpoint_remove_all(GDBProcess *p)
Luc Michel546f3c62019-01-07 15:23:46 +00001116{
Alex Bennéea346af32020-03-16 17:21:34 +00001117 CPUState *cpu = get_first_cpu_in_process(p);
Luc Michel546f3c62019-01-07 15:23:46 +00001118
1119 while (cpu) {
1120 gdb_cpu_breakpoint_remove_all(cpu);
Alex Bennéea346af32020-03-16 17:21:34 +00001121 cpu = gdb_next_cpu_in_process(cpu);
Luc Michel546f3c62019-01-07 15:23:46 +00001122 }
1123}
1124
aliguori880a7572008-11-18 20:30:24 +00001125static void gdb_breakpoint_remove_all(void)
aliguoria1d1bb32008-11-18 20:07:32 +00001126{
Andreas Färber182735e2013-05-29 22:29:20 +02001127 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001128
aliguorie22a25c2009-03-12 20:12:48 +00001129 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001130 kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
aliguorie22a25c2009-03-12 20:12:48 +00001131 return;
1132 }
1133
Andreas Färberbdc44642013-06-24 23:50:24 +02001134 CPU_FOREACH(cpu) {
Luc Michel546f3c62019-01-07 15:23:46 +00001135 gdb_cpu_breakpoint_remove_all(cpu);
aliguori880a7572008-11-18 20:30:24 +00001136 }
aliguoria1d1bb32008-11-18 20:07:32 +00001137}
1138
Alex Bennéea346af32020-03-16 17:21:34 +00001139static void gdb_set_cpu_pc(target_ulong pc)
aurel32fab9d282009-04-08 21:29:37 +00001140{
Alex Bennéea346af32020-03-16 17:21:34 +00001141 CPUState *cpu = gdbserver_state.c_cpu;
Andreas Färberf45748f2013-06-21 19:09:18 +02001142
1143 cpu_synchronize_state(cpu);
Peter Crosthwaite4a2b24e2015-06-23 20:19:21 -07001144 cpu_set_pc(cpu, pc);
aurel32fab9d282009-04-08 21:29:37 +00001145}
1146
Alex Bennée308f9e82020-03-16 17:21:35 +00001147static void gdb_append_thread_id(CPUState *cpu, GString *buf)
Luc Michel1a227332019-01-07 15:23:45 +00001148{
Alex Bennéea346af32020-03-16 17:21:34 +00001149 if (gdbserver_state.multiprocess) {
Alex Bennée308f9e82020-03-16 17:21:35 +00001150 g_string_append_printf(buf, "p%02x.%02x",
1151 gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001152 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00001153 g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001154 }
Luc Michel1a227332019-01-07 15:23:45 +00001155}
1156
Luc Michel7d8c87d2019-01-07 15:23:45 +00001157typedef enum GDBThreadIdKind {
1158 GDB_ONE_THREAD = 0,
1159 GDB_ALL_THREADS, /* One process, all threads */
1160 GDB_ALL_PROCESSES,
1161 GDB_READ_THREAD_ERR
1162} GDBThreadIdKind;
1163
1164static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
1165 uint32_t *pid, uint32_t *tid)
1166{
1167 unsigned long p, t;
1168 int ret;
1169
1170 if (*buf == 'p') {
1171 buf++;
1172 ret = qemu_strtoul(buf, &buf, 16, &p);
1173
1174 if (ret) {
1175 return GDB_READ_THREAD_ERR;
1176 }
1177
1178 /* Skip '.' */
1179 buf++;
1180 } else {
1181 p = 1;
1182 }
1183
1184 ret = qemu_strtoul(buf, &buf, 16, &t);
1185
1186 if (ret) {
1187 return GDB_READ_THREAD_ERR;
1188 }
1189
1190 *end_buf = buf;
1191
1192 if (p == -1) {
1193 return GDB_ALL_PROCESSES;
1194 }
1195
1196 if (pid) {
1197 *pid = p;
1198 }
1199
1200 if (t == -1) {
1201 return GDB_ALL_THREADS;
1202 }
1203
1204 if (tid) {
1205 *tid = t;
1206 }
1207
1208 return GDB_ONE_THREAD;
1209}
1210
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001211/**
1212 * gdb_handle_vcont - Parses and handles a vCont packet.
1213 * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1214 * a format error, 0 on success.
1215 */
Alex Bennéea346af32020-03-16 17:21:34 +00001216static int gdb_handle_vcont(const char *p)
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001217{
Luc Michele40e5202019-01-07 15:23:46 +00001218 int res, signal = 0;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001219 char cur_action;
1220 char *newstates;
1221 unsigned long tmp;
Luc Michele40e5202019-01-07 15:23:46 +00001222 uint32_t pid, tid;
1223 GDBProcess *process;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001224 CPUState *cpu;
Luc Michelc99ef792019-03-26 12:53:26 +00001225 GDBThreadIdKind kind;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001226#ifdef CONFIG_USER_ONLY
1227 int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1228
1229 CPU_FOREACH(cpu) {
1230 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1231 }
Like Xu5cc87672019-05-19 04:54:21 +08001232#else
1233 MachineState *ms = MACHINE(qdev_get_machine());
1234 unsigned int max_cpus = ms->smp.max_cpus;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001235#endif
1236 /* uninitialised CPUs stay 0 */
1237 newstates = g_new0(char, max_cpus);
1238
1239 /* mark valid CPUs with 1 */
1240 CPU_FOREACH(cpu) {
1241 newstates[cpu->cpu_index] = 1;
1242 }
1243
1244 /*
1245 * res keeps track of what error we are returning, with -ENOTSUP meaning
1246 * that the command is unknown or unsupported, thus returning an empty
1247 * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1248 * or incorrect parameters passed.
1249 */
1250 res = 0;
1251 while (*p) {
1252 if (*p++ != ';') {
1253 res = -ENOTSUP;
1254 goto out;
1255 }
1256
1257 cur_action = *p++;
1258 if (cur_action == 'C' || cur_action == 'S') {
Peter Maydell95a5bef2017-07-20 17:31:30 +01001259 cur_action = qemu_tolower(cur_action);
Peter Maydell3ddd9032020-11-21 21:03:42 +00001260 res = qemu_strtoul(p, &p, 16, &tmp);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001261 if (res) {
1262 goto out;
1263 }
1264 signal = gdb_signal_to_target(tmp);
1265 } else if (cur_action != 'c' && cur_action != 's') {
1266 /* unknown/invalid/unsupported command */
1267 res = -ENOTSUP;
1268 goto out;
1269 }
Luc Michele40e5202019-01-07 15:23:46 +00001270
Luc Michelc99ef792019-03-26 12:53:26 +00001271 if (*p == '\0' || *p == ';') {
1272 /*
1273 * No thread specifier, action is on "all threads". The
1274 * specification is unclear regarding the process to act on. We
1275 * choose all processes.
1276 */
1277 kind = GDB_ALL_PROCESSES;
1278 } else if (*p++ == ':') {
1279 kind = read_thread_id(p, &p, &pid, &tid);
1280 } else {
Luc Michele40e5202019-01-07 15:23:46 +00001281 res = -ENOTSUP;
1282 goto out;
1283 }
1284
Luc Michelc99ef792019-03-26 12:53:26 +00001285 switch (kind) {
Luc Michele40e5202019-01-07 15:23:46 +00001286 case GDB_READ_THREAD_ERR:
1287 res = -EINVAL;
1288 goto out;
1289
1290 case GDB_ALL_PROCESSES:
Alex Bennéea346af32020-03-16 17:21:34 +00001291 cpu = gdb_first_attached_cpu();
Luc Michele40e5202019-01-07 15:23:46 +00001292 while (cpu) {
1293 if (newstates[cpu->cpu_index] == 1) {
1294 newstates[cpu->cpu_index] = cur_action;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001295 }
Luc Michele40e5202019-01-07 15:23:46 +00001296
Alex Bennéea346af32020-03-16 17:21:34 +00001297 cpu = gdb_next_attached_cpu(cpu);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001298 }
Luc Michele40e5202019-01-07 15:23:46 +00001299 break;
1300
1301 case GDB_ALL_THREADS:
Alex Bennéea346af32020-03-16 17:21:34 +00001302 process = gdb_get_process(pid);
Luc Michele40e5202019-01-07 15:23:46 +00001303
1304 if (!process->attached) {
1305 res = -EINVAL;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001306 goto out;
1307 }
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001308
Alex Bennéea346af32020-03-16 17:21:34 +00001309 cpu = get_first_cpu_in_process(process);
Luc Michele40e5202019-01-07 15:23:46 +00001310 while (cpu) {
1311 if (newstates[cpu->cpu_index] == 1) {
1312 newstates[cpu->cpu_index] = cur_action;
1313 }
1314
Alex Bennéea346af32020-03-16 17:21:34 +00001315 cpu = gdb_next_cpu_in_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +00001316 }
1317 break;
1318
1319 case GDB_ONE_THREAD:
Alex Bennéea346af32020-03-16 17:21:34 +00001320 cpu = gdb_get_cpu(pid, tid);
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001321
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001322 /* invalid CPU/thread specified */
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001323 if (!cpu) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001324 res = -EINVAL;
1325 goto out;
1326 }
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001327
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001328 /* only use if no previous match occourred */
1329 if (newstates[cpu->cpu_index] == 1) {
1330 newstates[cpu->cpu_index] = cur_action;
1331 }
Luc Michele40e5202019-01-07 15:23:46 +00001332 break;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001333 }
1334 }
Alex Bennéea346af32020-03-16 17:21:34 +00001335 gdbserver_state.signal = signal;
1336 gdb_continue_partial(newstates);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001337
1338out:
1339 g_free(newstates);
1340
1341 return res;
1342}
1343
Jon Dorond14055d2019-05-29 09:41:29 +03001344typedef union GdbCmdVariant {
1345 const char *data;
1346 uint8_t opcode;
1347 unsigned long val_ul;
1348 unsigned long long val_ull;
1349 struct {
1350 GDBThreadIdKind kind;
1351 uint32_t pid;
1352 uint32_t tid;
1353 } thread_id;
1354} GdbCmdVariant;
1355
Alex Bennée26a16182021-05-25 09:24:14 +01001356#define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
1357
Jon Dorond14055d2019-05-29 09:41:29 +03001358static const char *cmd_next_param(const char *param, const char delimiter)
1359{
1360 static const char all_delimiters[] = ",;:=";
1361 char curr_delimiters[2] = {0};
1362 const char *delimiters;
1363
1364 if (delimiter == '?') {
1365 delimiters = all_delimiters;
1366 } else if (delimiter == '0') {
1367 return strchr(param, '\0');
1368 } else if (delimiter == '.' && *param) {
1369 return param + 1;
1370 } else {
1371 curr_delimiters[0] = delimiter;
1372 delimiters = curr_delimiters;
1373 }
1374
1375 param += strcspn(param, delimiters);
1376 if (*param) {
1377 param++;
1378 }
1379 return param;
1380}
1381
1382static int cmd_parse_params(const char *data, const char *schema,
Alex Bennée26a16182021-05-25 09:24:14 +01001383 GArray *params)
Jon Dorond14055d2019-05-29 09:41:29 +03001384{
Jon Dorond14055d2019-05-29 09:41:29 +03001385 const char *curr_schema, *curr_data;
1386
Alex Bennée26a16182021-05-25 09:24:14 +01001387 g_assert(schema);
1388 g_assert(params->len == 0);
Jon Dorond14055d2019-05-29 09:41:29 +03001389
1390 curr_schema = schema;
Jon Dorond14055d2019-05-29 09:41:29 +03001391 curr_data = data;
1392 while (curr_schema[0] && curr_schema[1] && *curr_data) {
Alex Bennée26a16182021-05-25 09:24:14 +01001393 GdbCmdVariant this_param;
1394
Jon Dorond14055d2019-05-29 09:41:29 +03001395 switch (curr_schema[0]) {
1396 case 'l':
1397 if (qemu_strtoul(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001398 &this_param.val_ul)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001399 return -EINVAL;
1400 }
Jon Dorond14055d2019-05-29 09:41:29 +03001401 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001402 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001403 break;
1404 case 'L':
1405 if (qemu_strtou64(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001406 (uint64_t *)&this_param.val_ull)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001407 return -EINVAL;
1408 }
Jon Dorond14055d2019-05-29 09:41:29 +03001409 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001410 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001411 break;
1412 case 's':
Alex Bennée26a16182021-05-25 09:24:14 +01001413 this_param.data = curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001414 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001415 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001416 break;
1417 case 'o':
Alex Bennée26a16182021-05-25 09:24:14 +01001418 this_param.opcode = *(uint8_t *)curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001419 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001420 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001421 break;
1422 case 't':
Alex Bennée26a16182021-05-25 09:24:14 +01001423 this_param.thread_id.kind =
Jon Dorond14055d2019-05-29 09:41:29 +03001424 read_thread_id(curr_data, &curr_data,
Alex Bennée26a16182021-05-25 09:24:14 +01001425 &this_param.thread_id.pid,
1426 &this_param.thread_id.tid);
Jon Dorond14055d2019-05-29 09:41:29 +03001427 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001428 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001429 break;
1430 case '?':
1431 curr_data = cmd_next_param(curr_data, curr_schema[1]);
1432 break;
1433 default:
1434 return -EINVAL;
1435 }
1436 curr_schema += 2;
1437 }
1438
Jon Dorond14055d2019-05-29 09:41:29 +03001439 return 0;
1440}
1441
Alex Bennée26a16182021-05-25 09:24:14 +01001442typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001443
1444/*
1445 * cmd_startswith -> cmd is compared using startswith
1446 *
1447 *
1448 * schema definitions:
1449 * Each schema parameter entry consists of 2 chars,
1450 * the first char represents the parameter type handling
1451 * the second char represents the delimiter for the next parameter
1452 *
1453 * Currently supported schema types:
1454 * 'l' -> unsigned long (stored in .val_ul)
1455 * 'L' -> unsigned long long (stored in .val_ull)
1456 * 's' -> string (stored in .data)
1457 * 'o' -> single char (stored in .opcode)
1458 * 't' -> thread id (stored in .thread_id)
1459 * '?' -> skip according to delimiter
1460 *
1461 * Currently supported delimiters:
1462 * '?' -> Stop at any delimiter (",;:=\0")
1463 * '0' -> Stop at "\0"
1464 * '.' -> Skip 1 char unless reached "\0"
1465 * Any other value is treated as the delimiter value itself
1466 */
1467typedef struct GdbCmdParseEntry {
1468 GdbCmdHandler handler;
1469 const char *cmd;
1470 bool cmd_startswith;
1471 const char *schema;
1472} GdbCmdParseEntry;
1473
1474static inline int startswith(const char *string, const char *pattern)
1475{
1476 return !strncmp(string, pattern, strlen(pattern));
1477}
1478
Alex Bennéea346af32020-03-16 17:21:34 +00001479static int process_string_cmd(void *user_ctx, const char *data,
Jon Dorond14055d2019-05-29 09:41:29 +03001480 const GdbCmdParseEntry *cmds, int num_cmds)
1481{
Alex Bennée26a16182021-05-25 09:24:14 +01001482 int i;
1483 g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
Jon Dorond14055d2019-05-29 09:41:29 +03001484
1485 if (!cmds) {
1486 return -1;
1487 }
1488
1489 for (i = 0; i < num_cmds; i++) {
1490 const GdbCmdParseEntry *cmd = &cmds[i];
1491 g_assert(cmd->handler && cmd->cmd);
1492
1493 if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1494 (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1495 continue;
1496 }
1497
1498 if (cmd->schema) {
Alex Bennée26a16182021-05-25 09:24:14 +01001499 if (cmd_parse_params(&data[strlen(cmd->cmd)],
1500 cmd->schema, params)) {
1501 return -1;
Jon Dorond14055d2019-05-29 09:41:29 +03001502 }
Jon Dorond14055d2019-05-29 09:41:29 +03001503 }
1504
Alex Bennée26a16182021-05-25 09:24:14 +01001505 cmd->handler(params, user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001506 return 0;
1507 }
1508
1509 return -1;
1510}
1511
Alex Bennéea346af32020-03-16 17:21:34 +00001512static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
Jon Doron3e2c1262019-05-29 09:41:30 +03001513{
1514 if (!data) {
1515 return;
1516 }
1517
Alex Bennée308f9e82020-03-16 17:21:35 +00001518 g_string_set_size(gdbserver_state.str_buf, 0);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001519 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Alex Bennée308f9e82020-03-16 17:21:35 +00001520
Jon Doron3e2c1262019-05-29 09:41:30 +03001521 /* In case there was an error during the command parsing we must
1522 * send a NULL packet to indicate the command is not supported */
Alex Bennéea346af32020-03-16 17:21:34 +00001523 if (process_string_cmd(NULL, data, cmd, 1)) {
1524 put_packet("");
Jon Doron3e2c1262019-05-29 09:41:30 +03001525 }
1526}
1527
Alex Bennée26a16182021-05-25 09:24:14 +01001528static void handle_detach(GArray *params, void *user_ctx)
Jon Doron3e2c1262019-05-29 09:41:30 +03001529{
1530 GDBProcess *process;
Jon Doron3e2c1262019-05-29 09:41:30 +03001531 uint32_t pid = 1;
1532
Alex Bennéea346af32020-03-16 17:21:34 +00001533 if (gdbserver_state.multiprocess) {
Alex Bennée26a16182021-05-25 09:24:14 +01001534 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001535 put_packet("E22");
Jon Doron3e2c1262019-05-29 09:41:30 +03001536 return;
1537 }
1538
Alex Bennée26a16182021-05-25 09:24:14 +01001539 pid = get_param(params, 0)->val_ul;
Jon Doron3e2c1262019-05-29 09:41:30 +03001540 }
1541
Alex Bennéea346af32020-03-16 17:21:34 +00001542 process = gdb_get_process(pid);
1543 gdb_process_breakpoint_remove_all(process);
Jon Doron3e2c1262019-05-29 09:41:30 +03001544 process->attached = false;
1545
Alex Bennéea346af32020-03-16 17:21:34 +00001546 if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1547 gdbserver_state.c_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001548 }
1549
Alex Bennéea346af32020-03-16 17:21:34 +00001550 if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1551 gdbserver_state.g_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001552 }
1553
Alex Bennéea346af32020-03-16 17:21:34 +00001554 if (!gdbserver_state.c_cpu) {
Jon Doron3e2c1262019-05-29 09:41:30 +03001555 /* No more process attached */
1556 gdb_syscall_mode = GDB_SYS_DISABLED;
Alex Bennéea346af32020-03-16 17:21:34 +00001557 gdb_continue();
Jon Doron3e2c1262019-05-29 09:41:30 +03001558 }
Alex Bennéea346af32020-03-16 17:21:34 +00001559 put_packet("OK");
Jon Doron3e2c1262019-05-29 09:41:30 +03001560}
1561
Alex Bennée26a16182021-05-25 09:24:14 +01001562static void handle_thread_alive(GArray *params, void *user_ctx)
Jon Doron44ffded2019-05-29 09:41:31 +03001563{
1564 CPUState *cpu;
1565
Alex Bennée26a16182021-05-25 09:24:14 +01001566 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001567 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001568 return;
1569 }
1570
Alex Bennée26a16182021-05-25 09:24:14 +01001571 if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001572 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001573 return;
1574 }
1575
Alex Bennée26a16182021-05-25 09:24:14 +01001576 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1577 get_param(params, 0)->thread_id.tid);
Jon Doron44ffded2019-05-29 09:41:31 +03001578 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001579 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001580 return;
1581 }
1582
Alex Bennéea346af32020-03-16 17:21:34 +00001583 put_packet("OK");
Jon Doron44ffded2019-05-29 09:41:31 +03001584}
1585
Alex Bennée26a16182021-05-25 09:24:14 +01001586static void handle_continue(GArray *params, void *user_ctx)
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001587{
Alex Bennée26a16182021-05-25 09:24:14 +01001588 if (params->len) {
1589 gdb_set_cpu_pc(get_param(params, 0)->val_ull);
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001590 }
1591
Alex Bennéea346af32020-03-16 17:21:34 +00001592 gdbserver_state.signal = 0;
1593 gdb_continue();
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001594}
1595
Alex Bennée26a16182021-05-25 09:24:14 +01001596static void handle_cont_with_sig(GArray *params, void *user_ctx)
Jon Doronccc47d52019-05-29 09:41:33 +03001597{
1598 unsigned long signal = 0;
1599
1600 /*
1601 * Note: C sig;[addr] is currently unsupported and we simply
1602 * omit the addr parameter
1603 */
Alex Bennée26a16182021-05-25 09:24:14 +01001604 if (params->len) {
1605 signal = get_param(params, 0)->val_ul;
Jon Doronccc47d52019-05-29 09:41:33 +03001606 }
1607
Alex Bennéea346af32020-03-16 17:21:34 +00001608 gdbserver_state.signal = gdb_signal_to_target(signal);
1609 if (gdbserver_state.signal == -1) {
1610 gdbserver_state.signal = 0;
Jon Doronccc47d52019-05-29 09:41:33 +03001611 }
Alex Bennéea346af32020-03-16 17:21:34 +00001612 gdb_continue();
Jon Doronccc47d52019-05-29 09:41:33 +03001613}
1614
Alex Bennée26a16182021-05-25 09:24:14 +01001615static void handle_set_thread(GArray *params, void *user_ctx)
Jon Doron3a9651d2019-05-29 09:41:34 +03001616{
1617 CPUState *cpu;
1618
Alex Bennée26a16182021-05-25 09:24:14 +01001619 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001620 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001621 return;
1622 }
1623
Alex Bennée26a16182021-05-25 09:24:14 +01001624 if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001625 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001626 return;
1627 }
1628
Alex Bennée26a16182021-05-25 09:24:14 +01001629 if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
Alex Bennéea346af32020-03-16 17:21:34 +00001630 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001631 return;
1632 }
1633
Alex Bennée26a16182021-05-25 09:24:14 +01001634 cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1635 get_param(params, 1)->thread_id.tid);
Jon Doron3a9651d2019-05-29 09:41:34 +03001636 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001637 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001638 return;
1639 }
1640
1641 /*
1642 * Note: This command is deprecated and modern gdb's will be using the
1643 * vCont command instead.
1644 */
Alex Bennée26a16182021-05-25 09:24:14 +01001645 switch (get_param(params, 0)->opcode) {
Jon Doron3a9651d2019-05-29 09:41:34 +03001646 case 'c':
Alex Bennéea346af32020-03-16 17:21:34 +00001647 gdbserver_state.c_cpu = cpu;
1648 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001649 break;
1650 case 'g':
Alex Bennéea346af32020-03-16 17:21:34 +00001651 gdbserver_state.g_cpu = cpu;
1652 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001653 break;
1654 default:
Alex Bennéea346af32020-03-16 17:21:34 +00001655 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001656 break;
1657 }
1658}
1659
Alex Bennée26a16182021-05-25 09:24:14 +01001660static void handle_insert_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001661{
1662 int res;
1663
Alex Bennée26a16182021-05-25 09:24:14 +01001664 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001665 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001666 return;
1667 }
1668
Alex Bennée26a16182021-05-25 09:24:14 +01001669 res = gdb_breakpoint_insert(get_param(params, 0)->val_ul,
1670 get_param(params, 1)->val_ull,
1671 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001672 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001673 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001674 return;
1675 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001676 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001677 return;
1678 }
1679
Alex Bennéea346af32020-03-16 17:21:34 +00001680 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001681}
1682
Alex Bennée26a16182021-05-25 09:24:14 +01001683static void handle_remove_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001684{
1685 int res;
1686
Alex Bennée26a16182021-05-25 09:24:14 +01001687 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001688 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001689 return;
1690 }
1691
Alex Bennée26a16182021-05-25 09:24:14 +01001692 res = gdb_breakpoint_remove(get_param(params, 0)->val_ul,
1693 get_param(params, 1)->val_ull,
1694 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001695 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001696 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001697 return;
1698 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001699 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001700 return;
1701 }
1702
Alex Bennéea346af32020-03-16 17:21:34 +00001703 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001704}
1705
Alex Bennée94b2a622019-07-05 14:23:07 +01001706/*
1707 * handle_set/get_reg
1708 *
1709 * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1710 * This works, but can be very slow. Anything new enough to understand
1711 * XML also knows how to use this properly. However to use this we
1712 * need to define a local XML file as well as be talking to a
1713 * reasonably modern gdb. Responding with an empty packet will cause
1714 * the remote gdb to fallback to older methods.
1715 */
1716
Alex Bennée26a16182021-05-25 09:24:14 +01001717static void handle_set_reg(GArray *params, void *user_ctx)
Jon Doron62b33202019-05-29 09:41:36 +03001718{
1719 int reg_size;
1720
1721 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001722 put_packet("");
Jon Doron62b33202019-05-29 09:41:36 +03001723 return;
1724 }
1725
Alex Bennée26a16182021-05-25 09:24:14 +01001726 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001727 put_packet("E22");
Jon Doron62b33202019-05-29 09:41:36 +03001728 return;
1729 }
1730
Alex Bennée26a16182021-05-25 09:24:14 +01001731 reg_size = strlen(get_param(params, 1)->data) / 2;
1732 hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001733 gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
Alex Bennée26a16182021-05-25 09:24:14 +01001734 get_param(params, 0)->val_ull);
Alex Bennéea346af32020-03-16 17:21:34 +00001735 put_packet("OK");
Jon Doron62b33202019-05-29 09:41:36 +03001736}
1737
Alex Bennée26a16182021-05-25 09:24:14 +01001738static void handle_get_reg(GArray *params, void *user_ctx)
Jon Doron5d0e57b2019-05-29 09:41:37 +03001739{
1740 int reg_size;
1741
Jon Doron5d0e57b2019-05-29 09:41:37 +03001742 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001743 put_packet("");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001744 return;
1745 }
1746
Alex Bennée26a16182021-05-25 09:24:14 +01001747 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001748 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001749 return;
1750 }
1751
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001752 reg_size = gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001753 gdbserver_state.mem_buf,
Alex Bennée26a16182021-05-25 09:24:14 +01001754 get_param(params, 0)->val_ull);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001755 if (!reg_size) {
Alex Bennéea346af32020-03-16 17:21:34 +00001756 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001757 return;
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001758 } else {
1759 g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001760 }
1761
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001762 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
Alex Bennée308f9e82020-03-16 17:21:35 +00001763 put_strbuf();
Jon Doron5d0e57b2019-05-29 09:41:37 +03001764}
1765
Alex Bennée26a16182021-05-25 09:24:14 +01001766static void handle_write_mem(GArray *params, void *user_ctx)
Jon Doroncc0ecc72019-05-29 09:41:38 +03001767{
Alex Bennée26a16182021-05-25 09:24:14 +01001768 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001769 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001770 return;
1771 }
1772
1773 /* hextomem() reads 2*len bytes */
Alex Bennée26a16182021-05-25 09:24:14 +01001774 if (get_param(params, 1)->val_ull >
1775 strlen(get_param(params, 2)->data) / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001776 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001777 return;
1778 }
1779
Alex Bennée26a16182021-05-25 09:24:14 +01001780 hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1781 get_param(params, 1)->val_ull);
1782 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1783 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001784 gdbserver_state.mem_buf->data,
1785 gdbserver_state.mem_buf->len, true)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001786 put_packet("E14");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001787 return;
1788 }
1789
Alex Bennéea346af32020-03-16 17:21:34 +00001790 put_packet("OK");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001791}
1792
Alex Bennée26a16182021-05-25 09:24:14 +01001793static void handle_read_mem(GArray *params, void *user_ctx)
Jon Doronda92e232019-05-29 09:41:39 +03001794{
Alex Bennée26a16182021-05-25 09:24:14 +01001795 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001796 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001797 return;
1798 }
1799
1800 /* memtohex() doubles the required space */
Alex Bennée26a16182021-05-25 09:24:14 +01001801 if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001802 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001803 return;
1804 }
1805
Alex Bennée26a16182021-05-25 09:24:14 +01001806 g_byte_array_set_size(gdbserver_state.mem_buf,
1807 get_param(params, 1)->val_ull);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001808
Alex Bennée26a16182021-05-25 09:24:14 +01001809 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1810 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001811 gdbserver_state.mem_buf->data,
1812 gdbserver_state.mem_buf->len, false)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001813 put_packet("E14");
Jon Doronda92e232019-05-29 09:41:39 +03001814 return;
1815 }
1816
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001817 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1818 gdbserver_state.mem_buf->len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001819 put_strbuf();
Jon Doronda92e232019-05-29 09:41:39 +03001820}
1821
Alex Bennée26a16182021-05-25 09:24:14 +01001822static void handle_write_all_regs(GArray *params, void *user_ctx)
Jon Doron287ca122019-05-29 09:41:40 +03001823{
1824 target_ulong addr, len;
1825 uint8_t *registers;
1826 int reg_size;
1827
Alex Bennée26a16182021-05-25 09:24:14 +01001828 if (!params->len) {
Jon Doron287ca122019-05-29 09:41:40 +03001829 return;
1830 }
1831
Alex Bennéea346af32020-03-16 17:21:34 +00001832 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennée26a16182021-05-25 09:24:14 +01001833 len = strlen(get_param(params, 0)->data) / 2;
1834 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001835 registers = gdbserver_state.mem_buf->data;
Alex Bennéea346af32020-03-16 17:21:34 +00001836 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
Jon Doron287ca122019-05-29 09:41:40 +03001837 addr++) {
Alex Bennéea346af32020-03-16 17:21:34 +00001838 reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
Jon Doron287ca122019-05-29 09:41:40 +03001839 len -= reg_size;
1840 registers += reg_size;
1841 }
Alex Bennéea346af32020-03-16 17:21:34 +00001842 put_packet("OK");
Jon Doron287ca122019-05-29 09:41:40 +03001843}
1844
Alex Bennée26a16182021-05-25 09:24:14 +01001845static void handle_read_all_regs(GArray *params, void *user_ctx)
Jon Doron397d1372019-05-29 09:41:41 +03001846{
1847 target_ulong addr, len;
1848
Alex Bennéea346af32020-03-16 17:21:34 +00001849 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennéea010bdb2020-03-16 17:21:41 +00001850 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Jon Doron397d1372019-05-29 09:41:41 +03001851 len = 0;
Alex Bennéea346af32020-03-16 17:21:34 +00001852 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001853 len += gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001854 gdbserver_state.mem_buf,
Jon Doron397d1372019-05-29 09:41:41 +03001855 addr);
1856 }
Alex Bennéea010bdb2020-03-16 17:21:41 +00001857 g_assert(len == gdbserver_state.mem_buf->len);
Jon Doron397d1372019-05-29 09:41:41 +03001858
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001859 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001860 put_strbuf();
Jon Doron397d1372019-05-29 09:41:41 +03001861}
1862
Alex Bennée26a16182021-05-25 09:24:14 +01001863static void handle_file_io(GArray *params, void *user_ctx)
Jon Doron4b20fab2019-05-29 09:41:42 +03001864{
Alex Bennée26a16182021-05-25 09:24:14 +01001865 if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
Jon Doron4b20fab2019-05-29 09:41:42 +03001866 target_ulong ret, err;
1867
Alex Bennée26a16182021-05-25 09:24:14 +01001868 ret = (target_ulong)get_param(params, 0)->val_ull;
1869 if (params->len >= 2) {
1870 err = (target_ulong)get_param(params, 1)->val_ull;
Sandra Loosemorec6ee9522019-08-27 16:33:17 -06001871 } else {
1872 err = 0;
1873 }
Alex Bennéea346af32020-03-16 17:21:34 +00001874 gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1875 gdbserver_state.current_syscall_cb = NULL;
Jon Doron4b20fab2019-05-29 09:41:42 +03001876 }
1877
Alex Bennée26a16182021-05-25 09:24:14 +01001878 if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
Alex Bennéea346af32020-03-16 17:21:34 +00001879 put_packet("T02");
Jon Doron4b20fab2019-05-29 09:41:42 +03001880 return;
1881 }
1882
Alex Bennéea346af32020-03-16 17:21:34 +00001883 gdb_continue();
Jon Doron4b20fab2019-05-29 09:41:42 +03001884}
1885
Alex Bennée26a16182021-05-25 09:24:14 +01001886static void handle_step(GArray *params, void *user_ctx)
Jon Doron933f80d2019-05-29 09:41:43 +03001887{
Alex Bennée26a16182021-05-25 09:24:14 +01001888 if (params->len) {
1889 gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
Jon Doron933f80d2019-05-29 09:41:43 +03001890 }
1891
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001892 cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
Alex Bennéea346af32020-03-16 17:21:34 +00001893 gdb_continue();
Jon Doron933f80d2019-05-29 09:41:43 +03001894}
1895
Alex Bennée26a16182021-05-25 09:24:14 +01001896static void handle_backward(GArray *params, void *user_ctx)
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001897{
Alex Bennéeed12f5b2021-05-20 18:43:02 +01001898 if (!stub_can_reverse()) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001899 put_packet("E22");
1900 }
Alex Bennée26a16182021-05-25 09:24:14 +01001901 if (params->len == 1) {
1902 switch (get_param(params, 0)->opcode) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001903 case 's':
1904 if (replay_reverse_step()) {
1905 gdb_continue();
1906 } else {
1907 put_packet("E14");
1908 }
1909 return;
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03001910 case 'c':
1911 if (replay_reverse_continue()) {
1912 gdb_continue();
1913 } else {
1914 put_packet("E14");
1915 }
1916 return;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001917 }
1918 }
1919
1920 /* Default invalid command */
1921 put_packet("");
1922}
1923
Alex Bennée26a16182021-05-25 09:24:14 +01001924static void handle_v_cont_query(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001925{
Alex Bennéea346af32020-03-16 17:21:34 +00001926 put_packet("vCont;c;C;s;S");
Jon Doron8536ec02019-05-29 09:41:44 +03001927}
1928
Alex Bennée26a16182021-05-25 09:24:14 +01001929static void handle_v_cont(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001930{
1931 int res;
1932
Alex Bennée26a16182021-05-25 09:24:14 +01001933 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001934 return;
1935 }
1936
Alex Bennée26a16182021-05-25 09:24:14 +01001937 res = gdb_handle_vcont(get_param(params, 0)->data);
Jon Doron8536ec02019-05-29 09:41:44 +03001938 if ((res == -EINVAL) || (res == -ERANGE)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001939 put_packet("E22");
Jon Doron8536ec02019-05-29 09:41:44 +03001940 } else if (res) {
Alex Bennéea346af32020-03-16 17:21:34 +00001941 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03001942 }
1943}
1944
Alex Bennée26a16182021-05-25 09:24:14 +01001945static void handle_v_attach(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001946{
1947 GDBProcess *process;
1948 CPUState *cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001949
Alex Bennée308f9e82020-03-16 17:21:35 +00001950 g_string_assign(gdbserver_state.str_buf, "E22");
Alex Bennée26a16182021-05-25 09:24:14 +01001951 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001952 goto cleanup;
1953 }
1954
Alex Bennée26a16182021-05-25 09:24:14 +01001955 process = gdb_get_process(get_param(params, 0)->val_ul);
Jon Doron8536ec02019-05-29 09:41:44 +03001956 if (!process) {
1957 goto cleanup;
1958 }
1959
Alex Bennéea346af32020-03-16 17:21:34 +00001960 cpu = get_first_cpu_in_process(process);
Jon Doron8536ec02019-05-29 09:41:44 +03001961 if (!cpu) {
1962 goto cleanup;
1963 }
1964
1965 process->attached = true;
Alex Bennéea346af32020-03-16 17:21:34 +00001966 gdbserver_state.g_cpu = cpu;
1967 gdbserver_state.c_cpu = cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001968
Alex Bennée308f9e82020-03-16 17:21:35 +00001969 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
1970 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
1971 g_string_append_c(gdbserver_state.str_buf, ';');
Jon Doron8536ec02019-05-29 09:41:44 +03001972cleanup:
Alex Bennée308f9e82020-03-16 17:21:35 +00001973 put_strbuf();
Jon Doron8536ec02019-05-29 09:41:44 +03001974}
1975
Alex Bennée26a16182021-05-25 09:24:14 +01001976static void handle_v_kill(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001977{
1978 /* Kill the target */
Alex Bennéea346af32020-03-16 17:21:34 +00001979 put_packet("OK");
Jon Doron8536ec02019-05-29 09:41:44 +03001980 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00001981 gdb_exit(0);
Jon Doron8536ec02019-05-29 09:41:44 +03001982 exit(0);
1983}
1984
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01001985static const GdbCmdParseEntry gdb_v_commands_table[] = {
Jon Doron8536ec02019-05-29 09:41:44 +03001986 /* Order is important if has same prefix */
1987 {
1988 .handler = handle_v_cont_query,
1989 .cmd = "Cont?",
1990 .cmd_startswith = 1
1991 },
1992 {
1993 .handler = handle_v_cont,
1994 .cmd = "Cont",
1995 .cmd_startswith = 1,
1996 .schema = "s0"
1997 },
1998 {
1999 .handler = handle_v_attach,
2000 .cmd = "Attach;",
2001 .cmd_startswith = 1,
2002 .schema = "l0"
2003 },
2004 {
2005 .handler = handle_v_kill,
2006 .cmd = "Kill;",
2007 .cmd_startswith = 1
2008 },
2009};
2010
Alex Bennée26a16182021-05-25 09:24:14 +01002011static void handle_v_commands(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03002012{
Alex Bennée26a16182021-05-25 09:24:14 +01002013 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03002014 return;
2015 }
2016
Alex Bennée26a16182021-05-25 09:24:14 +01002017 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron8536ec02019-05-29 09:41:44 +03002018 gdb_v_commands_table,
2019 ARRAY_SIZE(gdb_v_commands_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002020 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03002021 }
2022}
2023
Alex Bennée26a16182021-05-25 09:24:14 +01002024static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002025{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002026 g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
2027
2028 if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
2029 g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
2030 SSTEP_NOIRQ);
2031 }
2032
2033 if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
2034 g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
2035 SSTEP_NOTIMER);
2036 }
2037
Alex Bennée308f9e82020-03-16 17:21:35 +00002038 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002039}
2040
Alex Bennée26a16182021-05-25 09:24:14 +01002041static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002042{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002043 int new_sstep_flags;
2044
Alex Bennée26a16182021-05-25 09:24:14 +01002045 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002046 return;
2047 }
2048
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002049 new_sstep_flags = get_param(params, 0)->val_ul;
2050
2051 if (new_sstep_flags & ~gdbserver_state.supported_sstep_flags) {
2052 put_packet("E22");
2053 return;
2054 }
2055
2056 gdbserver_state.sstep_flags = new_sstep_flags;
Alex Bennéea346af32020-03-16 17:21:34 +00002057 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002058}
2059
Alex Bennée26a16182021-05-25 09:24:14 +01002060static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002061{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002062 g_string_printf(gdbserver_state.str_buf, "0x%x",
2063 gdbserver_state.sstep_flags);
Alex Bennée308f9e82020-03-16 17:21:35 +00002064 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002065}
2066
Alex Bennée26a16182021-05-25 09:24:14 +01002067static void handle_query_curr_tid(GArray *params, void *user_ctx)
bellardb4608c02003-06-27 17:34:32 +00002068{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002069 CPUState *cpu;
Luc Michelc145eea2019-01-07 15:23:46 +00002070 GDBProcess *process;
Jon Doron2704efa2019-05-29 09:41:45 +03002071
2072 /*
2073 * "Current thread" remains vague in the spec, so always return
2074 * the first thread of the current process (gdb returns the
2075 * first thread).
2076 */
Alex Bennéea346af32020-03-16 17:21:34 +00002077 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2078 cpu = get_first_cpu_in_process(process);
Alex Bennée308f9e82020-03-16 17:21:35 +00002079 g_string_assign(gdbserver_state.str_buf, "QC");
2080 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2081 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002082}
2083
Alex Bennée26a16182021-05-25 09:24:14 +01002084static void handle_query_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002085{
Alex Bennéea346af32020-03-16 17:21:34 +00002086 if (!gdbserver_state.query_cpu) {
2087 put_packet("l");
Jon Doron2704efa2019-05-29 09:41:45 +03002088 return;
2089 }
2090
Alex Bennée308f9e82020-03-16 17:21:35 +00002091 g_string_assign(gdbserver_state.str_buf, "m");
2092 gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
2093 put_strbuf();
Alex Bennéea346af32020-03-16 17:21:34 +00002094 gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002095}
2096
Alex Bennée26a16182021-05-25 09:24:14 +01002097static void handle_query_first_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002098{
Alex Bennéea346af32020-03-16 17:21:34 +00002099 gdbserver_state.query_cpu = gdb_first_attached_cpu();
Alex Bennée26a16182021-05-25 09:24:14 +01002100 handle_query_threads(params, user_ctx);
Jon Doron2704efa2019-05-29 09:41:45 +03002101}
2102
Alex Bennée26a16182021-05-25 09:24:14 +01002103static void handle_query_thread_extra(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002104{
Alex Bennée308f9e82020-03-16 17:21:35 +00002105 g_autoptr(GString) rs = g_string_new(NULL);
Jon Doron2704efa2019-05-29 09:41:45 +03002106 CPUState *cpu;
Jon Doron2704efa2019-05-29 09:41:45 +03002107
Alex Bennée26a16182021-05-25 09:24:14 +01002108 if (!params->len ||
2109 get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00002110 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002111 return;
2112 }
2113
Alex Bennée26a16182021-05-25 09:24:14 +01002114 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
2115 get_param(params, 0)->thread_id.tid);
Jon Doron2704efa2019-05-29 09:41:45 +03002116 if (!cpu) {
2117 return;
2118 }
2119
2120 cpu_synchronize_state(cpu);
2121
Alex Bennéea346af32020-03-16 17:21:34 +00002122 if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
Jon Doron2704efa2019-05-29 09:41:45 +03002123 /* Print the CPU model and name in multiprocess mode */
2124 ObjectClass *oc = object_get_class(OBJECT(cpu));
2125 const char *cpu_model = object_class_get_name(oc);
Markus Armbruster7a309cc2020-07-14 18:02:00 +02002126 const char *cpu_name =
Denis Plotnikov076b2fa2020-04-03 20:11:44 +01002127 object_get_canonical_path_component(OBJECT(cpu));
Alex Bennée308f9e82020-03-16 17:21:35 +00002128 g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
2129 cpu->halted ? "halted " : "running");
Jon Doron2704efa2019-05-29 09:41:45 +03002130 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002131 g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
Jon Doron2704efa2019-05-29 09:41:45 +03002132 cpu->halted ? "halted " : "running");
2133 }
Alex Bennée308f9e82020-03-16 17:21:35 +00002134 trace_gdbstub_op_extra_info(rs->str);
2135 memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
2136 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002137}
2138
2139#ifdef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002140static void handle_query_offsets(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002141{
2142 TaskState *ts;
2143
Alex Bennéea346af32020-03-16 17:21:34 +00002144 ts = gdbserver_state.c_cpu->opaque;
Alex Bennée308f9e82020-03-16 17:21:35 +00002145 g_string_printf(gdbserver_state.str_buf,
2146 "Text=" TARGET_ABI_FMT_lx
2147 ";Data=" TARGET_ABI_FMT_lx
2148 ";Bss=" TARGET_ABI_FMT_lx,
2149 ts->info->code_offset,
2150 ts->info->data_offset,
2151 ts->info->data_offset);
2152 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002153}
2154#else
Alex Bennée26a16182021-05-25 09:24:14 +01002155static void handle_query_rcmd(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002156{
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002157 const guint8 zero = 0;
Jon Doron2704efa2019-05-29 09:41:45 +03002158 int len;
2159
Alex Bennée26a16182021-05-25 09:24:14 +01002160 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002161 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002162 return;
2163 }
2164
Alex Bennée26a16182021-05-25 09:24:14 +01002165 len = strlen(get_param(params, 0)->data);
Jon Doron2704efa2019-05-29 09:41:45 +03002166 if (len % 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00002167 put_packet("E01");
Jon Doron2704efa2019-05-29 09:41:45 +03002168 return;
2169 }
2170
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002171 g_assert(gdbserver_state.mem_buf->len == 0);
Jon Doron2704efa2019-05-29 09:41:45 +03002172 len = len / 2;
Alex Bennée26a16182021-05-25 09:24:14 +01002173 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002174 g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
2175 qemu_chr_be_write(gdbserver_state.mon_chr, gdbserver_state.mem_buf->data,
2176 gdbserver_state.mem_buf->len);
Alex Bennéea346af32020-03-16 17:21:34 +00002177 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002178}
2179#endif
2180
Alex Bennée26a16182021-05-25 09:24:14 +01002181static void handle_query_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002182{
Andreas Färber5b24c642013-07-07 15:08:22 +02002183 CPUClass *cc;
Jon Doron2704efa2019-05-29 09:41:45 +03002184
Alex Bennée308f9e82020-03-16 17:21:35 +00002185 g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
Jon Doron2704efa2019-05-29 09:41:45 +03002186 cc = CPU_GET_CLASS(first_cpu);
2187 if (cc->gdb_core_xml_file) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002188 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
Jon Doron2704efa2019-05-29 09:41:45 +03002189 }
2190
Alex Bennéeed12f5b2021-05-20 18:43:02 +01002191 if (stub_can_reverse()) {
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03002192 g_string_append(gdbserver_state.str_buf,
2193 ";ReverseStep+;ReverseContinue+");
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002194 }
2195
Lirong Yuan51c623b2021-01-08 22:42:42 +00002196#ifdef CONFIG_USER_ONLY
2197 if (gdbserver_state.c_cpu->opaque) {
2198 g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
2199 }
2200#endif
2201
Alex Bennée26a16182021-05-25 09:24:14 +01002202 if (params->len &&
2203 strstr(get_param(params, 0)->data, "multiprocess+")) {
Alex Bennéea346af32020-03-16 17:21:34 +00002204 gdbserver_state.multiprocess = true;
Jon Doron2704efa2019-05-29 09:41:45 +03002205 }
2206
Changbin Du3bc26092020-03-16 17:21:55 +00002207 g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
Alex Bennée308f9e82020-03-16 17:21:35 +00002208 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002209}
2210
Alex Bennée26a16182021-05-25 09:24:14 +01002211static void handle_query_xfer_features(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002212{
2213 GDBProcess *process;
2214 CPUClass *cc;
2215 unsigned long len, total_len, addr;
2216 const char *xml;
bellardb4608c02003-06-27 17:34:32 +00002217 const char *p;
Jon Doron2704efa2019-05-29 09:41:45 +03002218
Alex Bennée26a16182021-05-25 09:24:14 +01002219 if (params->len < 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00002220 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002221 return;
2222 }
2223
Alex Bennéea346af32020-03-16 17:21:34 +00002224 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2225 cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002226 if (!cc->gdb_core_xml_file) {
Alex Bennéea346af32020-03-16 17:21:34 +00002227 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002228 return;
2229 }
2230
2231 gdb_has_xml = true;
Alex Bennée26a16182021-05-25 09:24:14 +01002232 p = get_param(params, 0)->data;
Alex Bennéea346af32020-03-16 17:21:34 +00002233 xml = get_feature_xml(p, &p, process);
Jon Doron2704efa2019-05-29 09:41:45 +03002234 if (!xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00002235 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002236 return;
2237 }
2238
Alex Bennée26a16182021-05-25 09:24:14 +01002239 addr = get_param(params, 1)->val_ul;
2240 len = get_param(params, 2)->val_ul;
Jon Doron2704efa2019-05-29 09:41:45 +03002241 total_len = strlen(xml);
2242 if (addr > total_len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002243 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002244 return;
2245 }
2246
2247 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2248 len = (MAX_PACKET_LENGTH - 5) / 2;
2249 }
2250
2251 if (len < total_len - addr) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002252 g_string_assign(gdbserver_state.str_buf, "m");
2253 memtox(gdbserver_state.str_buf, xml + addr, len);
Jon Doron2704efa2019-05-29 09:41:45 +03002254 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002255 g_string_assign(gdbserver_state.str_buf, "l");
2256 memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
Jon Doron2704efa2019-05-29 09:41:45 +03002257 }
2258
Alex Bennée308f9e82020-03-16 17:21:35 +00002259 put_packet_binary(gdbserver_state.str_buf->str,
2260 gdbserver_state.str_buf->len, true);
Jon Doron2704efa2019-05-29 09:41:45 +03002261}
2262
Lirong Yuan51c623b2021-01-08 22:42:42 +00002263#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
Alex Bennée26a16182021-05-25 09:24:14 +01002264static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
Lirong Yuan51c623b2021-01-08 22:42:42 +00002265{
2266 TaskState *ts;
2267 unsigned long offset, len, saved_auxv, auxv_len;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002268
Alex Bennée26a16182021-05-25 09:24:14 +01002269 if (params->len < 2) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002270 put_packet("E22");
2271 return;
2272 }
2273
Alex Bennée26a16182021-05-25 09:24:14 +01002274 offset = get_param(params, 0)->val_ul;
2275 len = get_param(params, 1)->val_ul;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002276 ts = gdbserver_state.c_cpu->opaque;
2277 saved_auxv = ts->info->saved_auxv;
2278 auxv_len = ts->info->auxv_len;
Richard Henderson6e3dd752021-02-02 13:39:55 +00002279
2280 if (offset >= auxv_len) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002281 put_packet("E00");
2282 return;
2283 }
2284
2285 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2286 len = (MAX_PACKET_LENGTH - 5) / 2;
2287 }
2288
2289 if (len < auxv_len - offset) {
2290 g_string_assign(gdbserver_state.str_buf, "m");
Lirong Yuan51c623b2021-01-08 22:42:42 +00002291 } else {
2292 g_string_assign(gdbserver_state.str_buf, "l");
Richard Henderson6e3dd752021-02-02 13:39:55 +00002293 len = auxv_len - offset;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002294 }
2295
Richard Henderson6e3dd752021-02-02 13:39:55 +00002296 g_byte_array_set_size(gdbserver_state.mem_buf, len);
2297 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2298 gdbserver_state.mem_buf->data, len, false)) {
2299 put_packet("E14");
2300 return;
2301 }
2302
2303 memtox(gdbserver_state.str_buf,
2304 (const char *)gdbserver_state.mem_buf->data, len);
Lirong Yuan51c623b2021-01-08 22:42:42 +00002305 put_packet_binary(gdbserver_state.str_buf->str,
2306 gdbserver_state.str_buf->len, true);
2307}
2308#endif
2309
Alex Bennée26a16182021-05-25 09:24:14 +01002310static void handle_query_attached(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002311{
Alex Bennéea346af32020-03-16 17:21:34 +00002312 put_packet(GDB_ATTACHED);
Jon Doron2704efa2019-05-29 09:41:45 +03002313}
2314
Alex Bennée26a16182021-05-25 09:24:14 +01002315static void handle_query_qemu_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002316{
Alex Bennée308f9e82020-03-16 17:21:35 +00002317 g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
Jon Doronab4752e2019-05-29 09:41:48 +03002318#ifndef CONFIG_USER_ONLY
Alex Bennée308f9e82020-03-16 17:21:35 +00002319 g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
Jon Doronab4752e2019-05-29 09:41:48 +03002320#endif
Alex Bennée308f9e82020-03-16 17:21:35 +00002321 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002322}
2323
Jon Doronab4752e2019-05-29 09:41:48 +03002324#ifndef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002325static void handle_query_qemu_phy_mem_mode(GArray *params,
Jon Doronab4752e2019-05-29 09:41:48 +03002326 void *user_ctx)
2327{
Alex Bennée308f9e82020-03-16 17:21:35 +00002328 g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
2329 put_strbuf();
Jon Doronab4752e2019-05-29 09:41:48 +03002330}
2331
Alex Bennée26a16182021-05-25 09:24:14 +01002332static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
Jon Doronab4752e2019-05-29 09:41:48 +03002333{
Alex Bennée26a16182021-05-25 09:24:14 +01002334 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002335 put_packet("E22");
Jon Doronab4752e2019-05-29 09:41:48 +03002336 return;
2337 }
2338
Alex Bennée26a16182021-05-25 09:24:14 +01002339 if (!get_param(params, 0)->val_ul) {
Jon Doronab4752e2019-05-29 09:41:48 +03002340 phy_memory_mode = 0;
2341 } else {
2342 phy_memory_mode = 1;
2343 }
Alex Bennéea346af32020-03-16 17:21:34 +00002344 put_packet("OK");
Jon Doronab4752e2019-05-29 09:41:48 +03002345}
2346#endif
2347
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002348static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002349 /* Order is important if has same prefix */
2350 {
2351 .handler = handle_query_qemu_sstepbits,
2352 .cmd = "qemu.sstepbits",
2353 },
2354 {
2355 .handler = handle_query_qemu_sstep,
2356 .cmd = "qemu.sstep",
2357 },
2358 {
2359 .handler = handle_set_qemu_sstep,
2360 .cmd = "qemu.sstep=",
2361 .cmd_startswith = 1,
2362 .schema = "l0"
2363 },
2364};
2365
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002366static const GdbCmdParseEntry gdb_gen_query_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002367 {
2368 .handler = handle_query_curr_tid,
2369 .cmd = "C",
2370 },
2371 {
2372 .handler = handle_query_threads,
2373 .cmd = "sThreadInfo",
2374 },
2375 {
2376 .handler = handle_query_first_threads,
2377 .cmd = "fThreadInfo",
2378 },
2379 {
2380 .handler = handle_query_thread_extra,
2381 .cmd = "ThreadExtraInfo,",
2382 .cmd_startswith = 1,
2383 .schema = "t0"
2384 },
2385#ifdef CONFIG_USER_ONLY
2386 {
2387 .handler = handle_query_offsets,
2388 .cmd = "Offsets",
2389 },
2390#else
2391 {
2392 .handler = handle_query_rcmd,
2393 .cmd = "Rcmd,",
2394 .cmd_startswith = 1,
2395 .schema = "s0"
2396 },
2397#endif
2398 {
2399 .handler = handle_query_supported,
2400 .cmd = "Supported:",
2401 .cmd_startswith = 1,
2402 .schema = "s0"
2403 },
2404 {
2405 .handler = handle_query_supported,
2406 .cmd = "Supported",
2407 .schema = "s0"
2408 },
2409 {
2410 .handler = handle_query_xfer_features,
2411 .cmd = "Xfer:features:read:",
2412 .cmd_startswith = 1,
2413 .schema = "s:l,l0"
2414 },
Lirong Yuan51c623b2021-01-08 22:42:42 +00002415#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2416 {
2417 .handler = handle_query_xfer_auxv,
2418 .cmd = "Xfer:auxv:read::",
2419 .cmd_startswith = 1,
2420 .schema = "l,l0"
2421 },
2422#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002423 {
2424 .handler = handle_query_attached,
2425 .cmd = "Attached:",
2426 .cmd_startswith = 1
2427 },
2428 {
2429 .handler = handle_query_attached,
2430 .cmd = "Attached",
2431 },
2432 {
2433 .handler = handle_query_qemu_supported,
2434 .cmd = "qemu.Supported",
2435 },
Jon Doronab4752e2019-05-29 09:41:48 +03002436#ifndef CONFIG_USER_ONLY
2437 {
2438 .handler = handle_query_qemu_phy_mem_mode,
2439 .cmd = "qemu.PhyMemMode",
2440 },
2441#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002442};
2443
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002444static const GdbCmdParseEntry gdb_gen_set_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002445 /* Order is important if has same prefix */
2446 {
2447 .handler = handle_set_qemu_sstep,
2448 .cmd = "qemu.sstep:",
2449 .cmd_startswith = 1,
2450 .schema = "l0"
2451 },
Jon Doronab4752e2019-05-29 09:41:48 +03002452#ifndef CONFIG_USER_ONLY
2453 {
2454 .handler = handle_set_qemu_phy_mem_mode,
2455 .cmd = "qemu.PhyMemMode:",
2456 .cmd_startswith = 1,
2457 .schema = "l0"
2458 },
2459#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002460};
2461
Alex Bennée26a16182021-05-25 09:24:14 +01002462static void handle_gen_query(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002463{
Alex Bennée26a16182021-05-25 09:24:14 +01002464 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002465 return;
2466 }
2467
Alex Bennée26a16182021-05-25 09:24:14 +01002468 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002469 gdb_gen_query_set_common_table,
2470 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2471 return;
2472 }
2473
Alex Bennée26a16182021-05-25 09:24:14 +01002474 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002475 gdb_gen_query_table,
2476 ARRAY_SIZE(gdb_gen_query_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002477 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002478 }
2479}
2480
Alex Bennée26a16182021-05-25 09:24:14 +01002481static void handle_gen_set(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002482{
Alex Bennée26a16182021-05-25 09:24:14 +01002483 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002484 return;
2485 }
2486
Alex Bennée26a16182021-05-25 09:24:14 +01002487 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002488 gdb_gen_query_set_common_table,
2489 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2490 return;
2491 }
2492
Alex Bennée26a16182021-05-25 09:24:14 +01002493 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002494 gdb_gen_set_table,
2495 ARRAY_SIZE(gdb_gen_set_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002496 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002497 }
2498}
2499
Alex Bennée26a16182021-05-25 09:24:14 +01002500static void handle_target_halt(GArray *params, void *user_ctx)
Jon Doron7009d572019-05-29 09:41:46 +03002501{
Alex Bennée308f9e82020-03-16 17:21:35 +00002502 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2503 gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2504 g_string_append_c(gdbserver_state.str_buf, ';');
2505 put_strbuf();
Jon Doron7009d572019-05-29 09:41:46 +03002506 /*
2507 * Remove all the breakpoints when this query is issued,
2508 * because gdb is doing an initial connect and the state
2509 * should be cleaned up.
2510 */
2511 gdb_breakpoint_remove_all();
2512}
2513
Alex Bennéea346af32020-03-16 17:21:34 +00002514static int gdb_handle_packet(const char *line_buf)
Jon Doron2704efa2019-05-29 09:41:45 +03002515{
Jon Doron3e2c1262019-05-29 09:41:30 +03002516 const GdbCmdParseEntry *cmd_parser = NULL;
ths3b46e622007-09-17 08:09:54 +00002517
Doug Gale5c9522b2017-12-02 20:30:37 -05002518 trace_gdbstub_io_command(line_buf);
Alex Bennée118e2262017-07-12 11:52:13 +01002519
Jon Doron3f1cbac2019-05-29 09:41:47 +03002520 switch (line_buf[0]) {
Luc Michel53fd6552019-01-07 15:23:46 +00002521 case '!':
Alex Bennéea346af32020-03-16 17:21:34 +00002522 put_packet("OK");
Luc Michel53fd6552019-01-07 15:23:46 +00002523 break;
bellard858693c2004-03-31 18:52:07 +00002524 case '?':
Jon Doron7009d572019-05-29 09:41:46 +03002525 {
2526 static const GdbCmdParseEntry target_halted_cmd_desc = {
2527 .handler = handle_target_halt,
2528 .cmd = "?",
2529 .cmd_startswith = 1
2530 };
2531 cmd_parser = &target_halted_cmd_desc;
2532 }
bellard858693c2004-03-31 18:52:07 +00002533 break;
2534 case 'c':
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002535 {
2536 static const GdbCmdParseEntry continue_cmd_desc = {
2537 .handler = handle_continue,
2538 .cmd = "c",
2539 .cmd_startswith = 1,
2540 .schema = "L0"
2541 };
2542 cmd_parser = &continue_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002543 }
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002544 break;
edgar_igl1f487ee2008-05-17 22:20:53 +00002545 case 'C':
Jon Doronccc47d52019-05-29 09:41:33 +03002546 {
2547 static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2548 .handler = handle_cont_with_sig,
2549 .cmd = "C",
2550 .cmd_startswith = 1,
2551 .schema = "l0"
2552 };
2553 cmd_parser = &cont_with_sig_cmd_desc;
2554 }
2555 break;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002556 case 'v':
Jon Doron8536ec02019-05-29 09:41:44 +03002557 {
2558 static const GdbCmdParseEntry v_cmd_desc = {
2559 .handler = handle_v_commands,
2560 .cmd = "v",
2561 .cmd_startswith = 1,
2562 .schema = "s0"
2563 };
2564 cmd_parser = &v_cmd_desc;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002565 }
Jon Doron8536ec02019-05-29 09:41:44 +03002566 break;
edgar_igl7d03f822008-05-17 18:58:29 +00002567 case 'k':
2568 /* Kill the target */
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002569 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00002570 gdb_exit(0);
edgar_igl7d03f822008-05-17 18:58:29 +00002571 exit(0);
2572 case 'D':
Jon Doron3e2c1262019-05-29 09:41:30 +03002573 {
2574 static const GdbCmdParseEntry detach_cmd_desc = {
2575 .handler = handle_detach,
2576 .cmd = "D",
2577 .cmd_startswith = 1,
2578 .schema = "?.l0"
2579 };
2580 cmd_parser = &detach_cmd_desc;
Luc Michel546f3c62019-01-07 15:23:46 +00002581 }
edgar_igl7d03f822008-05-17 18:58:29 +00002582 break;
bellard858693c2004-03-31 18:52:07 +00002583 case 's':
Jon Doron933f80d2019-05-29 09:41:43 +03002584 {
2585 static const GdbCmdParseEntry step_cmd_desc = {
2586 .handler = handle_step,
2587 .cmd = "s",
2588 .cmd_startswith = 1,
2589 .schema = "L0"
2590 };
2591 cmd_parser = &step_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002592 }
Jon Doron933f80d2019-05-29 09:41:43 +03002593 break;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002594 case 'b':
2595 {
2596 static const GdbCmdParseEntry backward_cmd_desc = {
2597 .handler = handle_backward,
2598 .cmd = "b",
2599 .cmd_startswith = 1,
2600 .schema = "o0"
2601 };
2602 cmd_parser = &backward_cmd_desc;
2603 }
2604 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002605 case 'F':
2606 {
Jon Doron4b20fab2019-05-29 09:41:42 +03002607 static const GdbCmdParseEntry file_io_cmd_desc = {
2608 .handler = handle_file_io,
2609 .cmd = "F",
2610 .cmd_startswith = 1,
2611 .schema = "L,L,o0"
2612 };
2613 cmd_parser = &file_io_cmd_desc;
pbrooka2d1eba2007-01-28 03:10:55 +00002614 }
2615 break;
bellard858693c2004-03-31 18:52:07 +00002616 case 'g':
Jon Doron397d1372019-05-29 09:41:41 +03002617 {
2618 static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2619 .handler = handle_read_all_regs,
2620 .cmd = "g",
2621 .cmd_startswith = 1
2622 };
2623 cmd_parser = &read_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002624 }
bellard858693c2004-03-31 18:52:07 +00002625 break;
2626 case 'G':
Jon Doron287ca122019-05-29 09:41:40 +03002627 {
2628 static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2629 .handler = handle_write_all_regs,
2630 .cmd = "G",
2631 .cmd_startswith = 1,
2632 .schema = "s0"
2633 };
2634 cmd_parser = &write_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002635 }
bellard858693c2004-03-31 18:52:07 +00002636 break;
2637 case 'm':
Jon Doronda92e232019-05-29 09:41:39 +03002638 {
2639 static const GdbCmdParseEntry read_mem_cmd_desc = {
2640 .handler = handle_read_mem,
2641 .cmd = "m",
2642 .cmd_startswith = 1,
2643 .schema = "L,L0"
2644 };
2645 cmd_parser = &read_mem_cmd_desc;
bellard6f970bd2005-12-05 19:55:19 +00002646 }
bellard858693c2004-03-31 18:52:07 +00002647 break;
2648 case 'M':
Jon Doroncc0ecc72019-05-29 09:41:38 +03002649 {
2650 static const GdbCmdParseEntry write_mem_cmd_desc = {
2651 .handler = handle_write_mem,
2652 .cmd = "M",
2653 .cmd_startswith = 1,
2654 .schema = "L,L:s0"
2655 };
2656 cmd_parser = &write_mem_cmd_desc;
Fabien Chouteau44520db2011-09-08 12:48:16 +02002657 }
bellard858693c2004-03-31 18:52:07 +00002658 break;
pbrook56aebc82008-10-11 17:55:29 +00002659 case 'p':
Jon Doron5d0e57b2019-05-29 09:41:37 +03002660 {
2661 static const GdbCmdParseEntry get_reg_cmd_desc = {
2662 .handler = handle_get_reg,
2663 .cmd = "p",
2664 .cmd_startswith = 1,
2665 .schema = "L0"
2666 };
2667 cmd_parser = &get_reg_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002668 }
2669 break;
2670 case 'P':
Jon Doron62b33202019-05-29 09:41:36 +03002671 {
2672 static const GdbCmdParseEntry set_reg_cmd_desc = {
2673 .handler = handle_set_reg,
2674 .cmd = "P",
2675 .cmd_startswith = 1,
2676 .schema = "L?s0"
2677 };
2678 cmd_parser = &set_reg_cmd_desc;
2679 }
pbrook56aebc82008-10-11 17:55:29 +00002680 break;
bellard858693c2004-03-31 18:52:07 +00002681 case 'Z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002682 {
2683 static const GdbCmdParseEntry insert_bp_cmd_desc = {
2684 .handler = handle_insert_bp,
2685 .cmd = "Z",
2686 .cmd_startswith = 1,
2687 .schema = "l?L?L0"
2688 };
2689 cmd_parser = &insert_bp_cmd_desc;
2690 }
2691 break;
bellard858693c2004-03-31 18:52:07 +00002692 case 'z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002693 {
2694 static const GdbCmdParseEntry remove_bp_cmd_desc = {
2695 .handler = handle_remove_bp,
2696 .cmd = "z",
2697 .cmd_startswith = 1,
2698 .schema = "l?L?L0"
2699 };
2700 cmd_parser = &remove_bp_cmd_desc;
2701 }
bellard858693c2004-03-31 18:52:07 +00002702 break;
aliguori880a7572008-11-18 20:30:24 +00002703 case 'H':
Jon Doron3a9651d2019-05-29 09:41:34 +03002704 {
2705 static const GdbCmdParseEntry set_thread_cmd_desc = {
2706 .handler = handle_set_thread,
2707 .cmd = "H",
2708 .cmd_startswith = 1,
2709 .schema = "o.t0"
2710 };
2711 cmd_parser = &set_thread_cmd_desc;
aliguori880a7572008-11-18 20:30:24 +00002712 }
2713 break;
2714 case 'T':
Jon Doron44ffded2019-05-29 09:41:31 +03002715 {
2716 static const GdbCmdParseEntry thread_alive_cmd_desc = {
2717 .handler = handle_thread_alive,
2718 .cmd = "T",
2719 .cmd_startswith = 1,
2720 .schema = "t0"
2721 };
2722 cmd_parser = &thread_alive_cmd_desc;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002723 }
aliguori880a7572008-11-18 20:30:24 +00002724 break;
pbrook978efd62006-06-17 18:30:42 +00002725 case 'q':
Jon Doron2704efa2019-05-29 09:41:45 +03002726 {
2727 static const GdbCmdParseEntry gen_query_cmd_desc = {
2728 .handler = handle_gen_query,
2729 .cmd = "q",
2730 .cmd_startswith = 1,
2731 .schema = "s0"
2732 };
2733 cmd_parser = &gen_query_cmd_desc;
2734 }
2735 break;
edgar_igl60897d32008-05-09 08:25:14 +00002736 case 'Q':
Jon Doron2704efa2019-05-29 09:41:45 +03002737 {
2738 static const GdbCmdParseEntry gen_set_cmd_desc = {
2739 .handler = handle_gen_set,
2740 .cmd = "Q",
2741 .cmd_startswith = 1,
2742 .schema = "s0"
2743 };
2744 cmd_parser = &gen_set_cmd_desc;
edgar_igl60897d32008-05-09 08:25:14 +00002745 }
Jon Doron2704efa2019-05-29 09:41:45 +03002746 break;
bellard858693c2004-03-31 18:52:07 +00002747 default:
bellard858693c2004-03-31 18:52:07 +00002748 /* put empty packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002749 put_packet("");
bellard858693c2004-03-31 18:52:07 +00002750 break;
2751 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002752
Ramiro Polla2bdec392019-08-05 21:09:01 +02002753 if (cmd_parser) {
Alex Bennéea346af32020-03-16 17:21:34 +00002754 run_cmd_parser(line_buf, cmd_parser);
Ramiro Polla2bdec392019-08-05 21:09:01 +02002755 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002756
bellard858693c2004-03-31 18:52:07 +00002757 return RS_IDLE;
2758}
2759
Andreas Färber64f6b342013-05-27 02:06:09 +02002760void gdb_set_stop_cpu(CPUState *cpu)
aliguori880a7572008-11-18 20:30:24 +00002761{
Alex Bennéea346af32020-03-16 17:21:34 +00002762 GDBProcess *p = gdb_get_cpu_process(cpu);
Luc Michel160d8582019-01-07 15:23:46 +00002763
2764 if (!p->attached) {
2765 /*
2766 * Having a stop CPU corresponding to a process that is not attached
2767 * confuses GDB. So we ignore the request.
2768 */
2769 return;
2770 }
2771
Alex Bennée8d98c442020-03-16 17:21:33 +00002772 gdbserver_state.c_cpu = cpu;
2773 gdbserver_state.g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002774}
2775
bellard1fddef42005-04-17 19:16:13 +00002776#ifndef CONFIG_USER_ONLY
Philippe Mathieu-Daudé538f0492021-01-11 16:20:20 +01002777static void gdb_vm_state_change(void *opaque, bool running, RunState state)
bellard858693c2004-03-31 18:52:07 +00002778{
Alex Bennéea346af32020-03-16 17:21:34 +00002779 CPUState *cpu = gdbserver_state.c_cpu;
Alex Bennée308f9e82020-03-16 17:21:35 +00002780 g_autoptr(GString) buf = g_string_new(NULL);
2781 g_autoptr(GString) tid = g_string_new(NULL);
aliguorid6fc1b32008-11-18 19:55:44 +00002782 const char *type;
bellard858693c2004-03-31 18:52:07 +00002783 int ret;
2784
Alex Bennéea346af32020-03-16 17:21:34 +00002785 if (running || gdbserver_state.state == RS_INACTIVE) {
Meador Ingecdb432b2012-03-15 17:49:45 +00002786 return;
2787 }
2788 /* Is there a GDB syscall waiting to be sent? */
Alex Bennéea346af32020-03-16 17:21:34 +00002789 if (gdbserver_state.current_syscall_cb) {
2790 put_packet(gdbserver_state.syscall_buf);
pbrooka2d1eba2007-01-28 03:10:55 +00002791 return;
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002792 }
Luc Michel95567c22019-01-07 15:23:46 +00002793
2794 if (cpu == NULL) {
2795 /* No process attached */
2796 return;
2797 }
2798
Alex Bennée308f9e82020-03-16 17:21:35 +00002799 gdb_append_thread_id(cpu, tid);
Luc Michel95567c22019-01-07 15:23:46 +00002800
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002801 switch (state) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002802 case RUN_STATE_DEBUG:
Andreas Färberff4700b2013-08-26 18:23:18 +02002803 if (cpu->watchpoint_hit) {
2804 switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
aliguoria1d1bb32008-11-18 20:07:32 +00002805 case BP_MEM_READ:
aliguorid6fc1b32008-11-18 19:55:44 +00002806 type = "r";
2807 break;
aliguoria1d1bb32008-11-18 20:07:32 +00002808 case BP_MEM_ACCESS:
aliguorid6fc1b32008-11-18 19:55:44 +00002809 type = "a";
2810 break;
2811 default:
2812 type = "";
2813 break;
2814 }
Doug Gale5c9522b2017-12-02 20:30:37 -05002815 trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
2816 (target_ulong)cpu->watchpoint_hit->vaddr);
Alex Bennée308f9e82020-03-16 17:21:35 +00002817 g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
2818 GDB_SIGNAL_TRAP, tid->str, type,
2819 (target_ulong)cpu->watchpoint_hit->vaddr);
Andreas Färberff4700b2013-08-26 18:23:18 +02002820 cpu->watchpoint_hit = NULL;
Jan Kiszka425189a2011-03-22 11:02:09 +01002821 goto send_packet;
Doug Gale5c9522b2017-12-02 20:30:37 -05002822 } else {
2823 trace_gdbstub_hit_break();
pbrook6658ffb2007-03-16 23:58:11 +00002824 }
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07002825 tb_flush(cpu);
aurel32ca587a82008-12-18 22:44:13 +00002826 ret = GDB_SIGNAL_TRAP;
Jan Kiszka425189a2011-03-22 11:02:09 +01002827 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002828 case RUN_STATE_PAUSED:
Doug Gale5c9522b2017-12-02 20:30:37 -05002829 trace_gdbstub_hit_paused();
aliguori9781e042009-01-22 17:15:29 +00002830 ret = GDB_SIGNAL_INT;
Jan Kiszka425189a2011-03-22 11:02:09 +01002831 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002832 case RUN_STATE_SHUTDOWN:
Doug Gale5c9522b2017-12-02 20:30:37 -05002833 trace_gdbstub_hit_shutdown();
Jan Kiszka425189a2011-03-22 11:02:09 +01002834 ret = GDB_SIGNAL_QUIT;
2835 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002836 case RUN_STATE_IO_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002837 trace_gdbstub_hit_io_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002838 ret = GDB_SIGNAL_IO;
2839 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002840 case RUN_STATE_WATCHDOG:
Doug Gale5c9522b2017-12-02 20:30:37 -05002841 trace_gdbstub_hit_watchdog();
Jan Kiszka425189a2011-03-22 11:02:09 +01002842 ret = GDB_SIGNAL_ALRM;
2843 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002844 case RUN_STATE_INTERNAL_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002845 trace_gdbstub_hit_internal_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002846 ret = GDB_SIGNAL_ABRT;
2847 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002848 case RUN_STATE_SAVE_VM:
2849 case RUN_STATE_RESTORE_VM:
Jan Kiszka425189a2011-03-22 11:02:09 +01002850 return;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002851 case RUN_STATE_FINISH_MIGRATE:
Jan Kiszka425189a2011-03-22 11:02:09 +01002852 ret = GDB_SIGNAL_XCPU;
2853 break;
2854 default:
Doug Gale5c9522b2017-12-02 20:30:37 -05002855 trace_gdbstub_hit_unknown(state);
Jan Kiszka425189a2011-03-22 11:02:09 +01002856 ret = GDB_SIGNAL_UNKNOWN;
2857 break;
bellardbbeb7b52006-04-23 18:42:15 +00002858 }
Jan Kiszka226d0072015-07-24 18:52:31 +02002859 gdb_set_stop_cpu(cpu);
Alex Bennée308f9e82020-03-16 17:21:35 +00002860 g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002861
2862send_packet:
Alex Bennée308f9e82020-03-16 17:21:35 +00002863 put_packet(buf->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002864
2865 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002866 cpu_single_step(cpu, 0);
bellard858693c2004-03-31 18:52:07 +00002867}
bellard1fddef42005-04-17 19:16:13 +00002868#endif
bellard858693c2004-03-31 18:52:07 +00002869
pbrooka2d1eba2007-01-28 03:10:55 +00002870/* Send a gdb syscall request.
2871 This accepts limited printf-style format specifiers, specifically:
pbrooka87295e2007-05-26 15:09:38 +00002872 %x - target_ulong argument printed in hex.
2873 %lx - 64-bit argument printed in hex.
2874 %s - string pointer (target_ulong) and length (int) pair. */
Peter Maydell19239b32015-09-07 10:39:27 +01002875void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
pbrooka2d1eba2007-01-28 03:10:55 +00002876{
pbrooka2d1eba2007-01-28 03:10:55 +00002877 char *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00002878 char *p_end;
pbrooka2d1eba2007-01-28 03:10:55 +00002879 target_ulong addr;
pbrooka87295e2007-05-26 15:09:38 +00002880 uint64_t i64;
pbrooka2d1eba2007-01-28 03:10:55 +00002881
Alex Bennéea346af32020-03-16 17:21:34 +00002882 if (!gdbserver_state.init) {
pbrooka2d1eba2007-01-28 03:10:55 +00002883 return;
Alex Bennéea346af32020-03-16 17:21:34 +00002884 }
Alex Bennée8d98c442020-03-16 17:21:33 +00002885
2886 gdbserver_state.current_syscall_cb = cb;
pbrooka2d1eba2007-01-28 03:10:55 +00002887#ifndef CONFIG_USER_ONLY
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002888 vm_stop(RUN_STATE_DEBUG);
pbrooka2d1eba2007-01-28 03:10:55 +00002889#endif
Alex Bennée8d98c442020-03-16 17:21:33 +00002890 p = &gdbserver_state.syscall_buf[0];
2891 p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
pbrooka2d1eba2007-01-28 03:10:55 +00002892 *(p++) = 'F';
2893 while (*fmt) {
2894 if (*fmt == '%') {
2895 fmt++;
2896 switch (*fmt++) {
2897 case 'x':
2898 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002899 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
pbrooka2d1eba2007-01-28 03:10:55 +00002900 break;
pbrooka87295e2007-05-26 15:09:38 +00002901 case 'l':
2902 if (*(fmt++) != 'x')
2903 goto bad_format;
2904 i64 = va_arg(va, uint64_t);
Meador Ingecdb432b2012-03-15 17:49:45 +00002905 p += snprintf(p, p_end - p, "%" PRIx64, i64);
pbrooka87295e2007-05-26 15:09:38 +00002906 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002907 case 's':
2908 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002909 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
blueswir1363a37d2008-08-21 17:58:08 +00002910 addr, va_arg(va, int));
pbrooka2d1eba2007-01-28 03:10:55 +00002911 break;
2912 default:
pbrooka87295e2007-05-26 15:09:38 +00002913 bad_format:
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002914 error_report("gdbstub: Bad syscall format string '%s'",
2915 fmt - 1);
pbrooka2d1eba2007-01-28 03:10:55 +00002916 break;
2917 }
2918 } else {
2919 *(p++) = *(fmt++);
2920 }
2921 }
pbrook8a93e022007-08-06 13:19:15 +00002922 *p = 0;
pbrooka2d1eba2007-01-28 03:10:55 +00002923#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +00002924 put_packet(gdbserver_state.syscall_buf);
Peter Maydell4f710862018-05-15 19:19:58 +01002925 /* Return control to gdb for it to process the syscall request.
2926 * Since the protocol requires that gdb hands control back to us
2927 * using a "here are the results" F packet, we don't need to check
2928 * gdb_handlesig's return value (which is the signal to deliver if
2929 * execution was resumed via a continue packet).
2930 */
Alex Bennée8d98c442020-03-16 17:21:33 +00002931 gdb_handlesig(gdbserver_state.c_cpu, 0);
pbrooka2d1eba2007-01-28 03:10:55 +00002932#else
Meador Ingecdb432b2012-03-15 17:49:45 +00002933 /* In this case wait to send the syscall packet until notification that
2934 the CPU has stopped. This must be done because if the packet is sent
2935 now the reply from the syscall request could be received while the CPU
2936 is still in the running state, which can cause packets to be dropped
2937 and state transition 'T' packets to be sent while the syscall is still
2938 being processed. */
Alex Bennée8d98c442020-03-16 17:21:33 +00002939 qemu_cpu_kick(gdbserver_state.c_cpu);
pbrooka2d1eba2007-01-28 03:10:55 +00002940#endif
2941}
2942
Peter Maydell19239b32015-09-07 10:39:27 +01002943void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2944{
2945 va_list va;
2946
2947 va_start(va, fmt);
2948 gdb_do_syscallv(cb, fmt, va);
2949 va_end(va);
2950}
2951
Alex Bennéea346af32020-03-16 17:21:34 +00002952static void gdb_read_byte(uint8_t ch)
bellard858693c2004-03-31 18:52:07 +00002953{
ths60fe76f2007-12-16 03:02:09 +00002954 uint8_t reply;
bellard858693c2004-03-31 18:52:07 +00002955
bellard1fddef42005-04-17 19:16:13 +00002956#ifndef CONFIG_USER_ONLY
Damien Hedded116e812020-03-16 17:21:53 +00002957 if (gdbserver_state.last_packet->len) {
pbrook4046d912007-01-28 01:53:16 +00002958 /* Waiting for a response to the last packet. If we see the start
2959 of a new command then abandon the previous response. */
2960 if (ch == '-') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002961 trace_gdbstub_err_got_nack();
Damien Hedded116e812020-03-16 17:21:53 +00002962 put_buffer(gdbserver_state.last_packet->data,
2963 gdbserver_state.last_packet->len);
Alex Bennée118e2262017-07-12 11:52:13 +01002964 } else if (ch == '+') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002965 trace_gdbstub_io_got_ack();
Alex Bennée118e2262017-07-12 11:52:13 +01002966 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002967 trace_gdbstub_io_got_unexpected(ch);
pbrook4046d912007-01-28 01:53:16 +00002968 }
Alex Bennée118e2262017-07-12 11:52:13 +01002969
Damien Hedded116e812020-03-16 17:21:53 +00002970 if (ch == '+' || ch == '$') {
2971 g_byte_array_set_size(gdbserver_state.last_packet, 0);
2972 }
pbrook4046d912007-01-28 01:53:16 +00002973 if (ch != '$')
2974 return;
2975 }
Luiz Capitulino13548692011-07-29 15:36:43 -03002976 if (runstate_is_running()) {
bellard858693c2004-03-31 18:52:07 +00002977 /* when the CPU is running, we cannot do anything except stop
2978 it when receiving a char */
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002979 vm_stop(RUN_STATE_PAUSED);
ths5fafdf22007-09-16 21:08:06 +00002980 } else
bellard1fddef42005-04-17 19:16:13 +00002981#endif
bellard41625032005-04-24 10:07:11 +00002982 {
Alex Bennéea346af32020-03-16 17:21:34 +00002983 switch(gdbserver_state.state) {
bellard858693c2004-03-31 18:52:07 +00002984 case RS_IDLE:
2985 if (ch == '$') {
Doug Gale4bf43122017-05-01 12:22:10 -04002986 /* start of command packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002987 gdbserver_state.line_buf_index = 0;
2988 gdbserver_state.line_sum = 0;
2989 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002990 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002991 trace_gdbstub_err_garbage(ch);
bellard4c3a88a2003-07-26 12:06:08 +00002992 }
2993 break;
bellard858693c2004-03-31 18:52:07 +00002994 case RS_GETLINE:
Doug Gale4bf43122017-05-01 12:22:10 -04002995 if (ch == '}') {
2996 /* start escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002997 gdbserver_state.state = RS_GETLINE_ESC;
2998 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002999 } else if (ch == '*') {
3000 /* start run length encoding sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003001 gdbserver_state.state = RS_GETLINE_RLE;
3002 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003003 } else if (ch == '#') {
3004 /* end of command, start of checksum*/
Alex Bennéea346af32020-03-16 17:21:34 +00003005 gdbserver_state.state = RS_CHKSUM1;
3006 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale5c9522b2017-12-02 20:30:37 -05003007 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003008 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003009 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003010 /* unescaped command character */
Alex Bennéea346af32020-03-16 17:21:34 +00003011 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
3012 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003013 }
3014 break;
3015 case RS_GETLINE_ESC:
3016 if (ch == '#') {
3017 /* unexpected end of command in escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003018 gdbserver_state.state = RS_CHKSUM1;
3019 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003020 /* command buffer overrun */
Doug Gale5c9522b2017-12-02 20:30:37 -05003021 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003022 gdbserver_state.state = RS_IDLE;
Doug Gale4bf43122017-05-01 12:22:10 -04003023 } else {
3024 /* parse escaped character and leave escape state */
Alex Bennéea346af32020-03-16 17:21:34 +00003025 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
3026 gdbserver_state.line_sum += ch;
3027 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003028 }
3029 break;
3030 case RS_GETLINE_RLE:
Markus Armbruster046aba12019-05-14 20:03:08 +02003031 /*
3032 * Run-length encoding is explained in "Debugging with GDB /
3033 * Appendix E GDB Remote Serial Protocol / Overview".
3034 */
3035 if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
Doug Gale4bf43122017-05-01 12:22:10 -04003036 /* invalid RLE count encoding */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003037 trace_gdbstub_err_invalid_repeat(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003038 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003039 } else {
3040 /* decode repeat length */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003041 int repeat = ch - ' ' + 3;
Alex Bennéea346af32020-03-16 17:21:34 +00003042 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003043 /* that many repeats would overrun the command buffer */
Doug Gale5c9522b2017-12-02 20:30:37 -05003044 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003045 gdbserver_state.state = RS_IDLE;
3046 } else if (gdbserver_state.line_buf_index < 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003047 /* got a repeat but we have nothing to repeat */
Doug Gale5c9522b2017-12-02 20:30:37 -05003048 trace_gdbstub_err_invalid_rle();
Alex Bennéea346af32020-03-16 17:21:34 +00003049 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003050 } else {
3051 /* repeat the last character */
Alex Bennéea346af32020-03-16 17:21:34 +00003052 memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
3053 gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
3054 gdbserver_state.line_buf_index += repeat;
3055 gdbserver_state.line_sum += ch;
3056 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003057 }
bellard858693c2004-03-31 18:52:07 +00003058 }
3059 break;
3060 case RS_CHKSUM1:
Doug Gale4bf43122017-05-01 12:22:10 -04003061 /* get high hex digit of checksum */
3062 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003063 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003064 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003065 break;
3066 }
Alex Bennéea346af32020-03-16 17:21:34 +00003067 gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
3068 gdbserver_state.line_csum = fromhex(ch) << 4;
3069 gdbserver_state.state = RS_CHKSUM2;
bellard858693c2004-03-31 18:52:07 +00003070 break;
3071 case RS_CHKSUM2:
Doug Gale4bf43122017-05-01 12:22:10 -04003072 /* get low hex digit of checksum */
3073 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003074 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003075 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003076 break;
bellard858693c2004-03-31 18:52:07 +00003077 }
Alex Bennéea346af32020-03-16 17:21:34 +00003078 gdbserver_state.line_csum |= fromhex(ch);
Doug Gale4bf43122017-05-01 12:22:10 -04003079
Alex Bennéea346af32020-03-16 17:21:34 +00003080 if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
3081 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
Doug Gale4bf43122017-05-01 12:22:10 -04003082 /* send NAK reply */
ths60fe76f2007-12-16 03:02:09 +00003083 reply = '-';
Alex Bennéea346af32020-03-16 17:21:34 +00003084 put_buffer(&reply, 1);
3085 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003086 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003087 /* send ACK reply */
ths60fe76f2007-12-16 03:02:09 +00003088 reply = '+';
Alex Bennéea346af32020-03-16 17:21:34 +00003089 put_buffer(&reply, 1);
3090 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
bellard858693c2004-03-31 18:52:07 +00003091 }
bellardb4608c02003-06-27 17:34:32 +00003092 break;
pbrooka2d1eba2007-01-28 03:10:55 +00003093 default:
3094 abort();
bellardb4608c02003-06-27 17:34:32 +00003095 }
3096 }
bellard858693c2004-03-31 18:52:07 +00003097}
3098
Paul Brook0e1c9c52010-06-16 13:03:51 +01003099/* Tell the remote gdb that the process has exited. */
Alex Bennéead9dcb22021-01-08 22:42:43 +00003100void gdb_exit(int code)
Paul Brook0e1c9c52010-06-16 13:03:51 +01003101{
Paul Brook0e1c9c52010-06-16 13:03:51 +01003102 char buf[4];
3103
Alex Bennée8d98c442020-03-16 17:21:33 +00003104 if (!gdbserver_state.init) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003105 return;
3106 }
3107#ifdef CONFIG_USER_ONLY
Alex Bennéefcedd922020-04-30 20:01:19 +01003108 if (gdbserver_state.socket_path) {
3109 unlink(gdbserver_state.socket_path);
3110 }
Alex Bennéee0a1e202020-04-30 20:01:18 +01003111 if (gdbserver_state.fd < 0) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003112 return;
3113 }
3114#endif
3115
Doug Gale5c9522b2017-12-02 20:30:37 -05003116 trace_gdbstub_op_exiting((uint8_t)code);
3117
Paul Brook0e1c9c52010-06-16 13:03:51 +01003118 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
Alex Bennéea346af32020-03-16 17:21:34 +00003119 put_packet(buf);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003120
3121#ifndef CONFIG_USER_ONLY
Alex Bennée8d98c442020-03-16 17:21:33 +00003122 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003123#endif
Paul Brook0e1c9c52010-06-16 13:03:51 +01003124}
3125
Luc Michel8f468632019-01-07 15:23:45 +00003126/*
3127 * Create the process that will contain all the "orphan" CPUs (that are not
3128 * part of a CPU cluster). Note that if this process contains no CPUs, it won't
3129 * be attachable and thus will be invisible to the user.
3130 */
3131static void create_default_process(GDBState *s)
3132{
3133 GDBProcess *process;
3134 int max_pid = 0;
3135
Alex Bennéea346af32020-03-16 17:21:34 +00003136 if (gdbserver_state.process_num) {
Luc Michel8f468632019-01-07 15:23:45 +00003137 max_pid = s->processes[s->process_num - 1].pid;
3138 }
3139
3140 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3141 process = &s->processes[s->process_num - 1];
3142
3143 /* We need an available PID slot for this process */
3144 assert(max_pid < UINT32_MAX);
3145
3146 process->pid = max_pid + 1;
3147 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003148 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003149}
3150
bellard1fddef42005-04-17 19:16:13 +00003151#ifdef CONFIG_USER_ONLY
3152int
Andreas Färberdb6b81d2013-06-27 19:49:31 +02003153gdb_handlesig(CPUState *cpu, int sig)
bellard1fddef42005-04-17 19:16:13 +00003154{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003155 char buf[256];
3156 int n;
bellard1fddef42005-04-17 19:16:13 +00003157
Alex Bennéee0a1e202020-04-30 20:01:18 +01003158 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003159 return sig;
bellard1fddef42005-04-17 19:16:13 +00003160 }
3161
Andreas Färber5ca666c2013-06-24 19:20:57 +02003162 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02003163 cpu_single_step(cpu, 0);
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07003164 tb_flush(cpu);
bellard1fddef42005-04-17 19:16:13 +00003165
Andreas Färber5ca666c2013-06-24 19:20:57 +02003166 if (sig != 0) {
Pavel Labath4a82be72021-10-26 11:22:34 +01003167 gdb_set_stop_cpu(cpu);
3168 g_string_printf(gdbserver_state.str_buf,
3169 "T%02xthread:", target_signal_to_gdb(sig));
3170 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
3171 g_string_append_c(gdbserver_state.str_buf, ';');
3172 put_strbuf();
Andreas Färber5ca666c2013-06-24 19:20:57 +02003173 }
3174 /* put_packet() might have detected that the peer terminated the
3175 connection. */
Alex Bennée8d98c442020-03-16 17:21:33 +00003176 if (gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003177 return sig;
3178 }
3179
3180 sig = 0;
Alex Bennée8d98c442020-03-16 17:21:33 +00003181 gdbserver_state.state = RS_IDLE;
3182 gdbserver_state.running_state = 0;
3183 while (gdbserver_state.running_state == 0) {
3184 n = read(gdbserver_state.fd, buf, 256);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003185 if (n > 0) {
3186 int i;
3187
3188 for (i = 0; i < n; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003189 gdb_read_byte(buf[i]);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003190 }
Peter Wu5819e3e2016-06-05 16:35:48 +02003191 } else {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003192 /* XXX: Connection closed. Should probably wait for another
3193 connection before continuing. */
Peter Wu5819e3e2016-06-05 16:35:48 +02003194 if (n == 0) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003195 close(gdbserver_state.fd);
Peter Wu5819e3e2016-06-05 16:35:48 +02003196 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003197 gdbserver_state.fd = -1;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003198 return sig;
bellard1fddef42005-04-17 19:16:13 +00003199 }
Andreas Färber5ca666c2013-06-24 19:20:57 +02003200 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003201 sig = gdbserver_state.signal;
3202 gdbserver_state.signal = 0;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003203 return sig;
bellard1fddef42005-04-17 19:16:13 +00003204}
bellarde9009672005-04-26 20:42:36 +00003205
aurel32ca587a82008-12-18 22:44:13 +00003206/* Tell the remote gdb that the process has exited due to SIG. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01003207void gdb_signalled(CPUArchState *env, int sig)
aurel32ca587a82008-12-18 22:44:13 +00003208{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003209 char buf[4];
aurel32ca587a82008-12-18 22:44:13 +00003210
Alex Bennéee0a1e202020-04-30 20:01:18 +01003211 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003212 return;
3213 }
aurel32ca587a82008-12-18 22:44:13 +00003214
Andreas Färber5ca666c2013-06-24 19:20:57 +02003215 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003216 put_packet(buf);
aurel32ca587a82008-12-18 22:44:13 +00003217}
bellard1fddef42005-04-17 19:16:13 +00003218
Alex Bennéefcedd922020-04-30 20:01:19 +01003219static void gdb_accept_init(int fd)
3220{
3221 init_gdbserver_state();
3222 create_default_process(&gdbserver_state);
3223 gdbserver_state.processes[0].attached = true;
3224 gdbserver_state.c_cpu = gdb_first_attached_cpu();
3225 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
3226 gdbserver_state.fd = fd;
3227 gdb_has_xml = false;
3228}
3229
3230static bool gdb_accept_socket(int gdb_fd)
3231{
3232 int fd;
3233
3234 for(;;) {
3235 fd = accept(gdb_fd, NULL, NULL);
3236 if (fd < 0 && errno != EINTR) {
3237 perror("accept socket");
3238 return false;
3239 } else if (fd >= 0) {
3240 qemu_set_cloexec(fd);
3241 break;
3242 }
3243 }
3244
3245 gdb_accept_init(fd);
3246 return true;
3247}
3248
3249static int gdbserver_open_socket(const char *path)
3250{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003251 struct sockaddr_un sockaddr = {};
Alex Bennéefcedd922020-04-30 20:01:19 +01003252 int fd, ret;
3253
3254 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3255 if (fd < 0) {
3256 perror("create socket");
3257 return -1;
3258 }
3259
3260 sockaddr.sun_family = AF_UNIX;
3261 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
3262 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3263 if (ret < 0) {
3264 perror("bind socket");
3265 close(fd);
3266 return -1;
3267 }
3268 ret = listen(fd, 1);
3269 if (ret < 0) {
3270 perror("listen socket");
3271 close(fd);
3272 return -1;
3273 }
3274
3275 return fd;
3276}
3277
3278static bool gdb_accept_tcp(int gdb_fd)
bellard858693c2004-03-31 18:52:07 +00003279{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003280 struct sockaddr_in sockaddr = {};
bellard858693c2004-03-31 18:52:07 +00003281 socklen_t len;
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09003282 int fd;
bellard858693c2004-03-31 18:52:07 +00003283
3284 for(;;) {
3285 len = sizeof(sockaddr);
Alex Bennéee0a1e202020-04-30 20:01:18 +01003286 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
bellard858693c2004-03-31 18:52:07 +00003287 if (fd < 0 && errno != EINTR) {
3288 perror("accept");
Peter Maydell2f652222018-05-14 18:30:44 +01003289 return false;
bellard858693c2004-03-31 18:52:07 +00003290 } else if (fd >= 0) {
Peter Maydellf5bdd782018-05-14 18:30:43 +01003291 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003292 break;
3293 }
3294 }
3295
3296 /* set short latency */
Peter Maydell2f652222018-05-14 18:30:44 +01003297 if (socket_set_nodelay(fd)) {
3298 perror("setsockopt");
Philippe Mathieu-Daudéead75d82018-05-24 19:34:58 -03003299 close(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003300 return false;
3301 }
ths3b46e622007-09-17 08:09:54 +00003302
Alex Bennéefcedd922020-04-30 20:01:19 +01003303 gdb_accept_init(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003304 return true;
bellard858693c2004-03-31 18:52:07 +00003305}
3306
Alex Bennéefcedd922020-04-30 20:01:19 +01003307static int gdbserver_open_port(int port)
bellard858693c2004-03-31 18:52:07 +00003308{
3309 struct sockaddr_in sockaddr;
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003310 int fd, ret;
bellard858693c2004-03-31 18:52:07 +00003311
3312 fd = socket(PF_INET, SOCK_STREAM, 0);
3313 if (fd < 0) {
3314 perror("socket");
3315 return -1;
3316 }
Peter Maydellf5bdd782018-05-14 18:30:43 +01003317 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003318
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003319 socket_set_fast_reuse(fd);
bellard858693c2004-03-31 18:52:07 +00003320
3321 sockaddr.sin_family = AF_INET;
3322 sockaddr.sin_port = htons(port);
3323 sockaddr.sin_addr.s_addr = 0;
3324 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3325 if (ret < 0) {
3326 perror("bind");
Peter Maydellbb161722011-12-24 23:37:24 +00003327 close(fd);
bellard858693c2004-03-31 18:52:07 +00003328 return -1;
3329 }
Peter Wu96165b92016-05-04 11:32:17 +02003330 ret = listen(fd, 1);
bellard858693c2004-03-31 18:52:07 +00003331 if (ret < 0) {
3332 perror("listen");
Peter Maydellbb161722011-12-24 23:37:24 +00003333 close(fd);
bellard858693c2004-03-31 18:52:07 +00003334 return -1;
3335 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003336
bellard858693c2004-03-31 18:52:07 +00003337 return fd;
3338}
3339
Alex Bennéefcedd922020-04-30 20:01:19 +01003340int gdbserver_start(const char *port_or_path)
bellard858693c2004-03-31 18:52:07 +00003341{
Alex Bennéefcedd922020-04-30 20:01:19 +01003342 int port = g_ascii_strtoull(port_or_path, NULL, 10);
3343 int gdb_fd;
3344
3345 if (port > 0) {
3346 gdb_fd = gdbserver_open_port(port);
3347 } else {
3348 gdb_fd = gdbserver_open_socket(port_or_path);
3349 }
3350
Alex Bennéee0a1e202020-04-30 20:01:18 +01003351 if (gdb_fd < 0) {
bellard858693c2004-03-31 18:52:07 +00003352 return -1;
Alex Bennéee0a1e202020-04-30 20:01:18 +01003353 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003354
3355 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3356 return 0;
3357 } else if (gdb_accept_socket(gdb_fd)) {
3358 gdbserver_state.socket_path = g_strdup(port_or_path);
3359 return 0;
Peter Maydell2f652222018-05-14 18:30:44 +01003360 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003361
3362 /* gone wrong */
3363 close(gdb_fd);
3364 return -1;
bellardb4608c02003-06-27 17:34:32 +00003365}
aurel322b1319c2008-12-18 22:44:04 +00003366
3367/* Disable gdb stub for child processes. */
Peter Crosthwaitef7ec7f72015-06-23 19:31:16 -07003368void gdbserver_fork(CPUState *cpu)
aurel322b1319c2008-12-18 22:44:04 +00003369{
Alex Bennéee0a1e202020-04-30 20:01:18 +01003370 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber75a34032013-09-02 16:57:02 +02003371 return;
3372 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003373 close(gdbserver_state.fd);
3374 gdbserver_state.fd = -1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02003375 cpu_breakpoint_remove_all(cpu, BP_GDB);
Andreas Färber75a34032013-09-02 16:57:02 +02003376 cpu_watchpoint_remove_all(cpu, BP_GDB);
aurel322b1319c2008-12-18 22:44:04 +00003377}
pbrook4046d912007-01-28 01:53:16 +00003378#else
thsaa1f17c2007-07-11 22:48:58 +00003379static int gdb_chr_can_receive(void *opaque)
pbrook4046d912007-01-28 01:53:16 +00003380{
pbrook56aebc82008-10-11 17:55:29 +00003381 /* We can handle an arbitrarily large amount of data.
3382 Pick the maximum packet size, which is as good as anything. */
3383 return MAX_PACKET_LENGTH;
pbrook4046d912007-01-28 01:53:16 +00003384}
3385
thsaa1f17c2007-07-11 22:48:58 +00003386static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
pbrook4046d912007-01-28 01:53:16 +00003387{
pbrook4046d912007-01-28 01:53:16 +00003388 int i;
3389
3390 for (i = 0; i < size; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003391 gdb_read_byte(buf[i]);
pbrook4046d912007-01-28 01:53:16 +00003392 }
3393}
3394
Philippe Mathieu-Daudé083b2662019-12-18 18:20:09 +01003395static void gdb_chr_event(void *opaque, QEMUChrEvent event)
pbrook4046d912007-01-28 01:53:16 +00003396{
Luc Michel970ed902019-01-07 15:23:46 +00003397 int i;
3398 GDBState *s = (GDBState *) opaque;
3399
pbrook4046d912007-01-28 01:53:16 +00003400 switch (event) {
Amit Shahb6b8df52009-10-07 18:31:16 +05303401 case CHR_EVENT_OPENED:
Luc Michel970ed902019-01-07 15:23:46 +00003402 /* Start with first process attached, others detached */
3403 for (i = 0; i < s->process_num; i++) {
3404 s->processes[i].attached = !i;
3405 }
3406
Alex Bennéea346af32020-03-16 17:21:34 +00003407 s->c_cpu = gdb_first_attached_cpu();
Luc Michel970ed902019-01-07 15:23:46 +00003408 s->g_cpu = s->c_cpu;
3409
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003410 vm_stop(RUN_STATE_PAUSED);
Pavel Dovgalyuk56357d82020-10-03 20:14:01 +03003411 replay_gdb_attached();
Andreas Färber5b50e792013-06-29 04:18:45 +02003412 gdb_has_xml = false;
pbrook4046d912007-01-28 01:53:16 +00003413 break;
3414 default:
3415 break;
3416 }
3417}
3418
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003419static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
aliguori8a34a0f2009-03-05 23:01:55 +00003420{
Damien Hedded86b4672020-03-16 17:21:54 +00003421 g_autoptr(GString) hex_buf = g_string_new("O");
3422 memtohex(hex_buf, buf, len);
3423 put_packet(hex_buf->str);
aliguori8a34a0f2009-03-05 23:01:55 +00003424 return len;
3425}
3426
aliguori59030a82009-04-05 18:43:41 +00003427#ifndef _WIN32
3428static void gdb_sigterm_handler(int signal)
3429{
Luiz Capitulino13548692011-07-29 15:36:43 -03003430 if (runstate_is_running()) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003431 vm_stop(RUN_STATE_PAUSED);
Jan Kiszkae07bbac2011-02-09 16:29:40 +01003432 }
aliguori59030a82009-04-05 18:43:41 +00003433}
3434#endif
3435
Marc-André Lureau777357d2016-12-07 18:39:10 +03003436static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
3437 bool *be_opened, Error **errp)
3438{
3439 *be_opened = false;
3440}
3441
3442static void char_gdb_class_init(ObjectClass *oc, void *data)
3443{
3444 ChardevClass *cc = CHARDEV_CLASS(oc);
3445
3446 cc->internal = true;
3447 cc->open = gdb_monitor_open;
3448 cc->chr_write = gdb_monitor_write;
3449}
3450
3451#define TYPE_CHARDEV_GDB "chardev-gdb"
3452
3453static const TypeInfo char_gdb_type_info = {
3454 .name = TYPE_CHARDEV_GDB,
3455 .parent = TYPE_CHARDEV,
3456 .class_init = char_gdb_class_init,
3457};
3458
Luc Michel8f468632019-01-07 15:23:45 +00003459static int find_cpu_clusters(Object *child, void *opaque)
3460{
3461 if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
3462 GDBState *s = (GDBState *) opaque;
3463 CPUClusterState *cluster = CPU_CLUSTER(child);
3464 GDBProcess *process;
3465
3466 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3467
3468 process = &s->processes[s->process_num - 1];
3469
3470 /*
3471 * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
3472 * runtime, we enforce here that the machine does not use a cluster ID
3473 * that would lead to PID 0.
3474 */
3475 assert(cluster->cluster_id != UINT32_MAX);
3476 process->pid = cluster->cluster_id + 1;
3477 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003478 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003479
3480 return 0;
3481 }
3482
3483 return object_child_foreach(child, find_cpu_clusters, opaque);
3484}
3485
3486static int pid_order(const void *a, const void *b)
3487{
3488 GDBProcess *pa = (GDBProcess *) a;
3489 GDBProcess *pb = (GDBProcess *) b;
3490
3491 if (pa->pid < pb->pid) {
3492 return -1;
3493 } else if (pa->pid > pb->pid) {
3494 return 1;
3495 } else {
3496 return 0;
3497 }
3498}
3499
3500static void create_processes(GDBState *s)
3501{
3502 object_child_foreach(object_get_root(), find_cpu_clusters, s);
3503
Alex Bennéea346af32020-03-16 17:21:34 +00003504 if (gdbserver_state.processes) {
Luc Michel8f468632019-01-07 15:23:45 +00003505 /* Sort by PID */
Alex Bennéea346af32020-03-16 17:21:34 +00003506 qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
Luc Michel8f468632019-01-07 15:23:45 +00003507 }
3508
3509 create_default_process(s);
3510}
3511
aliguori59030a82009-04-05 18:43:41 +00003512int gdbserver_start(const char *device)
pbrook4046d912007-01-28 01:53:16 +00003513{
Doug Gale5c9522b2017-12-02 20:30:37 -05003514 trace_gdbstub_op_start(device);
3515
aliguori59030a82009-04-05 18:43:41 +00003516 char gdbstub_device_name[128];
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003517 Chardev *chr = NULL;
3518 Chardev *mon_chr;
pbrook4046d912007-01-28 01:53:16 +00003519
Ziyue Yang508b4ec2017-01-18 16:02:41 +08003520 if (!first_cpu) {
3521 error_report("gdbstub: meaningless to attach gdb to a "
3522 "machine without any CPU.");
3523 return -1;
3524 }
3525
Maxim Levitsky12bc5b42021-11-11 12:06:03 +01003526 if (kvm_enabled() && !kvm_supports_guest_debug()) {
3527 error_report("gdbstub: KVM doesn't support guest debugging");
3528 return -1;
3529 }
3530
aliguori59030a82009-04-05 18:43:41 +00003531 if (!device)
3532 return -1;
3533 if (strcmp(device, "none") != 0) {
3534 if (strstart(device, "tcp:", NULL)) {
3535 /* enforce required TCP attributes */
3536 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
Paolo Bonzinia9b13152021-02-25 11:47:52 +01003537 "%s,wait=off,nodelay=on,server=on", device);
aliguori59030a82009-04-05 18:43:41 +00003538 device = gdbstub_device_name;
aliguori36556b22009-03-28 18:05:53 +00003539 }
aliguori59030a82009-04-05 18:43:41 +00003540#ifndef _WIN32
3541 else if (strcmp(device, "stdio") == 0) {
3542 struct sigaction act;
pbrookcfc34752007-02-22 01:48:01 +00003543
aliguori59030a82009-04-05 18:43:41 +00003544 memset(&act, 0, sizeof(act));
3545 act.sa_handler = gdb_sigterm_handler;
3546 sigaction(SIGINT, &act, NULL);
3547 }
3548#endif
Marc-André Lureau95e30b22018-08-22 19:19:42 +02003549 /*
3550 * FIXME: it's a bit weird to allow using a mux chardev here
3551 * and implicitly setup a monitor. We may want to break this.
3552 */
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003553 chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
aliguori36556b22009-03-28 18:05:53 +00003554 if (!chr)
3555 return -1;
pbrookcfc34752007-02-22 01:48:01 +00003556 }
3557
Alex Bennée8d98c442020-03-16 17:21:33 +00003558 if (!gdbserver_state.init) {
3559 init_gdbserver_state();
pbrook4046d912007-01-28 01:53:16 +00003560
aliguori36556b22009-03-28 18:05:53 +00003561 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
3562
3563 /* Initialize a monitor terminal for gdb */
Marc-André Lureau777357d2016-12-07 18:39:10 +03003564 mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003565 NULL, NULL, &error_abort);
Kevin Wolf8e9119a2020-02-24 15:30:06 +01003566 monitor_init_hmp(mon_chr, false, &error_abort);
aliguori36556b22009-03-28 18:05:53 +00003567 } else {
Alex Bennée8d98c442020-03-16 17:21:33 +00003568 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
3569 mon_chr = gdbserver_state.mon_chr;
3570 reset_gdbserver_state();
aliguori36556b22009-03-28 18:05:53 +00003571 }
Luc Michel8f468632019-01-07 15:23:45 +00003572
Alex Bennée8d98c442020-03-16 17:21:33 +00003573 create_processes(&gdbserver_state);
Luc Michel8f468632019-01-07 15:23:45 +00003574
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003575 if (chr) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003576 qemu_chr_fe_init(&gdbserver_state.chr, chr, &error_abort);
3577 qemu_chr_fe_set_handlers(&gdbserver_state.chr, gdb_chr_can_receive,
3578 gdb_chr_receive, gdb_chr_event,
3579 NULL, &gdbserver_state, NULL, true);
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003580 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003581 gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
3582 gdbserver_state.mon_chr = mon_chr;
3583 gdbserver_state.current_syscall_cb = NULL;
aliguori8a34a0f2009-03-05 23:01:55 +00003584
pbrook4046d912007-01-28 01:53:16 +00003585 return 0;
3586}
Marc-André Lureau777357d2016-12-07 18:39:10 +03003587
3588static void register_types(void)
3589{
3590 type_register_static(&char_gdb_type_info);
3591}
3592
3593type_init(register_types);
pbrook4046d912007-01-28 01:53:16 +00003594#endif