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