blob: 2ba01c17faf0f1cb0bd6b2d34c75a6ac82314a86 [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éec5660802023-03-02 18:57:57 -080018#include "gdbstub/syscalls.h"
Alex Bennéed96bf492023-03-02 18:57:47 -080019#include "gdbstub/user.h"
Alex Bennéeae7467b2022-09-29 12:42:24 +010020#include "hw/core/cpu.h"
Alex Bennéed96bf492023-03-02 18:57:47 -080021#include "trace.h"
Alex Bennéeae7467b2022-09-29 12:42:24 +010022#include "internals.h"
23
Alex Bennéed96bf492023-03-02 18:57:47 -080024/* User-mode specific state */
25typedef struct {
26 int fd;
27 char *socket_path;
28 int running_state;
29} GDBUserState;
30
31static GDBUserState gdbserver_user_state;
32
33int gdb_get_char(void)
34{
35 uint8_t ch;
36 int ret;
37
38 for (;;) {
39 ret = recv(gdbserver_user_state.fd, &ch, 1, 0);
40 if (ret < 0) {
41 if (errno == ECONNRESET) {
42 gdbserver_user_state.fd = -1;
43 }
44 if (errno != EINTR) {
45 return -1;
46 }
47 } else if (ret == 0) {
48 close(gdbserver_user_state.fd);
49 gdbserver_user_state.fd = -1;
50 return -1;
51 } else {
52 break;
53 }
54 }
55 return ch;
56}
57
Alex Bennéea7e0f9b2023-03-02 18:57:49 -080058bool gdb_got_immediate_ack(void)
59{
60 int i;
61
62 i = gdb_get_char();
63 if (i < 0) {
64 /* no response, continue anyway */
65 return true;
66 }
67
68 if (i == '+') {
69 /* received correctly, continue */
70 return true;
71 }
72
73 /* anything else, including '-' then try again */
74 return false;
75}
76
Alex Bennéed96bf492023-03-02 18:57:47 -080077void gdb_put_buffer(const uint8_t *buf, int len)
78{
79 int ret;
80
81 while (len > 0) {
82 ret = send(gdbserver_user_state.fd, buf, len, 0);
83 if (ret < 0) {
84 if (errno != EINTR) {
85 return;
86 }
87 } else {
88 buf += ret;
89 len -= ret;
90 }
91 }
92}
93
94/* Tell the remote gdb that the process has exited. */
95void gdb_exit(int code)
96{
97 char buf[4];
98
99 if (!gdbserver_state.init) {
100 return;
101 }
102 if (gdbserver_user_state.socket_path) {
103 unlink(gdbserver_user_state.socket_path);
104 }
105 if (gdbserver_user_state.fd < 0) {
106 return;
107 }
108
109 trace_gdbstub_op_exiting((uint8_t)code);
110
Matheus Tavares Bernardino75837002023-05-04 12:37:31 -0300111 if (gdbserver_state.allow_stop_reply) {
112 snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
113 gdb_put_packet(buf);
114 gdbserver_state.allow_stop_reply = false;
115 }
Clément Chigote2162562023-10-03 09:14:27 +0200116
117}
118
119void gdb_qemu_exit(int code)
120{
121 exit(code);
Alex Bennéed96bf492023-03-02 18:57:47 -0800122}
123
Ilya Leoshkevich8b7fcb82024-02-07 16:38:09 +0000124int gdb_handlesig_reason(CPUState *cpu, int sig, const char *reason)
Alex Bennéed96bf492023-03-02 18:57:47 -0800125{
126 char buf[256];
127 int n;
128
129 if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
130 return sig;
131 }
132
133 /* disable single step if it was enabled */
134 cpu_single_step(cpu, 0);
135 tb_flush(cpu);
136
137 if (sig != 0) {
138 gdb_set_stop_cpu(cpu);
Matheus Tavares Bernardino75837002023-05-04 12:37:31 -0300139 if (gdbserver_state.allow_stop_reply) {
140 g_string_printf(gdbserver_state.str_buf,
141 "T%02xthread:", gdb_target_signal_to_gdb(sig));
142 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
143 g_string_append_c(gdbserver_state.str_buf, ';');
Ilya Leoshkevich8b7fcb82024-02-07 16:38:09 +0000144 if (reason) {
145 g_string_append(gdbserver_state.str_buf, reason);
146 }
Matheus Tavares Bernardino75837002023-05-04 12:37:31 -0300147 gdb_put_strbuf();
148 gdbserver_state.allow_stop_reply = false;
149 }
Alex Bennéed96bf492023-03-02 18:57:47 -0800150 }
151 /*
152 * gdb_put_packet() might have detected that the peer terminated the
153 * connection.
154 */
155 if (gdbserver_user_state.fd < 0) {
156 return sig;
157 }
158
159 sig = 0;
160 gdbserver_state.state = RS_IDLE;
161 gdbserver_user_state.running_state = 0;
162 while (gdbserver_user_state.running_state == 0) {
163 n = read(gdbserver_user_state.fd, buf, 256);
164 if (n > 0) {
165 int i;
166
167 for (i = 0; i < n; i++) {
168 gdb_read_byte(buf[i]);
169 }
170 } else {
171 /*
172 * XXX: Connection closed. Should probably wait for another
173 * connection before continuing.
174 */
175 if (n == 0) {
176 close(gdbserver_user_state.fd);
177 }
178 gdbserver_user_state.fd = -1;
179 return sig;
180 }
181 }
182 sig = gdbserver_state.signal;
183 gdbserver_state.signal = 0;
184 return sig;
185}
186
187/* Tell the remote gdb that the process has exited due to SIG. */
188void gdb_signalled(CPUArchState *env, int sig)
189{
190 char buf[4];
191
Matheus Tavares Bernardino75837002023-05-04 12:37:31 -0300192 if (!gdbserver_state.init || gdbserver_user_state.fd < 0 ||
193 !gdbserver_state.allow_stop_reply) {
Alex Bennéed96bf492023-03-02 18:57:47 -0800194 return;
195 }
196
197 snprintf(buf, sizeof(buf), "X%02x", gdb_target_signal_to_gdb(sig));
198 gdb_put_packet(buf);
Matheus Tavares Bernardino75837002023-05-04 12:37:31 -0300199 gdbserver_state.allow_stop_reply = false;
Alex Bennéed96bf492023-03-02 18:57:47 -0800200}
201
202static void gdb_accept_init(int fd)
203{
204 gdb_init_gdbserver_state();
205 gdb_create_default_process(&gdbserver_state);
206 gdbserver_state.processes[0].attached = true;
207 gdbserver_state.c_cpu = gdb_first_attached_cpu();
208 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
209 gdbserver_user_state.fd = fd;
Alex Bennéed96bf492023-03-02 18:57:47 -0800210}
211
212static bool gdb_accept_socket(int gdb_fd)
213{
214 int fd;
215
216 for (;;) {
217 fd = accept(gdb_fd, NULL, NULL);
218 if (fd < 0 && errno != EINTR) {
219 perror("accept socket");
220 return false;
221 } else if (fd >= 0) {
222 qemu_set_cloexec(fd);
223 break;
224 }
225 }
226
227 gdb_accept_init(fd);
228 return true;
229}
230
231static int gdbserver_open_socket(const char *path)
232{
233 struct sockaddr_un sockaddr = {};
234 int fd, ret;
235
236 fd = socket(AF_UNIX, SOCK_STREAM, 0);
237 if (fd < 0) {
238 perror("create socket");
239 return -1;
240 }
241
242 sockaddr.sun_family = AF_UNIX;
243 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
244 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
245 if (ret < 0) {
246 perror("bind socket");
247 close(fd);
248 return -1;
249 }
250 ret = listen(fd, 1);
251 if (ret < 0) {
252 perror("listen socket");
253 close(fd);
254 return -1;
255 }
256
257 return fd;
258}
259
260static bool gdb_accept_tcp(int gdb_fd)
261{
262 struct sockaddr_in sockaddr = {};
263 socklen_t len;
264 int fd;
265
266 for (;;) {
267 len = sizeof(sockaddr);
268 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
269 if (fd < 0 && errno != EINTR) {
270 perror("accept");
271 return false;
272 } else if (fd >= 0) {
273 qemu_set_cloexec(fd);
274 break;
275 }
276 }
277
278 /* set short latency */
279 if (socket_set_nodelay(fd)) {
280 perror("setsockopt");
281 close(fd);
282 return false;
283 }
284
285 gdb_accept_init(fd);
286 return true;
287}
288
289static int gdbserver_open_port(int port)
290{
291 struct sockaddr_in sockaddr;
292 int fd, ret;
293
294 fd = socket(PF_INET, SOCK_STREAM, 0);
295 if (fd < 0) {
296 perror("socket");
297 return -1;
298 }
299 qemu_set_cloexec(fd);
300
301 socket_set_fast_reuse(fd);
302
303 sockaddr.sin_family = AF_INET;
304 sockaddr.sin_port = htons(port);
305 sockaddr.sin_addr.s_addr = 0;
306 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
307 if (ret < 0) {
308 perror("bind");
309 close(fd);
310 return -1;
311 }
312 ret = listen(fd, 1);
313 if (ret < 0) {
314 perror("listen");
315 close(fd);
316 return -1;
317 }
318
319 return fd;
320}
321
322int gdbserver_start(const char *port_or_path)
323{
324 int port = g_ascii_strtoull(port_or_path, NULL, 10);
325 int gdb_fd;
326
327 if (port > 0) {
328 gdb_fd = gdbserver_open_port(port);
329 } else {
330 gdb_fd = gdbserver_open_socket(port_or_path);
331 }
332
333 if (gdb_fd < 0) {
334 return -1;
335 }
336
337 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
338 return 0;
339 } else if (gdb_accept_socket(gdb_fd)) {
340 gdbserver_user_state.socket_path = g_strdup(port_or_path);
341 return 0;
342 }
343
344 /* gone wrong */
345 close(gdb_fd);
346 return -1;
347}
348
349/* Disable gdb stub for child processes. */
350void gdbserver_fork(CPUState *cpu)
351{
352 if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
353 return;
354 }
355 close(gdbserver_user_state.fd);
356 gdbserver_user_state.fd = -1;
357 cpu_breakpoint_remove_all(cpu, BP_GDB);
358 /* no cpu_watchpoint_remove_all for user-mode */
359}
360
361/*
362 * Execution state helpers
363 */
364
Alex Bennée8a2025b2023-03-02 18:57:50 -0800365void gdb_handle_query_attached(GArray *params, void *user_ctx)
366{
367 gdb_put_packet("0");
368}
369
Alex Bennéed96bf492023-03-02 18:57:47 -0800370void gdb_continue(void)
371{
372 gdbserver_user_state.running_state = 1;
373 trace_gdbstub_op_continue();
374}
375
376/*
377 * Resume execution, for user-mode emulation it's equivalent to
378 * gdb_continue.
379 */
380int gdb_continue_partial(char *newstates)
381{
382 CPUState *cpu;
383 int res = 0;
384 /*
385 * This is not exactly accurate, but it's an improvement compared to the
386 * previous situation, where only one CPU would be single-stepped.
387 */
388 CPU_FOREACH(cpu) {
389 if (newstates[cpu->cpu_index] == 's') {
390 trace_gdbstub_op_stepping(cpu->cpu_index);
391 cpu_single_step(cpu, gdbserver_state.sstep_flags);
392 }
393 }
394 gdbserver_user_state.running_state = 1;
395 return res;
396}
397
398/*
Alex Bennée589a5862023-03-02 18:57:51 -0800399 * Memory access helpers
400 */
401int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
402 uint8_t *buf, int len, bool is_write)
403{
404 CPUClass *cc;
405
406 cc = CPU_GET_CLASS(cpu);
407 if (cc->memory_rw_debug) {
408 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
409 }
410 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
411}
412
413/*
Alex Bennée7ea0c332023-03-02 18:57:52 -0800414 * cpu helpers
415 */
416
417unsigned int gdb_get_max_cpus(void)
418{
419 CPUState *cpu;
420 unsigned int max_cpus = 1;
421
422 CPU_FOREACH(cpu) {
423 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
424 }
425
426 return max_cpus;
427}
428
Alex Bennée505601d2023-03-02 18:57:53 -0800429/* replay not supported for user-mode */
430bool gdb_can_reverse(void)
431{
432 return false;
433}
Alex Bennée7ea0c332023-03-02 18:57:52 -0800434
435/*
Alex Bennéed96bf492023-03-02 18:57:47 -0800436 * Break/Watch point helpers
437 */
438
Alex Bennéea48e7d92022-09-29 12:42:25 +0100439bool gdb_supports_guest_debug(void)
440{
441 /* user-mode == TCG == supported */
442 return true;
443}
444
Philippe Mathieu-Daudé55b5b8e2022-12-06 16:20:27 +0100445int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
Alex Bennéeae7467b2022-09-29 12:42:24 +0100446{
447 CPUState *cpu;
448 int err = 0;
449
450 switch (type) {
451 case GDB_BREAKPOINT_SW:
452 case GDB_BREAKPOINT_HW:
453 CPU_FOREACH(cpu) {
454 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
455 if (err) {
456 break;
457 }
458 }
459 return err;
460 default:
461 /* user-mode doesn't support watchpoints */
462 return -ENOSYS;
463 }
464}
465
Philippe Mathieu-Daudé55b5b8e2022-12-06 16:20:27 +0100466int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len)
Alex Bennéeae7467b2022-09-29 12:42:24 +0100467{
468 CPUState *cpu;
469 int err = 0;
470
471 switch (type) {
472 case GDB_BREAKPOINT_SW:
473 case GDB_BREAKPOINT_HW:
474 CPU_FOREACH(cpu) {
475 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
476 if (err) {
477 break;
478 }
479 }
480 return err;
481 default:
482 /* user-mode doesn't support watchpoints */
483 return -ENOSYS;
484 }
485}
486
487void gdb_breakpoint_remove_all(CPUState *cs)
488{
489 cpu_breakpoint_remove_all(cs, BP_GDB);
490}
Alex Bennée131f3872023-03-02 18:58:01 -0800491
492/*
493 * For user-mode syscall support we send the system call immediately
494 * and then return control to gdb for it to process the syscall request.
495 * Since the protocol requires that gdb hands control back to us
496 * using a "here are the results" F packet, we don't need to check
497 * gdb_handlesig's return value (which is the signal to deliver if
498 * execution was resumed via a continue packet).
499 */
500void gdb_syscall_handling(const char *syscall_packet)
501{
502 gdb_put_packet(syscall_packet);
503 gdb_handlesig(gdbserver_state.c_cpu, 0);
504}
Ilya Leoshkevich0a0d87c2024-02-07 16:38:10 +0000505
506void gdb_syscall_entry(CPUState *cs, int num)
507{
508}
509
510void gdb_syscall_return(CPUState *cs, int num)
511{
512}