xref: /qemu/gdbstub/gdbstub.c (revision b6fa2ec2)
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 "qemu/ctype.h"
28842b42dfSAlex Bennée #include "qemu/cutils.h"
29842b42dfSAlex Bennée #include "qemu/module.h"
30842b42dfSAlex Bennée #include "trace.h"
31842b42dfSAlex Bennée #include "exec/gdbstub.h"
32842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
33842b42dfSAlex Bennée #include "qemu.h"
34842b42dfSAlex Bennée #else
35842b42dfSAlex Bennée #include "hw/cpu/cluster.h"
36842b42dfSAlex Bennée #include "hw/boards.h"
37842b42dfSAlex Bennée #endif
38842b42dfSAlex Bennée 
39842b42dfSAlex Bennée #include "qemu/sockets.h"
40842b42dfSAlex Bennée #include "sysemu/hw_accel.h"
41842b42dfSAlex Bennée #include "sysemu/runstate.h"
42842b42dfSAlex Bennée #include "semihosting/semihost.h"
43842b42dfSAlex Bennée #include "exec/exec-all.h"
445b5968c4SPhilippe Mathieu-Daudé #include "exec/replay-core.h"
45548c9609SAlex Bennée #include "exec/tb-flush.h"
46548c9609SAlex Bennée #include "exec/hwaddr.h"
47842b42dfSAlex Bennée 
48ae7467b1SAlex Bennée #include "internals.h"
49ae7467b1SAlex Bennée 
50842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
51842b42dfSAlex Bennée #define GDB_ATTACHED "0"
52842b42dfSAlex Bennée #else
53842b42dfSAlex Bennée #define GDB_ATTACHED "1"
54842b42dfSAlex Bennée #endif
55842b42dfSAlex Bennée 
56842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
57842b42dfSAlex Bennée static int phy_memory_mode;
58842b42dfSAlex Bennée #endif
59842b42dfSAlex Bennée 
60842b42dfSAlex Bennée static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
61842b42dfSAlex Bennée                                          uint8_t *buf, int len, bool is_write)
62842b42dfSAlex Bennée {
63842b42dfSAlex Bennée     CPUClass *cc;
64842b42dfSAlex Bennée 
65842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
66842b42dfSAlex Bennée     if (phy_memory_mode) {
67842b42dfSAlex Bennée         if (is_write) {
68842b42dfSAlex Bennée             cpu_physical_memory_write(addr, buf, len);
69842b42dfSAlex Bennée         } else {
70842b42dfSAlex Bennée             cpu_physical_memory_read(addr, buf, len);
71842b42dfSAlex Bennée         }
72842b42dfSAlex Bennée         return 0;
73842b42dfSAlex Bennée     }
74842b42dfSAlex Bennée #endif
75842b42dfSAlex Bennée 
76842b42dfSAlex Bennée     cc = CPU_GET_CLASS(cpu);
77842b42dfSAlex Bennée     if (cc->memory_rw_debug) {
78842b42dfSAlex Bennée         return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
79842b42dfSAlex Bennée     }
80842b42dfSAlex Bennée     return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
81842b42dfSAlex Bennée }
82842b42dfSAlex Bennée 
8336e067b2SAlex Bennée /*
8436e067b2SAlex Bennée  * Return the GDB index for a given vCPU state.
85842b42dfSAlex Bennée  *
86b6fa2ec2SAlex Bennée  * For user mode this is simply the thread id.
87842b42dfSAlex Bennée  */
88b6fa2ec2SAlex Bennée #if defined(CONFIG_USER_ONLY)
8936e067b2SAlex Bennée int gdb_get_cpu_index(CPUState *cpu)
90842b42dfSAlex Bennée {
91842b42dfSAlex Bennée     TaskState *ts = (TaskState *) cpu->opaque;
92842b42dfSAlex Bennée     return ts ? ts->ts_tid : -1;
93842b42dfSAlex Bennée }
94b6fa2ec2SAlex Bennée #endif
95842b42dfSAlex Bennée 
96842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
97842b42dfSAlex Bennée 
98842b42dfSAlex Bennée /* Map target signal numbers to GDB protocol signal numbers and vice
99842b42dfSAlex Bennée  * versa.  For user emulation's currently supported systems, we can
100842b42dfSAlex Bennée  * assume most signals are defined.
101842b42dfSAlex Bennée  */
102842b42dfSAlex Bennée 
103842b42dfSAlex Bennée static int gdb_signal_table[] = {
104842b42dfSAlex Bennée     0,
105842b42dfSAlex Bennée     TARGET_SIGHUP,
106842b42dfSAlex Bennée     TARGET_SIGINT,
107842b42dfSAlex Bennée     TARGET_SIGQUIT,
108842b42dfSAlex Bennée     TARGET_SIGILL,
109842b42dfSAlex Bennée     TARGET_SIGTRAP,
110842b42dfSAlex Bennée     TARGET_SIGABRT,
111842b42dfSAlex Bennée     -1, /* SIGEMT */
112842b42dfSAlex Bennée     TARGET_SIGFPE,
113842b42dfSAlex Bennée     TARGET_SIGKILL,
114842b42dfSAlex Bennée     TARGET_SIGBUS,
115842b42dfSAlex Bennée     TARGET_SIGSEGV,
116842b42dfSAlex Bennée     TARGET_SIGSYS,
117842b42dfSAlex Bennée     TARGET_SIGPIPE,
118842b42dfSAlex Bennée     TARGET_SIGALRM,
119842b42dfSAlex Bennée     TARGET_SIGTERM,
120842b42dfSAlex Bennée     TARGET_SIGURG,
121842b42dfSAlex Bennée     TARGET_SIGSTOP,
122842b42dfSAlex Bennée     TARGET_SIGTSTP,
123842b42dfSAlex Bennée     TARGET_SIGCONT,
124842b42dfSAlex Bennée     TARGET_SIGCHLD,
125842b42dfSAlex Bennée     TARGET_SIGTTIN,
126842b42dfSAlex Bennée     TARGET_SIGTTOU,
127842b42dfSAlex Bennée     TARGET_SIGIO,
128842b42dfSAlex Bennée     TARGET_SIGXCPU,
129842b42dfSAlex Bennée     TARGET_SIGXFSZ,
130842b42dfSAlex Bennée     TARGET_SIGVTALRM,
131842b42dfSAlex Bennée     TARGET_SIGPROF,
132842b42dfSAlex Bennée     TARGET_SIGWINCH,
133842b42dfSAlex Bennée     -1, /* SIGLOST */
134842b42dfSAlex Bennée     TARGET_SIGUSR1,
135842b42dfSAlex Bennée     TARGET_SIGUSR2,
136842b42dfSAlex Bennée #ifdef TARGET_SIGPWR
137842b42dfSAlex Bennée     TARGET_SIGPWR,
138842b42dfSAlex Bennée #else
139842b42dfSAlex Bennée     -1,
140842b42dfSAlex Bennée #endif
141842b42dfSAlex Bennée     -1, /* SIGPOLL */
142842b42dfSAlex Bennée     -1,
143842b42dfSAlex Bennée     -1,
144842b42dfSAlex Bennée     -1,
145842b42dfSAlex Bennée     -1,
146842b42dfSAlex Bennée     -1,
147842b42dfSAlex Bennée     -1,
148842b42dfSAlex Bennée     -1,
149842b42dfSAlex Bennée     -1,
150842b42dfSAlex Bennée     -1,
151842b42dfSAlex Bennée     -1,
152842b42dfSAlex Bennée     -1,
153842b42dfSAlex Bennée #ifdef __SIGRTMIN
154842b42dfSAlex Bennée     __SIGRTMIN + 1,
155842b42dfSAlex Bennée     __SIGRTMIN + 2,
156842b42dfSAlex Bennée     __SIGRTMIN + 3,
157842b42dfSAlex Bennée     __SIGRTMIN + 4,
158842b42dfSAlex Bennée     __SIGRTMIN + 5,
159842b42dfSAlex Bennée     __SIGRTMIN + 6,
160842b42dfSAlex Bennée     __SIGRTMIN + 7,
161842b42dfSAlex Bennée     __SIGRTMIN + 8,
162842b42dfSAlex Bennée     __SIGRTMIN + 9,
163842b42dfSAlex Bennée     __SIGRTMIN + 10,
164842b42dfSAlex Bennée     __SIGRTMIN + 11,
165842b42dfSAlex Bennée     __SIGRTMIN + 12,
166842b42dfSAlex Bennée     __SIGRTMIN + 13,
167842b42dfSAlex Bennée     __SIGRTMIN + 14,
168842b42dfSAlex Bennée     __SIGRTMIN + 15,
169842b42dfSAlex Bennée     __SIGRTMIN + 16,
170842b42dfSAlex Bennée     __SIGRTMIN + 17,
171842b42dfSAlex Bennée     __SIGRTMIN + 18,
172842b42dfSAlex Bennée     __SIGRTMIN + 19,
173842b42dfSAlex Bennée     __SIGRTMIN + 20,
174842b42dfSAlex Bennée     __SIGRTMIN + 21,
175842b42dfSAlex Bennée     __SIGRTMIN + 22,
176842b42dfSAlex Bennée     __SIGRTMIN + 23,
177842b42dfSAlex Bennée     __SIGRTMIN + 24,
178842b42dfSAlex Bennée     __SIGRTMIN + 25,
179842b42dfSAlex Bennée     __SIGRTMIN + 26,
180842b42dfSAlex Bennée     __SIGRTMIN + 27,
181842b42dfSAlex Bennée     __SIGRTMIN + 28,
182842b42dfSAlex Bennée     __SIGRTMIN + 29,
183842b42dfSAlex Bennée     __SIGRTMIN + 30,
184842b42dfSAlex Bennée     __SIGRTMIN + 31,
185842b42dfSAlex Bennée     -1, /* SIGCANCEL */
186842b42dfSAlex Bennée     __SIGRTMIN,
187842b42dfSAlex Bennée     __SIGRTMIN + 32,
188842b42dfSAlex Bennée     __SIGRTMIN + 33,
189842b42dfSAlex Bennée     __SIGRTMIN + 34,
190842b42dfSAlex Bennée     __SIGRTMIN + 35,
191842b42dfSAlex Bennée     __SIGRTMIN + 36,
192842b42dfSAlex Bennée     __SIGRTMIN + 37,
193842b42dfSAlex Bennée     __SIGRTMIN + 38,
194842b42dfSAlex Bennée     __SIGRTMIN + 39,
195842b42dfSAlex Bennée     __SIGRTMIN + 40,
196842b42dfSAlex Bennée     __SIGRTMIN + 41,
197842b42dfSAlex Bennée     __SIGRTMIN + 42,
198842b42dfSAlex Bennée     __SIGRTMIN + 43,
199842b42dfSAlex Bennée     __SIGRTMIN + 44,
200842b42dfSAlex Bennée     __SIGRTMIN + 45,
201842b42dfSAlex Bennée     __SIGRTMIN + 46,
202842b42dfSAlex Bennée     __SIGRTMIN + 47,
203842b42dfSAlex Bennée     __SIGRTMIN + 48,
204842b42dfSAlex Bennée     __SIGRTMIN + 49,
205842b42dfSAlex Bennée     __SIGRTMIN + 50,
206842b42dfSAlex Bennée     __SIGRTMIN + 51,
207842b42dfSAlex Bennée     __SIGRTMIN + 52,
208842b42dfSAlex Bennée     __SIGRTMIN + 53,
209842b42dfSAlex Bennée     __SIGRTMIN + 54,
210842b42dfSAlex Bennée     __SIGRTMIN + 55,
211842b42dfSAlex Bennée     __SIGRTMIN + 56,
212842b42dfSAlex Bennée     __SIGRTMIN + 57,
213842b42dfSAlex Bennée     __SIGRTMIN + 58,
214842b42dfSAlex Bennée     __SIGRTMIN + 59,
215842b42dfSAlex Bennée     __SIGRTMIN + 60,
216842b42dfSAlex Bennée     __SIGRTMIN + 61,
217842b42dfSAlex Bennée     __SIGRTMIN + 62,
218842b42dfSAlex Bennée     __SIGRTMIN + 63,
219842b42dfSAlex Bennée     __SIGRTMIN + 64,
220842b42dfSAlex Bennée     __SIGRTMIN + 65,
221842b42dfSAlex Bennée     __SIGRTMIN + 66,
222842b42dfSAlex Bennée     __SIGRTMIN + 67,
223842b42dfSAlex Bennée     __SIGRTMIN + 68,
224842b42dfSAlex Bennée     __SIGRTMIN + 69,
225842b42dfSAlex Bennée     __SIGRTMIN + 70,
226842b42dfSAlex Bennée     __SIGRTMIN + 71,
227842b42dfSAlex Bennée     __SIGRTMIN + 72,
228842b42dfSAlex Bennée     __SIGRTMIN + 73,
229842b42dfSAlex Bennée     __SIGRTMIN + 74,
230842b42dfSAlex Bennée     __SIGRTMIN + 75,
231842b42dfSAlex Bennée     __SIGRTMIN + 76,
232842b42dfSAlex Bennée     __SIGRTMIN + 77,
233842b42dfSAlex Bennée     __SIGRTMIN + 78,
234842b42dfSAlex Bennée     __SIGRTMIN + 79,
235842b42dfSAlex Bennée     __SIGRTMIN + 80,
236842b42dfSAlex Bennée     __SIGRTMIN + 81,
237842b42dfSAlex Bennée     __SIGRTMIN + 82,
238842b42dfSAlex Bennée     __SIGRTMIN + 83,
239842b42dfSAlex Bennée     __SIGRTMIN + 84,
240842b42dfSAlex Bennée     __SIGRTMIN + 85,
241842b42dfSAlex Bennée     __SIGRTMIN + 86,
242842b42dfSAlex Bennée     __SIGRTMIN + 87,
243842b42dfSAlex Bennée     __SIGRTMIN + 88,
244842b42dfSAlex Bennée     __SIGRTMIN + 89,
245842b42dfSAlex Bennée     __SIGRTMIN + 90,
246842b42dfSAlex Bennée     __SIGRTMIN + 91,
247842b42dfSAlex Bennée     __SIGRTMIN + 92,
248842b42dfSAlex Bennée     __SIGRTMIN + 93,
249842b42dfSAlex Bennée     __SIGRTMIN + 94,
250842b42dfSAlex Bennée     __SIGRTMIN + 95,
251842b42dfSAlex Bennée     -1, /* SIGINFO */
252842b42dfSAlex Bennée     -1, /* UNKNOWN */
253842b42dfSAlex Bennée     -1, /* DEFAULT */
254842b42dfSAlex Bennée     -1,
255842b42dfSAlex Bennée     -1,
256842b42dfSAlex Bennée     -1,
257842b42dfSAlex Bennée     -1,
258842b42dfSAlex Bennée     -1,
259842b42dfSAlex Bennée     -1
260842b42dfSAlex Bennée #endif
261842b42dfSAlex Bennée };
262842b42dfSAlex Bennée #else
263842b42dfSAlex Bennée /* In system mode we only need SIGINT and SIGTRAP; other signals
264842b42dfSAlex Bennée    are not yet supported.  */
265842b42dfSAlex Bennée 
266842b42dfSAlex Bennée enum {
267842b42dfSAlex Bennée     TARGET_SIGINT = 2,
268842b42dfSAlex Bennée     TARGET_SIGTRAP = 5
269842b42dfSAlex Bennée };
270842b42dfSAlex Bennée 
271842b42dfSAlex Bennée static int gdb_signal_table[] = {
272842b42dfSAlex Bennée     -1,
273842b42dfSAlex Bennée     -1,
274842b42dfSAlex Bennée     TARGET_SIGINT,
275842b42dfSAlex Bennée     -1,
276842b42dfSAlex Bennée     -1,
277842b42dfSAlex Bennée     TARGET_SIGTRAP
278842b42dfSAlex Bennée };
279842b42dfSAlex Bennée #endif
280842b42dfSAlex Bennée 
281842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
282842b42dfSAlex Bennée static int target_signal_to_gdb (int sig)
283842b42dfSAlex Bennée {
284842b42dfSAlex Bennée     int i;
285842b42dfSAlex Bennée     for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
286842b42dfSAlex Bennée         if (gdb_signal_table[i] == sig)
287842b42dfSAlex Bennée             return i;
288842b42dfSAlex Bennée     return GDB_SIGNAL_UNKNOWN;
289842b42dfSAlex Bennée }
290842b42dfSAlex Bennée #endif
291842b42dfSAlex Bennée 
292842b42dfSAlex Bennée static int gdb_signal_to_target (int sig)
293842b42dfSAlex Bennée {
294842b42dfSAlex Bennée     if (sig < ARRAY_SIZE (gdb_signal_table))
295842b42dfSAlex Bennée         return gdb_signal_table[sig];
296842b42dfSAlex Bennée     else
297842b42dfSAlex Bennée         return -1;
298842b42dfSAlex Bennée }
299842b42dfSAlex Bennée 
300842b42dfSAlex Bennée typedef struct GDBRegisterState {
301842b42dfSAlex Bennée     int base_reg;
302842b42dfSAlex Bennée     int num_regs;
303842b42dfSAlex Bennée     gdb_get_reg_cb get_reg;
304842b42dfSAlex Bennée     gdb_set_reg_cb set_reg;
305842b42dfSAlex Bennée     const char *xml;
306842b42dfSAlex Bennée     struct GDBRegisterState *next;
307842b42dfSAlex Bennée } GDBRegisterState;
308842b42dfSAlex Bennée 
3098e70c6f9SAlex Bennée #ifdef CONFIG_USER_ONLY
3108e70c6f9SAlex Bennée typedef struct {
3118e70c6f9SAlex Bennée     int fd;
3128e70c6f9SAlex Bennée     char *socket_path;
3138e70c6f9SAlex Bennée     int running_state;
3148e70c6f9SAlex Bennée } GDBUserState;
3158e70c6f9SAlex Bennée static GDBUserState gdbserver_user_state;
3168e70c6f9SAlex Bennée #endif
3178e70c6f9SAlex Bennée 
318b6fa2ec2SAlex Bennée GDBState gdbserver_state;
319842b42dfSAlex Bennée 
32036e067b2SAlex Bennée void gdb_init_gdbserver_state(void)
321842b42dfSAlex Bennée {
322842b42dfSAlex Bennée     g_assert(!gdbserver_state.init);
323842b42dfSAlex Bennée     memset(&gdbserver_state, 0, sizeof(GDBState));
324842b42dfSAlex Bennée     gdbserver_state.init = true;
325842b42dfSAlex Bennée     gdbserver_state.str_buf = g_string_new(NULL);
326842b42dfSAlex Bennée     gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
327842b42dfSAlex Bennée     gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
328842b42dfSAlex Bennée 
329842b42dfSAlex Bennée     /*
3303b7a9388SAlex Bennée      * What single-step modes are supported is accelerator dependent.
3313b7a9388SAlex Bennée      * By default try to use no IRQs and no timers while single
3323b7a9388SAlex Bennée      * stepping so as to make single stepping like a typical ICE HW step.
333842b42dfSAlex Bennée      */
3343b7a9388SAlex Bennée     gdbserver_state.supported_sstep_flags = accel_supported_gdbstub_sstep_flags();
335842b42dfSAlex Bennée     gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
336842b42dfSAlex Bennée     gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
337842b42dfSAlex Bennée }
338842b42dfSAlex Bennée 
339842b42dfSAlex Bennée bool gdb_has_xml;
340842b42dfSAlex Bennée 
341842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
342842b42dfSAlex Bennée 
343842b42dfSAlex Bennée static int get_char(void)
344842b42dfSAlex Bennée {
345842b42dfSAlex Bennée     uint8_t ch;
346842b42dfSAlex Bennée     int ret;
347842b42dfSAlex Bennée 
348842b42dfSAlex Bennée     for(;;) {
3498e70c6f9SAlex Bennée         ret = recv(gdbserver_user_state.fd, &ch, 1, 0);
350842b42dfSAlex Bennée         if (ret < 0) {
3518e70c6f9SAlex Bennée             if (errno == ECONNRESET) {
3528e70c6f9SAlex Bennée                 gdbserver_user_state.fd = -1;
3538e70c6f9SAlex Bennée             }
3548e70c6f9SAlex Bennée             if (errno != EINTR) {
355842b42dfSAlex Bennée                 return -1;
3568e70c6f9SAlex Bennée             }
357842b42dfSAlex Bennée         } else if (ret == 0) {
3588e70c6f9SAlex Bennée             close(gdbserver_user_state.fd);
3598e70c6f9SAlex Bennée             gdbserver_user_state.fd = -1;
360842b42dfSAlex Bennée             return -1;
361842b42dfSAlex Bennée         } else {
362842b42dfSAlex Bennée             break;
363842b42dfSAlex Bennée         }
364842b42dfSAlex Bennée     }
365842b42dfSAlex Bennée     return ch;
366842b42dfSAlex Bennée }
367842b42dfSAlex Bennée #endif
368842b42dfSAlex Bennée 
369842b42dfSAlex Bennée /*
370842b42dfSAlex Bennée  * Return true if there is a GDB currently connected to the stub
371842b42dfSAlex Bennée  * and attached to a CPU
372842b42dfSAlex Bennée  */
373842b42dfSAlex Bennée static bool gdb_attached(void)
374842b42dfSAlex Bennée {
375842b42dfSAlex Bennée     return gdbserver_state.init && gdbserver_state.c_cpu;
376842b42dfSAlex Bennée }
377842b42dfSAlex Bennée 
378842b42dfSAlex Bennée static enum {
379842b42dfSAlex Bennée     GDB_SYS_UNKNOWN,
380842b42dfSAlex Bennée     GDB_SYS_ENABLED,
381842b42dfSAlex Bennée     GDB_SYS_DISABLED,
382842b42dfSAlex Bennée } gdb_syscall_mode;
383842b42dfSAlex Bennée 
384842b42dfSAlex Bennée /* Decide if either remote gdb syscalls or native file IO should be used. */
385842b42dfSAlex Bennée int use_gdb_syscalls(void)
386842b42dfSAlex Bennée {
387842b42dfSAlex Bennée     SemihostingTarget target = semihosting_get_target();
388842b42dfSAlex Bennée     if (target == SEMIHOSTING_TARGET_NATIVE) {
389842b42dfSAlex Bennée         /* -semihosting-config target=native */
390842b42dfSAlex Bennée         return false;
391842b42dfSAlex Bennée     } else if (target == SEMIHOSTING_TARGET_GDB) {
392842b42dfSAlex Bennée         /* -semihosting-config target=gdb */
393842b42dfSAlex Bennée         return true;
394842b42dfSAlex Bennée     }
395842b42dfSAlex Bennée 
396842b42dfSAlex Bennée     /* -semihosting-config target=auto */
397842b42dfSAlex Bennée     /* On the first call check if gdb is connected and remember. */
398842b42dfSAlex Bennée     if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
399842b42dfSAlex Bennée         gdb_syscall_mode = gdb_attached() ? GDB_SYS_ENABLED : GDB_SYS_DISABLED;
400842b42dfSAlex Bennée     }
401842b42dfSAlex Bennée     return gdb_syscall_mode == GDB_SYS_ENABLED;
402842b42dfSAlex Bennée }
403842b42dfSAlex Bennée 
404842b42dfSAlex Bennée static bool stub_can_reverse(void)
405842b42dfSAlex Bennée {
406842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
407842b42dfSAlex Bennée     return false;
408842b42dfSAlex Bennée #else
409842b42dfSAlex Bennée     return replay_mode == REPLAY_MODE_PLAY;
410842b42dfSAlex Bennée #endif
411842b42dfSAlex Bennée }
412842b42dfSAlex Bennée 
413842b42dfSAlex Bennée /* Resume execution.  */
414b6fa2ec2SAlex Bennée static void gdb_continue(void)
415842b42dfSAlex Bennée {
416842b42dfSAlex Bennée 
417842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
4188e70c6f9SAlex Bennée     gdbserver_user_state.running_state = 1;
419842b42dfSAlex Bennée     trace_gdbstub_op_continue();
420842b42dfSAlex Bennée #else
421842b42dfSAlex Bennée     if (!runstate_needs_reset()) {
422842b42dfSAlex Bennée         trace_gdbstub_op_continue();
423842b42dfSAlex Bennée         vm_start();
424842b42dfSAlex Bennée     }
425842b42dfSAlex Bennée #endif
426842b42dfSAlex Bennée }
427842b42dfSAlex Bennée 
428842b42dfSAlex Bennée /*
429842b42dfSAlex Bennée  * Resume execution, per CPU actions. For user-mode emulation it's
430842b42dfSAlex Bennée  * equivalent to gdb_continue.
431842b42dfSAlex Bennée  */
432842b42dfSAlex Bennée static int gdb_continue_partial(char *newstates)
433842b42dfSAlex Bennée {
434842b42dfSAlex Bennée     CPUState *cpu;
435842b42dfSAlex Bennée     int res = 0;
436842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
437842b42dfSAlex Bennée     /*
438842b42dfSAlex Bennée      * This is not exactly accurate, but it's an improvement compared to the
439842b42dfSAlex Bennée      * previous situation, where only one CPU would be single-stepped.
440842b42dfSAlex Bennée      */
441842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
442842b42dfSAlex Bennée         if (newstates[cpu->cpu_index] == 's') {
443842b42dfSAlex Bennée             trace_gdbstub_op_stepping(cpu->cpu_index);
444842b42dfSAlex Bennée             cpu_single_step(cpu, gdbserver_state.sstep_flags);
445842b42dfSAlex Bennée         }
446842b42dfSAlex Bennée     }
4478e70c6f9SAlex Bennée     gdbserver_user_state.running_state = 1;
448842b42dfSAlex Bennée #else
449842b42dfSAlex Bennée     int flag = 0;
450842b42dfSAlex Bennée 
451842b42dfSAlex Bennée     if (!runstate_needs_reset()) {
452842b42dfSAlex Bennée         bool step_requested = false;
453842b42dfSAlex Bennée         CPU_FOREACH(cpu) {
454842b42dfSAlex Bennée             if (newstates[cpu->cpu_index] == 's') {
455842b42dfSAlex Bennée                 step_requested = true;
456842b42dfSAlex Bennée                 break;
457842b42dfSAlex Bennée             }
458842b42dfSAlex Bennée         }
459842b42dfSAlex Bennée 
460842b42dfSAlex Bennée         if (vm_prepare_start(step_requested)) {
461842b42dfSAlex Bennée             return 0;
462842b42dfSAlex Bennée         }
463842b42dfSAlex Bennée 
464842b42dfSAlex Bennée         CPU_FOREACH(cpu) {
465842b42dfSAlex Bennée             switch (newstates[cpu->cpu_index]) {
466842b42dfSAlex Bennée             case 0:
467842b42dfSAlex Bennée             case 1:
468842b42dfSAlex Bennée                 break; /* nothing to do here */
469842b42dfSAlex Bennée             case 's':
470842b42dfSAlex Bennée                 trace_gdbstub_op_stepping(cpu->cpu_index);
471842b42dfSAlex Bennée                 cpu_single_step(cpu, gdbserver_state.sstep_flags);
472842b42dfSAlex Bennée                 cpu_resume(cpu);
473842b42dfSAlex Bennée                 flag = 1;
474842b42dfSAlex Bennée                 break;
475842b42dfSAlex Bennée             case 'c':
476842b42dfSAlex Bennée                 trace_gdbstub_op_continue_cpu(cpu->cpu_index);
477842b42dfSAlex Bennée                 cpu_resume(cpu);
478842b42dfSAlex Bennée                 flag = 1;
479842b42dfSAlex Bennée                 break;
480842b42dfSAlex Bennée             default:
481842b42dfSAlex Bennée                 res = -1;
482842b42dfSAlex Bennée                 break;
483842b42dfSAlex Bennée             }
484842b42dfSAlex Bennée         }
485842b42dfSAlex Bennée     }
486842b42dfSAlex Bennée     if (flag) {
487842b42dfSAlex Bennée         qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
488842b42dfSAlex Bennée     }
489842b42dfSAlex Bennée #endif
490842b42dfSAlex Bennée     return res;
491842b42dfSAlex Bennée }
492842b42dfSAlex Bennée 
493b6fa2ec2SAlex Bennée #ifdef CONFIG_USER_ONLY
49436e067b2SAlex Bennée void gdb_put_buffer(const uint8_t *buf, int len)
495842b42dfSAlex Bennée {
496842b42dfSAlex Bennée     int ret;
497842b42dfSAlex Bennée 
498842b42dfSAlex Bennée     while (len > 0) {
4998e70c6f9SAlex Bennée         ret = send(gdbserver_user_state.fd, buf, len, 0);
500842b42dfSAlex Bennée         if (ret < 0) {
501842b42dfSAlex Bennée             if (errno != EINTR)
502842b42dfSAlex Bennée                 return;
503842b42dfSAlex Bennée         } else {
504842b42dfSAlex Bennée             buf += ret;
505842b42dfSAlex Bennée             len -= ret;
506842b42dfSAlex Bennée         }
507842b42dfSAlex Bennée     }
508842b42dfSAlex Bennée }
509b6fa2ec2SAlex Bennée #endif
510842b42dfSAlex Bennée 
511842b42dfSAlex Bennée /* writes 2*len+1 bytes in buf */
51236e067b2SAlex Bennée void gdb_memtohex(GString *buf, const uint8_t *mem, int len)
513842b42dfSAlex Bennée {
514842b42dfSAlex Bennée     int i, c;
515842b42dfSAlex Bennée     for(i = 0; i < len; i++) {
516842b42dfSAlex Bennée         c = mem[i];
517842b42dfSAlex Bennée         g_string_append_c(buf, tohex(c >> 4));
518842b42dfSAlex Bennée         g_string_append_c(buf, tohex(c & 0xf));
519842b42dfSAlex Bennée     }
520842b42dfSAlex Bennée     g_string_append_c(buf, '\0');
521842b42dfSAlex Bennée }
522842b42dfSAlex Bennée 
52336e067b2SAlex Bennée void gdb_hextomem(GByteArray *mem, const char *buf, int len)
524842b42dfSAlex Bennée {
525842b42dfSAlex Bennée     int i;
526842b42dfSAlex Bennée 
527842b42dfSAlex Bennée     for(i = 0; i < len; i++) {
528842b42dfSAlex Bennée         guint8 byte = fromhex(buf[0]) << 4 | fromhex(buf[1]);
529842b42dfSAlex Bennée         g_byte_array_append(mem, &byte, 1);
530842b42dfSAlex Bennée         buf += 2;
531842b42dfSAlex Bennée     }
532842b42dfSAlex Bennée }
533842b42dfSAlex Bennée 
534842b42dfSAlex Bennée static void hexdump(const char *buf, int len,
535842b42dfSAlex Bennée                     void (*trace_fn)(size_t ofs, char const *text))
536842b42dfSAlex Bennée {
537842b42dfSAlex Bennée     char line_buffer[3 * 16 + 4 + 16 + 1];
538842b42dfSAlex Bennée 
539842b42dfSAlex Bennée     size_t i;
540842b42dfSAlex Bennée     for (i = 0; i < len || (i & 0xF); ++i) {
541842b42dfSAlex Bennée         size_t byte_ofs = i & 15;
542842b42dfSAlex Bennée 
543842b42dfSAlex Bennée         if (byte_ofs == 0) {
544842b42dfSAlex Bennée             memset(line_buffer, ' ', 3 * 16 + 4 + 16);
545842b42dfSAlex Bennée             line_buffer[3 * 16 + 4 + 16] = 0;
546842b42dfSAlex Bennée         }
547842b42dfSAlex Bennée 
548842b42dfSAlex Bennée         size_t col_group = (i >> 2) & 3;
549842b42dfSAlex Bennée         size_t hex_col = byte_ofs * 3 + col_group;
550842b42dfSAlex Bennée         size_t txt_col = 3 * 16 + 4 + byte_ofs;
551842b42dfSAlex Bennée 
552842b42dfSAlex Bennée         if (i < len) {
553842b42dfSAlex Bennée             char value = buf[i];
554842b42dfSAlex Bennée 
555842b42dfSAlex Bennée             line_buffer[hex_col + 0] = tohex((value >> 4) & 0xF);
556842b42dfSAlex Bennée             line_buffer[hex_col + 1] = tohex((value >> 0) & 0xF);
557842b42dfSAlex Bennée             line_buffer[txt_col + 0] = (value >= ' ' && value < 127)
558842b42dfSAlex Bennée                     ? value
559842b42dfSAlex Bennée                     : '.';
560842b42dfSAlex Bennée         }
561842b42dfSAlex Bennée 
562842b42dfSAlex Bennée         if (byte_ofs == 0xF)
563842b42dfSAlex Bennée             trace_fn(i & -16, line_buffer);
564842b42dfSAlex Bennée     }
565842b42dfSAlex Bennée }
566842b42dfSAlex Bennée 
567842b42dfSAlex Bennée /* return -1 if error, 0 if OK */
56836e067b2SAlex Bennée int gdb_put_packet_binary(const char *buf, int len, bool dump)
569842b42dfSAlex Bennée {
570842b42dfSAlex Bennée     int csum, i;
571842b42dfSAlex Bennée     uint8_t footer[3];
572842b42dfSAlex Bennée 
573842b42dfSAlex Bennée     if (dump && trace_event_get_state_backends(TRACE_GDBSTUB_IO_BINARYREPLY)) {
574842b42dfSAlex Bennée         hexdump(buf, len, trace_gdbstub_io_binaryreply);
575842b42dfSAlex Bennée     }
576842b42dfSAlex Bennée 
577842b42dfSAlex Bennée     for(;;) {
578842b42dfSAlex Bennée         g_byte_array_set_size(gdbserver_state.last_packet, 0);
579842b42dfSAlex Bennée         g_byte_array_append(gdbserver_state.last_packet,
580842b42dfSAlex Bennée                             (const uint8_t *) "$", 1);
581842b42dfSAlex Bennée         g_byte_array_append(gdbserver_state.last_packet,
582842b42dfSAlex Bennée                             (const uint8_t *) buf, len);
583842b42dfSAlex Bennée         csum = 0;
584842b42dfSAlex Bennée         for(i = 0; i < len; i++) {
585842b42dfSAlex Bennée             csum += buf[i];
586842b42dfSAlex Bennée         }
587842b42dfSAlex Bennée         footer[0] = '#';
588842b42dfSAlex Bennée         footer[1] = tohex((csum >> 4) & 0xf);
589842b42dfSAlex Bennée         footer[2] = tohex((csum) & 0xf);
590842b42dfSAlex Bennée         g_byte_array_append(gdbserver_state.last_packet, footer, 3);
591842b42dfSAlex Bennée 
59236e067b2SAlex Bennée         gdb_put_buffer(gdbserver_state.last_packet->data,
593842b42dfSAlex Bennée                    gdbserver_state.last_packet->len);
594842b42dfSAlex Bennée 
595842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
596842b42dfSAlex Bennée         i = get_char();
597842b42dfSAlex Bennée         if (i < 0)
598842b42dfSAlex Bennée             return -1;
599842b42dfSAlex Bennée         if (i == '+')
600842b42dfSAlex Bennée             break;
601842b42dfSAlex Bennée #else
602842b42dfSAlex Bennée         break;
603842b42dfSAlex Bennée #endif
604842b42dfSAlex Bennée     }
605842b42dfSAlex Bennée     return 0;
606842b42dfSAlex Bennée }
607842b42dfSAlex Bennée 
608842b42dfSAlex Bennée /* return -1 if error, 0 if OK */
60936e067b2SAlex Bennée int gdb_put_packet(const char *buf)
610842b42dfSAlex Bennée {
611842b42dfSAlex Bennée     trace_gdbstub_io_reply(buf);
612842b42dfSAlex Bennée 
61336e067b2SAlex Bennée     return gdb_put_packet_binary(buf, strlen(buf), false);
614842b42dfSAlex Bennée }
615842b42dfSAlex Bennée 
61636e067b2SAlex Bennée void gdb_put_strbuf(void)
617842b42dfSAlex Bennée {
61836e067b2SAlex Bennée     gdb_put_packet(gdbserver_state.str_buf->str);
619842b42dfSAlex Bennée }
620842b42dfSAlex Bennée 
621842b42dfSAlex Bennée /* Encode data using the encoding for 'x' packets.  */
62236e067b2SAlex Bennée void gdb_memtox(GString *buf, const char *mem, int len)
623842b42dfSAlex Bennée {
624842b42dfSAlex Bennée     char c;
625842b42dfSAlex Bennée 
626842b42dfSAlex Bennée     while (len--) {
627842b42dfSAlex Bennée         c = *(mem++);
628842b42dfSAlex Bennée         switch (c) {
629842b42dfSAlex Bennée         case '#': case '$': case '*': case '}':
630842b42dfSAlex Bennée             g_string_append_c(buf, '}');
631842b42dfSAlex Bennée             g_string_append_c(buf, c ^ 0x20);
632842b42dfSAlex Bennée             break;
633842b42dfSAlex Bennée         default:
634842b42dfSAlex Bennée             g_string_append_c(buf, c);
635842b42dfSAlex Bennée             break;
636842b42dfSAlex Bennée         }
637842b42dfSAlex Bennée     }
638842b42dfSAlex Bennée }
639842b42dfSAlex Bennée 
640842b42dfSAlex Bennée static uint32_t gdb_get_cpu_pid(CPUState *cpu)
641842b42dfSAlex Bennée {
642842b42dfSAlex Bennée     /* TODO: In user mode, we should use the task state PID */
643842b42dfSAlex Bennée     if (cpu->cluster_index == UNASSIGNED_CLUSTER_INDEX) {
644842b42dfSAlex Bennée         /* Return the default process' PID */
645842b42dfSAlex Bennée         int index = gdbserver_state.process_num - 1;
646842b42dfSAlex Bennée         return gdbserver_state.processes[index].pid;
647842b42dfSAlex Bennée     }
648842b42dfSAlex Bennée     return cpu->cluster_index + 1;
649842b42dfSAlex Bennée }
650842b42dfSAlex Bennée 
651842b42dfSAlex Bennée static GDBProcess *gdb_get_process(uint32_t pid)
652842b42dfSAlex Bennée {
653842b42dfSAlex Bennée     int i;
654842b42dfSAlex Bennée 
655842b42dfSAlex Bennée     if (!pid) {
656842b42dfSAlex Bennée         /* 0 means any process, we take the first one */
657842b42dfSAlex Bennée         return &gdbserver_state.processes[0];
658842b42dfSAlex Bennée     }
659842b42dfSAlex Bennée 
660842b42dfSAlex Bennée     for (i = 0; i < gdbserver_state.process_num; i++) {
661842b42dfSAlex Bennée         if (gdbserver_state.processes[i].pid == pid) {
662842b42dfSAlex Bennée             return &gdbserver_state.processes[i];
663842b42dfSAlex Bennée         }
664842b42dfSAlex Bennée     }
665842b42dfSAlex Bennée 
666842b42dfSAlex Bennée     return NULL;
667842b42dfSAlex Bennée }
668842b42dfSAlex Bennée 
669842b42dfSAlex Bennée static GDBProcess *gdb_get_cpu_process(CPUState *cpu)
670842b42dfSAlex Bennée {
671842b42dfSAlex Bennée     return gdb_get_process(gdb_get_cpu_pid(cpu));
672842b42dfSAlex Bennée }
673842b42dfSAlex Bennée 
674842b42dfSAlex Bennée static CPUState *find_cpu(uint32_t thread_id)
675842b42dfSAlex Bennée {
676842b42dfSAlex Bennée     CPUState *cpu;
677842b42dfSAlex Bennée 
678842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
67936e067b2SAlex Bennée         if (gdb_get_cpu_index(cpu) == thread_id) {
680842b42dfSAlex Bennée             return cpu;
681842b42dfSAlex Bennée         }
682842b42dfSAlex Bennée     }
683842b42dfSAlex Bennée 
684842b42dfSAlex Bennée     return NULL;
685842b42dfSAlex Bennée }
686842b42dfSAlex Bennée 
687842b42dfSAlex Bennée static CPUState *get_first_cpu_in_process(GDBProcess *process)
688842b42dfSAlex Bennée {
689842b42dfSAlex Bennée     CPUState *cpu;
690842b42dfSAlex Bennée 
691842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
692842b42dfSAlex Bennée         if (gdb_get_cpu_pid(cpu) == process->pid) {
693842b42dfSAlex Bennée             return cpu;
694842b42dfSAlex Bennée         }
695842b42dfSAlex Bennée     }
696842b42dfSAlex Bennée 
697842b42dfSAlex Bennée     return NULL;
698842b42dfSAlex Bennée }
699842b42dfSAlex Bennée 
700842b42dfSAlex Bennée static CPUState *gdb_next_cpu_in_process(CPUState *cpu)
701842b42dfSAlex Bennée {
702842b42dfSAlex Bennée     uint32_t pid = gdb_get_cpu_pid(cpu);
703842b42dfSAlex Bennée     cpu = CPU_NEXT(cpu);
704842b42dfSAlex Bennée 
705842b42dfSAlex Bennée     while (cpu) {
706842b42dfSAlex Bennée         if (gdb_get_cpu_pid(cpu) == pid) {
707842b42dfSAlex Bennée             break;
708842b42dfSAlex Bennée         }
709842b42dfSAlex Bennée 
710842b42dfSAlex Bennée         cpu = CPU_NEXT(cpu);
711842b42dfSAlex Bennée     }
712842b42dfSAlex Bennée 
713842b42dfSAlex Bennée     return cpu;
714842b42dfSAlex Bennée }
715842b42dfSAlex Bennée 
716842b42dfSAlex Bennée /* Return the cpu following @cpu, while ignoring unattached processes. */
717842b42dfSAlex Bennée static CPUState *gdb_next_attached_cpu(CPUState *cpu)
718842b42dfSAlex Bennée {
719842b42dfSAlex Bennée     cpu = CPU_NEXT(cpu);
720842b42dfSAlex Bennée 
721842b42dfSAlex Bennée     while (cpu) {
722842b42dfSAlex Bennée         if (gdb_get_cpu_process(cpu)->attached) {
723842b42dfSAlex Bennée             break;
724842b42dfSAlex Bennée         }
725842b42dfSAlex Bennée 
726842b42dfSAlex Bennée         cpu = CPU_NEXT(cpu);
727842b42dfSAlex Bennée     }
728842b42dfSAlex Bennée 
729842b42dfSAlex Bennée     return cpu;
730842b42dfSAlex Bennée }
731842b42dfSAlex Bennée 
732842b42dfSAlex Bennée /* Return the first attached cpu */
73336e067b2SAlex Bennée CPUState *gdb_first_attached_cpu(void)
734842b42dfSAlex Bennée {
735842b42dfSAlex Bennée     CPUState *cpu = first_cpu;
736842b42dfSAlex Bennée     GDBProcess *process = gdb_get_cpu_process(cpu);
737842b42dfSAlex Bennée 
738842b42dfSAlex Bennée     if (!process->attached) {
739842b42dfSAlex Bennée         return gdb_next_attached_cpu(cpu);
740842b42dfSAlex Bennée     }
741842b42dfSAlex Bennée 
742842b42dfSAlex Bennée     return cpu;
743842b42dfSAlex Bennée }
744842b42dfSAlex Bennée 
745842b42dfSAlex Bennée static CPUState *gdb_get_cpu(uint32_t pid, uint32_t tid)
746842b42dfSAlex Bennée {
747842b42dfSAlex Bennée     GDBProcess *process;
748842b42dfSAlex Bennée     CPUState *cpu;
749842b42dfSAlex Bennée 
750842b42dfSAlex Bennée     if (!pid && !tid) {
751842b42dfSAlex Bennée         /* 0 means any process/thread, we take the first attached one */
752842b42dfSAlex Bennée         return gdb_first_attached_cpu();
753842b42dfSAlex Bennée     } else if (pid && !tid) {
754842b42dfSAlex Bennée         /* any thread in a specific process */
755842b42dfSAlex Bennée         process = gdb_get_process(pid);
756842b42dfSAlex Bennée 
757842b42dfSAlex Bennée         if (process == NULL) {
758842b42dfSAlex Bennée             return NULL;
759842b42dfSAlex Bennée         }
760842b42dfSAlex Bennée 
761842b42dfSAlex Bennée         if (!process->attached) {
762842b42dfSAlex Bennée             return NULL;
763842b42dfSAlex Bennée         }
764842b42dfSAlex Bennée 
765842b42dfSAlex Bennée         return get_first_cpu_in_process(process);
766842b42dfSAlex Bennée     } else {
767842b42dfSAlex Bennée         /* a specific thread */
768842b42dfSAlex Bennée         cpu = find_cpu(tid);
769842b42dfSAlex Bennée 
770842b42dfSAlex Bennée         if (cpu == NULL) {
771842b42dfSAlex Bennée             return NULL;
772842b42dfSAlex Bennée         }
773842b42dfSAlex Bennée 
774842b42dfSAlex Bennée         process = gdb_get_cpu_process(cpu);
775842b42dfSAlex Bennée 
776842b42dfSAlex Bennée         if (pid && process->pid != pid) {
777842b42dfSAlex Bennée             return NULL;
778842b42dfSAlex Bennée         }
779842b42dfSAlex Bennée 
780842b42dfSAlex Bennée         if (!process->attached) {
781842b42dfSAlex Bennée             return NULL;
782842b42dfSAlex Bennée         }
783842b42dfSAlex Bennée 
784842b42dfSAlex Bennée         return cpu;
785842b42dfSAlex Bennée     }
786842b42dfSAlex Bennée }
787842b42dfSAlex Bennée 
788842b42dfSAlex Bennée static const char *get_feature_xml(const char *p, const char **newp,
789842b42dfSAlex Bennée                                    GDBProcess *process)
790842b42dfSAlex Bennée {
791842b42dfSAlex Bennée     size_t len;
792842b42dfSAlex Bennée     int i;
793842b42dfSAlex Bennée     const char *name;
794842b42dfSAlex Bennée     CPUState *cpu = get_first_cpu_in_process(process);
795842b42dfSAlex Bennée     CPUClass *cc = CPU_GET_CLASS(cpu);
796842b42dfSAlex Bennée 
797842b42dfSAlex Bennée     len = 0;
798842b42dfSAlex Bennée     while (p[len] && p[len] != ':')
799842b42dfSAlex Bennée         len++;
800842b42dfSAlex Bennée     *newp = p + len;
801842b42dfSAlex Bennée 
802842b42dfSAlex Bennée     name = NULL;
803842b42dfSAlex Bennée     if (strncmp(p, "target.xml", len) == 0) {
804842b42dfSAlex Bennée         char *buf = process->target_xml;
805842b42dfSAlex Bennée         const size_t buf_sz = sizeof(process->target_xml);
806842b42dfSAlex Bennée 
807842b42dfSAlex Bennée         /* Generate the XML description for this CPU.  */
808842b42dfSAlex Bennée         if (!buf[0]) {
809842b42dfSAlex Bennée             GDBRegisterState *r;
810842b42dfSAlex Bennée 
811842b42dfSAlex Bennée             pstrcat(buf, buf_sz,
812842b42dfSAlex Bennée                     "<?xml version=\"1.0\"?>"
813842b42dfSAlex Bennée                     "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
814842b42dfSAlex Bennée                     "<target>");
815842b42dfSAlex Bennée             if (cc->gdb_arch_name) {
816842b42dfSAlex Bennée                 gchar *arch = cc->gdb_arch_name(cpu);
817842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, "<architecture>");
818842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, arch);
819842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, "</architecture>");
820842b42dfSAlex Bennée                 g_free(arch);
821842b42dfSAlex Bennée             }
822842b42dfSAlex Bennée             pstrcat(buf, buf_sz, "<xi:include href=\"");
823842b42dfSAlex Bennée             pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
824842b42dfSAlex Bennée             pstrcat(buf, buf_sz, "\"/>");
825842b42dfSAlex Bennée             for (r = cpu->gdb_regs; r; r = r->next) {
826842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, "<xi:include href=\"");
827842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, r->xml);
828842b42dfSAlex Bennée                 pstrcat(buf, buf_sz, "\"/>");
829842b42dfSAlex Bennée             }
830842b42dfSAlex Bennée             pstrcat(buf, buf_sz, "</target>");
831842b42dfSAlex Bennée         }
832842b42dfSAlex Bennée         return buf;
833842b42dfSAlex Bennée     }
834842b42dfSAlex Bennée     if (cc->gdb_get_dynamic_xml) {
835842b42dfSAlex Bennée         char *xmlname = g_strndup(p, len);
836842b42dfSAlex Bennée         const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
837842b42dfSAlex Bennée 
838842b42dfSAlex Bennée         g_free(xmlname);
839842b42dfSAlex Bennée         if (xml) {
840842b42dfSAlex Bennée             return xml;
841842b42dfSAlex Bennée         }
842842b42dfSAlex Bennée     }
843842b42dfSAlex Bennée     for (i = 0; ; i++) {
844842b42dfSAlex Bennée         name = xml_builtin[i][0];
845842b42dfSAlex Bennée         if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
846842b42dfSAlex Bennée             break;
847842b42dfSAlex Bennée     }
848842b42dfSAlex Bennée     return name ? xml_builtin[i][1] : NULL;
849842b42dfSAlex Bennée }
850842b42dfSAlex Bennée 
851842b42dfSAlex Bennée static int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg)
852842b42dfSAlex Bennée {
853842b42dfSAlex Bennée     CPUClass *cc = CPU_GET_CLASS(cpu);
854842b42dfSAlex Bennée     CPUArchState *env = cpu->env_ptr;
855842b42dfSAlex Bennée     GDBRegisterState *r;
856842b42dfSAlex Bennée 
857842b42dfSAlex Bennée     if (reg < cc->gdb_num_core_regs) {
858842b42dfSAlex Bennée         return cc->gdb_read_register(cpu, buf, reg);
859842b42dfSAlex Bennée     }
860842b42dfSAlex Bennée 
861842b42dfSAlex Bennée     for (r = cpu->gdb_regs; r; r = r->next) {
862842b42dfSAlex Bennée         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
863842b42dfSAlex Bennée             return r->get_reg(env, buf, reg - r->base_reg);
864842b42dfSAlex Bennée         }
865842b42dfSAlex Bennée     }
866842b42dfSAlex Bennée     return 0;
867842b42dfSAlex Bennée }
868842b42dfSAlex Bennée 
869842b42dfSAlex Bennée static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
870842b42dfSAlex Bennée {
871842b42dfSAlex Bennée     CPUClass *cc = CPU_GET_CLASS(cpu);
872842b42dfSAlex Bennée     CPUArchState *env = cpu->env_ptr;
873842b42dfSAlex Bennée     GDBRegisterState *r;
874842b42dfSAlex Bennée 
875842b42dfSAlex Bennée     if (reg < cc->gdb_num_core_regs) {
876842b42dfSAlex Bennée         return cc->gdb_write_register(cpu, mem_buf, reg);
877842b42dfSAlex Bennée     }
878842b42dfSAlex Bennée 
879842b42dfSAlex Bennée     for (r = cpu->gdb_regs; r; r = r->next) {
880842b42dfSAlex Bennée         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
881842b42dfSAlex Bennée             return r->set_reg(env, mem_buf, reg - r->base_reg);
882842b42dfSAlex Bennée         }
883842b42dfSAlex Bennée     }
884842b42dfSAlex Bennée     return 0;
885842b42dfSAlex Bennée }
886842b42dfSAlex Bennée 
887842b42dfSAlex Bennée /* Register a supplemental set of CPU registers.  If g_pos is nonzero it
888842b42dfSAlex Bennée    specifies the first register number and these registers are included in
889842b42dfSAlex Bennée    a standard "g" packet.  Direction is relative to gdb, i.e. get_reg is
890842b42dfSAlex Bennée    gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
891842b42dfSAlex Bennée  */
892842b42dfSAlex Bennée 
893842b42dfSAlex Bennée void gdb_register_coprocessor(CPUState *cpu,
894842b42dfSAlex Bennée                               gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
895842b42dfSAlex Bennée                               int num_regs, const char *xml, int g_pos)
896842b42dfSAlex Bennée {
897842b42dfSAlex Bennée     GDBRegisterState *s;
898842b42dfSAlex Bennée     GDBRegisterState **p;
899842b42dfSAlex Bennée 
900842b42dfSAlex Bennée     p = &cpu->gdb_regs;
901842b42dfSAlex Bennée     while (*p) {
902842b42dfSAlex Bennée         /* Check for duplicates.  */
903842b42dfSAlex Bennée         if (strcmp((*p)->xml, xml) == 0)
904842b42dfSAlex Bennée             return;
905842b42dfSAlex Bennée         p = &(*p)->next;
906842b42dfSAlex Bennée     }
907842b42dfSAlex Bennée 
908842b42dfSAlex Bennée     s = g_new0(GDBRegisterState, 1);
909842b42dfSAlex Bennée     s->base_reg = cpu->gdb_num_regs;
910842b42dfSAlex Bennée     s->num_regs = num_regs;
911842b42dfSAlex Bennée     s->get_reg = get_reg;
912842b42dfSAlex Bennée     s->set_reg = set_reg;
913842b42dfSAlex Bennée     s->xml = xml;
914842b42dfSAlex Bennée 
915842b42dfSAlex Bennée     /* Add to end of list.  */
916842b42dfSAlex Bennée     cpu->gdb_num_regs += num_regs;
917842b42dfSAlex Bennée     *p = s;
918842b42dfSAlex Bennée     if (g_pos) {
919842b42dfSAlex Bennée         if (g_pos != s->base_reg) {
920842b42dfSAlex Bennée             error_report("Error: Bad gdb register numbering for '%s', "
921842b42dfSAlex Bennée                          "expected %d got %d", xml, g_pos, s->base_reg);
922842b42dfSAlex Bennée         } else {
923842b42dfSAlex Bennée             cpu->gdb_num_g_regs = cpu->gdb_num_regs;
924842b42dfSAlex Bennée         }
925842b42dfSAlex Bennée     }
926842b42dfSAlex Bennée }
927842b42dfSAlex Bennée 
928842b42dfSAlex Bennée static void gdb_process_breakpoint_remove_all(GDBProcess *p)
929842b42dfSAlex Bennée {
930842b42dfSAlex Bennée     CPUState *cpu = get_first_cpu_in_process(p);
931842b42dfSAlex Bennée 
932842b42dfSAlex Bennée     while (cpu) {
933ae7467b1SAlex Bennée         gdb_breakpoint_remove_all(cpu);
934842b42dfSAlex Bennée         cpu = gdb_next_cpu_in_process(cpu);
935842b42dfSAlex Bennée     }
936842b42dfSAlex Bennée }
937842b42dfSAlex Bennée 
938842b42dfSAlex Bennée 
939842b42dfSAlex Bennée static void gdb_set_cpu_pc(target_ulong pc)
940842b42dfSAlex Bennée {
941842b42dfSAlex Bennée     CPUState *cpu = gdbserver_state.c_cpu;
942842b42dfSAlex Bennée 
943842b42dfSAlex Bennée     cpu_synchronize_state(cpu);
944842b42dfSAlex Bennée     cpu_set_pc(cpu, pc);
945842b42dfSAlex Bennée }
946842b42dfSAlex Bennée 
94736e067b2SAlex Bennée void gdb_append_thread_id(CPUState *cpu, GString *buf)
948842b42dfSAlex Bennée {
949842b42dfSAlex Bennée     if (gdbserver_state.multiprocess) {
950842b42dfSAlex Bennée         g_string_append_printf(buf, "p%02x.%02x",
95136e067b2SAlex Bennée                                gdb_get_cpu_pid(cpu), gdb_get_cpu_index(cpu));
952842b42dfSAlex Bennée     } else {
95336e067b2SAlex Bennée         g_string_append_printf(buf, "%02x", gdb_get_cpu_index(cpu));
954842b42dfSAlex Bennée     }
955842b42dfSAlex Bennée }
956842b42dfSAlex Bennée 
957842b42dfSAlex Bennée static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
958842b42dfSAlex Bennée                                       uint32_t *pid, uint32_t *tid)
959842b42dfSAlex Bennée {
960842b42dfSAlex Bennée     unsigned long p, t;
961842b42dfSAlex Bennée     int ret;
962842b42dfSAlex Bennée 
963842b42dfSAlex Bennée     if (*buf == 'p') {
964842b42dfSAlex Bennée         buf++;
965842b42dfSAlex Bennée         ret = qemu_strtoul(buf, &buf, 16, &p);
966842b42dfSAlex Bennée 
967842b42dfSAlex Bennée         if (ret) {
968842b42dfSAlex Bennée             return GDB_READ_THREAD_ERR;
969842b42dfSAlex Bennée         }
970842b42dfSAlex Bennée 
971842b42dfSAlex Bennée         /* Skip '.' */
972842b42dfSAlex Bennée         buf++;
973842b42dfSAlex Bennée     } else {
974842b42dfSAlex Bennée         p = 1;
975842b42dfSAlex Bennée     }
976842b42dfSAlex Bennée 
977842b42dfSAlex Bennée     ret = qemu_strtoul(buf, &buf, 16, &t);
978842b42dfSAlex Bennée 
979842b42dfSAlex Bennée     if (ret) {
980842b42dfSAlex Bennée         return GDB_READ_THREAD_ERR;
981842b42dfSAlex Bennée     }
982842b42dfSAlex Bennée 
983842b42dfSAlex Bennée     *end_buf = buf;
984842b42dfSAlex Bennée 
985842b42dfSAlex Bennée     if (p == -1) {
986842b42dfSAlex Bennée         return GDB_ALL_PROCESSES;
987842b42dfSAlex Bennée     }
988842b42dfSAlex Bennée 
989842b42dfSAlex Bennée     if (pid) {
990842b42dfSAlex Bennée         *pid = p;
991842b42dfSAlex Bennée     }
992842b42dfSAlex Bennée 
993842b42dfSAlex Bennée     if (t == -1) {
994842b42dfSAlex Bennée         return GDB_ALL_THREADS;
995842b42dfSAlex Bennée     }
996842b42dfSAlex Bennée 
997842b42dfSAlex Bennée     if (tid) {
998842b42dfSAlex Bennée         *tid = t;
999842b42dfSAlex Bennée     }
1000842b42dfSAlex Bennée 
1001842b42dfSAlex Bennée     return GDB_ONE_THREAD;
1002842b42dfSAlex Bennée }
1003842b42dfSAlex Bennée 
1004842b42dfSAlex Bennée /**
1005842b42dfSAlex Bennée  * gdb_handle_vcont - Parses and handles a vCont packet.
1006842b42dfSAlex Bennée  * returns -ENOTSUP if a command is unsupported, -EINVAL or -ERANGE if there is
1007842b42dfSAlex Bennée  *         a format error, 0 on success.
1008842b42dfSAlex Bennée  */
1009842b42dfSAlex Bennée static int gdb_handle_vcont(const char *p)
1010842b42dfSAlex Bennée {
1011842b42dfSAlex Bennée     int res, signal = 0;
1012842b42dfSAlex Bennée     char cur_action;
1013842b42dfSAlex Bennée     char *newstates;
1014842b42dfSAlex Bennée     unsigned long tmp;
1015842b42dfSAlex Bennée     uint32_t pid, tid;
1016842b42dfSAlex Bennée     GDBProcess *process;
1017842b42dfSAlex Bennée     CPUState *cpu;
1018842b42dfSAlex Bennée     GDBThreadIdKind kind;
1019842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
1020842b42dfSAlex Bennée     int max_cpus = 1; /* global variable max_cpus exists only in system mode */
1021842b42dfSAlex Bennée 
1022842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
1023842b42dfSAlex Bennée         max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
1024842b42dfSAlex Bennée     }
1025842b42dfSAlex Bennée #else
1026842b42dfSAlex Bennée     MachineState *ms = MACHINE(qdev_get_machine());
1027842b42dfSAlex Bennée     unsigned int max_cpus = ms->smp.max_cpus;
1028842b42dfSAlex Bennée #endif
1029842b42dfSAlex Bennée     /* uninitialised CPUs stay 0 */
1030842b42dfSAlex Bennée     newstates = g_new0(char, max_cpus);
1031842b42dfSAlex Bennée 
1032842b42dfSAlex Bennée     /* mark valid CPUs with 1 */
1033842b42dfSAlex Bennée     CPU_FOREACH(cpu) {
1034842b42dfSAlex Bennée         newstates[cpu->cpu_index] = 1;
1035842b42dfSAlex Bennée     }
1036842b42dfSAlex Bennée 
1037842b42dfSAlex Bennée     /*
1038842b42dfSAlex Bennée      * res keeps track of what error we are returning, with -ENOTSUP meaning
1039842b42dfSAlex Bennée      * that the command is unknown or unsupported, thus returning an empty
1040842b42dfSAlex Bennée      * packet, while -EINVAL and -ERANGE cause an E22 packet, due to invalid,
1041842b42dfSAlex Bennée      *  or incorrect parameters passed.
1042842b42dfSAlex Bennée      */
1043842b42dfSAlex Bennée     res = 0;
1044842b42dfSAlex Bennée     while (*p) {
1045842b42dfSAlex Bennée         if (*p++ != ';') {
1046842b42dfSAlex Bennée             res = -ENOTSUP;
1047842b42dfSAlex Bennée             goto out;
1048842b42dfSAlex Bennée         }
1049842b42dfSAlex Bennée 
1050842b42dfSAlex Bennée         cur_action = *p++;
1051842b42dfSAlex Bennée         if (cur_action == 'C' || cur_action == 'S') {
1052842b42dfSAlex Bennée             cur_action = qemu_tolower(cur_action);
1053842b42dfSAlex Bennée             res = qemu_strtoul(p, &p, 16, &tmp);
1054842b42dfSAlex Bennée             if (res) {
1055842b42dfSAlex Bennée                 goto out;
1056842b42dfSAlex Bennée             }
1057842b42dfSAlex Bennée             signal = gdb_signal_to_target(tmp);
1058842b42dfSAlex Bennée         } else if (cur_action != 'c' && cur_action != 's') {
1059842b42dfSAlex Bennée             /* unknown/invalid/unsupported command */
1060842b42dfSAlex Bennée             res = -ENOTSUP;
1061842b42dfSAlex Bennée             goto out;
1062842b42dfSAlex Bennée         }
1063842b42dfSAlex Bennée 
1064842b42dfSAlex Bennée         if (*p == '\0' || *p == ';') {
1065842b42dfSAlex Bennée             /*
1066842b42dfSAlex Bennée              * No thread specifier, action is on "all threads". The
1067842b42dfSAlex Bennée              * specification is unclear regarding the process to act on. We
1068842b42dfSAlex Bennée              * choose all processes.
1069842b42dfSAlex Bennée              */
1070842b42dfSAlex Bennée             kind = GDB_ALL_PROCESSES;
1071842b42dfSAlex Bennée         } else if (*p++ == ':') {
1072842b42dfSAlex Bennée             kind = read_thread_id(p, &p, &pid, &tid);
1073842b42dfSAlex Bennée         } else {
1074842b42dfSAlex Bennée             res = -ENOTSUP;
1075842b42dfSAlex Bennée             goto out;
1076842b42dfSAlex Bennée         }
1077842b42dfSAlex Bennée 
1078842b42dfSAlex Bennée         switch (kind) {
1079842b42dfSAlex Bennée         case GDB_READ_THREAD_ERR:
1080842b42dfSAlex Bennée             res = -EINVAL;
1081842b42dfSAlex Bennée             goto out;
1082842b42dfSAlex Bennée 
1083842b42dfSAlex Bennée         case GDB_ALL_PROCESSES:
1084842b42dfSAlex Bennée             cpu = gdb_first_attached_cpu();
1085842b42dfSAlex Bennée             while (cpu) {
1086842b42dfSAlex Bennée                 if (newstates[cpu->cpu_index] == 1) {
1087842b42dfSAlex Bennée                     newstates[cpu->cpu_index] = cur_action;
1088842b42dfSAlex Bennée                 }
1089842b42dfSAlex Bennée 
1090842b42dfSAlex Bennée                 cpu = gdb_next_attached_cpu(cpu);
1091842b42dfSAlex Bennée             }
1092842b42dfSAlex Bennée             break;
1093842b42dfSAlex Bennée 
1094842b42dfSAlex Bennée         case GDB_ALL_THREADS:
1095842b42dfSAlex Bennée             process = gdb_get_process(pid);
1096842b42dfSAlex Bennée 
1097842b42dfSAlex Bennée             if (!process->attached) {
1098842b42dfSAlex Bennée                 res = -EINVAL;
1099842b42dfSAlex Bennée                 goto out;
1100842b42dfSAlex Bennée             }
1101842b42dfSAlex Bennée 
1102842b42dfSAlex Bennée             cpu = get_first_cpu_in_process(process);
1103842b42dfSAlex Bennée             while (cpu) {
1104842b42dfSAlex Bennée                 if (newstates[cpu->cpu_index] == 1) {
1105842b42dfSAlex Bennée                     newstates[cpu->cpu_index] = cur_action;
1106842b42dfSAlex Bennée                 }
1107842b42dfSAlex Bennée 
1108842b42dfSAlex Bennée                 cpu = gdb_next_cpu_in_process(cpu);
1109842b42dfSAlex Bennée             }
1110842b42dfSAlex Bennée             break;
1111842b42dfSAlex Bennée 
1112842b42dfSAlex Bennée         case GDB_ONE_THREAD:
1113842b42dfSAlex Bennée             cpu = gdb_get_cpu(pid, tid);
1114842b42dfSAlex Bennée 
1115842b42dfSAlex Bennée             /* invalid CPU/thread specified */
1116842b42dfSAlex Bennée             if (!cpu) {
1117842b42dfSAlex Bennée                 res = -EINVAL;
1118842b42dfSAlex Bennée                 goto out;
1119842b42dfSAlex Bennée             }
1120842b42dfSAlex Bennée 
1121842b42dfSAlex Bennée             /* only use if no previous match occourred */
1122842b42dfSAlex Bennée             if (newstates[cpu->cpu_index] == 1) {
1123842b42dfSAlex Bennée                 newstates[cpu->cpu_index] = cur_action;
1124842b42dfSAlex Bennée             }
1125842b42dfSAlex Bennée             break;
1126842b42dfSAlex Bennée         }
1127842b42dfSAlex Bennée     }
1128842b42dfSAlex Bennée     gdbserver_state.signal = signal;
1129842b42dfSAlex Bennée     gdb_continue_partial(newstates);
1130842b42dfSAlex Bennée 
1131842b42dfSAlex Bennée out:
1132842b42dfSAlex Bennée     g_free(newstates);
1133842b42dfSAlex Bennée 
1134842b42dfSAlex Bennée     return res;
1135842b42dfSAlex Bennée }
1136842b42dfSAlex Bennée 
1137842b42dfSAlex Bennée static const char *cmd_next_param(const char *param, const char delimiter)
1138842b42dfSAlex Bennée {
1139842b42dfSAlex Bennée     static const char all_delimiters[] = ",;:=";
1140842b42dfSAlex Bennée     char curr_delimiters[2] = {0};
1141842b42dfSAlex Bennée     const char *delimiters;
1142842b42dfSAlex Bennée 
1143842b42dfSAlex Bennée     if (delimiter == '?') {
1144842b42dfSAlex Bennée         delimiters = all_delimiters;
1145842b42dfSAlex Bennée     } else if (delimiter == '0') {
1146842b42dfSAlex Bennée         return strchr(param, '\0');
1147842b42dfSAlex Bennée     } else if (delimiter == '.' && *param) {
1148842b42dfSAlex Bennée         return param + 1;
1149842b42dfSAlex Bennée     } else {
1150842b42dfSAlex Bennée         curr_delimiters[0] = delimiter;
1151842b42dfSAlex Bennée         delimiters = curr_delimiters;
1152842b42dfSAlex Bennée     }
1153842b42dfSAlex Bennée 
1154842b42dfSAlex Bennée     param += strcspn(param, delimiters);
1155842b42dfSAlex Bennée     if (*param) {
1156842b42dfSAlex Bennée         param++;
1157842b42dfSAlex Bennée     }
1158842b42dfSAlex Bennée     return param;
1159842b42dfSAlex Bennée }
1160842b42dfSAlex Bennée 
1161842b42dfSAlex Bennée static int cmd_parse_params(const char *data, const char *schema,
1162842b42dfSAlex Bennée                             GArray *params)
1163842b42dfSAlex Bennée {
1164842b42dfSAlex Bennée     const char *curr_schema, *curr_data;
1165842b42dfSAlex Bennée 
1166842b42dfSAlex Bennée     g_assert(schema);
1167842b42dfSAlex Bennée     g_assert(params->len == 0);
1168842b42dfSAlex Bennée 
1169842b42dfSAlex Bennée     curr_schema = schema;
1170842b42dfSAlex Bennée     curr_data = data;
1171842b42dfSAlex Bennée     while (curr_schema[0] && curr_schema[1] && *curr_data) {
1172842b42dfSAlex Bennée         GdbCmdVariant this_param;
1173842b42dfSAlex Bennée 
1174842b42dfSAlex Bennée         switch (curr_schema[0]) {
1175842b42dfSAlex Bennée         case 'l':
1176842b42dfSAlex Bennée             if (qemu_strtoul(curr_data, &curr_data, 16,
1177842b42dfSAlex Bennée                              &this_param.val_ul)) {
1178842b42dfSAlex Bennée                 return -EINVAL;
1179842b42dfSAlex Bennée             }
1180842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1181842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1182842b42dfSAlex Bennée             break;
1183842b42dfSAlex Bennée         case 'L':
1184842b42dfSAlex Bennée             if (qemu_strtou64(curr_data, &curr_data, 16,
1185842b42dfSAlex Bennée                               (uint64_t *)&this_param.val_ull)) {
1186842b42dfSAlex Bennée                 return -EINVAL;
1187842b42dfSAlex Bennée             }
1188842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1189842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1190842b42dfSAlex Bennée             break;
1191842b42dfSAlex Bennée         case 's':
1192842b42dfSAlex Bennée             this_param.data = curr_data;
1193842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1194842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1195842b42dfSAlex Bennée             break;
1196842b42dfSAlex Bennée         case 'o':
1197842b42dfSAlex Bennée             this_param.opcode = *(uint8_t *)curr_data;
1198842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1199842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1200842b42dfSAlex Bennée             break;
1201842b42dfSAlex Bennée         case 't':
1202842b42dfSAlex Bennée             this_param.thread_id.kind =
1203842b42dfSAlex Bennée                 read_thread_id(curr_data, &curr_data,
1204842b42dfSAlex Bennée                                &this_param.thread_id.pid,
1205842b42dfSAlex Bennée                                &this_param.thread_id.tid);
1206842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1207842b42dfSAlex Bennée             g_array_append_val(params, this_param);
1208842b42dfSAlex Bennée             break;
1209842b42dfSAlex Bennée         case '?':
1210842b42dfSAlex Bennée             curr_data = cmd_next_param(curr_data, curr_schema[1]);
1211842b42dfSAlex Bennée             break;
1212842b42dfSAlex Bennée         default:
1213842b42dfSAlex Bennée             return -EINVAL;
1214842b42dfSAlex Bennée         }
1215842b42dfSAlex Bennée         curr_schema += 2;
1216842b42dfSAlex Bennée     }
1217842b42dfSAlex Bennée 
1218842b42dfSAlex Bennée     return 0;
1219842b42dfSAlex Bennée }
1220842b42dfSAlex Bennée 
1221842b42dfSAlex Bennée typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
1222842b42dfSAlex Bennée 
1223842b42dfSAlex Bennée /*
1224842b42dfSAlex Bennée  * cmd_startswith -> cmd is compared using startswith
1225842b42dfSAlex Bennée  *
1226842b42dfSAlex Bennée  *
1227842b42dfSAlex Bennée  * schema definitions:
1228842b42dfSAlex Bennée  * Each schema parameter entry consists of 2 chars,
1229842b42dfSAlex Bennée  * the first char represents the parameter type handling
1230842b42dfSAlex Bennée  * the second char represents the delimiter for the next parameter
1231842b42dfSAlex Bennée  *
1232842b42dfSAlex Bennée  * Currently supported schema types:
1233842b42dfSAlex Bennée  * 'l' -> unsigned long (stored in .val_ul)
1234842b42dfSAlex Bennée  * 'L' -> unsigned long long (stored in .val_ull)
1235842b42dfSAlex Bennée  * 's' -> string (stored in .data)
1236842b42dfSAlex Bennée  * 'o' -> single char (stored in .opcode)
1237842b42dfSAlex Bennée  * 't' -> thread id (stored in .thread_id)
1238842b42dfSAlex Bennée  * '?' -> skip according to delimiter
1239842b42dfSAlex Bennée  *
1240842b42dfSAlex Bennée  * Currently supported delimiters:
1241842b42dfSAlex Bennée  * '?' -> Stop at any delimiter (",;:=\0")
1242842b42dfSAlex Bennée  * '0' -> Stop at "\0"
1243842b42dfSAlex Bennée  * '.' -> Skip 1 char unless reached "\0"
1244842b42dfSAlex Bennée  * Any other value is treated as the delimiter value itself
1245842b42dfSAlex Bennée  */
1246842b42dfSAlex Bennée typedef struct GdbCmdParseEntry {
1247842b42dfSAlex Bennée     GdbCmdHandler handler;
1248842b42dfSAlex Bennée     const char *cmd;
1249842b42dfSAlex Bennée     bool cmd_startswith;
1250842b42dfSAlex Bennée     const char *schema;
1251842b42dfSAlex Bennée } GdbCmdParseEntry;
1252842b42dfSAlex Bennée 
1253842b42dfSAlex Bennée static inline int startswith(const char *string, const char *pattern)
1254842b42dfSAlex Bennée {
1255842b42dfSAlex Bennée   return !strncmp(string, pattern, strlen(pattern));
1256842b42dfSAlex Bennée }
1257842b42dfSAlex Bennée 
1258842b42dfSAlex Bennée static int process_string_cmd(void *user_ctx, const char *data,
1259842b42dfSAlex Bennée                               const GdbCmdParseEntry *cmds, int num_cmds)
1260842b42dfSAlex Bennée {
1261842b42dfSAlex Bennée     int i;
1262842b42dfSAlex Bennée     g_autoptr(GArray) params = g_array_new(false, true, sizeof(GdbCmdVariant));
1263842b42dfSAlex Bennée 
1264842b42dfSAlex Bennée     if (!cmds) {
1265842b42dfSAlex Bennée         return -1;
1266842b42dfSAlex Bennée     }
1267842b42dfSAlex Bennée 
1268842b42dfSAlex Bennée     for (i = 0; i < num_cmds; i++) {
1269842b42dfSAlex Bennée         const GdbCmdParseEntry *cmd = &cmds[i];
1270842b42dfSAlex Bennée         g_assert(cmd->handler && cmd->cmd);
1271842b42dfSAlex Bennée 
1272842b42dfSAlex Bennée         if ((cmd->cmd_startswith && !startswith(data, cmd->cmd)) ||
1273842b42dfSAlex Bennée             (!cmd->cmd_startswith && strcmp(cmd->cmd, data))) {
1274842b42dfSAlex Bennée             continue;
1275842b42dfSAlex Bennée         }
1276842b42dfSAlex Bennée 
1277842b42dfSAlex Bennée         if (cmd->schema) {
1278842b42dfSAlex Bennée             if (cmd_parse_params(&data[strlen(cmd->cmd)],
1279842b42dfSAlex Bennée                                  cmd->schema, params)) {
1280842b42dfSAlex Bennée                 return -1;
1281842b42dfSAlex Bennée             }
1282842b42dfSAlex Bennée         }
1283842b42dfSAlex Bennée 
1284842b42dfSAlex Bennée         cmd->handler(params, user_ctx);
1285842b42dfSAlex Bennée         return 0;
1286842b42dfSAlex Bennée     }
1287842b42dfSAlex Bennée 
1288842b42dfSAlex Bennée     return -1;
1289842b42dfSAlex Bennée }
1290842b42dfSAlex Bennée 
1291842b42dfSAlex Bennée static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
1292842b42dfSAlex Bennée {
1293842b42dfSAlex Bennée     if (!data) {
1294842b42dfSAlex Bennée         return;
1295842b42dfSAlex Bennée     }
1296842b42dfSAlex Bennée 
1297842b42dfSAlex Bennée     g_string_set_size(gdbserver_state.str_buf, 0);
1298842b42dfSAlex Bennée     g_byte_array_set_size(gdbserver_state.mem_buf, 0);
1299842b42dfSAlex Bennée 
1300842b42dfSAlex Bennée     /* In case there was an error during the command parsing we must
1301842b42dfSAlex Bennée     * send a NULL packet to indicate the command is not supported */
1302842b42dfSAlex Bennée     if (process_string_cmd(NULL, data, cmd, 1)) {
130336e067b2SAlex Bennée         gdb_put_packet("");
1304842b42dfSAlex Bennée     }
1305842b42dfSAlex Bennée }
1306842b42dfSAlex Bennée 
1307842b42dfSAlex Bennée static void handle_detach(GArray *params, void *user_ctx)
1308842b42dfSAlex Bennée {
1309842b42dfSAlex Bennée     GDBProcess *process;
1310842b42dfSAlex Bennée     uint32_t pid = 1;
1311842b42dfSAlex Bennée 
1312842b42dfSAlex Bennée     if (gdbserver_state.multiprocess) {
1313842b42dfSAlex Bennée         if (!params->len) {
131436e067b2SAlex Bennée             gdb_put_packet("E22");
1315842b42dfSAlex Bennée             return;
1316842b42dfSAlex Bennée         }
1317842b42dfSAlex Bennée 
1318842b42dfSAlex Bennée         pid = get_param(params, 0)->val_ul;
1319842b42dfSAlex Bennée     }
1320842b42dfSAlex Bennée 
1321842b42dfSAlex Bennée     process = gdb_get_process(pid);
1322842b42dfSAlex Bennée     gdb_process_breakpoint_remove_all(process);
1323842b42dfSAlex Bennée     process->attached = false;
1324842b42dfSAlex Bennée 
1325842b42dfSAlex Bennée     if (pid == gdb_get_cpu_pid(gdbserver_state.c_cpu)) {
1326842b42dfSAlex Bennée         gdbserver_state.c_cpu = gdb_first_attached_cpu();
1327842b42dfSAlex Bennée     }
1328842b42dfSAlex Bennée 
1329842b42dfSAlex Bennée     if (pid == gdb_get_cpu_pid(gdbserver_state.g_cpu)) {
1330842b42dfSAlex Bennée         gdbserver_state.g_cpu = gdb_first_attached_cpu();
1331842b42dfSAlex Bennée     }
1332842b42dfSAlex Bennée 
1333842b42dfSAlex Bennée     if (!gdbserver_state.c_cpu) {
1334842b42dfSAlex Bennée         /* No more process attached */
1335842b42dfSAlex Bennée         gdb_syscall_mode = GDB_SYS_DISABLED;
1336842b42dfSAlex Bennée         gdb_continue();
1337842b42dfSAlex Bennée     }
133836e067b2SAlex Bennée     gdb_put_packet("OK");
1339842b42dfSAlex Bennée }
1340842b42dfSAlex Bennée 
1341842b42dfSAlex Bennée static void handle_thread_alive(GArray *params, void *user_ctx)
1342842b42dfSAlex Bennée {
1343842b42dfSAlex Bennée     CPUState *cpu;
1344842b42dfSAlex Bennée 
1345842b42dfSAlex Bennée     if (!params->len) {
134636e067b2SAlex Bennée         gdb_put_packet("E22");
1347842b42dfSAlex Bennée         return;
1348842b42dfSAlex Bennée     }
1349842b42dfSAlex Bennée 
1350842b42dfSAlex Bennée     if (get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
135136e067b2SAlex Bennée         gdb_put_packet("E22");
1352842b42dfSAlex Bennée         return;
1353842b42dfSAlex Bennée     }
1354842b42dfSAlex Bennée 
1355842b42dfSAlex Bennée     cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1356842b42dfSAlex Bennée                       get_param(params, 0)->thread_id.tid);
1357842b42dfSAlex Bennée     if (!cpu) {
135836e067b2SAlex Bennée         gdb_put_packet("E22");
1359842b42dfSAlex Bennée         return;
1360842b42dfSAlex Bennée     }
1361842b42dfSAlex Bennée 
136236e067b2SAlex Bennée     gdb_put_packet("OK");
1363842b42dfSAlex Bennée }
1364842b42dfSAlex Bennée 
1365842b42dfSAlex Bennée static void handle_continue(GArray *params, void *user_ctx)
1366842b42dfSAlex Bennée {
1367842b42dfSAlex Bennée     if (params->len) {
1368842b42dfSAlex Bennée         gdb_set_cpu_pc(get_param(params, 0)->val_ull);
1369842b42dfSAlex Bennée     }
1370842b42dfSAlex Bennée 
1371842b42dfSAlex Bennée     gdbserver_state.signal = 0;
1372842b42dfSAlex Bennée     gdb_continue();
1373842b42dfSAlex Bennée }
1374842b42dfSAlex Bennée 
1375842b42dfSAlex Bennée static void handle_cont_with_sig(GArray *params, void *user_ctx)
1376842b42dfSAlex Bennée {
1377842b42dfSAlex Bennée     unsigned long signal = 0;
1378842b42dfSAlex Bennée 
1379842b42dfSAlex Bennée     /*
1380842b42dfSAlex Bennée      * Note: C sig;[addr] is currently unsupported and we simply
1381842b42dfSAlex Bennée      *       omit the addr parameter
1382842b42dfSAlex Bennée      */
1383842b42dfSAlex Bennée     if (params->len) {
1384842b42dfSAlex Bennée         signal = get_param(params, 0)->val_ul;
1385842b42dfSAlex Bennée     }
1386842b42dfSAlex Bennée 
1387842b42dfSAlex Bennée     gdbserver_state.signal = gdb_signal_to_target(signal);
1388842b42dfSAlex Bennée     if (gdbserver_state.signal == -1) {
1389842b42dfSAlex Bennée         gdbserver_state.signal = 0;
1390842b42dfSAlex Bennée     }
1391842b42dfSAlex Bennée     gdb_continue();
1392842b42dfSAlex Bennée }
1393842b42dfSAlex Bennée 
1394842b42dfSAlex Bennée static void handle_set_thread(GArray *params, void *user_ctx)
1395842b42dfSAlex Bennée {
1396842b42dfSAlex Bennée     CPUState *cpu;
1397842b42dfSAlex Bennée 
1398842b42dfSAlex Bennée     if (params->len != 2) {
139936e067b2SAlex Bennée         gdb_put_packet("E22");
1400842b42dfSAlex Bennée         return;
1401842b42dfSAlex Bennée     }
1402842b42dfSAlex Bennée 
1403842b42dfSAlex Bennée     if (get_param(params, 1)->thread_id.kind == GDB_READ_THREAD_ERR) {
140436e067b2SAlex Bennée         gdb_put_packet("E22");
1405842b42dfSAlex Bennée         return;
1406842b42dfSAlex Bennée     }
1407842b42dfSAlex Bennée 
1408842b42dfSAlex Bennée     if (get_param(params, 1)->thread_id.kind != GDB_ONE_THREAD) {
140936e067b2SAlex Bennée         gdb_put_packet("OK");
1410842b42dfSAlex Bennée         return;
1411842b42dfSAlex Bennée     }
1412842b42dfSAlex Bennée 
1413842b42dfSAlex Bennée     cpu = gdb_get_cpu(get_param(params, 1)->thread_id.pid,
1414842b42dfSAlex Bennée                       get_param(params, 1)->thread_id.tid);
1415842b42dfSAlex Bennée     if (!cpu) {
141636e067b2SAlex Bennée         gdb_put_packet("E22");
1417842b42dfSAlex Bennée         return;
1418842b42dfSAlex Bennée     }
1419842b42dfSAlex Bennée 
1420842b42dfSAlex Bennée     /*
1421842b42dfSAlex Bennée      * Note: This command is deprecated and modern gdb's will be using the
1422842b42dfSAlex Bennée      *       vCont command instead.
1423842b42dfSAlex Bennée      */
1424842b42dfSAlex Bennée     switch (get_param(params, 0)->opcode) {
1425842b42dfSAlex Bennée     case 'c':
1426842b42dfSAlex Bennée         gdbserver_state.c_cpu = cpu;
142736e067b2SAlex Bennée         gdb_put_packet("OK");
1428842b42dfSAlex Bennée         break;
1429842b42dfSAlex Bennée     case 'g':
1430842b42dfSAlex Bennée         gdbserver_state.g_cpu = cpu;
143136e067b2SAlex Bennée         gdb_put_packet("OK");
1432842b42dfSAlex Bennée         break;
1433842b42dfSAlex Bennée     default:
143436e067b2SAlex Bennée         gdb_put_packet("E22");
1435842b42dfSAlex Bennée         break;
1436842b42dfSAlex Bennée     }
1437842b42dfSAlex Bennée }
1438842b42dfSAlex Bennée 
1439842b42dfSAlex Bennée static void handle_insert_bp(GArray *params, void *user_ctx)
1440842b42dfSAlex Bennée {
1441842b42dfSAlex Bennée     int res;
1442842b42dfSAlex Bennée 
1443842b42dfSAlex Bennée     if (params->len != 3) {
144436e067b2SAlex Bennée         gdb_put_packet("E22");
1445842b42dfSAlex Bennée         return;
1446842b42dfSAlex Bennée     }
1447842b42dfSAlex Bennée 
1448ae7467b1SAlex Bennée     res = gdb_breakpoint_insert(gdbserver_state.c_cpu,
1449ae7467b1SAlex Bennée                                 get_param(params, 0)->val_ul,
1450842b42dfSAlex Bennée                                 get_param(params, 1)->val_ull,
1451842b42dfSAlex Bennée                                 get_param(params, 2)->val_ull);
1452842b42dfSAlex Bennée     if (res >= 0) {
145336e067b2SAlex Bennée         gdb_put_packet("OK");
1454842b42dfSAlex Bennée         return;
1455842b42dfSAlex Bennée     } else if (res == -ENOSYS) {
145636e067b2SAlex Bennée         gdb_put_packet("");
1457842b42dfSAlex Bennée         return;
1458842b42dfSAlex Bennée     }
1459842b42dfSAlex Bennée 
146036e067b2SAlex Bennée     gdb_put_packet("E22");
1461842b42dfSAlex Bennée }
1462842b42dfSAlex Bennée 
1463842b42dfSAlex Bennée static void handle_remove_bp(GArray *params, void *user_ctx)
1464842b42dfSAlex Bennée {
1465842b42dfSAlex Bennée     int res;
1466842b42dfSAlex Bennée 
1467842b42dfSAlex Bennée     if (params->len != 3) {
146836e067b2SAlex Bennée         gdb_put_packet("E22");
1469842b42dfSAlex Bennée         return;
1470842b42dfSAlex Bennée     }
1471842b42dfSAlex Bennée 
1472ae7467b1SAlex Bennée     res = gdb_breakpoint_remove(gdbserver_state.c_cpu,
1473ae7467b1SAlex Bennée                                 get_param(params, 0)->val_ul,
1474842b42dfSAlex Bennée                                 get_param(params, 1)->val_ull,
1475842b42dfSAlex Bennée                                 get_param(params, 2)->val_ull);
1476842b42dfSAlex Bennée     if (res >= 0) {
147736e067b2SAlex Bennée         gdb_put_packet("OK");
1478842b42dfSAlex Bennée         return;
1479842b42dfSAlex Bennée     } else if (res == -ENOSYS) {
148036e067b2SAlex Bennée         gdb_put_packet("");
1481842b42dfSAlex Bennée         return;
1482842b42dfSAlex Bennée     }
1483842b42dfSAlex Bennée 
148436e067b2SAlex Bennée     gdb_put_packet("E22");
1485842b42dfSAlex Bennée }
1486842b42dfSAlex Bennée 
1487842b42dfSAlex Bennée /*
1488842b42dfSAlex Bennée  * handle_set/get_reg
1489842b42dfSAlex Bennée  *
1490842b42dfSAlex Bennée  * Older gdb are really dumb, and don't use 'G/g' if 'P/p' is available.
1491842b42dfSAlex Bennée  * This works, but can be very slow. Anything new enough to understand
1492842b42dfSAlex Bennée  * XML also knows how to use this properly. However to use this we
1493842b42dfSAlex Bennée  * need to define a local XML file as well as be talking to a
1494842b42dfSAlex Bennée  * reasonably modern gdb. Responding with an empty packet will cause
1495842b42dfSAlex Bennée  * the remote gdb to fallback to older methods.
1496842b42dfSAlex Bennée  */
1497842b42dfSAlex Bennée 
1498842b42dfSAlex Bennée static void handle_set_reg(GArray *params, void *user_ctx)
1499842b42dfSAlex Bennée {
1500842b42dfSAlex Bennée     int reg_size;
1501842b42dfSAlex Bennée 
1502842b42dfSAlex Bennée     if (!gdb_has_xml) {
150336e067b2SAlex Bennée         gdb_put_packet("");
1504842b42dfSAlex Bennée         return;
1505842b42dfSAlex Bennée     }
1506842b42dfSAlex Bennée 
1507842b42dfSAlex Bennée     if (params->len != 2) {
150836e067b2SAlex Bennée         gdb_put_packet("E22");
1509842b42dfSAlex Bennée         return;
1510842b42dfSAlex Bennée     }
1511842b42dfSAlex Bennée 
1512842b42dfSAlex Bennée     reg_size = strlen(get_param(params, 1)->data) / 2;
151336e067b2SAlex Bennée     gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 1)->data, reg_size);
1514842b42dfSAlex Bennée     gdb_write_register(gdbserver_state.g_cpu, gdbserver_state.mem_buf->data,
1515842b42dfSAlex Bennée                        get_param(params, 0)->val_ull);
151636e067b2SAlex Bennée     gdb_put_packet("OK");
1517842b42dfSAlex Bennée }
1518842b42dfSAlex Bennée 
1519842b42dfSAlex Bennée static void handle_get_reg(GArray *params, void *user_ctx)
1520842b42dfSAlex Bennée {
1521842b42dfSAlex Bennée     int reg_size;
1522842b42dfSAlex Bennée 
1523842b42dfSAlex Bennée     if (!gdb_has_xml) {
152436e067b2SAlex Bennée         gdb_put_packet("");
1525842b42dfSAlex Bennée         return;
1526842b42dfSAlex Bennée     }
1527842b42dfSAlex Bennée 
1528842b42dfSAlex Bennée     if (!params->len) {
152936e067b2SAlex Bennée         gdb_put_packet("E14");
1530842b42dfSAlex Bennée         return;
1531842b42dfSAlex Bennée     }
1532842b42dfSAlex Bennée 
1533842b42dfSAlex Bennée     reg_size = gdb_read_register(gdbserver_state.g_cpu,
1534842b42dfSAlex Bennée                                  gdbserver_state.mem_buf,
1535842b42dfSAlex Bennée                                  get_param(params, 0)->val_ull);
1536842b42dfSAlex Bennée     if (!reg_size) {
153736e067b2SAlex Bennée         gdb_put_packet("E14");
1538842b42dfSAlex Bennée         return;
1539842b42dfSAlex Bennée     } else {
1540842b42dfSAlex Bennée         g_byte_array_set_size(gdbserver_state.mem_buf, reg_size);
1541842b42dfSAlex Bennée     }
1542842b42dfSAlex Bennée 
154336e067b2SAlex Bennée     gdb_memtohex(gdbserver_state.str_buf,
154436e067b2SAlex Bennée                  gdbserver_state.mem_buf->data, reg_size);
154536e067b2SAlex Bennée     gdb_put_strbuf();
1546842b42dfSAlex Bennée }
1547842b42dfSAlex Bennée 
1548842b42dfSAlex Bennée static void handle_write_mem(GArray *params, void *user_ctx)
1549842b42dfSAlex Bennée {
1550842b42dfSAlex Bennée     if (params->len != 3) {
155136e067b2SAlex Bennée         gdb_put_packet("E22");
1552842b42dfSAlex Bennée         return;
1553842b42dfSAlex Bennée     }
1554842b42dfSAlex Bennée 
155536e067b2SAlex Bennée     /* gdb_hextomem() reads 2*len bytes */
1556842b42dfSAlex Bennée     if (get_param(params, 1)->val_ull >
1557842b42dfSAlex Bennée         strlen(get_param(params, 2)->data) / 2) {
155836e067b2SAlex Bennée         gdb_put_packet("E22");
1559842b42dfSAlex Bennée         return;
1560842b42dfSAlex Bennée     }
1561842b42dfSAlex Bennée 
156236e067b2SAlex Bennée     gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 2)->data,
1563842b42dfSAlex Bennée              get_param(params, 1)->val_ull);
1564842b42dfSAlex Bennée     if (target_memory_rw_debug(gdbserver_state.g_cpu,
1565842b42dfSAlex Bennée                                get_param(params, 0)->val_ull,
1566842b42dfSAlex Bennée                                gdbserver_state.mem_buf->data,
1567842b42dfSAlex Bennée                                gdbserver_state.mem_buf->len, true)) {
156836e067b2SAlex Bennée         gdb_put_packet("E14");
1569842b42dfSAlex Bennée         return;
1570842b42dfSAlex Bennée     }
1571842b42dfSAlex Bennée 
157236e067b2SAlex Bennée     gdb_put_packet("OK");
1573842b42dfSAlex Bennée }
1574842b42dfSAlex Bennée 
1575842b42dfSAlex Bennée static void handle_read_mem(GArray *params, void *user_ctx)
1576842b42dfSAlex Bennée {
1577842b42dfSAlex Bennée     if (params->len != 2) {
157836e067b2SAlex Bennée         gdb_put_packet("E22");
1579842b42dfSAlex Bennée         return;
1580842b42dfSAlex Bennée     }
1581842b42dfSAlex Bennée 
158236e067b2SAlex Bennée     /* gdb_memtohex() doubles the required space */
1583842b42dfSAlex Bennée     if (get_param(params, 1)->val_ull > MAX_PACKET_LENGTH / 2) {
158436e067b2SAlex Bennée         gdb_put_packet("E22");
1585842b42dfSAlex Bennée         return;
1586842b42dfSAlex Bennée     }
1587842b42dfSAlex Bennée 
1588842b42dfSAlex Bennée     g_byte_array_set_size(gdbserver_state.mem_buf,
1589842b42dfSAlex Bennée                           get_param(params, 1)->val_ull);
1590842b42dfSAlex Bennée 
1591842b42dfSAlex Bennée     if (target_memory_rw_debug(gdbserver_state.g_cpu,
1592842b42dfSAlex Bennée                                get_param(params, 0)->val_ull,
1593842b42dfSAlex Bennée                                gdbserver_state.mem_buf->data,
1594842b42dfSAlex Bennée                                gdbserver_state.mem_buf->len, false)) {
159536e067b2SAlex Bennée         gdb_put_packet("E14");
1596842b42dfSAlex Bennée         return;
1597842b42dfSAlex Bennée     }
1598842b42dfSAlex Bennée 
159936e067b2SAlex Bennée     gdb_memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data,
1600842b42dfSAlex Bennée              gdbserver_state.mem_buf->len);
160136e067b2SAlex Bennée     gdb_put_strbuf();
1602842b42dfSAlex Bennée }
1603842b42dfSAlex Bennée 
1604842b42dfSAlex Bennée static void handle_write_all_regs(GArray *params, void *user_ctx)
1605842b42dfSAlex Bennée {
1606842b42dfSAlex Bennée     target_ulong addr, len;
1607842b42dfSAlex Bennée     uint8_t *registers;
1608842b42dfSAlex Bennée     int reg_size;
1609842b42dfSAlex Bennée 
1610842b42dfSAlex Bennée     if (!params->len) {
1611842b42dfSAlex Bennée         return;
1612842b42dfSAlex Bennée     }
1613842b42dfSAlex Bennée 
1614842b42dfSAlex Bennée     cpu_synchronize_state(gdbserver_state.g_cpu);
1615842b42dfSAlex Bennée     len = strlen(get_param(params, 0)->data) / 2;
161636e067b2SAlex Bennée     gdb_hextomem(gdbserver_state.mem_buf, get_param(params, 0)->data, len);
1617842b42dfSAlex Bennée     registers = gdbserver_state.mem_buf->data;
1618842b42dfSAlex Bennée     for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs && len > 0;
1619842b42dfSAlex Bennée          addr++) {
1620842b42dfSAlex Bennée         reg_size = gdb_write_register(gdbserver_state.g_cpu, registers, addr);
1621842b42dfSAlex Bennée         len -= reg_size;
1622842b42dfSAlex Bennée         registers += reg_size;
1623842b42dfSAlex Bennée     }
162436e067b2SAlex Bennée     gdb_put_packet("OK");
1625842b42dfSAlex Bennée }
1626842b42dfSAlex Bennée 
1627842b42dfSAlex Bennée static void handle_read_all_regs(GArray *params, void *user_ctx)
1628842b42dfSAlex Bennée {
1629842b42dfSAlex Bennée     target_ulong addr, len;
1630842b42dfSAlex Bennée 
1631842b42dfSAlex Bennée     cpu_synchronize_state(gdbserver_state.g_cpu);
1632842b42dfSAlex Bennée     g_byte_array_set_size(gdbserver_state.mem_buf, 0);
1633842b42dfSAlex Bennée     len = 0;
1634842b42dfSAlex Bennée     for (addr = 0; addr < gdbserver_state.g_cpu->gdb_num_g_regs; addr++) {
1635842b42dfSAlex Bennée         len += gdb_read_register(gdbserver_state.g_cpu,
1636842b42dfSAlex Bennée                                  gdbserver_state.mem_buf,
1637842b42dfSAlex Bennée                                  addr);
1638842b42dfSAlex Bennée     }
1639842b42dfSAlex Bennée     g_assert(len == gdbserver_state.mem_buf->len);
1640842b42dfSAlex Bennée 
164136e067b2SAlex Bennée     gdb_memtohex(gdbserver_state.str_buf, gdbserver_state.mem_buf->data, len);
164236e067b2SAlex Bennée     gdb_put_strbuf();
1643842b42dfSAlex Bennée }
1644842b42dfSAlex Bennée 
1645842b42dfSAlex Bennée static void handle_file_io(GArray *params, void *user_ctx)
1646842b42dfSAlex Bennée {
1647842b42dfSAlex Bennée     if (params->len >= 1 && gdbserver_state.current_syscall_cb) {
1648842b42dfSAlex Bennée         uint64_t ret;
1649842b42dfSAlex Bennée         int err;
1650842b42dfSAlex Bennée 
1651842b42dfSAlex Bennée         ret = get_param(params, 0)->val_ull;
1652842b42dfSAlex Bennée         if (params->len >= 2) {
1653842b42dfSAlex Bennée             err = get_param(params, 1)->val_ull;
1654842b42dfSAlex Bennée         } else {
1655842b42dfSAlex Bennée             err = 0;
1656842b42dfSAlex Bennée         }
1657842b42dfSAlex Bennée 
1658842b42dfSAlex Bennée         /* Convert GDB error numbers back to host error numbers. */
1659842b42dfSAlex Bennée #define E(X)  case GDB_E##X: err = E##X; break
1660842b42dfSAlex Bennée         switch (err) {
1661842b42dfSAlex Bennée         case 0:
1662842b42dfSAlex Bennée             break;
1663842b42dfSAlex Bennée         E(PERM);
1664842b42dfSAlex Bennée         E(NOENT);
1665842b42dfSAlex Bennée         E(INTR);
1666842b42dfSAlex Bennée         E(BADF);
1667842b42dfSAlex Bennée         E(ACCES);
1668842b42dfSAlex Bennée         E(FAULT);
1669842b42dfSAlex Bennée         E(BUSY);
1670842b42dfSAlex Bennée         E(EXIST);
1671842b42dfSAlex Bennée         E(NODEV);
1672842b42dfSAlex Bennée         E(NOTDIR);
1673842b42dfSAlex Bennée         E(ISDIR);
1674842b42dfSAlex Bennée         E(INVAL);
1675842b42dfSAlex Bennée         E(NFILE);
1676842b42dfSAlex Bennée         E(MFILE);
1677842b42dfSAlex Bennée         E(FBIG);
1678842b42dfSAlex Bennée         E(NOSPC);
1679842b42dfSAlex Bennée         E(SPIPE);
1680842b42dfSAlex Bennée         E(ROFS);
1681842b42dfSAlex Bennée         E(NAMETOOLONG);
1682842b42dfSAlex Bennée         default:
1683842b42dfSAlex Bennée             err = EINVAL;
1684842b42dfSAlex Bennée             break;
1685842b42dfSAlex Bennée         }
1686842b42dfSAlex Bennée #undef E
1687842b42dfSAlex Bennée 
1688842b42dfSAlex Bennée         gdbserver_state.current_syscall_cb(gdbserver_state.c_cpu, ret, err);
1689842b42dfSAlex Bennée         gdbserver_state.current_syscall_cb = NULL;
1690842b42dfSAlex Bennée     }
1691842b42dfSAlex Bennée 
1692842b42dfSAlex Bennée     if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') {
169336e067b2SAlex Bennée         gdb_put_packet("T02");
1694842b42dfSAlex Bennée         return;
1695842b42dfSAlex Bennée     }
1696842b42dfSAlex Bennée 
1697842b42dfSAlex Bennée     gdb_continue();
1698842b42dfSAlex Bennée }
1699842b42dfSAlex Bennée 
1700842b42dfSAlex Bennée static void handle_step(GArray *params, void *user_ctx)
1701842b42dfSAlex Bennée {
1702842b42dfSAlex Bennée     if (params->len) {
1703842b42dfSAlex Bennée         gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
1704842b42dfSAlex Bennée     }
1705842b42dfSAlex Bennée 
1706842b42dfSAlex Bennée     cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
1707842b42dfSAlex Bennée     gdb_continue();
1708842b42dfSAlex Bennée }
1709842b42dfSAlex Bennée 
1710842b42dfSAlex Bennée static void handle_backward(GArray *params, void *user_ctx)
1711842b42dfSAlex Bennée {
1712842b42dfSAlex Bennée     if (!stub_can_reverse()) {
171336e067b2SAlex Bennée         gdb_put_packet("E22");
1714842b42dfSAlex Bennée     }
1715842b42dfSAlex Bennée     if (params->len == 1) {
1716842b42dfSAlex Bennée         switch (get_param(params, 0)->opcode) {
1717842b42dfSAlex Bennée         case 's':
1718842b42dfSAlex Bennée             if (replay_reverse_step()) {
1719842b42dfSAlex Bennée                 gdb_continue();
1720842b42dfSAlex Bennée             } else {
172136e067b2SAlex Bennée                 gdb_put_packet("E14");
1722842b42dfSAlex Bennée             }
1723842b42dfSAlex Bennée             return;
1724842b42dfSAlex Bennée         case 'c':
1725842b42dfSAlex Bennée             if (replay_reverse_continue()) {
1726842b42dfSAlex Bennée                 gdb_continue();
1727842b42dfSAlex Bennée             } else {
172836e067b2SAlex Bennée                 gdb_put_packet("E14");
1729842b42dfSAlex Bennée             }
1730842b42dfSAlex Bennée             return;
1731842b42dfSAlex Bennée         }
1732842b42dfSAlex Bennée     }
1733842b42dfSAlex Bennée 
1734842b42dfSAlex Bennée     /* Default invalid command */
173536e067b2SAlex Bennée     gdb_put_packet("");
1736842b42dfSAlex Bennée }
1737842b42dfSAlex Bennée 
1738842b42dfSAlex Bennée static void handle_v_cont_query(GArray *params, void *user_ctx)
1739842b42dfSAlex Bennée {
174036e067b2SAlex Bennée     gdb_put_packet("vCont;c;C;s;S");
1741842b42dfSAlex Bennée }
1742842b42dfSAlex Bennée 
1743842b42dfSAlex Bennée static void handle_v_cont(GArray *params, void *user_ctx)
1744842b42dfSAlex Bennée {
1745842b42dfSAlex Bennée     int res;
1746842b42dfSAlex Bennée 
1747842b42dfSAlex Bennée     if (!params->len) {
1748842b42dfSAlex Bennée         return;
1749842b42dfSAlex Bennée     }
1750842b42dfSAlex Bennée 
1751842b42dfSAlex Bennée     res = gdb_handle_vcont(get_param(params, 0)->data);
1752842b42dfSAlex Bennée     if ((res == -EINVAL) || (res == -ERANGE)) {
175336e067b2SAlex Bennée         gdb_put_packet("E22");
1754842b42dfSAlex Bennée     } else if (res) {
175536e067b2SAlex Bennée         gdb_put_packet("");
1756842b42dfSAlex Bennée     }
1757842b42dfSAlex Bennée }
1758842b42dfSAlex Bennée 
1759842b42dfSAlex Bennée static void handle_v_attach(GArray *params, void *user_ctx)
1760842b42dfSAlex Bennée {
1761842b42dfSAlex Bennée     GDBProcess *process;
1762842b42dfSAlex Bennée     CPUState *cpu;
1763842b42dfSAlex Bennée 
1764842b42dfSAlex Bennée     g_string_assign(gdbserver_state.str_buf, "E22");
1765842b42dfSAlex Bennée     if (!params->len) {
1766842b42dfSAlex Bennée         goto cleanup;
1767842b42dfSAlex Bennée     }
1768842b42dfSAlex Bennée 
1769842b42dfSAlex Bennée     process = gdb_get_process(get_param(params, 0)->val_ul);
1770842b42dfSAlex Bennée     if (!process) {
1771842b42dfSAlex Bennée         goto cleanup;
1772842b42dfSAlex Bennée     }
1773842b42dfSAlex Bennée 
1774842b42dfSAlex Bennée     cpu = get_first_cpu_in_process(process);
1775842b42dfSAlex Bennée     if (!cpu) {
1776842b42dfSAlex Bennée         goto cleanup;
1777842b42dfSAlex Bennée     }
1778842b42dfSAlex Bennée 
1779842b42dfSAlex Bennée     process->attached = true;
1780842b42dfSAlex Bennée     gdbserver_state.g_cpu = cpu;
1781842b42dfSAlex Bennée     gdbserver_state.c_cpu = cpu;
1782842b42dfSAlex Bennée 
1783842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
1784842b42dfSAlex Bennée     gdb_append_thread_id(cpu, gdbserver_state.str_buf);
1785842b42dfSAlex Bennée     g_string_append_c(gdbserver_state.str_buf, ';');
1786842b42dfSAlex Bennée cleanup:
178736e067b2SAlex Bennée     gdb_put_strbuf();
1788842b42dfSAlex Bennée }
1789842b42dfSAlex Bennée 
1790842b42dfSAlex Bennée static void handle_v_kill(GArray *params, void *user_ctx)
1791842b42dfSAlex Bennée {
1792842b42dfSAlex Bennée     /* Kill the target */
179336e067b2SAlex Bennée     gdb_put_packet("OK");
1794842b42dfSAlex Bennée     error_report("QEMU: Terminated via GDBstub");
1795842b42dfSAlex Bennée     gdb_exit(0);
1796842b42dfSAlex Bennée     exit(0);
1797842b42dfSAlex Bennée }
1798842b42dfSAlex Bennée 
1799842b42dfSAlex Bennée static const GdbCmdParseEntry gdb_v_commands_table[] = {
1800842b42dfSAlex Bennée     /* Order is important if has same prefix */
1801842b42dfSAlex Bennée     {
1802842b42dfSAlex Bennée         .handler = handle_v_cont_query,
1803842b42dfSAlex Bennée         .cmd = "Cont?",
1804842b42dfSAlex Bennée         .cmd_startswith = 1
1805842b42dfSAlex Bennée     },
1806842b42dfSAlex Bennée     {
1807842b42dfSAlex Bennée         .handler = handle_v_cont,
1808842b42dfSAlex Bennée         .cmd = "Cont",
1809842b42dfSAlex Bennée         .cmd_startswith = 1,
1810842b42dfSAlex Bennée         .schema = "s0"
1811842b42dfSAlex Bennée     },
1812842b42dfSAlex Bennée     {
1813842b42dfSAlex Bennée         .handler = handle_v_attach,
1814842b42dfSAlex Bennée         .cmd = "Attach;",
1815842b42dfSAlex Bennée         .cmd_startswith = 1,
1816842b42dfSAlex Bennée         .schema = "l0"
1817842b42dfSAlex Bennée     },
1818842b42dfSAlex Bennée     {
1819842b42dfSAlex Bennée         .handler = handle_v_kill,
1820842b42dfSAlex Bennée         .cmd = "Kill;",
1821842b42dfSAlex Bennée         .cmd_startswith = 1
1822842b42dfSAlex Bennée     },
1823842b42dfSAlex Bennée };
1824842b42dfSAlex Bennée 
1825842b42dfSAlex Bennée static void handle_v_commands(GArray *params, void *user_ctx)
1826842b42dfSAlex Bennée {
1827842b42dfSAlex Bennée     if (!params->len) {
1828842b42dfSAlex Bennée         return;
1829842b42dfSAlex Bennée     }
1830842b42dfSAlex Bennée 
1831842b42dfSAlex Bennée     if (process_string_cmd(NULL, get_param(params, 0)->data,
1832842b42dfSAlex Bennée                            gdb_v_commands_table,
1833842b42dfSAlex Bennée                            ARRAY_SIZE(gdb_v_commands_table))) {
183436e067b2SAlex Bennée         gdb_put_packet("");
1835842b42dfSAlex Bennée     }
1836842b42dfSAlex Bennée }
1837842b42dfSAlex Bennée 
1838842b42dfSAlex Bennée static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
1839842b42dfSAlex Bennée {
1840842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
1841842b42dfSAlex Bennée 
1842842b42dfSAlex Bennée     if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
1843842b42dfSAlex Bennée         g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
1844842b42dfSAlex Bennée                                SSTEP_NOIRQ);
1845842b42dfSAlex Bennée     }
1846842b42dfSAlex Bennée 
1847842b42dfSAlex Bennée     if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
1848842b42dfSAlex Bennée         g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
1849842b42dfSAlex Bennée                                SSTEP_NOTIMER);
1850842b42dfSAlex Bennée     }
1851842b42dfSAlex Bennée 
185236e067b2SAlex Bennée     gdb_put_strbuf();
1853842b42dfSAlex Bennée }
1854842b42dfSAlex Bennée 
1855842b42dfSAlex Bennée static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
1856842b42dfSAlex Bennée {
1857842b42dfSAlex Bennée     int new_sstep_flags;
1858842b42dfSAlex Bennée 
1859842b42dfSAlex Bennée     if (!params->len) {
1860842b42dfSAlex Bennée         return;
1861842b42dfSAlex Bennée     }
1862842b42dfSAlex Bennée 
1863842b42dfSAlex Bennée     new_sstep_flags = get_param(params, 0)->val_ul;
1864842b42dfSAlex Bennée 
1865842b42dfSAlex Bennée     if (new_sstep_flags  & ~gdbserver_state.supported_sstep_flags) {
186636e067b2SAlex Bennée         gdb_put_packet("E22");
1867842b42dfSAlex Bennée         return;
1868842b42dfSAlex Bennée     }
1869842b42dfSAlex Bennée 
1870842b42dfSAlex Bennée     gdbserver_state.sstep_flags = new_sstep_flags;
187136e067b2SAlex Bennée     gdb_put_packet("OK");
1872842b42dfSAlex Bennée }
1873842b42dfSAlex Bennée 
1874842b42dfSAlex Bennée static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
1875842b42dfSAlex Bennée {
1876842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "0x%x",
1877842b42dfSAlex Bennée                     gdbserver_state.sstep_flags);
187836e067b2SAlex Bennée     gdb_put_strbuf();
1879842b42dfSAlex Bennée }
1880842b42dfSAlex Bennée 
1881842b42dfSAlex Bennée static void handle_query_curr_tid(GArray *params, void *user_ctx)
1882842b42dfSAlex Bennée {
1883842b42dfSAlex Bennée     CPUState *cpu;
1884842b42dfSAlex Bennée     GDBProcess *process;
1885842b42dfSAlex Bennée 
1886842b42dfSAlex Bennée     /*
1887842b42dfSAlex Bennée      * "Current thread" remains vague in the spec, so always return
1888842b42dfSAlex Bennée      * the first thread of the current process (gdb returns the
1889842b42dfSAlex Bennée      * first thread).
1890842b42dfSAlex Bennée      */
1891842b42dfSAlex Bennée     process = gdb_get_cpu_process(gdbserver_state.g_cpu);
1892842b42dfSAlex Bennée     cpu = get_first_cpu_in_process(process);
1893842b42dfSAlex Bennée     g_string_assign(gdbserver_state.str_buf, "QC");
1894842b42dfSAlex Bennée     gdb_append_thread_id(cpu, gdbserver_state.str_buf);
189536e067b2SAlex Bennée     gdb_put_strbuf();
1896842b42dfSAlex Bennée }
1897842b42dfSAlex Bennée 
1898842b42dfSAlex Bennée static void handle_query_threads(GArray *params, void *user_ctx)
1899842b42dfSAlex Bennée {
1900842b42dfSAlex Bennée     if (!gdbserver_state.query_cpu) {
190136e067b2SAlex Bennée         gdb_put_packet("l");
1902842b42dfSAlex Bennée         return;
1903842b42dfSAlex Bennée     }
1904842b42dfSAlex Bennée 
1905842b42dfSAlex Bennée     g_string_assign(gdbserver_state.str_buf, "m");
1906842b42dfSAlex Bennée     gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
190736e067b2SAlex Bennée     gdb_put_strbuf();
1908842b42dfSAlex Bennée     gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
1909842b42dfSAlex Bennée }
1910842b42dfSAlex Bennée 
1911842b42dfSAlex Bennée static void handle_query_first_threads(GArray *params, void *user_ctx)
1912842b42dfSAlex Bennée {
1913842b42dfSAlex Bennée     gdbserver_state.query_cpu = gdb_first_attached_cpu();
1914842b42dfSAlex Bennée     handle_query_threads(params, user_ctx);
1915842b42dfSAlex Bennée }
1916842b42dfSAlex Bennée 
1917842b42dfSAlex Bennée static void handle_query_thread_extra(GArray *params, void *user_ctx)
1918842b42dfSAlex Bennée {
1919842b42dfSAlex Bennée     g_autoptr(GString) rs = g_string_new(NULL);
1920842b42dfSAlex Bennée     CPUState *cpu;
1921842b42dfSAlex Bennée 
1922842b42dfSAlex Bennée     if (!params->len ||
1923842b42dfSAlex Bennée         get_param(params, 0)->thread_id.kind == GDB_READ_THREAD_ERR) {
192436e067b2SAlex Bennée         gdb_put_packet("E22");
1925842b42dfSAlex Bennée         return;
1926842b42dfSAlex Bennée     }
1927842b42dfSAlex Bennée 
1928842b42dfSAlex Bennée     cpu = gdb_get_cpu(get_param(params, 0)->thread_id.pid,
1929842b42dfSAlex Bennée                       get_param(params, 0)->thread_id.tid);
1930842b42dfSAlex Bennée     if (!cpu) {
1931842b42dfSAlex Bennée         return;
1932842b42dfSAlex Bennée     }
1933842b42dfSAlex Bennée 
1934842b42dfSAlex Bennée     cpu_synchronize_state(cpu);
1935842b42dfSAlex Bennée 
1936842b42dfSAlex Bennée     if (gdbserver_state.multiprocess && (gdbserver_state.process_num > 1)) {
1937842b42dfSAlex Bennée         /* Print the CPU model and name in multiprocess mode */
1938842b42dfSAlex Bennée         ObjectClass *oc = object_get_class(OBJECT(cpu));
1939842b42dfSAlex Bennée         const char *cpu_model = object_class_get_name(oc);
1940842b42dfSAlex Bennée         const char *cpu_name =
1941842b42dfSAlex Bennée             object_get_canonical_path_component(OBJECT(cpu));
1942842b42dfSAlex Bennée         g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
1943842b42dfSAlex Bennée                         cpu->halted ? "halted " : "running");
1944842b42dfSAlex Bennée     } else {
1945842b42dfSAlex Bennée         g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
1946842b42dfSAlex Bennée                         cpu->halted ? "halted " : "running");
1947842b42dfSAlex Bennée     }
1948842b42dfSAlex Bennée     trace_gdbstub_op_extra_info(rs->str);
194936e067b2SAlex Bennée     gdb_memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
195036e067b2SAlex Bennée     gdb_put_strbuf();
1951842b42dfSAlex Bennée }
1952842b42dfSAlex Bennée 
1953842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
1954842b42dfSAlex Bennée static void handle_query_offsets(GArray *params, void *user_ctx)
1955842b42dfSAlex Bennée {
1956842b42dfSAlex Bennée     TaskState *ts;
1957842b42dfSAlex Bennée 
1958842b42dfSAlex Bennée     ts = gdbserver_state.c_cpu->opaque;
1959842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf,
1960842b42dfSAlex Bennée                     "Text=" TARGET_ABI_FMT_lx
1961842b42dfSAlex Bennée                     ";Data=" TARGET_ABI_FMT_lx
1962842b42dfSAlex Bennée                     ";Bss=" TARGET_ABI_FMT_lx,
1963842b42dfSAlex Bennée                     ts->info->code_offset,
1964842b42dfSAlex Bennée                     ts->info->data_offset,
1965842b42dfSAlex Bennée                     ts->info->data_offset);
196636e067b2SAlex Bennée     gdb_put_strbuf();
1967842b42dfSAlex Bennée }
1968842b42dfSAlex Bennée #endif
1969842b42dfSAlex Bennée 
1970842b42dfSAlex Bennée static void handle_query_supported(GArray *params, void *user_ctx)
1971842b42dfSAlex Bennée {
1972842b42dfSAlex Bennée     CPUClass *cc;
1973842b42dfSAlex Bennée 
1974842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
1975842b42dfSAlex Bennée     cc = CPU_GET_CLASS(first_cpu);
1976842b42dfSAlex Bennée     if (cc->gdb_core_xml_file) {
1977842b42dfSAlex Bennée         g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
1978842b42dfSAlex Bennée     }
1979842b42dfSAlex Bennée 
1980842b42dfSAlex Bennée     if (stub_can_reverse()) {
1981842b42dfSAlex Bennée         g_string_append(gdbserver_state.str_buf,
1982842b42dfSAlex Bennée             ";ReverseStep+;ReverseContinue+");
1983842b42dfSAlex Bennée     }
1984842b42dfSAlex Bennée 
1985842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
1986842b42dfSAlex Bennée     if (gdbserver_state.c_cpu->opaque) {
1987842b42dfSAlex Bennée         g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
1988842b42dfSAlex Bennée     }
1989842b42dfSAlex Bennée #endif
1990842b42dfSAlex Bennée 
1991842b42dfSAlex Bennée     if (params->len &&
1992842b42dfSAlex Bennée         strstr(get_param(params, 0)->data, "multiprocess+")) {
1993842b42dfSAlex Bennée         gdbserver_state.multiprocess = true;
1994842b42dfSAlex Bennée     }
1995842b42dfSAlex Bennée 
1996842b42dfSAlex Bennée     g_string_append(gdbserver_state.str_buf, ";vContSupported+;multiprocess+");
199736e067b2SAlex Bennée     gdb_put_strbuf();
1998842b42dfSAlex Bennée }
1999842b42dfSAlex Bennée 
2000842b42dfSAlex Bennée static void handle_query_xfer_features(GArray *params, void *user_ctx)
2001842b42dfSAlex Bennée {
2002842b42dfSAlex Bennée     GDBProcess *process;
2003842b42dfSAlex Bennée     CPUClass *cc;
2004842b42dfSAlex Bennée     unsigned long len, total_len, addr;
2005842b42dfSAlex Bennée     const char *xml;
2006842b42dfSAlex Bennée     const char *p;
2007842b42dfSAlex Bennée 
2008842b42dfSAlex Bennée     if (params->len < 3) {
200936e067b2SAlex Bennée         gdb_put_packet("E22");
2010842b42dfSAlex Bennée         return;
2011842b42dfSAlex Bennée     }
2012842b42dfSAlex Bennée 
2013842b42dfSAlex Bennée     process = gdb_get_cpu_process(gdbserver_state.g_cpu);
2014842b42dfSAlex Bennée     cc = CPU_GET_CLASS(gdbserver_state.g_cpu);
2015842b42dfSAlex Bennée     if (!cc->gdb_core_xml_file) {
201636e067b2SAlex Bennée         gdb_put_packet("");
2017842b42dfSAlex Bennée         return;
2018842b42dfSAlex Bennée     }
2019842b42dfSAlex Bennée 
2020842b42dfSAlex Bennée     gdb_has_xml = true;
2021842b42dfSAlex Bennée     p = get_param(params, 0)->data;
2022842b42dfSAlex Bennée     xml = get_feature_xml(p, &p, process);
2023842b42dfSAlex Bennée     if (!xml) {
202436e067b2SAlex Bennée         gdb_put_packet("E00");
2025842b42dfSAlex Bennée         return;
2026842b42dfSAlex Bennée     }
2027842b42dfSAlex Bennée 
2028842b42dfSAlex Bennée     addr = get_param(params, 1)->val_ul;
2029842b42dfSAlex Bennée     len = get_param(params, 2)->val_ul;
2030842b42dfSAlex Bennée     total_len = strlen(xml);
2031842b42dfSAlex Bennée     if (addr > total_len) {
203236e067b2SAlex Bennée         gdb_put_packet("E00");
2033842b42dfSAlex Bennée         return;
2034842b42dfSAlex Bennée     }
2035842b42dfSAlex Bennée 
2036842b42dfSAlex Bennée     if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2037842b42dfSAlex Bennée         len = (MAX_PACKET_LENGTH - 5) / 2;
2038842b42dfSAlex Bennée     }
2039842b42dfSAlex Bennée 
2040842b42dfSAlex Bennée     if (len < total_len - addr) {
2041842b42dfSAlex Bennée         g_string_assign(gdbserver_state.str_buf, "m");
204236e067b2SAlex Bennée         gdb_memtox(gdbserver_state.str_buf, xml + addr, len);
2043842b42dfSAlex Bennée     } else {
2044842b42dfSAlex Bennée         g_string_assign(gdbserver_state.str_buf, "l");
204536e067b2SAlex Bennée         gdb_memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
2046842b42dfSAlex Bennée     }
2047842b42dfSAlex Bennée 
204836e067b2SAlex Bennée     gdb_put_packet_binary(gdbserver_state.str_buf->str,
2049842b42dfSAlex Bennée                       gdbserver_state.str_buf->len, true);
2050842b42dfSAlex Bennée }
2051842b42dfSAlex Bennée 
2052842b42dfSAlex Bennée #if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2053842b42dfSAlex Bennée static void handle_query_xfer_auxv(GArray *params, void *user_ctx)
2054842b42dfSAlex Bennée {
2055842b42dfSAlex Bennée     TaskState *ts;
2056842b42dfSAlex Bennée     unsigned long offset, len, saved_auxv, auxv_len;
2057842b42dfSAlex Bennée 
2058842b42dfSAlex Bennée     if (params->len < 2) {
205936e067b2SAlex Bennée         gdb_put_packet("E22");
2060842b42dfSAlex Bennée         return;
2061842b42dfSAlex Bennée     }
2062842b42dfSAlex Bennée 
2063842b42dfSAlex Bennée     offset = get_param(params, 0)->val_ul;
2064842b42dfSAlex Bennée     len = get_param(params, 1)->val_ul;
2065842b42dfSAlex Bennée     ts = gdbserver_state.c_cpu->opaque;
2066842b42dfSAlex Bennée     saved_auxv = ts->info->saved_auxv;
2067842b42dfSAlex Bennée     auxv_len = ts->info->auxv_len;
2068842b42dfSAlex Bennée 
2069842b42dfSAlex Bennée     if (offset >= auxv_len) {
207036e067b2SAlex Bennée         gdb_put_packet("E00");
2071842b42dfSAlex Bennée         return;
2072842b42dfSAlex Bennée     }
2073842b42dfSAlex Bennée 
2074842b42dfSAlex Bennée     if (len > (MAX_PACKET_LENGTH - 5) / 2) {
2075842b42dfSAlex Bennée         len = (MAX_PACKET_LENGTH - 5) / 2;
2076842b42dfSAlex Bennée     }
2077842b42dfSAlex Bennée 
2078842b42dfSAlex Bennée     if (len < auxv_len - offset) {
2079842b42dfSAlex Bennée         g_string_assign(gdbserver_state.str_buf, "m");
2080842b42dfSAlex Bennée     } else {
2081842b42dfSAlex Bennée         g_string_assign(gdbserver_state.str_buf, "l");
2082842b42dfSAlex Bennée         len = auxv_len - offset;
2083842b42dfSAlex Bennée     }
2084842b42dfSAlex Bennée 
2085842b42dfSAlex Bennée     g_byte_array_set_size(gdbserver_state.mem_buf, len);
2086842b42dfSAlex Bennée     if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
2087842b42dfSAlex Bennée                                gdbserver_state.mem_buf->data, len, false)) {
208836e067b2SAlex Bennée         gdb_put_packet("E14");
2089842b42dfSAlex Bennée         return;
2090842b42dfSAlex Bennée     }
2091842b42dfSAlex Bennée 
209236e067b2SAlex Bennée     gdb_memtox(gdbserver_state.str_buf,
2093842b42dfSAlex Bennée                (const char *)gdbserver_state.mem_buf->data, len);
209436e067b2SAlex Bennée     gdb_put_packet_binary(gdbserver_state.str_buf->str,
2095842b42dfSAlex Bennée                           gdbserver_state.str_buf->len, true);
2096842b42dfSAlex Bennée }
2097842b42dfSAlex Bennée #endif
2098842b42dfSAlex Bennée 
2099842b42dfSAlex Bennée static void handle_query_attached(GArray *params, void *user_ctx)
2100842b42dfSAlex Bennée {
210136e067b2SAlex Bennée     gdb_put_packet(GDB_ATTACHED);
2102842b42dfSAlex Bennée }
2103842b42dfSAlex Bennée 
2104842b42dfSAlex Bennée static void handle_query_qemu_supported(GArray *params, void *user_ctx)
2105842b42dfSAlex Bennée {
2106842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
2107842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2108842b42dfSAlex Bennée     g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
2109842b42dfSAlex Bennée #endif
211036e067b2SAlex Bennée     gdb_put_strbuf();
2111842b42dfSAlex Bennée }
2112842b42dfSAlex Bennée 
2113842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2114842b42dfSAlex Bennée static void handle_query_qemu_phy_mem_mode(GArray *params,
2115842b42dfSAlex Bennée                                            void *user_ctx)
2116842b42dfSAlex Bennée {
2117842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
211836e067b2SAlex Bennée     gdb_put_strbuf();
2119842b42dfSAlex Bennée }
2120842b42dfSAlex Bennée 
2121842b42dfSAlex Bennée static void handle_set_qemu_phy_mem_mode(GArray *params, void *user_ctx)
2122842b42dfSAlex Bennée {
2123842b42dfSAlex Bennée     if (!params->len) {
212436e067b2SAlex Bennée         gdb_put_packet("E22");
2125842b42dfSAlex Bennée         return;
2126842b42dfSAlex Bennée     }
2127842b42dfSAlex Bennée 
2128842b42dfSAlex Bennée     if (!get_param(params, 0)->val_ul) {
2129842b42dfSAlex Bennée         phy_memory_mode = 0;
2130842b42dfSAlex Bennée     } else {
2131842b42dfSAlex Bennée         phy_memory_mode = 1;
2132842b42dfSAlex Bennée     }
213336e067b2SAlex Bennée     gdb_put_packet("OK");
2134842b42dfSAlex Bennée }
2135842b42dfSAlex Bennée #endif
2136842b42dfSAlex Bennée 
2137842b42dfSAlex Bennée static const GdbCmdParseEntry gdb_gen_query_set_common_table[] = {
2138842b42dfSAlex Bennée     /* Order is important if has same prefix */
2139842b42dfSAlex Bennée     {
2140842b42dfSAlex Bennée         .handler = handle_query_qemu_sstepbits,
2141842b42dfSAlex Bennée         .cmd = "qemu.sstepbits",
2142842b42dfSAlex Bennée     },
2143842b42dfSAlex Bennée     {
2144842b42dfSAlex Bennée         .handler = handle_query_qemu_sstep,
2145842b42dfSAlex Bennée         .cmd = "qemu.sstep",
2146842b42dfSAlex Bennée     },
2147842b42dfSAlex Bennée     {
2148842b42dfSAlex Bennée         .handler = handle_set_qemu_sstep,
2149842b42dfSAlex Bennée         .cmd = "qemu.sstep=",
2150842b42dfSAlex Bennée         .cmd_startswith = 1,
2151842b42dfSAlex Bennée         .schema = "l0"
2152842b42dfSAlex Bennée     },
2153842b42dfSAlex Bennée };
2154842b42dfSAlex Bennée 
2155842b42dfSAlex Bennée static const GdbCmdParseEntry gdb_gen_query_table[] = {
2156842b42dfSAlex Bennée     {
2157842b42dfSAlex Bennée         .handler = handle_query_curr_tid,
2158842b42dfSAlex Bennée         .cmd = "C",
2159842b42dfSAlex Bennée     },
2160842b42dfSAlex Bennée     {
2161842b42dfSAlex Bennée         .handler = handle_query_threads,
2162842b42dfSAlex Bennée         .cmd = "sThreadInfo",
2163842b42dfSAlex Bennée     },
2164842b42dfSAlex Bennée     {
2165842b42dfSAlex Bennée         .handler = handle_query_first_threads,
2166842b42dfSAlex Bennée         .cmd = "fThreadInfo",
2167842b42dfSAlex Bennée     },
2168842b42dfSAlex Bennée     {
2169842b42dfSAlex Bennée         .handler = handle_query_thread_extra,
2170842b42dfSAlex Bennée         .cmd = "ThreadExtraInfo,",
2171842b42dfSAlex Bennée         .cmd_startswith = 1,
2172842b42dfSAlex Bennée         .schema = "t0"
2173842b42dfSAlex Bennée     },
2174842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
2175842b42dfSAlex Bennée     {
2176842b42dfSAlex Bennée         .handler = handle_query_offsets,
2177842b42dfSAlex Bennée         .cmd = "Offsets",
2178842b42dfSAlex Bennée     },
2179842b42dfSAlex Bennée #else
2180842b42dfSAlex Bennée     {
2181b6fa2ec2SAlex Bennée         .handler = gdb_handle_query_rcmd,
2182842b42dfSAlex Bennée         .cmd = "Rcmd,",
2183842b42dfSAlex Bennée         .cmd_startswith = 1,
2184842b42dfSAlex Bennée         .schema = "s0"
2185842b42dfSAlex Bennée     },
2186842b42dfSAlex Bennée #endif
2187842b42dfSAlex Bennée     {
2188842b42dfSAlex Bennée         .handler = handle_query_supported,
2189842b42dfSAlex Bennée         .cmd = "Supported:",
2190842b42dfSAlex Bennée         .cmd_startswith = 1,
2191842b42dfSAlex Bennée         .schema = "s0"
2192842b42dfSAlex Bennée     },
2193842b42dfSAlex Bennée     {
2194842b42dfSAlex Bennée         .handler = handle_query_supported,
2195842b42dfSAlex Bennée         .cmd = "Supported",
2196842b42dfSAlex Bennée         .schema = "s0"
2197842b42dfSAlex Bennée     },
2198842b42dfSAlex Bennée     {
2199842b42dfSAlex Bennée         .handler = handle_query_xfer_features,
2200842b42dfSAlex Bennée         .cmd = "Xfer:features:read:",
2201842b42dfSAlex Bennée         .cmd_startswith = 1,
2202842b42dfSAlex Bennée         .schema = "s:l,l0"
2203842b42dfSAlex Bennée     },
2204842b42dfSAlex Bennée #if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
2205842b42dfSAlex Bennée     {
2206842b42dfSAlex Bennée         .handler = handle_query_xfer_auxv,
2207842b42dfSAlex Bennée         .cmd = "Xfer:auxv:read::",
2208842b42dfSAlex Bennée         .cmd_startswith = 1,
2209842b42dfSAlex Bennée         .schema = "l,l0"
2210842b42dfSAlex Bennée     },
2211842b42dfSAlex Bennée #endif
2212842b42dfSAlex Bennée     {
2213842b42dfSAlex Bennée         .handler = handle_query_attached,
2214842b42dfSAlex Bennée         .cmd = "Attached:",
2215842b42dfSAlex Bennée         .cmd_startswith = 1
2216842b42dfSAlex Bennée     },
2217842b42dfSAlex Bennée     {
2218842b42dfSAlex Bennée         .handler = handle_query_attached,
2219842b42dfSAlex Bennée         .cmd = "Attached",
2220842b42dfSAlex Bennée     },
2221842b42dfSAlex Bennée     {
2222842b42dfSAlex Bennée         .handler = handle_query_qemu_supported,
2223842b42dfSAlex Bennée         .cmd = "qemu.Supported",
2224842b42dfSAlex Bennée     },
2225842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2226842b42dfSAlex Bennée     {
2227842b42dfSAlex Bennée         .handler = handle_query_qemu_phy_mem_mode,
2228842b42dfSAlex Bennée         .cmd = "qemu.PhyMemMode",
2229842b42dfSAlex Bennée     },
2230842b42dfSAlex Bennée #endif
2231842b42dfSAlex Bennée };
2232842b42dfSAlex Bennée 
2233842b42dfSAlex Bennée static const GdbCmdParseEntry gdb_gen_set_table[] = {
2234842b42dfSAlex Bennée     /* Order is important if has same prefix */
2235842b42dfSAlex Bennée     {
2236842b42dfSAlex Bennée         .handler = handle_set_qemu_sstep,
2237842b42dfSAlex Bennée         .cmd = "qemu.sstep:",
2238842b42dfSAlex Bennée         .cmd_startswith = 1,
2239842b42dfSAlex Bennée         .schema = "l0"
2240842b42dfSAlex Bennée     },
2241842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2242842b42dfSAlex Bennée     {
2243842b42dfSAlex Bennée         .handler = handle_set_qemu_phy_mem_mode,
2244842b42dfSAlex Bennée         .cmd = "qemu.PhyMemMode:",
2245842b42dfSAlex Bennée         .cmd_startswith = 1,
2246842b42dfSAlex Bennée         .schema = "l0"
2247842b42dfSAlex Bennée     },
2248842b42dfSAlex Bennée #endif
2249842b42dfSAlex Bennée };
2250842b42dfSAlex Bennée 
2251842b42dfSAlex Bennée static void handle_gen_query(GArray *params, void *user_ctx)
2252842b42dfSAlex Bennée {
2253842b42dfSAlex Bennée     if (!params->len) {
2254842b42dfSAlex Bennée         return;
2255842b42dfSAlex Bennée     }
2256842b42dfSAlex Bennée 
2257842b42dfSAlex Bennée     if (!process_string_cmd(NULL, get_param(params, 0)->data,
2258842b42dfSAlex Bennée                             gdb_gen_query_set_common_table,
2259842b42dfSAlex Bennée                             ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2260842b42dfSAlex Bennée         return;
2261842b42dfSAlex Bennée     }
2262842b42dfSAlex Bennée 
2263842b42dfSAlex Bennée     if (process_string_cmd(NULL, get_param(params, 0)->data,
2264842b42dfSAlex Bennée                            gdb_gen_query_table,
2265842b42dfSAlex Bennée                            ARRAY_SIZE(gdb_gen_query_table))) {
226636e067b2SAlex Bennée         gdb_put_packet("");
2267842b42dfSAlex Bennée     }
2268842b42dfSAlex Bennée }
2269842b42dfSAlex Bennée 
2270842b42dfSAlex Bennée static void handle_gen_set(GArray *params, void *user_ctx)
2271842b42dfSAlex Bennée {
2272842b42dfSAlex Bennée     if (!params->len) {
2273842b42dfSAlex Bennée         return;
2274842b42dfSAlex Bennée     }
2275842b42dfSAlex Bennée 
2276842b42dfSAlex Bennée     if (!process_string_cmd(NULL, get_param(params, 0)->data,
2277842b42dfSAlex Bennée                             gdb_gen_query_set_common_table,
2278842b42dfSAlex Bennée                             ARRAY_SIZE(gdb_gen_query_set_common_table))) {
2279842b42dfSAlex Bennée         return;
2280842b42dfSAlex Bennée     }
2281842b42dfSAlex Bennée 
2282842b42dfSAlex Bennée     if (process_string_cmd(NULL, get_param(params, 0)->data,
2283842b42dfSAlex Bennée                            gdb_gen_set_table,
2284842b42dfSAlex Bennée                            ARRAY_SIZE(gdb_gen_set_table))) {
228536e067b2SAlex Bennée         gdb_put_packet("");
2286842b42dfSAlex Bennée     }
2287842b42dfSAlex Bennée }
2288842b42dfSAlex Bennée 
2289842b42dfSAlex Bennée static void handle_target_halt(GArray *params, void *user_ctx)
2290842b42dfSAlex Bennée {
2291842b42dfSAlex Bennée     g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
2292842b42dfSAlex Bennée     gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
2293842b42dfSAlex Bennée     g_string_append_c(gdbserver_state.str_buf, ';');
229436e067b2SAlex Bennée     gdb_put_strbuf();
2295842b42dfSAlex Bennée     /*
2296842b42dfSAlex Bennée      * Remove all the breakpoints when this query is issued,
2297842b42dfSAlex Bennée      * because gdb is doing an initial connect and the state
2298842b42dfSAlex Bennée      * should be cleaned up.
2299842b42dfSAlex Bennée      */
2300ae7467b1SAlex Bennée     gdb_breakpoint_remove_all(gdbserver_state.c_cpu);
2301842b42dfSAlex Bennée }
2302842b42dfSAlex Bennée 
2303842b42dfSAlex Bennée static int gdb_handle_packet(const char *line_buf)
2304842b42dfSAlex Bennée {
2305842b42dfSAlex Bennée     const GdbCmdParseEntry *cmd_parser = NULL;
2306842b42dfSAlex Bennée 
2307842b42dfSAlex Bennée     trace_gdbstub_io_command(line_buf);
2308842b42dfSAlex Bennée 
2309842b42dfSAlex Bennée     switch (line_buf[0]) {
2310842b42dfSAlex Bennée     case '!':
231136e067b2SAlex Bennée         gdb_put_packet("OK");
2312842b42dfSAlex Bennée         break;
2313842b42dfSAlex Bennée     case '?':
2314842b42dfSAlex Bennée         {
2315842b42dfSAlex Bennée             static const GdbCmdParseEntry target_halted_cmd_desc = {
2316842b42dfSAlex Bennée                 .handler = handle_target_halt,
2317842b42dfSAlex Bennée                 .cmd = "?",
2318842b42dfSAlex Bennée                 .cmd_startswith = 1
2319842b42dfSAlex Bennée             };
2320842b42dfSAlex Bennée             cmd_parser = &target_halted_cmd_desc;
2321842b42dfSAlex Bennée         }
2322842b42dfSAlex Bennée         break;
2323842b42dfSAlex Bennée     case 'c':
2324842b42dfSAlex Bennée         {
2325842b42dfSAlex Bennée             static const GdbCmdParseEntry continue_cmd_desc = {
2326842b42dfSAlex Bennée                 .handler = handle_continue,
2327842b42dfSAlex Bennée                 .cmd = "c",
2328842b42dfSAlex Bennée                 .cmd_startswith = 1,
2329842b42dfSAlex Bennée                 .schema = "L0"
2330842b42dfSAlex Bennée             };
2331842b42dfSAlex Bennée             cmd_parser = &continue_cmd_desc;
2332842b42dfSAlex Bennée         }
2333842b42dfSAlex Bennée         break;
2334842b42dfSAlex Bennée     case 'C':
2335842b42dfSAlex Bennée         {
2336842b42dfSAlex Bennée             static const GdbCmdParseEntry cont_with_sig_cmd_desc = {
2337842b42dfSAlex Bennée                 .handler = handle_cont_with_sig,
2338842b42dfSAlex Bennée                 .cmd = "C",
2339842b42dfSAlex Bennée                 .cmd_startswith = 1,
2340842b42dfSAlex Bennée                 .schema = "l0"
2341842b42dfSAlex Bennée             };
2342842b42dfSAlex Bennée             cmd_parser = &cont_with_sig_cmd_desc;
2343842b42dfSAlex Bennée         }
2344842b42dfSAlex Bennée         break;
2345842b42dfSAlex Bennée     case 'v':
2346842b42dfSAlex Bennée         {
2347842b42dfSAlex Bennée             static const GdbCmdParseEntry v_cmd_desc = {
2348842b42dfSAlex Bennée                 .handler = handle_v_commands,
2349842b42dfSAlex Bennée                 .cmd = "v",
2350842b42dfSAlex Bennée                 .cmd_startswith = 1,
2351842b42dfSAlex Bennée                 .schema = "s0"
2352842b42dfSAlex Bennée             };
2353842b42dfSAlex Bennée             cmd_parser = &v_cmd_desc;
2354842b42dfSAlex Bennée         }
2355842b42dfSAlex Bennée         break;
2356842b42dfSAlex Bennée     case 'k':
2357842b42dfSAlex Bennée         /* Kill the target */
2358842b42dfSAlex Bennée         error_report("QEMU: Terminated via GDBstub");
2359842b42dfSAlex Bennée         gdb_exit(0);
2360842b42dfSAlex Bennée         exit(0);
2361842b42dfSAlex Bennée     case 'D':
2362842b42dfSAlex Bennée         {
2363842b42dfSAlex Bennée             static const GdbCmdParseEntry detach_cmd_desc = {
2364842b42dfSAlex Bennée                 .handler = handle_detach,
2365842b42dfSAlex Bennée                 .cmd = "D",
2366842b42dfSAlex Bennée                 .cmd_startswith = 1,
2367842b42dfSAlex Bennée                 .schema = "?.l0"
2368842b42dfSAlex Bennée             };
2369842b42dfSAlex Bennée             cmd_parser = &detach_cmd_desc;
2370842b42dfSAlex Bennée         }
2371842b42dfSAlex Bennée         break;
2372842b42dfSAlex Bennée     case 's':
2373842b42dfSAlex Bennée         {
2374842b42dfSAlex Bennée             static const GdbCmdParseEntry step_cmd_desc = {
2375842b42dfSAlex Bennée                 .handler = handle_step,
2376842b42dfSAlex Bennée                 .cmd = "s",
2377842b42dfSAlex Bennée                 .cmd_startswith = 1,
2378842b42dfSAlex Bennée                 .schema = "L0"
2379842b42dfSAlex Bennée             };
2380842b42dfSAlex Bennée             cmd_parser = &step_cmd_desc;
2381842b42dfSAlex Bennée         }
2382842b42dfSAlex Bennée         break;
2383842b42dfSAlex Bennée     case 'b':
2384842b42dfSAlex Bennée         {
2385842b42dfSAlex Bennée             static const GdbCmdParseEntry backward_cmd_desc = {
2386842b42dfSAlex Bennée                 .handler = handle_backward,
2387842b42dfSAlex Bennée                 .cmd = "b",
2388842b42dfSAlex Bennée                 .cmd_startswith = 1,
2389842b42dfSAlex Bennée                 .schema = "o0"
2390842b42dfSAlex Bennée             };
2391842b42dfSAlex Bennée             cmd_parser = &backward_cmd_desc;
2392842b42dfSAlex Bennée         }
2393842b42dfSAlex Bennée         break;
2394842b42dfSAlex Bennée     case 'F':
2395842b42dfSAlex Bennée         {
2396842b42dfSAlex Bennée             static const GdbCmdParseEntry file_io_cmd_desc = {
2397842b42dfSAlex Bennée                 .handler = handle_file_io,
2398842b42dfSAlex Bennée                 .cmd = "F",
2399842b42dfSAlex Bennée                 .cmd_startswith = 1,
2400842b42dfSAlex Bennée                 .schema = "L,L,o0"
2401842b42dfSAlex Bennée             };
2402842b42dfSAlex Bennée             cmd_parser = &file_io_cmd_desc;
2403842b42dfSAlex Bennée         }
2404842b42dfSAlex Bennée         break;
2405842b42dfSAlex Bennée     case 'g':
2406842b42dfSAlex Bennée         {
2407842b42dfSAlex Bennée             static const GdbCmdParseEntry read_all_regs_cmd_desc = {
2408842b42dfSAlex Bennée                 .handler = handle_read_all_regs,
2409842b42dfSAlex Bennée                 .cmd = "g",
2410842b42dfSAlex Bennée                 .cmd_startswith = 1
2411842b42dfSAlex Bennée             };
2412842b42dfSAlex Bennée             cmd_parser = &read_all_regs_cmd_desc;
2413842b42dfSAlex Bennée         }
2414842b42dfSAlex Bennée         break;
2415842b42dfSAlex Bennée     case 'G':
2416842b42dfSAlex Bennée         {
2417842b42dfSAlex Bennée             static const GdbCmdParseEntry write_all_regs_cmd_desc = {
2418842b42dfSAlex Bennée                 .handler = handle_write_all_regs,
2419842b42dfSAlex Bennée                 .cmd = "G",
2420842b42dfSAlex Bennée                 .cmd_startswith = 1,
2421842b42dfSAlex Bennée                 .schema = "s0"
2422842b42dfSAlex Bennée             };
2423842b42dfSAlex Bennée             cmd_parser = &write_all_regs_cmd_desc;
2424842b42dfSAlex Bennée         }
2425842b42dfSAlex Bennée         break;
2426842b42dfSAlex Bennée     case 'm':
2427842b42dfSAlex Bennée         {
2428842b42dfSAlex Bennée             static const GdbCmdParseEntry read_mem_cmd_desc = {
2429842b42dfSAlex Bennée                 .handler = handle_read_mem,
2430842b42dfSAlex Bennée                 .cmd = "m",
2431842b42dfSAlex Bennée                 .cmd_startswith = 1,
2432842b42dfSAlex Bennée                 .schema = "L,L0"
2433842b42dfSAlex Bennée             };
2434842b42dfSAlex Bennée             cmd_parser = &read_mem_cmd_desc;
2435842b42dfSAlex Bennée         }
2436842b42dfSAlex Bennée         break;
2437842b42dfSAlex Bennée     case 'M':
2438842b42dfSAlex Bennée         {
2439842b42dfSAlex Bennée             static const GdbCmdParseEntry write_mem_cmd_desc = {
2440842b42dfSAlex Bennée                 .handler = handle_write_mem,
2441842b42dfSAlex Bennée                 .cmd = "M",
2442842b42dfSAlex Bennée                 .cmd_startswith = 1,
2443842b42dfSAlex Bennée                 .schema = "L,L:s0"
2444842b42dfSAlex Bennée             };
2445842b42dfSAlex Bennée             cmd_parser = &write_mem_cmd_desc;
2446842b42dfSAlex Bennée         }
2447842b42dfSAlex Bennée         break;
2448842b42dfSAlex Bennée     case 'p':
2449842b42dfSAlex Bennée         {
2450842b42dfSAlex Bennée             static const GdbCmdParseEntry get_reg_cmd_desc = {
2451842b42dfSAlex Bennée                 .handler = handle_get_reg,
2452842b42dfSAlex Bennée                 .cmd = "p",
2453842b42dfSAlex Bennée                 .cmd_startswith = 1,
2454842b42dfSAlex Bennée                 .schema = "L0"
2455842b42dfSAlex Bennée             };
2456842b42dfSAlex Bennée             cmd_parser = &get_reg_cmd_desc;
2457842b42dfSAlex Bennée         }
2458842b42dfSAlex Bennée         break;
2459842b42dfSAlex Bennée     case 'P':
2460842b42dfSAlex Bennée         {
2461842b42dfSAlex Bennée             static const GdbCmdParseEntry set_reg_cmd_desc = {
2462842b42dfSAlex Bennée                 .handler = handle_set_reg,
2463842b42dfSAlex Bennée                 .cmd = "P",
2464842b42dfSAlex Bennée                 .cmd_startswith = 1,
2465842b42dfSAlex Bennée                 .schema = "L?s0"
2466842b42dfSAlex Bennée             };
2467842b42dfSAlex Bennée             cmd_parser = &set_reg_cmd_desc;
2468842b42dfSAlex Bennée         }
2469842b42dfSAlex Bennée         break;
2470842b42dfSAlex Bennée     case 'Z':
2471842b42dfSAlex Bennée         {
2472842b42dfSAlex Bennée             static const GdbCmdParseEntry insert_bp_cmd_desc = {
2473842b42dfSAlex Bennée                 .handler = handle_insert_bp,
2474842b42dfSAlex Bennée                 .cmd = "Z",
2475842b42dfSAlex Bennée                 .cmd_startswith = 1,
2476842b42dfSAlex Bennée                 .schema = "l?L?L0"
2477842b42dfSAlex Bennée             };
2478842b42dfSAlex Bennée             cmd_parser = &insert_bp_cmd_desc;
2479842b42dfSAlex Bennée         }
2480842b42dfSAlex Bennée         break;
2481842b42dfSAlex Bennée     case 'z':
2482842b42dfSAlex Bennée         {
2483842b42dfSAlex Bennée             static const GdbCmdParseEntry remove_bp_cmd_desc = {
2484842b42dfSAlex Bennée                 .handler = handle_remove_bp,
2485842b42dfSAlex Bennée                 .cmd = "z",
2486842b42dfSAlex Bennée                 .cmd_startswith = 1,
2487842b42dfSAlex Bennée                 .schema = "l?L?L0"
2488842b42dfSAlex Bennée             };
2489842b42dfSAlex Bennée             cmd_parser = &remove_bp_cmd_desc;
2490842b42dfSAlex Bennée         }
2491842b42dfSAlex Bennée         break;
2492842b42dfSAlex Bennée     case 'H':
2493842b42dfSAlex Bennée         {
2494842b42dfSAlex Bennée             static const GdbCmdParseEntry set_thread_cmd_desc = {
2495842b42dfSAlex Bennée                 .handler = handle_set_thread,
2496842b42dfSAlex Bennée                 .cmd = "H",
2497842b42dfSAlex Bennée                 .cmd_startswith = 1,
2498842b42dfSAlex Bennée                 .schema = "o.t0"
2499842b42dfSAlex Bennée             };
2500842b42dfSAlex Bennée             cmd_parser = &set_thread_cmd_desc;
2501842b42dfSAlex Bennée         }
2502842b42dfSAlex Bennée         break;
2503842b42dfSAlex Bennée     case 'T':
2504842b42dfSAlex Bennée         {
2505842b42dfSAlex Bennée             static const GdbCmdParseEntry thread_alive_cmd_desc = {
2506842b42dfSAlex Bennée                 .handler = handle_thread_alive,
2507842b42dfSAlex Bennée                 .cmd = "T",
2508842b42dfSAlex Bennée                 .cmd_startswith = 1,
2509842b42dfSAlex Bennée                 .schema = "t0"
2510842b42dfSAlex Bennée             };
2511842b42dfSAlex Bennée             cmd_parser = &thread_alive_cmd_desc;
2512842b42dfSAlex Bennée         }
2513842b42dfSAlex Bennée         break;
2514842b42dfSAlex Bennée     case 'q':
2515842b42dfSAlex Bennée         {
2516842b42dfSAlex Bennée             static const GdbCmdParseEntry gen_query_cmd_desc = {
2517842b42dfSAlex Bennée                 .handler = handle_gen_query,
2518842b42dfSAlex Bennée                 .cmd = "q",
2519842b42dfSAlex Bennée                 .cmd_startswith = 1,
2520842b42dfSAlex Bennée                 .schema = "s0"
2521842b42dfSAlex Bennée             };
2522842b42dfSAlex Bennée             cmd_parser = &gen_query_cmd_desc;
2523842b42dfSAlex Bennée         }
2524842b42dfSAlex Bennée         break;
2525842b42dfSAlex Bennée     case 'Q':
2526842b42dfSAlex Bennée         {
2527842b42dfSAlex Bennée             static const GdbCmdParseEntry gen_set_cmd_desc = {
2528842b42dfSAlex Bennée                 .handler = handle_gen_set,
2529842b42dfSAlex Bennée                 .cmd = "Q",
2530842b42dfSAlex Bennée                 .cmd_startswith = 1,
2531842b42dfSAlex Bennée                 .schema = "s0"
2532842b42dfSAlex Bennée             };
2533842b42dfSAlex Bennée             cmd_parser = &gen_set_cmd_desc;
2534842b42dfSAlex Bennée         }
2535842b42dfSAlex Bennée         break;
2536842b42dfSAlex Bennée     default:
2537842b42dfSAlex Bennée         /* put empty packet */
253836e067b2SAlex Bennée         gdb_put_packet("");
2539842b42dfSAlex Bennée         break;
2540842b42dfSAlex Bennée     }
2541842b42dfSAlex Bennée 
2542842b42dfSAlex Bennée     if (cmd_parser) {
2543842b42dfSAlex Bennée         run_cmd_parser(line_buf, cmd_parser);
2544842b42dfSAlex Bennée     }
2545842b42dfSAlex Bennée 
2546842b42dfSAlex Bennée     return RS_IDLE;
2547842b42dfSAlex Bennée }
2548842b42dfSAlex Bennée 
2549842b42dfSAlex Bennée void gdb_set_stop_cpu(CPUState *cpu)
2550842b42dfSAlex Bennée {
2551842b42dfSAlex Bennée     GDBProcess *p = gdb_get_cpu_process(cpu);
2552842b42dfSAlex Bennée 
2553842b42dfSAlex Bennée     if (!p->attached) {
2554842b42dfSAlex Bennée         /*
2555842b42dfSAlex Bennée          * Having a stop CPU corresponding to a process that is not attached
2556842b42dfSAlex Bennée          * confuses GDB. So we ignore the request.
2557842b42dfSAlex Bennée          */
2558842b42dfSAlex Bennée         return;
2559842b42dfSAlex Bennée     }
2560842b42dfSAlex Bennée 
2561842b42dfSAlex Bennée     gdbserver_state.c_cpu = cpu;
2562842b42dfSAlex Bennée     gdbserver_state.g_cpu = cpu;
2563842b42dfSAlex Bennée }
2564842b42dfSAlex Bennée 
2565842b42dfSAlex Bennée /* Send a gdb syscall request.
2566842b42dfSAlex Bennée    This accepts limited printf-style format specifiers, specifically:
2567842b42dfSAlex Bennée     %x  - target_ulong argument printed in hex.
2568842b42dfSAlex Bennée     %lx - 64-bit argument printed in hex.
2569842b42dfSAlex Bennée     %s  - string pointer (target_ulong) and length (int) pair.  */
2570842b42dfSAlex Bennée void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
2571842b42dfSAlex Bennée {
2572842b42dfSAlex Bennée     char *p;
2573842b42dfSAlex Bennée     char *p_end;
2574842b42dfSAlex Bennée     target_ulong addr;
2575842b42dfSAlex Bennée     uint64_t i64;
2576842b42dfSAlex Bennée 
2577842b42dfSAlex Bennée     if (!gdb_attached()) {
2578842b42dfSAlex Bennée         return;
2579842b42dfSAlex Bennée     }
2580842b42dfSAlex Bennée 
2581842b42dfSAlex Bennée     gdbserver_state.current_syscall_cb = cb;
2582842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2583842b42dfSAlex Bennée     vm_stop(RUN_STATE_DEBUG);
2584842b42dfSAlex Bennée #endif
2585842b42dfSAlex Bennée     p = &gdbserver_state.syscall_buf[0];
2586842b42dfSAlex Bennée     p_end = &gdbserver_state.syscall_buf[sizeof(gdbserver_state.syscall_buf)];
2587842b42dfSAlex Bennée     *(p++) = 'F';
2588842b42dfSAlex Bennée     while (*fmt) {
2589842b42dfSAlex Bennée         if (*fmt == '%') {
2590842b42dfSAlex Bennée             fmt++;
2591842b42dfSAlex Bennée             switch (*fmt++) {
2592842b42dfSAlex Bennée             case 'x':
2593842b42dfSAlex Bennée                 addr = va_arg(va, target_ulong);
2594842b42dfSAlex Bennée                 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr);
2595842b42dfSAlex Bennée                 break;
2596842b42dfSAlex Bennée             case 'l':
2597842b42dfSAlex Bennée                 if (*(fmt++) != 'x')
2598842b42dfSAlex Bennée                     goto bad_format;
2599842b42dfSAlex Bennée                 i64 = va_arg(va, uint64_t);
2600842b42dfSAlex Bennée                 p += snprintf(p, p_end - p, "%" PRIx64, i64);
2601842b42dfSAlex Bennée                 break;
2602842b42dfSAlex Bennée             case 's':
2603842b42dfSAlex Bennée                 addr = va_arg(va, target_ulong);
2604842b42dfSAlex Bennée                 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x",
2605842b42dfSAlex Bennée                               addr, va_arg(va, int));
2606842b42dfSAlex Bennée                 break;
2607842b42dfSAlex Bennée             default:
2608842b42dfSAlex Bennée             bad_format:
2609842b42dfSAlex Bennée                 error_report("gdbstub: Bad syscall format string '%s'",
2610842b42dfSAlex Bennée                              fmt - 1);
2611842b42dfSAlex Bennée                 break;
2612842b42dfSAlex Bennée             }
2613842b42dfSAlex Bennée         } else {
2614842b42dfSAlex Bennée             *(p++) = *(fmt++);
2615842b42dfSAlex Bennée         }
2616842b42dfSAlex Bennée     }
2617842b42dfSAlex Bennée     *p = 0;
2618842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
261936e067b2SAlex Bennée     gdb_put_packet(gdbserver_state.syscall_buf);
2620842b42dfSAlex Bennée     /* Return control to gdb for it to process the syscall request.
2621842b42dfSAlex Bennée      * Since the protocol requires that gdb hands control back to us
2622842b42dfSAlex Bennée      * using a "here are the results" F packet, we don't need to check
2623842b42dfSAlex Bennée      * gdb_handlesig's return value (which is the signal to deliver if
2624842b42dfSAlex Bennée      * execution was resumed via a continue packet).
2625842b42dfSAlex Bennée      */
2626842b42dfSAlex Bennée     gdb_handlesig(gdbserver_state.c_cpu, 0);
2627842b42dfSAlex Bennée #else
2628842b42dfSAlex Bennée     /* In this case wait to send the syscall packet until notification that
2629842b42dfSAlex Bennée        the CPU has stopped.  This must be done because if the packet is sent
2630842b42dfSAlex Bennée        now the reply from the syscall request could be received while the CPU
2631842b42dfSAlex Bennée        is still in the running state, which can cause packets to be dropped
2632842b42dfSAlex Bennée        and state transition 'T' packets to be sent while the syscall is still
2633842b42dfSAlex Bennée        being processed.  */
2634842b42dfSAlex Bennée     qemu_cpu_kick(gdbserver_state.c_cpu);
2635842b42dfSAlex Bennée #endif
2636842b42dfSAlex Bennée }
2637842b42dfSAlex Bennée 
2638842b42dfSAlex Bennée void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
2639842b42dfSAlex Bennée {
2640842b42dfSAlex Bennée     va_list va;
2641842b42dfSAlex Bennée 
2642842b42dfSAlex Bennée     va_start(va, fmt);
2643842b42dfSAlex Bennée     gdb_do_syscallv(cb, fmt, va);
2644842b42dfSAlex Bennée     va_end(va);
2645842b42dfSAlex Bennée }
2646842b42dfSAlex Bennée 
264736e067b2SAlex Bennée void gdb_read_byte(uint8_t ch)
2648842b42dfSAlex Bennée {
2649842b42dfSAlex Bennée     uint8_t reply;
2650842b42dfSAlex Bennée 
2651842b42dfSAlex Bennée #ifndef CONFIG_USER_ONLY
2652842b42dfSAlex Bennée     if (gdbserver_state.last_packet->len) {
2653842b42dfSAlex Bennée         /* Waiting for a response to the last packet.  If we see the start
2654842b42dfSAlex Bennée            of a new command then abandon the previous response.  */
2655842b42dfSAlex Bennée         if (ch == '-') {
2656842b42dfSAlex Bennée             trace_gdbstub_err_got_nack();
265736e067b2SAlex Bennée             gdb_put_buffer(gdbserver_state.last_packet->data,
2658842b42dfSAlex Bennée                        gdbserver_state.last_packet->len);
2659842b42dfSAlex Bennée         } else if (ch == '+') {
2660842b42dfSAlex Bennée             trace_gdbstub_io_got_ack();
2661842b42dfSAlex Bennée         } else {
2662842b42dfSAlex Bennée             trace_gdbstub_io_got_unexpected(ch);
2663842b42dfSAlex Bennée         }
2664842b42dfSAlex Bennée 
2665842b42dfSAlex Bennée         if (ch == '+' || ch == '$') {
2666842b42dfSAlex Bennée             g_byte_array_set_size(gdbserver_state.last_packet, 0);
2667842b42dfSAlex Bennée         }
2668842b42dfSAlex Bennée         if (ch != '$')
2669842b42dfSAlex Bennée             return;
2670842b42dfSAlex Bennée     }
2671842b42dfSAlex Bennée     if (runstate_is_running()) {
2672842b42dfSAlex Bennée         /* when the CPU is running, we cannot do anything except stop
2673842b42dfSAlex Bennée            it when receiving a char */
2674842b42dfSAlex Bennée         vm_stop(RUN_STATE_PAUSED);
2675842b42dfSAlex Bennée     } else
2676842b42dfSAlex Bennée #endif
2677842b42dfSAlex Bennée     {
2678842b42dfSAlex Bennée         switch(gdbserver_state.state) {
2679842b42dfSAlex Bennée         case RS_IDLE:
2680842b42dfSAlex Bennée             if (ch == '$') {
2681842b42dfSAlex Bennée                 /* start of command packet */
2682842b42dfSAlex Bennée                 gdbserver_state.line_buf_index = 0;
2683842b42dfSAlex Bennée                 gdbserver_state.line_sum = 0;
2684842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2685842b42dfSAlex Bennée             } else {
2686842b42dfSAlex Bennée                 trace_gdbstub_err_garbage(ch);
2687842b42dfSAlex Bennée             }
2688842b42dfSAlex Bennée             break;
2689842b42dfSAlex Bennée         case RS_GETLINE:
2690842b42dfSAlex Bennée             if (ch == '}') {
2691842b42dfSAlex Bennée                 /* start escape sequence */
2692842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE_ESC;
2693842b42dfSAlex Bennée                 gdbserver_state.line_sum += ch;
2694842b42dfSAlex Bennée             } else if (ch == '*') {
2695842b42dfSAlex Bennée                 /* start run length encoding sequence */
2696842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE_RLE;
2697842b42dfSAlex Bennée                 gdbserver_state.line_sum += ch;
2698842b42dfSAlex Bennée             } else if (ch == '#') {
2699842b42dfSAlex Bennée                 /* end of command, start of checksum*/
2700842b42dfSAlex Bennée                 gdbserver_state.state = RS_CHKSUM1;
2701842b42dfSAlex Bennée             } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
2702842b42dfSAlex Bennée                 trace_gdbstub_err_overrun();
2703842b42dfSAlex Bennée                 gdbserver_state.state = RS_IDLE;
2704842b42dfSAlex Bennée             } else {
2705842b42dfSAlex Bennée                 /* unescaped command character */
2706842b42dfSAlex Bennée                 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch;
2707842b42dfSAlex Bennée                 gdbserver_state.line_sum += ch;
2708842b42dfSAlex Bennée             }
2709842b42dfSAlex Bennée             break;
2710842b42dfSAlex Bennée         case RS_GETLINE_ESC:
2711842b42dfSAlex Bennée             if (ch == '#') {
2712842b42dfSAlex Bennée                 /* unexpected end of command in escape sequence */
2713842b42dfSAlex Bennée                 gdbserver_state.state = RS_CHKSUM1;
2714842b42dfSAlex Bennée             } else if (gdbserver_state.line_buf_index >= sizeof(gdbserver_state.line_buf) - 1) {
2715842b42dfSAlex Bennée                 /* command buffer overrun */
2716842b42dfSAlex Bennée                 trace_gdbstub_err_overrun();
2717842b42dfSAlex Bennée                 gdbserver_state.state = RS_IDLE;
2718842b42dfSAlex Bennée             } else {
2719842b42dfSAlex Bennée                 /* parse escaped character and leave escape state */
2720842b42dfSAlex Bennée                 gdbserver_state.line_buf[gdbserver_state.line_buf_index++] = ch ^ 0x20;
2721842b42dfSAlex Bennée                 gdbserver_state.line_sum += ch;
2722842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2723842b42dfSAlex Bennée             }
2724842b42dfSAlex Bennée             break;
2725842b42dfSAlex Bennée         case RS_GETLINE_RLE:
2726842b42dfSAlex Bennée             /*
2727842b42dfSAlex Bennée              * Run-length encoding is explained in "Debugging with GDB /
2728842b42dfSAlex Bennée              * Appendix E GDB Remote Serial Protocol / Overview".
2729842b42dfSAlex Bennée              */
2730842b42dfSAlex Bennée             if (ch < ' ' || ch == '#' || ch == '$' || ch > 126) {
2731842b42dfSAlex Bennée                 /* invalid RLE count encoding */
2732842b42dfSAlex Bennée                 trace_gdbstub_err_invalid_repeat(ch);
2733842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2734842b42dfSAlex Bennée             } else {
2735842b42dfSAlex Bennée                 /* decode repeat length */
2736842b42dfSAlex Bennée                 int repeat = ch - ' ' + 3;
2737842b42dfSAlex Bennée                 if (gdbserver_state.line_buf_index + repeat >= sizeof(gdbserver_state.line_buf) - 1) {
2738842b42dfSAlex Bennée                     /* that many repeats would overrun the command buffer */
2739842b42dfSAlex Bennée                     trace_gdbstub_err_overrun();
2740842b42dfSAlex Bennée                     gdbserver_state.state = RS_IDLE;
2741842b42dfSAlex Bennée                 } else if (gdbserver_state.line_buf_index < 1) {
2742842b42dfSAlex Bennée                     /* got a repeat but we have nothing to repeat */
2743842b42dfSAlex Bennée                     trace_gdbstub_err_invalid_rle();
2744842b42dfSAlex Bennée                     gdbserver_state.state = RS_GETLINE;
2745842b42dfSAlex Bennée                 } else {
2746842b42dfSAlex Bennée                     /* repeat the last character */
2747842b42dfSAlex Bennée                     memset(gdbserver_state.line_buf + gdbserver_state.line_buf_index,
2748842b42dfSAlex Bennée                            gdbserver_state.line_buf[gdbserver_state.line_buf_index - 1], repeat);
2749842b42dfSAlex Bennée                     gdbserver_state.line_buf_index += repeat;
2750842b42dfSAlex Bennée                     gdbserver_state.line_sum += ch;
2751842b42dfSAlex Bennée                     gdbserver_state.state = RS_GETLINE;
2752842b42dfSAlex Bennée                 }
2753842b42dfSAlex Bennée             }
2754842b42dfSAlex Bennée             break;
2755842b42dfSAlex Bennée         case RS_CHKSUM1:
2756842b42dfSAlex Bennée             /* get high hex digit of checksum */
2757842b42dfSAlex Bennée             if (!isxdigit(ch)) {
2758842b42dfSAlex Bennée                 trace_gdbstub_err_checksum_invalid(ch);
2759842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2760842b42dfSAlex Bennée                 break;
2761842b42dfSAlex Bennée             }
2762842b42dfSAlex Bennée             gdbserver_state.line_buf[gdbserver_state.line_buf_index] = '\0';
2763842b42dfSAlex Bennée             gdbserver_state.line_csum = fromhex(ch) << 4;
2764842b42dfSAlex Bennée             gdbserver_state.state = RS_CHKSUM2;
2765842b42dfSAlex Bennée             break;
2766842b42dfSAlex Bennée         case RS_CHKSUM2:
2767842b42dfSAlex Bennée             /* get low hex digit of checksum */
2768842b42dfSAlex Bennée             if (!isxdigit(ch)) {
2769842b42dfSAlex Bennée                 trace_gdbstub_err_checksum_invalid(ch);
2770842b42dfSAlex Bennée                 gdbserver_state.state = RS_GETLINE;
2771842b42dfSAlex Bennée                 break;
2772842b42dfSAlex Bennée             }
2773842b42dfSAlex Bennée             gdbserver_state.line_csum |= fromhex(ch);
2774842b42dfSAlex Bennée 
2775842b42dfSAlex Bennée             if (gdbserver_state.line_csum != (gdbserver_state.line_sum & 0xff)) {
2776842b42dfSAlex Bennée                 trace_gdbstub_err_checksum_incorrect(gdbserver_state.line_sum, gdbserver_state.line_csum);
2777842b42dfSAlex Bennée                 /* send NAK reply */
2778842b42dfSAlex Bennée                 reply = '-';
277936e067b2SAlex Bennée                 gdb_put_buffer(&reply, 1);
2780842b42dfSAlex Bennée                 gdbserver_state.state = RS_IDLE;
2781842b42dfSAlex Bennée             } else {
2782842b42dfSAlex Bennée                 /* send ACK reply */
2783842b42dfSAlex Bennée                 reply = '+';
278436e067b2SAlex Bennée                 gdb_put_buffer(&reply, 1);
2785842b42dfSAlex Bennée                 gdbserver_state.state = gdb_handle_packet(gdbserver_state.line_buf);
2786842b42dfSAlex Bennée             }
2787842b42dfSAlex Bennée             break;
2788842b42dfSAlex Bennée         default:
2789842b42dfSAlex Bennée             abort();
2790842b42dfSAlex Bennée         }
2791842b42dfSAlex Bennée     }
2792842b42dfSAlex Bennée }
2793842b42dfSAlex Bennée 
2794b6fa2ec2SAlex Bennée #ifdef CONFIG_USER_ONLY
2795842b42dfSAlex Bennée /* Tell the remote gdb that the process has exited.  */
2796842b42dfSAlex Bennée void gdb_exit(int code)
2797842b42dfSAlex Bennée {
2798842b42dfSAlex Bennée     char buf[4];
2799842b42dfSAlex Bennée 
2800842b42dfSAlex Bennée     if (!gdbserver_state.init) {
2801842b42dfSAlex Bennée         return;
2802842b42dfSAlex Bennée     }
28038e70c6f9SAlex Bennée     if (gdbserver_user_state.socket_path) {
28048e70c6f9SAlex Bennée         unlink(gdbserver_user_state.socket_path);
2805842b42dfSAlex Bennée     }
28068e70c6f9SAlex Bennée     if (gdbserver_user_state.fd < 0) {
2807842b42dfSAlex Bennée         return;
2808842b42dfSAlex Bennée     }
2809842b42dfSAlex Bennée 
2810842b42dfSAlex Bennée     trace_gdbstub_op_exiting((uint8_t)code);
2811842b42dfSAlex Bennée 
2812842b42dfSAlex Bennée     snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
281336e067b2SAlex Bennée     gdb_put_packet(buf);
2814842b42dfSAlex Bennée }
2815b6fa2ec2SAlex Bennée #endif
2816842b42dfSAlex Bennée 
2817842b42dfSAlex Bennée /*
2818842b42dfSAlex Bennée  * Create the process that will contain all the "orphan" CPUs (that are not
2819842b42dfSAlex Bennée  * part of a CPU cluster). Note that if this process contains no CPUs, it won't
2820842b42dfSAlex Bennée  * be attachable and thus will be invisible to the user.
2821842b42dfSAlex Bennée  */
282236e067b2SAlex Bennée void gdb_create_default_process(GDBState *s)
2823842b42dfSAlex Bennée {
2824842b42dfSAlex Bennée     GDBProcess *process;
2825842b42dfSAlex Bennée     int max_pid = 0;
2826842b42dfSAlex Bennée 
2827842b42dfSAlex Bennée     if (gdbserver_state.process_num) {
2828842b42dfSAlex Bennée         max_pid = s->processes[s->process_num - 1].pid;
2829842b42dfSAlex Bennée     }
2830842b42dfSAlex Bennée 
2831842b42dfSAlex Bennée     s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
2832842b42dfSAlex Bennée     process = &s->processes[s->process_num - 1];
2833842b42dfSAlex Bennée 
2834842b42dfSAlex Bennée     /* We need an available PID slot for this process */
2835842b42dfSAlex Bennée     assert(max_pid < UINT32_MAX);
2836842b42dfSAlex Bennée 
2837842b42dfSAlex Bennée     process->pid = max_pid + 1;
2838842b42dfSAlex Bennée     process->attached = false;
2839842b42dfSAlex Bennée     process->target_xml[0] = '\0';
2840842b42dfSAlex Bennée }
2841842b42dfSAlex Bennée 
2842842b42dfSAlex Bennée #ifdef CONFIG_USER_ONLY
2843842b42dfSAlex Bennée int
2844842b42dfSAlex Bennée gdb_handlesig(CPUState *cpu, int sig)
2845842b42dfSAlex Bennée {
2846842b42dfSAlex Bennée     char buf[256];
2847842b42dfSAlex Bennée     int n;
2848842b42dfSAlex Bennée 
28498e70c6f9SAlex Bennée     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
2850842b42dfSAlex Bennée         return sig;
2851842b42dfSAlex Bennée     }
2852842b42dfSAlex Bennée 
2853842b42dfSAlex Bennée     /* disable single step if it was enabled */
2854842b42dfSAlex Bennée     cpu_single_step(cpu, 0);
2855842b42dfSAlex Bennée     tb_flush(cpu);
2856842b42dfSAlex Bennée 
2857842b42dfSAlex Bennée     if (sig != 0) {
2858842b42dfSAlex Bennée         gdb_set_stop_cpu(cpu);
2859842b42dfSAlex Bennée         g_string_printf(gdbserver_state.str_buf,
2860842b42dfSAlex Bennée                         "T%02xthread:", target_signal_to_gdb(sig));
2861842b42dfSAlex Bennée         gdb_append_thread_id(cpu, gdbserver_state.str_buf);
2862842b42dfSAlex Bennée         g_string_append_c(gdbserver_state.str_buf, ';');
286336e067b2SAlex Bennée         gdb_put_strbuf();
2864842b42dfSAlex Bennée     }
286536e067b2SAlex Bennée     /*
286636e067b2SAlex Bennée      * gdb_put_packet() might have detected that the peer terminated the
286736e067b2SAlex Bennée      * connection.
286836e067b2SAlex Bennée      */
28698e70c6f9SAlex Bennée     if (gdbserver_user_state.fd < 0) {
2870842b42dfSAlex Bennée         return sig;
2871842b42dfSAlex Bennée     }
2872842b42dfSAlex Bennée 
2873842b42dfSAlex Bennée     sig = 0;
2874842b42dfSAlex Bennée     gdbserver_state.state = RS_IDLE;
28758e70c6f9SAlex Bennée     gdbserver_user_state.running_state = 0;
28768e70c6f9SAlex Bennée     while (gdbserver_user_state.running_state == 0) {
28778e70c6f9SAlex Bennée         n = read(gdbserver_user_state.fd, buf, 256);
2878842b42dfSAlex Bennée         if (n > 0) {
2879842b42dfSAlex Bennée             int i;
2880842b42dfSAlex Bennée 
2881842b42dfSAlex Bennée             for (i = 0; i < n; i++) {
2882842b42dfSAlex Bennée                 gdb_read_byte(buf[i]);
2883842b42dfSAlex Bennée             }
2884842b42dfSAlex Bennée         } else {
2885842b42dfSAlex Bennée             /* XXX: Connection closed.  Should probably wait for another
2886842b42dfSAlex Bennée                connection before continuing.  */
2887842b42dfSAlex Bennée             if (n == 0) {
28888e70c6f9SAlex Bennée                 close(gdbserver_user_state.fd);
2889842b42dfSAlex Bennée             }
28908e70c6f9SAlex Bennée             gdbserver_user_state.fd = -1;
2891842b42dfSAlex Bennée             return sig;
2892842b42dfSAlex Bennée         }
2893842b42dfSAlex Bennée     }
2894842b42dfSAlex Bennée     sig = gdbserver_state.signal;
2895842b42dfSAlex Bennée     gdbserver_state.signal = 0;
2896842b42dfSAlex Bennée     return sig;
2897842b42dfSAlex Bennée }
2898842b42dfSAlex Bennée 
2899842b42dfSAlex Bennée /* Tell the remote gdb that the process has exited due to SIG.  */
2900842b42dfSAlex Bennée void gdb_signalled(CPUArchState *env, int sig)
2901842b42dfSAlex Bennée {
2902842b42dfSAlex Bennée     char buf[4];
2903842b42dfSAlex Bennée 
29048e70c6f9SAlex Bennée     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
2905842b42dfSAlex Bennée         return;
2906842b42dfSAlex Bennée     }
2907842b42dfSAlex Bennée 
2908842b42dfSAlex Bennée     snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
290936e067b2SAlex Bennée     gdb_put_packet(buf);
2910842b42dfSAlex Bennée }
2911842b42dfSAlex Bennée 
2912842b42dfSAlex Bennée static void gdb_accept_init(int fd)
2913842b42dfSAlex Bennée {
291436e067b2SAlex Bennée     gdb_init_gdbserver_state();
291536e067b2SAlex Bennée     gdb_create_default_process(&gdbserver_state);
2916842b42dfSAlex Bennée     gdbserver_state.processes[0].attached = true;
2917842b42dfSAlex Bennée     gdbserver_state.c_cpu = gdb_first_attached_cpu();
2918842b42dfSAlex Bennée     gdbserver_state.g_cpu = gdbserver_state.c_cpu;
29198e70c6f9SAlex Bennée     gdbserver_user_state.fd = fd;
2920842b42dfSAlex Bennée     gdb_has_xml = false;
2921842b42dfSAlex Bennée }
2922842b42dfSAlex Bennée 
2923842b42dfSAlex Bennée static bool gdb_accept_socket(int gdb_fd)
2924842b42dfSAlex Bennée {
2925842b42dfSAlex Bennée     int fd;
2926842b42dfSAlex Bennée 
2927842b42dfSAlex Bennée     for(;;) {
2928842b42dfSAlex Bennée         fd = accept(gdb_fd, NULL, NULL);
2929842b42dfSAlex Bennée         if (fd < 0 && errno != EINTR) {
2930842b42dfSAlex Bennée             perror("accept socket");
2931842b42dfSAlex Bennée             return false;
2932842b42dfSAlex Bennée         } else if (fd >= 0) {
2933842b42dfSAlex Bennée             qemu_set_cloexec(fd);
2934842b42dfSAlex Bennée             break;
2935842b42dfSAlex Bennée         }
2936842b42dfSAlex Bennée     }
2937842b42dfSAlex Bennée 
2938842b42dfSAlex Bennée     gdb_accept_init(fd);
2939842b42dfSAlex Bennée     return true;
2940842b42dfSAlex Bennée }
2941842b42dfSAlex Bennée 
2942842b42dfSAlex Bennée static int gdbserver_open_socket(const char *path)
2943842b42dfSAlex Bennée {
2944842b42dfSAlex Bennée     struct sockaddr_un sockaddr = {};
2945842b42dfSAlex Bennée     int fd, ret;
2946842b42dfSAlex Bennée 
2947842b42dfSAlex Bennée     fd = socket(AF_UNIX, SOCK_STREAM, 0);
2948842b42dfSAlex Bennée     if (fd < 0) {
2949842b42dfSAlex Bennée         perror("create socket");
2950842b42dfSAlex Bennée         return -1;
2951842b42dfSAlex Bennée     }
2952842b42dfSAlex Bennée 
2953842b42dfSAlex Bennée     sockaddr.sun_family = AF_UNIX;
2954842b42dfSAlex Bennée     pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
2955842b42dfSAlex Bennée     ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
2956842b42dfSAlex Bennée     if (ret < 0) {
2957842b42dfSAlex Bennée         perror("bind socket");
2958842b42dfSAlex Bennée         close(fd);
2959842b42dfSAlex Bennée         return -1;
2960842b42dfSAlex Bennée     }
2961842b42dfSAlex Bennée     ret = listen(fd, 1);
2962842b42dfSAlex Bennée     if (ret < 0) {
2963842b42dfSAlex Bennée         perror("listen socket");
2964842b42dfSAlex Bennée         close(fd);
2965842b42dfSAlex Bennée         return -1;
2966842b42dfSAlex Bennée     }
2967842b42dfSAlex Bennée 
2968842b42dfSAlex Bennée     return fd;
2969842b42dfSAlex Bennée }
2970842b42dfSAlex Bennée 
2971842b42dfSAlex Bennée static bool gdb_accept_tcp(int gdb_fd)
2972842b42dfSAlex Bennée {
2973842b42dfSAlex Bennée     struct sockaddr_in sockaddr = {};
2974842b42dfSAlex Bennée     socklen_t len;
2975842b42dfSAlex Bennée     int fd;
2976842b42dfSAlex Bennée 
2977842b42dfSAlex Bennée     for(;;) {
2978842b42dfSAlex Bennée         len = sizeof(sockaddr);
2979842b42dfSAlex Bennée         fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
2980842b42dfSAlex Bennée         if (fd < 0 && errno != EINTR) {
2981842b42dfSAlex Bennée             perror("accept");
2982842b42dfSAlex Bennée             return false;
2983842b42dfSAlex Bennée         } else if (fd >= 0) {
2984842b42dfSAlex Bennée             qemu_set_cloexec(fd);
2985842b42dfSAlex Bennée             break;
2986842b42dfSAlex Bennée         }
2987842b42dfSAlex Bennée     }
2988842b42dfSAlex Bennée 
2989842b42dfSAlex Bennée     /* set short latency */
2990842b42dfSAlex Bennée     if (socket_set_nodelay(fd)) {
2991842b42dfSAlex Bennée         perror("setsockopt");
2992842b42dfSAlex Bennée         close(fd);
2993842b42dfSAlex Bennée         return false;
2994842b42dfSAlex Bennée     }
2995842b42dfSAlex Bennée 
2996842b42dfSAlex Bennée     gdb_accept_init(fd);
2997842b42dfSAlex Bennée     return true;
2998842b42dfSAlex Bennée }
2999842b42dfSAlex Bennée 
3000842b42dfSAlex Bennée static int gdbserver_open_port(int port)
3001842b42dfSAlex Bennée {
3002842b42dfSAlex Bennée     struct sockaddr_in sockaddr;
3003842b42dfSAlex Bennée     int fd, ret;
3004842b42dfSAlex Bennée 
3005842b42dfSAlex Bennée     fd = socket(PF_INET, SOCK_STREAM, 0);
3006842b42dfSAlex Bennée     if (fd < 0) {
3007842b42dfSAlex Bennée         perror("socket");
3008842b42dfSAlex Bennée         return -1;
3009842b42dfSAlex Bennée     }
3010842b42dfSAlex Bennée     qemu_set_cloexec(fd);
3011842b42dfSAlex Bennée 
3012842b42dfSAlex Bennée     socket_set_fast_reuse(fd);
3013842b42dfSAlex Bennée 
3014842b42dfSAlex Bennée     sockaddr.sin_family = AF_INET;
3015842b42dfSAlex Bennée     sockaddr.sin_port = htons(port);
3016842b42dfSAlex Bennée     sockaddr.sin_addr.s_addr = 0;
3017842b42dfSAlex Bennée     ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
3018842b42dfSAlex Bennée     if (ret < 0) {
3019842b42dfSAlex Bennée         perror("bind");
3020842b42dfSAlex Bennée         close(fd);
3021842b42dfSAlex Bennée         return -1;
3022842b42dfSAlex Bennée     }
3023842b42dfSAlex Bennée     ret = listen(fd, 1);
3024842b42dfSAlex Bennée     if (ret < 0) {
3025842b42dfSAlex Bennée         perror("listen");
3026842b42dfSAlex Bennée         close(fd);
3027842b42dfSAlex Bennée         return -1;
3028842b42dfSAlex Bennée     }
3029842b42dfSAlex Bennée 
3030842b42dfSAlex Bennée     return fd;
3031842b42dfSAlex Bennée }
3032842b42dfSAlex Bennée 
3033842b42dfSAlex Bennée int gdbserver_start(const char *port_or_path)
3034842b42dfSAlex Bennée {
3035842b42dfSAlex Bennée     int port = g_ascii_strtoull(port_or_path, NULL, 10);
3036842b42dfSAlex Bennée     int gdb_fd;
3037842b42dfSAlex Bennée 
3038842b42dfSAlex Bennée     if (port > 0) {
3039842b42dfSAlex Bennée         gdb_fd = gdbserver_open_port(port);
3040842b42dfSAlex Bennée     } else {
3041842b42dfSAlex Bennée         gdb_fd = gdbserver_open_socket(port_or_path);
3042842b42dfSAlex Bennée     }
3043842b42dfSAlex Bennée 
3044842b42dfSAlex Bennée     if (gdb_fd < 0) {
3045842b42dfSAlex Bennée         return -1;
3046842b42dfSAlex Bennée     }
3047842b42dfSAlex Bennée 
3048842b42dfSAlex Bennée     if (port > 0 && gdb_accept_tcp(gdb_fd)) {
3049842b42dfSAlex Bennée         return 0;
3050842b42dfSAlex Bennée     } else if (gdb_accept_socket(gdb_fd)) {
30518e70c6f9SAlex Bennée         gdbserver_user_state.socket_path = g_strdup(port_or_path);
3052842b42dfSAlex Bennée         return 0;
3053842b42dfSAlex Bennée     }
3054842b42dfSAlex Bennée 
3055842b42dfSAlex Bennée     /* gone wrong */
3056842b42dfSAlex Bennée     close(gdb_fd);
3057842b42dfSAlex Bennée     return -1;
3058842b42dfSAlex Bennée }
3059842b42dfSAlex Bennée 
3060842b42dfSAlex Bennée /* Disable gdb stub for child processes.  */
3061842b42dfSAlex Bennée void gdbserver_fork(CPUState *cpu)
3062842b42dfSAlex Bennée {
30638e70c6f9SAlex Bennée     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
3064842b42dfSAlex Bennée         return;
3065842b42dfSAlex Bennée     }
30668e70c6f9SAlex Bennée     close(gdbserver_user_state.fd);
30678e70c6f9SAlex Bennée     gdbserver_user_state.fd = -1;
3068842b42dfSAlex Bennée     cpu_breakpoint_remove_all(cpu, BP_GDB);
3069842b42dfSAlex Bennée     cpu_watchpoint_remove_all(cpu, BP_GDB);
3070842b42dfSAlex Bennée }
3071842b42dfSAlex Bennée #endif
3072