xref: /openbmc/qemu/gdbstub/user.c (revision d96bf49ba842e8e1b73c7884d2be084582f34228)
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  *
6  * Copyright (c) 2003-2005 Fabrice Bellard
7  * Copyright (c) 2022 Linaro Ltd
8  *
9  * SPDX-License-Identifier: LGPL-2.0+
10  */
11 
12 #include "qemu/osdep.h"
13 #include "qemu/cutils.h"
14 #include "qemu/sockets.h"
15 #include "exec/hwaddr.h"
16 #include "exec/tb-flush.h"
17 #include "exec/gdbstub.h"
18 #include "gdbstub/user.h"
19 #include "hw/core/cpu.h"
20 #include "trace.h"
21 #include "internals.h"
22 
23 /* User-mode specific state */
24 typedef struct {
25     int fd;
26     char *socket_path;
27     int running_state;
28 } GDBUserState;
29 
30 static GDBUserState gdbserver_user_state;
31 
32 int 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 
57 void gdb_put_buffer(const uint8_t *buf, int len)
58 {
59     int ret;
60 
61     while (len > 0) {
62         ret = send(gdbserver_user_state.fd, buf, len, 0);
63         if (ret < 0) {
64             if (errno != EINTR) {
65                 return;
66             }
67         } else {
68             buf += ret;
69             len -= ret;
70         }
71     }
72 }
73 
74 /* Tell the remote gdb that the process has exited.  */
75 void gdb_exit(int code)
76 {
77     char buf[4];
78 
79     if (!gdbserver_state.init) {
80         return;
81     }
82     if (gdbserver_user_state.socket_path) {
83         unlink(gdbserver_user_state.socket_path);
84     }
85     if (gdbserver_user_state.fd < 0) {
86         return;
87     }
88 
89     trace_gdbstub_op_exiting((uint8_t)code);
90 
91     snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
92     gdb_put_packet(buf);
93 }
94 
95 int gdb_handlesig(CPUState *cpu, int sig)
96 {
97     char buf[256];
98     int n;
99 
100     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
101         return sig;
102     }
103 
104     /* disable single step if it was enabled */
105     cpu_single_step(cpu, 0);
106     tb_flush(cpu);
107 
108     if (sig != 0) {
109         gdb_set_stop_cpu(cpu);
110         g_string_printf(gdbserver_state.str_buf,
111                         "T%02xthread:", gdb_target_signal_to_gdb(sig));
112         gdb_append_thread_id(cpu, gdbserver_state.str_buf);
113         g_string_append_c(gdbserver_state.str_buf, ';');
114         gdb_put_strbuf();
115     }
116     /*
117      * gdb_put_packet() might have detected that the peer terminated the
118      * connection.
119      */
120     if (gdbserver_user_state.fd < 0) {
121         return sig;
122     }
123 
124     sig = 0;
125     gdbserver_state.state = RS_IDLE;
126     gdbserver_user_state.running_state = 0;
127     while (gdbserver_user_state.running_state == 0) {
128         n = read(gdbserver_user_state.fd, buf, 256);
129         if (n > 0) {
130             int i;
131 
132             for (i = 0; i < n; i++) {
133                 gdb_read_byte(buf[i]);
134             }
135         } else {
136             /*
137              * XXX: Connection closed.  Should probably wait for another
138              * connection before continuing.
139              */
140             if (n == 0) {
141                 close(gdbserver_user_state.fd);
142             }
143             gdbserver_user_state.fd = -1;
144             return sig;
145         }
146     }
147     sig = gdbserver_state.signal;
148     gdbserver_state.signal = 0;
149     return sig;
150 }
151 
152 /* Tell the remote gdb that the process has exited due to SIG.  */
153 void gdb_signalled(CPUArchState *env, int sig)
154 {
155     char buf[4];
156 
157     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
158         return;
159     }
160 
161     snprintf(buf, sizeof(buf), "X%02x", gdb_target_signal_to_gdb(sig));
162     gdb_put_packet(buf);
163 }
164 
165 static void gdb_accept_init(int fd)
166 {
167     gdb_init_gdbserver_state();
168     gdb_create_default_process(&gdbserver_state);
169     gdbserver_state.processes[0].attached = true;
170     gdbserver_state.c_cpu = gdb_first_attached_cpu();
171     gdbserver_state.g_cpu = gdbserver_state.c_cpu;
172     gdbserver_user_state.fd = fd;
173     gdb_has_xml = false;
174 }
175 
176 static bool gdb_accept_socket(int gdb_fd)
177 {
178     int fd;
179 
180     for (;;) {
181         fd = accept(gdb_fd, NULL, NULL);
182         if (fd < 0 && errno != EINTR) {
183             perror("accept socket");
184             return false;
185         } else if (fd >= 0) {
186             qemu_set_cloexec(fd);
187             break;
188         }
189     }
190 
191     gdb_accept_init(fd);
192     return true;
193 }
194 
195 static int gdbserver_open_socket(const char *path)
196 {
197     struct sockaddr_un sockaddr = {};
198     int fd, ret;
199 
200     fd = socket(AF_UNIX, SOCK_STREAM, 0);
201     if (fd < 0) {
202         perror("create socket");
203         return -1;
204     }
205 
206     sockaddr.sun_family = AF_UNIX;
207     pstrcpy(sockaddr.sun_path, sizeof(sockaddr.sun_path) - 1, path);
208     ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
209     if (ret < 0) {
210         perror("bind socket");
211         close(fd);
212         return -1;
213     }
214     ret = listen(fd, 1);
215     if (ret < 0) {
216         perror("listen socket");
217         close(fd);
218         return -1;
219     }
220 
221     return fd;
222 }
223 
224 static bool gdb_accept_tcp(int gdb_fd)
225 {
226     struct sockaddr_in sockaddr = {};
227     socklen_t len;
228     int fd;
229 
230     for (;;) {
231         len = sizeof(sockaddr);
232         fd = accept(gdb_fd, (struct sockaddr *)&sockaddr, &len);
233         if (fd < 0 && errno != EINTR) {
234             perror("accept");
235             return false;
236         } else if (fd >= 0) {
237             qemu_set_cloexec(fd);
238             break;
239         }
240     }
241 
242     /* set short latency */
243     if (socket_set_nodelay(fd)) {
244         perror("setsockopt");
245         close(fd);
246         return false;
247     }
248 
249     gdb_accept_init(fd);
250     return true;
251 }
252 
253 static int gdbserver_open_port(int port)
254 {
255     struct sockaddr_in sockaddr;
256     int fd, ret;
257 
258     fd = socket(PF_INET, SOCK_STREAM, 0);
259     if (fd < 0) {
260         perror("socket");
261         return -1;
262     }
263     qemu_set_cloexec(fd);
264 
265     socket_set_fast_reuse(fd);
266 
267     sockaddr.sin_family = AF_INET;
268     sockaddr.sin_port = htons(port);
269     sockaddr.sin_addr.s_addr = 0;
270     ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
271     if (ret < 0) {
272         perror("bind");
273         close(fd);
274         return -1;
275     }
276     ret = listen(fd, 1);
277     if (ret < 0) {
278         perror("listen");
279         close(fd);
280         return -1;
281     }
282 
283     return fd;
284 }
285 
286 int gdbserver_start(const char *port_or_path)
287 {
288     int port = g_ascii_strtoull(port_or_path, NULL, 10);
289     int gdb_fd;
290 
291     if (port > 0) {
292         gdb_fd = gdbserver_open_port(port);
293     } else {
294         gdb_fd = gdbserver_open_socket(port_or_path);
295     }
296 
297     if (gdb_fd < 0) {
298         return -1;
299     }
300 
301     if (port > 0 && gdb_accept_tcp(gdb_fd)) {
302         return 0;
303     } else if (gdb_accept_socket(gdb_fd)) {
304         gdbserver_user_state.socket_path = g_strdup(port_or_path);
305         return 0;
306     }
307 
308     /* gone wrong */
309     close(gdb_fd);
310     return -1;
311 }
312 
313 /* Disable gdb stub for child processes.  */
314 void gdbserver_fork(CPUState *cpu)
315 {
316     if (!gdbserver_state.init || gdbserver_user_state.fd < 0) {
317         return;
318     }
319     close(gdbserver_user_state.fd);
320     gdbserver_user_state.fd = -1;
321     cpu_breakpoint_remove_all(cpu, BP_GDB);
322     /* no cpu_watchpoint_remove_all for user-mode */
323 }
324 
325 /*
326  * Execution state helpers
327  */
328 
329 void gdb_continue(void)
330 {
331     gdbserver_user_state.running_state = 1;
332     trace_gdbstub_op_continue();
333 }
334 
335 /*
336  * Resume execution, for user-mode emulation it's equivalent to
337  * gdb_continue.
338  */
339 int gdb_continue_partial(char *newstates)
340 {
341     CPUState *cpu;
342     int res = 0;
343     /*
344      * This is not exactly accurate, but it's an improvement compared to the
345      * previous situation, where only one CPU would be single-stepped.
346      */
347     CPU_FOREACH(cpu) {
348         if (newstates[cpu->cpu_index] == 's') {
349             trace_gdbstub_op_stepping(cpu->cpu_index);
350             cpu_single_step(cpu, gdbserver_state.sstep_flags);
351         }
352     }
353     gdbserver_user_state.running_state = 1;
354     return res;
355 }
356 
357 /*
358  * Break/Watch point helpers
359  */
360 
361 bool gdb_supports_guest_debug(void)
362 {
363     /* user-mode == TCG == supported */
364     return true;
365 }
366 
367 int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
368 {
369     CPUState *cpu;
370     int err = 0;
371 
372     switch (type) {
373     case GDB_BREAKPOINT_SW:
374     case GDB_BREAKPOINT_HW:
375         CPU_FOREACH(cpu) {
376             err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
377             if (err) {
378                 break;
379             }
380         }
381         return err;
382     default:
383         /* user-mode doesn't support watchpoints */
384         return -ENOSYS;
385     }
386 }
387 
388 int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len)
389 {
390     CPUState *cpu;
391     int err = 0;
392 
393     switch (type) {
394     case GDB_BREAKPOINT_SW:
395     case GDB_BREAKPOINT_HW:
396         CPU_FOREACH(cpu) {
397             err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
398             if (err) {
399                 break;
400             }
401         }
402         return err;
403     default:
404         /* user-mode doesn't support watchpoints */
405         return -ENOSYS;
406     }
407 }
408 
409 void gdb_breakpoint_remove_all(CPUState *cs)
410 {
411     cpu_breakpoint_remove_all(cs, BP_GDB);
412 }
413