]> git.proxmox.com Git - mirror_qemu.git/blame - gdbstub/user.c
Merge tag 'pull-block-2023-09-01' of https://gitlab.com/hreitz/qemu into staging
[mirror_qemu.git] / gdbstub / user.c
CommitLineData
ae7467b1
AB
1/*
2 * gdbstub user-mode helper routines.
3 *
4 * We know for user-mode we are using TCG so we can call stuff directly.
5 *
9455762f 6 * Copyright (c) 2003-2005 Fabrice Bellard
ae7467b1
AB
7 * Copyright (c) 2022 Linaro Ltd
8 *
9455762f 9 * SPDX-License-Identifier: LGPL-2.0+
ae7467b1
AB
10 */
11
12#include "qemu/osdep.h"
d96bf49b
AB
13#include "qemu/cutils.h"
14#include "qemu/sockets.h"
15#include "exec/hwaddr.h"
16#include "exec/tb-flush.h"
ae7467b1 17#include "exec/gdbstub.h"
c566080c 18#include "gdbstub/syscalls.h"
d96bf49b 19#include "gdbstub/user.h"
ae7467b1 20#include "hw/core/cpu.h"
d96bf49b 21#include "trace.h"
ae7467b1
AB
22#include "internals.h"
23
d96bf49b
AB
24/* 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
a7e0f9bd
AB
58bool 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
d96bf49b
AB
77void 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
75837005
MTB
111 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 }
d96bf49b
AB
116}
117
118int gdb_handlesig(CPUState *cpu, int sig)
119{
120 char buf[256];
121 int n;
122
123 if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
124 return sig;
125 }
126
127 /* disable single step if it was enabled */
128 cpu_single_step(cpu, 0);
129 tb_flush(cpu);
130
131 if (sig != 0) {
132 gdb_set_stop_cpu(cpu);
75837005
MTB
133 if (gdbserver_state.allow_stop_reply) {
134 g_string_printf(gdbserver_state.str_buf,
135 "T%02xthread:", gdb_target_signal_to_gdb(sig));
136 gdb_append_thread_id(cpu, gdbserver_state.str_buf);
137 g_string_append_c(gdbserver_state.str_buf, ';');
138 gdb_put_strbuf();
139 gdbserver_state.allow_stop_reply = false;
140 }
d96bf49b
AB
141 }
142 /*
143 * gdb_put_packet() might have detected that the peer terminated the
144 * connection.
145 */
146 if (gdbserver_user_state.fd < 0) {
147 return sig;
148 }
149
150 sig = 0;
151 gdbserver_state.state = RS_IDLE;
152 gdbserver_user_state.running_state = 0;
153 while (gdbserver_user_state.running_state == 0) {
154 n = read(gdbserver_user_state.fd, buf, 256);
155 if (n > 0) {
156 int i;
157
158 for (i = 0; i < n; i++) {
159 gdb_read_byte(buf[i]);
160 }
161 } else {
162 /*
163 * XXX: Connection closed. Should probably wait for another
164 * connection before continuing.
165 */
166 if (n == 0) {
167 close(gdbserver_user_state.fd);
168 }
169 gdbserver_user_state.fd = -1;
170 return sig;
171 }
172 }
173 sig = gdbserver_state.signal;
174 gdbserver_state.signal = 0;
175 return sig;
176}
177
178/* Tell the remote gdb that the process has exited due to SIG. */
179void gdb_signalled(CPUArchState *env, int sig)
180{
181 char buf[4];
182
75837005
MTB
183 if (!gdbserver_state.init || gdbserver_user_state.fd < 0 ||
184 !gdbserver_state.allow_stop_reply) {
d96bf49b
AB
185 return;
186 }
187
188 snprintf(buf, sizeof(buf), "X%02x", gdb_target_signal_to_gdb(sig));
189 gdb_put_packet(buf);
75837005 190 gdbserver_state.allow_stop_reply = false;
d96bf49b
AB
191}
192
193static void gdb_accept_init(int fd)
194{
195 gdb_init_gdbserver_state();
196 gdb_create_default_process(&gdbserver_state);
197 gdbserver_state.processes[0].attached = true;
198 gdbserver_state.c_cpu = gdb_first_attached_cpu();
199 gdbserver_state.g_cpu = gdbserver_state.c_cpu;
200 gdbserver_user_state.fd = fd;
d96bf49b
AB
201}
202
203static bool gdb_accept_socket(int gdb_fd)
204{
205 int fd;
206
207 for (;;) {
208 fd = accept(gdb_fd, NULL, NULL);
209 if (fd < 0 && errno != EINTR) {
210 perror("accept socket");
211 return false;
212 } else if (fd >= 0) {
213 qemu_set_cloexec(fd);
214 break;
215 }
216 }
217
218 gdb_accept_init(fd);
219 return true;
220}
221
222static int gdbserver_open_socket(const char *path)
223{
224 struct sockaddr_un sockaddr = {};
225 int fd, ret;
226
227 fd = socket(AF_UNIX, SOCK_STREAM, 0);
228 if (fd < 0) {
229 perror("create socket");
230 return -1;
231 }
232
233 sockaddr.sun_family = AF_UNIX;
234 pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
235 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
236 if (ret < 0) {
237 perror("bind socket");
238 close(fd);
239 return -1;
240 }
241 ret = listen(fd, 1);
242 if (ret < 0) {
243 perror("listen socket");
244 close(fd);
245 return -1;
246 }
247
248 return fd;
249}
250
251static bool gdb_accept_tcp(int gdb_fd)
252{
253 struct sockaddr_in sockaddr = {};
254 socklen_t len;
255 int fd;
256
257 for (;;) {
258 len = sizeof(sockaddr);
259 fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
260 if (fd < 0 && errno != EINTR) {
261 perror("accept");
262 return false;
263 } else if (fd >= 0) {
264 qemu_set_cloexec(fd);
265 break;
266 }
267 }
268
269 /* set short latency */
270 if (socket_set_nodelay(fd)) {
271 perror("setsockopt");
272 close(fd);
273 return false;
274 }
275
276 gdb_accept_init(fd);
277 return true;
278}
279
280static int gdbserver_open_port(int port)
281{
282 struct sockaddr_in sockaddr;
283 int fd, ret;
284
285 fd = socket(PF_INET, SOCK_STREAM, 0);
286 if (fd < 0) {
287 perror("socket");
288 return -1;
289 }
290 qemu_set_cloexec(fd);
291
292 socket_set_fast_reuse(fd);
293
294 sockaddr.sin_family = AF_INET;
295 sockaddr.sin_port = htons(port);
296 sockaddr.sin_addr.s_addr = 0;
297 ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
298 if (ret < 0) {
299 perror("bind");
300 close(fd);
301 return -1;
302 }
303 ret = listen(fd, 1);
304 if (ret < 0) {
305 perror("listen");
306 close(fd);
307 return -1;
308 }
309
310 return fd;
311}
312
313int gdbserver_start(const char *port_or_path)
314{
315 int port = g_ascii_strtoull(port_or_path, NULL, 10);
316 int gdb_fd;
317
318 if (port > 0) {
319 gdb_fd = gdbserver_open_port(port);
320 } else {
321 gdb_fd = gdbserver_open_socket(port_or_path);
322 }
323
324 if (gdb_fd < 0) {
325 return -1;
326 }
327
328 if (port > 0 && gdb_accept_tcp(gdb_fd)) {
329 return 0;
330 } else if (gdb_accept_socket(gdb_fd)) {
331 gdbserver_user_state.socket_path = g_strdup(port_or_path);
332 return 0;
333 }
334
335 /* gone wrong */
336 close(gdb_fd);
337 return -1;
338}
339
340/* Disable gdb stub for child processes. */
341void gdbserver_fork(CPUState *cpu)
342{
343 if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
344 return;
345 }
346 close(gdbserver_user_state.fd);
347 gdbserver_user_state.fd = -1;
348 cpu_breakpoint_remove_all(cpu, BP_GDB);
349 /* no cpu_watchpoint_remove_all for user-mode */
350}
351
352/*
353 * Execution state helpers
354 */
355
8a2025b3
AB
356void gdb_handle_query_attached(GArray *params, void *user_ctx)
357{
358 gdb_put_packet("0");
359}
360
d96bf49b
AB
361void gdb_continue(void)
362{
363 gdbserver_user_state.running_state = 1;
364 trace_gdbstub_op_continue();
365}
366
367/*
368 * Resume execution, for user-mode emulation it's equivalent to
369 * gdb_continue.
370 */
371int gdb_continue_partial(char *newstates)
372{
373 CPUState *cpu;
374 int res = 0;
375 /*
376 * This is not exactly accurate, but it's an improvement compared to the
377 * previous situation, where only one CPU would be single-stepped.
378 */
379 CPU_FOREACH(cpu) {
380 if (newstates[cpu->cpu_index] == 's') {
381 trace_gdbstub_op_stepping(cpu->cpu_index);
382 cpu_single_step(cpu, gdbserver_state.sstep_flags);
383 }
384 }
385 gdbserver_user_state.running_state = 1;
386 return res;
387}
388
589a5867
AB
389/*
390 * Memory access helpers
391 */
392int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
393 uint8_t *buf, int len, bool is_write)
394{
395 CPUClass *cc;
396
397 cc = CPU_GET_CLASS(cpu);
398 if (cc->memory_rw_debug) {
399 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
400 }
401 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
402}
403
7ea0c33d
AB
404/*
405 * cpu helpers
406 */
407
408unsigned int gdb_get_max_cpus(void)
409{
410 CPUState *cpu;
411 unsigned int max_cpus = 1;
412
413 CPU_FOREACH(cpu) {
414 max_cpus = max_cpus <= cpu->cpu_index ? cpu->cpu_index + 1 : max_cpus;
415 }
416
417 return max_cpus;
418}
419
505601d5
AB
420/* replay not supported for user-mode */
421bool gdb_can_reverse(void)
422{
423 return false;
424}
7ea0c33d 425
d96bf49b
AB
426/*
427 * Break/Watch point helpers
428 */
429
a48e7d9e
AB
430bool gdb_supports_guest_debug(void)
431{
432 /* user-mode == TCG == supported */
433 return true;
434}
435
55b5b8e9 436int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
ae7467b1
AB
437{
438 CPUState *cpu;
439 int err = 0;
440
441 switch (type) {
442 case GDB_BREAKPOINT_SW:
443 case GDB_BREAKPOINT_HW:
444 CPU_FOREACH(cpu) {
445 err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
446 if (err) {
447 break;
448 }
449 }
450 return err;
451 default:
452 /* user-mode doesn't support watchpoints */
453 return -ENOSYS;
454 }
455}
456
55b5b8e9 457int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len)
ae7467b1
AB
458{
459 CPUState *cpu;
460 int err = 0;
461
462 switch (type) {
463 case GDB_BREAKPOINT_SW:
464 case GDB_BREAKPOINT_HW:
465 CPU_FOREACH(cpu) {
466 err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
467 if (err) {
468 break;
469 }
470 }
471 return err;
472 default:
473 /* user-mode doesn't support watchpoints */
474 return -ENOSYS;
475 }
476}
477
478void gdb_breakpoint_remove_all(CPUState *cs)
479{
480 cpu_breakpoint_remove_all(cs, BP_GDB);
481}
131f387d
AB
482
483/*
484 * For user-mode syscall support we send the system call immediately
485 * and then return control to gdb for it to process the syscall request.
486 * Since the protocol requires that gdb hands control back to us
487 * using a "here are the results" F packet, we don't need to check
488 * gdb_handlesig's return value (which is the signal to deliver if
489 * execution was resumed via a continue packet).
490 */
491void gdb_syscall_handling(const char *syscall_packet)
492{
493 gdb_put_packet(syscall_packet);
494 gdb_handlesig(gdbserver_state.c_cpu, 0);
495}