blob: a955175fd415a517af7e9db2cdb378cc2cfdde25 [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;
394 } else {
395 gdbserver_state.supported_sstep_flags =
396 SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
397 }
398
399 /*
400 * By default use no IRQs and no timers while single stepping so as to
401 * make single stepping like an ICE HW step.
402 */
403 gdbserver_state.sstep_flags = gdbserver_state.supported_sstep_flags;
404
Alex Bennée8d98c442020-03-16 17:21:33 +0000405}
406
407#ifndef CONFIG_USER_ONLY
408static void reset_gdbserver_state(void)
409{
410 g_free(gdbserver_state.processes);
411 gdbserver_state.processes = NULL;
412 gdbserver_state.process_num = 0;
413}
414#endif
aliguori880a7572008-11-18 20:30:24 +0000415
Andreas Färber5b50e792013-06-29 04:18:45 +0200416bool gdb_has_xml;
pbrook56aebc82008-10-11 17:55:29 +0000417
bellard1fddef42005-04-17 19:16:13 +0000418#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000419
Alex Bennéea346af32020-03-16 17:21:34 +0000420static int get_char(void)
bellardb4608c02003-06-27 17:34:32 +0000421{
422 uint8_t ch;
423 int ret;
424
425 for(;;) {
Alex Bennéea346af32020-03-16 17:21:34 +0000426 ret = qemu_recv(gdbserver_state.fd, &ch, 1, 0);
bellardb4608c02003-06-27 17:34:32 +0000427 if (ret < 0) {
edgar_igl1f487ee2008-05-17 22:20:53 +0000428 if (errno == ECONNRESET)
Alex Bennéea346af32020-03-16 17:21:34 +0000429 gdbserver_state.fd = -1;
Peter Wu5819e3e2016-06-05 16:35:48 +0200430 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000431 return -1;
432 } else if (ret == 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000433 close(gdbserver_state.fd);
434 gdbserver_state.fd = -1;
bellardb4608c02003-06-27 17:34:32 +0000435 return -1;
436 } else {
437 break;
438 }
439 }
440 return ch;
441}
pbrook4046d912007-01-28 01:53:16 +0000442#endif
bellardb4608c02003-06-27 17:34:32 +0000443
blueswir1654efcf2009-04-18 07:29:59 +0000444static enum {
pbrooka2d1eba2007-01-28 03:10:55 +0000445 GDB_SYS_UNKNOWN,
446 GDB_SYS_ENABLED,
447 GDB_SYS_DISABLED,
448} gdb_syscall_mode;
449
Liviu Ionescua38bb072014-12-11 12:07:48 +0000450/* Decide if either remote gdb syscalls or native file IO should be used. */
pbrooka2d1eba2007-01-28 03:10:55 +0000451int use_gdb_syscalls(void)
452{
Leon Alraecfe67ce2015-06-19 14:17:45 +0100453 SemihostingTarget target = semihosting_get_target();
454 if (target == SEMIHOSTING_TARGET_NATIVE) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000455 /* -semihosting-config target=native */
456 return false;
Leon Alraecfe67ce2015-06-19 14:17:45 +0100457 } else if (target == SEMIHOSTING_TARGET_GDB) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000458 /* -semihosting-config target=gdb */
459 return true;
460 }
461
462 /* -semihosting-config target=auto */
463 /* On the first call check if gdb is connected and remember. */
pbrooka2d1eba2007-01-28 03:10:55 +0000464 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
Alex Bennée8d98c442020-03-16 17:21:33 +0000465 gdb_syscall_mode = gdbserver_state.init ?
466 GDB_SYS_ENABLED : GDB_SYS_DISABLED;
pbrooka2d1eba2007-01-28 03:10:55 +0000467 }
468 return gdb_syscall_mode == GDB_SYS_ENABLED;
469}
470
Alex Bennéeed12f5b2021-05-20 18:43:02 +0100471static bool stub_can_reverse(void)
472{
473#ifdef CONFIG_USER_ONLY
474 return false;
475#else
476 return replay_mode == REPLAY_MODE_PLAY;
477#endif
478}
479
edgar_iglba70a622008-03-14 06:10:42 +0000480/* Resume execution. */
Alex Bennéea346af32020-03-16 17:21:34 +0000481static inline void gdb_continue(void)
edgar_iglba70a622008-03-14 06:10:42 +0000482{
Doug Gale5c9522b2017-12-02 20:30:37 -0500483
edgar_iglba70a622008-03-14 06:10:42 +0000484#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000485 gdbserver_state.running_state = 1;
Doug Gale5c9522b2017-12-02 20:30:37 -0500486 trace_gdbstub_op_continue();
edgar_iglba70a622008-03-14 06:10:42 +0000487#else
Paolo Bonzini26ac7a32013-06-03 17:06:54 +0200488 if (!runstate_needs_reset()) {
Doug Gale5c9522b2017-12-02 20:30:37 -0500489 trace_gdbstub_op_continue();
Paolo Bonzini87f25c12013-05-30 13:20:40 +0200490 vm_start();
491 }
edgar_iglba70a622008-03-14 06:10:42 +0000492#endif
493}
494
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100495/*
496 * Resume execution, per CPU actions. For user-mode emulation it's
497 * equivalent to gdb_continue.
498 */
Alex Bennéea346af32020-03-16 17:21:34 +0000499static int gdb_continue_partial(char *newstates)
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100500{
501 CPUState *cpu;
502 int res = 0;
503#ifdef CONFIG_USER_ONLY
504 /*
505 * This is not exactly accurate, but it's an improvement compared to the
506 * previous situation, where only one CPU would be single-stepped.
507 */
508 CPU_FOREACH(cpu) {
509 if (newstates[cpu->cpu_index] == 's') {
Doug Gale5c9522b2017-12-02 20:30:37 -0500510 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100511 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100512 }
513 }
Alex Bennéea346af32020-03-16 17:21:34 +0000514 gdbserver_state.running_state = 1;
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100515#else
516 int flag = 0;
517
518 if (!runstate_needs_reset()) {
519 if (vm_prepare_start()) {
520 return 0;
521 }
522
523 CPU_FOREACH(cpu) {
524 switch (newstates[cpu->cpu_index]) {
525 case 0:
526 case 1:
527 break; /* nothing to do here */
528 case 's':
Doug Gale5c9522b2017-12-02 20:30:37 -0500529 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100530 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100531 cpu_resume(cpu);
532 flag = 1;
533 break;
534 case 'c':
Doug Gale5c9522b2017-12-02 20:30:37 -0500535 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100536 cpu_resume(cpu);
537 flag = 1;
538 break;
539 default:
540 res = -1;
541 break;
542 }
543 }
544 }
545 if (flag) {
546 qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
547 }
548#endif
549 return res;
550}
551
Alex Bennéea346af32020-03-16 17:21:34 +0000552static void put_buffer(const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000553{
pbrook4046d912007-01-28 01:53:16 +0000554#ifdef CONFIG_USER_ONLY
bellardb4608c02003-06-27 17:34:32 +0000555 int ret;
556
557 while (len > 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000558 ret = send(gdbserver_state.fd, buf, len, 0);
bellardb4608c02003-06-27 17:34:32 +0000559 if (ret < 0) {
Peter Wu5819e3e2016-06-05 16:35:48 +0200560 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000561 return;
562 } else {
563 buf += ret;
564 len -= ret;
565 }
566 }
pbrook4046d912007-01-28 01:53:16 +0000567#else
Daniel P. Berrange6ab3fc32016-09-06 14:56:04 +0100568 /* XXX this blocks entire thread. Rewrite to use
569 * qemu_chr_fe_write and background I/O callbacks */
Alex Bennéea346af32020-03-16 17:21:34 +0000570 qemu_chr_fe_write_all(&gdbserver_state.chr, buf, len);
pbrook4046d912007-01-28 01:53:16 +0000571#endif
bellardb4608c02003-06-27 17:34:32 +0000572}
573
574static inline int fromhex(int v)
575{
576 if (v >= '0' && v <= '9')
577 return v - '0';
578 else if (v >= 'A' && v <= 'F')
579 return v - 'A' + 10;
580 else if (v >= 'a' && v <= 'f')
581 return v - 'a' + 10;
582 else
583 return 0;
584}
585
586static inline int tohex(int v)
587{
588 if (v < 10)
589 return v + '0';
590 else
591 return v - 10 + 'a';
592}
593
Philippe Mathieu-Daudé90057742018-04-08 11:59:33 -0300594/* writes 2*len+1 bytes in buf */
Alex Bennée308f9e82020-03-16 17:21:35 +0000595static void memtohex(GString *buf, const uint8_t *mem, int len)
bellardb4608c02003-06-27 17:34:32 +0000596{
597 int i, c;
bellardb4608c02003-06-27 17:34:32 +0000598 for(i = 0; i < len; i++) {
599 c = mem[i];
Alex Bennée308f9e82020-03-16 17:21:35 +0000600 g_string_append_c(buf, tohex(c >> 4));
601 g_string_append_c(buf, tohex(c & 0xf));
bellardb4608c02003-06-27 17:34:32 +0000602 }
Alex Bennée308f9e82020-03-16 17:21:35 +0000603 g_string_append_c(buf, '\0');
bellardb4608c02003-06-27 17:34:32 +0000604}
605
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000606static void hextomem(GByteArray *mem, const char *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000607{
608 int i;
609
610 for(i = 0; i < len; i++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000611 guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
612 g_byte_array_append(mem, &byte, 1);
bellardb4608c02003-06-27 17:34:32 +0000613 buf += 2;
614 }
615}
616
Doug Gale5c9522b2017-12-02 20:30:37 -0500617static void hexdump(const char *buf, int len,
618 void (*trace_fn)(size_t ofs, char const *text))
619{
620 char line_buffer[3 * 16 + 4 + 16 + 1];
621
622 size_t i;
623 for (i = 0; i < len || (i & 0xF); ++i) {
624 size_t byte_ofs = i & 15;
625
626 if (byte_ofs == 0) {
627 memset(line_buffer, ' ', 3 * 16 + 4 + 16);
628 line_buffer[3 * 16 + 4 + 16] = 0;
629 }
630
631 size_t col_group = (i >> 2) & 3;
632 size_t hex_col = byte_ofs * 3 + col_group;
633 size_t txt_col = 3 * 16 + 4 + byte_ofs;
634
635 if (i < len) {
636 char value = buf[i];
637
638 line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
639 line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
640 line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
641 ? value
642 : '.';
643 }
644
645 if (byte_ofs == 0xF)
646 trace_fn(i & -16, line_buffer);
647 }
648}
649
bellardb4608c02003-06-27 17:34:32 +0000650/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000651static int put_packet_binary(const char *buf, int len, bool dump)
bellardb4608c02003-06-27 17:34:32 +0000652{
pbrook56aebc82008-10-11 17:55:29 +0000653 int csum, i;
Damien Hedded116e812020-03-16 17:21:53 +0000654 uint8_t footer[3];
bellardb4608c02003-06-27 17:34:32 +0000655
Doug Gale5c9522b2017-12-02 20:30:37 -0500656 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
657 hexdump(buf, len, trace_gdbstub_io_binaryreply);
658 }
659
bellardb4608c02003-06-27 17:34:32 +0000660 for(;;) {
Damien Hedded116e812020-03-16 17:21:53 +0000661 g_byte_array_set_size(gdbserver_state.last_packet, 0);
662 g_byte_array_append(gdbserver_state.last_packet,
663 (const uint8_t *) "$", 1);
664 g_byte_array_append(gdbserver_state.last_packet,
665 (const uint8_t *) buf, len);
bellardb4608c02003-06-27 17:34:32 +0000666 csum = 0;
667 for(i = 0; i < len; i++) {
668 csum += buf[i];
669 }
Damien Hedded116e812020-03-16 17:21:53 +0000670 footer[0] = '#';
671 footer[1] = tohex((csum >> 4) & 0xf);
672 footer[2] = tohex((csum) & 0xf);
673 g_byte_array_append(gdbserver_state.last_packet, footer, 3);
bellardb4608c02003-06-27 17:34:32 +0000674
Damien Hedded116e812020-03-16 17:21:53 +0000675 put_buffer(gdbserver_state.last_packet->data,
676 gdbserver_state.last_packet->len);
bellardb4608c02003-06-27 17:34:32 +0000677
pbrook4046d912007-01-28 01:53:16 +0000678#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000679 i = get_char();
pbrook4046d912007-01-28 01:53:16 +0000680 if (i < 0)
bellardb4608c02003-06-27 17:34:32 +0000681 return -1;
pbrook4046d912007-01-28 01:53:16 +0000682 if (i == '+')
bellardb4608c02003-06-27 17:34:32 +0000683 break;
pbrook4046d912007-01-28 01:53:16 +0000684#else
685 break;
686#endif
bellardb4608c02003-06-27 17:34:32 +0000687 }
688 return 0;
689}
690
pbrook56aebc82008-10-11 17:55:29 +0000691/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000692static int put_packet(const char *buf)
pbrook56aebc82008-10-11 17:55:29 +0000693{
Doug Gale5c9522b2017-12-02 20:30:37 -0500694 trace_gdbstub_io_reply(buf);
pbrook56aebc82008-10-11 17:55:29 +0000695
Alex Bennéea346af32020-03-16 17:21:34 +0000696 return put_packet_binary(buf, strlen(buf), false);
pbrook56aebc82008-10-11 17:55:29 +0000697}
698
Alex Bennée308f9e82020-03-16 17:21:35 +0000699static void put_strbuf(void)
pbrook56aebc82008-10-11 17:55:29 +0000700{
Alex Bennée308f9e82020-03-16 17:21:35 +0000701 put_packet(gdbserver_state.str_buf->str);
702}
703
704/* Encode data using the encoding for 'x' packets. */
705static void memtox(GString *buf, const char *mem, int len)
706{
pbrook56aebc82008-10-11 17:55:29 +0000707 char c;
708
709 while (len--) {
710 c = *(mem++);
711 switch (c) {
712 case '#': case '$': case '*': case '}':
Alex Bennée308f9e82020-03-16 17:21:35 +0000713 g_string_append_c(buf, '}');
714 g_string_append_c(buf, c ^ 0x20);
pbrook56aebc82008-10-11 17:55:29 +0000715 break;
716 default:
Alex Bennée308f9e82020-03-16 17:21:35 +0000717 g_string_append_c(buf, c);
pbrook56aebc82008-10-11 17:55:29 +0000718 break;
719 }
720 }
pbrook56aebc82008-10-11 17:55:29 +0000721}
722
Alex Bennéea346af32020-03-16 17:21:34 +0000723static uint32_t gdb_get_cpu_pid(CPUState *cpu)
Luc Michel1a227332019-01-07 15:23:45 +0000724{
Luc Michel1a227332019-01-07 15:23:45 +0000725 /* TODO: In user mode, we should use the task state PID */
Peter Maydell46f5abc2019-01-29 11:46:06 +0000726 if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
727 /* Return the default process' PID */
Alex Bennéea346af32020-03-16 17:21:34 +0000728 int index = gdbserver_state.process_num - 1;
729 return gdbserver_state.processes[index].pid;
Peter Maydell46f5abc2019-01-29 11:46:06 +0000730 }
731 return cpu->cluster_index + 1;
Luc Michel1a227332019-01-07 15:23:45 +0000732}
733
Alex Bennéea346af32020-03-16 17:21:34 +0000734static GDBProcess *gdb_get_process(uint32_t pid)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000735{
736 int i;
737
738 if (!pid) {
739 /* 0 means any process, we take the first one */
Alex Bennéea346af32020-03-16 17:21:34 +0000740 return &gdbserver_state.processes[0];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000741 }
742
Alex Bennéea346af32020-03-16 17:21:34 +0000743 for (i = 0; i < gdbserver_state.process_num; i++) {
744 if (gdbserver_state.processes[i].pid == pid) {
745 return &gdbserver_state.processes[i];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000746 }
747 }
748
749 return NULL;
750}
751
Alex Bennéea346af32020-03-16 17:21:34 +0000752static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000753{
Alex Bennéea346af32020-03-16 17:21:34 +0000754 return gdb_get_process(gdb_get_cpu_pid(cpu));
Luc Michel7d8c87d2019-01-07 15:23:45 +0000755}
756
757static CPUState *find_cpu(uint32_t thread_id)
758{
759 CPUState *cpu;
760
761 CPU_FOREACH(cpu) {
762 if (cpu_gdb_index(cpu) == thread_id) {
763 return cpu;
764 }
765 }
766
767 return NULL;
768}
769
Alex Bennéea346af32020-03-16 17:21:34 +0000770static CPUState *get_first_cpu_in_process(GDBProcess *process)
Luc Michele40e5202019-01-07 15:23:46 +0000771{
772 CPUState *cpu;
773
774 CPU_FOREACH(cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000775 if (gdb_get_cpu_pid(cpu) == process->pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000776 return cpu;
777 }
778 }
779
780 return NULL;
781}
782
Alex Bennéea346af32020-03-16 17:21:34 +0000783static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000784{
Alex Bennéea346af32020-03-16 17:21:34 +0000785 uint32_t pid = gdb_get_cpu_pid(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000786 cpu = CPU_NEXT(cpu);
787
788 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000789 if (gdb_get_cpu_pid(cpu) == pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000790 break;
791 }
792
793 cpu = CPU_NEXT(cpu);
794 }
795
796 return cpu;
797}
798
Luc Michele40e5202019-01-07 15:23:46 +0000799/* Return the cpu following @cpu, while ignoring unattached processes. */
Alex Bennéea346af32020-03-16 17:21:34 +0000800static CPUState *gdb_next_attached_cpu(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000801{
802 cpu = CPU_NEXT(cpu);
803
804 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000805 if (gdb_get_cpu_process(cpu)->attached) {
Luc Michele40e5202019-01-07 15:23:46 +0000806 break;
807 }
808
809 cpu = CPU_NEXT(cpu);
810 }
811
812 return cpu;
813}
814
815/* Return the first attached cpu */
Alex Bennéea346af32020-03-16 17:21:34 +0000816static CPUState *gdb_first_attached_cpu(void)
Luc Michele40e5202019-01-07 15:23:46 +0000817{
818 CPUState *cpu = first_cpu;
Alex Bennéea346af32020-03-16 17:21:34 +0000819 GDBProcess *process = gdb_get_cpu_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000820
821 if (!process->attached) {
Alex Bennéea346af32020-03-16 17:21:34 +0000822 return gdb_next_attached_cpu(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000823 }
824
825 return cpu;
826}
827
Alex Bennéea346af32020-03-16 17:21:34 +0000828static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
Luc Michelab65eed2019-01-29 11:46:03 +0000829{
830 GDBProcess *process;
831 CPUState *cpu;
832
833 if (!pid && !tid) {
834 /* 0 means any process/thread, we take the first attached one */
Alex Bennéea346af32020-03-16 17:21:34 +0000835 return gdb_first_attached_cpu();
Luc Michelab65eed2019-01-29 11:46:03 +0000836 } else if (pid && !tid) {
837 /* any thread in a specific process */
Alex Bennéea346af32020-03-16 17:21:34 +0000838 process = gdb_get_process(pid);
Luc Michelab65eed2019-01-29 11:46:03 +0000839
840 if (process == NULL) {
841 return NULL;
842 }
843
844 if (!process->attached) {
845 return NULL;
846 }
847
Alex Bennéea346af32020-03-16 17:21:34 +0000848 return get_first_cpu_in_process(process);
Luc Michelab65eed2019-01-29 11:46:03 +0000849 } else {
850 /* a specific thread */
851 cpu = find_cpu(tid);
852
853 if (cpu == NULL) {
854 return NULL;
855 }
856
Alex Bennéea346af32020-03-16 17:21:34 +0000857 process = gdb_get_cpu_process(cpu);
Luc Michelab65eed2019-01-29 11:46:03 +0000858
859 if (pid && process->pid != pid) {
860 return NULL;
861 }
862
863 if (!process->attached) {
864 return NULL;
865 }
866
867 return cpu;
868 }
869}
870
Alex Bennéea346af32020-03-16 17:21:34 +0000871static const char *get_feature_xml(const char *p, const char **newp,
872 GDBProcess *process)
pbrook56aebc82008-10-11 17:55:29 +0000873{
pbrook56aebc82008-10-11 17:55:29 +0000874 size_t len;
875 int i;
876 const char *name;
Alex Bennéea346af32020-03-16 17:21:34 +0000877 CPUState *cpu = get_first_cpu_in_process(process);
Luc Michelc145eea2019-01-07 15:23:46 +0000878 CPUClass *cc = CPU_GET_CLASS(cpu);
pbrook56aebc82008-10-11 17:55:29 +0000879
880 len = 0;
881 while (p[len] && p[len] != ':')
882 len++;
883 *newp = p + len;
884
885 name = NULL;
886 if (strncmp(p, "target.xml", len) == 0) {
Luc Michelc145eea2019-01-07 15:23:46 +0000887 char *buf = process->target_xml;
888 const size_t buf_sz = sizeof(process->target_xml);
pbrook56aebc82008-10-11 17:55:29 +0000889
Luc Michelc145eea2019-01-07 15:23:46 +0000890 /* Generate the XML description for this CPU. */
891 if (!buf[0]) {
892 GDBRegisterState *r;
893
894 pstrcat(buf, buf_sz,
David Hildenbrandb3820e62015-12-03 13:14:41 +0100895 "<?xml version=\"1.0\"?>"
896 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
897 "<target>");
898 if (cc->gdb_arch_name) {
899 gchar *arch = cc->gdb_arch_name(cpu);
Luc Michelc145eea2019-01-07 15:23:46 +0000900 pstrcat(buf, buf_sz, "<architecture>");
901 pstrcat(buf, buf_sz, arch);
902 pstrcat(buf, buf_sz, "</architecture>");
David Hildenbrandb3820e62015-12-03 13:14:41 +0100903 g_free(arch);
904 }
Luc Michelc145eea2019-01-07 15:23:46 +0000905 pstrcat(buf, buf_sz, "<xi:include href=\"");
906 pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
907 pstrcat(buf, buf_sz, "\"/>");
Andreas Färbereac8b352013-06-28 21:11:37 +0200908 for (r = cpu->gdb_regs; r; r = r->next) {
Luc Michelc145eea2019-01-07 15:23:46 +0000909 pstrcat(buf, buf_sz, "<xi:include href=\"");
910 pstrcat(buf, buf_sz, r->xml);
911 pstrcat(buf, buf_sz, "\"/>");
pbrook56aebc82008-10-11 17:55:29 +0000912 }
Luc Michelc145eea2019-01-07 15:23:46 +0000913 pstrcat(buf, buf_sz, "</target>");
pbrook56aebc82008-10-11 17:55:29 +0000914 }
Luc Michelc145eea2019-01-07 15:23:46 +0000915 return buf;
pbrook56aebc82008-10-11 17:55:29 +0000916 }
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100917 if (cc->gdb_get_dynamic_xml) {
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100918 char *xmlname = g_strndup(p, len);
919 const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
920
921 g_free(xmlname);
922 if (xml) {
923 return xml;
924 }
925 }
pbrook56aebc82008-10-11 17:55:29 +0000926 for (i = 0; ; i++) {
927 name = xml_builtin[i][0];
928 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
929 break;
930 }
931 return name ? xml_builtin[i][1] : NULL;
932}
pbrook56aebc82008-10-11 17:55:29 +0000933
Alex Bennéea010bdb2020-03-16 17:21:41 +0000934static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000935{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200936 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200937 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000938 GDBRegisterState *r;
939
Andreas Färbera0e372f2013-06-28 23:18:47 +0200940 if (reg < cc->gdb_num_core_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000941 return cc->gdb_read_register(cpu, buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200942 }
pbrook56aebc82008-10-11 17:55:29 +0000943
Andreas Färbereac8b352013-06-28 21:11:37 +0200944 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000945 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000946 return r->get_reg(env, buf, reg - r->base_reg);
pbrook56aebc82008-10-11 17:55:29 +0000947 }
948 }
949 return 0;
950}
951
Andreas Färber385b9f02013-06-27 18:25:36 +0200952static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000953{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200954 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200955 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000956 GDBRegisterState *r;
957
Andreas Färbera0e372f2013-06-28 23:18:47 +0200958 if (reg < cc->gdb_num_core_regs) {
Andreas Färber5b50e792013-06-29 04:18:45 +0200959 return cc->gdb_write_register(cpu, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200960 }
pbrook56aebc82008-10-11 17:55:29 +0000961
Andreas Färbereac8b352013-06-28 21:11:37 +0200962 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000963 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
964 return r->set_reg(env, mem_buf, reg - r->base_reg);
965 }
966 }
967 return 0;
968}
969
970/* Register a supplemental set of CPU registers. If g_pos is nonzero it
971 specifies the first register number and these registers are included in
972 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
973 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
974 */
975
Andreas Färber22169d42013-06-28 21:27:39 +0200976void gdb_register_coprocessor(CPUState *cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +0000977 gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
Andreas Färber22169d42013-06-28 21:27:39 +0200978 int num_regs, const char *xml, int g_pos)
pbrook56aebc82008-10-11 17:55:29 +0000979{
980 GDBRegisterState *s;
981 GDBRegisterState **p;
pbrook56aebc82008-10-11 17:55:29 +0000982
Andreas Färbereac8b352013-06-28 21:11:37 +0200983 p = &cpu->gdb_regs;
pbrook56aebc82008-10-11 17:55:29 +0000984 while (*p) {
985 /* Check for duplicates. */
986 if (strcmp((*p)->xml, xml) == 0)
987 return;
988 p = &(*p)->next;
989 }
Stefan Weil9643c252011-10-18 22:25:38 +0200990
991 s = g_new0(GDBRegisterState, 1);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200992 s->base_reg = cpu->gdb_num_regs;
Stefan Weil9643c252011-10-18 22:25:38 +0200993 s->num_regs = num_regs;
994 s->get_reg = get_reg;
995 s->set_reg = set_reg;
996 s->xml = xml;
997
pbrook56aebc82008-10-11 17:55:29 +0000998 /* Add to end of list. */
Andreas Färbera0e372f2013-06-28 23:18:47 +0200999 cpu->gdb_num_regs += num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001000 *p = s;
1001 if (g_pos) {
1002 if (g_pos != s->base_reg) {
Ziyue Yang7ae6c572017-01-18 16:03:29 +08001003 error_report("Error: Bad gdb register numbering for '%s', "
1004 "expected %d got %d", xml, g_pos, s->base_reg);
Andreas Färber35143f02013-08-12 18:09:47 +02001005 } else {
1006 cpu->gdb_num_g_regs = cpu->gdb_num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001007 }
1008 }
1009}
1010
aliguoria1d1bb32008-11-18 20:07:32 +00001011#ifndef CONFIG_USER_ONLY
Peter Maydell2472b6c2014-09-12 19:04:17 +01001012/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
1013static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
1014{
1015 static const int xlat[] = {
1016 [GDB_WATCHPOINT_WRITE] = BP_GDB | BP_MEM_WRITE,
1017 [GDB_WATCHPOINT_READ] = BP_GDB | BP_MEM_READ,
1018 [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1019 };
1020
1021 CPUClass *cc = CPU_GET_CLASS(cpu);
1022 int cputype = xlat[gdbtype];
1023
1024 if (cc->gdb_stop_before_watchpoint) {
1025 cputype |= BP_STOP_BEFORE_ACCESS;
1026 }
1027 return cputype;
1028}
aliguoria1d1bb32008-11-18 20:07:32 +00001029#endif
1030
Jon Doron77f6ce52019-05-29 09:41:35 +03001031static int gdb_breakpoint_insert(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001032{
Andreas Färber182735e2013-05-29 22:29:20 +02001033 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001034 int err = 0;
1035
Andreas Färber62278812013-06-27 17:12:06 +02001036 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001037 return kvm_insert_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001038 }
aliguorie22a25c2009-03-12 20:12:48 +00001039
aliguoria1d1bb32008-11-18 20:07:32 +00001040 switch (type) {
1041 case GDB_BREAKPOINT_SW:
1042 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001043 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001044 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
1045 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001046 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001047 }
aliguori880a7572008-11-18 20:30:24 +00001048 }
1049 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001050#ifndef CONFIG_USER_ONLY
1051 case GDB_WATCHPOINT_WRITE:
1052 case GDB_WATCHPOINT_READ:
1053 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001054 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001055 err = cpu_watchpoint_insert(cpu, addr, len,
1056 xlat_gdb_type(cpu, type), NULL);
1057 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001058 break;
Peter Maydell2472b6c2014-09-12 19:04:17 +01001059 }
aliguori880a7572008-11-18 20:30:24 +00001060 }
1061 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001062#endif
1063 default:
1064 return -ENOSYS;
1065 }
1066}
1067
Jon Doron77f6ce52019-05-29 09:41:35 +03001068static int gdb_breakpoint_remove(int type, target_ulong addr, target_ulong len)
aliguoria1d1bb32008-11-18 20:07:32 +00001069{
Andreas Färber182735e2013-05-29 22:29:20 +02001070 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001071 int err = 0;
1072
Andreas Färber62278812013-06-27 17:12:06 +02001073 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001074 return kvm_remove_breakpoint(gdbserver_state.c_cpu, addr, len, type);
Andreas Färber62278812013-06-27 17:12:06 +02001075 }
aliguorie22a25c2009-03-12 20:12:48 +00001076
aliguoria1d1bb32008-11-18 20:07:32 +00001077 switch (type) {
1078 case GDB_BREAKPOINT_SW:
1079 case GDB_BREAKPOINT_HW:
Andreas Färberbdc44642013-06-24 23:50:24 +02001080 CPU_FOREACH(cpu) {
Andreas Färberb3310ab2013-09-02 17:26:20 +02001081 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
1082 if (err) {
aliguori880a7572008-11-18 20:30:24 +00001083 break;
Andreas Färberb3310ab2013-09-02 17:26:20 +02001084 }
aliguori880a7572008-11-18 20:30:24 +00001085 }
1086 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001087#ifndef CONFIG_USER_ONLY
1088 case GDB_WATCHPOINT_WRITE:
1089 case GDB_WATCHPOINT_READ:
1090 case GDB_WATCHPOINT_ACCESS:
Andreas Färberbdc44642013-06-24 23:50:24 +02001091 CPU_FOREACH(cpu) {
Peter Maydell2472b6c2014-09-12 19:04:17 +01001092 err = cpu_watchpoint_remove(cpu, addr, len,
1093 xlat_gdb_type(cpu, type));
aliguori880a7572008-11-18 20:30:24 +00001094 if (err)
1095 break;
1096 }
1097 return err;
aliguoria1d1bb32008-11-18 20:07:32 +00001098#endif
1099 default:
1100 return -ENOSYS;
1101 }
1102}
1103
Luc Michel546f3c62019-01-07 15:23:46 +00001104static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
1105{
1106 cpu_breakpoint_remove_all(cpu, BP_GDB);
1107#ifndef CONFIG_USER_ONLY
1108 cpu_watchpoint_remove_all(cpu, BP_GDB);
1109#endif
1110}
1111
Alex Bennéea346af32020-03-16 17:21:34 +00001112static void gdb_process_breakpoint_remove_all(GDBProcess *p)
Luc Michel546f3c62019-01-07 15:23:46 +00001113{
Alex Bennéea346af32020-03-16 17:21:34 +00001114 CPUState *cpu = get_first_cpu_in_process(p);
Luc Michel546f3c62019-01-07 15:23:46 +00001115
1116 while (cpu) {
1117 gdb_cpu_breakpoint_remove_all(cpu);
Alex Bennéea346af32020-03-16 17:21:34 +00001118 cpu = gdb_next_cpu_in_process(cpu);
Luc Michel546f3c62019-01-07 15:23:46 +00001119 }
1120}
1121
aliguori880a7572008-11-18 20:30:24 +00001122static void gdb_breakpoint_remove_all(void)
aliguoria1d1bb32008-11-18 20:07:32 +00001123{
Andreas Färber182735e2013-05-29 22:29:20 +02001124 CPUState *cpu;
aliguori880a7572008-11-18 20:30:24 +00001125
aliguorie22a25c2009-03-12 20:12:48 +00001126 if (kvm_enabled()) {
Alex Bennée8d98c442020-03-16 17:21:33 +00001127 kvm_remove_all_breakpoints(gdbserver_state.c_cpu);
aliguorie22a25c2009-03-12 20:12:48 +00001128 return;
1129 }
1130
Andreas Färberbdc44642013-06-24 23:50:24 +02001131 CPU_FOREACH(cpu) {
Luc Michel546f3c62019-01-07 15:23:46 +00001132 gdb_cpu_breakpoint_remove_all(cpu);
aliguori880a7572008-11-18 20:30:24 +00001133 }
aliguoria1d1bb32008-11-18 20:07:32 +00001134}
1135
Alex Bennéea346af32020-03-16 17:21:34 +00001136static void gdb_set_cpu_pc(target_ulong pc)
aurel32fab9d282009-04-08 21:29:37 +00001137{
Alex Bennéea346af32020-03-16 17:21:34 +00001138 CPUState *cpu = gdbserver_state.c_cpu;
Andreas Färberf45748f2013-06-21 19:09:18 +02001139
1140 cpu_synchronize_state(cpu);
Peter Crosthwaite4a2b24e2015-06-23 20:19:21 -07001141 cpu_set_pc(cpu, pc);
aurel32fab9d282009-04-08 21:29:37 +00001142}
1143
Alex Bennée308f9e82020-03-16 17:21:35 +00001144static void gdb_append_thread_id(CPUState *cpu, GString *buf)
Luc Michel1a227332019-01-07 15:23:45 +00001145{
Alex Bennéea346af32020-03-16 17:21:34 +00001146 if (gdbserver_state.multiprocess) {
Alex Bennée308f9e82020-03-16 17:21:35 +00001147 g_string_append_printf(buf, "p%02x.%02x",
1148 gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001149 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00001150 g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001151 }
Luc Michel1a227332019-01-07 15:23:45 +00001152}
1153
Luc Michel7d8c87d2019-01-07 15:23:45 +00001154typedef enum GDBThreadIdKind {
1155 GDB_ONE_THREAD = 0,
1156 GDB_ALL_THREADS, /* One process, all threads */
1157 GDB_ALL_PROCESSES,
1158 GDB_READ_THREAD_ERR
1159} GDBThreadIdKind;
1160
1161static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
1162 uint32_t *pid, uint32_t *tid)
1163{
1164 unsigned long p, t;
1165 int ret;
1166
1167 if (*buf == 'p') {
1168 buf++;
1169 ret = qemu_strtoul(buf, &buf, 16, &p);
1170
1171 if (ret) {
1172 return GDB_READ_THREAD_ERR;
1173 }
1174
1175 /* Skip '.' */
1176 buf++;
1177 } else {
1178 p = 1;
1179 }
1180
1181 ret = qemu_strtoul(buf, &buf, 16, &t);
1182
1183 if (ret) {
1184 return GDB_READ_THREAD_ERR;
1185 }
1186
1187 *end_buf = buf;
1188
1189 if (p == -1) {
1190 return GDB_ALL_PROCESSES;
1191 }
1192
1193 if (pid) {
1194 *pid = p;
1195 }
1196
1197 if (t == -1) {
1198 return GDB_ALL_THREADS;
1199 }
1200
1201 if (tid) {
1202 *tid = t;
1203 }
1204
1205 return GDB_ONE_THREAD;
1206}
1207
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001208/**
1209 * gdb_handle_vcont - Parses and handles a vCont packet.
1210 * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1211 * a format error, 0 on success.
1212 */
Alex Bennéea346af32020-03-16 17:21:34 +00001213static int gdb_handle_vcont(const char *p)
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001214{
Luc Michele40e5202019-01-07 15:23:46 +00001215 int res, signal = 0;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001216 char cur_action;
1217 char *newstates;
1218 unsigned long tmp;
Luc Michele40e5202019-01-07 15:23:46 +00001219 uint32_t pid, tid;
1220 GDBProcess *process;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001221 CPUState *cpu;
Luc Michelc99ef792019-03-26 12:53:26 +00001222 GDBThreadIdKind kind;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001223#ifdef CONFIG_USER_ONLY
1224 int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1225
1226 CPU_FOREACH(cpu) {
1227 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1228 }
Like Xu5cc87672019-05-19 04:54:21 +08001229#else
1230 MachineState *ms = MACHINE(qdev_get_machine());
1231 unsigned int max_cpus = ms->smp.max_cpus;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001232#endif
1233 /* uninitialised CPUs stay 0 */
1234 newstates = g_new0(char, max_cpus);
1235
1236 /* mark valid CPUs with 1 */
1237 CPU_FOREACH(cpu) {
1238 newstates[cpu->cpu_index] = 1;
1239 }
1240
1241 /*
1242 * res keeps track of what error we are returning, with -ENOTSUP meaning
1243 * that the command is unknown or unsupported, thus returning an empty
1244 * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1245 * or incorrect parameters passed.
1246 */
1247 res = 0;
1248 while (*p) {
1249 if (*p++ != ';') {
1250 res = -ENOTSUP;
1251 goto out;
1252 }
1253
1254 cur_action = *p++;
1255 if (cur_action == 'C' || cur_action == 'S') {
Peter Maydell95a5bef2017-07-20 17:31:30 +01001256 cur_action = qemu_tolower(cur_action);
Peter Maydell3ddd9032020-11-21 21:03:42 +00001257 res = qemu_strtoul(p, &p, 16, &tmp);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001258 if (res) {
1259 goto out;
1260 }
1261 signal = gdb_signal_to_target(tmp);
1262 } else if (cur_action != 'c' && cur_action != 's') {
1263 /* unknown/invalid/unsupported command */
1264 res = -ENOTSUP;
1265 goto out;
1266 }
Luc Michele40e5202019-01-07 15:23:46 +00001267
Luc Michelc99ef792019-03-26 12:53:26 +00001268 if (*p == '\0' || *p == ';') {
1269 /*
1270 * No thread specifier, action is on "all threads". The
1271 * specification is unclear regarding the process to act on. We
1272 * choose all processes.
1273 */
1274 kind = GDB_ALL_PROCESSES;
1275 } else if (*p++ == ':') {
1276 kind = read_thread_id(p, &p, &pid, &tid);
1277 } else {
Luc Michele40e5202019-01-07 15:23:46 +00001278 res = -ENOTSUP;
1279 goto out;
1280 }
1281
Luc Michelc99ef792019-03-26 12:53:26 +00001282 switch (kind) {
Luc Michele40e5202019-01-07 15:23:46 +00001283 case GDB_READ_THREAD_ERR:
1284 res = -EINVAL;
1285 goto out;
1286
1287 case GDB_ALL_PROCESSES:
Alex Bennéea346af32020-03-16 17:21:34 +00001288 cpu = gdb_first_attached_cpu();
Luc Michele40e5202019-01-07 15:23:46 +00001289 while (cpu) {
1290 if (newstates[cpu->cpu_index] == 1) {
1291 newstates[cpu->cpu_index] = cur_action;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001292 }
Luc Michele40e5202019-01-07 15:23:46 +00001293
Alex Bennéea346af32020-03-16 17:21:34 +00001294 cpu = gdb_next_attached_cpu(cpu);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001295 }
Luc Michele40e5202019-01-07 15:23:46 +00001296 break;
1297
1298 case GDB_ALL_THREADS:
Alex Bennéea346af32020-03-16 17:21:34 +00001299 process = gdb_get_process(pid);
Luc Michele40e5202019-01-07 15:23:46 +00001300
1301 if (!process->attached) {
1302 res = -EINVAL;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001303 goto out;
1304 }
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001305
Alex Bennéea346af32020-03-16 17:21:34 +00001306 cpu = get_first_cpu_in_process(process);
Luc Michele40e5202019-01-07 15:23:46 +00001307 while (cpu) {
1308 if (newstates[cpu->cpu_index] == 1) {
1309 newstates[cpu->cpu_index] = cur_action;
1310 }
1311
Alex Bennéea346af32020-03-16 17:21:34 +00001312 cpu = gdb_next_cpu_in_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +00001313 }
1314 break;
1315
1316 case GDB_ONE_THREAD:
Alex Bennéea346af32020-03-16 17:21:34 +00001317 cpu = gdb_get_cpu(pid, tid);
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001318
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001319 /* invalid CPU/thread specified */
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001320 if (!cpu) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001321 res = -EINVAL;
1322 goto out;
1323 }
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001324
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001325 /* only use if no previous match occourred */
1326 if (newstates[cpu->cpu_index] == 1) {
1327 newstates[cpu->cpu_index] = cur_action;
1328 }
Luc Michele40e5202019-01-07 15:23:46 +00001329 break;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001330 }
1331 }
Alex Bennéea346af32020-03-16 17:21:34 +00001332 gdbserver_state.signal = signal;
1333 gdb_continue_partial(newstates);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001334
1335out:
1336 g_free(newstates);
1337
1338 return res;
1339}
1340
Jon Dorond14055d2019-05-29 09:41:29 +03001341typedef union GdbCmdVariant {
1342 const char *data;
1343 uint8_t opcode;
1344 unsigned long val_ul;
1345 unsigned long long val_ull;
1346 struct {
1347 GDBThreadIdKind kind;
1348 uint32_t pid;
1349 uint32_t tid;
1350 } thread_id;
1351} GdbCmdVariant;
1352
Alex Bennée26a16182021-05-25 09:24:14 +01001353#define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
1354
Jon Dorond14055d2019-05-29 09:41:29 +03001355static const char *cmd_next_param(const char *param, const char delimiter)
1356{
1357 static const char all_delimiters[] = ",;:=";
1358 char curr_delimiters[2] = {0};
1359 const char *delimiters;
1360
1361 if (delimiter == '?') {
1362 delimiters = all_delimiters;
1363 } else if (delimiter == '0') {
1364 return strchr(param, '\0');
1365 } else if (delimiter == '.' && *param) {
1366 return param + 1;
1367 } else {
1368 curr_delimiters[0] = delimiter;
1369 delimiters = curr_delimiters;
1370 }
1371
1372 param += strcspn(param, delimiters);
1373 if (*param) {
1374 param++;
1375 }
1376 return param;
1377}
1378
1379static int cmd_parse_params(const char *data, const char *schema,
Alex Bennée26a16182021-05-25 09:24:14 +01001380 GArray *params)
Jon Dorond14055d2019-05-29 09:41:29 +03001381{
Jon Dorond14055d2019-05-29 09:41:29 +03001382 const char *curr_schema, *curr_data;
1383
Alex Bennée26a16182021-05-25 09:24:14 +01001384 g_assert(schema);
1385 g_assert(params->len == 0);
Jon Dorond14055d2019-05-29 09:41:29 +03001386
1387 curr_schema = schema;
Jon Dorond14055d2019-05-29 09:41:29 +03001388 curr_data = data;
1389 while (curr_schema[0] && curr_schema[1] && *curr_data) {
Alex Bennée26a16182021-05-25 09:24:14 +01001390 GdbCmdVariant this_param;
1391
Jon Dorond14055d2019-05-29 09:41:29 +03001392 switch (curr_schema[0]) {
1393 case 'l':
1394 if (qemu_strtoul(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001395 &this_param.val_ul)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001396 return -EINVAL;
1397 }
Jon Dorond14055d2019-05-29 09:41:29 +03001398 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001399 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001400 break;
1401 case 'L':
1402 if (qemu_strtou64(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001403 (uint64_t *)&this_param.val_ull)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001404 return -EINVAL;
1405 }
Jon Dorond14055d2019-05-29 09:41:29 +03001406 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001407 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001408 break;
1409 case 's':
Alex Bennée26a16182021-05-25 09:24:14 +01001410 this_param.data = curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001411 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001412 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001413 break;
1414 case 'o':
Alex Bennée26a16182021-05-25 09:24:14 +01001415 this_param.opcode = *(uint8_t *)curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001416 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001417 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001418 break;
1419 case 't':
Alex Bennée26a16182021-05-25 09:24:14 +01001420 this_param.thread_id.kind =
Jon Dorond14055d2019-05-29 09:41:29 +03001421 read_thread_id(curr_data, &curr_data,
Alex Bennée26a16182021-05-25 09:24:14 +01001422 &this_param.thread_id.pid,
1423 &this_param.thread_id.tid);
Jon Dorond14055d2019-05-29 09:41:29 +03001424 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001425 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001426 break;
1427 case '?':
1428 curr_data = cmd_next_param(curr_data, curr_schema[1]);
1429 break;
1430 default:
1431 return -EINVAL;
1432 }
1433 curr_schema += 2;
1434 }
1435
Jon Dorond14055d2019-05-29 09:41:29 +03001436 return 0;
1437}
1438
Alex Bennée26a16182021-05-25 09:24:14 +01001439typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001440
1441/*
1442 * cmd_startswith -> cmd is compared using startswith
1443 *
1444 *
1445 * schema definitions:
1446 * Each schema parameter entry consists of 2 chars,
1447 * the first char represents the parameter type handling
1448 * the second char represents the delimiter for the next parameter
1449 *
1450 * Currently supported schema types:
1451 * 'l' -> unsigned long (stored in .val_ul)
1452 * 'L' -> unsigned long long (stored in .val_ull)
1453 * 's' -> string (stored in .data)
1454 * 'o' -> single char (stored in .opcode)
1455 * 't' -> thread id (stored in .thread_id)
1456 * '?' -> skip according to delimiter
1457 *
1458 * Currently supported delimiters:
1459 * '?' -> Stop at any delimiter (",;:=\0")
1460 * '0' -> Stop at "\0"
1461 * '.' -> Skip 1 char unless reached "\0"
1462 * Any other value is treated as the delimiter value itself
1463 */
1464typedef struct GdbCmdParseEntry {
1465 GdbCmdHandler handler;
1466 const char *cmd;
1467 bool cmd_startswith;
1468 const char *schema;
1469} GdbCmdParseEntry;
1470
1471static inline int startswith(const char *string, const char *pattern)
1472{
1473 return !strncmp(string, pattern, strlen(pattern));
1474}
1475
Alex Bennéea346af32020-03-16 17:21:34 +00001476static int process_string_cmd(void *user_ctx, const char *data,
Jon Dorond14055d2019-05-29 09:41:29 +03001477 const GdbCmdParseEntry *cmds, int num_cmds)
1478{
Alex Bennée26a16182021-05-25 09:24:14 +01001479 int i;
1480 g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
Jon Dorond14055d2019-05-29 09:41:29 +03001481
1482 if (!cmds) {
1483 return -1;
1484 }
1485
1486 for (i = 0; i < num_cmds; i++) {
1487 const GdbCmdParseEntry *cmd = &cmds[i];
1488 g_assert(cmd->handler && cmd->cmd);
1489
1490 if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1491 (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1492 continue;
1493 }
1494
1495 if (cmd->schema) {
Alex Bennée26a16182021-05-25 09:24:14 +01001496 if (cmd_parse_params(&data[strlen(cmd->cmd)],
1497 cmd->schema, params)) {
1498 return -1;
Jon Dorond14055d2019-05-29 09:41:29 +03001499 }
Jon Dorond14055d2019-05-29 09:41:29 +03001500 }
1501
Alex Bennée26a16182021-05-25 09:24:14 +01001502 cmd->handler(params, user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001503 return 0;
1504 }
1505
1506 return -1;
1507}
1508
Alex Bennéea346af32020-03-16 17:21:34 +00001509static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
Jon Doron3e2c1262019-05-29 09:41:30 +03001510{
1511 if (!data) {
1512 return;
1513 }
1514
Alex Bennée308f9e82020-03-16 17:21:35 +00001515 g_string_set_size(gdbserver_state.str_buf, 0);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001516 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Alex Bennée308f9e82020-03-16 17:21:35 +00001517
Jon Doron3e2c1262019-05-29 09:41:30 +03001518 /* In case there was an error during the command parsing we must
1519 * send a NULL packet to indicate the command is not supported */
Alex Bennéea346af32020-03-16 17:21:34 +00001520 if (process_string_cmd(NULL, data, cmd, 1)) {
1521 put_packet("");
Jon Doron3e2c1262019-05-29 09:41:30 +03001522 }
1523}
1524
Alex Bennée26a16182021-05-25 09:24:14 +01001525static void handle_detach(GArray *params, void *user_ctx)
Jon Doron3e2c1262019-05-29 09:41:30 +03001526{
1527 GDBProcess *process;
Jon Doron3e2c1262019-05-29 09:41:30 +03001528 uint32_t pid = 1;
1529
Alex Bennéea346af32020-03-16 17:21:34 +00001530 if (gdbserver_state.multiprocess) {
Alex Bennée26a16182021-05-25 09:24:14 +01001531 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001532 put_packet("E22");
Jon Doron3e2c1262019-05-29 09:41:30 +03001533 return;
1534 }
1535
Alex Bennée26a16182021-05-25 09:24:14 +01001536 pid = get_param(params, 0)->val_ul;
Jon Doron3e2c1262019-05-29 09:41:30 +03001537 }
1538
Alex Bennéea346af32020-03-16 17:21:34 +00001539 process = gdb_get_process(pid);
1540 gdb_process_breakpoint_remove_all(process);
Jon Doron3e2c1262019-05-29 09:41:30 +03001541 process->attached = false;
1542
Alex Bennéea346af32020-03-16 17:21:34 +00001543 if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1544 gdbserver_state.c_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001545 }
1546
Alex Bennéea346af32020-03-16 17:21:34 +00001547 if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1548 gdbserver_state.g_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001549 }
1550
Alex Bennéea346af32020-03-16 17:21:34 +00001551 if (!gdbserver_state.c_cpu) {
Jon Doron3e2c1262019-05-29 09:41:30 +03001552 /* No more process attached */
1553 gdb_syscall_mode = GDB_SYS_DISABLED;
Alex Bennéea346af32020-03-16 17:21:34 +00001554 gdb_continue();
Jon Doron3e2c1262019-05-29 09:41:30 +03001555 }
Alex Bennéea346af32020-03-16 17:21:34 +00001556 put_packet("OK");
Jon Doron3e2c1262019-05-29 09:41:30 +03001557}
1558
Alex Bennée26a16182021-05-25 09:24:14 +01001559static void handle_thread_alive(GArray *params, void *user_ctx)
Jon Doron44ffded2019-05-29 09:41:31 +03001560{
1561 CPUState *cpu;
1562
Alex Bennée26a16182021-05-25 09:24:14 +01001563 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001564 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001565 return;
1566 }
1567
Alex Bennée26a16182021-05-25 09:24:14 +01001568 if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001569 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001570 return;
1571 }
1572
Alex Bennée26a16182021-05-25 09:24:14 +01001573 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1574 get_param(params, 0)->thread_id.tid);
Jon Doron44ffded2019-05-29 09:41:31 +03001575 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001576 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001577 return;
1578 }
1579
Alex Bennéea346af32020-03-16 17:21:34 +00001580 put_packet("OK");
Jon Doron44ffded2019-05-29 09:41:31 +03001581}
1582
Alex Bennée26a16182021-05-25 09:24:14 +01001583static void handle_continue(GArray *params, void *user_ctx)
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001584{
Alex Bennée26a16182021-05-25 09:24:14 +01001585 if (params->len) {
1586 gdb_set_cpu_pc(get_param(params, 0)->val_ull);
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001587 }
1588
Alex Bennéea346af32020-03-16 17:21:34 +00001589 gdbserver_state.signal = 0;
1590 gdb_continue();
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001591}
1592
Alex Bennée26a16182021-05-25 09:24:14 +01001593static void handle_cont_with_sig(GArray *params, void *user_ctx)
Jon Doronccc47d52019-05-29 09:41:33 +03001594{
1595 unsigned long signal = 0;
1596
1597 /*
1598 * Note: C sig;[addr] is currently unsupported and we simply
1599 * omit the addr parameter
1600 */
Alex Bennée26a16182021-05-25 09:24:14 +01001601 if (params->len) {
1602 signal = get_param(params, 0)->val_ul;
Jon Doronccc47d52019-05-29 09:41:33 +03001603 }
1604
Alex Bennéea346af32020-03-16 17:21:34 +00001605 gdbserver_state.signal = gdb_signal_to_target(signal);
1606 if (gdbserver_state.signal == -1) {
1607 gdbserver_state.signal = 0;
Jon Doronccc47d52019-05-29 09:41:33 +03001608 }
Alex Bennéea346af32020-03-16 17:21:34 +00001609 gdb_continue();
Jon Doronccc47d52019-05-29 09:41:33 +03001610}
1611
Alex Bennée26a16182021-05-25 09:24:14 +01001612static void handle_set_thread(GArray *params, void *user_ctx)
Jon Doron3a9651d2019-05-29 09:41:34 +03001613{
1614 CPUState *cpu;
1615
Alex Bennée26a16182021-05-25 09:24:14 +01001616 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001617 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001618 return;
1619 }
1620
Alex Bennée26a16182021-05-25 09:24:14 +01001621 if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001622 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001623 return;
1624 }
1625
Alex Bennée26a16182021-05-25 09:24:14 +01001626 if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
Alex Bennéea346af32020-03-16 17:21:34 +00001627 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001628 return;
1629 }
1630
Alex Bennée26a16182021-05-25 09:24:14 +01001631 cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1632 get_param(params, 1)->thread_id.tid);
Jon Doron3a9651d2019-05-29 09:41:34 +03001633 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001634 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001635 return;
1636 }
1637
1638 /*
1639 * Note: This command is deprecated and modern gdb's will be using the
1640 * vCont command instead.
1641 */
Alex Bennée26a16182021-05-25 09:24:14 +01001642 switch (get_param(params, 0)->opcode) {
Jon Doron3a9651d2019-05-29 09:41:34 +03001643 case 'c':
Alex Bennéea346af32020-03-16 17:21:34 +00001644 gdbserver_state.c_cpu = cpu;
1645 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001646 break;
1647 case 'g':
Alex Bennéea346af32020-03-16 17:21:34 +00001648 gdbserver_state.g_cpu = cpu;
1649 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001650 break;
1651 default:
Alex Bennéea346af32020-03-16 17:21:34 +00001652 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001653 break;
1654 }
1655}
1656
Alex Bennée26a16182021-05-25 09:24:14 +01001657static void handle_insert_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001658{
1659 int res;
1660
Alex Bennée26a16182021-05-25 09:24:14 +01001661 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001662 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001663 return;
1664 }
1665
Alex Bennée26a16182021-05-25 09:24:14 +01001666 res = gdb_breakpoint_insert(get_param(params, 0)->val_ul,
1667 get_param(params, 1)->val_ull,
1668 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001669 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001670 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001671 return;
1672 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001673 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001674 return;
1675 }
1676
Alex Bennéea346af32020-03-16 17:21:34 +00001677 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001678}
1679
Alex Bennée26a16182021-05-25 09:24:14 +01001680static void handle_remove_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001681{
1682 int res;
1683
Alex Bennée26a16182021-05-25 09:24:14 +01001684 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001685 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001686 return;
1687 }
1688
Alex Bennée26a16182021-05-25 09:24:14 +01001689 res = gdb_breakpoint_remove(get_param(params, 0)->val_ul,
1690 get_param(params, 1)->val_ull,
1691 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001692 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001693 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001694 return;
1695 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001696 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001697 return;
1698 }
1699
Alex Bennéea346af32020-03-16 17:21:34 +00001700 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001701}
1702
Alex Bennée94b2a622019-07-05 14:23:07 +01001703/*
1704 * handle_set/get_reg
1705 *
1706 * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1707 * This works, but can be very slow. Anything new enough to understand
1708 * XML also knows how to use this properly. However to use this we
1709 * need to define a local XML file as well as be talking to a
1710 * reasonably modern gdb. Responding with an empty packet will cause
1711 * the remote gdb to fallback to older methods.
1712 */
1713
Alex Bennée26a16182021-05-25 09:24:14 +01001714static void handle_set_reg(GArray *params, void *user_ctx)
Jon Doron62b33202019-05-29 09:41:36 +03001715{
1716 int reg_size;
1717
1718 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001719 put_packet("");
Jon Doron62b33202019-05-29 09:41:36 +03001720 return;
1721 }
1722
Alex Bennée26a16182021-05-25 09:24:14 +01001723 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001724 put_packet("E22");
Jon Doron62b33202019-05-29 09:41:36 +03001725 return;
1726 }
1727
Alex Bennée26a16182021-05-25 09:24:14 +01001728 reg_size = strlen(get_param(params, 1)->data) / 2;
1729 hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001730 gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
Alex Bennée26a16182021-05-25 09:24:14 +01001731 get_param(params, 0)->val_ull);
Alex Bennéea346af32020-03-16 17:21:34 +00001732 put_packet("OK");
Jon Doron62b33202019-05-29 09:41:36 +03001733}
1734
Alex Bennée26a16182021-05-25 09:24:14 +01001735static void handle_get_reg(GArray *params, void *user_ctx)
Jon Doron5d0e57b2019-05-29 09:41:37 +03001736{
1737 int reg_size;
1738
Jon Doron5d0e57b2019-05-29 09:41:37 +03001739 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001740 put_packet("");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001741 return;
1742 }
1743
Alex Bennée26a16182021-05-25 09:24:14 +01001744 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001745 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001746 return;
1747 }
1748
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001749 reg_size = gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001750 gdbserver_state.mem_buf,
Alex Bennée26a16182021-05-25 09:24:14 +01001751 get_param(params, 0)->val_ull);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001752 if (!reg_size) {
Alex Bennéea346af32020-03-16 17:21:34 +00001753 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001754 return;
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001755 } else {
1756 g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001757 }
1758
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001759 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
Alex Bennée308f9e82020-03-16 17:21:35 +00001760 put_strbuf();
Jon Doron5d0e57b2019-05-29 09:41:37 +03001761}
1762
Alex Bennée26a16182021-05-25 09:24:14 +01001763static void handle_write_mem(GArray *params, void *user_ctx)
Jon Doroncc0ecc72019-05-29 09:41:38 +03001764{
Alex Bennée26a16182021-05-25 09:24:14 +01001765 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001766 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001767 return;
1768 }
1769
1770 /* hextomem() reads 2*len bytes */
Alex Bennée26a16182021-05-25 09:24:14 +01001771 if (get_param(params, 1)->val_ull >
1772 strlen(get_param(params, 2)->data) / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001773 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001774 return;
1775 }
1776
Alex Bennée26a16182021-05-25 09:24:14 +01001777 hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1778 get_param(params, 1)->val_ull);
1779 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1780 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001781 gdbserver_state.mem_buf->data,
1782 gdbserver_state.mem_buf->len, true)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001783 put_packet("E14");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001784 return;
1785 }
1786
Alex Bennéea346af32020-03-16 17:21:34 +00001787 put_packet("OK");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001788}
1789
Alex Bennée26a16182021-05-25 09:24:14 +01001790static void handle_read_mem(GArray *params, void *user_ctx)
Jon Doronda92e232019-05-29 09:41:39 +03001791{
Alex Bennée26a16182021-05-25 09:24:14 +01001792 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001793 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001794 return;
1795 }
1796
1797 /* memtohex() doubles the required space */
Alex Bennée26a16182021-05-25 09:24:14 +01001798 if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001799 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001800 return;
1801 }
1802
Alex Bennée26a16182021-05-25 09:24:14 +01001803 g_byte_array_set_size(gdbserver_state.mem_buf,
1804 get_param(params, 1)->val_ull);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001805
Alex Bennée26a16182021-05-25 09:24:14 +01001806 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1807 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001808 gdbserver_state.mem_buf->data,
1809 gdbserver_state.mem_buf->len, false)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001810 put_packet("E14");
Jon Doronda92e232019-05-29 09:41:39 +03001811 return;
1812 }
1813
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001814 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1815 gdbserver_state.mem_buf->len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001816 put_strbuf();
Jon Doronda92e232019-05-29 09:41:39 +03001817}
1818
Alex Bennée26a16182021-05-25 09:24:14 +01001819static void handle_write_all_regs(GArray *params, void *user_ctx)
Jon Doron287ca122019-05-29 09:41:40 +03001820{
1821 target_ulong addr, len;
1822 uint8_t *registers;
1823 int reg_size;
1824
Alex Bennée26a16182021-05-25 09:24:14 +01001825 if (!params->len) {
Jon Doron287ca122019-05-29 09:41:40 +03001826 return;
1827 }
1828
Alex Bennéea346af32020-03-16 17:21:34 +00001829 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennée26a16182021-05-25 09:24:14 +01001830 len = strlen(get_param(params, 0)->data) / 2;
1831 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001832 registers = gdbserver_state.mem_buf->data;
Alex Bennéea346af32020-03-16 17:21:34 +00001833 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
Jon Doron287ca122019-05-29 09:41:40 +03001834 addr++) {
Alex Bennéea346af32020-03-16 17:21:34 +00001835 reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
Jon Doron287ca122019-05-29 09:41:40 +03001836 len -= reg_size;
1837 registers += reg_size;
1838 }
Alex Bennéea346af32020-03-16 17:21:34 +00001839 put_packet("OK");
Jon Doron287ca122019-05-29 09:41:40 +03001840}
1841
Alex Bennée26a16182021-05-25 09:24:14 +01001842static void handle_read_all_regs(GArray *params, void *user_ctx)
Jon Doron397d1372019-05-29 09:41:41 +03001843{
1844 target_ulong addr, len;
1845
Alex Bennéea346af32020-03-16 17:21:34 +00001846 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennéea010bdb2020-03-16 17:21:41 +00001847 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Jon Doron397d1372019-05-29 09:41:41 +03001848 len = 0;
Alex Bennéea346af32020-03-16 17:21:34 +00001849 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001850 len += gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001851 gdbserver_state.mem_buf,
Jon Doron397d1372019-05-29 09:41:41 +03001852 addr);
1853 }
Alex Bennéea010bdb2020-03-16 17:21:41 +00001854 g_assert(len == gdbserver_state.mem_buf->len);
Jon Doron397d1372019-05-29 09:41:41 +03001855
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001856 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001857 put_strbuf();
Jon Doron397d1372019-05-29 09:41:41 +03001858}
1859
Alex Bennée26a16182021-05-25 09:24:14 +01001860static void handle_file_io(GArray *params, void *user_ctx)
Jon Doron4b20fab2019-05-29 09:41:42 +03001861{
Alex Bennée26a16182021-05-25 09:24:14 +01001862 if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
Jon Doron4b20fab2019-05-29 09:41:42 +03001863 target_ulong ret, err;
1864
Alex Bennée26a16182021-05-25 09:24:14 +01001865 ret = (target_ulong)get_param(params, 0)->val_ull;
1866 if (params->len >= 2) {
1867 err = (target_ulong)get_param(params, 1)->val_ull;
Sandra Loosemorec6ee9522019-08-27 16:33:17 -06001868 } else {
1869 err = 0;
1870 }
Alex Bennéea346af32020-03-16 17:21:34 +00001871 gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1872 gdbserver_state.current_syscall_cb = NULL;
Jon Doron4b20fab2019-05-29 09:41:42 +03001873 }
1874
Alex Bennée26a16182021-05-25 09:24:14 +01001875 if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
Alex Bennéea346af32020-03-16 17:21:34 +00001876 put_packet("T02");
Jon Doron4b20fab2019-05-29 09:41:42 +03001877 return;
1878 }
1879
Alex Bennéea346af32020-03-16 17:21:34 +00001880 gdb_continue();
Jon Doron4b20fab2019-05-29 09:41:42 +03001881}
1882
Alex Bennée26a16182021-05-25 09:24:14 +01001883static void handle_step(GArray *params, void *user_ctx)
Jon Doron933f80d2019-05-29 09:41:43 +03001884{
Alex Bennée26a16182021-05-25 09:24:14 +01001885 if (params->len) {
1886 gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
Jon Doron933f80d2019-05-29 09:41:43 +03001887 }
1888
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001889 cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
Alex Bennéea346af32020-03-16 17:21:34 +00001890 gdb_continue();
Jon Doron933f80d2019-05-29 09:41:43 +03001891}
1892
Alex Bennée26a16182021-05-25 09:24:14 +01001893static void handle_backward(GArray *params, void *user_ctx)
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001894{
Alex Bennéeed12f5b2021-05-20 18:43:02 +01001895 if (!stub_can_reverse()) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001896 put_packet("E22");
1897 }
Alex Bennée26a16182021-05-25 09:24:14 +01001898 if (params->len == 1) {
1899 switch (get_param(params, 0)->opcode) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001900 case 's':
1901 if (replay_reverse_step()) {
1902 gdb_continue();
1903 } else {
1904 put_packet("E14");
1905 }
1906 return;
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03001907 case 'c':
1908 if (replay_reverse_continue()) {
1909 gdb_continue();
1910 } else {
1911 put_packet("E14");
1912 }
1913 return;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001914 }
1915 }
1916
1917 /* Default invalid command */
1918 put_packet("");
1919}
1920
Alex Bennée26a16182021-05-25 09:24:14 +01001921static void handle_v_cont_query(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001922{
Alex Bennéea346af32020-03-16 17:21:34 +00001923 put_packet("vCont;c;C;s;S");
Jon Doron8536ec02019-05-29 09:41:44 +03001924}
1925
Alex Bennée26a16182021-05-25 09:24:14 +01001926static void handle_v_cont(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001927{
1928 int res;
1929
Alex Bennée26a16182021-05-25 09:24:14 +01001930 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001931 return;
1932 }
1933
Alex Bennée26a16182021-05-25 09:24:14 +01001934 res = gdb_handle_vcont(get_param(params, 0)->data);
Jon Doron8536ec02019-05-29 09:41:44 +03001935 if ((res == -EINVAL) || (res == -ERANGE)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001936 put_packet("E22");
Jon Doron8536ec02019-05-29 09:41:44 +03001937 } else if (res) {
Alex Bennéea346af32020-03-16 17:21:34 +00001938 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03001939 }
1940}
1941
Alex Bennée26a16182021-05-25 09:24:14 +01001942static void handle_v_attach(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001943{
1944 GDBProcess *process;
1945 CPUState *cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001946
Alex Bennée308f9e82020-03-16 17:21:35 +00001947 g_string_assign(gdbserver_state.str_buf, "E22");
Alex Bennée26a16182021-05-25 09:24:14 +01001948 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001949 goto cleanup;
1950 }
1951
Alex Bennée26a16182021-05-25 09:24:14 +01001952 process = gdb_get_process(get_param(params, 0)->val_ul);
Jon Doron8536ec02019-05-29 09:41:44 +03001953 if (!process) {
1954 goto cleanup;
1955 }
1956
Alex Bennéea346af32020-03-16 17:21:34 +00001957 cpu = get_first_cpu_in_process(process);
Jon Doron8536ec02019-05-29 09:41:44 +03001958 if (!cpu) {
1959 goto cleanup;
1960 }
1961
1962 process->attached = true;
Alex Bennéea346af32020-03-16 17:21:34 +00001963 gdbserver_state.g_cpu = cpu;
1964 gdbserver_state.c_cpu = cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001965
Alex Bennée308f9e82020-03-16 17:21:35 +00001966 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
1967 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
1968 g_string_append_c(gdbserver_state.str_buf, ';');
Jon Doron8536ec02019-05-29 09:41:44 +03001969cleanup:
Alex Bennée308f9e82020-03-16 17:21:35 +00001970 put_strbuf();
Jon Doron8536ec02019-05-29 09:41:44 +03001971}
1972
Alex Bennée26a16182021-05-25 09:24:14 +01001973static void handle_v_kill(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001974{
1975 /* Kill the target */
Alex Bennéea346af32020-03-16 17:21:34 +00001976 put_packet("OK");
Jon Doron8536ec02019-05-29 09:41:44 +03001977 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00001978 gdb_exit(0);
Jon Doron8536ec02019-05-29 09:41:44 +03001979 exit(0);
1980}
1981
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01001982static const GdbCmdParseEntry gdb_v_commands_table[] = {
Jon Doron8536ec02019-05-29 09:41:44 +03001983 /* Order is important if has same prefix */
1984 {
1985 .handler = handle_v_cont_query,
1986 .cmd = "Cont?",
1987 .cmd_startswith = 1
1988 },
1989 {
1990 .handler = handle_v_cont,
1991 .cmd = "Cont",
1992 .cmd_startswith = 1,
1993 .schema = "s0"
1994 },
1995 {
1996 .handler = handle_v_attach,
1997 .cmd = "Attach;",
1998 .cmd_startswith = 1,
1999 .schema = "l0"
2000 },
2001 {
2002 .handler = handle_v_kill,
2003 .cmd = "Kill;",
2004 .cmd_startswith = 1
2005 },
2006};
2007
Alex Bennée26a16182021-05-25 09:24:14 +01002008static void handle_v_commands(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03002009{
Alex Bennée26a16182021-05-25 09:24:14 +01002010 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03002011 return;
2012 }
2013
Alex Bennée26a16182021-05-25 09:24:14 +01002014 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron8536ec02019-05-29 09:41:44 +03002015 gdb_v_commands_table,
2016 ARRAY_SIZE(gdb_v_commands_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002017 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03002018 }
2019}
2020
Alex Bennée26a16182021-05-25 09:24:14 +01002021static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002022{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002023 g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
2024
2025 if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
2026 g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
2027 SSTEP_NOIRQ);
2028 }
2029
2030 if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
2031 g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
2032 SSTEP_NOTIMER);
2033 }
2034
Alex Bennée308f9e82020-03-16 17:21:35 +00002035 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002036}
2037
Alex Bennée26a16182021-05-25 09:24:14 +01002038static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002039{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002040 int new_sstep_flags;
2041
Alex Bennée26a16182021-05-25 09:24:14 +01002042 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002043 return;
2044 }
2045
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002046 new_sstep_flags = get_param(params, 0)->val_ul;
2047
2048 if (new_sstep_flags & ~gdbserver_state.supported_sstep_flags) {
2049 put_packet("E22");
2050 return;
2051 }
2052
2053 gdbserver_state.sstep_flags = new_sstep_flags;
Alex Bennéea346af32020-03-16 17:21:34 +00002054 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002055}
2056
Alex Bennée26a16182021-05-25 09:24:14 +01002057static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002058{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01002059 g_string_printf(gdbserver_state.str_buf, "0x%x",
2060 gdbserver_state.sstep_flags);
Alex Bennée308f9e82020-03-16 17:21:35 +00002061 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002062}
2063
Alex Bennée26a16182021-05-25 09:24:14 +01002064static void handle_query_curr_tid(GArray *params, void *user_ctx)
bellardb4608c02003-06-27 17:34:32 +00002065{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02002066 CPUState *cpu;
Luc Michelc145eea2019-01-07 15:23:46 +00002067 GDBProcess *process;
Jon Doron2704efa2019-05-29 09:41:45 +03002068
2069 /*
2070 * "Current thread" remains vague in the spec, so always return
2071 * the first thread of the current process (gdb returns the
2072 * first thread).
2073 */
Alex Bennéea346af32020-03-16 17:21:34 +00002074 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2075 cpu = get_first_cpu_in_process(process);
Alex Bennée308f9e82020-03-16 17:21:35 +00002076 g_string_assign(gdbserver_state.str_buf, "QC");
2077 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2078 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002079}
2080
Alex Bennée26a16182021-05-25 09:24:14 +01002081static void handle_query_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002082{
Alex Bennéea346af32020-03-16 17:21:34 +00002083 if (!gdbserver_state.query_cpu) {
2084 put_packet("l");
Jon Doron2704efa2019-05-29 09:41:45 +03002085 return;
2086 }
2087
Alex Bennée308f9e82020-03-16 17:21:35 +00002088 g_string_assign(gdbserver_state.str_buf, "m");
2089 gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
2090 put_strbuf();
Alex Bennéea346af32020-03-16 17:21:34 +00002091 gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002092}
2093
Alex Bennée26a16182021-05-25 09:24:14 +01002094static void handle_query_first_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002095{
Alex Bennéea346af32020-03-16 17:21:34 +00002096 gdbserver_state.query_cpu = gdb_first_attached_cpu();
Alex Bennée26a16182021-05-25 09:24:14 +01002097 handle_query_threads(params, user_ctx);
Jon Doron2704efa2019-05-29 09:41:45 +03002098}
2099
Alex Bennée26a16182021-05-25 09:24:14 +01002100static void handle_query_thread_extra(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002101{
Alex Bennée308f9e82020-03-16 17:21:35 +00002102 g_autoptr(GString) rs = g_string_new(NULL);
Jon Doron2704efa2019-05-29 09:41:45 +03002103 CPUState *cpu;
Jon Doron2704efa2019-05-29 09:41:45 +03002104
Alex Bennée26a16182021-05-25 09:24:14 +01002105 if (!params->len ||
2106 get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00002107 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002108 return;
2109 }
2110
Alex Bennée26a16182021-05-25 09:24:14 +01002111 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
2112 get_param(params, 0)->thread_id.tid);
Jon Doron2704efa2019-05-29 09:41:45 +03002113 if (!cpu) {
2114 return;
2115 }
2116
2117 cpu_synchronize_state(cpu);
2118
Alex Bennéea346af32020-03-16 17:21:34 +00002119 if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
Jon Doron2704efa2019-05-29 09:41:45 +03002120 /* Print the CPU model and name in multiprocess mode */
2121 ObjectClass *oc = object_get_class(OBJECT(cpu));
2122 const char *cpu_model = object_class_get_name(oc);
Markus Armbruster7a309cc2020-07-14 18:02:00 +02002123 const char *cpu_name =
Denis Plotnikov076b2fa2020-04-03 20:11:44 +01002124 object_get_canonical_path_component(OBJECT(cpu));
Alex Bennée308f9e82020-03-16 17:21:35 +00002125 g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
2126 cpu->halted ? "halted " : "running");
Jon Doron2704efa2019-05-29 09:41:45 +03002127 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002128 g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
Jon Doron2704efa2019-05-29 09:41:45 +03002129 cpu->halted ? "halted " : "running");
2130 }
Alex Bennée308f9e82020-03-16 17:21:35 +00002131 trace_gdbstub_op_extra_info(rs->str);
2132 memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
2133 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002134}
2135
2136#ifdef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002137static void handle_query_offsets(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002138{
2139 TaskState *ts;
2140
Alex Bennéea346af32020-03-16 17:21:34 +00002141 ts = gdbserver_state.c_cpu->opaque;
Alex Bennée308f9e82020-03-16 17:21:35 +00002142 g_string_printf(gdbserver_state.str_buf,
2143 "Text=" TARGET_ABI_FMT_lx
2144 ";Data=" TARGET_ABI_FMT_lx
2145 ";Bss=" TARGET_ABI_FMT_lx,
2146 ts->info->code_offset,
2147 ts->info->data_offset,
2148 ts->info->data_offset);
2149 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002150}
2151#else
Alex Bennée26a16182021-05-25 09:24:14 +01002152static void handle_query_rcmd(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002153{
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002154 const guint8 zero = 0;
Jon Doron2704efa2019-05-29 09:41:45 +03002155 int len;
2156
Alex Bennée26a16182021-05-25 09:24:14 +01002157 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002158 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002159 return;
2160 }
2161
Alex Bennée26a16182021-05-25 09:24:14 +01002162 len = strlen(get_param(params, 0)->data);
Jon Doron2704efa2019-05-29 09:41:45 +03002163 if (len % 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00002164 put_packet("E01");
Jon Doron2704efa2019-05-29 09:41:45 +03002165 return;
2166 }
2167
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002168 g_assert(gdbserver_state.mem_buf->len == 0);
Jon Doron2704efa2019-05-29 09:41:45 +03002169 len = len / 2;
Alex Bennée26a16182021-05-25 09:24:14 +01002170 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002171 g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
2172 qemu_chr_be_write(gdbserver_state.mon_chr, gdbserver_state.mem_buf->data,
2173 gdbserver_state.mem_buf->len);
Alex Bennéea346af32020-03-16 17:21:34 +00002174 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002175}
2176#endif
2177
Alex Bennée26a16182021-05-25 09:24:14 +01002178static void handle_query_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002179{
Andreas Färber5b24c642013-07-07 15:08:22 +02002180 CPUClass *cc;
Jon Doron2704efa2019-05-29 09:41:45 +03002181
Alex Bennée308f9e82020-03-16 17:21:35 +00002182 g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
Jon Doron2704efa2019-05-29 09:41:45 +03002183 cc = CPU_GET_CLASS(first_cpu);
2184 if (cc->gdb_core_xml_file) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002185 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
Jon Doron2704efa2019-05-29 09:41:45 +03002186 }
2187
Alex Bennéeed12f5b2021-05-20 18:43:02 +01002188 if (stub_can_reverse()) {
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03002189 g_string_append(gdbserver_state.str_buf,
2190 ";ReverseStep+;ReverseContinue+");
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002191 }
2192
Lirong Yuan51c623b2021-01-08 22:42:42 +00002193#ifdef CONFIG_USER_ONLY
2194 if (gdbserver_state.c_cpu->opaque) {
2195 g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
2196 }
2197#endif
2198
Alex Bennée26a16182021-05-25 09:24:14 +01002199 if (params->len &&
2200 strstr(get_param(params, 0)->data, "multiprocess+")) {
Alex Bennéea346af32020-03-16 17:21:34 +00002201 gdbserver_state.multiprocess = true;
Jon Doron2704efa2019-05-29 09:41:45 +03002202 }
2203
Changbin Du3bc26092020-03-16 17:21:55 +00002204 g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
Alex Bennée308f9e82020-03-16 17:21:35 +00002205 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002206}
2207
Alex Bennée26a16182021-05-25 09:24:14 +01002208static void handle_query_xfer_features(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002209{
2210 GDBProcess *process;
2211 CPUClass *cc;
2212 unsigned long len, total_len, addr;
2213 const char *xml;
bellardb4608c02003-06-27 17:34:32 +00002214 const char *p;
Jon Doron2704efa2019-05-29 09:41:45 +03002215
Alex Bennée26a16182021-05-25 09:24:14 +01002216 if (params->len < 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00002217 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002218 return;
2219 }
2220
Alex Bennéea346af32020-03-16 17:21:34 +00002221 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2222 cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002223 if (!cc->gdb_core_xml_file) {
Alex Bennéea346af32020-03-16 17:21:34 +00002224 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002225 return;
2226 }
2227
2228 gdb_has_xml = true;
Alex Bennée26a16182021-05-25 09:24:14 +01002229 p = get_param(params, 0)->data;
Alex Bennéea346af32020-03-16 17:21:34 +00002230 xml = get_feature_xml(p, &p, process);
Jon Doron2704efa2019-05-29 09:41:45 +03002231 if (!xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00002232 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002233 return;
2234 }
2235
Alex Bennée26a16182021-05-25 09:24:14 +01002236 addr = get_param(params, 1)->val_ul;
2237 len = get_param(params, 2)->val_ul;
Jon Doron2704efa2019-05-29 09:41:45 +03002238 total_len = strlen(xml);
2239 if (addr > total_len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002240 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002241 return;
2242 }
2243
2244 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2245 len = (MAX_PACKET_LENGTH - 5) / 2;
2246 }
2247
2248 if (len < total_len - addr) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002249 g_string_assign(gdbserver_state.str_buf, "m");
2250 memtox(gdbserver_state.str_buf, xml + addr, len);
Jon Doron2704efa2019-05-29 09:41:45 +03002251 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002252 g_string_assign(gdbserver_state.str_buf, "l");
2253 memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
Jon Doron2704efa2019-05-29 09:41:45 +03002254 }
2255
Alex Bennée308f9e82020-03-16 17:21:35 +00002256 put_packet_binary(gdbserver_state.str_buf->str,
2257 gdbserver_state.str_buf->len, true);
Jon Doron2704efa2019-05-29 09:41:45 +03002258}
2259
Lirong Yuan51c623b2021-01-08 22:42:42 +00002260#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
Alex Bennée26a16182021-05-25 09:24:14 +01002261static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
Lirong Yuan51c623b2021-01-08 22:42:42 +00002262{
2263 TaskState *ts;
2264 unsigned long offset, len, saved_auxv, auxv_len;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002265
Alex Bennée26a16182021-05-25 09:24:14 +01002266 if (params->len < 2) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002267 put_packet("E22");
2268 return;
2269 }
2270
Alex Bennée26a16182021-05-25 09:24:14 +01002271 offset = get_param(params, 0)->val_ul;
2272 len = get_param(params, 1)->val_ul;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002273 ts = gdbserver_state.c_cpu->opaque;
2274 saved_auxv = ts->info->saved_auxv;
2275 auxv_len = ts->info->auxv_len;
Richard Henderson6e3dd752021-02-02 13:39:55 +00002276
2277 if (offset >= auxv_len) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002278 put_packet("E00");
2279 return;
2280 }
2281
2282 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2283 len = (MAX_PACKET_LENGTH - 5) / 2;
2284 }
2285
2286 if (len < auxv_len - offset) {
2287 g_string_assign(gdbserver_state.str_buf, "m");
Lirong Yuan51c623b2021-01-08 22:42:42 +00002288 } else {
2289 g_string_assign(gdbserver_state.str_buf, "l");
Richard Henderson6e3dd752021-02-02 13:39:55 +00002290 len = auxv_len - offset;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002291 }
2292
Richard Henderson6e3dd752021-02-02 13:39:55 +00002293 g_byte_array_set_size(gdbserver_state.mem_buf, len);
2294 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2295 gdbserver_state.mem_buf->data, len, false)) {
2296 put_packet("E14");
2297 return;
2298 }
2299
2300 memtox(gdbserver_state.str_buf,
2301 (const char *)gdbserver_state.mem_buf->data, len);
Lirong Yuan51c623b2021-01-08 22:42:42 +00002302 put_packet_binary(gdbserver_state.str_buf->str,
2303 gdbserver_state.str_buf->len, true);
2304}
2305#endif
2306
Alex Bennée26a16182021-05-25 09:24:14 +01002307static void handle_query_attached(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002308{
Alex Bennéea346af32020-03-16 17:21:34 +00002309 put_packet(GDB_ATTACHED);
Jon Doron2704efa2019-05-29 09:41:45 +03002310}
2311
Alex Bennée26a16182021-05-25 09:24:14 +01002312static void handle_query_qemu_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002313{
Alex Bennée308f9e82020-03-16 17:21:35 +00002314 g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
Jon Doronab4752e2019-05-29 09:41:48 +03002315#ifndef CONFIG_USER_ONLY
Alex Bennée308f9e82020-03-16 17:21:35 +00002316 g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
Jon Doronab4752e2019-05-29 09:41:48 +03002317#endif
Alex Bennée308f9e82020-03-16 17:21:35 +00002318 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002319}
2320
Jon Doronab4752e2019-05-29 09:41:48 +03002321#ifndef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002322static void handle_query_qemu_phy_mem_mode(GArray *params,
Jon Doronab4752e2019-05-29 09:41:48 +03002323 void *user_ctx)
2324{
Alex Bennée308f9e82020-03-16 17:21:35 +00002325 g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
2326 put_strbuf();
Jon Doronab4752e2019-05-29 09:41:48 +03002327}
2328
Alex Bennée26a16182021-05-25 09:24:14 +01002329static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
Jon Doronab4752e2019-05-29 09:41:48 +03002330{
Alex Bennée26a16182021-05-25 09:24:14 +01002331 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002332 put_packet("E22");
Jon Doronab4752e2019-05-29 09:41:48 +03002333 return;
2334 }
2335
Alex Bennée26a16182021-05-25 09:24:14 +01002336 if (!get_param(params, 0)->val_ul) {
Jon Doronab4752e2019-05-29 09:41:48 +03002337 phy_memory_mode = 0;
2338 } else {
2339 phy_memory_mode = 1;
2340 }
Alex Bennéea346af32020-03-16 17:21:34 +00002341 put_packet("OK");
Jon Doronab4752e2019-05-29 09:41:48 +03002342}
2343#endif
2344
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002345static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002346 /* Order is important if has same prefix */
2347 {
2348 .handler = handle_query_qemu_sstepbits,
2349 .cmd = "qemu.sstepbits",
2350 },
2351 {
2352 .handler = handle_query_qemu_sstep,
2353 .cmd = "qemu.sstep",
2354 },
2355 {
2356 .handler = handle_set_qemu_sstep,
2357 .cmd = "qemu.sstep=",
2358 .cmd_startswith = 1,
2359 .schema = "l0"
2360 },
2361};
2362
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002363static const GdbCmdParseEntry gdb_gen_query_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002364 {
2365 .handler = handle_query_curr_tid,
2366 .cmd = "C",
2367 },
2368 {
2369 .handler = handle_query_threads,
2370 .cmd = "sThreadInfo",
2371 },
2372 {
2373 .handler = handle_query_first_threads,
2374 .cmd = "fThreadInfo",
2375 },
2376 {
2377 .handler = handle_query_thread_extra,
2378 .cmd = "ThreadExtraInfo,",
2379 .cmd_startswith = 1,
2380 .schema = "t0"
2381 },
2382#ifdef CONFIG_USER_ONLY
2383 {
2384 .handler = handle_query_offsets,
2385 .cmd = "Offsets",
2386 },
2387#else
2388 {
2389 .handler = handle_query_rcmd,
2390 .cmd = "Rcmd,",
2391 .cmd_startswith = 1,
2392 .schema = "s0"
2393 },
2394#endif
2395 {
2396 .handler = handle_query_supported,
2397 .cmd = "Supported:",
2398 .cmd_startswith = 1,
2399 .schema = "s0"
2400 },
2401 {
2402 .handler = handle_query_supported,
2403 .cmd = "Supported",
2404 .schema = "s0"
2405 },
2406 {
2407 .handler = handle_query_xfer_features,
2408 .cmd = "Xfer:features:read:",
2409 .cmd_startswith = 1,
2410 .schema = "s:l,l0"
2411 },
Lirong Yuan51c623b2021-01-08 22:42:42 +00002412#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2413 {
2414 .handler = handle_query_xfer_auxv,
2415 .cmd = "Xfer:auxv:read::",
2416 .cmd_startswith = 1,
2417 .schema = "l,l0"
2418 },
2419#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002420 {
2421 .handler = handle_query_attached,
2422 .cmd = "Attached:",
2423 .cmd_startswith = 1
2424 },
2425 {
2426 .handler = handle_query_attached,
2427 .cmd = "Attached",
2428 },
2429 {
2430 .handler = handle_query_qemu_supported,
2431 .cmd = "qemu.Supported",
2432 },
Jon Doronab4752e2019-05-29 09:41:48 +03002433#ifndef CONFIG_USER_ONLY
2434 {
2435 .handler = handle_query_qemu_phy_mem_mode,
2436 .cmd = "qemu.PhyMemMode",
2437 },
2438#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002439};
2440
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002441static const GdbCmdParseEntry gdb_gen_set_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002442 /* Order is important if has same prefix */
2443 {
2444 .handler = handle_set_qemu_sstep,
2445 .cmd = "qemu.sstep:",
2446 .cmd_startswith = 1,
2447 .schema = "l0"
2448 },
Jon Doronab4752e2019-05-29 09:41:48 +03002449#ifndef CONFIG_USER_ONLY
2450 {
2451 .handler = handle_set_qemu_phy_mem_mode,
2452 .cmd = "qemu.PhyMemMode:",
2453 .cmd_startswith = 1,
2454 .schema = "l0"
2455 },
2456#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002457};
2458
Alex Bennée26a16182021-05-25 09:24:14 +01002459static void handle_gen_query(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002460{
Alex Bennée26a16182021-05-25 09:24:14 +01002461 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002462 return;
2463 }
2464
Alex Bennée26a16182021-05-25 09:24:14 +01002465 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002466 gdb_gen_query_set_common_table,
2467 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2468 return;
2469 }
2470
Alex Bennée26a16182021-05-25 09:24:14 +01002471 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002472 gdb_gen_query_table,
2473 ARRAY_SIZE(gdb_gen_query_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002474 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002475 }
2476}
2477
Alex Bennée26a16182021-05-25 09:24:14 +01002478static void handle_gen_set(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002479{
Alex Bennée26a16182021-05-25 09:24:14 +01002480 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002481 return;
2482 }
2483
Alex Bennée26a16182021-05-25 09:24:14 +01002484 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002485 gdb_gen_query_set_common_table,
2486 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2487 return;
2488 }
2489
Alex Bennée26a16182021-05-25 09:24:14 +01002490 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002491 gdb_gen_set_table,
2492 ARRAY_SIZE(gdb_gen_set_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002493 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002494 }
2495}
2496
Alex Bennée26a16182021-05-25 09:24:14 +01002497static void handle_target_halt(GArray *params, void *user_ctx)
Jon Doron7009d572019-05-29 09:41:46 +03002498{
Alex Bennée308f9e82020-03-16 17:21:35 +00002499 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2500 gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2501 g_string_append_c(gdbserver_state.str_buf, ';');
2502 put_strbuf();
Jon Doron7009d572019-05-29 09:41:46 +03002503 /*
2504 * Remove all the breakpoints when this query is issued,
2505 * because gdb is doing an initial connect and the state
2506 * should be cleaned up.
2507 */
2508 gdb_breakpoint_remove_all();
2509}
2510
Alex Bennéea346af32020-03-16 17:21:34 +00002511static int gdb_handle_packet(const char *line_buf)
Jon Doron2704efa2019-05-29 09:41:45 +03002512{
Jon Doron3e2c1262019-05-29 09:41:30 +03002513 const GdbCmdParseEntry *cmd_parser = NULL;
ths3b46e622007-09-17 08:09:54 +00002514
Doug Gale5c9522b2017-12-02 20:30:37 -05002515 trace_gdbstub_io_command(line_buf);
Alex Bennée118e2262017-07-12 11:52:13 +01002516
Jon Doron3f1cbac2019-05-29 09:41:47 +03002517 switch (line_buf[0]) {
Luc Michel53fd6552019-01-07 15:23:46 +00002518 case '!':
Alex Bennéea346af32020-03-16 17:21:34 +00002519 put_packet("OK");
Luc Michel53fd6552019-01-07 15:23:46 +00002520 break;
bellard858693c2004-03-31 18:52:07 +00002521 case '?':
Jon Doron7009d572019-05-29 09:41:46 +03002522 {
2523 static const GdbCmdParseEntry target_halted_cmd_desc = {
2524 .handler = handle_target_halt,
2525 .cmd = "?",
2526 .cmd_startswith = 1
2527 };
2528 cmd_parser = &target_halted_cmd_desc;
2529 }
bellard858693c2004-03-31 18:52:07 +00002530 break;
2531 case 'c':
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002532 {
2533 static const GdbCmdParseEntry continue_cmd_desc = {
2534 .handler = handle_continue,
2535 .cmd = "c",
2536 .cmd_startswith = 1,
2537 .schema = "L0"
2538 };
2539 cmd_parser = &continue_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002540 }
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002541 break;
edgar_igl1f487ee2008-05-17 22:20:53 +00002542 case 'C':
Jon Doronccc47d52019-05-29 09:41:33 +03002543 {
2544 static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2545 .handler = handle_cont_with_sig,
2546 .cmd = "C",
2547 .cmd_startswith = 1,
2548 .schema = "l0"
2549 };
2550 cmd_parser = &cont_with_sig_cmd_desc;
2551 }
2552 break;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002553 case 'v':
Jon Doron8536ec02019-05-29 09:41:44 +03002554 {
2555 static const GdbCmdParseEntry v_cmd_desc = {
2556 .handler = handle_v_commands,
2557 .cmd = "v",
2558 .cmd_startswith = 1,
2559 .schema = "s0"
2560 };
2561 cmd_parser = &v_cmd_desc;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002562 }
Jon Doron8536ec02019-05-29 09:41:44 +03002563 break;
edgar_igl7d03f822008-05-17 18:58:29 +00002564 case 'k':
2565 /* Kill the target */
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002566 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00002567 gdb_exit(0);
edgar_igl7d03f822008-05-17 18:58:29 +00002568 exit(0);
2569 case 'D':
Jon Doron3e2c1262019-05-29 09:41:30 +03002570 {
2571 static const GdbCmdParseEntry detach_cmd_desc = {
2572 .handler = handle_detach,
2573 .cmd = "D",
2574 .cmd_startswith = 1,
2575 .schema = "?.l0"
2576 };
2577 cmd_parser = &detach_cmd_desc;
Luc Michel546f3c62019-01-07 15:23:46 +00002578 }
edgar_igl7d03f822008-05-17 18:58:29 +00002579 break;
bellard858693c2004-03-31 18:52:07 +00002580 case 's':
Jon Doron933f80d2019-05-29 09:41:43 +03002581 {
2582 static const GdbCmdParseEntry step_cmd_desc = {
2583 .handler = handle_step,
2584 .cmd = "s",
2585 .cmd_startswith = 1,
2586 .schema = "L0"
2587 };
2588 cmd_parser = &step_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002589 }
Jon Doron933f80d2019-05-29 09:41:43 +03002590 break;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002591 case 'b':
2592 {
2593 static const GdbCmdParseEntry backward_cmd_desc = {
2594 .handler = handle_backward,
2595 .cmd = "b",
2596 .cmd_startswith = 1,
2597 .schema = "o0"
2598 };
2599 cmd_parser = &backward_cmd_desc;
2600 }
2601 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002602 case 'F':
2603 {
Jon Doron4b20fab2019-05-29 09:41:42 +03002604 static const GdbCmdParseEntry file_io_cmd_desc = {
2605 .handler = handle_file_io,
2606 .cmd = "F",
2607 .cmd_startswith = 1,
2608 .schema = "L,L,o0"
2609 };
2610 cmd_parser = &file_io_cmd_desc;
pbrooka2d1eba2007-01-28 03:10:55 +00002611 }
2612 break;
bellard858693c2004-03-31 18:52:07 +00002613 case 'g':
Jon Doron397d1372019-05-29 09:41:41 +03002614 {
2615 static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2616 .handler = handle_read_all_regs,
2617 .cmd = "g",
2618 .cmd_startswith = 1
2619 };
2620 cmd_parser = &read_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002621 }
bellard858693c2004-03-31 18:52:07 +00002622 break;
2623 case 'G':
Jon Doron287ca122019-05-29 09:41:40 +03002624 {
2625 static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2626 .handler = handle_write_all_regs,
2627 .cmd = "G",
2628 .cmd_startswith = 1,
2629 .schema = "s0"
2630 };
2631 cmd_parser = &write_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002632 }
bellard858693c2004-03-31 18:52:07 +00002633 break;
2634 case 'm':
Jon Doronda92e232019-05-29 09:41:39 +03002635 {
2636 static const GdbCmdParseEntry read_mem_cmd_desc = {
2637 .handler = handle_read_mem,
2638 .cmd = "m",
2639 .cmd_startswith = 1,
2640 .schema = "L,L0"
2641 };
2642 cmd_parser = &read_mem_cmd_desc;
bellard6f970bd2005-12-05 19:55:19 +00002643 }
bellard858693c2004-03-31 18:52:07 +00002644 break;
2645 case 'M':
Jon Doroncc0ecc72019-05-29 09:41:38 +03002646 {
2647 static const GdbCmdParseEntry write_mem_cmd_desc = {
2648 .handler = handle_write_mem,
2649 .cmd = "M",
2650 .cmd_startswith = 1,
2651 .schema = "L,L:s0"
2652 };
2653 cmd_parser = &write_mem_cmd_desc;
Fabien Chouteau44520db2011-09-08 12:48:16 +02002654 }
bellard858693c2004-03-31 18:52:07 +00002655 break;
pbrook56aebc82008-10-11 17:55:29 +00002656 case 'p':
Jon Doron5d0e57b2019-05-29 09:41:37 +03002657 {
2658 static const GdbCmdParseEntry get_reg_cmd_desc = {
2659 .handler = handle_get_reg,
2660 .cmd = "p",
2661 .cmd_startswith = 1,
2662 .schema = "L0"
2663 };
2664 cmd_parser = &get_reg_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002665 }
2666 break;
2667 case 'P':
Jon Doron62b33202019-05-29 09:41:36 +03002668 {
2669 static const GdbCmdParseEntry set_reg_cmd_desc = {
2670 .handler = handle_set_reg,
2671 .cmd = "P",
2672 .cmd_startswith = 1,
2673 .schema = "L?s0"
2674 };
2675 cmd_parser = &set_reg_cmd_desc;
2676 }
pbrook56aebc82008-10-11 17:55:29 +00002677 break;
bellard858693c2004-03-31 18:52:07 +00002678 case 'Z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002679 {
2680 static const GdbCmdParseEntry insert_bp_cmd_desc = {
2681 .handler = handle_insert_bp,
2682 .cmd = "Z",
2683 .cmd_startswith = 1,
2684 .schema = "l?L?L0"
2685 };
2686 cmd_parser = &insert_bp_cmd_desc;
2687 }
2688 break;
bellard858693c2004-03-31 18:52:07 +00002689 case 'z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002690 {
2691 static const GdbCmdParseEntry remove_bp_cmd_desc = {
2692 .handler = handle_remove_bp,
2693 .cmd = "z",
2694 .cmd_startswith = 1,
2695 .schema = "l?L?L0"
2696 };
2697 cmd_parser = &remove_bp_cmd_desc;
2698 }
bellard858693c2004-03-31 18:52:07 +00002699 break;
aliguori880a7572008-11-18 20:30:24 +00002700 case 'H':
Jon Doron3a9651d2019-05-29 09:41:34 +03002701 {
2702 static const GdbCmdParseEntry set_thread_cmd_desc = {
2703 .handler = handle_set_thread,
2704 .cmd = "H",
2705 .cmd_startswith = 1,
2706 .schema = "o.t0"
2707 };
2708 cmd_parser = &set_thread_cmd_desc;
aliguori880a7572008-11-18 20:30:24 +00002709 }
2710 break;
2711 case 'T':
Jon Doron44ffded2019-05-29 09:41:31 +03002712 {
2713 static const GdbCmdParseEntry thread_alive_cmd_desc = {
2714 .handler = handle_thread_alive,
2715 .cmd = "T",
2716 .cmd_startswith = 1,
2717 .schema = "t0"
2718 };
2719 cmd_parser = &thread_alive_cmd_desc;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002720 }
aliguori880a7572008-11-18 20:30:24 +00002721 break;
pbrook978efd62006-06-17 18:30:42 +00002722 case 'q':
Jon Doron2704efa2019-05-29 09:41:45 +03002723 {
2724 static const GdbCmdParseEntry gen_query_cmd_desc = {
2725 .handler = handle_gen_query,
2726 .cmd = "q",
2727 .cmd_startswith = 1,
2728 .schema = "s0"
2729 };
2730 cmd_parser = &gen_query_cmd_desc;
2731 }
2732 break;
edgar_igl60897d32008-05-09 08:25:14 +00002733 case 'Q':
Jon Doron2704efa2019-05-29 09:41:45 +03002734 {
2735 static const GdbCmdParseEntry gen_set_cmd_desc = {
2736 .handler = handle_gen_set,
2737 .cmd = "Q",
2738 .cmd_startswith = 1,
2739 .schema = "s0"
2740 };
2741 cmd_parser = &gen_set_cmd_desc;
edgar_igl60897d32008-05-09 08:25:14 +00002742 }
Jon Doron2704efa2019-05-29 09:41:45 +03002743 break;
bellard858693c2004-03-31 18:52:07 +00002744 default:
bellard858693c2004-03-31 18:52:07 +00002745 /* put empty packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002746 put_packet("");
bellard858693c2004-03-31 18:52:07 +00002747 break;
2748 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002749
Ramiro Polla2bdec392019-08-05 21:09:01 +02002750 if (cmd_parser) {
Alex Bennéea346af32020-03-16 17:21:34 +00002751 run_cmd_parser(line_buf, cmd_parser);
Ramiro Polla2bdec392019-08-05 21:09:01 +02002752 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002753
bellard858693c2004-03-31 18:52:07 +00002754 return RS_IDLE;
2755}
2756
Andreas Färber64f6b342013-05-27 02:06:09 +02002757void gdb_set_stop_cpu(CPUState *cpu)
aliguori880a7572008-11-18 20:30:24 +00002758{
Alex Bennéea346af32020-03-16 17:21:34 +00002759 GDBProcess *p = gdb_get_cpu_process(cpu);
Luc Michel160d8582019-01-07 15:23:46 +00002760
2761 if (!p->attached) {
2762 /*
2763 * Having a stop CPU corresponding to a process that is not attached
2764 * confuses GDB. So we ignore the request.
2765 */
2766 return;
2767 }
2768
Alex Bennée8d98c442020-03-16 17:21:33 +00002769 gdbserver_state.c_cpu = cpu;
2770 gdbserver_state.g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002771}
2772
bellard1fddef42005-04-17 19:16:13 +00002773#ifndef CONFIG_USER_ONLY
Philippe Mathieu-Daudé538f0492021-01-11 16:20:20 +01002774static void gdb_vm_state_change(void *opaque, bool running, RunState state)
bellard858693c2004-03-31 18:52:07 +00002775{
Alex Bennéea346af32020-03-16 17:21:34 +00002776 CPUState *cpu = gdbserver_state.c_cpu;
Alex Bennée308f9e82020-03-16 17:21:35 +00002777 g_autoptr(GString) buf = g_string_new(NULL);
2778 g_autoptr(GString) tid = g_string_new(NULL);
aliguorid6fc1b32008-11-18 19:55:44 +00002779 const char *type;
bellard858693c2004-03-31 18:52:07 +00002780 int ret;
2781
Alex Bennéea346af32020-03-16 17:21:34 +00002782 if (running || gdbserver_state.state == RS_INACTIVE) {
Meador Ingecdb432b2012-03-15 17:49:45 +00002783 return;
2784 }
2785 /* Is there a GDB syscall waiting to be sent? */
Alex Bennéea346af32020-03-16 17:21:34 +00002786 if (gdbserver_state.current_syscall_cb) {
2787 put_packet(gdbserver_state.syscall_buf);
pbrooka2d1eba2007-01-28 03:10:55 +00002788 return;
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002789 }
Luc Michel95567c22019-01-07 15:23:46 +00002790
2791 if (cpu == NULL) {
2792 /* No process attached */
2793 return;
2794 }
2795
Alex Bennée308f9e82020-03-16 17:21:35 +00002796 gdb_append_thread_id(cpu, tid);
Luc Michel95567c22019-01-07 15:23:46 +00002797
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002798 switch (state) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002799 case RUN_STATE_DEBUG:
Andreas Färberff4700b2013-08-26 18:23:18 +02002800 if (cpu->watchpoint_hit) {
2801 switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
aliguoria1d1bb32008-11-18 20:07:32 +00002802 case BP_MEM_READ:
aliguorid6fc1b32008-11-18 19:55:44 +00002803 type = "r";
2804 break;
aliguoria1d1bb32008-11-18 20:07:32 +00002805 case BP_MEM_ACCESS:
aliguorid6fc1b32008-11-18 19:55:44 +00002806 type = "a";
2807 break;
2808 default:
2809 type = "";
2810 break;
2811 }
Doug Gale5c9522b2017-12-02 20:30:37 -05002812 trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
2813 (target_ulong)cpu->watchpoint_hit->vaddr);
Alex Bennée308f9e82020-03-16 17:21:35 +00002814 g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
2815 GDB_SIGNAL_TRAP, tid->str, type,
2816 (target_ulong)cpu->watchpoint_hit->vaddr);
Andreas Färberff4700b2013-08-26 18:23:18 +02002817 cpu->watchpoint_hit = NULL;
Jan Kiszka425189a2011-03-22 11:02:09 +01002818 goto send_packet;
Doug Gale5c9522b2017-12-02 20:30:37 -05002819 } else {
2820 trace_gdbstub_hit_break();
pbrook6658ffb2007-03-16 23:58:11 +00002821 }
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07002822 tb_flush(cpu);
aurel32ca587a82008-12-18 22:44:13 +00002823 ret = GDB_SIGNAL_TRAP;
Jan Kiszka425189a2011-03-22 11:02:09 +01002824 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002825 case RUN_STATE_PAUSED:
Doug Gale5c9522b2017-12-02 20:30:37 -05002826 trace_gdbstub_hit_paused();
aliguori9781e042009-01-22 17:15:29 +00002827 ret = GDB_SIGNAL_INT;
Jan Kiszka425189a2011-03-22 11:02:09 +01002828 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002829 case RUN_STATE_SHUTDOWN:
Doug Gale5c9522b2017-12-02 20:30:37 -05002830 trace_gdbstub_hit_shutdown();
Jan Kiszka425189a2011-03-22 11:02:09 +01002831 ret = GDB_SIGNAL_QUIT;
2832 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002833 case RUN_STATE_IO_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002834 trace_gdbstub_hit_io_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002835 ret = GDB_SIGNAL_IO;
2836 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002837 case RUN_STATE_WATCHDOG:
Doug Gale5c9522b2017-12-02 20:30:37 -05002838 trace_gdbstub_hit_watchdog();
Jan Kiszka425189a2011-03-22 11:02:09 +01002839 ret = GDB_SIGNAL_ALRM;
2840 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002841 case RUN_STATE_INTERNAL_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002842 trace_gdbstub_hit_internal_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002843 ret = GDB_SIGNAL_ABRT;
2844 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002845 case RUN_STATE_SAVE_VM:
2846 case RUN_STATE_RESTORE_VM:
Jan Kiszka425189a2011-03-22 11:02:09 +01002847 return;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002848 case RUN_STATE_FINISH_MIGRATE:
Jan Kiszka425189a2011-03-22 11:02:09 +01002849 ret = GDB_SIGNAL_XCPU;
2850 break;
2851 default:
Doug Gale5c9522b2017-12-02 20:30:37 -05002852 trace_gdbstub_hit_unknown(state);
Jan Kiszka425189a2011-03-22 11:02:09 +01002853 ret = GDB_SIGNAL_UNKNOWN;
2854 break;
bellardbbeb7b52006-04-23 18:42:15 +00002855 }
Jan Kiszka226d0072015-07-24 18:52:31 +02002856 gdb_set_stop_cpu(cpu);
Alex Bennée308f9e82020-03-16 17:21:35 +00002857 g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002858
2859send_packet:
Alex Bennée308f9e82020-03-16 17:21:35 +00002860 put_packet(buf->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002861
2862 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002863 cpu_single_step(cpu, 0);
bellard858693c2004-03-31 18:52:07 +00002864}
bellard1fddef42005-04-17 19:16:13 +00002865#endif
bellard858693c2004-03-31 18:52:07 +00002866
pbrooka2d1eba2007-01-28 03:10:55 +00002867/* Send a gdb syscall request.
2868 This accepts limited printf-style format specifiers, specifically:
pbrooka87295e2007-05-26 15:09:38 +00002869 %x - target_ulong argument printed in hex.
2870 %lx - 64-bit argument printed in hex.
2871 %s - string pointer (target_ulong) and length (int) pair. */
Peter Maydell19239b32015-09-07 10:39:27 +01002872void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
pbrooka2d1eba2007-01-28 03:10:55 +00002873{
pbrooka2d1eba2007-01-28 03:10:55 +00002874 char *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00002875 char *p_end;
pbrooka2d1eba2007-01-28 03:10:55 +00002876 target_ulong addr;
pbrooka87295e2007-05-26 15:09:38 +00002877 uint64_t i64;
pbrooka2d1eba2007-01-28 03:10:55 +00002878
Alex Bennéea346af32020-03-16 17:21:34 +00002879 if (!gdbserver_state.init) {
pbrooka2d1eba2007-01-28 03:10:55 +00002880 return;
Alex Bennéea346af32020-03-16 17:21:34 +00002881 }
Alex Bennée8d98c442020-03-16 17:21:33 +00002882
2883 gdbserver_state.current_syscall_cb = cb;
pbrooka2d1eba2007-01-28 03:10:55 +00002884#ifndef CONFIG_USER_ONLY
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002885 vm_stop(RUN_STATE_DEBUG);
pbrooka2d1eba2007-01-28 03:10:55 +00002886#endif
Alex Bennée8d98c442020-03-16 17:21:33 +00002887 p = &gdbserver_state.syscall_buf[0];
2888 p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
pbrooka2d1eba2007-01-28 03:10:55 +00002889 *(p++) = 'F';
2890 while (*fmt) {
2891 if (*fmt == '%') {
2892 fmt++;
2893 switch (*fmt++) {
2894 case 'x':
2895 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002896 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
pbrooka2d1eba2007-01-28 03:10:55 +00002897 break;
pbrooka87295e2007-05-26 15:09:38 +00002898 case 'l':
2899 if (*(fmt++) != 'x')
2900 goto bad_format;
2901 i64 = va_arg(va, uint64_t);
Meador Ingecdb432b2012-03-15 17:49:45 +00002902 p += snprintf(p, p_end - p, "%" PRIx64, i64);
pbrooka87295e2007-05-26 15:09:38 +00002903 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002904 case 's':
2905 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002906 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
blueswir1363a37d2008-08-21 17:58:08 +00002907 addr, va_arg(va, int));
pbrooka2d1eba2007-01-28 03:10:55 +00002908 break;
2909 default:
pbrooka87295e2007-05-26 15:09:38 +00002910 bad_format:
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002911 error_report("gdbstub: Bad syscall format string '%s'",
2912 fmt - 1);
pbrooka2d1eba2007-01-28 03:10:55 +00002913 break;
2914 }
2915 } else {
2916 *(p++) = *(fmt++);
2917 }
2918 }
pbrook8a93e022007-08-06 13:19:15 +00002919 *p = 0;
pbrooka2d1eba2007-01-28 03:10:55 +00002920#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +00002921 put_packet(gdbserver_state.syscall_buf);
Peter Maydell4f710862018-05-15 19:19:58 +01002922 /* Return control to gdb for it to process the syscall request.
2923 * Since the protocol requires that gdb hands control back to us
2924 * using a "here are the results" F packet, we don't need to check
2925 * gdb_handlesig's return value (which is the signal to deliver if
2926 * execution was resumed via a continue packet).
2927 */
Alex Bennée8d98c442020-03-16 17:21:33 +00002928 gdb_handlesig(gdbserver_state.c_cpu, 0);
pbrooka2d1eba2007-01-28 03:10:55 +00002929#else
Meador Ingecdb432b2012-03-15 17:49:45 +00002930 /* In this case wait to send the syscall packet until notification that
2931 the CPU has stopped. This must be done because if the packet is sent
2932 now the reply from the syscall request could be received while the CPU
2933 is still in the running state, which can cause packets to be dropped
2934 and state transition 'T' packets to be sent while the syscall is still
2935 being processed. */
Alex Bennée8d98c442020-03-16 17:21:33 +00002936 qemu_cpu_kick(gdbserver_state.c_cpu);
pbrooka2d1eba2007-01-28 03:10:55 +00002937#endif
2938}
2939
Peter Maydell19239b32015-09-07 10:39:27 +01002940void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2941{
2942 va_list va;
2943
2944 va_start(va, fmt);
2945 gdb_do_syscallv(cb, fmt, va);
2946 va_end(va);
2947}
2948
Alex Bennéea346af32020-03-16 17:21:34 +00002949static void gdb_read_byte(uint8_t ch)
bellard858693c2004-03-31 18:52:07 +00002950{
ths60fe76f2007-12-16 03:02:09 +00002951 uint8_t reply;
bellard858693c2004-03-31 18:52:07 +00002952
bellard1fddef42005-04-17 19:16:13 +00002953#ifndef CONFIG_USER_ONLY
Damien Hedded116e812020-03-16 17:21:53 +00002954 if (gdbserver_state.last_packet->len) {
pbrook4046d912007-01-28 01:53:16 +00002955 /* Waiting for a response to the last packet. If we see the start
2956 of a new command then abandon the previous response. */
2957 if (ch == '-') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002958 trace_gdbstub_err_got_nack();
Damien Hedded116e812020-03-16 17:21:53 +00002959 put_buffer(gdbserver_state.last_packet->data,
2960 gdbserver_state.last_packet->len);
Alex Bennée118e2262017-07-12 11:52:13 +01002961 } else if (ch == '+') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002962 trace_gdbstub_io_got_ack();
Alex Bennée118e2262017-07-12 11:52:13 +01002963 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002964 trace_gdbstub_io_got_unexpected(ch);
pbrook4046d912007-01-28 01:53:16 +00002965 }
Alex Bennée118e2262017-07-12 11:52:13 +01002966
Damien Hedded116e812020-03-16 17:21:53 +00002967 if (ch == '+' || ch == '$') {
2968 g_byte_array_set_size(gdbserver_state.last_packet, 0);
2969 }
pbrook4046d912007-01-28 01:53:16 +00002970 if (ch != '$')
2971 return;
2972 }
Luiz Capitulino13548692011-07-29 15:36:43 -03002973 if (runstate_is_running()) {
bellard858693c2004-03-31 18:52:07 +00002974 /* when the CPU is running, we cannot do anything except stop
2975 it when receiving a char */
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002976 vm_stop(RUN_STATE_PAUSED);
ths5fafdf22007-09-16 21:08:06 +00002977 } else
bellard1fddef42005-04-17 19:16:13 +00002978#endif
bellard41625032005-04-24 10:07:11 +00002979 {
Alex Bennéea346af32020-03-16 17:21:34 +00002980 switch(gdbserver_state.state) {
bellard858693c2004-03-31 18:52:07 +00002981 case RS_IDLE:
2982 if (ch == '$') {
Doug Gale4bf43122017-05-01 12:22:10 -04002983 /* start of command packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002984 gdbserver_state.line_buf_index = 0;
2985 gdbserver_state.line_sum = 0;
2986 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002987 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002988 trace_gdbstub_err_garbage(ch);
bellard4c3a88a2003-07-26 12:06:08 +00002989 }
2990 break;
bellard858693c2004-03-31 18:52:07 +00002991 case RS_GETLINE:
Doug Gale4bf43122017-05-01 12:22:10 -04002992 if (ch == '}') {
2993 /* start escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002994 gdbserver_state.state = RS_GETLINE_ESC;
2995 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002996 } else if (ch == '*') {
2997 /* start run length encoding sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002998 gdbserver_state.state = RS_GETLINE_RLE;
2999 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003000 } else if (ch == '#') {
3001 /* end of command, start of checksum*/
Alex Bennéea346af32020-03-16 17:21:34 +00003002 gdbserver_state.state = RS_CHKSUM1;
3003 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale5c9522b2017-12-02 20:30:37 -05003004 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003005 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003006 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003007 /* unescaped command character */
Alex Bennéea346af32020-03-16 17:21:34 +00003008 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
3009 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04003010 }
3011 break;
3012 case RS_GETLINE_ESC:
3013 if (ch == '#') {
3014 /* unexpected end of command in escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00003015 gdbserver_state.state = RS_CHKSUM1;
3016 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003017 /* command buffer overrun */
Doug Gale5c9522b2017-12-02 20:30:37 -05003018 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003019 gdbserver_state.state = RS_IDLE;
Doug Gale4bf43122017-05-01 12:22:10 -04003020 } else {
3021 /* parse escaped character and leave escape state */
Alex Bennéea346af32020-03-16 17:21:34 +00003022 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
3023 gdbserver_state.line_sum += ch;
3024 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003025 }
3026 break;
3027 case RS_GETLINE_RLE:
Markus Armbruster046aba12019-05-14 20:03:08 +02003028 /*
3029 * Run-length encoding is explained in "Debugging with GDB /
3030 * Appendix E GDB Remote Serial Protocol / Overview".
3031 */
3032 if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
Doug Gale4bf43122017-05-01 12:22:10 -04003033 /* invalid RLE count encoding */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003034 trace_gdbstub_err_invalid_repeat(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003035 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003036 } else {
3037 /* decode repeat length */
Markus Armbruster33c846e2019-05-14 20:03:09 +02003038 int repeat = ch - ' ' + 3;
Alex Bennéea346af32020-03-16 17:21:34 +00003039 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003040 /* that many repeats would overrun the command buffer */
Doug Gale5c9522b2017-12-02 20:30:37 -05003041 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00003042 gdbserver_state.state = RS_IDLE;
3043 } else if (gdbserver_state.line_buf_index < 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04003044 /* got a repeat but we have nothing to repeat */
Doug Gale5c9522b2017-12-02 20:30:37 -05003045 trace_gdbstub_err_invalid_rle();
Alex Bennéea346af32020-03-16 17:21:34 +00003046 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003047 } else {
3048 /* repeat the last character */
Alex Bennéea346af32020-03-16 17:21:34 +00003049 memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
3050 gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
3051 gdbserver_state.line_buf_index += repeat;
3052 gdbserver_state.line_sum += ch;
3053 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003054 }
bellard858693c2004-03-31 18:52:07 +00003055 }
3056 break;
3057 case RS_CHKSUM1:
Doug Gale4bf43122017-05-01 12:22:10 -04003058 /* get high hex digit of checksum */
3059 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003060 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003061 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003062 break;
3063 }
Alex Bennéea346af32020-03-16 17:21:34 +00003064 gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
3065 gdbserver_state.line_csum = fromhex(ch) << 4;
3066 gdbserver_state.state = RS_CHKSUM2;
bellard858693c2004-03-31 18:52:07 +00003067 break;
3068 case RS_CHKSUM2:
Doug Gale4bf43122017-05-01 12:22:10 -04003069 /* get low hex digit of checksum */
3070 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02003071 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00003072 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04003073 break;
bellard858693c2004-03-31 18:52:07 +00003074 }
Alex Bennéea346af32020-03-16 17:21:34 +00003075 gdbserver_state.line_csum |= fromhex(ch);
Doug Gale4bf43122017-05-01 12:22:10 -04003076
Alex Bennéea346af32020-03-16 17:21:34 +00003077 if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
3078 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
Doug Gale4bf43122017-05-01 12:22:10 -04003079 /* send NAK reply */
ths60fe76f2007-12-16 03:02:09 +00003080 reply = '-';
Alex Bennéea346af32020-03-16 17:21:34 +00003081 put_buffer(&reply, 1);
3082 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003083 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003084 /* send ACK reply */
ths60fe76f2007-12-16 03:02:09 +00003085 reply = '+';
Alex Bennéea346af32020-03-16 17:21:34 +00003086 put_buffer(&reply, 1);
3087 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
bellard858693c2004-03-31 18:52:07 +00003088 }
bellardb4608c02003-06-27 17:34:32 +00003089 break;
pbrooka2d1eba2007-01-28 03:10:55 +00003090 default:
3091 abort();
bellardb4608c02003-06-27 17:34:32 +00003092 }
3093 }
bellard858693c2004-03-31 18:52:07 +00003094}
3095
Paul Brook0e1c9c52010-06-16 13:03:51 +01003096/* Tell the remote gdb that the process has exited. */
Alex Bennéead9dcb22021-01-08 22:42:43 +00003097void gdb_exit(int code)
Paul Brook0e1c9c52010-06-16 13:03:51 +01003098{
Paul Brook0e1c9c52010-06-16 13:03:51 +01003099 char buf[4];
3100
Alex Bennée8d98c442020-03-16 17:21:33 +00003101 if (!gdbserver_state.init) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003102 return;
3103 }
3104#ifdef CONFIG_USER_ONLY
Alex Bennéefcedd922020-04-30 20:01:19 +01003105 if (gdbserver_state.socket_path) {
3106 unlink(gdbserver_state.socket_path);
3107 }
Alex Bennéee0a1e202020-04-30 20:01:18 +01003108 if (gdbserver_state.fd < 0) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003109 return;
3110 }
3111#endif
3112
Doug Gale5c9522b2017-12-02 20:30:37 -05003113 trace_gdbstub_op_exiting((uint8_t)code);
3114
Paul Brook0e1c9c52010-06-16 13:03:51 +01003115 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
Alex Bennéea346af32020-03-16 17:21:34 +00003116 put_packet(buf);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003117
3118#ifndef CONFIG_USER_ONLY
Alex Bennée8d98c442020-03-16 17:21:33 +00003119 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003120#endif
Paul Brook0e1c9c52010-06-16 13:03:51 +01003121}
3122
Luc Michel8f468632019-01-07 15:23:45 +00003123/*
3124 * Create the process that will contain all the "orphan" CPUs (that are not
3125 * part of a CPU cluster). Note that if this process contains no CPUs, it won't
3126 * be attachable and thus will be invisible to the user.
3127 */
3128static void create_default_process(GDBState *s)
3129{
3130 GDBProcess *process;
3131 int max_pid = 0;
3132
Alex Bennéea346af32020-03-16 17:21:34 +00003133 if (gdbserver_state.process_num) {
Luc Michel8f468632019-01-07 15:23:45 +00003134 max_pid = s->processes[s->process_num - 1].pid;
3135 }
3136
3137 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3138 process = &s->processes[s->process_num - 1];
3139
3140 /* We need an available PID slot for this process */
3141 assert(max_pid < UINT32_MAX);
3142
3143 process->pid = max_pid + 1;
3144 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003145 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003146}
3147
bellard1fddef42005-04-17 19:16:13 +00003148#ifdef CONFIG_USER_ONLY
3149int
Andreas Färberdb6b81d2013-06-27 19:49:31 +02003150gdb_handlesig(CPUState *cpu, int sig)
bellard1fddef42005-04-17 19:16:13 +00003151{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003152 char buf[256];
3153 int n;
bellard1fddef42005-04-17 19:16:13 +00003154
Alex Bennéee0a1e202020-04-30 20:01:18 +01003155 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003156 return sig;
bellard1fddef42005-04-17 19:16:13 +00003157 }
3158
Andreas Färber5ca666c2013-06-24 19:20:57 +02003159 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02003160 cpu_single_step(cpu, 0);
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07003161 tb_flush(cpu);
bellard1fddef42005-04-17 19:16:13 +00003162
Andreas Färber5ca666c2013-06-24 19:20:57 +02003163 if (sig != 0) {
Pavel Labath4a82be72021-10-26 11:22:34 +01003164 gdb_set_stop_cpu(cpu);
3165 g_string_printf(gdbserver_state.str_buf,
3166 "T%02xthread:", target_signal_to_gdb(sig));
3167 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
3168 g_string_append_c(gdbserver_state.str_buf, ';');
3169 put_strbuf();
Andreas Färber5ca666c2013-06-24 19:20:57 +02003170 }
3171 /* put_packet() might have detected that the peer terminated the
3172 connection. */
Alex Bennée8d98c442020-03-16 17:21:33 +00003173 if (gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003174 return sig;
3175 }
3176
3177 sig = 0;
Alex Bennée8d98c442020-03-16 17:21:33 +00003178 gdbserver_state.state = RS_IDLE;
3179 gdbserver_state.running_state = 0;
3180 while (gdbserver_state.running_state == 0) {
3181 n = read(gdbserver_state.fd, buf, 256);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003182 if (n > 0) {
3183 int i;
3184
3185 for (i = 0; i < n; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003186 gdb_read_byte(buf[i]);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003187 }
Peter Wu5819e3e2016-06-05 16:35:48 +02003188 } else {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003189 /* XXX: Connection closed. Should probably wait for another
3190 connection before continuing. */
Peter Wu5819e3e2016-06-05 16:35:48 +02003191 if (n == 0) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003192 close(gdbserver_state.fd);
Peter Wu5819e3e2016-06-05 16:35:48 +02003193 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003194 gdbserver_state.fd = -1;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003195 return sig;
bellard1fddef42005-04-17 19:16:13 +00003196 }
Andreas Färber5ca666c2013-06-24 19:20:57 +02003197 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003198 sig = gdbserver_state.signal;
3199 gdbserver_state.signal = 0;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003200 return sig;
bellard1fddef42005-04-17 19:16:13 +00003201}
bellarde9009672005-04-26 20:42:36 +00003202
aurel32ca587a82008-12-18 22:44:13 +00003203/* Tell the remote gdb that the process has exited due to SIG. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01003204void gdb_signalled(CPUArchState *env, int sig)
aurel32ca587a82008-12-18 22:44:13 +00003205{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003206 char buf[4];
aurel32ca587a82008-12-18 22:44:13 +00003207
Alex Bennéee0a1e202020-04-30 20:01:18 +01003208 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003209 return;
3210 }
aurel32ca587a82008-12-18 22:44:13 +00003211
Andreas Färber5ca666c2013-06-24 19:20:57 +02003212 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003213 put_packet(buf);
aurel32ca587a82008-12-18 22:44:13 +00003214}
bellard1fddef42005-04-17 19:16:13 +00003215
Alex Bennéefcedd922020-04-30 20:01:19 +01003216static void gdb_accept_init(int fd)
3217{
3218 init_gdbserver_state();
3219 create_default_process(&gdbserver_state);
3220 gdbserver_state.processes[0].attached = true;
3221 gdbserver_state.c_cpu = gdb_first_attached_cpu();
3222 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
3223 gdbserver_state.fd = fd;
3224 gdb_has_xml = false;
3225}
3226
3227static bool gdb_accept_socket(int gdb_fd)
3228{
3229 int fd;
3230
3231 for(;;) {
3232 fd = accept(gdb_fd, NULL, NULL);
3233 if (fd < 0 && errno != EINTR) {
3234 perror("accept socket");
3235 return false;
3236 } else if (fd >= 0) {
3237 qemu_set_cloexec(fd);
3238 break;
3239 }
3240 }
3241
3242 gdb_accept_init(fd);
3243 return true;
3244}
3245
3246static int gdbserver_open_socket(const char *path)
3247{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003248 struct sockaddr_un sockaddr = {};
Alex Bennéefcedd922020-04-30 20:01:19 +01003249 int fd, ret;
3250
3251 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3252 if (fd < 0) {
3253 perror("create socket");
3254 return -1;
3255 }
3256
3257 sockaddr.sun_family = AF_UNIX;
3258 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
3259 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3260 if (ret < 0) {
3261 perror("bind socket");
3262 close(fd);
3263 return -1;
3264 }
3265 ret = listen(fd, 1);
3266 if (ret < 0) {
3267 perror("listen socket");
3268 close(fd);
3269 return -1;
3270 }
3271
3272 return fd;
3273}
3274
3275static bool gdb_accept_tcp(int gdb_fd)
bellard858693c2004-03-31 18:52:07 +00003276{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003277 struct sockaddr_in sockaddr = {};
bellard858693c2004-03-31 18:52:07 +00003278 socklen_t len;
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09003279 int fd;
bellard858693c2004-03-31 18:52:07 +00003280
3281 for(;;) {
3282 len = sizeof(sockaddr);
Alex Bennéee0a1e202020-04-30 20:01:18 +01003283 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
bellard858693c2004-03-31 18:52:07 +00003284 if (fd < 0 && errno != EINTR) {
3285 perror("accept");
Peter Maydell2f652222018-05-14 18:30:44 +01003286 return false;
bellard858693c2004-03-31 18:52:07 +00003287 } else if (fd >= 0) {
Peter Maydellf5bdd782018-05-14 18:30:43 +01003288 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003289 break;
3290 }
3291 }
3292
3293 /* set short latency */
Peter Maydell2f652222018-05-14 18:30:44 +01003294 if (socket_set_nodelay(fd)) {
3295 perror("setsockopt");
Philippe Mathieu-Daudéead75d82018-05-24 19:34:58 -03003296 close(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003297 return false;
3298 }
ths3b46e622007-09-17 08:09:54 +00003299
Alex Bennéefcedd922020-04-30 20:01:19 +01003300 gdb_accept_init(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003301 return true;
bellard858693c2004-03-31 18:52:07 +00003302}
3303
Alex Bennéefcedd922020-04-30 20:01:19 +01003304static int gdbserver_open_port(int port)
bellard858693c2004-03-31 18:52:07 +00003305{
3306 struct sockaddr_in sockaddr;
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003307 int fd, ret;
bellard858693c2004-03-31 18:52:07 +00003308
3309 fd = socket(PF_INET, SOCK_STREAM, 0);
3310 if (fd < 0) {
3311 perror("socket");
3312 return -1;
3313 }
Peter Maydellf5bdd782018-05-14 18:30:43 +01003314 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003315
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003316 socket_set_fast_reuse(fd);
bellard858693c2004-03-31 18:52:07 +00003317
3318 sockaddr.sin_family = AF_INET;
3319 sockaddr.sin_port = htons(port);
3320 sockaddr.sin_addr.s_addr = 0;
3321 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3322 if (ret < 0) {
3323 perror("bind");
Peter Maydellbb161722011-12-24 23:37:24 +00003324 close(fd);
bellard858693c2004-03-31 18:52:07 +00003325 return -1;
3326 }
Peter Wu96165b92016-05-04 11:32:17 +02003327 ret = listen(fd, 1);
bellard858693c2004-03-31 18:52:07 +00003328 if (ret < 0) {
3329 perror("listen");
Peter Maydellbb161722011-12-24 23:37:24 +00003330 close(fd);
bellard858693c2004-03-31 18:52:07 +00003331 return -1;
3332 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003333
bellard858693c2004-03-31 18:52:07 +00003334 return fd;
3335}
3336
Alex Bennéefcedd922020-04-30 20:01:19 +01003337int gdbserver_start(const char *port_or_path)
bellard858693c2004-03-31 18:52:07 +00003338{
Alex Bennéefcedd922020-04-30 20:01:19 +01003339 int port = g_ascii_strtoull(port_or_path, NULL, 10);
3340 int gdb_fd;
3341
3342 if (port > 0) {
3343 gdb_fd = gdbserver_open_port(port);
3344 } else {
3345 gdb_fd = gdbserver_open_socket(port_or_path);
3346 }
3347
Alex Bennéee0a1e202020-04-30 20:01:18 +01003348 if (gdb_fd < 0) {
bellard858693c2004-03-31 18:52:07 +00003349 return -1;
Alex Bennéee0a1e202020-04-30 20:01:18 +01003350 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003351
3352 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3353 return 0;
3354 } else if (gdb_accept_socket(gdb_fd)) {
3355 gdbserver_state.socket_path = g_strdup(port_or_path);
3356 return 0;
Peter Maydell2f652222018-05-14 18:30:44 +01003357 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003358
3359 /* gone wrong */
3360 close(gdb_fd);
3361 return -1;
bellardb4608c02003-06-27 17:34:32 +00003362}
aurel322b1319c2008-12-18 22:44:04 +00003363
3364/* Disable gdb stub for child processes. */
Peter Crosthwaitef7ec7f72015-06-23 19:31:16 -07003365void gdbserver_fork(CPUState *cpu)
aurel322b1319c2008-12-18 22:44:04 +00003366{
Alex Bennéee0a1e202020-04-30 20:01:18 +01003367 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber75a34032013-09-02 16:57:02 +02003368 return;
3369 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003370 close(gdbserver_state.fd);
3371 gdbserver_state.fd = -1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02003372 cpu_breakpoint_remove_all(cpu, BP_GDB);
Andreas Färber75a34032013-09-02 16:57:02 +02003373 cpu_watchpoint_remove_all(cpu, BP_GDB);
aurel322b1319c2008-12-18 22:44:04 +00003374}
pbrook4046d912007-01-28 01:53:16 +00003375#else
thsaa1f17c2007-07-11 22:48:58 +00003376static int gdb_chr_can_receive(void *opaque)
pbrook4046d912007-01-28 01:53:16 +00003377{
pbrook56aebc82008-10-11 17:55:29 +00003378 /* We can handle an arbitrarily large amount of data.
3379 Pick the maximum packet size, which is as good as anything. */
3380 return MAX_PACKET_LENGTH;
pbrook4046d912007-01-28 01:53:16 +00003381}
3382
thsaa1f17c2007-07-11 22:48:58 +00003383static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
pbrook4046d912007-01-28 01:53:16 +00003384{
pbrook4046d912007-01-28 01:53:16 +00003385 int i;
3386
3387 for (i = 0; i < size; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003388 gdb_read_byte(buf[i]);
pbrook4046d912007-01-28 01:53:16 +00003389 }
3390}
3391
Philippe Mathieu-Daudé083b2662019-12-18 18:20:09 +01003392static void gdb_chr_event(void *opaque, QEMUChrEvent event)
pbrook4046d912007-01-28 01:53:16 +00003393{
Luc Michel970ed902019-01-07 15:23:46 +00003394 int i;
3395 GDBState *s = (GDBState *) opaque;
3396
pbrook4046d912007-01-28 01:53:16 +00003397 switch (event) {
Amit Shahb6b8df52009-10-07 18:31:16 +05303398 case CHR_EVENT_OPENED:
Luc Michel970ed902019-01-07 15:23:46 +00003399 /* Start with first process attached, others detached */
3400 for (i = 0; i < s->process_num; i++) {
3401 s->processes[i].attached = !i;
3402 }
3403
Alex Bennéea346af32020-03-16 17:21:34 +00003404 s->c_cpu = gdb_first_attached_cpu();
Luc Michel970ed902019-01-07 15:23:46 +00003405 s->g_cpu = s->c_cpu;
3406
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003407 vm_stop(RUN_STATE_PAUSED);
Pavel Dovgalyuk56357d82020-10-03 20:14:01 +03003408 replay_gdb_attached();
Andreas Färber5b50e792013-06-29 04:18:45 +02003409 gdb_has_xml = false;
pbrook4046d912007-01-28 01:53:16 +00003410 break;
3411 default:
3412 break;
3413 }
3414}
3415
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003416static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
aliguori8a34a0f2009-03-05 23:01:55 +00003417{
Damien Hedded86b4672020-03-16 17:21:54 +00003418 g_autoptr(GString) hex_buf = g_string_new("O");
3419 memtohex(hex_buf, buf, len);
3420 put_packet(hex_buf->str);
aliguori8a34a0f2009-03-05 23:01:55 +00003421 return len;
3422}
3423
aliguori59030a82009-04-05 18:43:41 +00003424#ifndef _WIN32
3425static void gdb_sigterm_handler(int signal)
3426{
Luiz Capitulino13548692011-07-29 15:36:43 -03003427 if (runstate_is_running()) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003428 vm_stop(RUN_STATE_PAUSED);
Jan Kiszkae07bbac2011-02-09 16:29:40 +01003429 }
aliguori59030a82009-04-05 18:43:41 +00003430}
3431#endif
3432
Marc-André Lureau777357d2016-12-07 18:39:10 +03003433static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
3434 bool *be_opened, Error **errp)
3435{
3436 *be_opened = false;
3437}
3438
3439static void char_gdb_class_init(ObjectClass *oc, void *data)
3440{
3441 ChardevClass *cc = CHARDEV_CLASS(oc);
3442
3443 cc->internal = true;
3444 cc->open = gdb_monitor_open;
3445 cc->chr_write = gdb_monitor_write;
3446}
3447
3448#define TYPE_CHARDEV_GDB "chardev-gdb"
3449
3450static const TypeInfo char_gdb_type_info = {
3451 .name = TYPE_CHARDEV_GDB,
3452 .parent = TYPE_CHARDEV,
3453 .class_init = char_gdb_class_init,
3454};
3455
Luc Michel8f468632019-01-07 15:23:45 +00003456static int find_cpu_clusters(Object *child, void *opaque)
3457{
3458 if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
3459 GDBState *s = (GDBState *) opaque;
3460 CPUClusterState *cluster = CPU_CLUSTER(child);
3461 GDBProcess *process;
3462
3463 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3464
3465 process = &s->processes[s->process_num - 1];
3466
3467 /*
3468 * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
3469 * runtime, we enforce here that the machine does not use a cluster ID
3470 * that would lead to PID 0.
3471 */
3472 assert(cluster->cluster_id != UINT32_MAX);
3473 process->pid = cluster->cluster_id + 1;
3474 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003475 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003476
3477 return 0;
3478 }
3479
3480 return object_child_foreach(child, find_cpu_clusters, opaque);
3481}
3482
3483static int pid_order(const void *a, const void *b)
3484{
3485 GDBProcess *pa = (GDBProcess *) a;
3486 GDBProcess *pb = (GDBProcess *) b;
3487
3488 if (pa->pid < pb->pid) {
3489 return -1;
3490 } else if (pa->pid > pb->pid) {
3491 return 1;
3492 } else {
3493 return 0;
3494 }
3495}
3496
3497static void create_processes(GDBState *s)
3498{
3499 object_child_foreach(object_get_root(), find_cpu_clusters, s);
3500
Alex Bennéea346af32020-03-16 17:21:34 +00003501 if (gdbserver_state.processes) {
Luc Michel8f468632019-01-07 15:23:45 +00003502 /* Sort by PID */
Alex Bennéea346af32020-03-16 17:21:34 +00003503 qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
Luc Michel8f468632019-01-07 15:23:45 +00003504 }
3505
3506 create_default_process(s);
3507}
3508
aliguori59030a82009-04-05 18:43:41 +00003509int gdbserver_start(const char *device)
pbrook4046d912007-01-28 01:53:16 +00003510{
Doug Gale5c9522b2017-12-02 20:30:37 -05003511 trace_gdbstub_op_start(device);
3512
aliguori59030a82009-04-05 18:43:41 +00003513 char gdbstub_device_name[128];
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003514 Chardev *chr = NULL;
3515 Chardev *mon_chr;
pbrook4046d912007-01-28 01:53:16 +00003516
Ziyue Yang508b4ec2017-01-18 16:02:41 +08003517 if (!first_cpu) {
3518 error_report("gdbstub: meaningless to attach gdb to a "
3519 "machine without any CPU.");
3520 return -1;
3521 }
3522
aliguori59030a82009-04-05 18:43:41 +00003523 if (!device)
3524 return -1;
3525 if (strcmp(device, "none") != 0) {
3526 if (strstart(device, "tcp:", NULL)) {
3527 /* enforce required TCP attributes */
3528 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
Paolo Bonzinia9b13152021-02-25 11:47:52 +01003529 "%s,wait=off,nodelay=on,server=on", device);
aliguori59030a82009-04-05 18:43:41 +00003530 device = gdbstub_device_name;
aliguori36556b22009-03-28 18:05:53 +00003531 }
aliguori59030a82009-04-05 18:43:41 +00003532#ifndef _WIN32
3533 else if (strcmp(device, "stdio") == 0) {
3534 struct sigaction act;
pbrookcfc34752007-02-22 01:48:01 +00003535
aliguori59030a82009-04-05 18:43:41 +00003536 memset(&act, 0, sizeof(act));
3537 act.sa_handler = gdb_sigterm_handler;
3538 sigaction(SIGINT, &act, NULL);
3539 }
3540#endif
Marc-André Lureau95e30b22018-08-22 19:19:42 +02003541 /*
3542 * FIXME: it's a bit weird to allow using a mux chardev here
3543 * and implicitly setup a monitor. We may want to break this.
3544 */
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003545 chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
aliguori36556b22009-03-28 18:05:53 +00003546 if (!chr)
3547 return -1;
pbrookcfc34752007-02-22 01:48:01 +00003548 }
3549
Alex Bennée8d98c442020-03-16 17:21:33 +00003550 if (!gdbserver_state.init) {
3551 init_gdbserver_state();
pbrook4046d912007-01-28 01:53:16 +00003552
aliguori36556b22009-03-28 18:05:53 +00003553 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
3554
3555 /* Initialize a monitor terminal for gdb */
Marc-André Lureau777357d2016-12-07 18:39:10 +03003556 mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003557 NULL, NULL, &error_abort);
Kevin Wolf8e9119a2020-02-24 15:30:06 +01003558 monitor_init_hmp(mon_chr, false, &error_abort);
aliguori36556b22009-03-28 18:05:53 +00003559 } else {
Alex Bennée8d98c442020-03-16 17:21:33 +00003560 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
3561 mon_chr = gdbserver_state.mon_chr;
3562 reset_gdbserver_state();
aliguori36556b22009-03-28 18:05:53 +00003563 }
Luc Michel8f468632019-01-07 15:23:45 +00003564
Alex Bennée8d98c442020-03-16 17:21:33 +00003565 create_processes(&gdbserver_state);
Luc Michel8f468632019-01-07 15:23:45 +00003566
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003567 if (chr) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003568 qemu_chr_fe_init(&gdbserver_state.chr, chr, &error_abort);
3569 qemu_chr_fe_set_handlers(&gdbserver_state.chr, gdb_chr_can_receive,
3570 gdb_chr_receive, gdb_chr_event,
3571 NULL, &gdbserver_state, NULL, true);
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003572 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003573 gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
3574 gdbserver_state.mon_chr = mon_chr;
3575 gdbserver_state.current_syscall_cb = NULL;
aliguori8a34a0f2009-03-05 23:01:55 +00003576
pbrook4046d912007-01-28 01:53:16 +00003577 return 0;
3578}
Marc-André Lureau777357d2016-12-07 18:39:10 +03003579
3580static void register_types(void)
3581{
3582 type_register_static(&char_gdb_type_info);
3583}
3584
3585type_init(register_types);
pbrook4046d912007-01-28 01:53:16 +00003586#endif