blob: be88ca0d718219967e08a271306ce19a0ba6a68a [file] [log] [blame]
bellardb4608c02003-06-27 17:34:32 +00001/*
2 * gdb server stub
ths5fafdf22007-09-16 21:08:06 +00003 *
Alex Bennée42a09592019-07-05 13:28:19 +01004 * This implements a subset of the remote protocol as described in:
5 *
6 * https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html
7 *
bellard34751872005-07-02 14:31:34 +00008 * Copyright (c) 2003-2005 Fabrice Bellard
bellardb4608c02003-06-27 17:34:32 +00009 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
Blue Swirl8167ee82009-07-16 20:47:01 +000021 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Alex Bennée42a09592019-07-05 13:28:19 +010022 *
23 * SPDX-License-Identifier: LGPL-2.0+
bellardb4608c02003-06-27 17:34:32 +000024 */
Markus Armbruster856dfd82019-05-23 16:35:06 +020025
Peter Maydelld38ea872016-01-29 17:50:05 +000026#include "qemu/osdep.h"
Markus Armbrusterda34e652016-03-14 09:01:28 +010027#include "qapi/error.h"
Ziyue Yang508b4ec2017-01-18 16:02:41 +080028#include "qemu/error-report.h"
Markus Armbruster856dfd82019-05-23 16:35:06 +020029#include "qemu/ctype.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020030#include "qemu/cutils.h"
Markus Armbruster0b8fa322019-05-23 16:35:07 +020031#include "qemu/module.h"
Alex Bennée842b42d2022-09-29 12:42:22 +010032#include "trace.h"
Peter Maydell85b4fa02021-09-08 16:44:04 +010033#include "exec/gdbstub.h"
Veronia Bahaaf348b6d2016-03-20 19:16:19 +020034#ifdef CONFIG_USER_ONLY
bellard1fddef42005-04-17 19:16:13 +000035#include "qemu.h"
36#else
Paolo Bonzini83c90892012-12-17 18:19:49 +010037#include "monitor/monitor.h"
Marc-André Lureau8228e352017-01-26 17:19:46 +040038#include "chardev/char.h"
Marc-André Lureau4d43a602017-01-26 18:26:44 +040039#include "chardev/char-fe.h"
Luc Michel8f468632019-01-07 15:23:45 +000040#include "hw/cpu/cluster.h"
Like Xu5cc87672019-05-19 04:54:21 +080041#include "hw/boards.h"
bellard1fddef42005-04-17 19:16:13 +000042#endif
bellard67b915a2004-03-31 23:37:16 +000043
pbrook56aebc82008-10-11 17:55:29 +000044#define MAX_PACKET_LENGTH 4096
45
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010046#include "qemu/sockets.h"
Vincent Palatinb3946622017-01-10 11:59:55 +010047#include "sysemu/hw_accel.h"
Markus Armbruster54d31232019-08-12 07:23:59 +020048#include "sysemu/runstate.h"
Philippe Mathieu-Daudé6b5fe132021-03-05 13:54:49 +000049#include "semihosting/semihost.h"
Paolo Bonzini63c91552016-03-15 13:18:37 +010050#include "exec/exec-all.h"
Alex Bennéeae7467b2022-09-29 12:42:24 +010051#include "exec/hwaddr.h"
Pavel Dovgalyukfda84582020-10-03 20:13:43 +030052#include "sysemu/replay.h"
aurel32ca587a82008-12-18 22:44:13 +000053
Alex Bennéeae7467b2022-09-29 12:42:24 +010054#include "internals.h"
55
Jan Kiszkaa3919382015-02-07 09:38:44 +010056#ifdef CONFIG_USER_ONLY
57#define GDB_ATTACHED "0"
58#else
59#define GDB_ATTACHED "1"
60#endif
61
Jon Doronab4752e2019-05-29 09:41:48 +030062#ifndef CONFIG_USER_ONLY
63static int phy_memory_mode;
64#endif
65
Andreas Färberf3659ee2013-06-27 19:09:09 +020066static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
67 uint8_t *buf, int len, bool is_write)
Fabien Chouteau44520db2011-09-08 12:48:16 +020068{
Jon Doronab4752e2019-05-29 09:41:48 +030069 CPUClass *cc;
Andreas Färberf3659ee2013-06-27 19:09:09 +020070
Jon Doronab4752e2019-05-29 09:41:48 +030071#ifndef CONFIG_USER_ONLY
72 if (phy_memory_mode) {
73 if (is_write) {
74 cpu_physical_memory_write(addr, buf, len);
75 } else {
76 cpu_physical_memory_read(addr, buf, len);
77 }
78 return 0;
79 }
80#endif
81
82 cc = CPU_GET_CLASS(cpu);
Andreas Färberf3659ee2013-06-27 19:09:09 +020083 if (cc->memory_rw_debug) {
84 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
85 }
86 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
Fabien Chouteau44520db2011-09-08 12:48:16 +020087}
aurel32ca587a82008-12-18 22:44:13 +000088
Alex Bennéed2a6c852017-07-12 11:52:14 +010089/* Return the GDB index for a given vCPU state.
90 *
91 * For user mode this is simply the thread id. In system mode GDB
92 * numbers CPUs from 1 as 0 is reserved as an "any cpu" index.
93 */
94static inline int cpu_gdb_index(CPUState *cpu)
95{
96#if defined(CONFIG_USER_ONLY)
Alex Bennéebd88c782017-07-12 11:52:15 +010097 TaskState *ts = (TaskState *) cpu->opaque;
Alex Bennéea8e537f2021-11-29 14:09:29 +000098 return ts ? ts->ts_tid : -1;
Alex Bennéed2a6c852017-07-12 11:52:14 +010099#else
100 return cpu->cpu_index + 1;
101#endif
102}
103
aurel32ca587a82008-12-18 22:44:13 +0000104enum {
105 GDB_SIGNAL_0 = 0,
106 GDB_SIGNAL_INT = 2,
Jan Kiszka425189a2011-03-22 11:02:09 +0100107 GDB_SIGNAL_QUIT = 3,
aurel32ca587a82008-12-18 22:44:13 +0000108 GDB_SIGNAL_TRAP = 5,
Jan Kiszka425189a2011-03-22 11:02:09 +0100109 GDB_SIGNAL_ABRT = 6,
110 GDB_SIGNAL_ALRM = 14,
111 GDB_SIGNAL_IO = 23,
112 GDB_SIGNAL_XCPU = 24,
aurel32ca587a82008-12-18 22:44:13 +0000113 GDB_SIGNAL_UNKNOWN = 143
114};
115
116#ifdef CONFIG_USER_ONLY
117
118/* Map target signal numbers to GDB protocol signal numbers and vice
119 * versa. For user emulation's currently supported systems, we can
120 * assume most signals are defined.
121 */
122
123static int gdb_signal_table[] = {
124 0,
125 TARGET_SIGHUP,
126 TARGET_SIGINT,
127 TARGET_SIGQUIT,
128 TARGET_SIGILL,
129 TARGET_SIGTRAP,
130 TARGET_SIGABRT,
131 -1, /* SIGEMT */
132 TARGET_SIGFPE,
133 TARGET_SIGKILL,
134 TARGET_SIGBUS,
135 TARGET_SIGSEGV,
136 TARGET_SIGSYS,
137 TARGET_SIGPIPE,
138 TARGET_SIGALRM,
139 TARGET_SIGTERM,
140 TARGET_SIGURG,
141 TARGET_SIGSTOP,
142 TARGET_SIGTSTP,
143 TARGET_SIGCONT,
144 TARGET_SIGCHLD,
145 TARGET_SIGTTIN,
146 TARGET_SIGTTOU,
147 TARGET_SIGIO,
148 TARGET_SIGXCPU,
149 TARGET_SIGXFSZ,
150 TARGET_SIGVTALRM,
151 TARGET_SIGPROF,
152 TARGET_SIGWINCH,
153 -1, /* SIGLOST */
154 TARGET_SIGUSR1,
155 TARGET_SIGUSR2,
blueswir1c72d5bf2009-01-15 17:27:45 +0000156#ifdef TARGET_SIGPWR
aurel32ca587a82008-12-18 22:44:13 +0000157 TARGET_SIGPWR,
blueswir1c72d5bf2009-01-15 17:27:45 +0000158#else
159 -1,
160#endif
aurel32ca587a82008-12-18 22:44:13 +0000161 -1, /* SIGPOLL */
162 -1,
163 -1,
164 -1,
165 -1,
166 -1,
167 -1,
168 -1,
169 -1,
170 -1,
171 -1,
172 -1,
blueswir1c72d5bf2009-01-15 17:27:45 +0000173#ifdef __SIGRTMIN
aurel32ca587a82008-12-18 22:44:13 +0000174 __SIGRTMIN + 1,
175 __SIGRTMIN + 2,
176 __SIGRTMIN + 3,
177 __SIGRTMIN + 4,
178 __SIGRTMIN + 5,
179 __SIGRTMIN + 6,
180 __SIGRTMIN + 7,
181 __SIGRTMIN + 8,
182 __SIGRTMIN + 9,
183 __SIGRTMIN + 10,
184 __SIGRTMIN + 11,
185 __SIGRTMIN + 12,
186 __SIGRTMIN + 13,
187 __SIGRTMIN + 14,
188 __SIGRTMIN + 15,
189 __SIGRTMIN + 16,
190 __SIGRTMIN + 17,
191 __SIGRTMIN + 18,
192 __SIGRTMIN + 19,
193 __SIGRTMIN + 20,
194 __SIGRTMIN + 21,
195 __SIGRTMIN + 22,
196 __SIGRTMIN + 23,
197 __SIGRTMIN + 24,
198 __SIGRTMIN + 25,
199 __SIGRTMIN + 26,
200 __SIGRTMIN + 27,
201 __SIGRTMIN + 28,
202 __SIGRTMIN + 29,
203 __SIGRTMIN + 30,
204 __SIGRTMIN + 31,
205 -1, /* SIGCANCEL */
206 __SIGRTMIN,
207 __SIGRTMIN + 32,
208 __SIGRTMIN + 33,
209 __SIGRTMIN + 34,
210 __SIGRTMIN + 35,
211 __SIGRTMIN + 36,
212 __SIGRTMIN + 37,
213 __SIGRTMIN + 38,
214 __SIGRTMIN + 39,
215 __SIGRTMIN + 40,
216 __SIGRTMIN + 41,
217 __SIGRTMIN + 42,
218 __SIGRTMIN + 43,
219 __SIGRTMIN + 44,
220 __SIGRTMIN + 45,
221 __SIGRTMIN + 46,
222 __SIGRTMIN + 47,
223 __SIGRTMIN + 48,
224 __SIGRTMIN + 49,
225 __SIGRTMIN + 50,
226 __SIGRTMIN + 51,
227 __SIGRTMIN + 52,
228 __SIGRTMIN + 53,
229 __SIGRTMIN + 54,
230 __SIGRTMIN + 55,
231 __SIGRTMIN + 56,
232 __SIGRTMIN + 57,
233 __SIGRTMIN + 58,
234 __SIGRTMIN + 59,
235 __SIGRTMIN + 60,
236 __SIGRTMIN + 61,
237 __SIGRTMIN + 62,
238 __SIGRTMIN + 63,
239 __SIGRTMIN + 64,
240 __SIGRTMIN + 65,
241 __SIGRTMIN + 66,
242 __SIGRTMIN + 67,
243 __SIGRTMIN + 68,
244 __SIGRTMIN + 69,
245 __SIGRTMIN + 70,
246 __SIGRTMIN + 71,
247 __SIGRTMIN + 72,
248 __SIGRTMIN + 73,
249 __SIGRTMIN + 74,
250 __SIGRTMIN + 75,
251 __SIGRTMIN + 76,
252 __SIGRTMIN + 77,
253 __SIGRTMIN + 78,
254 __SIGRTMIN + 79,
255 __SIGRTMIN + 80,
256 __SIGRTMIN + 81,
257 __SIGRTMIN + 82,
258 __SIGRTMIN + 83,
259 __SIGRTMIN + 84,
260 __SIGRTMIN + 85,
261 __SIGRTMIN + 86,
262 __SIGRTMIN + 87,
263 __SIGRTMIN + 88,
264 __SIGRTMIN + 89,
265 __SIGRTMIN + 90,
266 __SIGRTMIN + 91,
267 __SIGRTMIN + 92,
268 __SIGRTMIN + 93,
269 __SIGRTMIN + 94,
270 __SIGRTMIN + 95,
271 -1, /* SIGINFO */
272 -1, /* UNKNOWN */
273 -1, /* DEFAULT */
274 -1,
275 -1,
276 -1,
277 -1,
278 -1,
279 -1
blueswir1c72d5bf2009-01-15 17:27:45 +0000280#endif
aurel32ca587a82008-12-18 22:44:13 +0000281};
bellard8f447cc2006-06-14 15:21:14 +0000282#else
aurel32ca587a82008-12-18 22:44:13 +0000283/* In system mode we only need SIGINT and SIGTRAP; other signals
284 are not yet supported. */
285
286enum {
287 TARGET_SIGINT = 2,
288 TARGET_SIGTRAP = 5
289};
290
291static int gdb_signal_table[] = {
292 -1,
293 -1,
294 TARGET_SIGINT,
295 -1,
296 -1,
297 TARGET_SIGTRAP
298};
bellard8f447cc2006-06-14 15:21:14 +0000299#endif
bellardb4608c02003-06-27 17:34:32 +0000300
aurel32ca587a82008-12-18 22:44:13 +0000301#ifdef CONFIG_USER_ONLY
302static int target_signal_to_gdb (int sig)
303{
304 int i;
305 for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
306 if (gdb_signal_table[i] == sig)
307 return i;
308 return GDB_SIGNAL_UNKNOWN;
309}
310#endif
311
312static int gdb_signal_to_target (int sig)
313{
314 if (sig < ARRAY_SIZE (gdb_signal_table))
315 return gdb_signal_table[sig];
316 else
317 return -1;
318}
319
pbrook56aebc82008-10-11 17:55:29 +0000320typedef struct GDBRegisterState {
321 int base_reg;
322 int num_regs;
Alex Bennéea010bdb2020-03-16 17:21:41 +0000323 gdb_get_reg_cb get_reg;
324 gdb_set_reg_cb set_reg;
pbrook56aebc82008-10-11 17:55:29 +0000325 const char *xml;
326 struct GDBRegisterState *next;
327} GDBRegisterState;
328
Luc Michel8f468632019-01-07 15:23:45 +0000329typedef struct GDBProcess {
330 uint32_t pid;
331 bool attached;
Luc Michelc145eea2019-01-07 15:23:46 +0000332
333 char target_xml[1024];
Luc Michel8f468632019-01-07 15:23:45 +0000334} GDBProcess;
335
bellard858693c2004-03-31 18:52:07 +0000336enum RSState {
aliguori36556b22009-03-28 18:05:53 +0000337 RS_INACTIVE,
bellard858693c2004-03-31 18:52:07 +0000338 RS_IDLE,
339 RS_GETLINE,
Doug Gale4bf43122017-05-01 12:22:10 -0400340 RS_GETLINE_ESC,
341 RS_GETLINE_RLE,
bellard858693c2004-03-31 18:52:07 +0000342 RS_CHKSUM1,
343 RS_CHKSUM2,
344};
bellard858693c2004-03-31 18:52:07 +0000345typedef struct GDBState {
Alex Bennée8d98c442020-03-16 17:21:33 +0000346 bool init; /* have we been initialised? */
Andreas Färber2e0f2cf2013-06-27 19:19:39 +0200347 CPUState *c_cpu; /* current CPU for step/continue ops */
348 CPUState *g_cpu; /* current CPU for other ops */
Andreas Färber52f34622013-06-27 13:44:40 +0200349 CPUState *query_cpu; /* for q{f|s}ThreadInfo */
bellard41625032005-04-24 10:07:11 +0000350 enum RSState state; /* parsing state */
pbrook56aebc82008-10-11 17:55:29 +0000351 char line_buf[MAX_PACKET_LENGTH];
bellard858693c2004-03-31 18:52:07 +0000352 int line_buf_index;
Doug Gale4bf43122017-05-01 12:22:10 -0400353 int line_sum; /* running checksum */
354 int line_csum; /* checksum at the end of the packet */
Damien Hedded116e812020-03-16 17:21:53 +0000355 GByteArray *last_packet;
edgar_igl1f487ee2008-05-17 22:20:53 +0000356 int signal;
bellard41625032005-04-24 10:07:11 +0000357#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000358 int fd;
Alex Bennéefcedd922020-04-30 20:01:19 +0100359 char *socket_path;
bellard41625032005-04-24 10:07:11 +0000360 int running_state;
pbrook4046d912007-01-28 01:53:16 +0000361#else
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +0300362 CharBackend chr;
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +0300363 Chardev *mon_chr;
bellard41625032005-04-24 10:07:11 +0000364#endif
Luc Michel8f468632019-01-07 15:23:45 +0000365 bool multiprocess;
366 GDBProcess *processes;
367 int process_num;
Meador Ingecdb432b2012-03-15 17:49:45 +0000368 char syscall_buf[256];
369 gdb_syscall_complete_cb current_syscall_cb;
Alex Bennée308f9e82020-03-16 17:21:35 +0000370 GString *str_buf;
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000371 GByteArray *mem_buf;
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100372 int sstep_flags;
373 int supported_sstep_flags;
bellard858693c2004-03-31 18:52:07 +0000374} GDBState;
bellardb4608c02003-06-27 17:34:32 +0000375
Alex Bennée8d98c442020-03-16 17:21:33 +0000376static GDBState gdbserver_state;
377
378static void init_gdbserver_state(void)
379{
380 g_assert(!gdbserver_state.init);
381 memset(&gdbserver_state, 0, sizeof(GDBState));
382 gdbserver_state.init = true;
Alex Bennée308f9e82020-03-16 17:21:35 +0000383 gdbserver_state.str_buf = g_string_new(NULL);
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000384 gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
Damien Hedded116e812020-03-16 17:21:53 +0000385 gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100386
387 /*
Alex Bennée3b7a9382022-09-29 12:42:23 +0100388 * What single-step modes are supported is accelerator dependent.
389 * By default try to use no IRQs and no timers while single
390 * stepping so as to make single stepping like a typical ICE HW step.
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100391 */
Alex Bennée3b7a9382022-09-29 12:42:23 +0100392 gdbserver_state.supported_sstep_flags = accel_supported_gdbstub_sstep_flags();
Maxim Levitsky12bc5b42021-11-11 12:06:03 +0100393 gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
394 gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
Alex Bennée8d98c442020-03-16 17:21:33 +0000395}
396
397#ifndef CONFIG_USER_ONLY
398static void reset_gdbserver_state(void)
399{
400 g_free(gdbserver_state.processes);
401 gdbserver_state.processes = NULL;
402 gdbserver_state.process_num = 0;
403}
404#endif
aliguori880a7572008-11-18 20:30:24 +0000405
Andreas Färber5b50e792013-06-29 04:18:45 +0200406bool gdb_has_xml;
pbrook56aebc82008-10-11 17:55:29 +0000407
bellard1fddef42005-04-17 19:16:13 +0000408#ifdef CONFIG_USER_ONLY
pbrook4046d912007-01-28 01:53:16 +0000409
Alex Bennéea346af32020-03-16 17:21:34 +0000410static int get_char(void)
bellardb4608c02003-06-27 17:34:32 +0000411{
412 uint8_t ch;
413 int ret;
414
415 for(;;) {
Marc-André Lureaue7b79422022-02-19 01:34:50 +0400416 ret = recv(gdbserver_state.fd, &ch, 1, 0);
bellardb4608c02003-06-27 17:34:32 +0000417 if (ret < 0) {
edgar_igl1f487ee2008-05-17 22:20:53 +0000418 if (errno == ECONNRESET)
Alex Bennéea346af32020-03-16 17:21:34 +0000419 gdbserver_state.fd = -1;
Peter Wu5819e3e2016-06-05 16:35:48 +0200420 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000421 return -1;
422 } else if (ret == 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000423 close(gdbserver_state.fd);
424 gdbserver_state.fd = -1;
bellardb4608c02003-06-27 17:34:32 +0000425 return -1;
426 } else {
427 break;
428 }
429 }
430 return ch;
431}
pbrook4046d912007-01-28 01:53:16 +0000432#endif
bellardb4608c02003-06-27 17:34:32 +0000433
Peter Maydellebf1b4c2022-06-10 14:32:36 +0100434/*
435 * Return true if there is a GDB currently connected to the stub
436 * and attached to a CPU
437 */
438static bool gdb_attached(void)
439{
440 return gdbserver_state.init && gdbserver_state.c_cpu;
441}
442
blueswir1654efcf2009-04-18 07:29:59 +0000443static enum {
pbrooka2d1eba2007-01-28 03:10:55 +0000444 GDB_SYS_UNKNOWN,
445 GDB_SYS_ENABLED,
446 GDB_SYS_DISABLED,
447} gdb_syscall_mode;
448
Liviu Ionescua38bb072014-12-11 12:07:48 +0000449/* Decide if either remote gdb syscalls or native file IO should be used. */
pbrooka2d1eba2007-01-28 03:10:55 +0000450int use_gdb_syscalls(void)
451{
Leon Alraecfe67ce2015-06-19 14:17:45 +0100452 SemihostingTarget target = semihosting_get_target();
453 if (target == SEMIHOSTING_TARGET_NATIVE) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000454 /* -semihosting-config target=native */
455 return false;
Leon Alraecfe67ce2015-06-19 14:17:45 +0100456 } else if (target == SEMIHOSTING_TARGET_GDB) {
Liviu Ionescua38bb072014-12-11 12:07:48 +0000457 /* -semihosting-config target=gdb */
458 return true;
459 }
460
461 /* -semihosting-config target=auto */
462 /* On the first call check if gdb is connected and remember. */
pbrooka2d1eba2007-01-28 03:10:55 +0000463 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
Peter Maydellebf1b4c2022-06-10 14:32:36 +0100464 gdb_syscall_mode = gdb_attached() ? GDB_SYS_ENABLED : GDB_SYS_DISABLED;
pbrooka2d1eba2007-01-28 03:10:55 +0000465 }
466 return gdb_syscall_mode == GDB_SYS_ENABLED;
467}
468
Alex Bennéeed12f5b2021-05-20 18:43:02 +0100469static bool stub_can_reverse(void)
470{
471#ifdef CONFIG_USER_ONLY
472 return false;
473#else
474 return replay_mode == REPLAY_MODE_PLAY;
475#endif
476}
477
edgar_iglba70a622008-03-14 06:10:42 +0000478/* Resume execution. */
Alex Bennéea346af32020-03-16 17:21:34 +0000479static inline void gdb_continue(void)
edgar_iglba70a622008-03-14 06:10:42 +0000480{
Doug Gale5c9522b2017-12-02 20:30:37 -0500481
edgar_iglba70a622008-03-14 06:10:42 +0000482#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000483 gdbserver_state.running_state = 1;
Doug Gale5c9522b2017-12-02 20:30:37 -0500484 trace_gdbstub_op_continue();
edgar_iglba70a622008-03-14 06:10:42 +0000485#else
Paolo Bonzini26ac7a32013-06-03 17:06:54 +0200486 if (!runstate_needs_reset()) {
Doug Gale5c9522b2017-12-02 20:30:37 -0500487 trace_gdbstub_op_continue();
Paolo Bonzini87f25c12013-05-30 13:20:40 +0200488 vm_start();
489 }
edgar_iglba70a622008-03-14 06:10:42 +0000490#endif
491}
492
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100493/*
494 * Resume execution, per CPU actions. For user-mode emulation it's
495 * equivalent to gdb_continue.
496 */
Alex Bennéea346af32020-03-16 17:21:34 +0000497static int gdb_continue_partial(char *newstates)
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100498{
499 CPUState *cpu;
500 int res = 0;
501#ifdef CONFIG_USER_ONLY
502 /*
503 * This is not exactly accurate, but it's an improvement compared to the
504 * previous situation, where only one CPU would be single-stepped.
505 */
506 CPU_FOREACH(cpu) {
507 if (newstates[cpu->cpu_index] == 's') {
Doug Gale5c9522b2017-12-02 20:30:37 -0500508 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100509 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100510 }
511 }
Alex Bennéea346af32020-03-16 17:21:34 +0000512 gdbserver_state.running_state = 1;
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100513#else
514 int flag = 0;
515
516 if (!runstate_needs_reset()) {
Ivan Shcherbakovd7482ff2022-03-02 17:28:33 -0800517 bool step_requested = false;
518 CPU_FOREACH(cpu) {
519 if (newstates[cpu->cpu_index] == 's') {
520 step_requested = true;
521 break;
522 }
523 }
524
525 if (vm_prepare_start(step_requested)) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100526 return 0;
527 }
528
529 CPU_FOREACH(cpu) {
530 switch (newstates[cpu->cpu_index]) {
531 case 0:
532 case 1:
533 break; /* nothing to do here */
534 case 's':
Doug Gale5c9522b2017-12-02 20:30:37 -0500535 trace_gdbstub_op_stepping(cpu->cpu_index);
Maxim Levitskyecd39d62021-11-11 12:06:02 +0100536 cpu_single_step(cpu, gdbserver_state.sstep_flags);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100537 cpu_resume(cpu);
538 flag = 1;
539 break;
540 case 'c':
Doug Gale5c9522b2017-12-02 20:30:37 -0500541 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
Claudio Imbrenda544177a2017-02-14 18:07:48 +0100542 cpu_resume(cpu);
543 flag = 1;
544 break;
545 default:
546 res = -1;
547 break;
548 }
549 }
550 }
551 if (flag) {
552 qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
553 }
554#endif
555 return res;
556}
557
Alex Bennéea346af32020-03-16 17:21:34 +0000558static void put_buffer(const uint8_t *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000559{
pbrook4046d912007-01-28 01:53:16 +0000560#ifdef CONFIG_USER_ONLY
bellardb4608c02003-06-27 17:34:32 +0000561 int ret;
562
563 while (len > 0) {
Alex Bennéea346af32020-03-16 17:21:34 +0000564 ret = send(gdbserver_state.fd, buf, len, 0);
bellardb4608c02003-06-27 17:34:32 +0000565 if (ret < 0) {
Peter Wu5819e3e2016-06-05 16:35:48 +0200566 if (errno != EINTR)
bellardb4608c02003-06-27 17:34:32 +0000567 return;
568 } else {
569 buf += ret;
570 len -= ret;
571 }
572 }
pbrook4046d912007-01-28 01:53:16 +0000573#else
Daniel P. Berrange6ab3fc32016-09-06 14:56:04 +0100574 /* XXX this blocks entire thread. Rewrite to use
575 * qemu_chr_fe_write and background I/O callbacks */
Alex Bennéea346af32020-03-16 17:21:34 +0000576 qemu_chr_fe_write_all(&gdbserver_state.chr, buf, len);
pbrook4046d912007-01-28 01:53:16 +0000577#endif
bellardb4608c02003-06-27 17:34:32 +0000578}
579
580static inline int fromhex(int v)
581{
582 if (v >= '0' && v <= '9')
583 return v - '0';
584 else if (v >= 'A' && v <= 'F')
585 return v - 'A' + 10;
586 else if (v >= 'a' && v <= 'f')
587 return v - 'a' + 10;
588 else
589 return 0;
590}
591
592static inline int tohex(int v)
593{
594 if (v < 10)
595 return v + '0';
596 else
597 return v - 10 + 'a';
598}
599
Philippe Mathieu-Daudé90057742018-04-08 11:59:33 -0300600/* writes 2*len+1 bytes in buf */
Alex Bennée308f9e82020-03-16 17:21:35 +0000601static void memtohex(GString *buf, const uint8_t *mem, int len)
bellardb4608c02003-06-27 17:34:32 +0000602{
603 int i, c;
bellardb4608c02003-06-27 17:34:32 +0000604 for(i = 0; i < len; i++) {
605 c = mem[i];
Alex Bennée308f9e82020-03-16 17:21:35 +0000606 g_string_append_c(buf, tohex(c >> 4));
607 g_string_append_c(buf, tohex(c & 0xf));
bellardb4608c02003-06-27 17:34:32 +0000608 }
Alex Bennée308f9e82020-03-16 17:21:35 +0000609 g_string_append_c(buf, '\0');
bellardb4608c02003-06-27 17:34:32 +0000610}
611
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000612static void hextomem(GByteArray *mem, const char *buf, int len)
bellardb4608c02003-06-27 17:34:32 +0000613{
614 int i;
615
616 for(i = 0; i < len; i++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +0000617 guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
618 g_byte_array_append(mem, &byte, 1);
bellardb4608c02003-06-27 17:34:32 +0000619 buf += 2;
620 }
621}
622
Doug Gale5c9522b2017-12-02 20:30:37 -0500623static void hexdump(const char *buf, int len,
624 void (*trace_fn)(size_t ofs, char const *text))
625{
626 char line_buffer[3 * 16 + 4 + 16 + 1];
627
628 size_t i;
629 for (i = 0; i < len || (i & 0xF); ++i) {
630 size_t byte_ofs = i & 15;
631
632 if (byte_ofs == 0) {
633 memset(line_buffer, ' ', 3 * 16 + 4 + 16);
634 line_buffer[3 * 16 + 4 + 16] = 0;
635 }
636
637 size_t col_group = (i >> 2) & 3;
638 size_t hex_col = byte_ofs * 3 + col_group;
639 size_t txt_col = 3 * 16 + 4 + byte_ofs;
640
641 if (i < len) {
642 char value = buf[i];
643
644 line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
645 line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
646 line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
647 ? value
648 : '.';
649 }
650
651 if (byte_ofs == 0xF)
652 trace_fn(i & -16, line_buffer);
653 }
654}
655
bellardb4608c02003-06-27 17:34:32 +0000656/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000657static int put_packet_binary(const char *buf, int len, bool dump)
bellardb4608c02003-06-27 17:34:32 +0000658{
pbrook56aebc82008-10-11 17:55:29 +0000659 int csum, i;
Damien Hedded116e812020-03-16 17:21:53 +0000660 uint8_t footer[3];
bellardb4608c02003-06-27 17:34:32 +0000661
Doug Gale5c9522b2017-12-02 20:30:37 -0500662 if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
663 hexdump(buf, len, trace_gdbstub_io_binaryreply);
664 }
665
bellardb4608c02003-06-27 17:34:32 +0000666 for(;;) {
Damien Hedded116e812020-03-16 17:21:53 +0000667 g_byte_array_set_size(gdbserver_state.last_packet, 0);
668 g_byte_array_append(gdbserver_state.last_packet,
669 (const uint8_t *) "$", 1);
670 g_byte_array_append(gdbserver_state.last_packet,
671 (const uint8_t *) buf, len);
bellardb4608c02003-06-27 17:34:32 +0000672 csum = 0;
673 for(i = 0; i < len; i++) {
674 csum += buf[i];
675 }
Damien Hedded116e812020-03-16 17:21:53 +0000676 footer[0] = '#';
677 footer[1] = tohex((csum >> 4) & 0xf);
678 footer[2] = tohex((csum) & 0xf);
679 g_byte_array_append(gdbserver_state.last_packet, footer, 3);
bellardb4608c02003-06-27 17:34:32 +0000680
Damien Hedded116e812020-03-16 17:21:53 +0000681 put_buffer(gdbserver_state.last_packet->data,
682 gdbserver_state.last_packet->len);
bellardb4608c02003-06-27 17:34:32 +0000683
pbrook4046d912007-01-28 01:53:16 +0000684#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +0000685 i = get_char();
pbrook4046d912007-01-28 01:53:16 +0000686 if (i < 0)
bellardb4608c02003-06-27 17:34:32 +0000687 return -1;
pbrook4046d912007-01-28 01:53:16 +0000688 if (i == '+')
bellardb4608c02003-06-27 17:34:32 +0000689 break;
pbrook4046d912007-01-28 01:53:16 +0000690#else
691 break;
692#endif
bellardb4608c02003-06-27 17:34:32 +0000693 }
694 return 0;
695}
696
pbrook56aebc82008-10-11 17:55:29 +0000697/* return -1 if error, 0 if OK */
Alex Bennéea346af32020-03-16 17:21:34 +0000698static int put_packet(const char *buf)
pbrook56aebc82008-10-11 17:55:29 +0000699{
Doug Gale5c9522b2017-12-02 20:30:37 -0500700 trace_gdbstub_io_reply(buf);
pbrook56aebc82008-10-11 17:55:29 +0000701
Alex Bennéea346af32020-03-16 17:21:34 +0000702 return put_packet_binary(buf, strlen(buf), false);
pbrook56aebc82008-10-11 17:55:29 +0000703}
704
Alex Bennée308f9e82020-03-16 17:21:35 +0000705static void put_strbuf(void)
pbrook56aebc82008-10-11 17:55:29 +0000706{
Alex Bennée308f9e82020-03-16 17:21:35 +0000707 put_packet(gdbserver_state.str_buf->str);
708}
709
710/* Encode data using the encoding for 'x' packets. */
711static void memtox(GString *buf, const char *mem, int len)
712{
pbrook56aebc82008-10-11 17:55:29 +0000713 char c;
714
715 while (len--) {
716 c = *(mem++);
717 switch (c) {
718 case '#': case '$': case '*': case '}':
Alex Bennée308f9e82020-03-16 17:21:35 +0000719 g_string_append_c(buf, '}');
720 g_string_append_c(buf, c ^ 0x20);
pbrook56aebc82008-10-11 17:55:29 +0000721 break;
722 default:
Alex Bennée308f9e82020-03-16 17:21:35 +0000723 g_string_append_c(buf, c);
pbrook56aebc82008-10-11 17:55:29 +0000724 break;
725 }
726 }
pbrook56aebc82008-10-11 17:55:29 +0000727}
728
Alex Bennéea346af32020-03-16 17:21:34 +0000729static uint32_t gdb_get_cpu_pid(CPUState *cpu)
Luc Michel1a227332019-01-07 15:23:45 +0000730{
Luc Michel1a227332019-01-07 15:23:45 +0000731 /* TODO: In user mode, we should use the task state PID */
Peter Maydell46f5abc2019-01-29 11:46:06 +0000732 if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
733 /* Return the default process' PID */
Alex Bennéea346af32020-03-16 17:21:34 +0000734 int index = gdbserver_state.process_num - 1;
735 return gdbserver_state.processes[index].pid;
Peter Maydell46f5abc2019-01-29 11:46:06 +0000736 }
737 return cpu->cluster_index + 1;
Luc Michel1a227332019-01-07 15:23:45 +0000738}
739
Alex Bennéea346af32020-03-16 17:21:34 +0000740static GDBProcess *gdb_get_process(uint32_t pid)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000741{
742 int i;
743
744 if (!pid) {
745 /* 0 means any process, we take the first one */
Alex Bennéea346af32020-03-16 17:21:34 +0000746 return &gdbserver_state.processes[0];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000747 }
748
Alex Bennéea346af32020-03-16 17:21:34 +0000749 for (i = 0; i < gdbserver_state.process_num; i++) {
750 if (gdbserver_state.processes[i].pid == pid) {
751 return &gdbserver_state.processes[i];
Luc Michel7d8c87d2019-01-07 15:23:45 +0000752 }
753 }
754
755 return NULL;
756}
757
Alex Bennéea346af32020-03-16 17:21:34 +0000758static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
Luc Michel7d8c87d2019-01-07 15:23:45 +0000759{
Alex Bennéea346af32020-03-16 17:21:34 +0000760 return gdb_get_process(gdb_get_cpu_pid(cpu));
Luc Michel7d8c87d2019-01-07 15:23:45 +0000761}
762
763static CPUState *find_cpu(uint32_t thread_id)
764{
765 CPUState *cpu;
766
767 CPU_FOREACH(cpu) {
768 if (cpu_gdb_index(cpu) == thread_id) {
769 return cpu;
770 }
771 }
772
773 return NULL;
774}
775
Alex Bennéea346af32020-03-16 17:21:34 +0000776static CPUState *get_first_cpu_in_process(GDBProcess *process)
Luc Michele40e5202019-01-07 15:23:46 +0000777{
778 CPUState *cpu;
779
780 CPU_FOREACH(cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000781 if (gdb_get_cpu_pid(cpu) == process->pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000782 return cpu;
783 }
784 }
785
786 return NULL;
787}
788
Alex Bennéea346af32020-03-16 17:21:34 +0000789static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000790{
Alex Bennéea346af32020-03-16 17:21:34 +0000791 uint32_t pid = gdb_get_cpu_pid(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000792 cpu = CPU_NEXT(cpu);
793
794 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000795 if (gdb_get_cpu_pid(cpu) == pid) {
Luc Michele40e5202019-01-07 15:23:46 +0000796 break;
797 }
798
799 cpu = CPU_NEXT(cpu);
800 }
801
802 return cpu;
803}
804
Luc Michele40e5202019-01-07 15:23:46 +0000805/* Return the cpu following @cpu, while ignoring unattached processes. */
Alex Bennéea346af32020-03-16 17:21:34 +0000806static CPUState *gdb_next_attached_cpu(CPUState *cpu)
Luc Michele40e5202019-01-07 15:23:46 +0000807{
808 cpu = CPU_NEXT(cpu);
809
810 while (cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +0000811 if (gdb_get_cpu_process(cpu)->attached) {
Luc Michele40e5202019-01-07 15:23:46 +0000812 break;
813 }
814
815 cpu = CPU_NEXT(cpu);
816 }
817
818 return cpu;
819}
820
821/* Return the first attached cpu */
Alex Bennéea346af32020-03-16 17:21:34 +0000822static CPUState *gdb_first_attached_cpu(void)
Luc Michele40e5202019-01-07 15:23:46 +0000823{
824 CPUState *cpu = first_cpu;
Alex Bennéea346af32020-03-16 17:21:34 +0000825 GDBProcess *process = gdb_get_cpu_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000826
827 if (!process->attached) {
Alex Bennéea346af32020-03-16 17:21:34 +0000828 return gdb_next_attached_cpu(cpu);
Luc Michele40e5202019-01-07 15:23:46 +0000829 }
830
831 return cpu;
832}
833
Alex Bennéea346af32020-03-16 17:21:34 +0000834static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
Luc Michelab65eed2019-01-29 11:46:03 +0000835{
836 GDBProcess *process;
837 CPUState *cpu;
838
839 if (!pid && !tid) {
840 /* 0 means any process/thread, we take the first attached one */
Alex Bennéea346af32020-03-16 17:21:34 +0000841 return gdb_first_attached_cpu();
Luc Michelab65eed2019-01-29 11:46:03 +0000842 } else if (pid && !tid) {
843 /* any thread in a specific process */
Alex Bennéea346af32020-03-16 17:21:34 +0000844 process = gdb_get_process(pid);
Luc Michelab65eed2019-01-29 11:46:03 +0000845
846 if (process == NULL) {
847 return NULL;
848 }
849
850 if (!process->attached) {
851 return NULL;
852 }
853
Alex Bennéea346af32020-03-16 17:21:34 +0000854 return get_first_cpu_in_process(process);
Luc Michelab65eed2019-01-29 11:46:03 +0000855 } else {
856 /* a specific thread */
857 cpu = find_cpu(tid);
858
859 if (cpu == NULL) {
860 return NULL;
861 }
862
Alex Bennéea346af32020-03-16 17:21:34 +0000863 process = gdb_get_cpu_process(cpu);
Luc Michelab65eed2019-01-29 11:46:03 +0000864
865 if (pid && process->pid != pid) {
866 return NULL;
867 }
868
869 if (!process->attached) {
870 return NULL;
871 }
872
873 return cpu;
874 }
875}
876
Alex Bennéea346af32020-03-16 17:21:34 +0000877static const char *get_feature_xml(const char *p, const char **newp,
878 GDBProcess *process)
pbrook56aebc82008-10-11 17:55:29 +0000879{
pbrook56aebc82008-10-11 17:55:29 +0000880 size_t len;
881 int i;
882 const char *name;
Alex Bennéea346af32020-03-16 17:21:34 +0000883 CPUState *cpu = get_first_cpu_in_process(process);
Luc Michelc145eea2019-01-07 15:23:46 +0000884 CPUClass *cc = CPU_GET_CLASS(cpu);
pbrook56aebc82008-10-11 17:55:29 +0000885
886 len = 0;
887 while (p[len] && p[len] != ':')
888 len++;
889 *newp = p + len;
890
891 name = NULL;
892 if (strncmp(p, "target.xml", len) == 0) {
Luc Michelc145eea2019-01-07 15:23:46 +0000893 char *buf = process->target_xml;
894 const size_t buf_sz = sizeof(process->target_xml);
pbrook56aebc82008-10-11 17:55:29 +0000895
Luc Michelc145eea2019-01-07 15:23:46 +0000896 /* Generate the XML description for this CPU. */
897 if (!buf[0]) {
898 GDBRegisterState *r;
899
900 pstrcat(buf, buf_sz,
David Hildenbrandb3820e62015-12-03 13:14:41 +0100901 "<?xml version=\"1.0\"?>"
902 "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
903 "<target>");
904 if (cc->gdb_arch_name) {
905 gchar *arch = cc->gdb_arch_name(cpu);
Luc Michelc145eea2019-01-07 15:23:46 +0000906 pstrcat(buf, buf_sz, "<architecture>");
907 pstrcat(buf, buf_sz, arch);
908 pstrcat(buf, buf_sz, "</architecture>");
David Hildenbrandb3820e62015-12-03 13:14:41 +0100909 g_free(arch);
910 }
Luc Michelc145eea2019-01-07 15:23:46 +0000911 pstrcat(buf, buf_sz, "<xi:include href=\"");
912 pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
913 pstrcat(buf, buf_sz, "\"/>");
Andreas Färbereac8b352013-06-28 21:11:37 +0200914 for (r = cpu->gdb_regs; r; r = r->next) {
Luc Michelc145eea2019-01-07 15:23:46 +0000915 pstrcat(buf, buf_sz, "<xi:include href=\"");
916 pstrcat(buf, buf_sz, r->xml);
917 pstrcat(buf, buf_sz, "\"/>");
pbrook56aebc82008-10-11 17:55:29 +0000918 }
Luc Michelc145eea2019-01-07 15:23:46 +0000919 pstrcat(buf, buf_sz, "</target>");
pbrook56aebc82008-10-11 17:55:29 +0000920 }
Luc Michelc145eea2019-01-07 15:23:46 +0000921 return buf;
pbrook56aebc82008-10-11 17:55:29 +0000922 }
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100923 if (cc->gdb_get_dynamic_xml) {
Abdallah Bouassida200bf5b2018-05-18 17:48:07 +0100924 char *xmlname = g_strndup(p, len);
925 const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
926
927 g_free(xmlname);
928 if (xml) {
929 return xml;
930 }
931 }
pbrook56aebc82008-10-11 17:55:29 +0000932 for (i = 0; ; i++) {
933 name = xml_builtin[i][0];
934 if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
935 break;
936 }
937 return name ? xml_builtin[i][1] : NULL;
938}
pbrook56aebc82008-10-11 17:55:29 +0000939
Alex Bennéea010bdb2020-03-16 17:21:41 +0000940static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000941{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200942 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200943 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000944 GDBRegisterState *r;
945
Andreas Färbera0e372f2013-06-28 23:18:47 +0200946 if (reg < cc->gdb_num_core_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000947 return cc->gdb_read_register(cpu, buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200948 }
pbrook56aebc82008-10-11 17:55:29 +0000949
Andreas Färbereac8b352013-06-28 21:11:37 +0200950 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000951 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
Alex Bennéea010bdb2020-03-16 17:21:41 +0000952 return r->get_reg(env, buf, reg - r->base_reg);
pbrook56aebc82008-10-11 17:55:29 +0000953 }
954 }
955 return 0;
956}
957
Andreas Färber385b9f02013-06-27 18:25:36 +0200958static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
pbrook56aebc82008-10-11 17:55:29 +0000959{
Andreas Färbera0e372f2013-06-28 23:18:47 +0200960 CPUClass *cc = CPU_GET_CLASS(cpu);
Andreas Färber385b9f02013-06-27 18:25:36 +0200961 CPUArchState *env = cpu->env_ptr;
pbrook56aebc82008-10-11 17:55:29 +0000962 GDBRegisterState *r;
963
Andreas Färbera0e372f2013-06-28 23:18:47 +0200964 if (reg < cc->gdb_num_core_regs) {
Andreas Färber5b50e792013-06-29 04:18:45 +0200965 return cc->gdb_write_register(cpu, mem_buf, reg);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200966 }
pbrook56aebc82008-10-11 17:55:29 +0000967
Andreas Färbereac8b352013-06-28 21:11:37 +0200968 for (r = cpu->gdb_regs; r; r = r->next) {
pbrook56aebc82008-10-11 17:55:29 +0000969 if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
970 return r->set_reg(env, mem_buf, reg - r->base_reg);
971 }
972 }
973 return 0;
974}
975
976/* Register a supplemental set of CPU registers. If g_pos is nonzero it
977 specifies the first register number and these registers are included in
978 a standard "g" packet. Direction is relative to gdb, i.e. get_reg is
979 gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
980 */
981
Andreas Färber22169d42013-06-28 21:27:39 +0200982void gdb_register_coprocessor(CPUState *cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +0000983 gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
Andreas Färber22169d42013-06-28 21:27:39 +0200984 int num_regs, const char *xml, int g_pos)
pbrook56aebc82008-10-11 17:55:29 +0000985{
986 GDBRegisterState *s;
987 GDBRegisterState **p;
pbrook56aebc82008-10-11 17:55:29 +0000988
Andreas Färbereac8b352013-06-28 21:11:37 +0200989 p = &cpu->gdb_regs;
pbrook56aebc82008-10-11 17:55:29 +0000990 while (*p) {
991 /* Check for duplicates. */
992 if (strcmp((*p)->xml, xml) == 0)
993 return;
994 p = &(*p)->next;
995 }
Stefan Weil9643c252011-10-18 22:25:38 +0200996
997 s = g_new0(GDBRegisterState, 1);
Andreas Färbera0e372f2013-06-28 23:18:47 +0200998 s->base_reg = cpu->gdb_num_regs;
Stefan Weil9643c252011-10-18 22:25:38 +0200999 s->num_regs = num_regs;
1000 s->get_reg = get_reg;
1001 s->set_reg = set_reg;
1002 s->xml = xml;
1003
pbrook56aebc82008-10-11 17:55:29 +00001004 /* Add to end of list. */
Andreas Färbera0e372f2013-06-28 23:18:47 +02001005 cpu->gdb_num_regs += num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001006 *p = s;
1007 if (g_pos) {
1008 if (g_pos != s->base_reg) {
Ziyue Yang7ae6c572017-01-18 16:03:29 +08001009 error_report("Error: Bad gdb register numbering for '%s', "
1010 "expected %d got %d", xml, g_pos, s->base_reg);
Andreas Färber35143f02013-08-12 18:09:47 +02001011 } else {
1012 cpu->gdb_num_g_regs = cpu->gdb_num_regs;
pbrook56aebc82008-10-11 17:55:29 +00001013 }
1014 }
1015}
1016
Alex Bennéea346af32020-03-16 17:21:34 +00001017static void gdb_process_breakpoint_remove_all(GDBProcess *p)
Luc Michel546f3c62019-01-07 15:23:46 +00001018{
Alex Bennéea346af32020-03-16 17:21:34 +00001019 CPUState *cpu = get_first_cpu_in_process(p);
Luc Michel546f3c62019-01-07 15:23:46 +00001020
1021 while (cpu) {
Alex Bennéeae7467b2022-09-29 12:42:24 +01001022 gdb_breakpoint_remove_all(cpu);
Alex Bennéea346af32020-03-16 17:21:34 +00001023 cpu = gdb_next_cpu_in_process(cpu);
Luc Michel546f3c62019-01-07 15:23:46 +00001024 }
1025}
1026
aliguoria1d1bb32008-11-18 20:07:32 +00001027
Alex Bennéea346af32020-03-16 17:21:34 +00001028static void gdb_set_cpu_pc(target_ulong pc)
aurel32fab9d282009-04-08 21:29:37 +00001029{
Alex Bennéea346af32020-03-16 17:21:34 +00001030 CPUState *cpu = gdbserver_state.c_cpu;
Andreas Färberf45748f2013-06-21 19:09:18 +02001031
1032 cpu_synchronize_state(cpu);
Peter Crosthwaite4a2b24e2015-06-23 20:19:21 -07001033 cpu_set_pc(cpu, pc);
aurel32fab9d282009-04-08 21:29:37 +00001034}
1035
Alex Bennée308f9e82020-03-16 17:21:35 +00001036static void gdb_append_thread_id(CPUState *cpu, GString *buf)
Luc Michel1a227332019-01-07 15:23:45 +00001037{
Alex Bennéea346af32020-03-16 17:21:34 +00001038 if (gdbserver_state.multiprocess) {
Alex Bennée308f9e82020-03-16 17:21:35 +00001039 g_string_append_printf(buf, "p%02x.%02x",
1040 gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001041 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00001042 g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
Luc Michel1a227332019-01-07 15:23:45 +00001043 }
Luc Michel1a227332019-01-07 15:23:45 +00001044}
1045
Luc Michel7d8c87d2019-01-07 15:23:45 +00001046typedef enum GDBThreadIdKind {
1047 GDB_ONE_THREAD = 0,
1048 GDB_ALL_THREADS, /* One process, all threads */
1049 GDB_ALL_PROCESSES,
1050 GDB_READ_THREAD_ERR
1051} GDBThreadIdKind;
1052
1053static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
1054 uint32_t *pid, uint32_t *tid)
1055{
1056 unsigned long p, t;
1057 int ret;
1058
1059 if (*buf == 'p') {
1060 buf++;
1061 ret = qemu_strtoul(buf, &buf, 16, &p);
1062
1063 if (ret) {
1064 return GDB_READ_THREAD_ERR;
1065 }
1066
1067 /* Skip '.' */
1068 buf++;
1069 } else {
1070 p = 1;
1071 }
1072
1073 ret = qemu_strtoul(buf, &buf, 16, &t);
1074
1075 if (ret) {
1076 return GDB_READ_THREAD_ERR;
1077 }
1078
1079 *end_buf = buf;
1080
1081 if (p == -1) {
1082 return GDB_ALL_PROCESSES;
1083 }
1084
1085 if (pid) {
1086 *pid = p;
1087 }
1088
1089 if (t == -1) {
1090 return GDB_ALL_THREADS;
1091 }
1092
1093 if (tid) {
1094 *tid = t;
1095 }
1096
1097 return GDB_ONE_THREAD;
1098}
1099
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001100/**
1101 * gdb_handle_vcont - Parses and handles a vCont packet.
1102 * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1103 * a format error, 0 on success.
1104 */
Alex Bennéea346af32020-03-16 17:21:34 +00001105static int gdb_handle_vcont(const char *p)
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001106{
Luc Michele40e5202019-01-07 15:23:46 +00001107 int res, signal = 0;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001108 char cur_action;
1109 char *newstates;
1110 unsigned long tmp;
Luc Michele40e5202019-01-07 15:23:46 +00001111 uint32_t pid, tid;
1112 GDBProcess *process;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001113 CPUState *cpu;
Luc Michelc99ef792019-03-26 12:53:26 +00001114 GDBThreadIdKind kind;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001115#ifdef CONFIG_USER_ONLY
1116 int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1117
1118 CPU_FOREACH(cpu) {
1119 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1120 }
Like Xu5cc87672019-05-19 04:54:21 +08001121#else
1122 MachineState *ms = MACHINE(qdev_get_machine());
1123 unsigned int max_cpus = ms->smp.max_cpus;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001124#endif
1125 /* uninitialised CPUs stay 0 */
1126 newstates = g_new0(char, max_cpus);
1127
1128 /* mark valid CPUs with 1 */
1129 CPU_FOREACH(cpu) {
1130 newstates[cpu->cpu_index] = 1;
1131 }
1132
1133 /*
1134 * res keeps track of what error we are returning, with -ENOTSUP meaning
1135 * that the command is unknown or unsupported, thus returning an empty
1136 * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1137 * or incorrect parameters passed.
1138 */
1139 res = 0;
1140 while (*p) {
1141 if (*p++ != ';') {
1142 res = -ENOTSUP;
1143 goto out;
1144 }
1145
1146 cur_action = *p++;
1147 if (cur_action == 'C' || cur_action == 'S') {
Peter Maydell95a5bef2017-07-20 17:31:30 +01001148 cur_action = qemu_tolower(cur_action);
Peter Maydell3ddd9032020-11-21 21:03:42 +00001149 res = qemu_strtoul(p, &p, 16, &tmp);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001150 if (res) {
1151 goto out;
1152 }
1153 signal = gdb_signal_to_target(tmp);
1154 } else if (cur_action != 'c' && cur_action != 's') {
1155 /* unknown/invalid/unsupported command */
1156 res = -ENOTSUP;
1157 goto out;
1158 }
Luc Michele40e5202019-01-07 15:23:46 +00001159
Luc Michelc99ef792019-03-26 12:53:26 +00001160 if (*p == '\0' || *p == ';') {
1161 /*
1162 * No thread specifier, action is on "all threads". The
1163 * specification is unclear regarding the process to act on. We
1164 * choose all processes.
1165 */
1166 kind = GDB_ALL_PROCESSES;
1167 } else if (*p++ == ':') {
1168 kind = read_thread_id(p, &p, &pid, &tid);
1169 } else {
Luc Michele40e5202019-01-07 15:23:46 +00001170 res = -ENOTSUP;
1171 goto out;
1172 }
1173
Luc Michelc99ef792019-03-26 12:53:26 +00001174 switch (kind) {
Luc Michele40e5202019-01-07 15:23:46 +00001175 case GDB_READ_THREAD_ERR:
1176 res = -EINVAL;
1177 goto out;
1178
1179 case GDB_ALL_PROCESSES:
Alex Bennéea346af32020-03-16 17:21:34 +00001180 cpu = gdb_first_attached_cpu();
Luc Michele40e5202019-01-07 15:23:46 +00001181 while (cpu) {
1182 if (newstates[cpu->cpu_index] == 1) {
1183 newstates[cpu->cpu_index] = cur_action;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001184 }
Luc Michele40e5202019-01-07 15:23:46 +00001185
Alex Bennéea346af32020-03-16 17:21:34 +00001186 cpu = gdb_next_attached_cpu(cpu);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001187 }
Luc Michele40e5202019-01-07 15:23:46 +00001188 break;
1189
1190 case GDB_ALL_THREADS:
Alex Bennéea346af32020-03-16 17:21:34 +00001191 process = gdb_get_process(pid);
Luc Michele40e5202019-01-07 15:23:46 +00001192
1193 if (!process->attached) {
1194 res = -EINVAL;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001195 goto out;
1196 }
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001197
Alex Bennéea346af32020-03-16 17:21:34 +00001198 cpu = get_first_cpu_in_process(process);
Luc Michele40e5202019-01-07 15:23:46 +00001199 while (cpu) {
1200 if (newstates[cpu->cpu_index] == 1) {
1201 newstates[cpu->cpu_index] = cur_action;
1202 }
1203
Alex Bennéea346af32020-03-16 17:21:34 +00001204 cpu = gdb_next_cpu_in_process(cpu);
Luc Michele40e5202019-01-07 15:23:46 +00001205 }
1206 break;
1207
1208 case GDB_ONE_THREAD:
Alex Bennéea346af32020-03-16 17:21:34 +00001209 cpu = gdb_get_cpu(pid, tid);
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001210
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001211 /* invalid CPU/thread specified */
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001212 if (!cpu) {
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001213 res = -EINVAL;
1214 goto out;
1215 }
Alex Bennée5a6a1ad2017-07-12 11:52:16 +01001216
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001217 /* only use if no previous match occourred */
1218 if (newstates[cpu->cpu_index] == 1) {
1219 newstates[cpu->cpu_index] = cur_action;
1220 }
Luc Michele40e5202019-01-07 15:23:46 +00001221 break;
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001222 }
1223 }
Alex Bennéea346af32020-03-16 17:21:34 +00001224 gdbserver_state.signal = signal;
1225 gdb_continue_partial(newstates);
Claudio Imbrenda544177a2017-02-14 18:07:48 +01001226
1227out:
1228 g_free(newstates);
1229
1230 return res;
1231}
1232
Jon Dorond14055d2019-05-29 09:41:29 +03001233typedef union GdbCmdVariant {
1234 const char *data;
1235 uint8_t opcode;
1236 unsigned long val_ul;
1237 unsigned long long val_ull;
1238 struct {
1239 GDBThreadIdKind kind;
1240 uint32_t pid;
1241 uint32_t tid;
1242 } thread_id;
1243} GdbCmdVariant;
1244
Alex Bennée26a16182021-05-25 09:24:14 +01001245#define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
1246
Jon Dorond14055d2019-05-29 09:41:29 +03001247static const char *cmd_next_param(const char *param, const char delimiter)
1248{
1249 static const char all_delimiters[] = ",;:=";
1250 char curr_delimiters[2] = {0};
1251 const char *delimiters;
1252
1253 if (delimiter == '?') {
1254 delimiters = all_delimiters;
1255 } else if (delimiter == '0') {
1256 return strchr(param, '\0');
1257 } else if (delimiter == '.' && *param) {
1258 return param + 1;
1259 } else {
1260 curr_delimiters[0] = delimiter;
1261 delimiters = curr_delimiters;
1262 }
1263
1264 param += strcspn(param, delimiters);
1265 if (*param) {
1266 param++;
1267 }
1268 return param;
1269}
1270
1271static int cmd_parse_params(const char *data, const char *schema,
Alex Bennée26a16182021-05-25 09:24:14 +01001272 GArray *params)
Jon Dorond14055d2019-05-29 09:41:29 +03001273{
Jon Dorond14055d2019-05-29 09:41:29 +03001274 const char *curr_schema, *curr_data;
1275
Alex Bennée26a16182021-05-25 09:24:14 +01001276 g_assert(schema);
1277 g_assert(params->len == 0);
Jon Dorond14055d2019-05-29 09:41:29 +03001278
1279 curr_schema = schema;
Jon Dorond14055d2019-05-29 09:41:29 +03001280 curr_data = data;
1281 while (curr_schema[0] && curr_schema[1] && *curr_data) {
Alex Bennée26a16182021-05-25 09:24:14 +01001282 GdbCmdVariant this_param;
1283
Jon Dorond14055d2019-05-29 09:41:29 +03001284 switch (curr_schema[0]) {
1285 case 'l':
1286 if (qemu_strtoul(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001287 &this_param.val_ul)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001288 return -EINVAL;
1289 }
Jon Dorond14055d2019-05-29 09:41:29 +03001290 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001291 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001292 break;
1293 case 'L':
1294 if (qemu_strtou64(curr_data, &curr_data, 16,
Alex Bennée26a16182021-05-25 09:24:14 +01001295 (uint64_t *)&this_param.val_ull)) {
Jon Dorond14055d2019-05-29 09:41:29 +03001296 return -EINVAL;
1297 }
Jon Dorond14055d2019-05-29 09:41:29 +03001298 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001299 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001300 break;
1301 case 's':
Alex Bennée26a16182021-05-25 09:24:14 +01001302 this_param.data = curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001303 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001304 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001305 break;
1306 case 'o':
Alex Bennée26a16182021-05-25 09:24:14 +01001307 this_param.opcode = *(uint8_t *)curr_data;
Jon Dorond14055d2019-05-29 09:41:29 +03001308 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001309 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001310 break;
1311 case 't':
Alex Bennée26a16182021-05-25 09:24:14 +01001312 this_param.thread_id.kind =
Jon Dorond14055d2019-05-29 09:41:29 +03001313 read_thread_id(curr_data, &curr_data,
Alex Bennée26a16182021-05-25 09:24:14 +01001314 &this_param.thread_id.pid,
1315 &this_param.thread_id.tid);
Jon Dorond14055d2019-05-29 09:41:29 +03001316 curr_data = cmd_next_param(curr_data, curr_schema[1]);
Alex Bennée26a16182021-05-25 09:24:14 +01001317 g_array_append_val(params, this_param);
Jon Dorond14055d2019-05-29 09:41:29 +03001318 break;
1319 case '?':
1320 curr_data = cmd_next_param(curr_data, curr_schema[1]);
1321 break;
1322 default:
1323 return -EINVAL;
1324 }
1325 curr_schema += 2;
1326 }
1327
Jon Dorond14055d2019-05-29 09:41:29 +03001328 return 0;
1329}
1330
Alex Bennée26a16182021-05-25 09:24:14 +01001331typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001332
1333/*
1334 * cmd_startswith -> cmd is compared using startswith
1335 *
1336 *
1337 * schema definitions:
1338 * Each schema parameter entry consists of 2 chars,
1339 * the first char represents the parameter type handling
1340 * the second char represents the delimiter for the next parameter
1341 *
1342 * Currently supported schema types:
1343 * 'l' -> unsigned long (stored in .val_ul)
1344 * 'L' -> unsigned long long (stored in .val_ull)
1345 * 's' -> string (stored in .data)
1346 * 'o' -> single char (stored in .opcode)
1347 * 't' -> thread id (stored in .thread_id)
1348 * '?' -> skip according to delimiter
1349 *
1350 * Currently supported delimiters:
1351 * '?' -> Stop at any delimiter (",;:=\0")
1352 * '0' -> Stop at "\0"
1353 * '.' -> Skip 1 char unless reached "\0"
1354 * Any other value is treated as the delimiter value itself
1355 */
1356typedef struct GdbCmdParseEntry {
1357 GdbCmdHandler handler;
1358 const char *cmd;
1359 bool cmd_startswith;
1360 const char *schema;
1361} GdbCmdParseEntry;
1362
1363static inline int startswith(const char *string, const char *pattern)
1364{
1365 return !strncmp(string, pattern, strlen(pattern));
1366}
1367
Alex Bennéea346af32020-03-16 17:21:34 +00001368static int process_string_cmd(void *user_ctx, const char *data,
Jon Dorond14055d2019-05-29 09:41:29 +03001369 const GdbCmdParseEntry *cmds, int num_cmds)
1370{
Alex Bennée26a16182021-05-25 09:24:14 +01001371 int i;
1372 g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
Jon Dorond14055d2019-05-29 09:41:29 +03001373
1374 if (!cmds) {
1375 return -1;
1376 }
1377
1378 for (i = 0; i < num_cmds; i++) {
1379 const GdbCmdParseEntry *cmd = &cmds[i];
1380 g_assert(cmd->handler && cmd->cmd);
1381
1382 if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1383 (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1384 continue;
1385 }
1386
1387 if (cmd->schema) {
Alex Bennée26a16182021-05-25 09:24:14 +01001388 if (cmd_parse_params(&data[strlen(cmd->cmd)],
1389 cmd->schema, params)) {
1390 return -1;
Jon Dorond14055d2019-05-29 09:41:29 +03001391 }
Jon Dorond14055d2019-05-29 09:41:29 +03001392 }
1393
Alex Bennée26a16182021-05-25 09:24:14 +01001394 cmd->handler(params, user_ctx);
Jon Dorond14055d2019-05-29 09:41:29 +03001395 return 0;
1396 }
1397
1398 return -1;
1399}
1400
Alex Bennéea346af32020-03-16 17:21:34 +00001401static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
Jon Doron3e2c1262019-05-29 09:41:30 +03001402{
1403 if (!data) {
1404 return;
1405 }
1406
Alex Bennée308f9e82020-03-16 17:21:35 +00001407 g_string_set_size(gdbserver_state.str_buf, 0);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001408 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Alex Bennée308f9e82020-03-16 17:21:35 +00001409
Jon Doron3e2c1262019-05-29 09:41:30 +03001410 /* In case there was an error during the command parsing we must
1411 * send a NULL packet to indicate the command is not supported */
Alex Bennéea346af32020-03-16 17:21:34 +00001412 if (process_string_cmd(NULL, data, cmd, 1)) {
1413 put_packet("");
Jon Doron3e2c1262019-05-29 09:41:30 +03001414 }
1415}
1416
Alex Bennée26a16182021-05-25 09:24:14 +01001417static void handle_detach(GArray *params, void *user_ctx)
Jon Doron3e2c1262019-05-29 09:41:30 +03001418{
1419 GDBProcess *process;
Jon Doron3e2c1262019-05-29 09:41:30 +03001420 uint32_t pid = 1;
1421
Alex Bennéea346af32020-03-16 17:21:34 +00001422 if (gdbserver_state.multiprocess) {
Alex Bennée26a16182021-05-25 09:24:14 +01001423 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001424 put_packet("E22");
Jon Doron3e2c1262019-05-29 09:41:30 +03001425 return;
1426 }
1427
Alex Bennée26a16182021-05-25 09:24:14 +01001428 pid = get_param(params, 0)->val_ul;
Jon Doron3e2c1262019-05-29 09:41:30 +03001429 }
1430
Alex Bennéea346af32020-03-16 17:21:34 +00001431 process = gdb_get_process(pid);
1432 gdb_process_breakpoint_remove_all(process);
Jon Doron3e2c1262019-05-29 09:41:30 +03001433 process->attached = false;
1434
Alex Bennéea346af32020-03-16 17:21:34 +00001435 if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1436 gdbserver_state.c_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001437 }
1438
Alex Bennéea346af32020-03-16 17:21:34 +00001439 if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1440 gdbserver_state.g_cpu = gdb_first_attached_cpu();
Jon Doron3e2c1262019-05-29 09:41:30 +03001441 }
1442
Alex Bennéea346af32020-03-16 17:21:34 +00001443 if (!gdbserver_state.c_cpu) {
Jon Doron3e2c1262019-05-29 09:41:30 +03001444 /* No more process attached */
1445 gdb_syscall_mode = GDB_SYS_DISABLED;
Alex Bennéea346af32020-03-16 17:21:34 +00001446 gdb_continue();
Jon Doron3e2c1262019-05-29 09:41:30 +03001447 }
Alex Bennéea346af32020-03-16 17:21:34 +00001448 put_packet("OK");
Jon Doron3e2c1262019-05-29 09:41:30 +03001449}
1450
Alex Bennée26a16182021-05-25 09:24:14 +01001451static void handle_thread_alive(GArray *params, void *user_ctx)
Jon Doron44ffded2019-05-29 09:41:31 +03001452{
1453 CPUState *cpu;
1454
Alex Bennée26a16182021-05-25 09:24:14 +01001455 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001456 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001457 return;
1458 }
1459
Alex Bennée26a16182021-05-25 09:24:14 +01001460 if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001461 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001462 return;
1463 }
1464
Alex Bennée26a16182021-05-25 09:24:14 +01001465 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1466 get_param(params, 0)->thread_id.tid);
Jon Doron44ffded2019-05-29 09:41:31 +03001467 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001468 put_packet("E22");
Jon Doron44ffded2019-05-29 09:41:31 +03001469 return;
1470 }
1471
Alex Bennéea346af32020-03-16 17:21:34 +00001472 put_packet("OK");
Jon Doron44ffded2019-05-29 09:41:31 +03001473}
1474
Alex Bennée26a16182021-05-25 09:24:14 +01001475static void handle_continue(GArray *params, void *user_ctx)
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001476{
Alex Bennée26a16182021-05-25 09:24:14 +01001477 if (params->len) {
1478 gdb_set_cpu_pc(get_param(params, 0)->val_ull);
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001479 }
1480
Alex Bennéea346af32020-03-16 17:21:34 +00001481 gdbserver_state.signal = 0;
1482 gdb_continue();
Jon Doron4d6e3fe2019-05-29 09:41:32 +03001483}
1484
Alex Bennée26a16182021-05-25 09:24:14 +01001485static void handle_cont_with_sig(GArray *params, void *user_ctx)
Jon Doronccc47d52019-05-29 09:41:33 +03001486{
1487 unsigned long signal = 0;
1488
1489 /*
1490 * Note: C sig;[addr] is currently unsupported and we simply
1491 * omit the addr parameter
1492 */
Alex Bennée26a16182021-05-25 09:24:14 +01001493 if (params->len) {
1494 signal = get_param(params, 0)->val_ul;
Jon Doronccc47d52019-05-29 09:41:33 +03001495 }
1496
Alex Bennéea346af32020-03-16 17:21:34 +00001497 gdbserver_state.signal = gdb_signal_to_target(signal);
1498 if (gdbserver_state.signal == -1) {
1499 gdbserver_state.signal = 0;
Jon Doronccc47d52019-05-29 09:41:33 +03001500 }
Alex Bennéea346af32020-03-16 17:21:34 +00001501 gdb_continue();
Jon Doronccc47d52019-05-29 09:41:33 +03001502}
1503
Alex Bennée26a16182021-05-25 09:24:14 +01001504static void handle_set_thread(GArray *params, void *user_ctx)
Jon Doron3a9651d2019-05-29 09:41:34 +03001505{
1506 CPUState *cpu;
1507
Alex Bennée26a16182021-05-25 09:24:14 +01001508 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001509 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001510 return;
1511 }
1512
Alex Bennée26a16182021-05-25 09:24:14 +01001513 if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00001514 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001515 return;
1516 }
1517
Alex Bennée26a16182021-05-25 09:24:14 +01001518 if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
Alex Bennéea346af32020-03-16 17:21:34 +00001519 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001520 return;
1521 }
1522
Alex Bennée26a16182021-05-25 09:24:14 +01001523 cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1524 get_param(params, 1)->thread_id.tid);
Jon Doron3a9651d2019-05-29 09:41:34 +03001525 if (!cpu) {
Alex Bennéea346af32020-03-16 17:21:34 +00001526 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001527 return;
1528 }
1529
1530 /*
1531 * Note: This command is deprecated and modern gdb's will be using the
1532 * vCont command instead.
1533 */
Alex Bennée26a16182021-05-25 09:24:14 +01001534 switch (get_param(params, 0)->opcode) {
Jon Doron3a9651d2019-05-29 09:41:34 +03001535 case 'c':
Alex Bennéea346af32020-03-16 17:21:34 +00001536 gdbserver_state.c_cpu = cpu;
1537 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001538 break;
1539 case 'g':
Alex Bennéea346af32020-03-16 17:21:34 +00001540 gdbserver_state.g_cpu = cpu;
1541 put_packet("OK");
Jon Doron3a9651d2019-05-29 09:41:34 +03001542 break;
1543 default:
Alex Bennéea346af32020-03-16 17:21:34 +00001544 put_packet("E22");
Jon Doron3a9651d2019-05-29 09:41:34 +03001545 break;
1546 }
1547}
1548
Alex Bennée26a16182021-05-25 09:24:14 +01001549static void handle_insert_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001550{
1551 int res;
1552
Alex Bennée26a16182021-05-25 09:24:14 +01001553 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001554 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001555 return;
1556 }
1557
Alex Bennéeae7467b2022-09-29 12:42:24 +01001558 res = gdb_breakpoint_insert(gdbserver_state.c_cpu,
1559 get_param(params, 0)->val_ul,
Alex Bennée26a16182021-05-25 09:24:14 +01001560 get_param(params, 1)->val_ull,
1561 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001562 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001563 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001564 return;
1565 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001566 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001567 return;
1568 }
1569
Alex Bennéea346af32020-03-16 17:21:34 +00001570 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001571}
1572
Alex Bennée26a16182021-05-25 09:24:14 +01001573static void handle_remove_bp(GArray *params, void *user_ctx)
Jon Doron77f6ce52019-05-29 09:41:35 +03001574{
1575 int res;
1576
Alex Bennée26a16182021-05-25 09:24:14 +01001577 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001578 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001579 return;
1580 }
1581
Alex Bennéeae7467b2022-09-29 12:42:24 +01001582 res = gdb_breakpoint_remove(gdbserver_state.c_cpu,
1583 get_param(params, 0)->val_ul,
Alex Bennée26a16182021-05-25 09:24:14 +01001584 get_param(params, 1)->val_ull,
1585 get_param(params, 2)->val_ull);
Jon Doron77f6ce52019-05-29 09:41:35 +03001586 if (res >= 0) {
Alex Bennéea346af32020-03-16 17:21:34 +00001587 put_packet("OK");
Jon Doron77f6ce52019-05-29 09:41:35 +03001588 return;
1589 } else if (res == -ENOSYS) {
Alex Bennéea346af32020-03-16 17:21:34 +00001590 put_packet("");
Jon Doron77f6ce52019-05-29 09:41:35 +03001591 return;
1592 }
1593
Alex Bennéea346af32020-03-16 17:21:34 +00001594 put_packet("E22");
Jon Doron77f6ce52019-05-29 09:41:35 +03001595}
1596
Alex Bennée94b2a622019-07-05 14:23:07 +01001597/*
1598 * handle_set/get_reg
1599 *
1600 * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1601 * This works, but can be very slow. Anything new enough to understand
1602 * XML also knows how to use this properly. However to use this we
1603 * need to define a local XML file as well as be talking to a
1604 * reasonably modern gdb. Responding with an empty packet will cause
1605 * the remote gdb to fallback to older methods.
1606 */
1607
Alex Bennée26a16182021-05-25 09:24:14 +01001608static void handle_set_reg(GArray *params, void *user_ctx)
Jon Doron62b33202019-05-29 09:41:36 +03001609{
1610 int reg_size;
1611
1612 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001613 put_packet("");
Jon Doron62b33202019-05-29 09:41:36 +03001614 return;
1615 }
1616
Alex Bennée26a16182021-05-25 09:24:14 +01001617 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001618 put_packet("E22");
Jon Doron62b33202019-05-29 09:41:36 +03001619 return;
1620 }
1621
Alex Bennée26a16182021-05-25 09:24:14 +01001622 reg_size = strlen(get_param(params, 1)->data) / 2;
1623 hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001624 gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
Alex Bennée26a16182021-05-25 09:24:14 +01001625 get_param(params, 0)->val_ull);
Alex Bennéea346af32020-03-16 17:21:34 +00001626 put_packet("OK");
Jon Doron62b33202019-05-29 09:41:36 +03001627}
1628
Alex Bennée26a16182021-05-25 09:24:14 +01001629static void handle_get_reg(GArray *params, void *user_ctx)
Jon Doron5d0e57b2019-05-29 09:41:37 +03001630{
1631 int reg_size;
1632
Jon Doron5d0e57b2019-05-29 09:41:37 +03001633 if (!gdb_has_xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00001634 put_packet("");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001635 return;
1636 }
1637
Alex Bennée26a16182021-05-25 09:24:14 +01001638 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00001639 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001640 return;
1641 }
1642
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001643 reg_size = gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001644 gdbserver_state.mem_buf,
Alex Bennée26a16182021-05-25 09:24:14 +01001645 get_param(params, 0)->val_ull);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001646 if (!reg_size) {
Alex Bennéea346af32020-03-16 17:21:34 +00001647 put_packet("E14");
Jon Doron5d0e57b2019-05-29 09:41:37 +03001648 return;
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001649 } else {
1650 g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
Jon Doron5d0e57b2019-05-29 09:41:37 +03001651 }
1652
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001653 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, reg_size);
Alex Bennée308f9e82020-03-16 17:21:35 +00001654 put_strbuf();
Jon Doron5d0e57b2019-05-29 09:41:37 +03001655}
1656
Alex Bennée26a16182021-05-25 09:24:14 +01001657static void handle_write_mem(GArray *params, void *user_ctx)
Jon Doroncc0ecc72019-05-29 09:41:38 +03001658{
Alex Bennée26a16182021-05-25 09:24:14 +01001659 if (params->len != 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00001660 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001661 return;
1662 }
1663
1664 /* hextomem() reads 2*len bytes */
Alex Bennée26a16182021-05-25 09:24:14 +01001665 if (get_param(params, 1)->val_ull >
1666 strlen(get_param(params, 2)->data) / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001667 put_packet("E22");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001668 return;
1669 }
1670
Alex Bennée26a16182021-05-25 09:24:14 +01001671 hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1672 get_param(params, 1)->val_ull);
1673 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1674 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001675 gdbserver_state.mem_buf->data,
1676 gdbserver_state.mem_buf->len, true)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001677 put_packet("E14");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001678 return;
1679 }
1680
Alex Bennéea346af32020-03-16 17:21:34 +00001681 put_packet("OK");
Jon Doroncc0ecc72019-05-29 09:41:38 +03001682}
1683
Alex Bennée26a16182021-05-25 09:24:14 +01001684static void handle_read_mem(GArray *params, void *user_ctx)
Jon Doronda92e232019-05-29 09:41:39 +03001685{
Alex Bennée26a16182021-05-25 09:24:14 +01001686 if (params->len != 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001687 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001688 return;
1689 }
1690
1691 /* memtohex() doubles the required space */
Alex Bennée26a16182021-05-25 09:24:14 +01001692 if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00001693 put_packet("E22");
Jon Doronda92e232019-05-29 09:41:39 +03001694 return;
1695 }
1696
Alex Bennée26a16182021-05-25 09:24:14 +01001697 g_byte_array_set_size(gdbserver_state.mem_buf,
1698 get_param(params, 1)->val_ull);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001699
Alex Bennée26a16182021-05-25 09:24:14 +01001700 if (target_memory_rw_debug(gdbserver_state.g_cpu,
1701 get_param(params, 0)->val_ull,
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001702 gdbserver_state.mem_buf->data,
1703 gdbserver_state.mem_buf->len, false)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001704 put_packet("E14");
Jon Doronda92e232019-05-29 09:41:39 +03001705 return;
1706 }
1707
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001708 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1709 gdbserver_state.mem_buf->len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001710 put_strbuf();
Jon Doronda92e232019-05-29 09:41:39 +03001711}
1712
Alex Bennée26a16182021-05-25 09:24:14 +01001713static void handle_write_all_regs(GArray *params, void *user_ctx)
Jon Doron287ca122019-05-29 09:41:40 +03001714{
1715 target_ulong addr, len;
1716 uint8_t *registers;
1717 int reg_size;
1718
Alex Bennée26a16182021-05-25 09:24:14 +01001719 if (!params->len) {
Jon Doron287ca122019-05-29 09:41:40 +03001720 return;
1721 }
1722
Alex Bennéea346af32020-03-16 17:21:34 +00001723 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennée26a16182021-05-25 09:24:14 +01001724 len = strlen(get_param(params, 0)->data) / 2;
1725 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001726 registers = gdbserver_state.mem_buf->data;
Alex Bennéea346af32020-03-16 17:21:34 +00001727 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
Jon Doron287ca122019-05-29 09:41:40 +03001728 addr++) {
Alex Bennéea346af32020-03-16 17:21:34 +00001729 reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
Jon Doron287ca122019-05-29 09:41:40 +03001730 len -= reg_size;
1731 registers += reg_size;
1732 }
Alex Bennéea346af32020-03-16 17:21:34 +00001733 put_packet("OK");
Jon Doron287ca122019-05-29 09:41:40 +03001734}
1735
Alex Bennée26a16182021-05-25 09:24:14 +01001736static void handle_read_all_regs(GArray *params, void *user_ctx)
Jon Doron397d1372019-05-29 09:41:41 +03001737{
1738 target_ulong addr, len;
1739
Alex Bennéea346af32020-03-16 17:21:34 +00001740 cpu_synchronize_state(gdbserver_state.g_cpu);
Alex Bennéea010bdb2020-03-16 17:21:41 +00001741 g_byte_array_set_size(gdbserver_state.mem_buf, 0);
Jon Doron397d1372019-05-29 09:41:41 +03001742 len = 0;
Alex Bennéea346af32020-03-16 17:21:34 +00001743 for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001744 len += gdb_read_register(gdbserver_state.g_cpu,
Alex Bennéea010bdb2020-03-16 17:21:41 +00001745 gdbserver_state.mem_buf,
Jon Doron397d1372019-05-29 09:41:41 +03001746 addr);
1747 }
Alex Bennéea010bdb2020-03-16 17:21:41 +00001748 g_assert(len == gdbserver_state.mem_buf->len);
Jon Doron397d1372019-05-29 09:41:41 +03001749
Alex Bennée4a25f1b2020-03-16 17:21:36 +00001750 memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
Alex Bennée308f9e82020-03-16 17:21:35 +00001751 put_strbuf();
Jon Doron397d1372019-05-29 09:41:41 +03001752}
1753
Alex Bennée26a16182021-05-25 09:24:14 +01001754static void handle_file_io(GArray *params, void *user_ctx)
Jon Doron4b20fab2019-05-29 09:41:42 +03001755{
Alex Bennée26a16182021-05-25 09:24:14 +01001756 if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
Richard Henderson64c8c6a2022-04-29 16:21:43 -07001757 uint64_t ret;
1758 int err;
Jon Doron4b20fab2019-05-29 09:41:42 +03001759
Richard Henderson64c8c6a2022-04-29 16:21:43 -07001760 ret = get_param(params, 0)->val_ull;
Alex Bennée26a16182021-05-25 09:24:14 +01001761 if (params->len >= 2) {
Richard Henderson64c8c6a2022-04-29 16:21:43 -07001762 err = get_param(params, 1)->val_ull;
Sandra Loosemorec6ee9522019-08-27 16:33:17 -06001763 } else {
1764 err = 0;
1765 }
Richard Hendersonc805e112022-06-07 12:38:26 -07001766
1767 /* Convert GDB error numbers back to host error numbers. */
1768#define E(X) case GDB_E##X: err = E##X; break
1769 switch (err) {
1770 case 0:
1771 break;
1772 E(PERM);
1773 E(NOENT);
1774 E(INTR);
1775 E(BADF);
1776 E(ACCES);
1777 E(FAULT);
1778 E(BUSY);
1779 E(EXIST);
1780 E(NODEV);
1781 E(NOTDIR);
1782 E(ISDIR);
1783 E(INVAL);
1784 E(NFILE);
1785 E(MFILE);
1786 E(FBIG);
1787 E(NOSPC);
1788 E(SPIPE);
1789 E(ROFS);
1790 E(NAMETOOLONG);
1791 default:
1792 err = EINVAL;
1793 break;
1794 }
1795#undef E
1796
Alex Bennéea346af32020-03-16 17:21:34 +00001797 gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1798 gdbserver_state.current_syscall_cb = NULL;
Jon Doron4b20fab2019-05-29 09:41:42 +03001799 }
1800
Alex Bennée26a16182021-05-25 09:24:14 +01001801 if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
Alex Bennéea346af32020-03-16 17:21:34 +00001802 put_packet("T02");
Jon Doron4b20fab2019-05-29 09:41:42 +03001803 return;
1804 }
1805
Alex Bennéea346af32020-03-16 17:21:34 +00001806 gdb_continue();
Jon Doron4b20fab2019-05-29 09:41:42 +03001807}
1808
Alex Bennée26a16182021-05-25 09:24:14 +01001809static void handle_step(GArray *params, void *user_ctx)
Jon Doron933f80d2019-05-29 09:41:43 +03001810{
Alex Bennée26a16182021-05-25 09:24:14 +01001811 if (params->len) {
1812 gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
Jon Doron933f80d2019-05-29 09:41:43 +03001813 }
1814
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001815 cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
Alex Bennéea346af32020-03-16 17:21:34 +00001816 gdb_continue();
Jon Doron933f80d2019-05-29 09:41:43 +03001817}
1818
Alex Bennée26a16182021-05-25 09:24:14 +01001819static void handle_backward(GArray *params, void *user_ctx)
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001820{
Alex Bennéeed12f5b2021-05-20 18:43:02 +01001821 if (!stub_can_reverse()) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001822 put_packet("E22");
1823 }
Alex Bennée26a16182021-05-25 09:24:14 +01001824 if (params->len == 1) {
1825 switch (get_param(params, 0)->opcode) {
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001826 case 's':
1827 if (replay_reverse_step()) {
1828 gdb_continue();
1829 } else {
1830 put_packet("E14");
1831 }
1832 return;
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03001833 case 'c':
1834 if (replay_reverse_continue()) {
1835 gdb_continue();
1836 } else {
1837 put_packet("E14");
1838 }
1839 return;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03001840 }
1841 }
1842
1843 /* Default invalid command */
1844 put_packet("");
1845}
1846
Alex Bennée26a16182021-05-25 09:24:14 +01001847static void handle_v_cont_query(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001848{
Alex Bennéea346af32020-03-16 17:21:34 +00001849 put_packet("vCont;c;C;s;S");
Jon Doron8536ec02019-05-29 09:41:44 +03001850}
1851
Alex Bennée26a16182021-05-25 09:24:14 +01001852static void handle_v_cont(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001853{
1854 int res;
1855
Alex Bennée26a16182021-05-25 09:24:14 +01001856 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001857 return;
1858 }
1859
Alex Bennée26a16182021-05-25 09:24:14 +01001860 res = gdb_handle_vcont(get_param(params, 0)->data);
Jon Doron8536ec02019-05-29 09:41:44 +03001861 if ((res == -EINVAL) || (res == -ERANGE)) {
Alex Bennéea346af32020-03-16 17:21:34 +00001862 put_packet("E22");
Jon Doron8536ec02019-05-29 09:41:44 +03001863 } else if (res) {
Alex Bennéea346af32020-03-16 17:21:34 +00001864 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03001865 }
1866}
1867
Alex Bennée26a16182021-05-25 09:24:14 +01001868static void handle_v_attach(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001869{
1870 GDBProcess *process;
1871 CPUState *cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001872
Alex Bennée308f9e82020-03-16 17:21:35 +00001873 g_string_assign(gdbserver_state.str_buf, "E22");
Alex Bennée26a16182021-05-25 09:24:14 +01001874 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001875 goto cleanup;
1876 }
1877
Alex Bennée26a16182021-05-25 09:24:14 +01001878 process = gdb_get_process(get_param(params, 0)->val_ul);
Jon Doron8536ec02019-05-29 09:41:44 +03001879 if (!process) {
1880 goto cleanup;
1881 }
1882
Alex Bennéea346af32020-03-16 17:21:34 +00001883 cpu = get_first_cpu_in_process(process);
Jon Doron8536ec02019-05-29 09:41:44 +03001884 if (!cpu) {
1885 goto cleanup;
1886 }
1887
1888 process->attached = true;
Alex Bennéea346af32020-03-16 17:21:34 +00001889 gdbserver_state.g_cpu = cpu;
1890 gdbserver_state.c_cpu = cpu;
Jon Doron8536ec02019-05-29 09:41:44 +03001891
Alex Bennée308f9e82020-03-16 17:21:35 +00001892 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
1893 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
1894 g_string_append_c(gdbserver_state.str_buf, ';');
Jon Doron8536ec02019-05-29 09:41:44 +03001895cleanup:
Alex Bennée308f9e82020-03-16 17:21:35 +00001896 put_strbuf();
Jon Doron8536ec02019-05-29 09:41:44 +03001897}
1898
Alex Bennée26a16182021-05-25 09:24:14 +01001899static void handle_v_kill(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001900{
1901 /* Kill the target */
Alex Bennéea346af32020-03-16 17:21:34 +00001902 put_packet("OK");
Jon Doron8536ec02019-05-29 09:41:44 +03001903 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00001904 gdb_exit(0);
Jon Doron8536ec02019-05-29 09:41:44 +03001905 exit(0);
1906}
1907
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01001908static const GdbCmdParseEntry gdb_v_commands_table[] = {
Jon Doron8536ec02019-05-29 09:41:44 +03001909 /* Order is important if has same prefix */
1910 {
1911 .handler = handle_v_cont_query,
1912 .cmd = "Cont?",
1913 .cmd_startswith = 1
1914 },
1915 {
1916 .handler = handle_v_cont,
1917 .cmd = "Cont",
1918 .cmd_startswith = 1,
1919 .schema = "s0"
1920 },
1921 {
1922 .handler = handle_v_attach,
1923 .cmd = "Attach;",
1924 .cmd_startswith = 1,
1925 .schema = "l0"
1926 },
1927 {
1928 .handler = handle_v_kill,
1929 .cmd = "Kill;",
1930 .cmd_startswith = 1
1931 },
1932};
1933
Alex Bennée26a16182021-05-25 09:24:14 +01001934static void handle_v_commands(GArray *params, void *user_ctx)
Jon Doron8536ec02019-05-29 09:41:44 +03001935{
Alex Bennée26a16182021-05-25 09:24:14 +01001936 if (!params->len) {
Jon Doron8536ec02019-05-29 09:41:44 +03001937 return;
1938 }
1939
Alex Bennée26a16182021-05-25 09:24:14 +01001940 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron8536ec02019-05-29 09:41:44 +03001941 gdb_v_commands_table,
1942 ARRAY_SIZE(gdb_v_commands_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00001943 put_packet("");
Jon Doron8536ec02019-05-29 09:41:44 +03001944 }
1945}
1946
Alex Bennée26a16182021-05-25 09:24:14 +01001947static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03001948{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001949 g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
1950
1951 if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
1952 g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
1953 SSTEP_NOIRQ);
1954 }
1955
1956 if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
1957 g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
1958 SSTEP_NOTIMER);
1959 }
1960
Alex Bennée308f9e82020-03-16 17:21:35 +00001961 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03001962}
1963
Alex Bennée26a16182021-05-25 09:24:14 +01001964static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03001965{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001966 int new_sstep_flags;
1967
Alex Bennée26a16182021-05-25 09:24:14 +01001968 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03001969 return;
1970 }
1971
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001972 new_sstep_flags = get_param(params, 0)->val_ul;
1973
1974 if (new_sstep_flags & ~gdbserver_state.supported_sstep_flags) {
1975 put_packet("E22");
1976 return;
1977 }
1978
1979 gdbserver_state.sstep_flags = new_sstep_flags;
Alex Bennéea346af32020-03-16 17:21:34 +00001980 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03001981}
1982
Alex Bennée26a16182021-05-25 09:24:14 +01001983static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03001984{
Maxim Levitskyecd39d62021-11-11 12:06:02 +01001985 g_string_printf(gdbserver_state.str_buf, "0x%x",
1986 gdbserver_state.sstep_flags);
Alex Bennée308f9e82020-03-16 17:21:35 +00001987 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03001988}
1989
Alex Bennée26a16182021-05-25 09:24:14 +01001990static void handle_query_curr_tid(GArray *params, void *user_ctx)
bellardb4608c02003-06-27 17:34:32 +00001991{
Andreas Färber2e0f2cf2013-06-27 19:19:39 +02001992 CPUState *cpu;
Luc Michelc145eea2019-01-07 15:23:46 +00001993 GDBProcess *process;
Jon Doron2704efa2019-05-29 09:41:45 +03001994
1995 /*
1996 * "Current thread" remains vague in the spec, so always return
1997 * the first thread of the current process (gdb returns the
1998 * first thread).
1999 */
Alex Bennéea346af32020-03-16 17:21:34 +00002000 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2001 cpu = get_first_cpu_in_process(process);
Alex Bennée308f9e82020-03-16 17:21:35 +00002002 g_string_assign(gdbserver_state.str_buf, "QC");
2003 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2004 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002005}
2006
Alex Bennée26a16182021-05-25 09:24:14 +01002007static void handle_query_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002008{
Alex Bennéea346af32020-03-16 17:21:34 +00002009 if (!gdbserver_state.query_cpu) {
2010 put_packet("l");
Jon Doron2704efa2019-05-29 09:41:45 +03002011 return;
2012 }
2013
Alex Bennée308f9e82020-03-16 17:21:35 +00002014 g_string_assign(gdbserver_state.str_buf, "m");
2015 gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
2016 put_strbuf();
Alex Bennéea346af32020-03-16 17:21:34 +00002017 gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002018}
2019
Alex Bennée26a16182021-05-25 09:24:14 +01002020static void handle_query_first_threads(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002021{
Alex Bennéea346af32020-03-16 17:21:34 +00002022 gdbserver_state.query_cpu = gdb_first_attached_cpu();
Alex Bennée26a16182021-05-25 09:24:14 +01002023 handle_query_threads(params, user_ctx);
Jon Doron2704efa2019-05-29 09:41:45 +03002024}
2025
Alex Bennée26a16182021-05-25 09:24:14 +01002026static void handle_query_thread_extra(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002027{
Alex Bennée308f9e82020-03-16 17:21:35 +00002028 g_autoptr(GString) rs = g_string_new(NULL);
Jon Doron2704efa2019-05-29 09:41:45 +03002029 CPUState *cpu;
Jon Doron2704efa2019-05-29 09:41:45 +03002030
Alex Bennée26a16182021-05-25 09:24:14 +01002031 if (!params->len ||
2032 get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
Alex Bennéea346af32020-03-16 17:21:34 +00002033 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002034 return;
2035 }
2036
Alex Bennée26a16182021-05-25 09:24:14 +01002037 cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
2038 get_param(params, 0)->thread_id.tid);
Jon Doron2704efa2019-05-29 09:41:45 +03002039 if (!cpu) {
2040 return;
2041 }
2042
2043 cpu_synchronize_state(cpu);
2044
Alex Bennéea346af32020-03-16 17:21:34 +00002045 if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
Jon Doron2704efa2019-05-29 09:41:45 +03002046 /* Print the CPU model and name in multiprocess mode */
2047 ObjectClass *oc = object_get_class(OBJECT(cpu));
2048 const char *cpu_model = object_class_get_name(oc);
Markus Armbruster7a309cc2020-07-14 18:02:00 +02002049 const char *cpu_name =
Denis Plotnikov076b2fa2020-04-03 20:11:44 +01002050 object_get_canonical_path_component(OBJECT(cpu));
Alex Bennée308f9e82020-03-16 17:21:35 +00002051 g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
2052 cpu->halted ? "halted " : "running");
Jon Doron2704efa2019-05-29 09:41:45 +03002053 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002054 g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
Jon Doron2704efa2019-05-29 09:41:45 +03002055 cpu->halted ? "halted " : "running");
2056 }
Alex Bennée308f9e82020-03-16 17:21:35 +00002057 trace_gdbstub_op_extra_info(rs->str);
2058 memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
2059 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002060}
2061
2062#ifdef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002063static void handle_query_offsets(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002064{
2065 TaskState *ts;
2066
Alex Bennéea346af32020-03-16 17:21:34 +00002067 ts = gdbserver_state.c_cpu->opaque;
Alex Bennée308f9e82020-03-16 17:21:35 +00002068 g_string_printf(gdbserver_state.str_buf,
2069 "Text=" TARGET_ABI_FMT_lx
2070 ";Data=" TARGET_ABI_FMT_lx
2071 ";Bss=" TARGET_ABI_FMT_lx,
2072 ts->info->code_offset,
2073 ts->info->data_offset,
2074 ts->info->data_offset);
2075 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002076}
2077#else
Alex Bennée26a16182021-05-25 09:24:14 +01002078static void handle_query_rcmd(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002079{
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002080 const guint8 zero = 0;
Jon Doron2704efa2019-05-29 09:41:45 +03002081 int len;
2082
Alex Bennée26a16182021-05-25 09:24:14 +01002083 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002084 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002085 return;
2086 }
2087
Alex Bennée26a16182021-05-25 09:24:14 +01002088 len = strlen(get_param(params, 0)->data);
Jon Doron2704efa2019-05-29 09:41:45 +03002089 if (len % 2) {
Alex Bennéea346af32020-03-16 17:21:34 +00002090 put_packet("E01");
Jon Doron2704efa2019-05-29 09:41:45 +03002091 return;
2092 }
2093
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002094 g_assert(gdbserver_state.mem_buf->len == 0);
Jon Doron2704efa2019-05-29 09:41:45 +03002095 len = len / 2;
Alex Bennée26a16182021-05-25 09:24:14 +01002096 hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
Alex Bennée4a25f1b2020-03-16 17:21:36 +00002097 g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
2098 qemu_chr_be_write(gdbserver_state.mon_chr, gdbserver_state.mem_buf->data,
2099 gdbserver_state.mem_buf->len);
Alex Bennéea346af32020-03-16 17:21:34 +00002100 put_packet("OK");
Jon Doron2704efa2019-05-29 09:41:45 +03002101}
2102#endif
2103
Alex Bennée26a16182021-05-25 09:24:14 +01002104static void handle_query_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002105{
Andreas Färber5b24c642013-07-07 15:08:22 +02002106 CPUClass *cc;
Jon Doron2704efa2019-05-29 09:41:45 +03002107
Alex Bennée308f9e82020-03-16 17:21:35 +00002108 g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
Jon Doron2704efa2019-05-29 09:41:45 +03002109 cc = CPU_GET_CLASS(first_cpu);
2110 if (cc->gdb_core_xml_file) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002111 g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
Jon Doron2704efa2019-05-29 09:41:45 +03002112 }
2113
Alex Bennéeed12f5b2021-05-20 18:43:02 +01002114 if (stub_can_reverse()) {
Pavel Dovgalyukcda38252020-10-03 20:13:49 +03002115 g_string_append(gdbserver_state.str_buf,
2116 ";ReverseStep+;ReverseContinue+");
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002117 }
2118
Lirong Yuan51c623b2021-01-08 22:42:42 +00002119#ifdef CONFIG_USER_ONLY
2120 if (gdbserver_state.c_cpu->opaque) {
2121 g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
2122 }
2123#endif
2124
Alex Bennée26a16182021-05-25 09:24:14 +01002125 if (params->len &&
2126 strstr(get_param(params, 0)->data, "multiprocess+")) {
Alex Bennéea346af32020-03-16 17:21:34 +00002127 gdbserver_state.multiprocess = true;
Jon Doron2704efa2019-05-29 09:41:45 +03002128 }
2129
Changbin Du3bc26092020-03-16 17:21:55 +00002130 g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
Alex Bennée308f9e82020-03-16 17:21:35 +00002131 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002132}
2133
Alex Bennée26a16182021-05-25 09:24:14 +01002134static void handle_query_xfer_features(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002135{
2136 GDBProcess *process;
2137 CPUClass *cc;
2138 unsigned long len, total_len, addr;
2139 const char *xml;
bellardb4608c02003-06-27 17:34:32 +00002140 const char *p;
Jon Doron2704efa2019-05-29 09:41:45 +03002141
Alex Bennée26a16182021-05-25 09:24:14 +01002142 if (params->len < 3) {
Alex Bennéea346af32020-03-16 17:21:34 +00002143 put_packet("E22");
Jon Doron2704efa2019-05-29 09:41:45 +03002144 return;
2145 }
2146
Alex Bennéea346af32020-03-16 17:21:34 +00002147 process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2148 cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
Jon Doron2704efa2019-05-29 09:41:45 +03002149 if (!cc->gdb_core_xml_file) {
Alex Bennéea346af32020-03-16 17:21:34 +00002150 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002151 return;
2152 }
2153
2154 gdb_has_xml = true;
Alex Bennée26a16182021-05-25 09:24:14 +01002155 p = get_param(params, 0)->data;
Alex Bennéea346af32020-03-16 17:21:34 +00002156 xml = get_feature_xml(p, &p, process);
Jon Doron2704efa2019-05-29 09:41:45 +03002157 if (!xml) {
Alex Bennéea346af32020-03-16 17:21:34 +00002158 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002159 return;
2160 }
2161
Alex Bennée26a16182021-05-25 09:24:14 +01002162 addr = get_param(params, 1)->val_ul;
2163 len = get_param(params, 2)->val_ul;
Jon Doron2704efa2019-05-29 09:41:45 +03002164 total_len = strlen(xml);
2165 if (addr > total_len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002166 put_packet("E00");
Jon Doron2704efa2019-05-29 09:41:45 +03002167 return;
2168 }
2169
2170 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2171 len = (MAX_PACKET_LENGTH - 5) / 2;
2172 }
2173
2174 if (len < total_len - addr) {
Alex Bennée308f9e82020-03-16 17:21:35 +00002175 g_string_assign(gdbserver_state.str_buf, "m");
2176 memtox(gdbserver_state.str_buf, xml + addr, len);
Jon Doron2704efa2019-05-29 09:41:45 +03002177 } else {
Alex Bennée308f9e82020-03-16 17:21:35 +00002178 g_string_assign(gdbserver_state.str_buf, "l");
2179 memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
Jon Doron2704efa2019-05-29 09:41:45 +03002180 }
2181
Alex Bennée308f9e82020-03-16 17:21:35 +00002182 put_packet_binary(gdbserver_state.str_buf->str,
2183 gdbserver_state.str_buf->len, true);
Jon Doron2704efa2019-05-29 09:41:45 +03002184}
2185
Lirong Yuan51c623b2021-01-08 22:42:42 +00002186#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
Alex Bennée26a16182021-05-25 09:24:14 +01002187static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
Lirong Yuan51c623b2021-01-08 22:42:42 +00002188{
2189 TaskState *ts;
2190 unsigned long offset, len, saved_auxv, auxv_len;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002191
Alex Bennée26a16182021-05-25 09:24:14 +01002192 if (params->len < 2) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002193 put_packet("E22");
2194 return;
2195 }
2196
Alex Bennée26a16182021-05-25 09:24:14 +01002197 offset = get_param(params, 0)->val_ul;
2198 len = get_param(params, 1)->val_ul;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002199 ts = gdbserver_state.c_cpu->opaque;
2200 saved_auxv = ts->info->saved_auxv;
2201 auxv_len = ts->info->auxv_len;
Richard Henderson6e3dd752021-02-02 13:39:55 +00002202
2203 if (offset >= auxv_len) {
Lirong Yuan51c623b2021-01-08 22:42:42 +00002204 put_packet("E00");
2205 return;
2206 }
2207
2208 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2209 len = (MAX_PACKET_LENGTH - 5) / 2;
2210 }
2211
2212 if (len < auxv_len - offset) {
2213 g_string_assign(gdbserver_state.str_buf, "m");
Lirong Yuan51c623b2021-01-08 22:42:42 +00002214 } else {
2215 g_string_assign(gdbserver_state.str_buf, "l");
Richard Henderson6e3dd752021-02-02 13:39:55 +00002216 len = auxv_len - offset;
Lirong Yuan51c623b2021-01-08 22:42:42 +00002217 }
2218
Richard Henderson6e3dd752021-02-02 13:39:55 +00002219 g_byte_array_set_size(gdbserver_state.mem_buf, len);
2220 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2221 gdbserver_state.mem_buf->data, len, false)) {
2222 put_packet("E14");
2223 return;
2224 }
2225
2226 memtox(gdbserver_state.str_buf,
2227 (const char *)gdbserver_state.mem_buf->data, len);
Lirong Yuan51c623b2021-01-08 22:42:42 +00002228 put_packet_binary(gdbserver_state.str_buf->str,
2229 gdbserver_state.str_buf->len, true);
2230}
2231#endif
2232
Alex Bennée26a16182021-05-25 09:24:14 +01002233static void handle_query_attached(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002234{
Alex Bennéea346af32020-03-16 17:21:34 +00002235 put_packet(GDB_ATTACHED);
Jon Doron2704efa2019-05-29 09:41:45 +03002236}
2237
Alex Bennée26a16182021-05-25 09:24:14 +01002238static void handle_query_qemu_supported(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002239{
Alex Bennée308f9e82020-03-16 17:21:35 +00002240 g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
Jon Doronab4752e2019-05-29 09:41:48 +03002241#ifndef CONFIG_USER_ONLY
Alex Bennée308f9e82020-03-16 17:21:35 +00002242 g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
Jon Doronab4752e2019-05-29 09:41:48 +03002243#endif
Alex Bennée308f9e82020-03-16 17:21:35 +00002244 put_strbuf();
Jon Doron2704efa2019-05-29 09:41:45 +03002245}
2246
Jon Doronab4752e2019-05-29 09:41:48 +03002247#ifndef CONFIG_USER_ONLY
Alex Bennée26a16182021-05-25 09:24:14 +01002248static void handle_query_qemu_phy_mem_mode(GArray *params,
Jon Doronab4752e2019-05-29 09:41:48 +03002249 void *user_ctx)
2250{
Alex Bennée308f9e82020-03-16 17:21:35 +00002251 g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
2252 put_strbuf();
Jon Doronab4752e2019-05-29 09:41:48 +03002253}
2254
Alex Bennée26a16182021-05-25 09:24:14 +01002255static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
Jon Doronab4752e2019-05-29 09:41:48 +03002256{
Alex Bennée26a16182021-05-25 09:24:14 +01002257 if (!params->len) {
Alex Bennéea346af32020-03-16 17:21:34 +00002258 put_packet("E22");
Jon Doronab4752e2019-05-29 09:41:48 +03002259 return;
2260 }
2261
Alex Bennée26a16182021-05-25 09:24:14 +01002262 if (!get_param(params, 0)->val_ul) {
Jon Doronab4752e2019-05-29 09:41:48 +03002263 phy_memory_mode = 0;
2264 } else {
2265 phy_memory_mode = 1;
2266 }
Alex Bennéea346af32020-03-16 17:21:34 +00002267 put_packet("OK");
Jon Doronab4752e2019-05-29 09:41:48 +03002268}
2269#endif
2270
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002271static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002272 /* Order is important if has same prefix */
2273 {
2274 .handler = handle_query_qemu_sstepbits,
2275 .cmd = "qemu.sstepbits",
2276 },
2277 {
2278 .handler = handle_query_qemu_sstep,
2279 .cmd = "qemu.sstep",
2280 },
2281 {
2282 .handler = handle_set_qemu_sstep,
2283 .cmd = "qemu.sstep=",
2284 .cmd_startswith = 1,
2285 .schema = "l0"
2286 },
2287};
2288
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002289static const GdbCmdParseEntry gdb_gen_query_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002290 {
2291 .handler = handle_query_curr_tid,
2292 .cmd = "C",
2293 },
2294 {
2295 .handler = handle_query_threads,
2296 .cmd = "sThreadInfo",
2297 },
2298 {
2299 .handler = handle_query_first_threads,
2300 .cmd = "fThreadInfo",
2301 },
2302 {
2303 .handler = handle_query_thread_extra,
2304 .cmd = "ThreadExtraInfo,",
2305 .cmd_startswith = 1,
2306 .schema = "t0"
2307 },
2308#ifdef CONFIG_USER_ONLY
2309 {
2310 .handler = handle_query_offsets,
2311 .cmd = "Offsets",
2312 },
2313#else
2314 {
2315 .handler = handle_query_rcmd,
2316 .cmd = "Rcmd,",
2317 .cmd_startswith = 1,
2318 .schema = "s0"
2319 },
2320#endif
2321 {
2322 .handler = handle_query_supported,
2323 .cmd = "Supported:",
2324 .cmd_startswith = 1,
2325 .schema = "s0"
2326 },
2327 {
2328 .handler = handle_query_supported,
2329 .cmd = "Supported",
2330 .schema = "s0"
2331 },
2332 {
2333 .handler = handle_query_xfer_features,
2334 .cmd = "Xfer:features:read:",
2335 .cmd_startswith = 1,
2336 .schema = "s:l,l0"
2337 },
Lirong Yuan51c623b2021-01-08 22:42:42 +00002338#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2339 {
2340 .handler = handle_query_xfer_auxv,
2341 .cmd = "Xfer:auxv:read::",
2342 .cmd_startswith = 1,
2343 .schema = "l,l0"
2344 },
2345#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002346 {
2347 .handler = handle_query_attached,
2348 .cmd = "Attached:",
2349 .cmd_startswith = 1
2350 },
2351 {
2352 .handler = handle_query_attached,
2353 .cmd = "Attached",
2354 },
2355 {
2356 .handler = handle_query_qemu_supported,
2357 .cmd = "qemu.Supported",
2358 },
Jon Doronab4752e2019-05-29 09:41:48 +03002359#ifndef CONFIG_USER_ONLY
2360 {
2361 .handler = handle_query_qemu_phy_mem_mode,
2362 .cmd = "qemu.PhyMemMode",
2363 },
2364#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002365};
2366
Philippe Mathieu-Daudé305bea02021-05-20 18:42:59 +01002367static const GdbCmdParseEntry gdb_gen_set_table[] = {
Jon Doron2704efa2019-05-29 09:41:45 +03002368 /* Order is important if has same prefix */
2369 {
2370 .handler = handle_set_qemu_sstep,
2371 .cmd = "qemu.sstep:",
2372 .cmd_startswith = 1,
2373 .schema = "l0"
2374 },
Jon Doronab4752e2019-05-29 09:41:48 +03002375#ifndef CONFIG_USER_ONLY
2376 {
2377 .handler = handle_set_qemu_phy_mem_mode,
2378 .cmd = "qemu.PhyMemMode:",
2379 .cmd_startswith = 1,
2380 .schema = "l0"
2381 },
2382#endif
Jon Doron2704efa2019-05-29 09:41:45 +03002383};
2384
Alex Bennée26a16182021-05-25 09:24:14 +01002385static void handle_gen_query(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002386{
Alex Bennée26a16182021-05-25 09:24:14 +01002387 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002388 return;
2389 }
2390
Alex Bennée26a16182021-05-25 09:24:14 +01002391 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002392 gdb_gen_query_set_common_table,
2393 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2394 return;
2395 }
2396
Alex Bennée26a16182021-05-25 09:24:14 +01002397 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002398 gdb_gen_query_table,
2399 ARRAY_SIZE(gdb_gen_query_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002400 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002401 }
2402}
2403
Alex Bennée26a16182021-05-25 09:24:14 +01002404static void handle_gen_set(GArray *params, void *user_ctx)
Jon Doron2704efa2019-05-29 09:41:45 +03002405{
Alex Bennée26a16182021-05-25 09:24:14 +01002406 if (!params->len) {
Jon Doron2704efa2019-05-29 09:41:45 +03002407 return;
2408 }
2409
Alex Bennée26a16182021-05-25 09:24:14 +01002410 if (!process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002411 gdb_gen_query_set_common_table,
2412 ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2413 return;
2414 }
2415
Alex Bennée26a16182021-05-25 09:24:14 +01002416 if (process_string_cmd(NULL, get_param(params, 0)->data,
Jon Doron2704efa2019-05-29 09:41:45 +03002417 gdb_gen_set_table,
2418 ARRAY_SIZE(gdb_gen_set_table))) {
Alex Bennéea346af32020-03-16 17:21:34 +00002419 put_packet("");
Jon Doron2704efa2019-05-29 09:41:45 +03002420 }
2421}
2422
Alex Bennée26a16182021-05-25 09:24:14 +01002423static void handle_target_halt(GArray *params, void *user_ctx)
Jon Doron7009d572019-05-29 09:41:46 +03002424{
Alex Bennée308f9e82020-03-16 17:21:35 +00002425 g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2426 gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2427 g_string_append_c(gdbserver_state.str_buf, ';');
2428 put_strbuf();
Jon Doron7009d572019-05-29 09:41:46 +03002429 /*
2430 * Remove all the breakpoints when this query is issued,
2431 * because gdb is doing an initial connect and the state
2432 * should be cleaned up.
2433 */
Alex Bennéeae7467b2022-09-29 12:42:24 +01002434 gdb_breakpoint_remove_all(gdbserver_state.c_cpu);
Jon Doron7009d572019-05-29 09:41:46 +03002435}
2436
Alex Bennéea346af32020-03-16 17:21:34 +00002437static int gdb_handle_packet(const char *line_buf)
Jon Doron2704efa2019-05-29 09:41:45 +03002438{
Jon Doron3e2c1262019-05-29 09:41:30 +03002439 const GdbCmdParseEntry *cmd_parser = NULL;
ths3b46e622007-09-17 08:09:54 +00002440
Doug Gale5c9522b2017-12-02 20:30:37 -05002441 trace_gdbstub_io_command(line_buf);
Alex Bennée118e2262017-07-12 11:52:13 +01002442
Jon Doron3f1cbac2019-05-29 09:41:47 +03002443 switch (line_buf[0]) {
Luc Michel53fd6552019-01-07 15:23:46 +00002444 case '!':
Alex Bennéea346af32020-03-16 17:21:34 +00002445 put_packet("OK");
Luc Michel53fd6552019-01-07 15:23:46 +00002446 break;
bellard858693c2004-03-31 18:52:07 +00002447 case '?':
Jon Doron7009d572019-05-29 09:41:46 +03002448 {
2449 static const GdbCmdParseEntry target_halted_cmd_desc = {
2450 .handler = handle_target_halt,
2451 .cmd = "?",
2452 .cmd_startswith = 1
2453 };
2454 cmd_parser = &target_halted_cmd_desc;
2455 }
bellard858693c2004-03-31 18:52:07 +00002456 break;
2457 case 'c':
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002458 {
2459 static const GdbCmdParseEntry continue_cmd_desc = {
2460 .handler = handle_continue,
2461 .cmd = "c",
2462 .cmd_startswith = 1,
2463 .schema = "L0"
2464 };
2465 cmd_parser = &continue_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002466 }
Jon Doron4d6e3fe2019-05-29 09:41:32 +03002467 break;
edgar_igl1f487ee2008-05-17 22:20:53 +00002468 case 'C':
Jon Doronccc47d52019-05-29 09:41:33 +03002469 {
2470 static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2471 .handler = handle_cont_with_sig,
2472 .cmd = "C",
2473 .cmd_startswith = 1,
2474 .schema = "l0"
2475 };
2476 cmd_parser = &cont_with_sig_cmd_desc;
2477 }
2478 break;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002479 case 'v':
Jon Doron8536ec02019-05-29 09:41:44 +03002480 {
2481 static const GdbCmdParseEntry v_cmd_desc = {
2482 .handler = handle_v_commands,
2483 .cmd = "v",
2484 .cmd_startswith = 1,
2485 .schema = "s0"
2486 };
2487 cmd_parser = &v_cmd_desc;
Jan Kiszkadd32aa12009-06-27 09:53:51 +02002488 }
Jon Doron8536ec02019-05-29 09:41:44 +03002489 break;
edgar_igl7d03f822008-05-17 18:58:29 +00002490 case 'k':
2491 /* Kill the target */
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002492 error_report("QEMU: Terminated via GDBstub");
Alex Bennéeb9e10c62021-01-08 22:42:45 +00002493 gdb_exit(0);
edgar_igl7d03f822008-05-17 18:58:29 +00002494 exit(0);
2495 case 'D':
Jon Doron3e2c1262019-05-29 09:41:30 +03002496 {
2497 static const GdbCmdParseEntry detach_cmd_desc = {
2498 .handler = handle_detach,
2499 .cmd = "D",
2500 .cmd_startswith = 1,
2501 .schema = "?.l0"
2502 };
2503 cmd_parser = &detach_cmd_desc;
Luc Michel546f3c62019-01-07 15:23:46 +00002504 }
edgar_igl7d03f822008-05-17 18:58:29 +00002505 break;
bellard858693c2004-03-31 18:52:07 +00002506 case 's':
Jon Doron933f80d2019-05-29 09:41:43 +03002507 {
2508 static const GdbCmdParseEntry step_cmd_desc = {
2509 .handler = handle_step,
2510 .cmd = "s",
2511 .cmd_startswith = 1,
2512 .schema = "L0"
2513 };
2514 cmd_parser = &step_cmd_desc;
bellard858693c2004-03-31 18:52:07 +00002515 }
Jon Doron933f80d2019-05-29 09:41:43 +03002516 break;
Pavel Dovgalyukfda84582020-10-03 20:13:43 +03002517 case 'b':
2518 {
2519 static const GdbCmdParseEntry backward_cmd_desc = {
2520 .handler = handle_backward,
2521 .cmd = "b",
2522 .cmd_startswith = 1,
2523 .schema = "o0"
2524 };
2525 cmd_parser = &backward_cmd_desc;
2526 }
2527 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002528 case 'F':
2529 {
Jon Doron4b20fab2019-05-29 09:41:42 +03002530 static const GdbCmdParseEntry file_io_cmd_desc = {
2531 .handler = handle_file_io,
2532 .cmd = "F",
2533 .cmd_startswith = 1,
2534 .schema = "L,L,o0"
2535 };
2536 cmd_parser = &file_io_cmd_desc;
pbrooka2d1eba2007-01-28 03:10:55 +00002537 }
2538 break;
bellard858693c2004-03-31 18:52:07 +00002539 case 'g':
Jon Doron397d1372019-05-29 09:41:41 +03002540 {
2541 static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2542 .handler = handle_read_all_regs,
2543 .cmd = "g",
2544 .cmd_startswith = 1
2545 };
2546 cmd_parser = &read_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002547 }
bellard858693c2004-03-31 18:52:07 +00002548 break;
2549 case 'G':
Jon Doron287ca122019-05-29 09:41:40 +03002550 {
2551 static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2552 .handler = handle_write_all_regs,
2553 .cmd = "G",
2554 .cmd_startswith = 1,
2555 .schema = "s0"
2556 };
2557 cmd_parser = &write_all_regs_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002558 }
bellard858693c2004-03-31 18:52:07 +00002559 break;
2560 case 'm':
Jon Doronda92e232019-05-29 09:41:39 +03002561 {
2562 static const GdbCmdParseEntry read_mem_cmd_desc = {
2563 .handler = handle_read_mem,
2564 .cmd = "m",
2565 .cmd_startswith = 1,
2566 .schema = "L,L0"
2567 };
2568 cmd_parser = &read_mem_cmd_desc;
bellard6f970bd2005-12-05 19:55:19 +00002569 }
bellard858693c2004-03-31 18:52:07 +00002570 break;
2571 case 'M':
Jon Doroncc0ecc72019-05-29 09:41:38 +03002572 {
2573 static const GdbCmdParseEntry write_mem_cmd_desc = {
2574 .handler = handle_write_mem,
2575 .cmd = "M",
2576 .cmd_startswith = 1,
2577 .schema = "L,L:s0"
2578 };
2579 cmd_parser = &write_mem_cmd_desc;
Fabien Chouteau44520db2011-09-08 12:48:16 +02002580 }
bellard858693c2004-03-31 18:52:07 +00002581 break;
pbrook56aebc82008-10-11 17:55:29 +00002582 case 'p':
Jon Doron5d0e57b2019-05-29 09:41:37 +03002583 {
2584 static const GdbCmdParseEntry get_reg_cmd_desc = {
2585 .handler = handle_get_reg,
2586 .cmd = "p",
2587 .cmd_startswith = 1,
2588 .schema = "L0"
2589 };
2590 cmd_parser = &get_reg_cmd_desc;
pbrook56aebc82008-10-11 17:55:29 +00002591 }
2592 break;
2593 case 'P':
Jon Doron62b33202019-05-29 09:41:36 +03002594 {
2595 static const GdbCmdParseEntry set_reg_cmd_desc = {
2596 .handler = handle_set_reg,
2597 .cmd = "P",
2598 .cmd_startswith = 1,
2599 .schema = "L?s0"
2600 };
2601 cmd_parser = &set_reg_cmd_desc;
2602 }
pbrook56aebc82008-10-11 17:55:29 +00002603 break;
bellard858693c2004-03-31 18:52:07 +00002604 case 'Z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002605 {
2606 static const GdbCmdParseEntry insert_bp_cmd_desc = {
2607 .handler = handle_insert_bp,
2608 .cmd = "Z",
2609 .cmd_startswith = 1,
2610 .schema = "l?L?L0"
2611 };
2612 cmd_parser = &insert_bp_cmd_desc;
2613 }
2614 break;
bellard858693c2004-03-31 18:52:07 +00002615 case 'z':
Jon Doron77f6ce52019-05-29 09:41:35 +03002616 {
2617 static const GdbCmdParseEntry remove_bp_cmd_desc = {
2618 .handler = handle_remove_bp,
2619 .cmd = "z",
2620 .cmd_startswith = 1,
2621 .schema = "l?L?L0"
2622 };
2623 cmd_parser = &remove_bp_cmd_desc;
2624 }
bellard858693c2004-03-31 18:52:07 +00002625 break;
aliguori880a7572008-11-18 20:30:24 +00002626 case 'H':
Jon Doron3a9651d2019-05-29 09:41:34 +03002627 {
2628 static const GdbCmdParseEntry set_thread_cmd_desc = {
2629 .handler = handle_set_thread,
2630 .cmd = "H",
2631 .cmd_startswith = 1,
2632 .schema = "o.t0"
2633 };
2634 cmd_parser = &set_thread_cmd_desc;
aliguori880a7572008-11-18 20:30:24 +00002635 }
2636 break;
2637 case 'T':
Jon Doron44ffded2019-05-29 09:41:31 +03002638 {
2639 static const GdbCmdParseEntry thread_alive_cmd_desc = {
2640 .handler = handle_thread_alive,
2641 .cmd = "T",
2642 .cmd_startswith = 1,
2643 .schema = "t0"
2644 };
2645 cmd_parser = &thread_alive_cmd_desc;
Nathan Froyd1e9fa732009-06-03 11:33:08 -07002646 }
aliguori880a7572008-11-18 20:30:24 +00002647 break;
pbrook978efd62006-06-17 18:30:42 +00002648 case 'q':
Jon Doron2704efa2019-05-29 09:41:45 +03002649 {
2650 static const GdbCmdParseEntry gen_query_cmd_desc = {
2651 .handler = handle_gen_query,
2652 .cmd = "q",
2653 .cmd_startswith = 1,
2654 .schema = "s0"
2655 };
2656 cmd_parser = &gen_query_cmd_desc;
2657 }
2658 break;
edgar_igl60897d32008-05-09 08:25:14 +00002659 case 'Q':
Jon Doron2704efa2019-05-29 09:41:45 +03002660 {
2661 static const GdbCmdParseEntry gen_set_cmd_desc = {
2662 .handler = handle_gen_set,
2663 .cmd = "Q",
2664 .cmd_startswith = 1,
2665 .schema = "s0"
2666 };
2667 cmd_parser = &gen_set_cmd_desc;
edgar_igl60897d32008-05-09 08:25:14 +00002668 }
Jon Doron2704efa2019-05-29 09:41:45 +03002669 break;
bellard858693c2004-03-31 18:52:07 +00002670 default:
bellard858693c2004-03-31 18:52:07 +00002671 /* put empty packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002672 put_packet("");
bellard858693c2004-03-31 18:52:07 +00002673 break;
2674 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002675
Ramiro Polla2bdec392019-08-05 21:09:01 +02002676 if (cmd_parser) {
Alex Bennéea346af32020-03-16 17:21:34 +00002677 run_cmd_parser(line_buf, cmd_parser);
Ramiro Polla2bdec392019-08-05 21:09:01 +02002678 }
Jon Doron3e2c1262019-05-29 09:41:30 +03002679
bellard858693c2004-03-31 18:52:07 +00002680 return RS_IDLE;
2681}
2682
Andreas Färber64f6b342013-05-27 02:06:09 +02002683void gdb_set_stop_cpu(CPUState *cpu)
aliguori880a7572008-11-18 20:30:24 +00002684{
Alex Bennéea346af32020-03-16 17:21:34 +00002685 GDBProcess *p = gdb_get_cpu_process(cpu);
Luc Michel160d8582019-01-07 15:23:46 +00002686
2687 if (!p->attached) {
2688 /*
2689 * Having a stop CPU corresponding to a process that is not attached
2690 * confuses GDB. So we ignore the request.
2691 */
2692 return;
2693 }
2694
Alex Bennée8d98c442020-03-16 17:21:33 +00002695 gdbserver_state.c_cpu = cpu;
2696 gdbserver_state.g_cpu = cpu;
aliguori880a7572008-11-18 20:30:24 +00002697}
2698
bellard1fddef42005-04-17 19:16:13 +00002699#ifndef CONFIG_USER_ONLY
Philippe Mathieu-Daudé538f0492021-01-11 16:20:20 +01002700static void gdb_vm_state_change(void *opaque, bool running, RunState state)
bellard858693c2004-03-31 18:52:07 +00002701{
Alex Bennéea346af32020-03-16 17:21:34 +00002702 CPUState *cpu = gdbserver_state.c_cpu;
Alex Bennée308f9e82020-03-16 17:21:35 +00002703 g_autoptr(GString) buf = g_string_new(NULL);
2704 g_autoptr(GString) tid = g_string_new(NULL);
aliguorid6fc1b32008-11-18 19:55:44 +00002705 const char *type;
bellard858693c2004-03-31 18:52:07 +00002706 int ret;
2707
Alex Bennéea346af32020-03-16 17:21:34 +00002708 if (running || gdbserver_state.state == RS_INACTIVE) {
Meador Ingecdb432b2012-03-15 17:49:45 +00002709 return;
2710 }
2711 /* Is there a GDB syscall waiting to be sent? */
Alex Bennéea346af32020-03-16 17:21:34 +00002712 if (gdbserver_state.current_syscall_cb) {
2713 put_packet(gdbserver_state.syscall_buf);
pbrooka2d1eba2007-01-28 03:10:55 +00002714 return;
Jan Kiszkae07bbac2011-02-09 16:29:40 +01002715 }
Luc Michel95567c22019-01-07 15:23:46 +00002716
2717 if (cpu == NULL) {
2718 /* No process attached */
2719 return;
2720 }
2721
Alex Bennée308f9e82020-03-16 17:21:35 +00002722 gdb_append_thread_id(cpu, tid);
Luc Michel95567c22019-01-07 15:23:46 +00002723
Luiz Capitulino1dfb4dd2011-07-29 14:26:33 -03002724 switch (state) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002725 case RUN_STATE_DEBUG:
Andreas Färberff4700b2013-08-26 18:23:18 +02002726 if (cpu->watchpoint_hit) {
2727 switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
aliguoria1d1bb32008-11-18 20:07:32 +00002728 case BP_MEM_READ:
aliguorid6fc1b32008-11-18 19:55:44 +00002729 type = "r";
2730 break;
aliguoria1d1bb32008-11-18 20:07:32 +00002731 case BP_MEM_ACCESS:
aliguorid6fc1b32008-11-18 19:55:44 +00002732 type = "a";
2733 break;
2734 default:
2735 type = "";
2736 break;
2737 }
Doug Gale5c9522b2017-12-02 20:30:37 -05002738 trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
2739 (target_ulong)cpu->watchpoint_hit->vaddr);
Alex Bennée308f9e82020-03-16 17:21:35 +00002740 g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
2741 GDB_SIGNAL_TRAP, tid->str, type,
2742 (target_ulong)cpu->watchpoint_hit->vaddr);
Andreas Färberff4700b2013-08-26 18:23:18 +02002743 cpu->watchpoint_hit = NULL;
Jan Kiszka425189a2011-03-22 11:02:09 +01002744 goto send_packet;
Doug Gale5c9522b2017-12-02 20:30:37 -05002745 } else {
2746 trace_gdbstub_hit_break();
pbrook6658ffb2007-03-16 23:58:11 +00002747 }
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07002748 tb_flush(cpu);
aurel32ca587a82008-12-18 22:44:13 +00002749 ret = GDB_SIGNAL_TRAP;
Jan Kiszka425189a2011-03-22 11:02:09 +01002750 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002751 case RUN_STATE_PAUSED:
Doug Gale5c9522b2017-12-02 20:30:37 -05002752 trace_gdbstub_hit_paused();
aliguori9781e042009-01-22 17:15:29 +00002753 ret = GDB_SIGNAL_INT;
Jan Kiszka425189a2011-03-22 11:02:09 +01002754 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002755 case RUN_STATE_SHUTDOWN:
Doug Gale5c9522b2017-12-02 20:30:37 -05002756 trace_gdbstub_hit_shutdown();
Jan Kiszka425189a2011-03-22 11:02:09 +01002757 ret = GDB_SIGNAL_QUIT;
2758 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002759 case RUN_STATE_IO_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002760 trace_gdbstub_hit_io_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002761 ret = GDB_SIGNAL_IO;
2762 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002763 case RUN_STATE_WATCHDOG:
Doug Gale5c9522b2017-12-02 20:30:37 -05002764 trace_gdbstub_hit_watchdog();
Jan Kiszka425189a2011-03-22 11:02:09 +01002765 ret = GDB_SIGNAL_ALRM;
2766 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002767 case RUN_STATE_INTERNAL_ERROR:
Doug Gale5c9522b2017-12-02 20:30:37 -05002768 trace_gdbstub_hit_internal_error();
Jan Kiszka425189a2011-03-22 11:02:09 +01002769 ret = GDB_SIGNAL_ABRT;
2770 break;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002771 case RUN_STATE_SAVE_VM:
2772 case RUN_STATE_RESTORE_VM:
Jan Kiszka425189a2011-03-22 11:02:09 +01002773 return;
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002774 case RUN_STATE_FINISH_MIGRATE:
Jan Kiszka425189a2011-03-22 11:02:09 +01002775 ret = GDB_SIGNAL_XCPU;
2776 break;
2777 default:
Doug Gale5c9522b2017-12-02 20:30:37 -05002778 trace_gdbstub_hit_unknown(state);
Jan Kiszka425189a2011-03-22 11:02:09 +01002779 ret = GDB_SIGNAL_UNKNOWN;
2780 break;
bellardbbeb7b52006-04-23 18:42:15 +00002781 }
Jan Kiszka226d0072015-07-24 18:52:31 +02002782 gdb_set_stop_cpu(cpu);
Alex Bennée308f9e82020-03-16 17:21:35 +00002783 g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002784
2785send_packet:
Alex Bennée308f9e82020-03-16 17:21:35 +00002786 put_packet(buf->str);
Jan Kiszka425189a2011-03-22 11:02:09 +01002787
2788 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02002789 cpu_single_step(cpu, 0);
bellard858693c2004-03-31 18:52:07 +00002790}
bellard1fddef42005-04-17 19:16:13 +00002791#endif
bellard858693c2004-03-31 18:52:07 +00002792
pbrooka2d1eba2007-01-28 03:10:55 +00002793/* Send a gdb syscall request.
2794 This accepts limited printf-style format specifiers, specifically:
pbrooka87295e2007-05-26 15:09:38 +00002795 %x - target_ulong argument printed in hex.
2796 %lx - 64-bit argument printed in hex.
2797 %s - string pointer (target_ulong) and length (int) pair. */
Peter Maydell19239b32015-09-07 10:39:27 +01002798void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
pbrooka2d1eba2007-01-28 03:10:55 +00002799{
pbrooka2d1eba2007-01-28 03:10:55 +00002800 char *p;
Meador Ingecdb432b2012-03-15 17:49:45 +00002801 char *p_end;
pbrooka2d1eba2007-01-28 03:10:55 +00002802 target_ulong addr;
pbrooka87295e2007-05-26 15:09:38 +00002803 uint64_t i64;
pbrooka2d1eba2007-01-28 03:10:55 +00002804
Peter Maydellebf1b4c2022-06-10 14:32:36 +01002805 if (!gdb_attached()) {
pbrooka2d1eba2007-01-28 03:10:55 +00002806 return;
Alex Bennéea346af32020-03-16 17:21:34 +00002807 }
Alex Bennée8d98c442020-03-16 17:21:33 +00002808
2809 gdbserver_state.current_syscall_cb = cb;
pbrooka2d1eba2007-01-28 03:10:55 +00002810#ifndef CONFIG_USER_ONLY
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002811 vm_stop(RUN_STATE_DEBUG);
pbrooka2d1eba2007-01-28 03:10:55 +00002812#endif
Alex Bennée8d98c442020-03-16 17:21:33 +00002813 p = &gdbserver_state.syscall_buf[0];
2814 p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
pbrooka2d1eba2007-01-28 03:10:55 +00002815 *(p++) = 'F';
2816 while (*fmt) {
2817 if (*fmt == '%') {
2818 fmt++;
2819 switch (*fmt++) {
2820 case 'x':
2821 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002822 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
pbrooka2d1eba2007-01-28 03:10:55 +00002823 break;
pbrooka87295e2007-05-26 15:09:38 +00002824 case 'l':
2825 if (*(fmt++) != 'x')
2826 goto bad_format;
2827 i64 = va_arg(va, uint64_t);
Meador Ingecdb432b2012-03-15 17:49:45 +00002828 p += snprintf(p, p_end - p, "%" PRIx64, i64);
pbrooka87295e2007-05-26 15:09:38 +00002829 break;
pbrooka2d1eba2007-01-28 03:10:55 +00002830 case 's':
2831 addr = va_arg(va, target_ulong);
Meador Ingecdb432b2012-03-15 17:49:45 +00002832 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
blueswir1363a37d2008-08-21 17:58:08 +00002833 addr, va_arg(va, int));
pbrooka2d1eba2007-01-28 03:10:55 +00002834 break;
2835 default:
pbrooka87295e2007-05-26 15:09:38 +00002836 bad_format:
Ziyue Yang7ae6c572017-01-18 16:03:29 +08002837 error_report("gdbstub: Bad syscall format string '%s'",
2838 fmt - 1);
pbrooka2d1eba2007-01-28 03:10:55 +00002839 break;
2840 }
2841 } else {
2842 *(p++) = *(fmt++);
2843 }
2844 }
pbrook8a93e022007-08-06 13:19:15 +00002845 *p = 0;
pbrooka2d1eba2007-01-28 03:10:55 +00002846#ifdef CONFIG_USER_ONLY
Alex Bennéea346af32020-03-16 17:21:34 +00002847 put_packet(gdbserver_state.syscall_buf);
Peter Maydell4f710862018-05-15 19:19:58 +01002848 /* Return control to gdb for it to process the syscall request.
2849 * Since the protocol requires that gdb hands control back to us
2850 * using a "here are the results" F packet, we don't need to check
2851 * gdb_handlesig's return value (which is the signal to deliver if
2852 * execution was resumed via a continue packet).
2853 */
Alex Bennée8d98c442020-03-16 17:21:33 +00002854 gdb_handlesig(gdbserver_state.c_cpu, 0);
pbrooka2d1eba2007-01-28 03:10:55 +00002855#else
Meador Ingecdb432b2012-03-15 17:49:45 +00002856 /* In this case wait to send the syscall packet until notification that
2857 the CPU has stopped. This must be done because if the packet is sent
2858 now the reply from the syscall request could be received while the CPU
2859 is still in the running state, which can cause packets to be dropped
2860 and state transition 'T' packets to be sent while the syscall is still
2861 being processed. */
Alex Bennée8d98c442020-03-16 17:21:33 +00002862 qemu_cpu_kick(gdbserver_state.c_cpu);
pbrooka2d1eba2007-01-28 03:10:55 +00002863#endif
2864}
2865
Peter Maydell19239b32015-09-07 10:39:27 +01002866void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2867{
2868 va_list va;
2869
2870 va_start(va, fmt);
2871 gdb_do_syscallv(cb, fmt, va);
2872 va_end(va);
2873}
2874
Alex Bennéea346af32020-03-16 17:21:34 +00002875static void gdb_read_byte(uint8_t ch)
bellard858693c2004-03-31 18:52:07 +00002876{
ths60fe76f2007-12-16 03:02:09 +00002877 uint8_t reply;
bellard858693c2004-03-31 18:52:07 +00002878
bellard1fddef42005-04-17 19:16:13 +00002879#ifndef CONFIG_USER_ONLY
Damien Hedded116e812020-03-16 17:21:53 +00002880 if (gdbserver_state.last_packet->len) {
pbrook4046d912007-01-28 01:53:16 +00002881 /* Waiting for a response to the last packet. If we see the start
2882 of a new command then abandon the previous response. */
2883 if (ch == '-') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002884 trace_gdbstub_err_got_nack();
Damien Hedded116e812020-03-16 17:21:53 +00002885 put_buffer(gdbserver_state.last_packet->data,
2886 gdbserver_state.last_packet->len);
Alex Bennée118e2262017-07-12 11:52:13 +01002887 } else if (ch == '+') {
Doug Gale5c9522b2017-12-02 20:30:37 -05002888 trace_gdbstub_io_got_ack();
Alex Bennée118e2262017-07-12 11:52:13 +01002889 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002890 trace_gdbstub_io_got_unexpected(ch);
pbrook4046d912007-01-28 01:53:16 +00002891 }
Alex Bennée118e2262017-07-12 11:52:13 +01002892
Damien Hedded116e812020-03-16 17:21:53 +00002893 if (ch == '+' || ch == '$') {
2894 g_byte_array_set_size(gdbserver_state.last_packet, 0);
2895 }
pbrook4046d912007-01-28 01:53:16 +00002896 if (ch != '$')
2897 return;
2898 }
Luiz Capitulino13548692011-07-29 15:36:43 -03002899 if (runstate_is_running()) {
bellard858693c2004-03-31 18:52:07 +00002900 /* when the CPU is running, we cannot do anything except stop
2901 it when receiving a char */
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002902 vm_stop(RUN_STATE_PAUSED);
ths5fafdf22007-09-16 21:08:06 +00002903 } else
bellard1fddef42005-04-17 19:16:13 +00002904#endif
bellard41625032005-04-24 10:07:11 +00002905 {
Alex Bennéea346af32020-03-16 17:21:34 +00002906 switch(gdbserver_state.state) {
bellard858693c2004-03-31 18:52:07 +00002907 case RS_IDLE:
2908 if (ch == '$') {
Doug Gale4bf43122017-05-01 12:22:10 -04002909 /* start of command packet */
Alex Bennéea346af32020-03-16 17:21:34 +00002910 gdbserver_state.line_buf_index = 0;
2911 gdbserver_state.line_sum = 0;
2912 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002913 } else {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002914 trace_gdbstub_err_garbage(ch);
bellard4c3a88a2003-07-26 12:06:08 +00002915 }
2916 break;
bellard858693c2004-03-31 18:52:07 +00002917 case RS_GETLINE:
Doug Gale4bf43122017-05-01 12:22:10 -04002918 if (ch == '}') {
2919 /* start escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002920 gdbserver_state.state = RS_GETLINE_ESC;
2921 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002922 } else if (ch == '*') {
2923 /* start run length encoding sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002924 gdbserver_state.state = RS_GETLINE_RLE;
2925 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002926 } else if (ch == '#') {
2927 /* end of command, start of checksum*/
Alex Bennéea346af32020-03-16 17:21:34 +00002928 gdbserver_state.state = RS_CHKSUM1;
2929 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale5c9522b2017-12-02 20:30:37 -05002930 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00002931 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00002932 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04002933 /* unescaped command character */
Alex Bennéea346af32020-03-16 17:21:34 +00002934 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
2935 gdbserver_state.line_sum += ch;
Doug Gale4bf43122017-05-01 12:22:10 -04002936 }
2937 break;
2938 case RS_GETLINE_ESC:
2939 if (ch == '#') {
2940 /* unexpected end of command in escape sequence */
Alex Bennéea346af32020-03-16 17:21:34 +00002941 gdbserver_state.state = RS_CHKSUM1;
2942 } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04002943 /* command buffer overrun */
Doug Gale5c9522b2017-12-02 20:30:37 -05002944 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00002945 gdbserver_state.state = RS_IDLE;
Doug Gale4bf43122017-05-01 12:22:10 -04002946 } else {
2947 /* parse escaped character and leave escape state */
Alex Bennéea346af32020-03-16 17:21:34 +00002948 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
2949 gdbserver_state.line_sum += ch;
2950 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002951 }
2952 break;
2953 case RS_GETLINE_RLE:
Markus Armbruster046aba12019-05-14 20:03:08 +02002954 /*
2955 * Run-length encoding is explained in "Debugging with GDB /
2956 * Appendix E GDB Remote Serial Protocol / Overview".
2957 */
2958 if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
Doug Gale4bf43122017-05-01 12:22:10 -04002959 /* invalid RLE count encoding */
Markus Armbruster33c846e2019-05-14 20:03:09 +02002960 trace_gdbstub_err_invalid_repeat(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00002961 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002962 } else {
2963 /* decode repeat length */
Markus Armbruster33c846e2019-05-14 20:03:09 +02002964 int repeat = ch - ' ' + 3;
Alex Bennéea346af32020-03-16 17:21:34 +00002965 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04002966 /* that many repeats would overrun the command buffer */
Doug Gale5c9522b2017-12-02 20:30:37 -05002967 trace_gdbstub_err_overrun();
Alex Bennéea346af32020-03-16 17:21:34 +00002968 gdbserver_state.state = RS_IDLE;
2969 } else if (gdbserver_state.line_buf_index < 1) {
Doug Gale4bf43122017-05-01 12:22:10 -04002970 /* got a repeat but we have nothing to repeat */
Doug Gale5c9522b2017-12-02 20:30:37 -05002971 trace_gdbstub_err_invalid_rle();
Alex Bennéea346af32020-03-16 17:21:34 +00002972 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002973 } else {
2974 /* repeat the last character */
Alex Bennéea346af32020-03-16 17:21:34 +00002975 memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
2976 gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
2977 gdbserver_state.line_buf_index += repeat;
2978 gdbserver_state.line_sum += ch;
2979 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002980 }
bellard858693c2004-03-31 18:52:07 +00002981 }
2982 break;
2983 case RS_CHKSUM1:
Doug Gale4bf43122017-05-01 12:22:10 -04002984 /* get high hex digit of checksum */
2985 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002986 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00002987 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002988 break;
2989 }
Alex Bennéea346af32020-03-16 17:21:34 +00002990 gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
2991 gdbserver_state.line_csum = fromhex(ch) << 4;
2992 gdbserver_state.state = RS_CHKSUM2;
bellard858693c2004-03-31 18:52:07 +00002993 break;
2994 case RS_CHKSUM2:
Doug Gale4bf43122017-05-01 12:22:10 -04002995 /* get low hex digit of checksum */
2996 if (!isxdigit(ch)) {
Markus Armbruster33c846e2019-05-14 20:03:09 +02002997 trace_gdbstub_err_checksum_invalid(ch);
Alex Bennéea346af32020-03-16 17:21:34 +00002998 gdbserver_state.state = RS_GETLINE;
Doug Gale4bf43122017-05-01 12:22:10 -04002999 break;
bellard858693c2004-03-31 18:52:07 +00003000 }
Alex Bennéea346af32020-03-16 17:21:34 +00003001 gdbserver_state.line_csum |= fromhex(ch);
Doug Gale4bf43122017-05-01 12:22:10 -04003002
Alex Bennéea346af32020-03-16 17:21:34 +00003003 if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
3004 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
Doug Gale4bf43122017-05-01 12:22:10 -04003005 /* send NAK reply */
ths60fe76f2007-12-16 03:02:09 +00003006 reply = '-';
Alex Bennéea346af32020-03-16 17:21:34 +00003007 put_buffer(&reply, 1);
3008 gdbserver_state.state = RS_IDLE;
bellard858693c2004-03-31 18:52:07 +00003009 } else {
Doug Gale4bf43122017-05-01 12:22:10 -04003010 /* send ACK reply */
ths60fe76f2007-12-16 03:02:09 +00003011 reply = '+';
Alex Bennéea346af32020-03-16 17:21:34 +00003012 put_buffer(&reply, 1);
3013 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
bellard858693c2004-03-31 18:52:07 +00003014 }
bellardb4608c02003-06-27 17:34:32 +00003015 break;
pbrooka2d1eba2007-01-28 03:10:55 +00003016 default:
3017 abort();
bellardb4608c02003-06-27 17:34:32 +00003018 }
3019 }
bellard858693c2004-03-31 18:52:07 +00003020}
3021
Paul Brook0e1c9c52010-06-16 13:03:51 +01003022/* Tell the remote gdb that the process has exited. */
Alex Bennéead9dcb22021-01-08 22:42:43 +00003023void gdb_exit(int code)
Paul Brook0e1c9c52010-06-16 13:03:51 +01003024{
Paul Brook0e1c9c52010-06-16 13:03:51 +01003025 char buf[4];
3026
Alex Bennée8d98c442020-03-16 17:21:33 +00003027 if (!gdbserver_state.init) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003028 return;
3029 }
3030#ifdef CONFIG_USER_ONLY
Alex Bennéefcedd922020-04-30 20:01:19 +01003031 if (gdbserver_state.socket_path) {
3032 unlink(gdbserver_state.socket_path);
3033 }
Alex Bennéee0a1e202020-04-30 20:01:18 +01003034 if (gdbserver_state.fd < 0) {
Paul Brook0e1c9c52010-06-16 13:03:51 +01003035 return;
3036 }
3037#endif
3038
Doug Gale5c9522b2017-12-02 20:30:37 -05003039 trace_gdbstub_op_exiting((uint8_t)code);
3040
Paul Brook0e1c9c52010-06-16 13:03:51 +01003041 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
Alex Bennéea346af32020-03-16 17:21:34 +00003042 put_packet(buf);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003043
3044#ifndef CONFIG_USER_ONLY
Alex Bennée8d98c442020-03-16 17:21:33 +00003045 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
Fabien Chouteaue2af15b2011-01-13 12:46:57 +01003046#endif
Paul Brook0e1c9c52010-06-16 13:03:51 +01003047}
3048
Luc Michel8f468632019-01-07 15:23:45 +00003049/*
3050 * Create the process that will contain all the "orphan" CPUs (that are not
3051 * part of a CPU cluster). Note that if this process contains no CPUs, it won't
3052 * be attachable and thus will be invisible to the user.
3053 */
3054static void create_default_process(GDBState *s)
3055{
3056 GDBProcess *process;
3057 int max_pid = 0;
3058
Alex Bennéea346af32020-03-16 17:21:34 +00003059 if (gdbserver_state.process_num) {
Luc Michel8f468632019-01-07 15:23:45 +00003060 max_pid = s->processes[s->process_num - 1].pid;
3061 }
3062
3063 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3064 process = &s->processes[s->process_num - 1];
3065
3066 /* We need an available PID slot for this process */
3067 assert(max_pid < UINT32_MAX);
3068
3069 process->pid = max_pid + 1;
3070 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003071 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003072}
3073
bellard1fddef42005-04-17 19:16:13 +00003074#ifdef CONFIG_USER_ONLY
3075int
Andreas Färberdb6b81d2013-06-27 19:49:31 +02003076gdb_handlesig(CPUState *cpu, int sig)
bellard1fddef42005-04-17 19:16:13 +00003077{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003078 char buf[256];
3079 int n;
bellard1fddef42005-04-17 19:16:13 +00003080
Alex Bennéee0a1e202020-04-30 20:01:18 +01003081 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003082 return sig;
bellard1fddef42005-04-17 19:16:13 +00003083 }
3084
Andreas Färber5ca666c2013-06-24 19:20:57 +02003085 /* disable single step if it was enabled */
Andreas Färber3825b282013-06-24 18:41:06 +02003086 cpu_single_step(cpu, 0);
Peter Crosthwaitebbd77c12015-06-23 19:31:15 -07003087 tb_flush(cpu);
bellard1fddef42005-04-17 19:16:13 +00003088
Andreas Färber5ca666c2013-06-24 19:20:57 +02003089 if (sig != 0) {
Pavel Labath4a82be72021-10-26 11:22:34 +01003090 gdb_set_stop_cpu(cpu);
3091 g_string_printf(gdbserver_state.str_buf,
3092 "T%02xthread:", target_signal_to_gdb(sig));
3093 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
3094 g_string_append_c(gdbserver_state.str_buf, ';');
3095 put_strbuf();
Andreas Färber5ca666c2013-06-24 19:20:57 +02003096 }
3097 /* put_packet() might have detected that the peer terminated the
3098 connection. */
Alex Bennée8d98c442020-03-16 17:21:33 +00003099 if (gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003100 return sig;
3101 }
3102
3103 sig = 0;
Alex Bennée8d98c442020-03-16 17:21:33 +00003104 gdbserver_state.state = RS_IDLE;
3105 gdbserver_state.running_state = 0;
3106 while (gdbserver_state.running_state == 0) {
3107 n = read(gdbserver_state.fd, buf, 256);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003108 if (n > 0) {
3109 int i;
3110
3111 for (i = 0; i < n; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003112 gdb_read_byte(buf[i]);
Andreas Färber5ca666c2013-06-24 19:20:57 +02003113 }
Peter Wu5819e3e2016-06-05 16:35:48 +02003114 } else {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003115 /* XXX: Connection closed. Should probably wait for another
3116 connection before continuing. */
Peter Wu5819e3e2016-06-05 16:35:48 +02003117 if (n == 0) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003118 close(gdbserver_state.fd);
Peter Wu5819e3e2016-06-05 16:35:48 +02003119 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003120 gdbserver_state.fd = -1;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003121 return sig;
bellard1fddef42005-04-17 19:16:13 +00003122 }
Andreas Färber5ca666c2013-06-24 19:20:57 +02003123 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003124 sig = gdbserver_state.signal;
3125 gdbserver_state.signal = 0;
Andreas Färber5ca666c2013-06-24 19:20:57 +02003126 return sig;
bellard1fddef42005-04-17 19:16:13 +00003127}
bellarde9009672005-04-26 20:42:36 +00003128
aurel32ca587a82008-12-18 22:44:13 +00003129/* Tell the remote gdb that the process has exited due to SIG. */
Andreas Färber9349b4f2012-03-14 01:38:32 +01003130void gdb_signalled(CPUArchState *env, int sig)
aurel32ca587a82008-12-18 22:44:13 +00003131{
Andreas Färber5ca666c2013-06-24 19:20:57 +02003132 char buf[4];
aurel32ca587a82008-12-18 22:44:13 +00003133
Alex Bennéee0a1e202020-04-30 20:01:18 +01003134 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber5ca666c2013-06-24 19:20:57 +02003135 return;
3136 }
aurel32ca587a82008-12-18 22:44:13 +00003137
Andreas Färber5ca666c2013-06-24 19:20:57 +02003138 snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
Alex Bennéea346af32020-03-16 17:21:34 +00003139 put_packet(buf);
aurel32ca587a82008-12-18 22:44:13 +00003140}
bellard1fddef42005-04-17 19:16:13 +00003141
Alex Bennéefcedd922020-04-30 20:01:19 +01003142static void gdb_accept_init(int fd)
3143{
3144 init_gdbserver_state();
3145 create_default_process(&gdbserver_state);
3146 gdbserver_state.processes[0].attached = true;
3147 gdbserver_state.c_cpu = gdb_first_attached_cpu();
3148 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
3149 gdbserver_state.fd = fd;
3150 gdb_has_xml = false;
3151}
3152
3153static bool gdb_accept_socket(int gdb_fd)
3154{
3155 int fd;
3156
3157 for(;;) {
3158 fd = accept(gdb_fd, NULL, NULL);
3159 if (fd < 0 && errno != EINTR) {
3160 perror("accept socket");
3161 return false;
3162 } else if (fd >= 0) {
3163 qemu_set_cloexec(fd);
3164 break;
3165 }
3166 }
3167
3168 gdb_accept_init(fd);
3169 return true;
3170}
3171
3172static int gdbserver_open_socket(const char *path)
3173{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003174 struct sockaddr_un sockaddr = {};
Alex Bennéefcedd922020-04-30 20:01:19 +01003175 int fd, ret;
3176
3177 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3178 if (fd < 0) {
3179 perror("create socket");
3180 return -1;
3181 }
3182
3183 sockaddr.sun_family = AF_UNIX;
3184 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
3185 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3186 if (ret < 0) {
3187 perror("bind socket");
3188 close(fd);
3189 return -1;
3190 }
3191 ret = listen(fd, 1);
3192 if (ret < 0) {
3193 perror("listen socket");
3194 close(fd);
3195 return -1;
3196 }
3197
3198 return fd;
3199}
3200
3201static bool gdb_accept_tcp(int gdb_fd)
bellard858693c2004-03-31 18:52:07 +00003202{
Peter Maydellfdcdf542021-08-13 16:05:04 +01003203 struct sockaddr_in sockaddr = {};
bellard858693c2004-03-31 18:52:07 +00003204 socklen_t len;
MORITA Kazutakabf1c8522013-02-22 12:39:50 +09003205 int fd;
bellard858693c2004-03-31 18:52:07 +00003206
3207 for(;;) {
3208 len = sizeof(sockaddr);
Alex Bennéee0a1e202020-04-30 20:01:18 +01003209 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
bellard858693c2004-03-31 18:52:07 +00003210 if (fd < 0 && errno != EINTR) {
3211 perror("accept");
Peter Maydell2f652222018-05-14 18:30:44 +01003212 return false;
bellard858693c2004-03-31 18:52:07 +00003213 } else if (fd >= 0) {
Peter Maydellf5bdd782018-05-14 18:30:43 +01003214 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003215 break;
3216 }
3217 }
3218
3219 /* set short latency */
Peter Maydell2f652222018-05-14 18:30:44 +01003220 if (socket_set_nodelay(fd)) {
3221 perror("setsockopt");
Philippe Mathieu-Daudéead75d82018-05-24 19:34:58 -03003222 close(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003223 return false;
3224 }
ths3b46e622007-09-17 08:09:54 +00003225
Alex Bennéefcedd922020-04-30 20:01:19 +01003226 gdb_accept_init(fd);
Peter Maydell2f652222018-05-14 18:30:44 +01003227 return true;
bellard858693c2004-03-31 18:52:07 +00003228}
3229
Alex Bennéefcedd922020-04-30 20:01:19 +01003230static int gdbserver_open_port(int port)
bellard858693c2004-03-31 18:52:07 +00003231{
3232 struct sockaddr_in sockaddr;
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003233 int fd, ret;
bellard858693c2004-03-31 18:52:07 +00003234
3235 fd = socket(PF_INET, SOCK_STREAM, 0);
3236 if (fd < 0) {
3237 perror("socket");
3238 return -1;
3239 }
Peter Maydellf5bdd782018-05-14 18:30:43 +01003240 qemu_set_cloexec(fd);
bellard858693c2004-03-31 18:52:07 +00003241
Sebastian Ottlik6669ca12013-10-02 12:23:13 +02003242 socket_set_fast_reuse(fd);
bellard858693c2004-03-31 18:52:07 +00003243
3244 sockaddr.sin_family = AF_INET;
3245 sockaddr.sin_port = htons(port);
3246 sockaddr.sin_addr.s_addr = 0;
3247 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3248 if (ret < 0) {
3249 perror("bind");
Peter Maydellbb161722011-12-24 23:37:24 +00003250 close(fd);
bellard858693c2004-03-31 18:52:07 +00003251 return -1;
3252 }
Peter Wu96165b92016-05-04 11:32:17 +02003253 ret = listen(fd, 1);
bellard858693c2004-03-31 18:52:07 +00003254 if (ret < 0) {
3255 perror("listen");
Peter Maydellbb161722011-12-24 23:37:24 +00003256 close(fd);
bellard858693c2004-03-31 18:52:07 +00003257 return -1;
3258 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003259
bellard858693c2004-03-31 18:52:07 +00003260 return fd;
3261}
3262
Alex Bennéefcedd922020-04-30 20:01:19 +01003263int gdbserver_start(const char *port_or_path)
bellard858693c2004-03-31 18:52:07 +00003264{
Alex Bennéefcedd922020-04-30 20:01:19 +01003265 int port = g_ascii_strtoull(port_or_path, NULL, 10);
3266 int gdb_fd;
3267
3268 if (port > 0) {
3269 gdb_fd = gdbserver_open_port(port);
3270 } else {
3271 gdb_fd = gdbserver_open_socket(port_or_path);
3272 }
3273
Alex Bennéee0a1e202020-04-30 20:01:18 +01003274 if (gdb_fd < 0) {
bellard858693c2004-03-31 18:52:07 +00003275 return -1;
Alex Bennéee0a1e202020-04-30 20:01:18 +01003276 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003277
3278 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3279 return 0;
3280 } else if (gdb_accept_socket(gdb_fd)) {
3281 gdbserver_state.socket_path = g_strdup(port_or_path);
3282 return 0;
Peter Maydell2f652222018-05-14 18:30:44 +01003283 }
Alex Bennéefcedd922020-04-30 20:01:19 +01003284
3285 /* gone wrong */
3286 close(gdb_fd);
3287 return -1;
bellardb4608c02003-06-27 17:34:32 +00003288}
aurel322b1319c2008-12-18 22:44:04 +00003289
3290/* Disable gdb stub for child processes. */
Peter Crosthwaitef7ec7f72015-06-23 19:31:16 -07003291void gdbserver_fork(CPUState *cpu)
aurel322b1319c2008-12-18 22:44:04 +00003292{
Alex Bennéee0a1e202020-04-30 20:01:18 +01003293 if (!gdbserver_state.init || gdbserver_state.fd < 0) {
Andreas Färber75a34032013-09-02 16:57:02 +02003294 return;
3295 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003296 close(gdbserver_state.fd);
3297 gdbserver_state.fd = -1;
Andreas Färberb3310ab2013-09-02 17:26:20 +02003298 cpu_breakpoint_remove_all(cpu, BP_GDB);
Andreas Färber75a34032013-09-02 16:57:02 +02003299 cpu_watchpoint_remove_all(cpu, BP_GDB);
aurel322b1319c2008-12-18 22:44:04 +00003300}
pbrook4046d912007-01-28 01:53:16 +00003301#else
thsaa1f17c2007-07-11 22:48:58 +00003302static int gdb_chr_can_receive(void *opaque)
pbrook4046d912007-01-28 01:53:16 +00003303{
pbrook56aebc82008-10-11 17:55:29 +00003304 /* We can handle an arbitrarily large amount of data.
3305 Pick the maximum packet size, which is as good as anything. */
3306 return MAX_PACKET_LENGTH;
pbrook4046d912007-01-28 01:53:16 +00003307}
3308
thsaa1f17c2007-07-11 22:48:58 +00003309static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
pbrook4046d912007-01-28 01:53:16 +00003310{
pbrook4046d912007-01-28 01:53:16 +00003311 int i;
3312
3313 for (i = 0; i < size; i++) {
Alex Bennéea346af32020-03-16 17:21:34 +00003314 gdb_read_byte(buf[i]);
pbrook4046d912007-01-28 01:53:16 +00003315 }
3316}
3317
Philippe Mathieu-Daudé083b2662019-12-18 18:20:09 +01003318static void gdb_chr_event(void *opaque, QEMUChrEvent event)
pbrook4046d912007-01-28 01:53:16 +00003319{
Luc Michel970ed902019-01-07 15:23:46 +00003320 int i;
3321 GDBState *s = (GDBState *) opaque;
3322
pbrook4046d912007-01-28 01:53:16 +00003323 switch (event) {
Amit Shahb6b8df52009-10-07 18:31:16 +05303324 case CHR_EVENT_OPENED:
Luc Michel970ed902019-01-07 15:23:46 +00003325 /* Start with first process attached, others detached */
3326 for (i = 0; i < s->process_num; i++) {
3327 s->processes[i].attached = !i;
3328 }
3329
Alex Bennéea346af32020-03-16 17:21:34 +00003330 s->c_cpu = gdb_first_attached_cpu();
Luc Michel970ed902019-01-07 15:23:46 +00003331 s->g_cpu = s->c_cpu;
3332
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003333 vm_stop(RUN_STATE_PAUSED);
Pavel Dovgalyuk56357d82020-10-03 20:14:01 +03003334 replay_gdb_attached();
Andreas Färber5b50e792013-06-29 04:18:45 +02003335 gdb_has_xml = false;
pbrook4046d912007-01-28 01:53:16 +00003336 break;
3337 default:
3338 break;
3339 }
3340}
3341
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003342static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
aliguori8a34a0f2009-03-05 23:01:55 +00003343{
Damien Hedded86b4672020-03-16 17:21:54 +00003344 g_autoptr(GString) hex_buf = g_string_new("O");
3345 memtohex(hex_buf, buf, len);
3346 put_packet(hex_buf->str);
aliguori8a34a0f2009-03-05 23:01:55 +00003347 return len;
3348}
3349
aliguori59030a82009-04-05 18:43:41 +00003350#ifndef _WIN32
3351static void gdb_sigterm_handler(int signal)
3352{
Luiz Capitulino13548692011-07-29 15:36:43 -03003353 if (runstate_is_running()) {
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03003354 vm_stop(RUN_STATE_PAUSED);
Jan Kiszkae07bbac2011-02-09 16:29:40 +01003355 }
aliguori59030a82009-04-05 18:43:41 +00003356}
3357#endif
3358
Marc-André Lureau777357d2016-12-07 18:39:10 +03003359static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
3360 bool *be_opened, Error **errp)
3361{
3362 *be_opened = false;
3363}
3364
3365static void char_gdb_class_init(ObjectClass *oc, void *data)
3366{
3367 ChardevClass *cc = CHARDEV_CLASS(oc);
3368
3369 cc->internal = true;
3370 cc->open = gdb_monitor_open;
3371 cc->chr_write = gdb_monitor_write;
3372}
3373
3374#define TYPE_CHARDEV_GDB "chardev-gdb"
3375
3376static const TypeInfo char_gdb_type_info = {
3377 .name = TYPE_CHARDEV_GDB,
3378 .parent = TYPE_CHARDEV,
3379 .class_init = char_gdb_class_init,
3380};
3381
Luc Michel8f468632019-01-07 15:23:45 +00003382static int find_cpu_clusters(Object *child, void *opaque)
3383{
3384 if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
3385 GDBState *s = (GDBState *) opaque;
3386 CPUClusterState *cluster = CPU_CLUSTER(child);
3387 GDBProcess *process;
3388
3389 s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3390
3391 process = &s->processes[s->process_num - 1];
3392
3393 /*
3394 * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
3395 * runtime, we enforce here that the machine does not use a cluster ID
3396 * that would lead to PID 0.
3397 */
3398 assert(cluster->cluster_id != UINT32_MAX);
3399 process->pid = cluster->cluster_id + 1;
3400 process->attached = false;
Luc Michelc145eea2019-01-07 15:23:46 +00003401 process->target_xml[0] = '\0';
Luc Michel8f468632019-01-07 15:23:45 +00003402
3403 return 0;
3404 }
3405
3406 return object_child_foreach(child, find_cpu_clusters, opaque);
3407}
3408
3409static int pid_order(const void *a, const void *b)
3410{
3411 GDBProcess *pa = (GDBProcess *) a;
3412 GDBProcess *pb = (GDBProcess *) b;
3413
3414 if (pa->pid < pb->pid) {
3415 return -1;
3416 } else if (pa->pid > pb->pid) {
3417 return 1;
3418 } else {
3419 return 0;
3420 }
3421}
3422
3423static void create_processes(GDBState *s)
3424{
3425 object_child_foreach(object_get_root(), find_cpu_clusters, s);
3426
Alex Bennéea346af32020-03-16 17:21:34 +00003427 if (gdbserver_state.processes) {
Luc Michel8f468632019-01-07 15:23:45 +00003428 /* Sort by PID */
Alex Bennéea346af32020-03-16 17:21:34 +00003429 qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
Luc Michel8f468632019-01-07 15:23:45 +00003430 }
3431
3432 create_default_process(s);
3433}
3434
aliguori59030a82009-04-05 18:43:41 +00003435int gdbserver_start(const char *device)
pbrook4046d912007-01-28 01:53:16 +00003436{
Doug Gale5c9522b2017-12-02 20:30:37 -05003437 trace_gdbstub_op_start(device);
3438
aliguori59030a82009-04-05 18:43:41 +00003439 char gdbstub_device_name[128];
Marc-André Lureau0ec7b3e2016-12-07 16:20:22 +03003440 Chardev *chr = NULL;
3441 Chardev *mon_chr;
pbrook4046d912007-01-28 01:53:16 +00003442
Ziyue Yang508b4ec2017-01-18 16:02:41 +08003443 if (!first_cpu) {
3444 error_report("gdbstub: meaningless to attach gdb to a "
3445 "machine without any CPU.");
3446 return -1;
3447 }
3448
Alex Bennéea48e7d92022-09-29 12:42:25 +01003449 if (!gdb_supports_guest_debug()) {
3450 error_report("gdbstub: current accelerator doesn't support guest debugging");
Maxim Levitsky12bc5b42021-11-11 12:06:03 +01003451 return -1;
3452 }
3453
aliguori59030a82009-04-05 18:43:41 +00003454 if (!device)
3455 return -1;
3456 if (strcmp(device, "none") != 0) {
3457 if (strstart(device, "tcp:", NULL)) {
3458 /* enforce required TCP attributes */
3459 snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
Paolo Bonzinia9b13152021-02-25 11:47:52 +01003460 "%s,wait=off,nodelay=on,server=on", device);
aliguori59030a82009-04-05 18:43:41 +00003461 device = gdbstub_device_name;
aliguori36556b22009-03-28 18:05:53 +00003462 }
aliguori59030a82009-04-05 18:43:41 +00003463#ifndef _WIN32
3464 else if (strcmp(device, "stdio") == 0) {
3465 struct sigaction act;
pbrookcfc34752007-02-22 01:48:01 +00003466
aliguori59030a82009-04-05 18:43:41 +00003467 memset(&act, 0, sizeof(act));
3468 act.sa_handler = gdb_sigterm_handler;
3469 sigaction(SIGINT, &act, NULL);
3470 }
3471#endif
Marc-André Lureau95e30b22018-08-22 19:19:42 +02003472 /*
3473 * FIXME: it's a bit weird to allow using a mux chardev here
3474 * and implicitly setup a monitor. We may want to break this.
3475 */
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003476 chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
aliguori36556b22009-03-28 18:05:53 +00003477 if (!chr)
3478 return -1;
pbrookcfc34752007-02-22 01:48:01 +00003479 }
3480
Alex Bennée8d98c442020-03-16 17:21:33 +00003481 if (!gdbserver_state.init) {
3482 init_gdbserver_state();
pbrook4046d912007-01-28 01:53:16 +00003483
aliguori36556b22009-03-28 18:05:53 +00003484 qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
3485
3486 /* Initialize a monitor terminal for gdb */
Marc-André Lureau777357d2016-12-07 18:39:10 +03003487 mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
Paolo Bonzini4ad6f6c2019-02-13 14:18:13 +01003488 NULL, NULL, &error_abort);
Kevin Wolf8e9119a2020-02-24 15:30:06 +01003489 monitor_init_hmp(mon_chr, false, &error_abort);
aliguori36556b22009-03-28 18:05:53 +00003490 } else {
Alex Bennée8d98c442020-03-16 17:21:33 +00003491 qemu_chr_fe_deinit(&gdbserver_state.chr, true);
3492 mon_chr = gdbserver_state.mon_chr;
3493 reset_gdbserver_state();
aliguori36556b22009-03-28 18:05:53 +00003494 }
Luc Michel8f468632019-01-07 15:23:45 +00003495
Alex Bennée8d98c442020-03-16 17:21:33 +00003496 create_processes(&gdbserver_state);
Luc Michel8f468632019-01-07 15:23:45 +00003497
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003498 if (chr) {
Alex Bennée8d98c442020-03-16 17:21:33 +00003499 qemu_chr_fe_init(&gdbserver_state.chr, chr, &error_abort);
3500 qemu_chr_fe_set_handlers(&gdbserver_state.chr, gdb_chr_can_receive,
3501 gdb_chr_receive, gdb_chr_event,
3502 NULL, &gdbserver_state, NULL, true);
Marc-André Lureau32a6ebe2016-10-22 12:52:52 +03003503 }
Alex Bennée8d98c442020-03-16 17:21:33 +00003504 gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
3505 gdbserver_state.mon_chr = mon_chr;
3506 gdbserver_state.current_syscall_cb = NULL;
aliguori8a34a0f2009-03-05 23:01:55 +00003507
pbrook4046d912007-01-28 01:53:16 +00003508 return 0;
3509}
Marc-André Lureau777357d2016-12-07 18:39:10 +03003510
3511static void register_types(void)
3512{
3513 type_register_static(&char_gdb_type_info);
3514}
3515
3516type_init(register_types);
pbrook4046d912007-01-28 01:53:16 +00003517#endif