blob: e10988a62b615507d6e1b3d612d7b51b4ec50eb4 [file] [log] [blame]
Alex Bennéeae7467b2022-09-29 12:42:24 +01001/*
2 * gdbstub user-mode helper routines.
3 *
4 * We know for user-mode we are using TCG so we can call stuff directly.
5 *
Alex Bennée94557622023-03-02 18:57:38 -08006 * Copyright (c) 2003-2005 Fabrice Bellard
Alex Bennéeae7467b2022-09-29 12:42:24 +01007 * Copyright (c) 2022 Linaro Ltd
8 *
Alex Bennée94557622023-03-02 18:57:38 -08009 * SPDX-License-Identifier: LGPL-2.0+
Alex Bennéeae7467b2022-09-29 12:42:24 +010010 */
11
12#include "qemu/osdep.h"
Alex Bennéed96bf492023-03-02 18:57:47 -080013#include "qemu/cutils.h"
14#include "qemu/sockets.h"
15#include "exec/hwaddr.h"
16#include "exec/tb-flush.h"
Alex Bennéeae7467b2022-09-29 12:42:24 +010017#include "exec/gdbstub.h"
Alex Bennéed96bf492023-03-02 18:57:47 -080018#include "gdbstub/user.h"
Alex Bennéeae7467b2022-09-29 12:42:24 +010019#include "hw/core/cpu.h"
Alex Bennéed96bf492023-03-02 18:57:47 -080020#include "trace.h"
Alex Bennéeae7467b2022-09-29 12:42:24 +010021#include "internals.h"
22
Alex Bennéed96bf492023-03-02 18:57:47 -080023/* User-mode specific state */
24typedef struct {
25 int fd;
26 char *socket_path;
27 int running_state;
28} GDBUserState;
29
30static GDBUserState gdbserver_user_state;
31
32int gdb_get_char(void)
33{
34 uint8_t ch;
35 int ret;
36
37 for (;;) {
38 ret = recv(gdbserver_user_state.fd, &ch, 1, 0);
39 if (ret < 0) {
40 if (errno == ECONNRESET) {
41 gdbserver_user_state.fd = -1;
42 }
43 if (errno != EINTR) {
44 return -1;
45 }
46 } else if (ret == 0) {
47 close(gdbserver_user_state.fd);
48 gdbserver_user_state.fd = -1;
49 return -1;
50 } else {
51 break;
52 }
53 }
54 return ch;
55}
56
Alex Bennéea7e0f9b2023-03-02 18:57:49 -080057bool gdb_got_immediate_ack(void)
58{
59 int i;
60
61 i = gdb_get_char();
62 if (i < 0) {
63 /* no response, continue anyway */
64 return true;
65 }
66
67 if (i == '+') {
68 /* received correctly, continue */
69 return true;
70 }
71
72 /* anything else, including '-' then try again */
73 return false;
74}
75
Alex Bennéed96bf492023-03-02 18:57:47 -080076void gdb_put_buffer(const uint8_t *buf, int len)
77{
78 int ret;
79
80 while (len > 0) {
81 ret = send(gdbserver_user_state.fd, buf, len, 0);
82 if (ret < 0) {
83 if (errno != EINTR) {
84 return;
85 }
86 } else {
87 buf += ret;
88 len -= ret;
89 }
90 }
91}
92
93/* Tell the remote gdb that the process has exited. */
94void gdb_exit(int code)
95{
96 char buf[4];
97
98 if (!gdbserver_state.init) {
99 return;
100 }
101 if (gdbserver_user_state.socket_path) {
102 unlink(gdbserver_user_state.socket_path);
103 }
104 if (gdbserver_user_state.fd < 0) {
105 return;
106 }
107
108 trace_gdbstub_op_exiting((uint8_t)code);
109
110 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
111 gdb_put_packet(buf);
112}
113
114int gdb_handlesig(CPUState *cpu, int sig)
115{
116 char buf[256];
117 int n;
118
119 if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
120 return sig;
121 }
122
123 /* disable single step if it was enabled */
124 cpu_single_step(cpu, 0);
125 tb_flush(cpu);
126
127 if (sig != 0) {
128 gdb_set_stop_cpu(cpu);
129 g_string_printf(gdbserver_state.str_buf,
130 "T%02xthread:", gdb_target_signal_to_gdb(sig));
131 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
132 g_string_append_c(gdbserver_state.str_buf, ';');
133 gdb_put_strbuf();
134 }
135 /*
136 * gdb_put_packet() might have detected that the peer terminated the
137 * connection.
138 */
139 if (gdbserver_user_state.fd < 0) {
140 return sig;
141 }
142
143 sig = 0;
144 gdbserver_state.state = RS_IDLE;
145 gdbserver_user_state.running_state = 0;
146 while (gdbserver_user_state.running_state == 0) {
147 n = read(gdbserver_user_state.fd, buf, 256);
148 if (n > 0) {
149 int i;
150
151 for (i = 0; i < n; i++) {
152 gdb_read_byte(buf[i]);
153 }
154 } else {
155 /*
156 * XXX: Connection closed. Should probably wait for another
157 * connection before continuing.
158 */
159 if (n == 0) {
160 close(gdbserver_user_state.fd);
161 }
162 gdbserver_user_state.fd = -1;
163 return sig;
164 }
165 }
166 sig = gdbserver_state.signal;
167 gdbserver_state.signal = 0;
168 return sig;
169}
170
171/* Tell the remote gdb that the process has exited due to SIG. */
172void gdb_signalled(CPUArchState *env, int sig)
173{
174 char buf[4];
175
176 if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
177 return;
178 }
179
180 snprintf(buf, sizeof(buf), "X%02x", gdb_target_signal_to_gdb(sig));
181 gdb_put_packet(buf);
182}
183
184static void gdb_accept_init(int fd)
185{
186 gdb_init_gdbserver_state();
187 gdb_create_default_process(&gdbserver_state);
188 gdbserver_state.processes[0].attached = true;
189 gdbserver_state.c_cpu = gdb_first_attached_cpu();
190 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
191 gdbserver_user_state.fd = fd;
192 gdb_has_xml = false;
193}
194
195static bool gdb_accept_socket(int gdb_fd)
196{
197 int fd;
198
199 for (;;) {
200 fd = accept(gdb_fd, NULL, NULL);
201 if (fd < 0 && errno != EINTR) {
202 perror("accept socket");
203 return false;
204 } else if (fd >= 0) {
205 qemu_set_cloexec(fd);
206 break;
207 }
208 }
209
210 gdb_accept_init(fd);
211 return true;
212}
213
214static int gdbserver_open_socket(const char *path)
215{
216 struct sockaddr_un sockaddr = {};
217 int fd, ret;
218
219 fd = socket(AF_UNIX, SOCK_STREAM, 0);
220 if (fd < 0) {
221 perror("create socket");
222 return -1;
223 }
224
225 sockaddr.sun_family = AF_UNIX;
226 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
227 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
228 if (ret < 0) {
229 perror("bind socket");
230 close(fd);
231 return -1;
232 }
233 ret = listen(fd, 1);
234 if (ret < 0) {
235 perror("listen socket");
236 close(fd);
237 return -1;
238 }
239
240 return fd;
241}
242
243static bool gdb_accept_tcp(int gdb_fd)
244{
245 struct sockaddr_in sockaddr = {};
246 socklen_t len;
247 int fd;
248
249 for (;;) {
250 len = sizeof(sockaddr);
251 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
252 if (fd < 0 && errno != EINTR) {
253 perror("accept");
254 return false;
255 } else if (fd >= 0) {
256 qemu_set_cloexec(fd);
257 break;
258 }
259 }
260
261 /* set short latency */
262 if (socket_set_nodelay(fd)) {
263 perror("setsockopt");
264 close(fd);
265 return false;
266 }
267
268 gdb_accept_init(fd);
269 return true;
270}
271
272static int gdbserver_open_port(int port)
273{
274 struct sockaddr_in sockaddr;
275 int fd, ret;
276
277 fd = socket(PF_INET, SOCK_STREAM, 0);
278 if (fd < 0) {
279 perror("socket");
280 return -1;
281 }
282 qemu_set_cloexec(fd);
283
284 socket_set_fast_reuse(fd);
285
286 sockaddr.sin_family = AF_INET;
287 sockaddr.sin_port = htons(port);
288 sockaddr.sin_addr.s_addr = 0;
289 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
290 if (ret < 0) {
291 perror("bind");
292 close(fd);
293 return -1;
294 }
295 ret = listen(fd, 1);
296 if (ret < 0) {
297 perror("listen");
298 close(fd);
299 return -1;
300 }
301
302 return fd;
303}
304
305int gdbserver_start(const char *port_or_path)
306{
307 int port = g_ascii_strtoull(port_or_path, NULL, 10);
308 int gdb_fd;
309
310 if (port > 0) {
311 gdb_fd = gdbserver_open_port(port);
312 } else {
313 gdb_fd = gdbserver_open_socket(port_or_path);
314 }
315
316 if (gdb_fd < 0) {
317 return -1;
318 }
319
320 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
321 return 0;
322 } else if (gdb_accept_socket(gdb_fd)) {
323 gdbserver_user_state.socket_path = g_strdup(port_or_path);
324 return 0;
325 }
326
327 /* gone wrong */
328 close(gdb_fd);
329 return -1;
330}
331
332/* Disable gdb stub for child processes. */
333void gdbserver_fork(CPUState *cpu)
334{
335 if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
336 return;
337 }
338 close(gdbserver_user_state.fd);
339 gdbserver_user_state.fd = -1;
340 cpu_breakpoint_remove_all(cpu, BP_GDB);
341 /* no cpu_watchpoint_remove_all for user-mode */
342}
343
344/*
345 * Execution state helpers
346 */
347
Alex Bennée8a2025b2023-03-02 18:57:50 -0800348void gdb_handle_query_attached(GArray *params, void *user_ctx)
349{
350 gdb_put_packet("0");
351}
352
Alex Bennéed96bf492023-03-02 18:57:47 -0800353void gdb_continue(void)
354{
355 gdbserver_user_state.running_state = 1;
356 trace_gdbstub_op_continue();
357}
358
359/*
360 * Resume execution, for user-mode emulation it's equivalent to
361 * gdb_continue.
362 */
363int gdb_continue_partial(char *newstates)
364{
365 CPUState *cpu;
366 int res = 0;
367 /*
368 * This is not exactly accurate, but it's an improvement compared to the
369 * previous situation, where only one CPU would be single-stepped.
370 */
371 CPU_FOREACH(cpu) {
372 if (newstates[cpu->cpu_index] == 's') {
373 trace_gdbstub_op_stepping(cpu->cpu_index);
374 cpu_single_step(cpu, gdbserver_state.sstep_flags);
375 }
376 }
377 gdbserver_user_state.running_state = 1;
378 return res;
379}
380
381/*
Alex Bennée589a5862023-03-02 18:57:51 -0800382 * Memory access helpers
383 */
384int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
385 uint8_t *buf, int len, bool is_write)
386{
387 CPUClass *cc;
388
389 cc = CPU_GET_CLASS(cpu);
390 if (cc->memory_rw_debug) {
391 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
392 }
393 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
394}
395
396/*
Alex Bennée7ea0c332023-03-02 18:57:52 -0800397 * cpu helpers
398 */
399
400unsigned int gdb_get_max_cpus(void)
401{
402 CPUState *cpu;
403 unsigned int max_cpus = 1;
404
405 CPU_FOREACH(cpu) {
406 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
407 }
408
409 return max_cpus;
410}
411
412
413/*
Alex Bennéed96bf492023-03-02 18:57:47 -0800414 * Break/Watch point helpers
415 */
416
Alex Bennéea48e7d92022-09-29 12:42:25 +0100417bool gdb_supports_guest_debug(void)
418{
419 /* user-mode == TCG == supported */
420 return true;
421}
422
Philippe Mathieu-Daudé55b5b8e2022-12-06 16:20:27 +0100423int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
Alex Bennéeae7467b2022-09-29 12:42:24 +0100424{
425 CPUState *cpu;
426 int err = 0;
427
428 switch (type) {
429 case GDB_BREAKPOINT_SW:
430 case GDB_BREAKPOINT_HW:
431 CPU_FOREACH(cpu) {
432 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
433 if (err) {
434 break;
435 }
436 }
437 return err;
438 default:
439 /* user-mode doesn't support watchpoints */
440 return -ENOSYS;
441 }
442}
443
Philippe Mathieu-Daudé55b5b8e2022-12-06 16:20:27 +0100444int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len)
Alex Bennéeae7467b2022-09-29 12:42:24 +0100445{
446 CPUState *cpu;
447 int err = 0;
448
449 switch (type) {
450 case GDB_BREAKPOINT_SW:
451 case GDB_BREAKPOINT_HW:
452 CPU_FOREACH(cpu) {
453 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
454 if (err) {
455 break;
456 }
457 }
458 return err;
459 default:
460 /* user-mode doesn't support watchpoints */
461 return -ENOSYS;
462 }
463}
464
465void gdb_breakpoint_remove_all(CPUState *cs)
466{
467 cpu_breakpoint_remove_all(cs, BP_GDB);
468}