xref: /qemu/gdbstub/gdbstub.c (revision 36e067b2)
1842b42dfSAlex Bennée /*
2842b42dfSAlex Bennée  * gdb server stub
3842b42dfSAlex Bennée  *
4842b42dfSAlex Bennée  * This implements a subset of the remote protocol as described in:
5842b42dfSAlex Bennée  *
6842b42dfSAlex Bennée  *   https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html
7842b42dfSAlex Bennée  *
8842b42dfSAlex Bennée  * Copyright (c) 2003-2005 Fabrice Bellard
9842b42dfSAlex Bennée  *
10842b42dfSAlex Bennée  * This library is free software; you can redistribute it and/or
11842b42dfSAlex Bennée  * modify it under the terms of the GNU Lesser General Public
12842b42dfSAlex Bennée  * License as published by the Free Software Foundation; either
13842b42dfSAlex Bennée  * version 2 of the License, or (at your option) any later version.
14842b42dfSAlex Bennée  *
15842b42dfSAlex Bennée  * This library is distributed in the hope that it will be useful,
16842b42dfSAlex Bennée  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17842b42dfSAlex Bennée  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18842b42dfSAlex Bennée  * Lesser General Public License for more details.
19842b42dfSAlex Bennée  *
20842b42dfSAlex Bennée  * You should have received a copy of the GNU Lesser General Public
21842b42dfSAlex Bennée  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22842b42dfSAlex Bennée  *
23842b42dfSAlex Bennée  * SPDX-License-Identifier: LGPL-2.0+
24842b42dfSAlex Bennée  */
25842b42dfSAlex Bennée 
26842b42dfSAlex Bennée #include "qemu/osdep.h"
27842b42dfSAlex Bennée #include "qapi/error.h"
28842b42dfSAlex Bennée #include "qemu/error-report.h"
29842b42dfSAlex Bennée #include "qemu/ctype.h"
30842b42dfSAlex Bennée #include "qemu/cutils.h"
31842b42dfSAlex Bennée #include "qemu/module.h"
32842b42dfSAlex Bennée #include "trace.h"
33842b42dfSAlex Bennée #include "exec/gdbstub.h"
34842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
35842b42dfSAlex Bennée #include "qemu.h"
36842b42dfSAlex Bennée #else
37842b42dfSAlex Bennée #include "monitor/monitor.h"
38842b42dfSAlex Bennée #include "chardev/char.h"
39842b42dfSAlex Bennée #include "chardev/char-fe.h"
40842b42dfSAlex Bennée #include "hw/cpu/cluster.h"
41842b42dfSAlex Bennée #include "hw/boards.h"
42842b42dfSAlex Bennée #endif
43842b42dfSAlex Bennée 
44842b42dfSAlex Bennée #include "qemu/sockets.h"
45842b42dfSAlex Bennée #include "sysemu/hw_accel.h"
46842b42dfSAlex Bennée #include "sysemu/runstate.h"
47842b42dfSAlex Bennée #include "semihosting/semihost.h"
48842b42dfSAlex Bennée #include "exec/exec-all.h"
495b5968c4SPhilippe Mathieu-Daudé #include "exec/replay-core.h"
50548c9609SAlex Bennée #include "exec/tb-flush.h"
51548c9609SAlex Bennée #include "exec/hwaddr.h"
52842b42dfSAlex Bennée 
53ae7467b1SAlex Bennée #include "internals.h"
54ae7467b1SAlex Bennée 
55842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
56842b42dfSAlex Bennée #define GDB_ATTACHED "0"
57842b42dfSAlex Bennée #else
58842b42dfSAlex Bennée #define GDB_ATTACHED "1"
59842b42dfSAlex Bennée #endif
60842b42dfSAlex Bennée 
61842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
62842b42dfSAlex Bennée static int phy_memory_mode;
63842b42dfSAlex Bennée #endif
64842b42dfSAlex Bennée 
65842b42dfSAlex Bennée static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
66842b42dfSAlex Bennée                                          uint8_t *buf, int len, bool is_write)
67842b42dfSAlex Bennée {
68842b42dfSAlex Bennée     CPUClass *cc;
69842b42dfSAlex Bennée 
70842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
71842b42dfSAlex Bennée     if (phy_memory_mode) {
72842b42dfSAlex Bennée         if (is_write) {
73842b42dfSAlex Bennée             cpu_physical_memory_write(addr, buf, len);
74842b42dfSAlex Bennée         } else {
75842b42dfSAlex Bennée             cpu_physical_memory_read(addr, buf, len);
76842b42dfSAlex Bennée         }
77842b42dfSAlex Bennée         return 0;
78842b42dfSAlex Bennée     }
79842b42dfSAlex Bennée #endif
80842b42dfSAlex Bennée 
81842b42dfSAlex Bennée     cc = CPU_GET_CLASS(cpu);
82842b42dfSAlex Bennée     if (cc->memory_rw_debug) {
83842b42dfSAlex Bennée         return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
84842b42dfSAlex Bennée     }
85842b42dfSAlex Bennée     return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
86842b42dfSAlex Bennée }
87842b42dfSAlex Bennée 
8836e067b2SAlex Bennée /*
8936e067b2SAlex Bennée  * Return the GDB index for a given vCPU state.
90842b42dfSAlex Bennée  *
91842b42dfSAlex Bennée  * For user mode this is simply the thread id. In system mode GDB
92842b42dfSAlex Bennée  * numbers CPUs from 1 as 0 is reserved as an "any cpu" index.
93842b42dfSAlex Bennée  */
9436e067b2SAlex Bennée int gdb_get_cpu_index(CPUState *cpu)
95842b42dfSAlex Bennée {
96842b42dfSAlex Bennée #if defined(CONFIG_USER_ONLY)
97842b42dfSAlex Bennée     TaskState *ts = (TaskState *) cpu->opaque;
98842b42dfSAlex Bennée     return ts ? ts->ts_tid : -1;
99842b42dfSAlex Bennée #else
100842b42dfSAlex Bennée     return cpu->cpu_index + 1;
101842b42dfSAlex Bennée #endif
102842b42dfSAlex Bennée }
103842b42dfSAlex Bennée 
104842b42dfSAlex Bennée enum {
105842b42dfSAlex Bennée     GDB_SIGNAL_0 = 0,
106842b42dfSAlex Bennée     GDB_SIGNAL_INT = 2,
107842b42dfSAlex Bennée     GDB_SIGNAL_QUIT = 3,
108842b42dfSAlex Bennée     GDB_SIGNAL_TRAP = 5,
109842b42dfSAlex Bennée     GDB_SIGNAL_ABRT = 6,
110842b42dfSAlex Bennée     GDB_SIGNAL_ALRM = 14,
111842b42dfSAlex Bennée     GDB_SIGNAL_IO = 23,
112842b42dfSAlex Bennée     GDB_SIGNAL_XCPU = 24,
113842b42dfSAlex Bennée     GDB_SIGNAL_UNKNOWN = 143
114842b42dfSAlex Bennée };
115842b42dfSAlex Bennée 
116842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
117842b42dfSAlex Bennée 
118842b42dfSAlex Bennée /* Map target signal numbers to GDB protocol signal numbers and vice
119842b42dfSAlex Bennée  * versa.  For user emulation's currently supported systems, we can
120842b42dfSAlex Bennée  * assume most signals are defined.
121842b42dfSAlex Bennée  */
122842b42dfSAlex Bennée 
123842b42dfSAlex Bennée static int gdb_signal_table[] = {
124842b42dfSAlex Bennée     0,
125842b42dfSAlex Bennée     TARGET_SIGHUP,
126842b42dfSAlex Bennée     TARGET_SIGINT,
127842b42dfSAlex Bennée     TARGET_SIGQUIT,
128842b42dfSAlex Bennée     TARGET_SIGILL,
129842b42dfSAlex Bennée     TARGET_SIGTRAP,
130842b42dfSAlex Bennée     TARGET_SIGABRT,
131842b42dfSAlex Bennée     -1, /* SIGEMT */
132842b42dfSAlex Bennée     TARGET_SIGFPE,
133842b42dfSAlex Bennée     TARGET_SIGKILL,
134842b42dfSAlex Bennée     TARGET_SIGBUS,
135842b42dfSAlex Bennée     TARGET_SIGSEGV,
136842b42dfSAlex Bennée     TARGET_SIGSYS,
137842b42dfSAlex Bennée     TARGET_SIGPIPE,
138842b42dfSAlex Bennée     TARGET_SIGALRM,
139842b42dfSAlex Bennée     TARGET_SIGTERM,
140842b42dfSAlex Bennée     TARGET_SIGURG,
141842b42dfSAlex Bennée     TARGET_SIGSTOP,
142842b42dfSAlex Bennée     TARGET_SIGTSTP,
143842b42dfSAlex Bennée     TARGET_SIGCONT,
144842b42dfSAlex Bennée     TARGET_SIGCHLD,
145842b42dfSAlex Bennée     TARGET_SIGTTIN,
146842b42dfSAlex Bennée     TARGET_SIGTTOU,
147842b42dfSAlex Bennée     TARGET_SIGIO,
148842b42dfSAlex Bennée     TARGET_SIGXCPU,
149842b42dfSAlex Bennée     TARGET_SIGXFSZ,
150842b42dfSAlex Bennée     TARGET_SIGVTALRM,
151842b42dfSAlex Bennée     TARGET_SIGPROF,
152842b42dfSAlex Bennée     TARGET_SIGWINCH,
153842b42dfSAlex Bennée     -1, /* SIGLOST */
154842b42dfSAlex Bennée     TARGET_SIGUSR1,
155842b42dfSAlex Bennée     TARGET_SIGUSR2,
156842b42dfSAlex Bennée #ifdef TARGET_SIGPWR
157842b42dfSAlex Bennée     TARGET_SIGPWR,
158842b42dfSAlex Bennée #else
159842b42dfSAlex Bennée     -1,
160842b42dfSAlex Bennée #endif
161842b42dfSAlex Bennée     -1, /* SIGPOLL */
162842b42dfSAlex Bennée     -1,
163842b42dfSAlex Bennée     -1,
164842b42dfSAlex Bennée     -1,
165842b42dfSAlex Bennée     -1,
166842b42dfSAlex Bennée     -1,
167842b42dfSAlex Bennée     -1,
168842b42dfSAlex Bennée     -1,
169842b42dfSAlex Bennée     -1,
170842b42dfSAlex Bennée     -1,
171842b42dfSAlex Bennée     -1,
172842b42dfSAlex Bennée     -1,
173842b42dfSAlex Bennée #ifdef __SIGRTMIN
174842b42dfSAlex Bennée     __SIGRTMIN + 1,
175842b42dfSAlex Bennée     __SIGRTMIN + 2,
176842b42dfSAlex Bennée     __SIGRTMIN + 3,
177842b42dfSAlex Bennée     __SIGRTMIN + 4,
178842b42dfSAlex Bennée     __SIGRTMIN + 5,
179842b42dfSAlex Bennée     __SIGRTMIN + 6,
180842b42dfSAlex Bennée     __SIGRTMIN + 7,
181842b42dfSAlex Bennée     __SIGRTMIN + 8,
182842b42dfSAlex Bennée     __SIGRTMIN + 9,
183842b42dfSAlex Bennée     __SIGRTMIN + 10,
184842b42dfSAlex Bennée     __SIGRTMIN + 11,
185842b42dfSAlex Bennée     __SIGRTMIN + 12,
186842b42dfSAlex Bennée     __SIGRTMIN + 13,
187842b42dfSAlex Bennée     __SIGRTMIN + 14,
188842b42dfSAlex Bennée     __SIGRTMIN + 15,
189842b42dfSAlex Bennée     __SIGRTMIN + 16,
190842b42dfSAlex Bennée     __SIGRTMIN + 17,
191842b42dfSAlex Bennée     __SIGRTMIN + 18,
192842b42dfSAlex Bennée     __SIGRTMIN + 19,
193842b42dfSAlex Bennée     __SIGRTMIN + 20,
194842b42dfSAlex Bennée     __SIGRTMIN + 21,
195842b42dfSAlex Bennée     __SIGRTMIN + 22,
196842b42dfSAlex Bennée     __SIGRTMIN + 23,
197842b42dfSAlex Bennée     __SIGRTMIN + 24,
198842b42dfSAlex Bennée     __SIGRTMIN + 25,
199842b42dfSAlex Bennée     __SIGRTMIN + 26,
200842b42dfSAlex Bennée     __SIGRTMIN + 27,
201842b42dfSAlex Bennée     __SIGRTMIN + 28,
202842b42dfSAlex Bennée     __SIGRTMIN + 29,
203842b42dfSAlex Bennée     __SIGRTMIN + 30,
204842b42dfSAlex Bennée     __SIGRTMIN + 31,
205842b42dfSAlex Bennée     -1, /* SIGCANCEL */
206842b42dfSAlex Bennée     __SIGRTMIN,
207842b42dfSAlex Bennée     __SIGRTMIN + 32,
208842b42dfSAlex Bennée     __SIGRTMIN + 33,
209842b42dfSAlex Bennée     __SIGRTMIN + 34,
210842b42dfSAlex Bennée     __SIGRTMIN + 35,
211842b42dfSAlex Bennée     __SIGRTMIN + 36,
212842b42dfSAlex Bennée     __SIGRTMIN + 37,
213842b42dfSAlex Bennée     __SIGRTMIN + 38,
214842b42dfSAlex Bennée     __SIGRTMIN + 39,
215842b42dfSAlex Bennée     __SIGRTMIN + 40,
216842b42dfSAlex Bennée     __SIGRTMIN + 41,
217842b42dfSAlex Bennée     __SIGRTMIN + 42,
218842b42dfSAlex Bennée     __SIGRTMIN + 43,
219842b42dfSAlex Bennée     __SIGRTMIN + 44,
220842b42dfSAlex Bennée     __SIGRTMIN + 45,
221842b42dfSAlex Bennée     __SIGRTMIN + 46,
222842b42dfSAlex Bennée     __SIGRTMIN + 47,
223842b42dfSAlex Bennée     __SIGRTMIN + 48,
224842b42dfSAlex Bennée     __SIGRTMIN + 49,
225842b42dfSAlex Bennée     __SIGRTMIN + 50,
226842b42dfSAlex Bennée     __SIGRTMIN + 51,
227842b42dfSAlex Bennée     __SIGRTMIN + 52,
228842b42dfSAlex Bennée     __SIGRTMIN + 53,
229842b42dfSAlex Bennée     __SIGRTMIN + 54,
230842b42dfSAlex Bennée     __SIGRTMIN + 55,
231842b42dfSAlex Bennée     __SIGRTMIN + 56,
232842b42dfSAlex Bennée     __SIGRTMIN + 57,
233842b42dfSAlex Bennée     __SIGRTMIN + 58,
234842b42dfSAlex Bennée     __SIGRTMIN + 59,
235842b42dfSAlex Bennée     __SIGRTMIN + 60,
236842b42dfSAlex Bennée     __SIGRTMIN + 61,
237842b42dfSAlex Bennée     __SIGRTMIN + 62,
238842b42dfSAlex Bennée     __SIGRTMIN + 63,
239842b42dfSAlex Bennée     __SIGRTMIN + 64,
240842b42dfSAlex Bennée     __SIGRTMIN + 65,
241842b42dfSAlex Bennée     __SIGRTMIN + 66,
242842b42dfSAlex Bennée     __SIGRTMIN + 67,
243842b42dfSAlex Bennée     __SIGRTMIN + 68,
244842b42dfSAlex Bennée     __SIGRTMIN + 69,
245842b42dfSAlex Bennée     __SIGRTMIN + 70,
246842b42dfSAlex Bennée     __SIGRTMIN + 71,
247842b42dfSAlex Bennée     __SIGRTMIN + 72,
248842b42dfSAlex Bennée     __SIGRTMIN + 73,
249842b42dfSAlex Bennée     __SIGRTMIN + 74,
250842b42dfSAlex Bennée     __SIGRTMIN + 75,
251842b42dfSAlex Bennée     __SIGRTMIN + 76,
252842b42dfSAlex Bennée     __SIGRTMIN + 77,
253842b42dfSAlex Bennée     __SIGRTMIN + 78,
254842b42dfSAlex Bennée     __SIGRTMIN + 79,
255842b42dfSAlex Bennée     __SIGRTMIN + 80,
256842b42dfSAlex Bennée     __SIGRTMIN + 81,
257842b42dfSAlex Bennée     __SIGRTMIN + 82,
258842b42dfSAlex Bennée     __SIGRTMIN + 83,
259842b42dfSAlex Bennée     __SIGRTMIN + 84,
260842b42dfSAlex Bennée     __SIGRTMIN + 85,
261842b42dfSAlex Bennée     __SIGRTMIN + 86,
262842b42dfSAlex Bennée     __SIGRTMIN + 87,
263842b42dfSAlex Bennée     __SIGRTMIN + 88,
264842b42dfSAlex Bennée     __SIGRTMIN + 89,
265842b42dfSAlex Bennée     __SIGRTMIN + 90,
266842b42dfSAlex Bennée     __SIGRTMIN + 91,
267842b42dfSAlex Bennée     __SIGRTMIN + 92,
268842b42dfSAlex Bennée     __SIGRTMIN + 93,
269842b42dfSAlex Bennée     __SIGRTMIN + 94,
270842b42dfSAlex Bennée     __SIGRTMIN + 95,
271842b42dfSAlex Bennée     -1, /* SIGINFO */
272842b42dfSAlex Bennée     -1, /* UNKNOWN */
273842b42dfSAlex Bennée     -1, /* DEFAULT */
274842b42dfSAlex Bennée     -1,
275842b42dfSAlex Bennée     -1,
276842b42dfSAlex Bennée     -1,
277842b42dfSAlex Bennée     -1,
278842b42dfSAlex Bennée     -1,
279842b42dfSAlex Bennée     -1
280842b42dfSAlex Bennée #endif
281842b42dfSAlex Bennée };
282842b42dfSAlex Bennée #else
283842b42dfSAlex Bennée /* In system mode we only need SIGINT and SIGTRAP; other signals
284842b42dfSAlex Bennée    are not yet supported.  */
285842b42dfSAlex Bennée 
286842b42dfSAlex Bennée enum {
287842b42dfSAlex Bennée     TARGET_SIGINT = 2,
288842b42dfSAlex Bennée     TARGET_SIGTRAP = 5
289842b42dfSAlex Bennée };
290842b42dfSAlex Bennée 
291842b42dfSAlex Bennée static int gdb_signal_table[] = {
292842b42dfSAlex Bennée     -1,
293842b42dfSAlex Bennée     -1,
294842b42dfSAlex Bennée     TARGET_SIGINT,
295842b42dfSAlex Bennée     -1,
296842b42dfSAlex Bennée     -1,
297842b42dfSAlex Bennée     TARGET_SIGTRAP
298842b42dfSAlex Bennée };
299842b42dfSAlex Bennée #endif
300842b42dfSAlex Bennée 
301842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
302842b42dfSAlex Bennée static int target_signal_to_gdb (int sig)
303842b42dfSAlex Bennée {
304842b42dfSAlex Bennée     int i;
305842b42dfSAlex Bennée     for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
306842b42dfSAlex Bennée         if (gdb_signal_table[i] == sig)
307842b42dfSAlex Bennée             return i;
308842b42dfSAlex Bennée     return GDB_SIGNAL_UNKNOWN;
309842b42dfSAlex Bennée }
310842b42dfSAlex Bennée #endif
311842b42dfSAlex Bennée 
312842b42dfSAlex Bennée static int gdb_signal_to_target (int sig)
313842b42dfSAlex Bennée {
314842b42dfSAlex Bennée     if (sig < ARRAY_SIZE (gdb_signal_table))
315842b42dfSAlex Bennée         return gdb_signal_table[sig];
316842b42dfSAlex Bennée     else
317842b42dfSAlex Bennée         return -1;
318842b42dfSAlex Bennée }
319842b42dfSAlex Bennée 
320842b42dfSAlex Bennée typedef struct GDBRegisterState {
321842b42dfSAlex Bennée     int base_reg;
322842b42dfSAlex Bennée     int num_regs;
323842b42dfSAlex Bennée     gdb_get_reg_cb get_reg;
324842b42dfSAlex Bennée     gdb_set_reg_cb set_reg;
325842b42dfSAlex Bennée     const char *xml;
326842b42dfSAlex Bennée     struct GDBRegisterState *next;
327842b42dfSAlex Bennée } GDBRegisterState;
328842b42dfSAlex Bennée 
3298e70c6f9SAlex Bennée #ifdef CONFIG_USER_ONLY
3308e70c6f9SAlex Bennée typedef struct {
3318e70c6f9SAlex Bennée     int fd;
3328e70c6f9SAlex Bennée     char *socket_path;
3338e70c6f9SAlex Bennée     int running_state;
3348e70c6f9SAlex Bennée } GDBUserState;
3358e70c6f9SAlex Bennée static GDBUserState gdbserver_user_state;
3368e70c6f9SAlex Bennée #else
3378e70c6f9SAlex Bennée typedef struct {
3388e70c6f9SAlex Bennée     CharBackend chr;
3398e70c6f9SAlex Bennée     Chardev *mon_chr;
3408e70c6f9SAlex Bennée } GDBSystemState;
3418e70c6f9SAlex Bennée static GDBSystemState gdbserver_system_state;
3428e70c6f9SAlex Bennée #endif
3438e70c6f9SAlex Bennée 
344842b42dfSAlex Bennée static GDBState gdbserver_state;
345842b42dfSAlex Bennée 
34636e067b2SAlex Bennée void gdb_init_gdbserver_state(void)
347842b42dfSAlex Bennée {
348842b42dfSAlex Bennée     g_assert(!gdbserver_state.init);
349842b42dfSAlex Bennée     memset(&gdbserver_state, 0, sizeof(GDBState));
350842b42dfSAlex Bennée     gdbserver_state.init = true;
351842b42dfSAlex Bennée     gdbserver_state.str_buf = g_string_new(NULL);
352842b42dfSAlex Bennée     gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
353842b42dfSAlex Bennée     gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
354842b42dfSAlex Bennée 
355842b42dfSAlex Bennée     /*
3563b7a9388SAlex Bennée      * What single-step modes are supported is accelerator dependent.
3573b7a9388SAlex Bennée      * By default try to use no IRQs and no timers while single
3583b7a9388SAlex Bennée      * stepping so as to make single stepping like a typical ICE HW step.
359842b42dfSAlex Bennée      */
3603b7a9388SAlex Bennée     gdbserver_state.supported_sstep_flags = accel_supported_gdbstub_sstep_flags();
361842b42dfSAlex Bennée     gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
362842b42dfSAlex Bennée     gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
363842b42dfSAlex Bennée }
364842b42dfSAlex Bennée 
365842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
366842b42dfSAlex Bennée static void reset_gdbserver_state(void)
367842b42dfSAlex Bennée {
368842b42dfSAlex Bennée     g_free(gdbserver_state.processes);
369842b42dfSAlex Bennée     gdbserver_state.processes = NULL;
370842b42dfSAlex Bennée     gdbserver_state.process_num = 0;
371842b42dfSAlex Bennée }
372842b42dfSAlex Bennée #endif
373842b42dfSAlex Bennée 
374842b42dfSAlex Bennée bool gdb_has_xml;
375842b42dfSAlex Bennée 
376842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
377842b42dfSAlex Bennée 
378842b42dfSAlex Bennée static int get_char(void)
379842b42dfSAlex Bennée {
380842b42dfSAlex Bennée     uint8_t ch;
381842b42dfSAlex Bennée     int ret;
382842b42dfSAlex Bennée 
383842b42dfSAlex Bennée     for(;;) {
3848e70c6f9SAlex Bennée         ret = recv(gdbserver_user_state.fd, &ch, 1, 0);
385842b42dfSAlex Bennée         if (ret < 0) {
3868e70c6f9SAlex Bennée             if (errno == ECONNRESET) {
3878e70c6f9SAlex Bennée                 gdbserver_user_state.fd = -1;
3888e70c6f9SAlex Bennée             }
3898e70c6f9SAlex Bennée             if (errno != EINTR) {
390842b42dfSAlex Bennée                 return -1;
3918e70c6f9SAlex Bennée             }
392842b42dfSAlex Bennée         } else if (ret == 0) {
3938e70c6f9SAlex Bennée             close(gdbserver_user_state.fd);
3948e70c6f9SAlex Bennée             gdbserver_user_state.fd = -1;
395842b42dfSAlex Bennée             return -1;
396842b42dfSAlex Bennée         } else {
397842b42dfSAlex Bennée             break;
398842b42dfSAlex Bennée         }
399842b42dfSAlex Bennée     }
400842b42dfSAlex Bennée     return ch;
401842b42dfSAlex Bennée }
402842b42dfSAlex Bennée #endif
403842b42dfSAlex Bennée 
404842b42dfSAlex Bennée /*
405842b42dfSAlex Bennée  * Return true if there is a GDB currently connected to the stub
406842b42dfSAlex Bennée  * and attached to a CPU
407842b42dfSAlex Bennée  */
408842b42dfSAlex Bennée static bool gdb_attached(void)
409842b42dfSAlex Bennée {
410842b42dfSAlex Bennée     return gdbserver_state.init && gdbserver_state.c_cpu;
411842b42dfSAlex Bennée }
412842b42dfSAlex Bennée 
413842b42dfSAlex Bennée static enum {
414842b42dfSAlex Bennée     GDB_SYS_UNKNOWN,
415842b42dfSAlex Bennée     GDB_SYS_ENABLED,
416842b42dfSAlex Bennée     GDB_SYS_DISABLED,
417842b42dfSAlex Bennée } gdb_syscall_mode;
418842b42dfSAlex Bennée 
419842b42dfSAlex Bennée /* Decide if either remote gdb syscalls or native file IO should be used. */
420842b42dfSAlex Bennée int use_gdb_syscalls(void)
421842b42dfSAlex Bennée {
422842b42dfSAlex Bennée     SemihostingTarget target = semihosting_get_target();
423842b42dfSAlex Bennée     if (target == SEMIHOSTING_TARGET_NATIVE) {
424842b42dfSAlex Bennée         /* -semihosting-config target=native */
425842b42dfSAlex Bennée         return false;
426842b42dfSAlex Bennée     } else if (target == SEMIHOSTING_TARGET_GDB) {
427842b42dfSAlex Bennée         /* -semihosting-config target=gdb */
428842b42dfSAlex Bennée         return true;
429842b42dfSAlex Bennée     }
430842b42dfSAlex Bennée 
431842b42dfSAlex Bennée     /* -semihosting-config target=auto */
432842b42dfSAlex Bennée     /* On the first call check if gdb is connected and remember. */
433842b42dfSAlex Bennée     if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
434842b42dfSAlex Bennée         gdb_syscall_mode = gdb_attached() ? GDB_SYS_ENABLED : GDB_SYS_DISABLED;
435842b42dfSAlex Bennée     }
436842b42dfSAlex Bennée     return gdb_syscall_mode == GDB_SYS_ENABLED;
437842b42dfSAlex Bennée }
438842b42dfSAlex Bennée 
439842b42dfSAlex Bennée static bool stub_can_reverse(void)
440842b42dfSAlex Bennée {
441842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
442842b42dfSAlex Bennée     return false;
443842b42dfSAlex Bennée #else
444842b42dfSAlex Bennée     return replay_mode == REPLAY_MODE_PLAY;
445842b42dfSAlex Bennée #endif
446842b42dfSAlex Bennée }
447842b42dfSAlex Bennée 
448842b42dfSAlex Bennée /* Resume execution.  */
449842b42dfSAlex Bennée static inline void gdb_continue(void)
450842b42dfSAlex Bennée {
451842b42dfSAlex Bennée 
452842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
4538e70c6f9SAlex Bennée     gdbserver_user_state.running_state = 1;
454842b42dfSAlex Bennée     trace_gdbstub_op_continue();
455842b42dfSAlex Bennée #else
456842b42dfSAlex Bennée     if (!runstate_needs_reset()) {
457842b42dfSAlex Bennée         trace_gdbstub_op_continue();
458842b42dfSAlex Bennée         vm_start();
459842b42dfSAlex Bennée     }
460842b42dfSAlex Bennée #endif
461842b42dfSAlex Bennée }
462842b42dfSAlex Bennée 
463842b42dfSAlex Bennée /*
464842b42dfSAlex Bennée  * Resume execution, per CPU actions. For user-mode emulation it's
465842b42dfSAlex Bennée  * equivalent to gdb_continue.
466842b42dfSAlex Bennée  */
467842b42dfSAlex Bennée static int gdb_continue_partial(char *newstates)
468842b42dfSAlex Bennée {
469842b42dfSAlex Bennée     CPUState *cpu;
470842b42dfSAlex Bennée     int res = 0;
471842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
472842b42dfSAlex Bennée     /*
473842b42dfSAlex Bennée      * This is not exactly accurate, but it's an improvement compared to the
474842b42dfSAlex Bennée      * previous situation, where only one CPU would be single-stepped.
475842b42dfSAlex Bennée      */
476842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
477842b42dfSAlex Bennée         if (newstates[cpu->cpu_index] == 's') {
478842b42dfSAlex Bennée             trace_gdbstub_op_stepping(cpu->cpu_index);
479842b42dfSAlex Bennée             cpu_single_step(cpu, gdbserver_state.sstep_flags);
480842b42dfSAlex Bennée         }
481842b42dfSAlex Bennée     }
4828e70c6f9SAlex Bennée     gdbserver_user_state.running_state = 1;
483842b42dfSAlex Bennée #else
484842b42dfSAlex Bennée     int flag = 0;
485842b42dfSAlex Bennée 
486842b42dfSAlex Bennée     if (!runstate_needs_reset()) {
487842b42dfSAlex Bennée         bool step_requested = false;
488842b42dfSAlex Bennée         CPU_FOREACH(cpu) {
489842b42dfSAlex Bennée             if (newstates[cpu->cpu_index] == 's') {
490842b42dfSAlex Bennée                 step_requested = true;
491842b42dfSAlex Bennée                 break;
492842b42dfSAlex Bennée             }
493842b42dfSAlex Bennée         }
494842b42dfSAlex Bennée 
495842b42dfSAlex Bennée         if (vm_prepare_start(step_requested)) {
496842b42dfSAlex Bennée             return 0;
497842b42dfSAlex Bennée         }
498842b42dfSAlex Bennée 
499842b42dfSAlex Bennée         CPU_FOREACH(cpu) {
500842b42dfSAlex Bennée             switch (newstates[cpu->cpu_index]) {
501842b42dfSAlex Bennée             case 0:
502842b42dfSAlex Bennée             case 1:
503842b42dfSAlex Bennée                 break; /* nothing to do here */
504842b42dfSAlex Bennée             case 's':
505842b42dfSAlex Bennée                 trace_gdbstub_op_stepping(cpu->cpu_index);
506842b42dfSAlex Bennée                 cpu_single_step(cpu, gdbserver_state.sstep_flags);
507842b42dfSAlex Bennée                 cpu_resume(cpu);
508842b42dfSAlex Bennée                 flag = 1;
509842b42dfSAlex Bennée                 break;
510842b42dfSAlex Bennée             case 'c':
511842b42dfSAlex Bennée                 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
512842b42dfSAlex Bennée                 cpu_resume(cpu);
513842b42dfSAlex Bennée                 flag = 1;
514842b42dfSAlex Bennée                 break;
515842b42dfSAlex Bennée             default:
516842b42dfSAlex Bennée                 res = -1;
517842b42dfSAlex Bennée                 break;
518842b42dfSAlex Bennée             }
519842b42dfSAlex Bennée         }
520842b42dfSAlex Bennée     }
521842b42dfSAlex Bennée     if (flag) {
522842b42dfSAlex Bennée         qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
523842b42dfSAlex Bennée     }
524842b42dfSAlex Bennée #endif
525842b42dfSAlex Bennée     return res;
526842b42dfSAlex Bennée }
527842b42dfSAlex Bennée 
52836e067b2SAlex Bennée void gdb_put_buffer(const uint8_t *buf, int len)
529842b42dfSAlex Bennée {
530842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
531842b42dfSAlex Bennée     int ret;
532842b42dfSAlex Bennée 
533842b42dfSAlex Bennée     while (len > 0) {
5348e70c6f9SAlex Bennée         ret = send(gdbserver_user_state.fd, buf, len, 0);
535842b42dfSAlex Bennée         if (ret < 0) {
536842b42dfSAlex Bennée             if (errno != EINTR)
537842b42dfSAlex Bennée                 return;
538842b42dfSAlex Bennée         } else {
539842b42dfSAlex Bennée             buf += ret;
540842b42dfSAlex Bennée             len -= ret;
541842b42dfSAlex Bennée         }
542842b42dfSAlex Bennée     }
543842b42dfSAlex Bennée #else
544842b42dfSAlex Bennée     /* XXX this blocks entire thread. Rewrite to use
545842b42dfSAlex Bennée      * qemu_chr_fe_write and background I/O callbacks */
5468e70c6f9SAlex Bennée     qemu_chr_fe_write_all(&gdbserver_system_state.chr, buf, len);
547842b42dfSAlex Bennée #endif
548842b42dfSAlex Bennée }
549842b42dfSAlex Bennée 
550842b42dfSAlex Bennée /* writes 2*len+1 bytes in buf */
55136e067b2SAlex Bennée void gdb_memtohex(GString *buf, const uint8_t *mem, int len)
552842b42dfSAlex Bennée {
553842b42dfSAlex Bennée     int i, c;
554842b42dfSAlex Bennée     for(i = 0; i < len; i++) {
555842b42dfSAlex Bennée         c = mem[i];
556842b42dfSAlex Bennée         g_string_append_c(buf, tohex(c >> 4));
557842b42dfSAlex Bennée         g_string_append_c(buf, tohex(c & 0xf));
558842b42dfSAlex Bennée     }
559842b42dfSAlex Bennée     g_string_append_c(buf, '\0');
560842b42dfSAlex Bennée }
561842b42dfSAlex Bennée 
56236e067b2SAlex Bennée void gdb_hextomem(GByteArray *mem, const char *buf, int len)
563842b42dfSAlex Bennée {
564842b42dfSAlex Bennée     int i;
565842b42dfSAlex Bennée 
566842b42dfSAlex Bennée     for(i = 0; i < len; i++) {
567842b42dfSAlex Bennée         guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
568842b42dfSAlex Bennée         g_byte_array_append(mem, &byte, 1);
569842b42dfSAlex Bennée         buf += 2;
570842b42dfSAlex Bennée     }
571842b42dfSAlex Bennée }
572842b42dfSAlex Bennée 
573842b42dfSAlex Bennée static void hexdump(const char *buf, int len,
574842b42dfSAlex Bennée                     void (*trace_fn)(size_t ofs, char const *text))
575842b42dfSAlex Bennée {
576842b42dfSAlex Bennée     char line_buffer[3 * 16 + 4 + 16 + 1];
577842b42dfSAlex Bennée 
578842b42dfSAlex Bennée     size_t i;
579842b42dfSAlex Bennée     for (i = 0; i < len || (i & 0xF); ++i) {
580842b42dfSAlex Bennée         size_t byte_ofs = i & 15;
581842b42dfSAlex Bennée 
582842b42dfSAlex Bennée         if (byte_ofs == 0) {
583842b42dfSAlex Bennée             memset(line_buffer, ' ', 3 * 16 + 4 + 16);
584842b42dfSAlex Bennée             line_buffer[3 * 16 + 4 + 16] = 0;
585842b42dfSAlex Bennée         }
586842b42dfSAlex Bennée 
587842b42dfSAlex Bennée         size_t col_group = (i >> 2) & 3;
588842b42dfSAlex Bennée         size_t hex_col = byte_ofs * 3 + col_group;
589842b42dfSAlex Bennée         size_t txt_col = 3 * 16 + 4 + byte_ofs;
590842b42dfSAlex Bennée 
591842b42dfSAlex Bennée         if (i < len) {
592842b42dfSAlex Bennée             char value = buf[i];
593842b42dfSAlex Bennée 
594842b42dfSAlex Bennée             line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
595842b42dfSAlex Bennée             line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
596842b42dfSAlex Bennée             line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
597842b42dfSAlex Bennée                     ? value
598842b42dfSAlex Bennée                     : '.';
599842b42dfSAlex Bennée         }
600842b42dfSAlex Bennée 
601842b42dfSAlex Bennée         if (byte_ofs == 0xF)
602842b42dfSAlex Bennée             trace_fn(i & -16, line_buffer);
603842b42dfSAlex Bennée     }
604842b42dfSAlex Bennée }
605842b42dfSAlex Bennée 
606842b42dfSAlex Bennée /* return -1 if error, 0 if OK */
60736e067b2SAlex Bennée int gdb_put_packet_binary(const char *buf, int len, bool dump)
608842b42dfSAlex Bennée {
609842b42dfSAlex Bennée     int csum, i;
610842b42dfSAlex Bennée     uint8_t footer[3];
611842b42dfSAlex Bennée 
612842b42dfSAlex Bennée     if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
613842b42dfSAlex Bennée         hexdump(buf, len, trace_gdbstub_io_binaryreply);
614842b42dfSAlex Bennée     }
615842b42dfSAlex Bennée 
616842b42dfSAlex Bennée     for(;;) {
617842b42dfSAlex Bennée         g_byte_array_set_size(gdbserver_state.last_packet, 0);
618842b42dfSAlex Bennée         g_byte_array_append(gdbserver_state.last_packet,
619842b42dfSAlex Bennée                             (const uint8_t *) "$", 1);
620842b42dfSAlex Bennée         g_byte_array_append(gdbserver_state.last_packet,
621842b42dfSAlex Bennée                             (const uint8_t *) buf, len);
622842b42dfSAlex Bennée         csum = 0;
623842b42dfSAlex Bennée         for(i = 0; i < len; i++) {
624842b42dfSAlex Bennée             csum += buf[i];
625842b42dfSAlex Bennée         }
626842b42dfSAlex Bennée         footer[0] = '#';
627842b42dfSAlex Bennée         footer[1] = tohex((csum >> 4) & 0xf);
628842b42dfSAlex Bennée         footer[2] = tohex((csum) & 0xf);
629842b42dfSAlex Bennée         g_byte_array_append(gdbserver_state.last_packet, footer, 3);
630842b42dfSAlex Bennée 
63136e067b2SAlex Bennée         gdb_put_buffer(gdbserver_state.last_packet->data,
632842b42dfSAlex Bennée                    gdbserver_state.last_packet->len);
633842b42dfSAlex Bennée 
634842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
635842b42dfSAlex Bennée         i = get_char();
636842b42dfSAlex Bennée         if (i < 0)
637842b42dfSAlex Bennée             return -1;
638842b42dfSAlex Bennée         if (i == '+')
639842b42dfSAlex Bennée             break;
640842b42dfSAlex Bennée #else
641842b42dfSAlex Bennée         break;
642842b42dfSAlex Bennée #endif
643842b42dfSAlex Bennée     }
644842b42dfSAlex Bennée     return 0;
645842b42dfSAlex Bennée }
646842b42dfSAlex Bennée 
647842b42dfSAlex Bennée /* return -1 if error, 0 if OK */
64836e067b2SAlex Bennée int gdb_put_packet(const char *buf)
649842b42dfSAlex Bennée {
650842b42dfSAlex Bennée     trace_gdbstub_io_reply(buf);
651842b42dfSAlex Bennée 
65236e067b2SAlex Bennée     return gdb_put_packet_binary(buf, strlen(buf), false);
653842b42dfSAlex Bennée }
654842b42dfSAlex Bennée 
65536e067b2SAlex Bennée void gdb_put_strbuf(void)
656842b42dfSAlex Bennée {
65736e067b2SAlex Bennée     gdb_put_packet(gdbserver_state.str_buf->str);
658842b42dfSAlex Bennée }
659842b42dfSAlex Bennée 
660842b42dfSAlex Bennée /* Encode data using the encoding for 'x' packets.  */
66136e067b2SAlex Bennée void gdb_memtox(GString *buf, const char *mem, int len)
662842b42dfSAlex Bennée {
663842b42dfSAlex Bennée     char c;
664842b42dfSAlex Bennée 
665842b42dfSAlex Bennée     while (len--) {
666842b42dfSAlex Bennée         c = *(mem++);
667842b42dfSAlex Bennée         switch (c) {
668842b42dfSAlex Bennée         case '#': case '$': case '*': case '}':
669842b42dfSAlex Bennée             g_string_append_c(buf, '}');
670842b42dfSAlex Bennée             g_string_append_c(buf, c ^ 0x20);
671842b42dfSAlex Bennée             break;
672842b42dfSAlex Bennée         default:
673842b42dfSAlex Bennée             g_string_append_c(buf, c);
674842b42dfSAlex Bennée             break;
675842b42dfSAlex Bennée         }
676842b42dfSAlex Bennée     }
677842b42dfSAlex Bennée }
678842b42dfSAlex Bennée 
679842b42dfSAlex Bennée static uint32_t gdb_get_cpu_pid(CPUState *cpu)
680842b42dfSAlex Bennée {
681842b42dfSAlex Bennée     /* TODO: In user mode, we should use the task state PID */
682842b42dfSAlex Bennée     if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
683842b42dfSAlex Bennée         /* Return the default process' PID */
684842b42dfSAlex Bennée         int index = gdbserver_state.process_num - 1;
685842b42dfSAlex Bennée         return gdbserver_state.processes[index].pid;
686842b42dfSAlex Bennée     }
687842b42dfSAlex Bennée     return cpu->cluster_index + 1;
688842b42dfSAlex Bennée }
689842b42dfSAlex Bennée 
690842b42dfSAlex Bennée static GDBProcess *gdb_get_process(uint32_t pid)
691842b42dfSAlex Bennée {
692842b42dfSAlex Bennée     int i;
693842b42dfSAlex Bennée 
694842b42dfSAlex Bennée     if (!pid) {
695842b42dfSAlex Bennée         /* 0 means any process, we take the first one */
696842b42dfSAlex Bennée         return &gdbserver_state.processes[0];
697842b42dfSAlex Bennée     }
698842b42dfSAlex Bennée 
699842b42dfSAlex Bennée     for (i = 0; i < gdbserver_state.process_num; i++) {
700842b42dfSAlex Bennée         if (gdbserver_state.processes[i].pid == pid) {
701842b42dfSAlex Bennée             return &gdbserver_state.processes[i];
702842b42dfSAlex Bennée         }
703842b42dfSAlex Bennée     }
704842b42dfSAlex Bennée 
705842b42dfSAlex Bennée     return NULL;
706842b42dfSAlex Bennée }
707842b42dfSAlex Bennée 
708842b42dfSAlex Bennée static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
709842b42dfSAlex Bennée {
710842b42dfSAlex Bennée     return gdb_get_process(gdb_get_cpu_pid(cpu));
711842b42dfSAlex Bennée }
712842b42dfSAlex Bennée 
713842b42dfSAlex Bennée static CPUState *find_cpu(uint32_t thread_id)
714842b42dfSAlex Bennée {
715842b42dfSAlex Bennée     CPUState *cpu;
716842b42dfSAlex Bennée 
717842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
71836e067b2SAlex Bennée         if (gdb_get_cpu_index(cpu) == thread_id) {
719842b42dfSAlex Bennée             return cpu;
720842b42dfSAlex Bennée         }
721842b42dfSAlex Bennée     }
722842b42dfSAlex Bennée 
723842b42dfSAlex Bennée     return NULL;
724842b42dfSAlex Bennée }
725842b42dfSAlex Bennée 
726842b42dfSAlex Bennée static CPUState *get_first_cpu_in_process(GDBProcess *process)
727842b42dfSAlex Bennée {
728842b42dfSAlex Bennée     CPUState *cpu;
729842b42dfSAlex Bennée 
730842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
731842b42dfSAlex Bennée         if (gdb_get_cpu_pid(cpu) == process->pid) {
732842b42dfSAlex Bennée             return cpu;
733842b42dfSAlex Bennée         }
734842b42dfSAlex Bennée     }
735842b42dfSAlex Bennée 
736842b42dfSAlex Bennée     return NULL;
737842b42dfSAlex Bennée }
738842b42dfSAlex Bennée 
739842b42dfSAlex Bennée static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
740842b42dfSAlex Bennée {
741842b42dfSAlex Bennée     uint32_t pid = gdb_get_cpu_pid(cpu);
742842b42dfSAlex Bennée     cpu = CPU_NEXT(cpu);
743842b42dfSAlex Bennée 
744842b42dfSAlex Bennée     while (cpu) {
745842b42dfSAlex Bennée         if (gdb_get_cpu_pid(cpu) == pid) {
746842b42dfSAlex Bennée             break;
747842b42dfSAlex Bennée         }
748842b42dfSAlex Bennée 
749842b42dfSAlex Bennée         cpu = CPU_NEXT(cpu);
750842b42dfSAlex Bennée     }
751842b42dfSAlex Bennée 
752842b42dfSAlex Bennée     return cpu;
753842b42dfSAlex Bennée }
754842b42dfSAlex Bennée 
755842b42dfSAlex Bennée /* Return the cpu following @cpu, while ignoring unattached processes. */
756842b42dfSAlex Bennée static CPUState *gdb_next_attached_cpu(CPUState *cpu)
757842b42dfSAlex Bennée {
758842b42dfSAlex Bennée     cpu = CPU_NEXT(cpu);
759842b42dfSAlex Bennée 
760842b42dfSAlex Bennée     while (cpu) {
761842b42dfSAlex Bennée         if (gdb_get_cpu_process(cpu)->attached) {
762842b42dfSAlex Bennée             break;
763842b42dfSAlex Bennée         }
764842b42dfSAlex Bennée 
765842b42dfSAlex Bennée         cpu = CPU_NEXT(cpu);
766842b42dfSAlex Bennée     }
767842b42dfSAlex Bennée 
768842b42dfSAlex Bennée     return cpu;
769842b42dfSAlex Bennée }
770842b42dfSAlex Bennée 
771842b42dfSAlex Bennée /* Return the first attached cpu */
77236e067b2SAlex Bennée CPUState *gdb_first_attached_cpu(void)
773842b42dfSAlex Bennée {
774842b42dfSAlex Bennée     CPUState *cpu = first_cpu;
775842b42dfSAlex Bennée     GDBProcess *process = gdb_get_cpu_process(cpu);
776842b42dfSAlex Bennée 
777842b42dfSAlex Bennée     if (!process->attached) {
778842b42dfSAlex Bennée         return gdb_next_attached_cpu(cpu);
779842b42dfSAlex Bennée     }
780842b42dfSAlex Bennée 
781842b42dfSAlex Bennée     return cpu;
782842b42dfSAlex Bennée }
783842b42dfSAlex Bennée 
784842b42dfSAlex Bennée static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
785842b42dfSAlex Bennée {
786842b42dfSAlex Bennée     GDBProcess *process;
787842b42dfSAlex Bennée     CPUState *cpu;
788842b42dfSAlex Bennée 
789842b42dfSAlex Bennée     if (!pid && !tid) {
790842b42dfSAlex Bennée         /* 0 means any process/thread, we take the first attached one */
791842b42dfSAlex Bennée         return gdb_first_attached_cpu();
792842b42dfSAlex Bennée     } else if (pid && !tid) {
793842b42dfSAlex Bennée         /* any thread in a specific process */
794842b42dfSAlex Bennée         process = gdb_get_process(pid);
795842b42dfSAlex Bennée 
796842b42dfSAlex Bennée         if (process == NULL) {
797842b42dfSAlex Bennée             return NULL;
798842b42dfSAlex Bennée         }
799842b42dfSAlex Bennée 
800842b42dfSAlex Bennée         if (!process->attached) {
801842b42dfSAlex Bennée             return NULL;
802842b42dfSAlex Bennée         }
803842b42dfSAlex Bennée 
804842b42dfSAlex Bennée         return get_first_cpu_in_process(process);
805842b42dfSAlex Bennée     } else {
806842b42dfSAlex Bennée         /* a specific thread */
807842b42dfSAlex Bennée         cpu = find_cpu(tid);
808842b42dfSAlex Bennée 
809842b42dfSAlex Bennée         if (cpu == NULL) {
810842b42dfSAlex Bennée             return NULL;
811842b42dfSAlex Bennée         }
812842b42dfSAlex Bennée 
813842b42dfSAlex Bennée         process = gdb_get_cpu_process(cpu);
814842b42dfSAlex Bennée 
815842b42dfSAlex Bennée         if (pid && process->pid != pid) {
816842b42dfSAlex Bennée             return NULL;
817842b42dfSAlex Bennée         }
818842b42dfSAlex Bennée 
819842b42dfSAlex Bennée         if (!process->attached) {
820842b42dfSAlex Bennée             return NULL;
821842b42dfSAlex Bennée         }
822842b42dfSAlex Bennée 
823842b42dfSAlex Bennée         return cpu;
824842b42dfSAlex Bennée     }
825842b42dfSAlex Bennée }
826842b42dfSAlex Bennée 
827842b42dfSAlex Bennée static const char *get_feature_xml(const char *p, const char **newp,
828842b42dfSAlex Bennée                                    GDBProcess *process)
829842b42dfSAlex Bennée {
830842b42dfSAlex Bennée     size_t len;
831842b42dfSAlex Bennée     int i;
832842b42dfSAlex Bennée     const char *name;
833842b42dfSAlex Bennée     CPUState *cpu = get_first_cpu_in_process(process);
834842b42dfSAlex Bennée     CPUClass *cc = CPU_GET_CLASS(cpu);
835842b42dfSAlex Bennée 
836842b42dfSAlex Bennée     len = 0;
837842b42dfSAlex Bennée     while (p[len] && p[len] != ':')
838842b42dfSAlex Bennée         len++;
839842b42dfSAlex Bennée     *newp = p + len;
840842b42dfSAlex Bennée 
841842b42dfSAlex Bennée     name = NULL;
842842b42dfSAlex Bennée     if (strncmp(p, "target.xml", len) == 0) {
843842b42dfSAlex Bennée         char *buf = process->target_xml;
844842b42dfSAlex Bennée         const size_t buf_sz = sizeof(process->target_xml);
845842b42dfSAlex Bennée 
846842b42dfSAlex Bennée         /* Generate the XML description for this CPU.  */
847842b42dfSAlex Bennée         if (!buf[0]) {
848842b42dfSAlex Bennée             GDBRegisterState *r;
849842b42dfSAlex Bennée 
850842b42dfSAlex Bennée             pstrcat(buf, buf_sz,
851842b42dfSAlex Bennée                     "<?xml version=\"1.0\"?>"
852842b42dfSAlex Bennée                     "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
853842b42dfSAlex Bennée                     "<target>");
854842b42dfSAlex Bennée             if (cc->gdb_arch_name) {
855842b42dfSAlex Bennée                 gchar *arch = cc->gdb_arch_name(cpu);
856842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, "<architecture>");
857842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, arch);
858842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, "</architecture>");
859842b42dfSAlex Bennée                 g_free(arch);
860842b42dfSAlex Bennée             }
861842b42dfSAlex Bennée             pstrcat(buf, buf_sz, "<xi:include href=\"");
862842b42dfSAlex Bennée             pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
863842b42dfSAlex Bennée             pstrcat(buf, buf_sz, "\"/>");
864842b42dfSAlex Bennée             for (r = cpu->gdb_regs; r; r = r->next) {
865842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, "<xi:include href=\"");
866842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, r->xml);
867842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, "\"/>");
868842b42dfSAlex Bennée             }
869842b42dfSAlex Bennée             pstrcat(buf, buf_sz, "</target>");
870842b42dfSAlex Bennée         }
871842b42dfSAlex Bennée         return buf;
872842b42dfSAlex Bennée     }
873842b42dfSAlex Bennée     if (cc->gdb_get_dynamic_xml) {
874842b42dfSAlex Bennée         char *xmlname = g_strndup(p, len);
875842b42dfSAlex Bennée         const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
876842b42dfSAlex Bennée 
877842b42dfSAlex Bennée         g_free(xmlname);
878842b42dfSAlex Bennée         if (xml) {
879842b42dfSAlex Bennée             return xml;
880842b42dfSAlex Bennée         }
881842b42dfSAlex Bennée     }
882842b42dfSAlex Bennée     for (i = 0; ; i++) {
883842b42dfSAlex Bennée         name = xml_builtin[i][0];
884842b42dfSAlex Bennée         if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
885842b42dfSAlex Bennée             break;
886842b42dfSAlex Bennée     }
887842b42dfSAlex Bennée     return name ? xml_builtin[i][1] : NULL;
888842b42dfSAlex Bennée }
889842b42dfSAlex Bennée 
890842b42dfSAlex Bennée static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
891842b42dfSAlex Bennée {
892842b42dfSAlex Bennée     CPUClass *cc = CPU_GET_CLASS(cpu);
893842b42dfSAlex Bennée     CPUArchState *env = cpu->env_ptr;
894842b42dfSAlex Bennée     GDBRegisterState *r;
895842b42dfSAlex Bennée 
896842b42dfSAlex Bennée     if (reg < cc->gdb_num_core_regs) {
897842b42dfSAlex Bennée         return cc->gdb_read_register(cpu, buf, reg);
898842b42dfSAlex Bennée     }
899842b42dfSAlex Bennée 
900842b42dfSAlex Bennée     for (r = cpu->gdb_regs; r; r = r->next) {
901842b42dfSAlex Bennée         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
902842b42dfSAlex Bennée             return r->get_reg(env, buf, reg - r->base_reg);
903842b42dfSAlex Bennée         }
904842b42dfSAlex Bennée     }
905842b42dfSAlex Bennée     return 0;
906842b42dfSAlex Bennée }
907842b42dfSAlex Bennée 
908842b42dfSAlex Bennée static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
909842b42dfSAlex Bennée {
910842b42dfSAlex Bennée     CPUClass *cc = CPU_GET_CLASS(cpu);
911842b42dfSAlex Bennée     CPUArchState *env = cpu->env_ptr;
912842b42dfSAlex Bennée     GDBRegisterState *r;
913842b42dfSAlex Bennée 
914842b42dfSAlex Bennée     if (reg < cc->gdb_num_core_regs) {
915842b42dfSAlex Bennée         return cc->gdb_write_register(cpu, mem_buf, reg);
916842b42dfSAlex Bennée     }
917842b42dfSAlex Bennée 
918842b42dfSAlex Bennée     for (r = cpu->gdb_regs; r; r = r->next) {
919842b42dfSAlex Bennée         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
920842b42dfSAlex Bennée             return r->set_reg(env, mem_buf, reg - r->base_reg);
921842b42dfSAlex Bennée         }
922842b42dfSAlex Bennée     }
923842b42dfSAlex Bennée     return 0;
924842b42dfSAlex Bennée }
925842b42dfSAlex Bennée 
926842b42dfSAlex Bennée /* Register a supplemental set of CPU registers.  If g_pos is nonzero it
927842b42dfSAlex Bennée    specifies the first register number and these registers are included in
928842b42dfSAlex Bennée    a standard "g" packet.  Direction is relative to gdb, i.e. get_reg is
929842b42dfSAlex Bennée    gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
930842b42dfSAlex Bennée  */
931842b42dfSAlex Bennée 
932842b42dfSAlex Bennée void gdb_register_coprocessor(CPUState *cpu,
933842b42dfSAlex Bennée                               gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
934842b42dfSAlex Bennée                               int num_regs, const char *xml, int g_pos)
935842b42dfSAlex Bennée {
936842b42dfSAlex Bennée     GDBRegisterState *s;
937842b42dfSAlex Bennée     GDBRegisterState **p;
938842b42dfSAlex Bennée 
939842b42dfSAlex Bennée     p = &cpu->gdb_regs;
940842b42dfSAlex Bennée     while (*p) {
941842b42dfSAlex Bennée         /* Check for duplicates.  */
942842b42dfSAlex Bennée         if (strcmp((*p)->xml, xml) == 0)
943842b42dfSAlex Bennée             return;
944842b42dfSAlex Bennée         p = &(*p)->next;
945842b42dfSAlex Bennée     }
946842b42dfSAlex Bennée 
947842b42dfSAlex Bennée     s = g_new0(GDBRegisterState, 1);
948842b42dfSAlex Bennée     s->base_reg = cpu->gdb_num_regs;
949842b42dfSAlex Bennée     s->num_regs = num_regs;
950842b42dfSAlex Bennée     s->get_reg = get_reg;
951842b42dfSAlex Bennée     s->set_reg = set_reg;
952842b42dfSAlex Bennée     s->xml = xml;
953842b42dfSAlex Bennée 
954842b42dfSAlex Bennée     /* Add to end of list.  */
955842b42dfSAlex Bennée     cpu->gdb_num_regs += num_regs;
956842b42dfSAlex Bennée     *p = s;
957842b42dfSAlex Bennée     if (g_pos) {
958842b42dfSAlex Bennée         if (g_pos != s->base_reg) {
959842b42dfSAlex Bennée             error_report("Error: Bad gdb register numbering for '%s', "
960842b42dfSAlex Bennée                          "expected %d got %d", xml, g_pos, s->base_reg);
961842b42dfSAlex Bennée         } else {
962842b42dfSAlex Bennée             cpu->gdb_num_g_regs = cpu->gdb_num_regs;
963842b42dfSAlex Bennée         }
964842b42dfSAlex Bennée     }
965842b42dfSAlex Bennée }
966842b42dfSAlex Bennée 
967842b42dfSAlex Bennée static void gdb_process_breakpoint_remove_all(GDBProcess *p)
968842b42dfSAlex Bennée {
969842b42dfSAlex Bennée     CPUState *cpu = get_first_cpu_in_process(p);
970842b42dfSAlex Bennée 
971842b42dfSAlex Bennée     while (cpu) {
972ae7467b1SAlex Bennée         gdb_breakpoint_remove_all(cpu);
973842b42dfSAlex Bennée         cpu = gdb_next_cpu_in_process(cpu);
974842b42dfSAlex Bennée     }
975842b42dfSAlex Bennée }
976842b42dfSAlex Bennée 
977842b42dfSAlex Bennée 
978842b42dfSAlex Bennée static void gdb_set_cpu_pc(target_ulong pc)
979842b42dfSAlex Bennée {
980842b42dfSAlex Bennée     CPUState *cpu = gdbserver_state.c_cpu;
981842b42dfSAlex Bennée 
982842b42dfSAlex Bennée     cpu_synchronize_state(cpu);
983842b42dfSAlex Bennée     cpu_set_pc(cpu, pc);
984842b42dfSAlex Bennée }
985842b42dfSAlex Bennée 
98636e067b2SAlex Bennée void gdb_append_thread_id(CPUState *cpu, GString *buf)
987842b42dfSAlex Bennée {
988842b42dfSAlex Bennée     if (gdbserver_state.multiprocess) {
989842b42dfSAlex Bennée         g_string_append_printf(buf, "p%02x.%02x",
99036e067b2SAlex Bennée                                gdb_get_cpu_pid(cpu), gdb_get_cpu_index(cpu));
991842b42dfSAlex Bennée     } else {
99236e067b2SAlex Bennée         g_string_append_printf(buf, "%02x", gdb_get_cpu_index(cpu));
993842b42dfSAlex Bennée     }
994842b42dfSAlex Bennée }
995842b42dfSAlex Bennée 
996842b42dfSAlex Bennée typedef enum GDBThreadIdKind {
997842b42dfSAlex Bennée     GDB_ONE_THREAD = 0,
998842b42dfSAlex Bennée     GDB_ALL_THREADS,     /* One process, all threads */
999842b42dfSAlex Bennée     GDB_ALL_PROCESSES,
1000842b42dfSAlex Bennée     GDB_READ_THREAD_ERR
1001842b42dfSAlex Bennée } GDBThreadIdKind;
1002842b42dfSAlex Bennée 
1003842b42dfSAlex Bennée static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
1004842b42dfSAlex Bennée                                       uint32_t *pid, uint32_t *tid)
1005842b42dfSAlex Bennée {
1006842b42dfSAlex Bennée     unsigned long p, t;
1007842b42dfSAlex Bennée     int ret;
1008842b42dfSAlex Bennée 
1009842b42dfSAlex Bennée     if (*buf == 'p') {
1010842b42dfSAlex Bennée         buf++;
1011842b42dfSAlex Bennée         ret = qemu_strtoul(buf, &buf, 16, &p);
1012842b42dfSAlex Bennée 
1013842b42dfSAlex Bennée         if (ret) {
1014842b42dfSAlex Bennée             return GDB_READ_THREAD_ERR;
1015842b42dfSAlex Bennée         }
1016842b42dfSAlex Bennée 
1017842b42dfSAlex Bennée         /* Skip '.' */
1018842b42dfSAlex Bennée         buf++;
1019842b42dfSAlex Bennée     } else {
1020842b42dfSAlex Bennée         p = 1;
1021842b42dfSAlex Bennée     }
1022842b42dfSAlex Bennée 
1023842b42dfSAlex Bennée     ret = qemu_strtoul(buf, &buf, 16, &t);
1024842b42dfSAlex Bennée 
1025842b42dfSAlex Bennée     if (ret) {
1026842b42dfSAlex Bennée         return GDB_READ_THREAD_ERR;
1027842b42dfSAlex Bennée     }
1028842b42dfSAlex Bennée 
1029842b42dfSAlex Bennée     *end_buf = buf;
1030842b42dfSAlex Bennée 
1031842b42dfSAlex Bennée     if (p == -1) {
1032842b42dfSAlex Bennée         return GDB_ALL_PROCESSES;
1033842b42dfSAlex Bennée     }
1034842b42dfSAlex Bennée 
1035842b42dfSAlex Bennée     if (pid) {
1036842b42dfSAlex Bennée         *pid = p;
1037842b42dfSAlex Bennée     }
1038842b42dfSAlex Bennée 
1039842b42dfSAlex Bennée     if (t == -1) {
1040842b42dfSAlex Bennée         return GDB_ALL_THREADS;
1041842b42dfSAlex Bennée     }
1042842b42dfSAlex Bennée 
1043842b42dfSAlex Bennée     if (tid) {
1044842b42dfSAlex Bennée         *tid = t;
1045842b42dfSAlex Bennée     }
1046842b42dfSAlex Bennée 
1047842b42dfSAlex Bennée     return GDB_ONE_THREAD;
1048842b42dfSAlex Bennée }
1049842b42dfSAlex Bennée 
1050842b42dfSAlex Bennée /**
1051842b42dfSAlex Bennée  * gdb_handle_vcont - Parses and handles a vCont packet.
1052842b42dfSAlex Bennée  * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1053842b42dfSAlex Bennée  *         a format error, 0 on success.
1054842b42dfSAlex Bennée  */
1055842b42dfSAlex Bennée static int gdb_handle_vcont(const char *p)
1056842b42dfSAlex Bennée {
1057842b42dfSAlex Bennée     int res, signal = 0;
1058842b42dfSAlex Bennée     char cur_action;
1059842b42dfSAlex Bennée     char *newstates;
1060842b42dfSAlex Bennée     unsigned long tmp;
1061842b42dfSAlex Bennée     uint32_t pid, tid;
1062842b42dfSAlex Bennée     GDBProcess *process;
1063842b42dfSAlex Bennée     CPUState *cpu;
1064842b42dfSAlex Bennée     GDBThreadIdKind kind;
1065842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
1066842b42dfSAlex Bennée     int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1067842b42dfSAlex Bennée 
1068842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
1069842b42dfSAlex Bennée         max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1070842b42dfSAlex Bennée     }
1071842b42dfSAlex Bennée #else
1072842b42dfSAlex Bennée     MachineState *ms = MACHINE(qdev_get_machine());
1073842b42dfSAlex Bennée     unsigned int max_cpus = ms->smp.max_cpus;
1074842b42dfSAlex Bennée #endif
1075842b42dfSAlex Bennée     /* uninitialised CPUs stay 0 */
1076842b42dfSAlex Bennée     newstates = g_new0(char, max_cpus);
1077842b42dfSAlex Bennée 
1078842b42dfSAlex Bennée     /* mark valid CPUs with 1 */
1079842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
1080842b42dfSAlex Bennée         newstates[cpu->cpu_index] = 1;
1081842b42dfSAlex Bennée     }
1082842b42dfSAlex Bennée 
1083842b42dfSAlex Bennée     /*
1084842b42dfSAlex Bennée      * res keeps track of what error we are returning, with -ENOTSUP meaning
1085842b42dfSAlex Bennée      * that the command is unknown or unsupported, thus returning an empty
1086842b42dfSAlex Bennée      * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1087842b42dfSAlex Bennée      *  or incorrect parameters passed.
1088842b42dfSAlex Bennée      */
1089842b42dfSAlex Bennée     res = 0;
1090842b42dfSAlex Bennée     while (*p) {
1091842b42dfSAlex Bennée         if (*p++ != ';') {
1092842b42dfSAlex Bennée             res = -ENOTSUP;
1093842b42dfSAlex Bennée             goto out;
1094842b42dfSAlex Bennée         }
1095842b42dfSAlex Bennée 
1096842b42dfSAlex Bennée         cur_action = *p++;
1097842b42dfSAlex Bennée         if (cur_action == 'C' || cur_action == 'S') {
1098842b42dfSAlex Bennée             cur_action = qemu_tolower(cur_action);
1099842b42dfSAlex Bennée             res = qemu_strtoul(p, &p, 16, &tmp);
1100842b42dfSAlex Bennée             if (res) {
1101842b42dfSAlex Bennée                 goto out;
1102842b42dfSAlex Bennée             }
1103842b42dfSAlex Bennée             signal = gdb_signal_to_target(tmp);
1104842b42dfSAlex Bennée         } else if (cur_action != 'c' && cur_action != 's') {
1105842b42dfSAlex Bennée             /* unknown/invalid/unsupported command */
1106842b42dfSAlex Bennée             res = -ENOTSUP;
1107842b42dfSAlex Bennée             goto out;
1108842b42dfSAlex Bennée         }
1109842b42dfSAlex Bennée 
1110842b42dfSAlex Bennée         if (*p == '\0' || *p == ';') {
1111842b42dfSAlex Bennée             /*
1112842b42dfSAlex Bennée              * No thread specifier, action is on "all threads". The
1113842b42dfSAlex Bennée              * specification is unclear regarding the process to act on. We
1114842b42dfSAlex Bennée              * choose all processes.
1115842b42dfSAlex Bennée              */
1116842b42dfSAlex Bennée             kind = GDB_ALL_PROCESSES;
1117842b42dfSAlex Bennée         } else if (*p++ == ':') {
1118842b42dfSAlex Bennée             kind = read_thread_id(p, &p, &pid, &tid);
1119842b42dfSAlex Bennée         } else {
1120842b42dfSAlex Bennée             res = -ENOTSUP;
1121842b42dfSAlex Bennée             goto out;
1122842b42dfSAlex Bennée         }
1123842b42dfSAlex Bennée 
1124842b42dfSAlex Bennée         switch (kind) {
1125842b42dfSAlex Bennée         case GDB_READ_THREAD_ERR:
1126842b42dfSAlex Bennée             res = -EINVAL;
1127842b42dfSAlex Bennée             goto out;
1128842b42dfSAlex Bennée 
1129842b42dfSAlex Bennée         case GDB_ALL_PROCESSES:
1130842b42dfSAlex Bennée             cpu = gdb_first_attached_cpu();
1131842b42dfSAlex Bennée             while (cpu) {
1132842b42dfSAlex Bennée                 if (newstates[cpu->cpu_index] == 1) {
1133842b42dfSAlex Bennée                     newstates[cpu->cpu_index] = cur_action;
1134842b42dfSAlex Bennée                 }
1135842b42dfSAlex Bennée 
1136842b42dfSAlex Bennée                 cpu = gdb_next_attached_cpu(cpu);
1137842b42dfSAlex Bennée             }
1138842b42dfSAlex Bennée             break;
1139842b42dfSAlex Bennée 
1140842b42dfSAlex Bennée         case GDB_ALL_THREADS:
1141842b42dfSAlex Bennée             process = gdb_get_process(pid);
1142842b42dfSAlex Bennée 
1143842b42dfSAlex Bennée             if (!process->attached) {
1144842b42dfSAlex Bennée                 res = -EINVAL;
1145842b42dfSAlex Bennée                 goto out;
1146842b42dfSAlex Bennée             }
1147842b42dfSAlex Bennée 
1148842b42dfSAlex Bennée             cpu = get_first_cpu_in_process(process);
1149842b42dfSAlex Bennée             while (cpu) {
1150842b42dfSAlex Bennée                 if (newstates[cpu->cpu_index] == 1) {
1151842b42dfSAlex Bennée                     newstates[cpu->cpu_index] = cur_action;
1152842b42dfSAlex Bennée                 }
1153842b42dfSAlex Bennée 
1154842b42dfSAlex Bennée                 cpu = gdb_next_cpu_in_process(cpu);
1155842b42dfSAlex Bennée             }
1156842b42dfSAlex Bennée             break;
1157842b42dfSAlex Bennée 
1158842b42dfSAlex Bennée         case GDB_ONE_THREAD:
1159842b42dfSAlex Bennée             cpu = gdb_get_cpu(pid, tid);
1160842b42dfSAlex Bennée 
1161842b42dfSAlex Bennée             /* invalid CPU/thread specified */
1162842b42dfSAlex Bennée             if (!cpu) {
1163842b42dfSAlex Bennée                 res = -EINVAL;
1164842b42dfSAlex Bennée                 goto out;
1165842b42dfSAlex Bennée             }
1166842b42dfSAlex Bennée 
1167842b42dfSAlex Bennée             /* only use if no previous match occourred */
1168842b42dfSAlex Bennée             if (newstates[cpu->cpu_index] == 1) {
1169842b42dfSAlex Bennée                 newstates[cpu->cpu_index] = cur_action;
1170842b42dfSAlex Bennée             }
1171842b42dfSAlex Bennée             break;
1172842b42dfSAlex Bennée         }
1173842b42dfSAlex Bennée     }
1174842b42dfSAlex Bennée     gdbserver_state.signal = signal;
1175842b42dfSAlex Bennée     gdb_continue_partial(newstates);
1176842b42dfSAlex Bennée 
1177842b42dfSAlex Bennée out:
1178842b42dfSAlex Bennée     g_free(newstates);
1179842b42dfSAlex Bennée 
1180842b42dfSAlex Bennée     return res;
1181842b42dfSAlex Bennée }
1182842b42dfSAlex Bennée 
1183842b42dfSAlex Bennée typedef union GdbCmdVariant {
1184842b42dfSAlex Bennée     const char *data;
1185842b42dfSAlex Bennée     uint8_t opcode;
1186842b42dfSAlex Bennée     unsigned long val_ul;
1187842b42dfSAlex Bennée     unsigned long long val_ull;
1188842b42dfSAlex Bennée     struct {
1189842b42dfSAlex Bennée         GDBThreadIdKind kind;
1190842b42dfSAlex Bennée         uint32_t pid;
1191842b42dfSAlex Bennée         uint32_t tid;
1192842b42dfSAlex Bennée     } thread_id;
1193842b42dfSAlex Bennée } GdbCmdVariant;
1194842b42dfSAlex Bennée 
1195842b42dfSAlex Bennée #define get_param(p, i)    (&g_array_index(p, GdbCmdVariant, i))
1196842b42dfSAlex Bennée 
1197842b42dfSAlex Bennée static const char *cmd_next_param(const char *param, const char delimiter)
1198842b42dfSAlex Bennée {
1199842b42dfSAlex Bennée     static const char all_delimiters[] = ",;:=";
1200842b42dfSAlex Bennée     char curr_delimiters[2] = {0};
1201842b42dfSAlex Bennée     const char *delimiters;
1202842b42dfSAlex Bennée 
1203842b42dfSAlex Bennée     if (delimiter == '?') {
1204842b42dfSAlex Bennée         delimiters = all_delimiters;
1205842b42dfSAlex Bennée     } else if (delimiter == '0') {
1206842b42dfSAlex Bennée         return strchr(param, '\0');
1207842b42dfSAlex Bennée     } else if (delimiter == '.' && *param) {
1208842b42dfSAlex Bennée         return param + 1;
1209842b42dfSAlex Bennée     } else {
1210842b42dfSAlex Bennée         curr_delimiters[0] = delimiter;
1211842b42dfSAlex Bennée         delimiters = curr_delimiters;
1212842b42dfSAlex Bennée     }
1213842b42dfSAlex Bennée 
1214842b42dfSAlex Bennée     param += strcspn(param, delimiters);
1215842b42dfSAlex Bennée     if (*param) {
1216842b42dfSAlex Bennée         param++;
1217842b42dfSAlex Bennée     }
1218842b42dfSAlex Bennée     return param;
1219842b42dfSAlex Bennée }
1220842b42dfSAlex Bennée 
1221842b42dfSAlex Bennée static int cmd_parse_params(const char *data, const char *schema,
1222842b42dfSAlex Bennée                             GArray *params)
1223842b42dfSAlex Bennée {
1224842b42dfSAlex Bennée     const char *curr_schema, *curr_data;
1225842b42dfSAlex Bennée 
1226842b42dfSAlex Bennée     g_assert(schema);
1227842b42dfSAlex Bennée     g_assert(params->len == 0);
1228842b42dfSAlex Bennée 
1229842b42dfSAlex Bennée     curr_schema = schema;
1230842b42dfSAlex Bennée     curr_data = data;
1231842b42dfSAlex Bennée     while (curr_schema[0] && curr_schema[1] && *curr_data) {
1232842b42dfSAlex Bennée         GdbCmdVariant this_param;
1233842b42dfSAlex Bennée 
1234842b42dfSAlex Bennée         switch (curr_schema[0]) {
1235842b42dfSAlex Bennée         case 'l':
1236842b42dfSAlex Bennée             if (qemu_strtoul(curr_data, &curr_data, 16,
1237842b42dfSAlex Bennée                              &this_param.val_ul)) {
1238842b42dfSAlex Bennée                 return -EINVAL;
1239842b42dfSAlex Bennée             }
1240842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1241842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1242842b42dfSAlex Bennée             break;
1243842b42dfSAlex Bennée         case 'L':
1244842b42dfSAlex Bennée             if (qemu_strtou64(curr_data, &curr_data, 16,
1245842b42dfSAlex Bennée                               (uint64_t *)&this_param.val_ull)) {
1246842b42dfSAlex Bennée                 return -EINVAL;
1247842b42dfSAlex Bennée             }
1248842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1249842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1250842b42dfSAlex Bennée             break;
1251842b42dfSAlex Bennée         case 's':
1252842b42dfSAlex Bennée             this_param.data = curr_data;
1253842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1254842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1255842b42dfSAlex Bennée             break;
1256842b42dfSAlex Bennée         case 'o':
1257842b42dfSAlex Bennée             this_param.opcode = *(uint8_t *)curr_data;
1258842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1259842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1260842b42dfSAlex Bennée             break;
1261842b42dfSAlex Bennée         case 't':
1262842b42dfSAlex Bennée             this_param.thread_id.kind =
1263842b42dfSAlex Bennée                 read_thread_id(curr_data, &curr_data,
1264842b42dfSAlex Bennée                                &this_param.thread_id.pid,
1265842b42dfSAlex Bennée                                &this_param.thread_id.tid);
1266842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1267842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1268842b42dfSAlex Bennée             break;
1269842b42dfSAlex Bennée         case '?':
1270842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1271842b42dfSAlex Bennée             break;
1272842b42dfSAlex Bennée         default:
1273842b42dfSAlex Bennée             return -EINVAL;
1274842b42dfSAlex Bennée         }
1275842b42dfSAlex Bennée         curr_schema += 2;
1276842b42dfSAlex Bennée     }
1277842b42dfSAlex Bennée 
1278842b42dfSAlex Bennée     return 0;
1279842b42dfSAlex Bennée }
1280842b42dfSAlex Bennée 
1281842b42dfSAlex Bennée typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
1282842b42dfSAlex Bennée 
1283842b42dfSAlex Bennée /*
1284842b42dfSAlex Bennée  * cmd_startswith -> cmd is compared using startswith
1285842b42dfSAlex Bennée  *
1286842b42dfSAlex Bennée  *
1287842b42dfSAlex Bennée  * schema definitions:
1288842b42dfSAlex Bennée  * Each schema parameter entry consists of 2 chars,
1289842b42dfSAlex Bennée  * the first char represents the parameter type handling
1290842b42dfSAlex Bennée  * the second char represents the delimiter for the next parameter
1291842b42dfSAlex Bennée  *
1292842b42dfSAlex Bennée  * Currently supported schema types:
1293842b42dfSAlex Bennée  * 'l' -> unsigned long (stored in .val_ul)
1294842b42dfSAlex Bennée  * 'L' -> unsigned long long (stored in .val_ull)
1295842b42dfSAlex Bennée  * 's' -> string (stored in .data)
1296842b42dfSAlex Bennée  * 'o' -> single char (stored in .opcode)
1297842b42dfSAlex Bennée  * 't' -> thread id (stored in .thread_id)
1298842b42dfSAlex Bennée  * '?' -> skip according to delimiter
1299842b42dfSAlex Bennée  *
1300842b42dfSAlex Bennée  * Currently supported delimiters:
1301842b42dfSAlex Bennée  * '?' -> Stop at any delimiter (",;:=\0")
1302842b42dfSAlex Bennée  * '0' -> Stop at "\0"
1303842b42dfSAlex Bennée  * '.' -> Skip 1 char unless reached "\0"
1304842b42dfSAlex Bennée  * Any other value is treated as the delimiter value itself
1305842b42dfSAlex Bennée  */
1306842b42dfSAlex Bennée typedef struct GdbCmdParseEntry {
1307842b42dfSAlex Bennée     GdbCmdHandler handler;
1308842b42dfSAlex Bennée     const char *cmd;
1309842b42dfSAlex Bennée     bool cmd_startswith;
1310842b42dfSAlex Bennée     const char *schema;
1311842b42dfSAlex Bennée } GdbCmdParseEntry;
1312842b42dfSAlex Bennée 
1313842b42dfSAlex Bennée static inline int startswith(const char *string, const char *pattern)
1314842b42dfSAlex Bennée {
1315842b42dfSAlex Bennée   return !strncmp(string, pattern, strlen(pattern));
1316842b42dfSAlex Bennée }
1317842b42dfSAlex Bennée 
1318842b42dfSAlex Bennée static int process_string_cmd(void *user_ctx, const char *data,
1319842b42dfSAlex Bennée                               const GdbCmdParseEntry *cmds, int num_cmds)
1320842b42dfSAlex Bennée {
1321842b42dfSAlex Bennée     int i;
1322842b42dfSAlex Bennée     g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
1323842b42dfSAlex Bennée 
1324842b42dfSAlex Bennée     if (!cmds) {
1325842b42dfSAlex Bennée         return -1;
1326842b42dfSAlex Bennée     }
1327842b42dfSAlex Bennée 
1328842b42dfSAlex Bennée     for (i = 0; i < num_cmds; i++) {
1329842b42dfSAlex Bennée         const GdbCmdParseEntry *cmd = &cmds[i];
1330842b42dfSAlex Bennée         g_assert(cmd->handler && cmd->cmd);
1331842b42dfSAlex Bennée 
1332842b42dfSAlex Bennée         if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1333842b42dfSAlex Bennée             (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1334842b42dfSAlex Bennée             continue;
1335842b42dfSAlex Bennée         }
1336842b42dfSAlex Bennée 
1337842b42dfSAlex Bennée         if (cmd->schema) {
1338842b42dfSAlex Bennée             if (cmd_parse_params(&data[strlen(cmd->cmd)],
1339842b42dfSAlex Bennée                                  cmd->schema, params)) {
1340842b42dfSAlex Bennée                 return -1;
1341842b42dfSAlex Bennée             }
1342842b42dfSAlex Bennée         }
1343842b42dfSAlex Bennée 
1344842b42dfSAlex Bennée         cmd->handler(params, user_ctx);
1345842b42dfSAlex Bennée         return 0;
1346842b42dfSAlex Bennée     }
1347842b42dfSAlex Bennée 
1348842b42dfSAlex Bennée     return -1;
1349842b42dfSAlex Bennée }
1350842b42dfSAlex Bennée 
1351842b42dfSAlex Bennée static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
1352842b42dfSAlex Bennée {
1353842b42dfSAlex Bennée     if (!data) {
1354842b42dfSAlex Bennée         return;
1355842b42dfSAlex Bennée     }
1356842b42dfSAlex Bennée 
1357842b42dfSAlex Bennée     g_string_set_size(gdbserver_state.str_buf, 0);
1358842b42dfSAlex Bennée     g_byte_array_set_size(gdbserver_state.mem_buf, 0);
1359842b42dfSAlex Bennée 
1360842b42dfSAlex Bennée     /* In case there was an error during the command parsing we must
1361842b42dfSAlex Bennée     * send a NULL packet to indicate the command is not supported */
1362842b42dfSAlex Bennée     if (process_string_cmd(NULL, data, cmd, 1)) {
136336e067b2SAlex Bennée         gdb_put_packet("");
1364842b42dfSAlex Bennée     }
1365842b42dfSAlex Bennée }
1366842b42dfSAlex Bennée 
1367842b42dfSAlex Bennée static void handle_detach(GArray *params, void *user_ctx)
1368842b42dfSAlex Bennée {
1369842b42dfSAlex Bennée     GDBProcess *process;
1370842b42dfSAlex Bennée     uint32_t pid = 1;
1371842b42dfSAlex Bennée 
1372842b42dfSAlex Bennée     if (gdbserver_state.multiprocess) {
1373842b42dfSAlex Bennée         if (!params->len) {
137436e067b2SAlex Bennée             gdb_put_packet("E22");
1375842b42dfSAlex Bennée             return;
1376842b42dfSAlex Bennée         }
1377842b42dfSAlex Bennée 
1378842b42dfSAlex Bennée         pid = get_param(params, 0)->val_ul;
1379842b42dfSAlex Bennée     }
1380842b42dfSAlex Bennée 
1381842b42dfSAlex Bennée     process = gdb_get_process(pid);
1382842b42dfSAlex Bennée     gdb_process_breakpoint_remove_all(process);
1383842b42dfSAlex Bennée     process->attached = false;
1384842b42dfSAlex Bennée 
1385842b42dfSAlex Bennée     if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1386842b42dfSAlex Bennée         gdbserver_state.c_cpu = gdb_first_attached_cpu();
1387842b42dfSAlex Bennée     }
1388842b42dfSAlex Bennée 
1389842b42dfSAlex Bennée     if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1390842b42dfSAlex Bennée         gdbserver_state.g_cpu = gdb_first_attached_cpu();
1391842b42dfSAlex Bennée     }
1392842b42dfSAlex Bennée 
1393842b42dfSAlex Bennée     if (!gdbserver_state.c_cpu) {
1394842b42dfSAlex Bennée         /* No more process attached */
1395842b42dfSAlex Bennée         gdb_syscall_mode = GDB_SYS_DISABLED;
1396842b42dfSAlex Bennée         gdb_continue();
1397842b42dfSAlex Bennée     }
139836e067b2SAlex Bennée     gdb_put_packet("OK");
1399842b42dfSAlex Bennée }
1400842b42dfSAlex Bennée 
1401842b42dfSAlex Bennée static void handle_thread_alive(GArray *params, void *user_ctx)
1402842b42dfSAlex Bennée {
1403842b42dfSAlex Bennée     CPUState *cpu;
1404842b42dfSAlex Bennée 
1405842b42dfSAlex Bennée     if (!params->len) {
140636e067b2SAlex Bennée         gdb_put_packet("E22");
1407842b42dfSAlex Bennée         return;
1408842b42dfSAlex Bennée     }
1409842b42dfSAlex Bennée 
1410842b42dfSAlex Bennée     if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
141136e067b2SAlex Bennée         gdb_put_packet("E22");
1412842b42dfSAlex Bennée         return;
1413842b42dfSAlex Bennée     }
1414842b42dfSAlex Bennée 
1415842b42dfSAlex Bennée     cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1416842b42dfSAlex Bennée                       get_param(params, 0)->thread_id.tid);
1417842b42dfSAlex Bennée     if (!cpu) {
141836e067b2SAlex Bennée         gdb_put_packet("E22");
1419842b42dfSAlex Bennée         return;
1420842b42dfSAlex Bennée     }
1421842b42dfSAlex Bennée 
142236e067b2SAlex Bennée     gdb_put_packet("OK");
1423842b42dfSAlex Bennée }
1424842b42dfSAlex Bennée 
1425842b42dfSAlex Bennée static void handle_continue(GArray *params, void *user_ctx)
1426842b42dfSAlex Bennée {
1427842b42dfSAlex Bennée     if (params->len) {
1428842b42dfSAlex Bennée         gdb_set_cpu_pc(get_param(params, 0)->val_ull);
1429842b42dfSAlex Bennée     }
1430842b42dfSAlex Bennée 
1431842b42dfSAlex Bennée     gdbserver_state.signal = 0;
1432842b42dfSAlex Bennée     gdb_continue();
1433842b42dfSAlex Bennée }
1434842b42dfSAlex Bennée 
1435842b42dfSAlex Bennée static void handle_cont_with_sig(GArray *params, void *user_ctx)
1436842b42dfSAlex Bennée {
1437842b42dfSAlex Bennée     unsigned long signal = 0;
1438842b42dfSAlex Bennée 
1439842b42dfSAlex Bennée     /*
1440842b42dfSAlex Bennée      * Note: C sig;[addr] is currently unsupported and we simply
1441842b42dfSAlex Bennée      *       omit the addr parameter
1442842b42dfSAlex Bennée      */
1443842b42dfSAlex Bennée     if (params->len) {
1444842b42dfSAlex Bennée         signal = get_param(params, 0)->val_ul;
1445842b42dfSAlex Bennée     }
1446842b42dfSAlex Bennée 
1447842b42dfSAlex Bennée     gdbserver_state.signal = gdb_signal_to_target(signal);
1448842b42dfSAlex Bennée     if (gdbserver_state.signal == -1) {
1449842b42dfSAlex Bennée         gdbserver_state.signal = 0;
1450842b42dfSAlex Bennée     }
1451842b42dfSAlex Bennée     gdb_continue();
1452842b42dfSAlex Bennée }
1453842b42dfSAlex Bennée 
1454842b42dfSAlex Bennée static void handle_set_thread(GArray *params, void *user_ctx)
1455842b42dfSAlex Bennée {
1456842b42dfSAlex Bennée     CPUState *cpu;
1457842b42dfSAlex Bennée 
1458842b42dfSAlex Bennée     if (params->len != 2) {
145936e067b2SAlex Bennée         gdb_put_packet("E22");
1460842b42dfSAlex Bennée         return;
1461842b42dfSAlex Bennée     }
1462842b42dfSAlex Bennée 
1463842b42dfSAlex Bennée     if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
146436e067b2SAlex Bennée         gdb_put_packet("E22");
1465842b42dfSAlex Bennée         return;
1466842b42dfSAlex Bennée     }
1467842b42dfSAlex Bennée 
1468842b42dfSAlex Bennée     if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
146936e067b2SAlex Bennée         gdb_put_packet("OK");
1470842b42dfSAlex Bennée         return;
1471842b42dfSAlex Bennée     }
1472842b42dfSAlex Bennée 
1473842b42dfSAlex Bennée     cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1474842b42dfSAlex Bennée                       get_param(params, 1)->thread_id.tid);
1475842b42dfSAlex Bennée     if (!cpu) {
147636e067b2SAlex Bennée         gdb_put_packet("E22");
1477842b42dfSAlex Bennée         return;
1478842b42dfSAlex Bennée     }
1479842b42dfSAlex Bennée 
1480842b42dfSAlex Bennée     /*
1481842b42dfSAlex Bennée      * Note: This command is deprecated and modern gdb's will be using the
1482842b42dfSAlex Bennée      *       vCont command instead.
1483842b42dfSAlex Bennée      */
1484842b42dfSAlex Bennée     switch (get_param(params, 0)->opcode) {
1485842b42dfSAlex Bennée     case 'c':
1486842b42dfSAlex Bennée         gdbserver_state.c_cpu = cpu;
148736e067b2SAlex Bennée         gdb_put_packet("OK");
1488842b42dfSAlex Bennée         break;
1489842b42dfSAlex Bennée     case 'g':
1490842b42dfSAlex Bennée         gdbserver_state.g_cpu = cpu;
149136e067b2SAlex Bennée         gdb_put_packet("OK");
1492842b42dfSAlex Bennée         break;
1493842b42dfSAlex Bennée     default:
149436e067b2SAlex Bennée         gdb_put_packet("E22");
1495842b42dfSAlex Bennée         break;
1496842b42dfSAlex Bennée     }
1497842b42dfSAlex Bennée }
1498842b42dfSAlex Bennée 
1499842b42dfSAlex Bennée static void handle_insert_bp(GArray *params, void *user_ctx)
1500842b42dfSAlex Bennée {
1501842b42dfSAlex Bennée     int res;
1502842b42dfSAlex Bennée 
1503842b42dfSAlex Bennée     if (params->len != 3) {
150436e067b2SAlex Bennée         gdb_put_packet("E22");
1505842b42dfSAlex Bennée         return;
1506842b42dfSAlex Bennée     }
1507842b42dfSAlex Bennée 
1508ae7467b1SAlex Bennée     res = gdb_breakpoint_insert(gdbserver_state.c_cpu,
1509ae7467b1SAlex Bennée                                 get_param(params, 0)->val_ul,
1510842b42dfSAlex Bennée                                 get_param(params, 1)->val_ull,
1511842b42dfSAlex Bennée                                 get_param(params, 2)->val_ull);
1512842b42dfSAlex Bennée     if (res >= 0) {
151336e067b2SAlex Bennée         gdb_put_packet("OK");
1514842b42dfSAlex Bennée         return;
1515842b42dfSAlex Bennée     } else if (res == -ENOSYS) {
151636e067b2SAlex Bennée         gdb_put_packet("");
1517842b42dfSAlex Bennée         return;
1518842b42dfSAlex Bennée     }
1519842b42dfSAlex Bennée 
152036e067b2SAlex Bennée     gdb_put_packet("E22");
1521842b42dfSAlex Bennée }
1522842b42dfSAlex Bennée 
1523842b42dfSAlex Bennée static void handle_remove_bp(GArray *params, void *user_ctx)
1524842b42dfSAlex Bennée {
1525842b42dfSAlex Bennée     int res;
1526842b42dfSAlex Bennée 
1527842b42dfSAlex Bennée     if (params->len != 3) {
152836e067b2SAlex Bennée         gdb_put_packet("E22");
1529842b42dfSAlex Bennée         return;
1530842b42dfSAlex Bennée     }
1531842b42dfSAlex Bennée 
1532ae7467b1SAlex Bennée     res = gdb_breakpoint_remove(gdbserver_state.c_cpu,
1533ae7467b1SAlex Bennée                                 get_param(params, 0)->val_ul,
1534842b42dfSAlex Bennée                                 get_param(params, 1)->val_ull,
1535842b42dfSAlex Bennée                                 get_param(params, 2)->val_ull);
1536842b42dfSAlex Bennée     if (res >= 0) {
153736e067b2SAlex Bennée         gdb_put_packet("OK");
1538842b42dfSAlex Bennée         return;
1539842b42dfSAlex Bennée     } else if (res == -ENOSYS) {
154036e067b2SAlex Bennée         gdb_put_packet("");
1541842b42dfSAlex Bennée         return;
1542842b42dfSAlex Bennée     }
1543842b42dfSAlex Bennée 
154436e067b2SAlex Bennée     gdb_put_packet("E22");
1545842b42dfSAlex Bennée }
1546842b42dfSAlex Bennée 
1547842b42dfSAlex Bennée /*
1548842b42dfSAlex Bennée  * handle_set/get_reg
1549842b42dfSAlex Bennée  *
1550842b42dfSAlex Bennée  * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1551842b42dfSAlex Bennée  * This works, but can be very slow. Anything new enough to understand
1552842b42dfSAlex Bennée  * XML also knows how to use this properly. However to use this we
1553842b42dfSAlex Bennée  * need to define a local XML file as well as be talking to a
1554842b42dfSAlex Bennée  * reasonably modern gdb. Responding with an empty packet will cause
1555842b42dfSAlex Bennée  * the remote gdb to fallback to older methods.
1556842b42dfSAlex Bennée  */
1557842b42dfSAlex Bennée 
1558842b42dfSAlex Bennée static void handle_set_reg(GArray *params, void *user_ctx)
1559842b42dfSAlex Bennée {
1560842b42dfSAlex Bennée     int reg_size;
1561842b42dfSAlex Bennée 
1562842b42dfSAlex Bennée     if (!gdb_has_xml) {
156336e067b2SAlex Bennée         gdb_put_packet("");
1564842b42dfSAlex Bennée         return;
1565842b42dfSAlex Bennée     }
1566842b42dfSAlex Bennée 
1567842b42dfSAlex Bennée     if (params->len != 2) {
156836e067b2SAlex Bennée         gdb_put_packet("E22");
1569842b42dfSAlex Bennée         return;
1570842b42dfSAlex Bennée     }
1571842b42dfSAlex Bennée 
1572842b42dfSAlex Bennée     reg_size = strlen(get_param(params, 1)->data) / 2;
157336e067b2SAlex Bennée     gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
1574842b42dfSAlex Bennée     gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
1575842b42dfSAlex Bennée                        get_param(params, 0)->val_ull);
157636e067b2SAlex Bennée     gdb_put_packet("OK");
1577842b42dfSAlex Bennée }
1578842b42dfSAlex Bennée 
1579842b42dfSAlex Bennée static void handle_get_reg(GArray *params, void *user_ctx)
1580842b42dfSAlex Bennée {
1581842b42dfSAlex Bennée     int reg_size;
1582842b42dfSAlex Bennée 
1583842b42dfSAlex Bennée     if (!gdb_has_xml) {
158436e067b2SAlex Bennée         gdb_put_packet("");
1585842b42dfSAlex Bennée         return;
1586842b42dfSAlex Bennée     }
1587842b42dfSAlex Bennée 
1588842b42dfSAlex Bennée     if (!params->len) {
158936e067b2SAlex Bennée         gdb_put_packet("E14");
1590842b42dfSAlex Bennée         return;
1591842b42dfSAlex Bennée     }
1592842b42dfSAlex Bennée 
1593842b42dfSAlex Bennée     reg_size = gdb_read_register(gdbserver_state.g_cpu,
1594842b42dfSAlex Bennée                                  gdbserver_state.mem_buf,
1595842b42dfSAlex Bennée                                  get_param(params, 0)->val_ull);
1596842b42dfSAlex Bennée     if (!reg_size) {
159736e067b2SAlex Bennée         gdb_put_packet("E14");
1598842b42dfSAlex Bennée         return;
1599842b42dfSAlex Bennée     } else {
1600842b42dfSAlex Bennée         g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
1601842b42dfSAlex Bennée     }
1602842b42dfSAlex Bennée 
160336e067b2SAlex Bennée     gdb_memtohex(gdbserver_state.str_buf,
160436e067b2SAlex Bennée                  gdbserver_state.mem_buf->data, reg_size);
160536e067b2SAlex Bennée     gdb_put_strbuf();
1606842b42dfSAlex Bennée }
1607842b42dfSAlex Bennée 
1608842b42dfSAlex Bennée static void handle_write_mem(GArray *params, void *user_ctx)
1609842b42dfSAlex Bennée {
1610842b42dfSAlex Bennée     if (params->len != 3) {
161136e067b2SAlex Bennée         gdb_put_packet("E22");
1612842b42dfSAlex Bennée         return;
1613842b42dfSAlex Bennée     }
1614842b42dfSAlex Bennée 
161536e067b2SAlex Bennée     /* gdb_hextomem() reads 2*len bytes */
1616842b42dfSAlex Bennée     if (get_param(params, 1)->val_ull >
1617842b42dfSAlex Bennée         strlen(get_param(params, 2)->data) / 2) {
161836e067b2SAlex Bennée         gdb_put_packet("E22");
1619842b42dfSAlex Bennée         return;
1620842b42dfSAlex Bennée     }
1621842b42dfSAlex Bennée 
162236e067b2SAlex Bennée     gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1623842b42dfSAlex Bennée              get_param(params, 1)->val_ull);
1624842b42dfSAlex Bennée     if (target_memory_rw_debug(gdbserver_state.g_cpu,
1625842b42dfSAlex Bennée                                get_param(params, 0)->val_ull,
1626842b42dfSAlex Bennée                                gdbserver_state.mem_buf->data,
1627842b42dfSAlex Bennée                                gdbserver_state.mem_buf->len, true)) {
162836e067b2SAlex Bennée         gdb_put_packet("E14");
1629842b42dfSAlex Bennée         return;
1630842b42dfSAlex Bennée     }
1631842b42dfSAlex Bennée 
163236e067b2SAlex Bennée     gdb_put_packet("OK");
1633842b42dfSAlex Bennée }
1634842b42dfSAlex Bennée 
1635842b42dfSAlex Bennée static void handle_read_mem(GArray *params, void *user_ctx)
1636842b42dfSAlex Bennée {
1637842b42dfSAlex Bennée     if (params->len != 2) {
163836e067b2SAlex Bennée         gdb_put_packet("E22");
1639842b42dfSAlex Bennée         return;
1640842b42dfSAlex Bennée     }
1641842b42dfSAlex Bennée 
164236e067b2SAlex Bennée     /* gdb_memtohex() doubles the required space */
1643842b42dfSAlex Bennée     if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
164436e067b2SAlex Bennée         gdb_put_packet("E22");
1645842b42dfSAlex Bennée         return;
1646842b42dfSAlex Bennée     }
1647842b42dfSAlex Bennée 
1648842b42dfSAlex Bennée     g_byte_array_set_size(gdbserver_state.mem_buf,
1649842b42dfSAlex Bennée                           get_param(params, 1)->val_ull);
1650842b42dfSAlex Bennée 
1651842b42dfSAlex Bennée     if (target_memory_rw_debug(gdbserver_state.g_cpu,
1652842b42dfSAlex Bennée                                get_param(params, 0)->val_ull,
1653842b42dfSAlex Bennée                                gdbserver_state.mem_buf->data,
1654842b42dfSAlex Bennée                                gdbserver_state.mem_buf->len, false)) {
165536e067b2SAlex Bennée         gdb_put_packet("E14");
1656842b42dfSAlex Bennée         return;
1657842b42dfSAlex Bennée     }
1658842b42dfSAlex Bennée 
165936e067b2SAlex Bennée     gdb_memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1660842b42dfSAlex Bennée              gdbserver_state.mem_buf->len);
166136e067b2SAlex Bennée     gdb_put_strbuf();
1662842b42dfSAlex Bennée }
1663842b42dfSAlex Bennée 
1664842b42dfSAlex Bennée static void handle_write_all_regs(GArray *params, void *user_ctx)
1665842b42dfSAlex Bennée {
1666842b42dfSAlex Bennée     target_ulong addr, len;
1667842b42dfSAlex Bennée     uint8_t *registers;
1668842b42dfSAlex Bennée     int reg_size;
1669842b42dfSAlex Bennée 
1670842b42dfSAlex Bennée     if (!params->len) {
1671842b42dfSAlex Bennée         return;
1672842b42dfSAlex Bennée     }
1673842b42dfSAlex Bennée 
1674842b42dfSAlex Bennée     cpu_synchronize_state(gdbserver_state.g_cpu);
1675842b42dfSAlex Bennée     len = strlen(get_param(params, 0)->data) / 2;
167636e067b2SAlex Bennée     gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
1677842b42dfSAlex Bennée     registers = gdbserver_state.mem_buf->data;
1678842b42dfSAlex Bennée     for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
1679842b42dfSAlex Bennée          addr++) {
1680842b42dfSAlex Bennée         reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
1681842b42dfSAlex Bennée         len -= reg_size;
1682842b42dfSAlex Bennée         registers += reg_size;
1683842b42dfSAlex Bennée     }
168436e067b2SAlex Bennée     gdb_put_packet("OK");
1685842b42dfSAlex Bennée }
1686842b42dfSAlex Bennée 
1687842b42dfSAlex Bennée static void handle_read_all_regs(GArray *params, void *user_ctx)
1688842b42dfSAlex Bennée {
1689842b42dfSAlex Bennée     target_ulong addr, len;
1690842b42dfSAlex Bennée 
1691842b42dfSAlex Bennée     cpu_synchronize_state(gdbserver_state.g_cpu);
1692842b42dfSAlex Bennée     g_byte_array_set_size(gdbserver_state.mem_buf, 0);
1693842b42dfSAlex Bennée     len = 0;
1694842b42dfSAlex Bennée     for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
1695842b42dfSAlex Bennée         len += gdb_read_register(gdbserver_state.g_cpu,
1696842b42dfSAlex Bennée                                  gdbserver_state.mem_buf,
1697842b42dfSAlex Bennée                                  addr);
1698842b42dfSAlex Bennée     }
1699842b42dfSAlex Bennée     g_assert(len == gdbserver_state.mem_buf->len);
1700842b42dfSAlex Bennée 
170136e067b2SAlex Bennée     gdb_memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
170236e067b2SAlex Bennée     gdb_put_strbuf();
1703842b42dfSAlex Bennée }
1704842b42dfSAlex Bennée 
1705842b42dfSAlex Bennée static void handle_file_io(GArray *params, void *user_ctx)
1706842b42dfSAlex Bennée {
1707842b42dfSAlex Bennée     if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
1708842b42dfSAlex Bennée         uint64_t ret;
1709842b42dfSAlex Bennée         int err;
1710842b42dfSAlex Bennée 
1711842b42dfSAlex Bennée         ret = get_param(params, 0)->val_ull;
1712842b42dfSAlex Bennée         if (params->len >= 2) {
1713842b42dfSAlex Bennée             err = get_param(params, 1)->val_ull;
1714842b42dfSAlex Bennée         } else {
1715842b42dfSAlex Bennée             err = 0;
1716842b42dfSAlex Bennée         }
1717842b42dfSAlex Bennée 
1718842b42dfSAlex Bennée         /* Convert GDB error numbers back to host error numbers. */
1719842b42dfSAlex Bennée #define E(X)  case GDB_E##X: err = E##X; break
1720842b42dfSAlex Bennée         switch (err) {
1721842b42dfSAlex Bennée         case 0:
1722842b42dfSAlex Bennée             break;
1723842b42dfSAlex Bennée         E(PERM);
1724842b42dfSAlex Bennée         E(NOENT);
1725842b42dfSAlex Bennée         E(INTR);
1726842b42dfSAlex Bennée         E(BADF);
1727842b42dfSAlex Bennée         E(ACCES);
1728842b42dfSAlex Bennée         E(FAULT);
1729842b42dfSAlex Bennée         E(BUSY);
1730842b42dfSAlex Bennée         E(EXIST);
1731842b42dfSAlex Bennée         E(NODEV);
1732842b42dfSAlex Bennée         E(NOTDIR);
1733842b42dfSAlex Bennée         E(ISDIR);
1734842b42dfSAlex Bennée         E(INVAL);
1735842b42dfSAlex Bennée         E(NFILE);
1736842b42dfSAlex Bennée         E(MFILE);
1737842b42dfSAlex Bennée         E(FBIG);
1738842b42dfSAlex Bennée         E(NOSPC);
1739842b42dfSAlex Bennée         E(SPIPE);
1740842b42dfSAlex Bennée         E(ROFS);
1741842b42dfSAlex Bennée         E(NAMETOOLONG);
1742842b42dfSAlex Bennée         default:
1743842b42dfSAlex Bennée             err = EINVAL;
1744842b42dfSAlex Bennée             break;
1745842b42dfSAlex Bennée         }
1746842b42dfSAlex Bennée #undef E
1747842b42dfSAlex Bennée 
1748842b42dfSAlex Bennée         gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1749842b42dfSAlex Bennée         gdbserver_state.current_syscall_cb = NULL;
1750842b42dfSAlex Bennée     }
1751842b42dfSAlex Bennée 
1752842b42dfSAlex Bennée     if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
175336e067b2SAlex Bennée         gdb_put_packet("T02");
1754842b42dfSAlex Bennée         return;
1755842b42dfSAlex Bennée     }
1756842b42dfSAlex Bennée 
1757842b42dfSAlex Bennée     gdb_continue();
1758842b42dfSAlex Bennée }
1759842b42dfSAlex Bennée 
1760842b42dfSAlex Bennée static void handle_step(GArray *params, void *user_ctx)
1761842b42dfSAlex Bennée {
1762842b42dfSAlex Bennée     if (params->len) {
1763842b42dfSAlex Bennée         gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
1764842b42dfSAlex Bennée     }
1765842b42dfSAlex Bennée 
1766842b42dfSAlex Bennée     cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
1767842b42dfSAlex Bennée     gdb_continue();
1768842b42dfSAlex Bennée }
1769842b42dfSAlex Bennée 
1770842b42dfSAlex Bennée static void handle_backward(GArray *params, void *user_ctx)
1771842b42dfSAlex Bennée {
1772842b42dfSAlex Bennée     if (!stub_can_reverse()) {
177336e067b2SAlex Bennée         gdb_put_packet("E22");
1774842b42dfSAlex Bennée     }
1775842b42dfSAlex Bennée     if (params->len == 1) {
1776842b42dfSAlex Bennée         switch (get_param(params, 0)->opcode) {
1777842b42dfSAlex Bennée         case 's':
1778842b42dfSAlex Bennée             if (replay_reverse_step()) {
1779842b42dfSAlex Bennée                 gdb_continue();
1780842b42dfSAlex Bennée             } else {
178136e067b2SAlex Bennée                 gdb_put_packet("E14");
1782842b42dfSAlex Bennée             }
1783842b42dfSAlex Bennée             return;
1784842b42dfSAlex Bennée         case 'c':
1785842b42dfSAlex Bennée             if (replay_reverse_continue()) {
1786842b42dfSAlex Bennée                 gdb_continue();
1787842b42dfSAlex Bennée             } else {
178836e067b2SAlex Bennée                 gdb_put_packet("E14");
1789842b42dfSAlex Bennée             }
1790842b42dfSAlex Bennée             return;
1791842b42dfSAlex Bennée         }
1792842b42dfSAlex Bennée     }
1793842b42dfSAlex Bennée 
1794842b42dfSAlex Bennée     /* Default invalid command */
179536e067b2SAlex Bennée     gdb_put_packet("");
1796842b42dfSAlex Bennée }
1797842b42dfSAlex Bennée 
1798842b42dfSAlex Bennée static void handle_v_cont_query(GArray *params, void *user_ctx)
1799842b42dfSAlex Bennée {
180036e067b2SAlex Bennée     gdb_put_packet("vCont;c;C;s;S");
1801842b42dfSAlex Bennée }
1802842b42dfSAlex Bennée 
1803842b42dfSAlex Bennée static void handle_v_cont(GArray *params, void *user_ctx)
1804842b42dfSAlex Bennée {
1805842b42dfSAlex Bennée     int res;
1806842b42dfSAlex Bennée 
1807842b42dfSAlex Bennée     if (!params->len) {
1808842b42dfSAlex Bennée         return;
1809842b42dfSAlex Bennée     }
1810842b42dfSAlex Bennée 
1811842b42dfSAlex Bennée     res = gdb_handle_vcont(get_param(params, 0)->data);
1812842b42dfSAlex Bennée     if ((res == -EINVAL) || (res == -ERANGE)) {
181336e067b2SAlex Bennée         gdb_put_packet("E22");
1814842b42dfSAlex Bennée     } else if (res) {
181536e067b2SAlex Bennée         gdb_put_packet("");
1816842b42dfSAlex Bennée     }
1817842b42dfSAlex Bennée }
1818842b42dfSAlex Bennée 
1819842b42dfSAlex Bennée static void handle_v_attach(GArray *params, void *user_ctx)
1820842b42dfSAlex Bennée {
1821842b42dfSAlex Bennée     GDBProcess *process;
1822842b42dfSAlex Bennée     CPUState *cpu;
1823842b42dfSAlex Bennée 
1824842b42dfSAlex Bennée     g_string_assign(gdbserver_state.str_buf, "E22");
1825842b42dfSAlex Bennée     if (!params->len) {
1826842b42dfSAlex Bennée         goto cleanup;
1827842b42dfSAlex Bennée     }
1828842b42dfSAlex Bennée 
1829842b42dfSAlex Bennée     process = gdb_get_process(get_param(params, 0)->val_ul);
1830842b42dfSAlex Bennée     if (!process) {
1831842b42dfSAlex Bennée         goto cleanup;
1832842b42dfSAlex Bennée     }
1833842b42dfSAlex Bennée 
1834842b42dfSAlex Bennée     cpu = get_first_cpu_in_process(process);
1835842b42dfSAlex Bennée     if (!cpu) {
1836842b42dfSAlex Bennée         goto cleanup;
1837842b42dfSAlex Bennée     }
1838842b42dfSAlex Bennée 
1839842b42dfSAlex Bennée     process->attached = true;
1840842b42dfSAlex Bennée     gdbserver_state.g_cpu = cpu;
1841842b42dfSAlex Bennée     gdbserver_state.c_cpu = cpu;
1842842b42dfSAlex Bennée 
1843842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
1844842b42dfSAlex Bennée     gdb_append_thread_id(cpu, gdbserver_state.str_buf);
1845842b42dfSAlex Bennée     g_string_append_c(gdbserver_state.str_buf, ';');
1846842b42dfSAlex Bennée cleanup:
184736e067b2SAlex Bennée     gdb_put_strbuf();
1848842b42dfSAlex Bennée }
1849842b42dfSAlex Bennée 
1850842b42dfSAlex Bennée static void handle_v_kill(GArray *params, void *user_ctx)
1851842b42dfSAlex Bennée {
1852842b42dfSAlex Bennée     /* Kill the target */
185336e067b2SAlex Bennée     gdb_put_packet("OK");
1854842b42dfSAlex Bennée     error_report("QEMU: Terminated via GDBstub");
1855842b42dfSAlex Bennée     gdb_exit(0);
1856842b42dfSAlex Bennée     exit(0);
1857842b42dfSAlex Bennée }
1858842b42dfSAlex Bennée 
1859842b42dfSAlex Bennée static const GdbCmdParseEntry gdb_v_commands_table[] = {
1860842b42dfSAlex Bennée     /* Order is important if has same prefix */
1861842b42dfSAlex Bennée     {
1862842b42dfSAlex Bennée         .handler = handle_v_cont_query,
1863842b42dfSAlex Bennée         .cmd = "Cont?",
1864842b42dfSAlex Bennée         .cmd_startswith = 1
1865842b42dfSAlex Bennée     },
1866842b42dfSAlex Bennée     {
1867842b42dfSAlex Bennée         .handler = handle_v_cont,
1868842b42dfSAlex Bennée         .cmd = "Cont",
1869842b42dfSAlex Bennée         .cmd_startswith = 1,
1870842b42dfSAlex Bennée         .schema = "s0"
1871842b42dfSAlex Bennée     },
1872842b42dfSAlex Bennée     {
1873842b42dfSAlex Bennée         .handler = handle_v_attach,
1874842b42dfSAlex Bennée         .cmd = "Attach;",
1875842b42dfSAlex Bennée         .cmd_startswith = 1,
1876842b42dfSAlex Bennée         .schema = "l0"
1877842b42dfSAlex Bennée     },
1878842b42dfSAlex Bennée     {
1879842b42dfSAlex Bennée         .handler = handle_v_kill,
1880842b42dfSAlex Bennée         .cmd = "Kill;",
1881842b42dfSAlex Bennée         .cmd_startswith = 1
1882842b42dfSAlex Bennée     },
1883842b42dfSAlex Bennée };
1884842b42dfSAlex Bennée 
1885842b42dfSAlex Bennée static void handle_v_commands(GArray *params, void *user_ctx)
1886842b42dfSAlex Bennée {
1887842b42dfSAlex Bennée     if (!params->len) {
1888842b42dfSAlex Bennée         return;
1889842b42dfSAlex Bennée     }
1890842b42dfSAlex Bennée 
1891842b42dfSAlex Bennée     if (process_string_cmd(NULL, get_param(params, 0)->data,
1892842b42dfSAlex Bennée                            gdb_v_commands_table,
1893842b42dfSAlex Bennée                            ARRAY_SIZE(gdb_v_commands_table))) {
189436e067b2SAlex Bennée         gdb_put_packet("");
1895842b42dfSAlex Bennée     }
1896842b42dfSAlex Bennée }
1897842b42dfSAlex Bennée 
1898842b42dfSAlex Bennée static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
1899842b42dfSAlex Bennée {
1900842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
1901842b42dfSAlex Bennée 
1902842b42dfSAlex Bennée     if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
1903842b42dfSAlex Bennée         g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
1904842b42dfSAlex Bennée                                SSTEP_NOIRQ);
1905842b42dfSAlex Bennée     }
1906842b42dfSAlex Bennée 
1907842b42dfSAlex Bennée     if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
1908842b42dfSAlex Bennée         g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
1909842b42dfSAlex Bennée                                SSTEP_NOTIMER);
1910842b42dfSAlex Bennée     }
1911842b42dfSAlex Bennée 
191236e067b2SAlex Bennée     gdb_put_strbuf();
1913842b42dfSAlex Bennée }
1914842b42dfSAlex Bennée 
1915842b42dfSAlex Bennée static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
1916842b42dfSAlex Bennée {
1917842b42dfSAlex Bennée     int new_sstep_flags;
1918842b42dfSAlex Bennée 
1919842b42dfSAlex Bennée     if (!params->len) {
1920842b42dfSAlex Bennée         return;
1921842b42dfSAlex Bennée     }
1922842b42dfSAlex Bennée 
1923842b42dfSAlex Bennée     new_sstep_flags = get_param(params, 0)->val_ul;
1924842b42dfSAlex Bennée 
1925842b42dfSAlex Bennée     if (new_sstep_flags  & ~gdbserver_state.supported_sstep_flags) {
192636e067b2SAlex Bennée         gdb_put_packet("E22");
1927842b42dfSAlex Bennée         return;
1928842b42dfSAlex Bennée     }
1929842b42dfSAlex Bennée 
1930842b42dfSAlex Bennée     gdbserver_state.sstep_flags = new_sstep_flags;
193136e067b2SAlex Bennée     gdb_put_packet("OK");
1932842b42dfSAlex Bennée }
1933842b42dfSAlex Bennée 
1934842b42dfSAlex Bennée static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
1935842b42dfSAlex Bennée {
1936842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "0x%x",
1937842b42dfSAlex Bennée                     gdbserver_state.sstep_flags);
193836e067b2SAlex Bennée     gdb_put_strbuf();
1939842b42dfSAlex Bennée }
1940842b42dfSAlex Bennée 
1941842b42dfSAlex Bennée static void handle_query_curr_tid(GArray *params, void *user_ctx)
1942842b42dfSAlex Bennée {
1943842b42dfSAlex Bennée     CPUState *cpu;
1944842b42dfSAlex Bennée     GDBProcess *process;
1945842b42dfSAlex Bennée 
1946842b42dfSAlex Bennée     /*
1947842b42dfSAlex Bennée      * "Current thread" remains vague in the spec, so always return
1948842b42dfSAlex Bennée      * the first thread of the current process (gdb returns the
1949842b42dfSAlex Bennée      * first thread).
1950842b42dfSAlex Bennée      */
1951842b42dfSAlex Bennée     process = gdb_get_cpu_process(gdbserver_state.g_cpu);
1952842b42dfSAlex Bennée     cpu = get_first_cpu_in_process(process);
1953842b42dfSAlex Bennée     g_string_assign(gdbserver_state.str_buf, "QC");
1954842b42dfSAlex Bennée     gdb_append_thread_id(cpu, gdbserver_state.str_buf);
195536e067b2SAlex Bennée     gdb_put_strbuf();
1956842b42dfSAlex Bennée }
1957842b42dfSAlex Bennée 
1958842b42dfSAlex Bennée static void handle_query_threads(GArray *params, void *user_ctx)
1959842b42dfSAlex Bennée {
1960842b42dfSAlex Bennée     if (!gdbserver_state.query_cpu) {
196136e067b2SAlex Bennée         gdb_put_packet("l");
1962842b42dfSAlex Bennée         return;
1963842b42dfSAlex Bennée     }
1964842b42dfSAlex Bennée 
1965842b42dfSAlex Bennée     g_string_assign(gdbserver_state.str_buf, "m");
1966842b42dfSAlex Bennée     gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
196736e067b2SAlex Bennée     gdb_put_strbuf();
1968842b42dfSAlex Bennée     gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
1969842b42dfSAlex Bennée }
1970842b42dfSAlex Bennée 
1971842b42dfSAlex Bennée static void handle_query_first_threads(GArray *params, void *user_ctx)
1972842b42dfSAlex Bennée {
1973842b42dfSAlex Bennée     gdbserver_state.query_cpu = gdb_first_attached_cpu();
1974842b42dfSAlex Bennée     handle_query_threads(params, user_ctx);
1975842b42dfSAlex Bennée }
1976842b42dfSAlex Bennée 
1977842b42dfSAlex Bennée static void handle_query_thread_extra(GArray *params, void *user_ctx)
1978842b42dfSAlex Bennée {
1979842b42dfSAlex Bennée     g_autoptr(GString) rs = g_string_new(NULL);
1980842b42dfSAlex Bennée     CPUState *cpu;
1981842b42dfSAlex Bennée 
1982842b42dfSAlex Bennée     if (!params->len ||
1983842b42dfSAlex Bennée         get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
198436e067b2SAlex Bennée         gdb_put_packet("E22");
1985842b42dfSAlex Bennée         return;
1986842b42dfSAlex Bennée     }
1987842b42dfSAlex Bennée 
1988842b42dfSAlex Bennée     cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1989842b42dfSAlex Bennée                       get_param(params, 0)->thread_id.tid);
1990842b42dfSAlex Bennée     if (!cpu) {
1991842b42dfSAlex Bennée         return;
1992842b42dfSAlex Bennée     }
1993842b42dfSAlex Bennée 
1994842b42dfSAlex Bennée     cpu_synchronize_state(cpu);
1995842b42dfSAlex Bennée 
1996842b42dfSAlex Bennée     if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
1997842b42dfSAlex Bennée         /* Print the CPU model and name in multiprocess mode */
1998842b42dfSAlex Bennée         ObjectClass *oc = object_get_class(OBJECT(cpu));
1999842b42dfSAlex Bennée         const char *cpu_model = object_class_get_name(oc);
2000842b42dfSAlex Bennée         const char *cpu_name =
2001842b42dfSAlex Bennée             object_get_canonical_path_component(OBJECT(cpu));
2002842b42dfSAlex Bennée         g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
2003842b42dfSAlex Bennée                         cpu->halted ? "halted " : "running");
2004842b42dfSAlex Bennée     } else {
2005842b42dfSAlex Bennée         g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
2006842b42dfSAlex Bennée                         cpu->halted ? "halted " : "running");
2007842b42dfSAlex Bennée     }
2008842b42dfSAlex Bennée     trace_gdbstub_op_extra_info(rs->str);
200936e067b2SAlex Bennée     gdb_memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
201036e067b2SAlex Bennée     gdb_put_strbuf();
2011842b42dfSAlex Bennée }
2012842b42dfSAlex Bennée 
2013842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
2014842b42dfSAlex Bennée static void handle_query_offsets(GArray *params, void *user_ctx)
2015842b42dfSAlex Bennée {
2016842b42dfSAlex Bennée     TaskState *ts;
2017842b42dfSAlex Bennée 
2018842b42dfSAlex Bennée     ts = gdbserver_state.c_cpu->opaque;
2019842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf,
2020842b42dfSAlex Bennée                     "Text=" TARGET_ABI_FMT_lx
2021842b42dfSAlex Bennée                     ";Data=" TARGET_ABI_FMT_lx
2022842b42dfSAlex Bennée                     ";Bss=" TARGET_ABI_FMT_lx,
2023842b42dfSAlex Bennée                     ts->info->code_offset,
2024842b42dfSAlex Bennée                     ts->info->data_offset,
2025842b42dfSAlex Bennée                     ts->info->data_offset);
202636e067b2SAlex Bennée     gdb_put_strbuf();
2027842b42dfSAlex Bennée }
2028842b42dfSAlex Bennée #else
2029842b42dfSAlex Bennée static void handle_query_rcmd(GArray *params, void *user_ctx)
2030842b42dfSAlex Bennée {
2031842b42dfSAlex Bennée     const guint8 zero = 0;
2032842b42dfSAlex Bennée     int len;
2033842b42dfSAlex Bennée 
2034842b42dfSAlex Bennée     if (!params->len) {
203536e067b2SAlex Bennée         gdb_put_packet("E22");
2036842b42dfSAlex Bennée         return;
2037842b42dfSAlex Bennée     }
2038842b42dfSAlex Bennée 
2039842b42dfSAlex Bennée     len = strlen(get_param(params, 0)->data);
2040842b42dfSAlex Bennée     if (len % 2) {
204136e067b2SAlex Bennée         gdb_put_packet("E01");
2042842b42dfSAlex Bennée         return;
2043842b42dfSAlex Bennée     }
2044842b42dfSAlex Bennée 
2045842b42dfSAlex Bennée     g_assert(gdbserver_state.mem_buf->len == 0);
2046842b42dfSAlex Bennée     len = len / 2;
204736e067b2SAlex Bennée     gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
2048842b42dfSAlex Bennée     g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
20498e70c6f9SAlex Bennée     qemu_chr_be_write(gdbserver_system_state.mon_chr,
20508e70c6f9SAlex Bennée                       gdbserver_state.mem_buf->data,
2051842b42dfSAlex Bennée                       gdbserver_state.mem_buf->len);
205236e067b2SAlex Bennée     gdb_put_packet("OK");
2053842b42dfSAlex Bennée }
2054842b42dfSAlex Bennée #endif
2055842b42dfSAlex Bennée 
2056842b42dfSAlex Bennée static void handle_query_supported(GArray *params, void *user_ctx)
2057842b42dfSAlex Bennée {
2058842b42dfSAlex Bennée     CPUClass *cc;
2059842b42dfSAlex Bennée 
2060842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
2061842b42dfSAlex Bennée     cc = CPU_GET_CLASS(first_cpu);
2062842b42dfSAlex Bennée     if (cc->gdb_core_xml_file) {
2063842b42dfSAlex Bennée         g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
2064842b42dfSAlex Bennée     }
2065842b42dfSAlex Bennée 
2066842b42dfSAlex Bennée     if (stub_can_reverse()) {
2067842b42dfSAlex Bennée         g_string_append(gdbserver_state.str_buf,
2068842b42dfSAlex Bennée             ";ReverseStep+;ReverseContinue+");
2069842b42dfSAlex Bennée     }
2070842b42dfSAlex Bennée 
2071842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
2072842b42dfSAlex Bennée     if (gdbserver_state.c_cpu->opaque) {
2073842b42dfSAlex Bennée         g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
2074842b42dfSAlex Bennée     }
2075842b42dfSAlex Bennée #endif
2076842b42dfSAlex Bennée 
2077842b42dfSAlex Bennée     if (params->len &&
2078842b42dfSAlex Bennée         strstr(get_param(params, 0)->data, "multiprocess+")) {
2079842b42dfSAlex Bennée         gdbserver_state.multiprocess = true;
2080842b42dfSAlex Bennée     }
2081842b42dfSAlex Bennée 
2082842b42dfSAlex Bennée     g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
208336e067b2SAlex Bennée     gdb_put_strbuf();
2084842b42dfSAlex Bennée }
2085842b42dfSAlex Bennée 
2086842b42dfSAlex Bennée static void handle_query_xfer_features(GArray *params, void *user_ctx)
2087842b42dfSAlex Bennée {
2088842b42dfSAlex Bennée     GDBProcess *process;
2089842b42dfSAlex Bennée     CPUClass *cc;
2090842b42dfSAlex Bennée     unsigned long len, total_len, addr;
2091842b42dfSAlex Bennée     const char *xml;
2092842b42dfSAlex Bennée     const char *p;
2093842b42dfSAlex Bennée 
2094842b42dfSAlex Bennée     if (params->len < 3) {
209536e067b2SAlex Bennée         gdb_put_packet("E22");
2096842b42dfSAlex Bennée         return;
2097842b42dfSAlex Bennée     }
2098842b42dfSAlex Bennée 
2099842b42dfSAlex Bennée     process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2100842b42dfSAlex Bennée     cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
2101842b42dfSAlex Bennée     if (!cc->gdb_core_xml_file) {
210236e067b2SAlex Bennée         gdb_put_packet("");
2103842b42dfSAlex Bennée         return;
2104842b42dfSAlex Bennée     }
2105842b42dfSAlex Bennée 
2106842b42dfSAlex Bennée     gdb_has_xml = true;
2107842b42dfSAlex Bennée     p = get_param(params, 0)->data;
2108842b42dfSAlex Bennée     xml = get_feature_xml(p, &p, process);
2109842b42dfSAlex Bennée     if (!xml) {
211036e067b2SAlex Bennée         gdb_put_packet("E00");
2111842b42dfSAlex Bennée         return;
2112842b42dfSAlex Bennée     }
2113842b42dfSAlex Bennée 
2114842b42dfSAlex Bennée     addr = get_param(params, 1)->val_ul;
2115842b42dfSAlex Bennée     len = get_param(params, 2)->val_ul;
2116842b42dfSAlex Bennée     total_len = strlen(xml);
2117842b42dfSAlex Bennée     if (addr > total_len) {
211836e067b2SAlex Bennée         gdb_put_packet("E00");
2119842b42dfSAlex Bennée         return;
2120842b42dfSAlex Bennée     }
2121842b42dfSAlex Bennée 
2122842b42dfSAlex Bennée     if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2123842b42dfSAlex Bennée         len = (MAX_PACKET_LENGTH - 5) / 2;
2124842b42dfSAlex Bennée     }
2125842b42dfSAlex Bennée 
2126842b42dfSAlex Bennée     if (len < total_len - addr) {
2127842b42dfSAlex Bennée         g_string_assign(gdbserver_state.str_buf, "m");
212836e067b2SAlex Bennée         gdb_memtox(gdbserver_state.str_buf, xml + addr, len);
2129842b42dfSAlex Bennée     } else {
2130842b42dfSAlex Bennée         g_string_assign(gdbserver_state.str_buf, "l");
213136e067b2SAlex Bennée         gdb_memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
2132842b42dfSAlex Bennée     }
2133842b42dfSAlex Bennée 
213436e067b2SAlex Bennée     gdb_put_packet_binary(gdbserver_state.str_buf->str,
2135842b42dfSAlex Bennée                       gdbserver_state.str_buf->len, true);
2136842b42dfSAlex Bennée }
2137842b42dfSAlex Bennée 
2138842b42dfSAlex Bennée #if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2139842b42dfSAlex Bennée static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
2140842b42dfSAlex Bennée {
2141842b42dfSAlex Bennée     TaskState *ts;
2142842b42dfSAlex Bennée     unsigned long offset, len, saved_auxv, auxv_len;
2143842b42dfSAlex Bennée 
2144842b42dfSAlex Bennée     if (params->len < 2) {
214536e067b2SAlex Bennée         gdb_put_packet("E22");
2146842b42dfSAlex Bennée         return;
2147842b42dfSAlex Bennée     }
2148842b42dfSAlex Bennée 
2149842b42dfSAlex Bennée     offset = get_param(params, 0)->val_ul;
2150842b42dfSAlex Bennée     len = get_param(params, 1)->val_ul;
2151842b42dfSAlex Bennée     ts = gdbserver_state.c_cpu->opaque;
2152842b42dfSAlex Bennée     saved_auxv = ts->info->saved_auxv;
2153842b42dfSAlex Bennée     auxv_len = ts->info->auxv_len;
2154842b42dfSAlex Bennée 
2155842b42dfSAlex Bennée     if (offset >= auxv_len) {
215636e067b2SAlex Bennée         gdb_put_packet("E00");
2157842b42dfSAlex Bennée         return;
2158842b42dfSAlex Bennée     }
2159842b42dfSAlex Bennée 
2160842b42dfSAlex Bennée     if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2161842b42dfSAlex Bennée         len = (MAX_PACKET_LENGTH - 5) / 2;
2162842b42dfSAlex Bennée     }
2163842b42dfSAlex Bennée 
2164842b42dfSAlex Bennée     if (len < auxv_len - offset) {
2165842b42dfSAlex Bennée         g_string_assign(gdbserver_state.str_buf, "m");
2166842b42dfSAlex Bennée     } else {
2167842b42dfSAlex Bennée         g_string_assign(gdbserver_state.str_buf, "l");
2168842b42dfSAlex Bennée         len = auxv_len - offset;
2169842b42dfSAlex Bennée     }
2170842b42dfSAlex Bennée 
2171842b42dfSAlex Bennée     g_byte_array_set_size(gdbserver_state.mem_buf, len);
2172842b42dfSAlex Bennée     if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2173842b42dfSAlex Bennée                                gdbserver_state.mem_buf->data, len, false)) {
217436e067b2SAlex Bennée         gdb_put_packet("E14");
2175842b42dfSAlex Bennée         return;
2176842b42dfSAlex Bennée     }
2177842b42dfSAlex Bennée 
217836e067b2SAlex Bennée     gdb_memtox(gdbserver_state.str_buf,
2179842b42dfSAlex Bennée                (const char *)gdbserver_state.mem_buf->data, len);
218036e067b2SAlex Bennée     gdb_put_packet_binary(gdbserver_state.str_buf->str,
2181842b42dfSAlex Bennée                           gdbserver_state.str_buf->len, true);
2182842b42dfSAlex Bennée }
2183842b42dfSAlex Bennée #endif
2184842b42dfSAlex Bennée 
2185842b42dfSAlex Bennée static void handle_query_attached(GArray *params, void *user_ctx)
2186842b42dfSAlex Bennée {
218736e067b2SAlex Bennée     gdb_put_packet(GDB_ATTACHED);
2188842b42dfSAlex Bennée }
2189842b42dfSAlex Bennée 
2190842b42dfSAlex Bennée static void handle_query_qemu_supported(GArray *params, void *user_ctx)
2191842b42dfSAlex Bennée {
2192842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
2193842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2194842b42dfSAlex Bennée     g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
2195842b42dfSAlex Bennée #endif
219636e067b2SAlex Bennée     gdb_put_strbuf();
2197842b42dfSAlex Bennée }
2198842b42dfSAlex Bennée 
2199842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2200842b42dfSAlex Bennée static void handle_query_qemu_phy_mem_mode(GArray *params,
2201842b42dfSAlex Bennée                                            void *user_ctx)
2202842b42dfSAlex Bennée {
2203842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
220436e067b2SAlex Bennée     gdb_put_strbuf();
2205842b42dfSAlex Bennée }
2206842b42dfSAlex Bennée 
2207842b42dfSAlex Bennée static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
2208842b42dfSAlex Bennée {
2209842b42dfSAlex Bennée     if (!params->len) {
221036e067b2SAlex Bennée         gdb_put_packet("E22");
2211842b42dfSAlex Bennée         return;
2212842b42dfSAlex Bennée     }
2213842b42dfSAlex Bennée 
2214842b42dfSAlex Bennée     if (!get_param(params, 0)->val_ul) {
2215842b42dfSAlex Bennée         phy_memory_mode = 0;
2216842b42dfSAlex Bennée     } else {
2217842b42dfSAlex Bennée         phy_memory_mode = 1;
2218842b42dfSAlex Bennée     }
221936e067b2SAlex Bennée     gdb_put_packet("OK");
2220842b42dfSAlex Bennée }
2221842b42dfSAlex Bennée #endif
2222842b42dfSAlex Bennée 
2223842b42dfSAlex Bennée static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
2224842b42dfSAlex Bennée     /* Order is important if has same prefix */
2225842b42dfSAlex Bennée     {
2226842b42dfSAlex Bennée         .handler = handle_query_qemu_sstepbits,
2227842b42dfSAlex Bennée         .cmd = "qemu.sstepbits",
2228842b42dfSAlex Bennée     },
2229842b42dfSAlex Bennée     {
2230842b42dfSAlex Bennée         .handler = handle_query_qemu_sstep,
2231842b42dfSAlex Bennée         .cmd = "qemu.sstep",
2232842b42dfSAlex Bennée     },
2233842b42dfSAlex Bennée     {
2234842b42dfSAlex Bennée         .handler = handle_set_qemu_sstep,
2235842b42dfSAlex Bennée         .cmd = "qemu.sstep=",
2236842b42dfSAlex Bennée         .cmd_startswith = 1,
2237842b42dfSAlex Bennée         .schema = "l0"
2238842b42dfSAlex Bennée     },
2239842b42dfSAlex Bennée };
2240842b42dfSAlex Bennée 
2241842b42dfSAlex Bennée static const GdbCmdParseEntry gdb_gen_query_table[] = {
2242842b42dfSAlex Bennée     {
2243842b42dfSAlex Bennée         .handler = handle_query_curr_tid,
2244842b42dfSAlex Bennée         .cmd = "C",
2245842b42dfSAlex Bennée     },
2246842b42dfSAlex Bennée     {
2247842b42dfSAlex Bennée         .handler = handle_query_threads,
2248842b42dfSAlex Bennée         .cmd = "sThreadInfo",
2249842b42dfSAlex Bennée     },
2250842b42dfSAlex Bennée     {
2251842b42dfSAlex Bennée         .handler = handle_query_first_threads,
2252842b42dfSAlex Bennée         .cmd = "fThreadInfo",
2253842b42dfSAlex Bennée     },
2254842b42dfSAlex Bennée     {
2255842b42dfSAlex Bennée         .handler = handle_query_thread_extra,
2256842b42dfSAlex Bennée         .cmd = "ThreadExtraInfo,",
2257842b42dfSAlex Bennée         .cmd_startswith = 1,
2258842b42dfSAlex Bennée         .schema = "t0"
2259842b42dfSAlex Bennée     },
2260842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
2261842b42dfSAlex Bennée     {
2262842b42dfSAlex Bennée         .handler = handle_query_offsets,
2263842b42dfSAlex Bennée         .cmd = "Offsets",
2264842b42dfSAlex Bennée     },
2265842b42dfSAlex Bennée #else
2266842b42dfSAlex Bennée     {
2267842b42dfSAlex Bennée         .handler = handle_query_rcmd,
2268842b42dfSAlex Bennée         .cmd = "Rcmd,",
2269842b42dfSAlex Bennée         .cmd_startswith = 1,
2270842b42dfSAlex Bennée         .schema = "s0"
2271842b42dfSAlex Bennée     },
2272842b42dfSAlex Bennée #endif
2273842b42dfSAlex Bennée     {
2274842b42dfSAlex Bennée         .handler = handle_query_supported,
2275842b42dfSAlex Bennée         .cmd = "Supported:",
2276842b42dfSAlex Bennée         .cmd_startswith = 1,
2277842b42dfSAlex Bennée         .schema = "s0"
2278842b42dfSAlex Bennée     },
2279842b42dfSAlex Bennée     {
2280842b42dfSAlex Bennée         .handler = handle_query_supported,
2281842b42dfSAlex Bennée         .cmd = "Supported",
2282842b42dfSAlex Bennée         .schema = "s0"
2283842b42dfSAlex Bennée     },
2284842b42dfSAlex Bennée     {
2285842b42dfSAlex Bennée         .handler = handle_query_xfer_features,
2286842b42dfSAlex Bennée         .cmd = "Xfer:features:read:",
2287842b42dfSAlex Bennée         .cmd_startswith = 1,
2288842b42dfSAlex Bennée         .schema = "s:l,l0"
2289842b42dfSAlex Bennée     },
2290842b42dfSAlex Bennée #if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2291842b42dfSAlex Bennée     {
2292842b42dfSAlex Bennée         .handler = handle_query_xfer_auxv,
2293842b42dfSAlex Bennée         .cmd = "Xfer:auxv:read::",
2294842b42dfSAlex Bennée         .cmd_startswith = 1,
2295842b42dfSAlex Bennée         .schema = "l,l0"
2296842b42dfSAlex Bennée     },
2297842b42dfSAlex Bennée #endif
2298842b42dfSAlex Bennée     {
2299842b42dfSAlex Bennée         .handler = handle_query_attached,
2300842b42dfSAlex Bennée         .cmd = "Attached:",
2301842b42dfSAlex Bennée         .cmd_startswith = 1
2302842b42dfSAlex Bennée     },
2303842b42dfSAlex Bennée     {
2304842b42dfSAlex Bennée         .handler = handle_query_attached,
2305842b42dfSAlex Bennée         .cmd = "Attached",
2306842b42dfSAlex Bennée     },
2307842b42dfSAlex Bennée     {
2308842b42dfSAlex Bennée         .handler = handle_query_qemu_supported,
2309842b42dfSAlex Bennée         .cmd = "qemu.Supported",
2310842b42dfSAlex Bennée     },
2311842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2312842b42dfSAlex Bennée     {
2313842b42dfSAlex Bennée         .handler = handle_query_qemu_phy_mem_mode,
2314842b42dfSAlex Bennée         .cmd = "qemu.PhyMemMode",
2315842b42dfSAlex Bennée     },
2316842b42dfSAlex Bennée #endif
2317842b42dfSAlex Bennée };
2318842b42dfSAlex Bennée 
2319842b42dfSAlex Bennée static const GdbCmdParseEntry gdb_gen_set_table[] = {
2320842b42dfSAlex Bennée     /* Order is important if has same prefix */
2321842b42dfSAlex Bennée     {
2322842b42dfSAlex Bennée         .handler = handle_set_qemu_sstep,
2323842b42dfSAlex Bennée         .cmd = "qemu.sstep:",
2324842b42dfSAlex Bennée         .cmd_startswith = 1,
2325842b42dfSAlex Bennée         .schema = "l0"
2326842b42dfSAlex Bennée     },
2327842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2328842b42dfSAlex Bennée     {
2329842b42dfSAlex Bennée         .handler = handle_set_qemu_phy_mem_mode,
2330842b42dfSAlex Bennée         .cmd = "qemu.PhyMemMode:",
2331842b42dfSAlex Bennée         .cmd_startswith = 1,
2332842b42dfSAlex Bennée         .schema = "l0"
2333842b42dfSAlex Bennée     },
2334842b42dfSAlex Bennée #endif
2335842b42dfSAlex Bennée };
2336842b42dfSAlex Bennée 
2337842b42dfSAlex Bennée static void handle_gen_query(GArray *params, void *user_ctx)
2338842b42dfSAlex Bennée {
2339842b42dfSAlex Bennée     if (!params->len) {
2340842b42dfSAlex Bennée         return;
2341842b42dfSAlex Bennée     }
2342842b42dfSAlex Bennée 
2343842b42dfSAlex Bennée     if (!process_string_cmd(NULL, get_param(params, 0)->data,
2344842b42dfSAlex Bennée                             gdb_gen_query_set_common_table,
2345842b42dfSAlex Bennée                             ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2346842b42dfSAlex Bennée         return;
2347842b42dfSAlex Bennée     }
2348842b42dfSAlex Bennée 
2349842b42dfSAlex Bennée     if (process_string_cmd(NULL, get_param(params, 0)->data,
2350842b42dfSAlex Bennée                            gdb_gen_query_table,
2351842b42dfSAlex Bennée                            ARRAY_SIZE(gdb_gen_query_table))) {
235236e067b2SAlex Bennée         gdb_put_packet("");
2353842b42dfSAlex Bennée     }
2354842b42dfSAlex Bennée }
2355842b42dfSAlex Bennée 
2356842b42dfSAlex Bennée static void handle_gen_set(GArray *params, void *user_ctx)
2357842b42dfSAlex Bennée {
2358842b42dfSAlex Bennée     if (!params->len) {
2359842b42dfSAlex Bennée         return;
2360842b42dfSAlex Bennée     }
2361842b42dfSAlex Bennée 
2362842b42dfSAlex Bennée     if (!process_string_cmd(NULL, get_param(params, 0)->data,
2363842b42dfSAlex Bennée                             gdb_gen_query_set_common_table,
2364842b42dfSAlex Bennée                             ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2365842b42dfSAlex Bennée         return;
2366842b42dfSAlex Bennée     }
2367842b42dfSAlex Bennée 
2368842b42dfSAlex Bennée     if (process_string_cmd(NULL, get_param(params, 0)->data,
2369842b42dfSAlex Bennée                            gdb_gen_set_table,
2370842b42dfSAlex Bennée                            ARRAY_SIZE(gdb_gen_set_table))) {
237136e067b2SAlex Bennée         gdb_put_packet("");
2372842b42dfSAlex Bennée     }
2373842b42dfSAlex Bennée }
2374842b42dfSAlex Bennée 
2375842b42dfSAlex Bennée static void handle_target_halt(GArray *params, void *user_ctx)
2376842b42dfSAlex Bennée {
2377842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2378842b42dfSAlex Bennée     gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2379842b42dfSAlex Bennée     g_string_append_c(gdbserver_state.str_buf, ';');
238036e067b2SAlex Bennée     gdb_put_strbuf();
2381842b42dfSAlex Bennée     /*
2382842b42dfSAlex Bennée      * Remove all the breakpoints when this query is issued,
2383842b42dfSAlex Bennée      * because gdb is doing an initial connect and the state
2384842b42dfSAlex Bennée      * should be cleaned up.
2385842b42dfSAlex Bennée      */
2386ae7467b1SAlex Bennée     gdb_breakpoint_remove_all(gdbserver_state.c_cpu);
2387842b42dfSAlex Bennée }
2388842b42dfSAlex Bennée 
2389842b42dfSAlex Bennée static int gdb_handle_packet(const char *line_buf)
2390842b42dfSAlex Bennée {
2391842b42dfSAlex Bennée     const GdbCmdParseEntry *cmd_parser = NULL;
2392842b42dfSAlex Bennée 
2393842b42dfSAlex Bennée     trace_gdbstub_io_command(line_buf);
2394842b42dfSAlex Bennée 
2395842b42dfSAlex Bennée     switch (line_buf[0]) {
2396842b42dfSAlex Bennée     case '!':
239736e067b2SAlex Bennée         gdb_put_packet("OK");
2398842b42dfSAlex Bennée         break;
2399842b42dfSAlex Bennée     case '?':
2400842b42dfSAlex Bennée         {
2401842b42dfSAlex Bennée             static const GdbCmdParseEntry target_halted_cmd_desc = {
2402842b42dfSAlex Bennée                 .handler = handle_target_halt,
2403842b42dfSAlex Bennée                 .cmd = "?",
2404842b42dfSAlex Bennée                 .cmd_startswith = 1
2405842b42dfSAlex Bennée             };
2406842b42dfSAlex Bennée             cmd_parser = &target_halted_cmd_desc;
2407842b42dfSAlex Bennée         }
2408842b42dfSAlex Bennée         break;
2409842b42dfSAlex Bennée     case 'c':
2410842b42dfSAlex Bennée         {
2411842b42dfSAlex Bennée             static const GdbCmdParseEntry continue_cmd_desc = {
2412842b42dfSAlex Bennée                 .handler = handle_continue,
2413842b42dfSAlex Bennée                 .cmd = "c",
2414842b42dfSAlex Bennée                 .cmd_startswith = 1,
2415842b42dfSAlex Bennée                 .schema = "L0"
2416842b42dfSAlex Bennée             };
2417842b42dfSAlex Bennée             cmd_parser = &continue_cmd_desc;
2418842b42dfSAlex Bennée         }
2419842b42dfSAlex Bennée         break;
2420842b42dfSAlex Bennée     case 'C':
2421842b42dfSAlex Bennée         {
2422842b42dfSAlex Bennée             static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2423842b42dfSAlex Bennée                 .handler = handle_cont_with_sig,
2424842b42dfSAlex Bennée                 .cmd = "C",
2425842b42dfSAlex Bennée                 .cmd_startswith = 1,
2426842b42dfSAlex Bennée                 .schema = "l0"
2427842b42dfSAlex Bennée             };
2428842b42dfSAlex Bennée             cmd_parser = &cont_with_sig_cmd_desc;
2429842b42dfSAlex Bennée         }
2430842b42dfSAlex Bennée         break;
2431842b42dfSAlex Bennée     case 'v':
2432842b42dfSAlex Bennée         {
2433842b42dfSAlex Bennée             static const GdbCmdParseEntry v_cmd_desc = {
2434842b42dfSAlex Bennée                 .handler = handle_v_commands,
2435842b42dfSAlex Bennée                 .cmd = "v",
2436842b42dfSAlex Bennée                 .cmd_startswith = 1,
2437842b42dfSAlex Bennée                 .schema = "s0"
2438842b42dfSAlex Bennée             };
2439842b42dfSAlex Bennée             cmd_parser = &v_cmd_desc;
2440842b42dfSAlex Bennée         }
2441842b42dfSAlex Bennée         break;
2442842b42dfSAlex Bennée     case 'k':
2443842b42dfSAlex Bennée         /* Kill the target */
2444842b42dfSAlex Bennée         error_report("QEMU: Terminated via GDBstub");
2445842b42dfSAlex Bennée         gdb_exit(0);
2446842b42dfSAlex Bennée         exit(0);
2447842b42dfSAlex Bennée     case 'D':
2448842b42dfSAlex Bennée         {
2449842b42dfSAlex Bennée             static const GdbCmdParseEntry detach_cmd_desc = {
2450842b42dfSAlex Bennée                 .handler = handle_detach,
2451842b42dfSAlex Bennée                 .cmd = "D",
2452842b42dfSAlex Bennée                 .cmd_startswith = 1,
2453842b42dfSAlex Bennée                 .schema = "?.l0"
2454842b42dfSAlex Bennée             };
2455842b42dfSAlex Bennée             cmd_parser = &detach_cmd_desc;
2456842b42dfSAlex Bennée         }
2457842b42dfSAlex Bennée         break;
2458842b42dfSAlex Bennée     case 's':
2459842b42dfSAlex Bennée         {
2460842b42dfSAlex Bennée             static const GdbCmdParseEntry step_cmd_desc = {
2461842b42dfSAlex Bennée                 .handler = handle_step,
2462842b42dfSAlex Bennée                 .cmd = "s",
2463842b42dfSAlex Bennée                 .cmd_startswith = 1,
2464842b42dfSAlex Bennée                 .schema = "L0"
2465842b42dfSAlex Bennée             };
2466842b42dfSAlex Bennée             cmd_parser = &step_cmd_desc;
2467842b42dfSAlex Bennée         }
2468842b42dfSAlex Bennée         break;
2469842b42dfSAlex Bennée     case 'b':
2470842b42dfSAlex Bennée         {
2471842b42dfSAlex Bennée             static const GdbCmdParseEntry backward_cmd_desc = {
2472842b42dfSAlex Bennée                 .handler = handle_backward,
2473842b42dfSAlex Bennée                 .cmd = "b",
2474842b42dfSAlex Bennée                 .cmd_startswith = 1,
2475842b42dfSAlex Bennée                 .schema = "o0"
2476842b42dfSAlex Bennée             };
2477842b42dfSAlex Bennée             cmd_parser = &backward_cmd_desc;
2478842b42dfSAlex Bennée         }
2479842b42dfSAlex Bennée         break;
2480842b42dfSAlex Bennée     case 'F':
2481842b42dfSAlex Bennée         {
2482842b42dfSAlex Bennée             static const GdbCmdParseEntry file_io_cmd_desc = {
2483842b42dfSAlex Bennée                 .handler = handle_file_io,
2484842b42dfSAlex Bennée                 .cmd = "F",
2485842b42dfSAlex Bennée                 .cmd_startswith = 1,
2486842b42dfSAlex Bennée                 .schema = "L,L,o0"
2487842b42dfSAlex Bennée             };
2488842b42dfSAlex Bennée             cmd_parser = &file_io_cmd_desc;
2489842b42dfSAlex Bennée         }
2490842b42dfSAlex Bennée         break;
2491842b42dfSAlex Bennée     case 'g':
2492842b42dfSAlex Bennée         {
2493842b42dfSAlex Bennée             static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2494842b42dfSAlex Bennée                 .handler = handle_read_all_regs,
2495842b42dfSAlex Bennée                 .cmd = "g",
2496842b42dfSAlex Bennée                 .cmd_startswith = 1
2497842b42dfSAlex Bennée             };
2498842b42dfSAlex Bennée             cmd_parser = &read_all_regs_cmd_desc;
2499842b42dfSAlex Bennée         }
2500842b42dfSAlex Bennée         break;
2501842b42dfSAlex Bennée     case 'G':
2502842b42dfSAlex Bennée         {
2503842b42dfSAlex Bennée             static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2504842b42dfSAlex Bennée                 .handler = handle_write_all_regs,
2505842b42dfSAlex Bennée                 .cmd = "G",
2506842b42dfSAlex Bennée                 .cmd_startswith = 1,
2507842b42dfSAlex Bennée                 .schema = "s0"
2508842b42dfSAlex Bennée             };
2509842b42dfSAlex Bennée             cmd_parser = &write_all_regs_cmd_desc;
2510842b42dfSAlex Bennée         }
2511842b42dfSAlex Bennée         break;
2512842b42dfSAlex Bennée     case 'm':
2513842b42dfSAlex Bennée         {
2514842b42dfSAlex Bennée             static const GdbCmdParseEntry read_mem_cmd_desc = {
2515842b42dfSAlex Bennée                 .handler = handle_read_mem,
2516842b42dfSAlex Bennée                 .cmd = "m",
2517842b42dfSAlex Bennée                 .cmd_startswith = 1,
2518842b42dfSAlex Bennée                 .schema = "L,L0"
2519842b42dfSAlex Bennée             };
2520842b42dfSAlex Bennée             cmd_parser = &read_mem_cmd_desc;
2521842b42dfSAlex Bennée         }
2522842b42dfSAlex Bennée         break;
2523842b42dfSAlex Bennée     case 'M':
2524842b42dfSAlex Bennée         {
2525842b42dfSAlex Bennée             static const GdbCmdParseEntry write_mem_cmd_desc = {
2526842b42dfSAlex Bennée                 .handler = handle_write_mem,
2527842b42dfSAlex Bennée                 .cmd = "M",
2528842b42dfSAlex Bennée                 .cmd_startswith = 1,
2529842b42dfSAlex Bennée                 .schema = "L,L:s0"
2530842b42dfSAlex Bennée             };
2531842b42dfSAlex Bennée             cmd_parser = &write_mem_cmd_desc;
2532842b42dfSAlex Bennée         }
2533842b42dfSAlex Bennée         break;
2534842b42dfSAlex Bennée     case 'p':
2535842b42dfSAlex Bennée         {
2536842b42dfSAlex Bennée             static const GdbCmdParseEntry get_reg_cmd_desc = {
2537842b42dfSAlex Bennée                 .handler = handle_get_reg,
2538842b42dfSAlex Bennée                 .cmd = "p",
2539842b42dfSAlex Bennée                 .cmd_startswith = 1,
2540842b42dfSAlex Bennée                 .schema = "L0"
2541842b42dfSAlex Bennée             };
2542842b42dfSAlex Bennée             cmd_parser = &get_reg_cmd_desc;
2543842b42dfSAlex Bennée         }
2544842b42dfSAlex Bennée         break;
2545842b42dfSAlex Bennée     case 'P':
2546842b42dfSAlex Bennée         {
2547842b42dfSAlex Bennée             static const GdbCmdParseEntry set_reg_cmd_desc = {
2548842b42dfSAlex Bennée                 .handler = handle_set_reg,
2549842b42dfSAlex Bennée                 .cmd = "P",
2550842b42dfSAlex Bennée                 .cmd_startswith = 1,
2551842b42dfSAlex Bennée                 .schema = "L?s0"
2552842b42dfSAlex Bennée             };
2553842b42dfSAlex Bennée             cmd_parser = &set_reg_cmd_desc;
2554842b42dfSAlex Bennée         }
2555842b42dfSAlex Bennée         break;
2556842b42dfSAlex Bennée     case 'Z':
2557842b42dfSAlex Bennée         {
2558842b42dfSAlex Bennée             static const GdbCmdParseEntry insert_bp_cmd_desc = {
2559842b42dfSAlex Bennée                 .handler = handle_insert_bp,
2560842b42dfSAlex Bennée                 .cmd = "Z",
2561842b42dfSAlex Bennée                 .cmd_startswith = 1,
2562842b42dfSAlex Bennée                 .schema = "l?L?L0"
2563842b42dfSAlex Bennée             };
2564842b42dfSAlex Bennée             cmd_parser = &insert_bp_cmd_desc;
2565842b42dfSAlex Bennée         }
2566842b42dfSAlex Bennée         break;
2567842b42dfSAlex Bennée     case 'z':
2568842b42dfSAlex Bennée         {
2569842b42dfSAlex Bennée             static const GdbCmdParseEntry remove_bp_cmd_desc = {
2570842b42dfSAlex Bennée                 .handler = handle_remove_bp,
2571842b42dfSAlex Bennée                 .cmd = "z",
2572842b42dfSAlex Bennée                 .cmd_startswith = 1,
2573842b42dfSAlex Bennée                 .schema = "l?L?L0"
2574842b42dfSAlex Bennée             };
2575842b42dfSAlex Bennée             cmd_parser = &remove_bp_cmd_desc;
2576842b42dfSAlex Bennée         }
2577842b42dfSAlex Bennée         break;
2578842b42dfSAlex Bennée     case 'H':
2579842b42dfSAlex Bennée         {
2580842b42dfSAlex Bennée             static const GdbCmdParseEntry set_thread_cmd_desc = {
2581842b42dfSAlex Bennée                 .handler = handle_set_thread,
2582842b42dfSAlex Bennée                 .cmd = "H",
2583842b42dfSAlex Bennée                 .cmd_startswith = 1,
2584842b42dfSAlex Bennée                 .schema = "o.t0"
2585842b42dfSAlex Bennée             };
2586842b42dfSAlex Bennée             cmd_parser = &set_thread_cmd_desc;
2587842b42dfSAlex Bennée         }
2588842b42dfSAlex Bennée         break;
2589842b42dfSAlex Bennée     case 'T':
2590842b42dfSAlex Bennée         {
2591842b42dfSAlex Bennée             static const GdbCmdParseEntry thread_alive_cmd_desc = {
2592842b42dfSAlex Bennée                 .handler = handle_thread_alive,
2593842b42dfSAlex Bennée                 .cmd = "T",
2594842b42dfSAlex Bennée                 .cmd_startswith = 1,
2595842b42dfSAlex Bennée                 .schema = "t0"
2596842b42dfSAlex Bennée             };
2597842b42dfSAlex Bennée             cmd_parser = &thread_alive_cmd_desc;
2598842b42dfSAlex Bennée         }
2599842b42dfSAlex Bennée         break;
2600842b42dfSAlex Bennée     case 'q':
2601842b42dfSAlex Bennée         {
2602842b42dfSAlex Bennée             static const GdbCmdParseEntry gen_query_cmd_desc = {
2603842b42dfSAlex Bennée                 .handler = handle_gen_query,
2604842b42dfSAlex Bennée                 .cmd = "q",
2605842b42dfSAlex Bennée                 .cmd_startswith = 1,
2606842b42dfSAlex Bennée                 .schema = "s0"
2607842b42dfSAlex Bennée             };
2608842b42dfSAlex Bennée             cmd_parser = &gen_query_cmd_desc;
2609842b42dfSAlex Bennée         }
2610842b42dfSAlex Bennée         break;
2611842b42dfSAlex Bennée     case 'Q':
2612842b42dfSAlex Bennée         {
2613842b42dfSAlex Bennée             static const GdbCmdParseEntry gen_set_cmd_desc = {
2614842b42dfSAlex Bennée                 .handler = handle_gen_set,
2615842b42dfSAlex Bennée                 .cmd = "Q",
2616842b42dfSAlex Bennée                 .cmd_startswith = 1,
2617842b42dfSAlex Bennée                 .schema = "s0"
2618842b42dfSAlex Bennée             };
2619842b42dfSAlex Bennée             cmd_parser = &gen_set_cmd_desc;
2620842b42dfSAlex Bennée         }
2621842b42dfSAlex Bennée         break;
2622842b42dfSAlex Bennée     default:
2623842b42dfSAlex Bennée         /* put empty packet */
262436e067b2SAlex Bennée         gdb_put_packet("");
2625842b42dfSAlex Bennée         break;
2626842b42dfSAlex Bennée     }
2627842b42dfSAlex Bennée 
2628842b42dfSAlex Bennée     if (cmd_parser) {
2629842b42dfSAlex Bennée         run_cmd_parser(line_buf, cmd_parser);
2630842b42dfSAlex Bennée     }
2631842b42dfSAlex Bennée 
2632842b42dfSAlex Bennée     return RS_IDLE;
2633842b42dfSAlex Bennée }
2634842b42dfSAlex Bennée 
2635842b42dfSAlex Bennée void gdb_set_stop_cpu(CPUState *cpu)
2636842b42dfSAlex Bennée {
2637842b42dfSAlex Bennée     GDBProcess *p = gdb_get_cpu_process(cpu);
2638842b42dfSAlex Bennée 
2639842b42dfSAlex Bennée     if (!p->attached) {
2640842b42dfSAlex Bennée         /*
2641842b42dfSAlex Bennée          * Having a stop CPU corresponding to a process that is not attached
2642842b42dfSAlex Bennée          * confuses GDB. So we ignore the request.
2643842b42dfSAlex Bennée          */
2644842b42dfSAlex Bennée         return;
2645842b42dfSAlex Bennée     }
2646842b42dfSAlex Bennée 
2647842b42dfSAlex Bennée     gdbserver_state.c_cpu = cpu;
2648842b42dfSAlex Bennée     gdbserver_state.g_cpu = cpu;
2649842b42dfSAlex Bennée }
2650842b42dfSAlex Bennée 
2651842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2652842b42dfSAlex Bennée static void gdb_vm_state_change(void *opaque, bool running, RunState state)
2653842b42dfSAlex Bennée {
2654842b42dfSAlex Bennée     CPUState *cpu = gdbserver_state.c_cpu;
2655842b42dfSAlex Bennée     g_autoptr(GString) buf = g_string_new(NULL);
2656842b42dfSAlex Bennée     g_autoptr(GString) tid = g_string_new(NULL);
2657842b42dfSAlex Bennée     const char *type;
2658842b42dfSAlex Bennée     int ret;
2659842b42dfSAlex Bennée 
2660842b42dfSAlex Bennée     if (running || gdbserver_state.state == RS_INACTIVE) {
2661842b42dfSAlex Bennée         return;
2662842b42dfSAlex Bennée     }
2663842b42dfSAlex Bennée     /* Is there a GDB syscall waiting to be sent?  */
2664842b42dfSAlex Bennée     if (gdbserver_state.current_syscall_cb) {
266536e067b2SAlex Bennée         gdb_put_packet(gdbserver_state.syscall_buf);
2666842b42dfSAlex Bennée         return;
2667842b42dfSAlex Bennée     }
2668842b42dfSAlex Bennée 
2669842b42dfSAlex Bennée     if (cpu == NULL) {
2670842b42dfSAlex Bennée         /* No process attached */
2671842b42dfSAlex Bennée         return;
2672842b42dfSAlex Bennée     }
2673842b42dfSAlex Bennée 
2674842b42dfSAlex Bennée     gdb_append_thread_id(cpu, tid);
2675842b42dfSAlex Bennée 
2676842b42dfSAlex Bennée     switch (state) {
2677842b42dfSAlex Bennée     case RUN_STATE_DEBUG:
2678842b42dfSAlex Bennée         if (cpu->watchpoint_hit) {
2679842b42dfSAlex Bennée             switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
2680842b42dfSAlex Bennée             case BP_MEM_READ:
2681842b42dfSAlex Bennée                 type = "r";
2682842b42dfSAlex Bennée                 break;
2683842b42dfSAlex Bennée             case BP_MEM_ACCESS:
2684842b42dfSAlex Bennée                 type = "a";
2685842b42dfSAlex Bennée                 break;
2686842b42dfSAlex Bennée             default:
2687842b42dfSAlex Bennée                 type = "";
2688842b42dfSAlex Bennée                 break;
2689842b42dfSAlex Bennée             }
269036e067b2SAlex Bennée             trace_gdbstub_hit_watchpoint(type, gdb_get_cpu_index(cpu),
2691842b42dfSAlex Bennée                     (target_ulong)cpu->watchpoint_hit->vaddr);
2692842b42dfSAlex Bennée             g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
2693842b42dfSAlex Bennée                             GDB_SIGNAL_TRAP, tid->str, type,
2694842b42dfSAlex Bennée                             (target_ulong)cpu->watchpoint_hit->vaddr);
2695842b42dfSAlex Bennée             cpu->watchpoint_hit = NULL;
2696842b42dfSAlex Bennée             goto send_packet;
2697842b42dfSAlex Bennée         } else {
2698842b42dfSAlex Bennée             trace_gdbstub_hit_break();
2699842b42dfSAlex Bennée         }
2700842b42dfSAlex Bennée         tb_flush(cpu);
2701842b42dfSAlex Bennée         ret = GDB_SIGNAL_TRAP;
2702842b42dfSAlex Bennée         break;
2703842b42dfSAlex Bennée     case RUN_STATE_PAUSED:
2704842b42dfSAlex Bennée         trace_gdbstub_hit_paused();
2705842b42dfSAlex Bennée         ret = GDB_SIGNAL_INT;
2706842b42dfSAlex Bennée         break;
2707842b42dfSAlex Bennée     case RUN_STATE_SHUTDOWN:
2708842b42dfSAlex Bennée         trace_gdbstub_hit_shutdown();
2709842b42dfSAlex Bennée         ret = GDB_SIGNAL_QUIT;
2710842b42dfSAlex Bennée         break;
2711842b42dfSAlex Bennée     case RUN_STATE_IO_ERROR:
2712842b42dfSAlex Bennée         trace_gdbstub_hit_io_error();
2713842b42dfSAlex Bennée         ret = GDB_SIGNAL_IO;
2714842b42dfSAlex Bennée         break;
2715842b42dfSAlex Bennée     case RUN_STATE_WATCHDOG:
2716842b42dfSAlex Bennée         trace_gdbstub_hit_watchdog();
2717842b42dfSAlex Bennée         ret = GDB_SIGNAL_ALRM;
2718842b42dfSAlex Bennée         break;
2719842b42dfSAlex Bennée     case RUN_STATE_INTERNAL_ERROR:
2720842b42dfSAlex Bennée         trace_gdbstub_hit_internal_error();
2721842b42dfSAlex Bennée         ret = GDB_SIGNAL_ABRT;
2722842b42dfSAlex Bennée         break;
2723842b42dfSAlex Bennée     case RUN_STATE_SAVE_VM:
2724842b42dfSAlex Bennée     case RUN_STATE_RESTORE_VM:
2725842b42dfSAlex Bennée         return;
2726842b42dfSAlex Bennée     case RUN_STATE_FINISH_MIGRATE:
2727842b42dfSAlex Bennée         ret = GDB_SIGNAL_XCPU;
2728842b42dfSAlex Bennée         break;
2729842b42dfSAlex Bennée     default:
2730842b42dfSAlex Bennée         trace_gdbstub_hit_unknown(state);
2731842b42dfSAlex Bennée         ret = GDB_SIGNAL_UNKNOWN;
2732842b42dfSAlex Bennée         break;
2733842b42dfSAlex Bennée     }
2734842b42dfSAlex Bennée     gdb_set_stop_cpu(cpu);
2735842b42dfSAlex Bennée     g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
2736842b42dfSAlex Bennée 
2737842b42dfSAlex Bennée send_packet:
273836e067b2SAlex Bennée     gdb_put_packet(buf->str);
2739842b42dfSAlex Bennée 
2740842b42dfSAlex Bennée     /* disable single step if it was enabled */
2741842b42dfSAlex Bennée     cpu_single_step(cpu, 0);
2742842b42dfSAlex Bennée }
2743842b42dfSAlex Bennée #endif
2744842b42dfSAlex Bennée 
2745842b42dfSAlex Bennée /* Send a gdb syscall request.
2746842b42dfSAlex Bennée    This accepts limited printf-style format specifiers, specifically:
2747842b42dfSAlex Bennée     %x  - target_ulong argument printed in hex.
2748842b42dfSAlex Bennée     %lx - 64-bit argument printed in hex.
2749842b42dfSAlex Bennée     %s  - string pointer (target_ulong) and length (int) pair.  */
2750842b42dfSAlex Bennée void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
2751842b42dfSAlex Bennée {
2752842b42dfSAlex Bennée     char *p;
2753842b42dfSAlex Bennée     char *p_end;
2754842b42dfSAlex Bennée     target_ulong addr;
2755842b42dfSAlex Bennée     uint64_t i64;
2756842b42dfSAlex Bennée 
2757842b42dfSAlex Bennée     if (!gdb_attached()) {
2758842b42dfSAlex Bennée         return;
2759842b42dfSAlex Bennée     }
2760842b42dfSAlex Bennée 
2761842b42dfSAlex Bennée     gdbserver_state.current_syscall_cb = cb;
2762842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2763842b42dfSAlex Bennée     vm_stop(RUN_STATE_DEBUG);
2764842b42dfSAlex Bennée #endif
2765842b42dfSAlex Bennée     p = &gdbserver_state.syscall_buf[0];
2766842b42dfSAlex Bennée     p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
2767842b42dfSAlex Bennée     *(p++) = 'F';
2768842b42dfSAlex Bennée     while (*fmt) {
2769842b42dfSAlex Bennée         if (*fmt == '%') {
2770842b42dfSAlex Bennée             fmt++;
2771842b42dfSAlex Bennée             switch (*fmt++) {
2772842b42dfSAlex Bennée             case 'x':
2773842b42dfSAlex Bennée                 addr = va_arg(va, target_ulong);
2774842b42dfSAlex Bennée                 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
2775842b42dfSAlex Bennée                 break;
2776842b42dfSAlex Bennée             case 'l':
2777842b42dfSAlex Bennée                 if (*(fmt++) != 'x')
2778842b42dfSAlex Bennée                     goto bad_format;
2779842b42dfSAlex Bennée                 i64 = va_arg(va, uint64_t);
2780842b42dfSAlex Bennée                 p += snprintf(p, p_end - p, "%" PRIx64, i64);
2781842b42dfSAlex Bennée                 break;
2782842b42dfSAlex Bennée             case 's':
2783842b42dfSAlex Bennée                 addr = va_arg(va, target_ulong);
2784842b42dfSAlex Bennée                 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
2785842b42dfSAlex Bennée                               addr, va_arg(va, int));
2786842b42dfSAlex Bennée                 break;
2787842b42dfSAlex Bennée             default:
2788842b42dfSAlex Bennée             bad_format:
2789842b42dfSAlex Bennée                 error_report("gdbstub: Bad syscall format string '%s'",
2790842b42dfSAlex Bennée                              fmt - 1);
2791842b42dfSAlex Bennée                 break;
2792842b42dfSAlex Bennée             }
2793842b42dfSAlex Bennée         } else {
2794842b42dfSAlex Bennée             *(p++) = *(fmt++);
2795842b42dfSAlex Bennée         }
2796842b42dfSAlex Bennée     }
2797842b42dfSAlex Bennée     *p = 0;
2798842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
279936e067b2SAlex Bennée     gdb_put_packet(gdbserver_state.syscall_buf);
2800842b42dfSAlex Bennée     /* Return control to gdb for it to process the syscall request.
2801842b42dfSAlex Bennée      * Since the protocol requires that gdb hands control back to us
2802842b42dfSAlex Bennée      * using a "here are the results" F packet, we don't need to check
2803842b42dfSAlex Bennée      * gdb_handlesig's return value (which is the signal to deliver if
2804842b42dfSAlex Bennée      * execution was resumed via a continue packet).
2805842b42dfSAlex Bennée      */
2806842b42dfSAlex Bennée     gdb_handlesig(gdbserver_state.c_cpu, 0);
2807842b42dfSAlex Bennée #else
2808842b42dfSAlex Bennée     /* In this case wait to send the syscall packet until notification that
2809842b42dfSAlex Bennée        the CPU has stopped.  This must be done because if the packet is sent
2810842b42dfSAlex Bennée        now the reply from the syscall request could be received while the CPU
2811842b42dfSAlex Bennée        is still in the running state, which can cause packets to be dropped
2812842b42dfSAlex Bennée        and state transition 'T' packets to be sent while the syscall is still
2813842b42dfSAlex Bennée        being processed.  */
2814842b42dfSAlex Bennée     qemu_cpu_kick(gdbserver_state.c_cpu);
2815842b42dfSAlex Bennée #endif
2816842b42dfSAlex Bennée }
2817842b42dfSAlex Bennée 
2818842b42dfSAlex Bennée void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2819842b42dfSAlex Bennée {
2820842b42dfSAlex Bennée     va_list va;
2821842b42dfSAlex Bennée 
2822842b42dfSAlex Bennée     va_start(va, fmt);
2823842b42dfSAlex Bennée     gdb_do_syscallv(cb, fmt, va);
2824842b42dfSAlex Bennée     va_end(va);
2825842b42dfSAlex Bennée }
2826842b42dfSAlex Bennée 
282736e067b2SAlex Bennée void gdb_read_byte(uint8_t ch)
2828842b42dfSAlex Bennée {
2829842b42dfSAlex Bennée     uint8_t reply;
2830842b42dfSAlex Bennée 
2831842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2832842b42dfSAlex Bennée     if (gdbserver_state.last_packet->len) {
2833842b42dfSAlex Bennée         /* Waiting for a response to the last packet.  If we see the start
2834842b42dfSAlex Bennée            of a new command then abandon the previous response.  */
2835842b42dfSAlex Bennée         if (ch == '-') {
2836842b42dfSAlex Bennée             trace_gdbstub_err_got_nack();
283736e067b2SAlex Bennée             gdb_put_buffer(gdbserver_state.last_packet->data,
2838842b42dfSAlex Bennée                        gdbserver_state.last_packet->len);
2839842b42dfSAlex Bennée         } else if (ch == '+') {
2840842b42dfSAlex Bennée             trace_gdbstub_io_got_ack();
2841842b42dfSAlex Bennée         } else {
2842842b42dfSAlex Bennée             trace_gdbstub_io_got_unexpected(ch);
2843842b42dfSAlex Bennée         }
2844842b42dfSAlex Bennée 
2845842b42dfSAlex Bennée         if (ch == '+' || ch == '$') {
2846842b42dfSAlex Bennée             g_byte_array_set_size(gdbserver_state.last_packet, 0);
2847842b42dfSAlex Bennée         }
2848842b42dfSAlex Bennée         if (ch != '$')
2849842b42dfSAlex Bennée             return;
2850842b42dfSAlex Bennée     }
2851842b42dfSAlex Bennée     if (runstate_is_running()) {
2852842b42dfSAlex Bennée         /* when the CPU is running, we cannot do anything except stop
2853842b42dfSAlex Bennée            it when receiving a char */
2854842b42dfSAlex Bennée         vm_stop(RUN_STATE_PAUSED);
2855842b42dfSAlex Bennée     } else
2856842b42dfSAlex Bennée #endif
2857842b42dfSAlex Bennée     {
2858842b42dfSAlex Bennée         switch(gdbserver_state.state) {
2859842b42dfSAlex Bennée         case RS_IDLE:
2860842b42dfSAlex Bennée             if (ch == '$') {
2861842b42dfSAlex Bennée                 /* start of command packet */
2862842b42dfSAlex Bennée                 gdbserver_state.line_buf_index = 0;
2863842b42dfSAlex Bennée                 gdbserver_state.line_sum = 0;
2864842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2865842b42dfSAlex Bennée             } else {
2866842b42dfSAlex Bennée                 trace_gdbstub_err_garbage(ch);
2867842b42dfSAlex Bennée             }
2868842b42dfSAlex Bennée             break;
2869842b42dfSAlex Bennée         case RS_GETLINE:
2870842b42dfSAlex Bennée             if (ch == '}') {
2871842b42dfSAlex Bennée                 /* start escape sequence */
2872842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE_ESC;
2873842b42dfSAlex Bennée                 gdbserver_state.line_sum += ch;
2874842b42dfSAlex Bennée             } else if (ch == '*') {
2875842b42dfSAlex Bennée                 /* start run length encoding sequence */
2876842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE_RLE;
2877842b42dfSAlex Bennée                 gdbserver_state.line_sum += ch;
2878842b42dfSAlex Bennée             } else if (ch == '#') {
2879842b42dfSAlex Bennée                 /* end of command, start of checksum*/
2880842b42dfSAlex Bennée                 gdbserver_state.state = RS_CHKSUM1;
2881842b42dfSAlex Bennée             } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
2882842b42dfSAlex Bennée                 trace_gdbstub_err_overrun();
2883842b42dfSAlex Bennée                 gdbserver_state.state = RS_IDLE;
2884842b42dfSAlex Bennée             } else {
2885842b42dfSAlex Bennée                 /* unescaped command character */
2886842b42dfSAlex Bennée                 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
2887842b42dfSAlex Bennée                 gdbserver_state.line_sum += ch;
2888842b42dfSAlex Bennée             }
2889842b42dfSAlex Bennée             break;
2890842b42dfSAlex Bennée         case RS_GETLINE_ESC:
2891842b42dfSAlex Bennée             if (ch == '#') {
2892842b42dfSAlex Bennée                 /* unexpected end of command in escape sequence */
2893842b42dfSAlex Bennée                 gdbserver_state.state = RS_CHKSUM1;
2894842b42dfSAlex Bennée             } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
2895842b42dfSAlex Bennée                 /* command buffer overrun */
2896842b42dfSAlex Bennée                 trace_gdbstub_err_overrun();
2897842b42dfSAlex Bennée                 gdbserver_state.state = RS_IDLE;
2898842b42dfSAlex Bennée             } else {
2899842b42dfSAlex Bennée                 /* parse escaped character and leave escape state */
2900842b42dfSAlex Bennée                 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
2901842b42dfSAlex Bennée                 gdbserver_state.line_sum += ch;
2902842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2903842b42dfSAlex Bennée             }
2904842b42dfSAlex Bennée             break;
2905842b42dfSAlex Bennée         case RS_GETLINE_RLE:
2906842b42dfSAlex Bennée             /*
2907842b42dfSAlex Bennée              * Run-length encoding is explained in "Debugging with GDB /
2908842b42dfSAlex Bennée              * Appendix E GDB Remote Serial Protocol / Overview".
2909842b42dfSAlex Bennée              */
2910842b42dfSAlex Bennée             if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
2911842b42dfSAlex Bennée                 /* invalid RLE count encoding */
2912842b42dfSAlex Bennée                 trace_gdbstub_err_invalid_repeat(ch);
2913842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2914842b42dfSAlex Bennée             } else {
2915842b42dfSAlex Bennée                 /* decode repeat length */
2916842b42dfSAlex Bennée                 int repeat = ch - ' ' + 3;
2917842b42dfSAlex Bennée                 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
2918842b42dfSAlex Bennée                     /* that many repeats would overrun the command buffer */
2919842b42dfSAlex Bennée                     trace_gdbstub_err_overrun();
2920842b42dfSAlex Bennée                     gdbserver_state.state = RS_IDLE;
2921842b42dfSAlex Bennée                 } else if (gdbserver_state.line_buf_index < 1) {
2922842b42dfSAlex Bennée                     /* got a repeat but we have nothing to repeat */
2923842b42dfSAlex Bennée                     trace_gdbstub_err_invalid_rle();
2924842b42dfSAlex Bennée                     gdbserver_state.state = RS_GETLINE;
2925842b42dfSAlex Bennée                 } else {
2926842b42dfSAlex Bennée                     /* repeat the last character */
2927842b42dfSAlex Bennée                     memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
2928842b42dfSAlex Bennée                            gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
2929842b42dfSAlex Bennée                     gdbserver_state.line_buf_index += repeat;
2930842b42dfSAlex Bennée                     gdbserver_state.line_sum += ch;
2931842b42dfSAlex Bennée                     gdbserver_state.state = RS_GETLINE;
2932842b42dfSAlex Bennée                 }
2933842b42dfSAlex Bennée             }
2934842b42dfSAlex Bennée             break;
2935842b42dfSAlex Bennée         case RS_CHKSUM1:
2936842b42dfSAlex Bennée             /* get high hex digit of checksum */
2937842b42dfSAlex Bennée             if (!isxdigit(ch)) {
2938842b42dfSAlex Bennée                 trace_gdbstub_err_checksum_invalid(ch);
2939842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2940842b42dfSAlex Bennée                 break;
2941842b42dfSAlex Bennée             }
2942842b42dfSAlex Bennée             gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
2943842b42dfSAlex Bennée             gdbserver_state.line_csum = fromhex(ch) << 4;
2944842b42dfSAlex Bennée             gdbserver_state.state = RS_CHKSUM2;
2945842b42dfSAlex Bennée             break;
2946842b42dfSAlex Bennée         case RS_CHKSUM2:
2947842b42dfSAlex Bennée             /* get low hex digit of checksum */
2948842b42dfSAlex Bennée             if (!isxdigit(ch)) {
2949842b42dfSAlex Bennée                 trace_gdbstub_err_checksum_invalid(ch);
2950842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2951842b42dfSAlex Bennée                 break;
2952842b42dfSAlex Bennée             }
2953842b42dfSAlex Bennée             gdbserver_state.line_csum |= fromhex(ch);
2954842b42dfSAlex Bennée 
2955842b42dfSAlex Bennée             if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
2956842b42dfSAlex Bennée                 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
2957842b42dfSAlex Bennée                 /* send NAK reply */
2958842b42dfSAlex Bennée                 reply = '-';
295936e067b2SAlex Bennée                 gdb_put_buffer(&reply, 1);
2960842b42dfSAlex Bennée                 gdbserver_state.state = RS_IDLE;
2961842b42dfSAlex Bennée             } else {
2962842b42dfSAlex Bennée                 /* send ACK reply */
2963842b42dfSAlex Bennée                 reply = '+';
296436e067b2SAlex Bennée                 gdb_put_buffer(&reply, 1);
2965842b42dfSAlex Bennée                 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
2966842b42dfSAlex Bennée             }
2967842b42dfSAlex Bennée             break;
2968842b42dfSAlex Bennée         default:
2969842b42dfSAlex Bennée             abort();
2970842b42dfSAlex Bennée         }
2971842b42dfSAlex Bennée     }
2972842b42dfSAlex Bennée }
2973842b42dfSAlex Bennée 
2974842b42dfSAlex Bennée /* Tell the remote gdb that the process has exited.  */
2975842b42dfSAlex Bennée void gdb_exit(int code)
2976842b42dfSAlex Bennée {
2977842b42dfSAlex Bennée     char buf[4];
2978842b42dfSAlex Bennée 
2979842b42dfSAlex Bennée     if (!gdbserver_state.init) {
2980842b42dfSAlex Bennée         return;
2981842b42dfSAlex Bennée     }
2982842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
29838e70c6f9SAlex Bennée     if (gdbserver_user_state.socket_path) {
29848e70c6f9SAlex Bennée         unlink(gdbserver_user_state.socket_path);
2985842b42dfSAlex Bennée     }
29868e70c6f9SAlex Bennée     if (gdbserver_user_state.fd < 0) {
2987842b42dfSAlex Bennée         return;
2988842b42dfSAlex Bennée     }
2989842b42dfSAlex Bennée #endif
2990842b42dfSAlex Bennée 
2991842b42dfSAlex Bennée     trace_gdbstub_op_exiting((uint8_t)code);
2992842b42dfSAlex Bennée 
2993842b42dfSAlex Bennée     snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
299436e067b2SAlex Bennée     gdb_put_packet(buf);
2995842b42dfSAlex Bennée 
2996842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
29978e70c6f9SAlex Bennée     qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
2998842b42dfSAlex Bennée #endif
2999842b42dfSAlex Bennée }
3000842b42dfSAlex Bennée 
3001842b42dfSAlex Bennée /*
3002842b42dfSAlex Bennée  * Create the process that will contain all the "orphan" CPUs (that are not
3003842b42dfSAlex Bennée  * part of a CPU cluster). Note that if this process contains no CPUs, it won't
3004842b42dfSAlex Bennée  * be attachable and thus will be invisible to the user.
3005842b42dfSAlex Bennée  */
300636e067b2SAlex Bennée void gdb_create_default_process(GDBState *s)
3007842b42dfSAlex Bennée {
3008842b42dfSAlex Bennée     GDBProcess *process;
3009842b42dfSAlex Bennée     int max_pid = 0;
3010842b42dfSAlex Bennée 
3011842b42dfSAlex Bennée     if (gdbserver_state.process_num) {
3012842b42dfSAlex Bennée         max_pid = s->processes[s->process_num - 1].pid;
3013842b42dfSAlex Bennée     }
3014842b42dfSAlex Bennée 
3015842b42dfSAlex Bennée     s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3016842b42dfSAlex Bennée     process = &s->processes[s->process_num - 1];
3017842b42dfSAlex Bennée 
3018842b42dfSAlex Bennée     /* We need an available PID slot for this process */
3019842b42dfSAlex Bennée     assert(max_pid < UINT32_MAX);
3020842b42dfSAlex Bennée 
3021842b42dfSAlex Bennée     process->pid = max_pid + 1;
3022842b42dfSAlex Bennée     process->attached = false;
3023842b42dfSAlex Bennée     process->target_xml[0] = '\0';
3024842b42dfSAlex Bennée }
3025842b42dfSAlex Bennée 
3026842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
3027842b42dfSAlex Bennée int
3028842b42dfSAlex Bennée gdb_handlesig(CPUState *cpu, int sig)
3029842b42dfSAlex Bennée {
3030842b42dfSAlex Bennée     char buf[256];
3031842b42dfSAlex Bennée     int n;
3032842b42dfSAlex Bennée 
30338e70c6f9SAlex Bennée     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
3034842b42dfSAlex Bennée         return sig;
3035842b42dfSAlex Bennée     }
3036842b42dfSAlex Bennée 
3037842b42dfSAlex Bennée     /* disable single step if it was enabled */
3038842b42dfSAlex Bennée     cpu_single_step(cpu, 0);
3039842b42dfSAlex Bennée     tb_flush(cpu);
3040842b42dfSAlex Bennée 
3041842b42dfSAlex Bennée     if (sig != 0) {
3042842b42dfSAlex Bennée         gdb_set_stop_cpu(cpu);
3043842b42dfSAlex Bennée         g_string_printf(gdbserver_state.str_buf,
3044842b42dfSAlex Bennée                         "T%02xthread:", target_signal_to_gdb(sig));
3045842b42dfSAlex Bennée         gdb_append_thread_id(cpu, gdbserver_state.str_buf);
3046842b42dfSAlex Bennée         g_string_append_c(gdbserver_state.str_buf, ';');
304736e067b2SAlex Bennée         gdb_put_strbuf();
3048842b42dfSAlex Bennée     }
304936e067b2SAlex Bennée     /*
305036e067b2SAlex Bennée      * gdb_put_packet() might have detected that the peer terminated the
305136e067b2SAlex Bennée      * connection.
305236e067b2SAlex Bennée      */
30538e70c6f9SAlex Bennée     if (gdbserver_user_state.fd < 0) {
3054842b42dfSAlex Bennée         return sig;
3055842b42dfSAlex Bennée     }
3056842b42dfSAlex Bennée 
3057842b42dfSAlex Bennée     sig = 0;
3058842b42dfSAlex Bennée     gdbserver_state.state = RS_IDLE;
30598e70c6f9SAlex Bennée     gdbserver_user_state.running_state = 0;
30608e70c6f9SAlex Bennée     while (gdbserver_user_state.running_state == 0) {
30618e70c6f9SAlex Bennée         n = read(gdbserver_user_state.fd, buf, 256);
3062842b42dfSAlex Bennée         if (n > 0) {
3063842b42dfSAlex Bennée             int i;
3064842b42dfSAlex Bennée 
3065842b42dfSAlex Bennée             for (i = 0; i < n; i++) {
3066842b42dfSAlex Bennée                 gdb_read_byte(buf[i]);
3067842b42dfSAlex Bennée             }
3068842b42dfSAlex Bennée         } else {
3069842b42dfSAlex Bennée             /* XXX: Connection closed.  Should probably wait for another
3070842b42dfSAlex Bennée                connection before continuing.  */
3071842b42dfSAlex Bennée             if (n == 0) {
30728e70c6f9SAlex Bennée                 close(gdbserver_user_state.fd);
3073842b42dfSAlex Bennée             }
30748e70c6f9SAlex Bennée             gdbserver_user_state.fd = -1;
3075842b42dfSAlex Bennée             return sig;
3076842b42dfSAlex Bennée         }
3077842b42dfSAlex Bennée     }
3078842b42dfSAlex Bennée     sig = gdbserver_state.signal;
3079842b42dfSAlex Bennée     gdbserver_state.signal = 0;
3080842b42dfSAlex Bennée     return sig;
3081842b42dfSAlex Bennée }
3082842b42dfSAlex Bennée 
3083842b42dfSAlex Bennée /* Tell the remote gdb that the process has exited due to SIG.  */
3084842b42dfSAlex Bennée void gdb_signalled(CPUArchState *env, int sig)
3085842b42dfSAlex Bennée {
3086842b42dfSAlex Bennée     char buf[4];
3087842b42dfSAlex Bennée 
30888e70c6f9SAlex Bennée     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
3089842b42dfSAlex Bennée         return;
3090842b42dfSAlex Bennée     }
3091842b42dfSAlex Bennée 
3092842b42dfSAlex Bennée     snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
309336e067b2SAlex Bennée     gdb_put_packet(buf);
3094842b42dfSAlex Bennée }
3095842b42dfSAlex Bennée 
3096842b42dfSAlex Bennée static void gdb_accept_init(int fd)
3097842b42dfSAlex Bennée {
309836e067b2SAlex Bennée     gdb_init_gdbserver_state();
309936e067b2SAlex Bennée     gdb_create_default_process(&gdbserver_state);
3100842b42dfSAlex Bennée     gdbserver_state.processes[0].attached = true;
3101842b42dfSAlex Bennée     gdbserver_state.c_cpu = gdb_first_attached_cpu();
3102842b42dfSAlex Bennée     gdbserver_state.g_cpu = gdbserver_state.c_cpu;
31038e70c6f9SAlex Bennée     gdbserver_user_state.fd = fd;
3104842b42dfSAlex Bennée     gdb_has_xml = false;
3105842b42dfSAlex Bennée }
3106842b42dfSAlex Bennée 
3107842b42dfSAlex Bennée static bool gdb_accept_socket(int gdb_fd)
3108842b42dfSAlex Bennée {
3109842b42dfSAlex Bennée     int fd;
3110842b42dfSAlex Bennée 
3111842b42dfSAlex Bennée     for(;;) {
3112842b42dfSAlex Bennée         fd = accept(gdb_fd, NULL, NULL);
3113842b42dfSAlex Bennée         if (fd < 0 && errno != EINTR) {
3114842b42dfSAlex Bennée             perror("accept socket");
3115842b42dfSAlex Bennée             return false;
3116842b42dfSAlex Bennée         } else if (fd >= 0) {
3117842b42dfSAlex Bennée             qemu_set_cloexec(fd);
3118842b42dfSAlex Bennée             break;
3119842b42dfSAlex Bennée         }
3120842b42dfSAlex Bennée     }
3121842b42dfSAlex Bennée 
3122842b42dfSAlex Bennée     gdb_accept_init(fd);
3123842b42dfSAlex Bennée     return true;
3124842b42dfSAlex Bennée }
3125842b42dfSAlex Bennée 
3126842b42dfSAlex Bennée static int gdbserver_open_socket(const char *path)
3127842b42dfSAlex Bennée {
3128842b42dfSAlex Bennée     struct sockaddr_un sockaddr = {};
3129842b42dfSAlex Bennée     int fd, ret;
3130842b42dfSAlex Bennée 
3131842b42dfSAlex Bennée     fd = socket(AF_UNIX, SOCK_STREAM, 0);
3132842b42dfSAlex Bennée     if (fd < 0) {
3133842b42dfSAlex Bennée         perror("create socket");
3134842b42dfSAlex Bennée         return -1;
3135842b42dfSAlex Bennée     }
3136842b42dfSAlex Bennée 
3137842b42dfSAlex Bennée     sockaddr.sun_family = AF_UNIX;
3138842b42dfSAlex Bennée     pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
3139842b42dfSAlex Bennée     ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3140842b42dfSAlex Bennée     if (ret < 0) {
3141842b42dfSAlex Bennée         perror("bind socket");
3142842b42dfSAlex Bennée         close(fd);
3143842b42dfSAlex Bennée         return -1;
3144842b42dfSAlex Bennée     }
3145842b42dfSAlex Bennée     ret = listen(fd, 1);
3146842b42dfSAlex Bennée     if (ret < 0) {
3147842b42dfSAlex Bennée         perror("listen socket");
3148842b42dfSAlex Bennée         close(fd);
3149842b42dfSAlex Bennée         return -1;
3150842b42dfSAlex Bennée     }
3151842b42dfSAlex Bennée 
3152842b42dfSAlex Bennée     return fd;
3153842b42dfSAlex Bennée }
3154842b42dfSAlex Bennée 
3155842b42dfSAlex Bennée static bool gdb_accept_tcp(int gdb_fd)
3156842b42dfSAlex Bennée {
3157842b42dfSAlex Bennée     struct sockaddr_in sockaddr = {};
3158842b42dfSAlex Bennée     socklen_t len;
3159842b42dfSAlex Bennée     int fd;
3160842b42dfSAlex Bennée 
3161842b42dfSAlex Bennée     for(;;) {
3162842b42dfSAlex Bennée         len = sizeof(sockaddr);
3163842b42dfSAlex Bennée         fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
3164842b42dfSAlex Bennée         if (fd < 0 && errno != EINTR) {
3165842b42dfSAlex Bennée             perror("accept");
3166842b42dfSAlex Bennée             return false;
3167842b42dfSAlex Bennée         } else if (fd >= 0) {
3168842b42dfSAlex Bennée             qemu_set_cloexec(fd);
3169842b42dfSAlex Bennée             break;
3170842b42dfSAlex Bennée         }
3171842b42dfSAlex Bennée     }
3172842b42dfSAlex Bennée 
3173842b42dfSAlex Bennée     /* set short latency */
3174842b42dfSAlex Bennée     if (socket_set_nodelay(fd)) {
3175842b42dfSAlex Bennée         perror("setsockopt");
3176842b42dfSAlex Bennée         close(fd);
3177842b42dfSAlex Bennée         return false;
3178842b42dfSAlex Bennée     }
3179842b42dfSAlex Bennée 
3180842b42dfSAlex Bennée     gdb_accept_init(fd);
3181842b42dfSAlex Bennée     return true;
3182842b42dfSAlex Bennée }
3183842b42dfSAlex Bennée 
3184842b42dfSAlex Bennée static int gdbserver_open_port(int port)
3185842b42dfSAlex Bennée {
3186842b42dfSAlex Bennée     struct sockaddr_in sockaddr;
3187842b42dfSAlex Bennée     int fd, ret;
3188842b42dfSAlex Bennée 
3189842b42dfSAlex Bennée     fd = socket(PF_INET, SOCK_STREAM, 0);
3190842b42dfSAlex Bennée     if (fd < 0) {
3191842b42dfSAlex Bennée         perror("socket");
3192842b42dfSAlex Bennée         return -1;
3193842b42dfSAlex Bennée     }
3194842b42dfSAlex Bennée     qemu_set_cloexec(fd);
3195842b42dfSAlex Bennée 
3196842b42dfSAlex Bennée     socket_set_fast_reuse(fd);
3197842b42dfSAlex Bennée 
3198842b42dfSAlex Bennée     sockaddr.sin_family = AF_INET;
3199842b42dfSAlex Bennée     sockaddr.sin_port = htons(port);
3200842b42dfSAlex Bennée     sockaddr.sin_addr.s_addr = 0;
3201842b42dfSAlex Bennée     ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3202842b42dfSAlex Bennée     if (ret < 0) {
3203842b42dfSAlex Bennée         perror("bind");
3204842b42dfSAlex Bennée         close(fd);
3205842b42dfSAlex Bennée         return -1;
3206842b42dfSAlex Bennée     }
3207842b42dfSAlex Bennée     ret = listen(fd, 1);
3208842b42dfSAlex Bennée     if (ret < 0) {
3209842b42dfSAlex Bennée         perror("listen");
3210842b42dfSAlex Bennée         close(fd);
3211842b42dfSAlex Bennée         return -1;
3212842b42dfSAlex Bennée     }
3213842b42dfSAlex Bennée 
3214842b42dfSAlex Bennée     return fd;
3215842b42dfSAlex Bennée }
3216842b42dfSAlex Bennée 
3217842b42dfSAlex Bennée int gdbserver_start(const char *port_or_path)
3218842b42dfSAlex Bennée {
3219842b42dfSAlex Bennée     int port = g_ascii_strtoull(port_or_path, NULL, 10);
3220842b42dfSAlex Bennée     int gdb_fd;
3221842b42dfSAlex Bennée 
3222842b42dfSAlex Bennée     if (port > 0) {
3223842b42dfSAlex Bennée         gdb_fd = gdbserver_open_port(port);
3224842b42dfSAlex Bennée     } else {
3225842b42dfSAlex Bennée         gdb_fd = gdbserver_open_socket(port_or_path);
3226842b42dfSAlex Bennée     }
3227842b42dfSAlex Bennée 
3228842b42dfSAlex Bennée     if (gdb_fd < 0) {
3229842b42dfSAlex Bennée         return -1;
3230842b42dfSAlex Bennée     }
3231842b42dfSAlex Bennée 
3232842b42dfSAlex Bennée     if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3233842b42dfSAlex Bennée         return 0;
3234842b42dfSAlex Bennée     } else if (gdb_accept_socket(gdb_fd)) {
32358e70c6f9SAlex Bennée         gdbserver_user_state.socket_path = g_strdup(port_or_path);
3236842b42dfSAlex Bennée         return 0;
3237842b42dfSAlex Bennée     }
3238842b42dfSAlex Bennée 
3239842b42dfSAlex Bennée     /* gone wrong */
3240842b42dfSAlex Bennée     close(gdb_fd);
3241842b42dfSAlex Bennée     return -1;
3242842b42dfSAlex Bennée }
3243842b42dfSAlex Bennée 
3244842b42dfSAlex Bennée /* Disable gdb stub for child processes.  */
3245842b42dfSAlex Bennée void gdbserver_fork(CPUState *cpu)
3246842b42dfSAlex Bennée {
32478e70c6f9SAlex Bennée     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
3248842b42dfSAlex Bennée         return;
3249842b42dfSAlex Bennée     }
32508e70c6f9SAlex Bennée     close(gdbserver_user_state.fd);
32518e70c6f9SAlex Bennée     gdbserver_user_state.fd = -1;
3252842b42dfSAlex Bennée     cpu_breakpoint_remove_all(cpu, BP_GDB);
3253842b42dfSAlex Bennée     cpu_watchpoint_remove_all(cpu, BP_GDB);
3254842b42dfSAlex Bennée }
3255842b42dfSAlex Bennée #else
3256842b42dfSAlex Bennée static int gdb_chr_can_receive(void *opaque)
3257842b42dfSAlex Bennée {
3258842b42dfSAlex Bennée   /* We can handle an arbitrarily large amount of data.
3259842b42dfSAlex Bennée    Pick the maximum packet size, which is as good as anything.  */
3260842b42dfSAlex Bennée   return MAX_PACKET_LENGTH;
3261842b42dfSAlex Bennée }
3262842b42dfSAlex Bennée 
3263842b42dfSAlex Bennée static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
3264842b42dfSAlex Bennée {
3265842b42dfSAlex Bennée     int i;
3266842b42dfSAlex Bennée 
3267842b42dfSAlex Bennée     for (i = 0; i < size; i++) {
3268842b42dfSAlex Bennée         gdb_read_byte(buf[i]);
3269842b42dfSAlex Bennée     }
3270842b42dfSAlex Bennée }
3271842b42dfSAlex Bennée 
3272842b42dfSAlex Bennée static void gdb_chr_event(void *opaque, QEMUChrEvent event)
3273842b42dfSAlex Bennée {
3274842b42dfSAlex Bennée     int i;
3275842b42dfSAlex Bennée     GDBState *s = (GDBState *) opaque;
3276842b42dfSAlex Bennée 
3277842b42dfSAlex Bennée     switch (event) {
3278842b42dfSAlex Bennée     case CHR_EVENT_OPENED:
3279842b42dfSAlex Bennée         /* Start with first process attached, others detached */
3280842b42dfSAlex Bennée         for (i = 0; i < s->process_num; i++) {
3281842b42dfSAlex Bennée             s->processes[i].attached = !i;
3282842b42dfSAlex Bennée         }
3283842b42dfSAlex Bennée 
3284842b42dfSAlex Bennée         s->c_cpu = gdb_first_attached_cpu();
3285842b42dfSAlex Bennée         s->g_cpu = s->c_cpu;
3286842b42dfSAlex Bennée 
3287842b42dfSAlex Bennée         vm_stop(RUN_STATE_PAUSED);
3288842b42dfSAlex Bennée         replay_gdb_attached();
3289842b42dfSAlex Bennée         gdb_has_xml = false;
3290842b42dfSAlex Bennée         break;
3291842b42dfSAlex Bennée     default:
3292842b42dfSAlex Bennée         break;
3293842b42dfSAlex Bennée     }
3294842b42dfSAlex Bennée }
3295842b42dfSAlex Bennée 
3296842b42dfSAlex Bennée static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
3297842b42dfSAlex Bennée {
3298842b42dfSAlex Bennée     g_autoptr(GString) hex_buf = g_string_new("O");
329936e067b2SAlex Bennée     gdb_memtohex(hex_buf, buf, len);
330036e067b2SAlex Bennée     gdb_put_packet(hex_buf->str);
3301842b42dfSAlex Bennée     return len;
3302842b42dfSAlex Bennée }
3303842b42dfSAlex Bennée 
3304842b42dfSAlex Bennée #ifndef _WIN32
3305842b42dfSAlex Bennée static void gdb_sigterm_handler(int signal)
3306842b42dfSAlex Bennée {
3307842b42dfSAlex Bennée     if (runstate_is_running()) {
3308842b42dfSAlex Bennée         vm_stop(RUN_STATE_PAUSED);
3309842b42dfSAlex Bennée     }
3310842b42dfSAlex Bennée }
3311842b42dfSAlex Bennée #endif
3312842b42dfSAlex Bennée 
3313842b42dfSAlex Bennée static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
3314842b42dfSAlex Bennée                              bool *be_opened, Error **errp)
3315842b42dfSAlex Bennée {
3316842b42dfSAlex Bennée     *be_opened = false;
3317842b42dfSAlex Bennée }
3318842b42dfSAlex Bennée 
3319842b42dfSAlex Bennée static void char_gdb_class_init(ObjectClass *oc, void *data)
3320842b42dfSAlex Bennée {
3321842b42dfSAlex Bennée     ChardevClass *cc = CHARDEV_CLASS(oc);
3322842b42dfSAlex Bennée 
3323842b42dfSAlex Bennée     cc->internal = true;
3324842b42dfSAlex Bennée     cc->open = gdb_monitor_open;
3325842b42dfSAlex Bennée     cc->chr_write = gdb_monitor_write;
3326842b42dfSAlex Bennée }
3327842b42dfSAlex Bennée 
3328842b42dfSAlex Bennée #define TYPE_CHARDEV_GDB "chardev-gdb"
3329842b42dfSAlex Bennée 
3330842b42dfSAlex Bennée static const TypeInfo char_gdb_type_info = {
3331842b42dfSAlex Bennée     .name = TYPE_CHARDEV_GDB,
3332842b42dfSAlex Bennée     .parent = TYPE_CHARDEV,
3333842b42dfSAlex Bennée     .class_init = char_gdb_class_init,
3334842b42dfSAlex Bennée };
3335842b42dfSAlex Bennée 
3336842b42dfSAlex Bennée static int find_cpu_clusters(Object *child, void *opaque)
3337842b42dfSAlex Bennée {
3338842b42dfSAlex Bennée     if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
3339842b42dfSAlex Bennée         GDBState *s = (GDBState *) opaque;
3340842b42dfSAlex Bennée         CPUClusterState *cluster = CPU_CLUSTER(child);
3341842b42dfSAlex Bennée         GDBProcess *process;
3342842b42dfSAlex Bennée 
3343842b42dfSAlex Bennée         s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
3344842b42dfSAlex Bennée 
3345842b42dfSAlex Bennée         process = &s->processes[s->process_num - 1];
3346842b42dfSAlex Bennée 
3347842b42dfSAlex Bennée         /*
3348842b42dfSAlex Bennée          * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
3349842b42dfSAlex Bennée          * runtime, we enforce here that the machine does not use a cluster ID
3350842b42dfSAlex Bennée          * that would lead to PID 0.
3351842b42dfSAlex Bennée          */
3352842b42dfSAlex Bennée         assert(cluster->cluster_id != UINT32_MAX);
3353842b42dfSAlex Bennée         process->pid = cluster->cluster_id + 1;
3354842b42dfSAlex Bennée         process->attached = false;
3355842b42dfSAlex Bennée         process->target_xml[0] = '\0';
3356842b42dfSAlex Bennée 
3357842b42dfSAlex Bennée         return 0;
3358842b42dfSAlex Bennée     }
3359842b42dfSAlex Bennée 
3360842b42dfSAlex Bennée     return object_child_foreach(child, find_cpu_clusters, opaque);
3361842b42dfSAlex Bennée }
3362842b42dfSAlex Bennée 
3363842b42dfSAlex Bennée static int pid_order(const void *a, const void *b)
3364842b42dfSAlex Bennée {
3365842b42dfSAlex Bennée     GDBProcess *pa = (GDBProcess *) a;
3366842b42dfSAlex Bennée     GDBProcess *pb = (GDBProcess *) b;
3367842b42dfSAlex Bennée 
3368842b42dfSAlex Bennée     if (pa->pid < pb->pid) {
3369842b42dfSAlex Bennée         return -1;
3370842b42dfSAlex Bennée     } else if (pa->pid > pb->pid) {
3371842b42dfSAlex Bennée         return 1;
3372842b42dfSAlex Bennée     } else {
3373842b42dfSAlex Bennée         return 0;
3374842b42dfSAlex Bennée     }
3375842b42dfSAlex Bennée }
3376842b42dfSAlex Bennée 
3377842b42dfSAlex Bennée static void create_processes(GDBState *s)
3378842b42dfSAlex Bennée {
3379842b42dfSAlex Bennée     object_child_foreach(object_get_root(), find_cpu_clusters, s);
3380842b42dfSAlex Bennée 
3381842b42dfSAlex Bennée     if (gdbserver_state.processes) {
3382842b42dfSAlex Bennée         /* Sort by PID */
3383842b42dfSAlex Bennée         qsort(gdbserver_state.processes, gdbserver_state.process_num, sizeof(gdbserver_state.processes[0]), pid_order);
3384842b42dfSAlex Bennée     }
3385842b42dfSAlex Bennée 
338636e067b2SAlex Bennée     gdb_create_default_process(s);
3387842b42dfSAlex Bennée }
3388842b42dfSAlex Bennée 
3389842b42dfSAlex Bennée int gdbserver_start(const char *device)
3390842b42dfSAlex Bennée {
3391842b42dfSAlex Bennée     trace_gdbstub_op_start(device);
3392842b42dfSAlex Bennée 
3393842b42dfSAlex Bennée     char gdbstub_device_name[128];
3394842b42dfSAlex Bennée     Chardev *chr = NULL;
3395842b42dfSAlex Bennée     Chardev *mon_chr;
3396842b42dfSAlex Bennée 
3397842b42dfSAlex Bennée     if (!first_cpu) {
3398842b42dfSAlex Bennée         error_report("gdbstub: meaningless to attach gdb to a "
3399842b42dfSAlex Bennée                      "machine without any CPU.");
3400842b42dfSAlex Bennée         return -1;
3401842b42dfSAlex Bennée     }
3402842b42dfSAlex Bennée 
3403a48e7d9eSAlex Bennée     if (!gdb_supports_guest_debug()) {
3404a48e7d9eSAlex Bennée         error_report("gdbstub: current accelerator doesn't support guest debugging");
3405842b42dfSAlex Bennée         return -1;
3406842b42dfSAlex Bennée     }
3407842b42dfSAlex Bennée 
3408842b42dfSAlex Bennée     if (!device)
3409842b42dfSAlex Bennée         return -1;
3410842b42dfSAlex Bennée     if (strcmp(device, "none") != 0) {
3411842b42dfSAlex Bennée         if (strstart(device, "tcp:", NULL)) {
3412842b42dfSAlex Bennée             /* enforce required TCP attributes */
3413842b42dfSAlex Bennée             snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
3414842b42dfSAlex Bennée                      "%s,wait=off,nodelay=on,server=on", device);
3415842b42dfSAlex Bennée             device = gdbstub_device_name;
3416842b42dfSAlex Bennée         }
3417842b42dfSAlex Bennée #ifndef _WIN32
3418842b42dfSAlex Bennée         else if (strcmp(device, "stdio") == 0) {
3419842b42dfSAlex Bennée             struct sigaction act;
3420842b42dfSAlex Bennée 
3421842b42dfSAlex Bennée             memset(&act, 0, sizeof(act));
3422842b42dfSAlex Bennée             act.sa_handler = gdb_sigterm_handler;
3423842b42dfSAlex Bennée             sigaction(SIGINT, &act, NULL);
3424842b42dfSAlex Bennée         }
3425842b42dfSAlex Bennée #endif
3426842b42dfSAlex Bennée         /*
3427842b42dfSAlex Bennée          * FIXME: it's a bit weird to allow using a mux chardev here
3428842b42dfSAlex Bennée          * and implicitly setup a monitor. We may want to break this.
3429842b42dfSAlex Bennée          */
3430842b42dfSAlex Bennée         chr = qemu_chr_new_noreplay("gdb", device, true, NULL);
3431842b42dfSAlex Bennée         if (!chr)
3432842b42dfSAlex Bennée             return -1;
3433842b42dfSAlex Bennée     }
3434842b42dfSAlex Bennée 
3435842b42dfSAlex Bennée     if (!gdbserver_state.init) {
343636e067b2SAlex Bennée         gdb_init_gdbserver_state();
3437842b42dfSAlex Bennée 
3438842b42dfSAlex Bennée         qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
3439842b42dfSAlex Bennée 
3440842b42dfSAlex Bennée         /* Initialize a monitor terminal for gdb */
3441842b42dfSAlex Bennée         mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
3442842b42dfSAlex Bennée                                    NULL, NULL, &error_abort);
3443842b42dfSAlex Bennée         monitor_init_hmp(mon_chr, false, &error_abort);
3444842b42dfSAlex Bennée     } else {
34458e70c6f9SAlex Bennée         qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
34468e70c6f9SAlex Bennée         mon_chr = gdbserver_system_state.mon_chr;
3447842b42dfSAlex Bennée         reset_gdbserver_state();
3448842b42dfSAlex Bennée     }
3449842b42dfSAlex Bennée 
3450842b42dfSAlex Bennée     create_processes(&gdbserver_state);
3451842b42dfSAlex Bennée 
3452842b42dfSAlex Bennée     if (chr) {
34538e70c6f9SAlex Bennée         qemu_chr_fe_init(&gdbserver_system_state.chr, chr, &error_abort);
34548e70c6f9SAlex Bennée         qemu_chr_fe_set_handlers(&gdbserver_system_state.chr,
34558e70c6f9SAlex Bennée                                  gdb_chr_can_receive,
3456842b42dfSAlex Bennée                                  gdb_chr_receive, gdb_chr_event,
3457842b42dfSAlex Bennée                                  NULL, &gdbserver_state, NULL, true);
3458842b42dfSAlex Bennée     }
3459842b42dfSAlex Bennée     gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
34608e70c6f9SAlex Bennée     gdbserver_system_state.mon_chr = mon_chr;
3461842b42dfSAlex Bennée     gdbserver_state.current_syscall_cb = NULL;
3462842b42dfSAlex Bennée 
3463842b42dfSAlex Bennée     return 0;
3464842b42dfSAlex Bennée }
3465842b42dfSAlex Bennée 
3466842b42dfSAlex Bennée static void register_types(void)
3467842b42dfSAlex Bennée {
3468842b42dfSAlex Bennée     type_register_static(&char_gdb_type_info);
3469842b42dfSAlex Bennée }
3470842b42dfSAlex Bennée 
3471842b42dfSAlex Bennée type_init(register_types);
3472842b42dfSAlex Bennée #endif
3473