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