1d96bf49bSAlex Bennée /*
2d96bf49bSAlex Bennée * Target specific user-mode handling
3d96bf49bSAlex Bennée *
4d96bf49bSAlex Bennée * Copyright (c) 2003-2005 Fabrice Bellard
5d96bf49bSAlex Bennée * Copyright (c) 2022 Linaro Ltd
6d96bf49bSAlex Bennée *
7b14d0649SPhilippe Mathieu-Daudé * SPDX-License-Identifier: LGPL-2.0-or-later
8d96bf49bSAlex Bennée */
9d96bf49bSAlex Bennée
10d96bf49bSAlex Bennée #include "qemu/osdep.h"
11d96bf49bSAlex Bennée #include "exec/gdbstub.h"
12133f202bSGustavo Romero #include "gdbstub/commands.h"
13d96bf49bSAlex Bennée #include "qemu.h"
14d96bf49bSAlex Bennée #include "internals.h"
15e282010bSIlya Leoshkevich #ifdef CONFIG_LINUX
16e282010bSIlya Leoshkevich #include "linux-user/loader.h"
17e282010bSIlya Leoshkevich #include "linux-user/qemu.h"
18e282010bSIlya Leoshkevich #endif
19d96bf49bSAlex Bennée
20d96bf49bSAlex Bennée /*
21d96bf49bSAlex Bennée * Map target signal numbers to GDB protocol signal numbers and vice
22d96bf49bSAlex Bennée * versa. For user emulation's currently supported systems, we can
23d96bf49bSAlex Bennée * assume most signals are defined.
24d96bf49bSAlex Bennée */
25d96bf49bSAlex Bennée
26d96bf49bSAlex Bennée static int gdb_signal_table[] = {
27d96bf49bSAlex Bennée 0,
28d96bf49bSAlex Bennée TARGET_SIGHUP,
29d96bf49bSAlex Bennée TARGET_SIGINT,
30d96bf49bSAlex Bennée TARGET_SIGQUIT,
31d96bf49bSAlex Bennée TARGET_SIGILL,
32d96bf49bSAlex Bennée TARGET_SIGTRAP,
33d96bf49bSAlex Bennée TARGET_SIGABRT,
34d96bf49bSAlex Bennée -1, /* SIGEMT */
35d96bf49bSAlex Bennée TARGET_SIGFPE,
36d96bf49bSAlex Bennée TARGET_SIGKILL,
37d96bf49bSAlex Bennée TARGET_SIGBUS,
38d96bf49bSAlex Bennée TARGET_SIGSEGV,
39d96bf49bSAlex Bennée TARGET_SIGSYS,
40d96bf49bSAlex Bennée TARGET_SIGPIPE,
41d96bf49bSAlex Bennée TARGET_SIGALRM,
42d96bf49bSAlex Bennée TARGET_SIGTERM,
43d96bf49bSAlex Bennée TARGET_SIGURG,
44d96bf49bSAlex Bennée TARGET_SIGSTOP,
45d96bf49bSAlex Bennée TARGET_SIGTSTP,
46d96bf49bSAlex Bennée TARGET_SIGCONT,
47d96bf49bSAlex Bennée TARGET_SIGCHLD,
48d96bf49bSAlex Bennée TARGET_SIGTTIN,
49d96bf49bSAlex Bennée TARGET_SIGTTOU,
50d96bf49bSAlex Bennée TARGET_SIGIO,
51d96bf49bSAlex Bennée TARGET_SIGXCPU,
52d96bf49bSAlex Bennée TARGET_SIGXFSZ,
53d96bf49bSAlex Bennée TARGET_SIGVTALRM,
54d96bf49bSAlex Bennée TARGET_SIGPROF,
55d96bf49bSAlex Bennée TARGET_SIGWINCH,
56d96bf49bSAlex Bennée -1, /* SIGLOST */
57d96bf49bSAlex Bennée TARGET_SIGUSR1,
58d96bf49bSAlex Bennée TARGET_SIGUSR2,
59d96bf49bSAlex Bennée #ifdef TARGET_SIGPWR
60d96bf49bSAlex Bennée TARGET_SIGPWR,
61d96bf49bSAlex Bennée #else
62d96bf49bSAlex Bennée -1,
63d96bf49bSAlex Bennée #endif
64d96bf49bSAlex Bennée -1, /* SIGPOLL */
65d96bf49bSAlex Bennée -1,
66d96bf49bSAlex Bennée -1,
67d96bf49bSAlex Bennée -1,
68d96bf49bSAlex Bennée -1,
69d96bf49bSAlex Bennée -1,
70d96bf49bSAlex Bennée -1,
71d96bf49bSAlex Bennée -1,
72d96bf49bSAlex Bennée -1,
73d96bf49bSAlex Bennée -1,
74d96bf49bSAlex Bennée -1,
75d96bf49bSAlex Bennée -1,
76d96bf49bSAlex Bennée #ifdef __SIGRTMIN
77d96bf49bSAlex Bennée __SIGRTMIN + 1,
78d96bf49bSAlex Bennée __SIGRTMIN + 2,
79d96bf49bSAlex Bennée __SIGRTMIN + 3,
80d96bf49bSAlex Bennée __SIGRTMIN + 4,
81d96bf49bSAlex Bennée __SIGRTMIN + 5,
82d96bf49bSAlex Bennée __SIGRTMIN + 6,
83d96bf49bSAlex Bennée __SIGRTMIN + 7,
84d96bf49bSAlex Bennée __SIGRTMIN + 8,
85d96bf49bSAlex Bennée __SIGRTMIN + 9,
86d96bf49bSAlex Bennée __SIGRTMIN + 10,
87d96bf49bSAlex Bennée __SIGRTMIN + 11,
88d96bf49bSAlex Bennée __SIGRTMIN + 12,
89d96bf49bSAlex Bennée __SIGRTMIN + 13,
90d96bf49bSAlex Bennée __SIGRTMIN + 14,
91d96bf49bSAlex Bennée __SIGRTMIN + 15,
92d96bf49bSAlex Bennée __SIGRTMIN + 16,
93d96bf49bSAlex Bennée __SIGRTMIN + 17,
94d96bf49bSAlex Bennée __SIGRTMIN + 18,
95d96bf49bSAlex Bennée __SIGRTMIN + 19,
96d96bf49bSAlex Bennée __SIGRTMIN + 20,
97d96bf49bSAlex Bennée __SIGRTMIN + 21,
98d96bf49bSAlex Bennée __SIGRTMIN + 22,
99d96bf49bSAlex Bennée __SIGRTMIN + 23,
100d96bf49bSAlex Bennée __SIGRTMIN + 24,
101d96bf49bSAlex Bennée __SIGRTMIN + 25,
102d96bf49bSAlex Bennée __SIGRTMIN + 26,
103d96bf49bSAlex Bennée __SIGRTMIN + 27,
104d96bf49bSAlex Bennée __SIGRTMIN + 28,
105d96bf49bSAlex Bennée __SIGRTMIN + 29,
106d96bf49bSAlex Bennée __SIGRTMIN + 30,
107d96bf49bSAlex Bennée __SIGRTMIN + 31,
108d96bf49bSAlex Bennée -1, /* SIGCANCEL */
109d96bf49bSAlex Bennée __SIGRTMIN,
110d96bf49bSAlex Bennée __SIGRTMIN + 32,
111d96bf49bSAlex Bennée __SIGRTMIN + 33,
112d96bf49bSAlex Bennée __SIGRTMIN + 34,
113d96bf49bSAlex Bennée __SIGRTMIN + 35,
114d96bf49bSAlex Bennée __SIGRTMIN + 36,
115d96bf49bSAlex Bennée __SIGRTMIN + 37,
116d96bf49bSAlex Bennée __SIGRTMIN + 38,
117d96bf49bSAlex Bennée __SIGRTMIN + 39,
118d96bf49bSAlex Bennée __SIGRTMIN + 40,
119d96bf49bSAlex Bennée __SIGRTMIN + 41,
120d96bf49bSAlex Bennée __SIGRTMIN + 42,
121d96bf49bSAlex Bennée __SIGRTMIN + 43,
122d96bf49bSAlex Bennée __SIGRTMIN + 44,
123d96bf49bSAlex Bennée __SIGRTMIN + 45,
124d96bf49bSAlex Bennée __SIGRTMIN + 46,
125d96bf49bSAlex Bennée __SIGRTMIN + 47,
126d96bf49bSAlex Bennée __SIGRTMIN + 48,
127d96bf49bSAlex Bennée __SIGRTMIN + 49,
128d96bf49bSAlex Bennée __SIGRTMIN + 50,
129d96bf49bSAlex Bennée __SIGRTMIN + 51,
130d96bf49bSAlex Bennée __SIGRTMIN + 52,
131d96bf49bSAlex Bennée __SIGRTMIN + 53,
132d96bf49bSAlex Bennée __SIGRTMIN + 54,
133d96bf49bSAlex Bennée __SIGRTMIN + 55,
134d96bf49bSAlex Bennée __SIGRTMIN + 56,
135d96bf49bSAlex Bennée __SIGRTMIN + 57,
136d96bf49bSAlex Bennée __SIGRTMIN + 58,
137d96bf49bSAlex Bennée __SIGRTMIN + 59,
138d96bf49bSAlex Bennée __SIGRTMIN + 60,
139d96bf49bSAlex Bennée __SIGRTMIN + 61,
140d96bf49bSAlex Bennée __SIGRTMIN + 62,
141d96bf49bSAlex Bennée __SIGRTMIN + 63,
142d96bf49bSAlex Bennée __SIGRTMIN + 64,
143d96bf49bSAlex Bennée __SIGRTMIN + 65,
144d96bf49bSAlex Bennée __SIGRTMIN + 66,
145d96bf49bSAlex Bennée __SIGRTMIN + 67,
146d96bf49bSAlex Bennée __SIGRTMIN + 68,
147d96bf49bSAlex Bennée __SIGRTMIN + 69,
148d96bf49bSAlex Bennée __SIGRTMIN + 70,
149d96bf49bSAlex Bennée __SIGRTMIN + 71,
150d96bf49bSAlex Bennée __SIGRTMIN + 72,
151d96bf49bSAlex Bennée __SIGRTMIN + 73,
152d96bf49bSAlex Bennée __SIGRTMIN + 74,
153d96bf49bSAlex Bennée __SIGRTMIN + 75,
154d96bf49bSAlex Bennée __SIGRTMIN + 76,
155d96bf49bSAlex Bennée __SIGRTMIN + 77,
156d96bf49bSAlex Bennée __SIGRTMIN + 78,
157d96bf49bSAlex Bennée __SIGRTMIN + 79,
158d96bf49bSAlex Bennée __SIGRTMIN + 80,
159d96bf49bSAlex Bennée __SIGRTMIN + 81,
160d96bf49bSAlex Bennée __SIGRTMIN + 82,
161d96bf49bSAlex Bennée __SIGRTMIN + 83,
162d96bf49bSAlex Bennée __SIGRTMIN + 84,
163d96bf49bSAlex Bennée __SIGRTMIN + 85,
164d96bf49bSAlex Bennée __SIGRTMIN + 86,
165d96bf49bSAlex Bennée __SIGRTMIN + 87,
166d96bf49bSAlex Bennée __SIGRTMIN + 88,
167d96bf49bSAlex Bennée __SIGRTMIN + 89,
168d96bf49bSAlex Bennée __SIGRTMIN + 90,
169d96bf49bSAlex Bennée __SIGRTMIN + 91,
170d96bf49bSAlex Bennée __SIGRTMIN + 92,
171d96bf49bSAlex Bennée __SIGRTMIN + 93,
172d96bf49bSAlex Bennée __SIGRTMIN + 94,
173d96bf49bSAlex Bennée __SIGRTMIN + 95,
174d96bf49bSAlex Bennée -1, /* SIGINFO */
175d96bf49bSAlex Bennée -1, /* UNKNOWN */
176d96bf49bSAlex Bennée -1, /* DEFAULT */
177d96bf49bSAlex Bennée -1,
178d96bf49bSAlex Bennée -1,
179d96bf49bSAlex Bennée -1,
180d96bf49bSAlex Bennée -1,
181d96bf49bSAlex Bennée -1,
182d96bf49bSAlex Bennée -1
183d96bf49bSAlex Bennée #endif
184d96bf49bSAlex Bennée };
185d96bf49bSAlex Bennée
gdb_signal_to_target(int sig)186d96bf49bSAlex Bennée int gdb_signal_to_target(int sig)
187d96bf49bSAlex Bennée {
188d96bf49bSAlex Bennée if (sig < ARRAY_SIZE(gdb_signal_table)) {
189d96bf49bSAlex Bennée return gdb_signal_table[sig];
190d96bf49bSAlex Bennée } else {
191d96bf49bSAlex Bennée return -1;
192d96bf49bSAlex Bennée }
193d96bf49bSAlex Bennée }
194d96bf49bSAlex Bennée
gdb_target_signal_to_gdb(int sig)195d96bf49bSAlex Bennée int gdb_target_signal_to_gdb(int sig)
196d96bf49bSAlex Bennée {
197d96bf49bSAlex Bennée int i;
198d96bf49bSAlex Bennée for (i = 0; i < ARRAY_SIZE(gdb_signal_table); i++) {
199d96bf49bSAlex Bennée if (gdb_signal_table[i] == sig) {
200d96bf49bSAlex Bennée return i;
201d96bf49bSAlex Bennée }
202d96bf49bSAlex Bennée }
203d96bf49bSAlex Bennée return GDB_SIGNAL_UNKNOWN;
204d96bf49bSAlex Bennée }
205d96bf49bSAlex Bennée
gdb_get_cpu_index(CPUState * cpu)206d96bf49bSAlex Bennée int gdb_get_cpu_index(CPUState *cpu)
207d96bf49bSAlex Bennée {
208e4e5cb4aSIlya Leoshkevich TaskState *ts = get_task_state(cpu);
209d96bf49bSAlex Bennée return ts ? ts->ts_tid : -1;
210d96bf49bSAlex Bennée }
211d96bf49bSAlex Bennée
212d96bf49bSAlex Bennée /*
213d96bf49bSAlex Bennée * User-mode specific command helpers
214d96bf49bSAlex Bennée */
215d96bf49bSAlex Bennée
gdb_handle_query_offsets(GArray * params,void * user_ctx)216d96bf49bSAlex Bennée void gdb_handle_query_offsets(GArray *params, void *user_ctx)
217d96bf49bSAlex Bennée {
218d96bf49bSAlex Bennée TaskState *ts;
219d96bf49bSAlex Bennée
22059272469SPhilippe Mathieu-Daudé ts = get_task_state(gdbserver_state.c_cpu);
221d96bf49bSAlex Bennée g_string_printf(gdbserver_state.str_buf,
222d96bf49bSAlex Bennée "Text=" TARGET_ABI_FMT_lx
223d96bf49bSAlex Bennée ";Data=" TARGET_ABI_FMT_lx
224d96bf49bSAlex Bennée ";Bss=" TARGET_ABI_FMT_lx,
225d96bf49bSAlex Bennée ts->info->code_offset,
226d96bf49bSAlex Bennée ts->info->data_offset,
227d96bf49bSAlex Bennée ts->info->data_offset);
228d96bf49bSAlex Bennée gdb_put_strbuf();
229d96bf49bSAlex Bennée }
230d96bf49bSAlex Bennée
231d96bf49bSAlex Bennée #if defined(CONFIG_LINUX)
232d96bf49bSAlex Bennée /* Partial user only duplicate of helper in gdbstub.c */
target_memory_rw_debug(CPUState * cpu,target_ulong addr,uint8_t * buf,int len,bool is_write)233d96bf49bSAlex Bennée static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
234d96bf49bSAlex Bennée uint8_t *buf, int len, bool is_write)
235d96bf49bSAlex Bennée {
236d96bf49bSAlex Bennée CPUClass *cc;
237d96bf49bSAlex Bennée cc = CPU_GET_CLASS(cpu);
238d96bf49bSAlex Bennée if (cc->memory_rw_debug) {
239d96bf49bSAlex Bennée return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
240d96bf49bSAlex Bennée }
241d96bf49bSAlex Bennée return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
242d96bf49bSAlex Bennée }
243d96bf49bSAlex Bennée
gdb_handle_query_xfer_auxv(GArray * params,void * user_ctx)244d96bf49bSAlex Bennée void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx)
245d96bf49bSAlex Bennée {
246d96bf49bSAlex Bennée TaskState *ts;
247d96bf49bSAlex Bennée unsigned long offset, len, saved_auxv, auxv_len;
248d96bf49bSAlex Bennée
249d96bf49bSAlex Bennée if (params->len < 2) {
250d96bf49bSAlex Bennée gdb_put_packet("E22");
251d96bf49bSAlex Bennée return;
252d96bf49bSAlex Bennée }
253d96bf49bSAlex Bennée
254133f202bSGustavo Romero offset = gdb_get_cmd_param(params, 0)->val_ul;
255133f202bSGustavo Romero len = gdb_get_cmd_param(params, 1)->val_ul;
25659272469SPhilippe Mathieu-Daudé ts = get_task_state(gdbserver_state.c_cpu);
257d96bf49bSAlex Bennée saved_auxv = ts->info->saved_auxv;
258d96bf49bSAlex Bennée auxv_len = ts->info->auxv_len;
259d96bf49bSAlex Bennée
260d96bf49bSAlex Bennée if (offset >= auxv_len) {
261d96bf49bSAlex Bennée gdb_put_packet("E00");
262d96bf49bSAlex Bennée return;
263d96bf49bSAlex Bennée }
264d96bf49bSAlex Bennée
265d96bf49bSAlex Bennée if (len > (MAX_PACKET_LENGTH - 5) / 2) {
266d96bf49bSAlex Bennée len = (MAX_PACKET_LENGTH - 5) / 2;
267d96bf49bSAlex Bennée }
268d96bf49bSAlex Bennée
269d96bf49bSAlex Bennée if (len < auxv_len - offset) {
270d96bf49bSAlex Bennée g_string_assign(gdbserver_state.str_buf, "m");
271d96bf49bSAlex Bennée } else {
272d96bf49bSAlex Bennée g_string_assign(gdbserver_state.str_buf, "l");
273d96bf49bSAlex Bennée len = auxv_len - offset;
274d96bf49bSAlex Bennée }
275d96bf49bSAlex Bennée
276d96bf49bSAlex Bennée g_byte_array_set_size(gdbserver_state.mem_buf, len);
277d96bf49bSAlex Bennée if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
278d96bf49bSAlex Bennée gdbserver_state.mem_buf->data, len, false)) {
279d96bf49bSAlex Bennée gdb_put_packet("E14");
280d96bf49bSAlex Bennée return;
281d96bf49bSAlex Bennée }
282d96bf49bSAlex Bennée
283d96bf49bSAlex Bennée gdb_memtox(gdbserver_state.str_buf,
284d96bf49bSAlex Bennée (const char *)gdbserver_state.mem_buf->data, len);
285d96bf49bSAlex Bennée gdb_put_packet_binary(gdbserver_state.str_buf->str,
286d96bf49bSAlex Bennée gdbserver_state.str_buf->len, true);
287d96bf49bSAlex Bennée }
288d96bf49bSAlex Bennée #endif
289e282010bSIlya Leoshkevich
get_filename_param(GArray * params,int i)290e282010bSIlya Leoshkevich static const char *get_filename_param(GArray *params, int i)
291e282010bSIlya Leoshkevich {
292133f202bSGustavo Romero const char *hex_filename = gdb_get_cmd_param(params, i)->data;
293e282010bSIlya Leoshkevich gdb_hextomem(gdbserver_state.mem_buf, hex_filename,
294e282010bSIlya Leoshkevich strlen(hex_filename) / 2);
295e282010bSIlya Leoshkevich g_byte_array_append(gdbserver_state.mem_buf, (const guint8 *)"", 1);
296e282010bSIlya Leoshkevich return (const char *)gdbserver_state.mem_buf->data;
297e282010bSIlya Leoshkevich }
298e282010bSIlya Leoshkevich
hostio_reply_with_data(const void * buf,size_t n)299e282010bSIlya Leoshkevich static void hostio_reply_with_data(const void *buf, size_t n)
300e282010bSIlya Leoshkevich {
301e282010bSIlya Leoshkevich g_string_printf(gdbserver_state.str_buf, "F%zx;", n);
302e282010bSIlya Leoshkevich gdb_memtox(gdbserver_state.str_buf, buf, n);
303e282010bSIlya Leoshkevich gdb_put_packet_binary(gdbserver_state.str_buf->str,
304e282010bSIlya Leoshkevich gdbserver_state.str_buf->len, true);
305e282010bSIlya Leoshkevich }
306e282010bSIlya Leoshkevich
gdb_handle_v_file_open(GArray * params,void * user_ctx)307e282010bSIlya Leoshkevich void gdb_handle_v_file_open(GArray *params, void *user_ctx)
308e282010bSIlya Leoshkevich {
309e282010bSIlya Leoshkevich const char *filename = get_filename_param(params, 0);
310133f202bSGustavo Romero uint64_t flags = gdb_get_cmd_param(params, 1)->val_ull;
311133f202bSGustavo Romero uint64_t mode = gdb_get_cmd_param(params, 2)->val_ull;
312e282010bSIlya Leoshkevich
313e282010bSIlya Leoshkevich #ifdef CONFIG_LINUX
314b77af26eSRichard Henderson int fd = do_guest_openat(cpu_env(gdbserver_state.g_cpu), 0, filename,
315e282010bSIlya Leoshkevich flags, mode, false);
316e282010bSIlya Leoshkevich #else
317e282010bSIlya Leoshkevich int fd = open(filename, flags, mode);
318e282010bSIlya Leoshkevich #endif
319e282010bSIlya Leoshkevich if (fd < 0) {
320*44047207SDominik 'Disconnect3d' Czarnota g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
321e282010bSIlya Leoshkevich } else {
322*44047207SDominik 'Disconnect3d' Czarnota g_string_printf(gdbserver_state.str_buf, "F%x", fd);
323e282010bSIlya Leoshkevich }
324e282010bSIlya Leoshkevich gdb_put_strbuf();
325e282010bSIlya Leoshkevich }
326e282010bSIlya Leoshkevich
gdb_handle_v_file_close(GArray * params,void * user_ctx)327e282010bSIlya Leoshkevich void gdb_handle_v_file_close(GArray *params, void *user_ctx)
328e282010bSIlya Leoshkevich {
329133f202bSGustavo Romero int fd = gdb_get_cmd_param(params, 0)->val_ul;
330e282010bSIlya Leoshkevich
331e282010bSIlya Leoshkevich if (close(fd) == -1) {
332*44047207SDominik 'Disconnect3d' Czarnota g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
333e282010bSIlya Leoshkevich gdb_put_strbuf();
334e282010bSIlya Leoshkevich return;
335e282010bSIlya Leoshkevich }
336e282010bSIlya Leoshkevich
337e282010bSIlya Leoshkevich gdb_put_packet("F00");
338e282010bSIlya Leoshkevich }
339e282010bSIlya Leoshkevich
gdb_handle_v_file_pread(GArray * params,void * user_ctx)340e282010bSIlya Leoshkevich void gdb_handle_v_file_pread(GArray *params, void *user_ctx)
341e282010bSIlya Leoshkevich {
342133f202bSGustavo Romero int fd = gdb_get_cmd_param(params, 0)->val_ul;
343133f202bSGustavo Romero size_t count = gdb_get_cmd_param(params, 1)->val_ull;
344133f202bSGustavo Romero off_t offset = gdb_get_cmd_param(params, 2)->val_ull;
345e282010bSIlya Leoshkevich
346e282010bSIlya Leoshkevich size_t bufsiz = MIN(count, BUFSIZ);
347e282010bSIlya Leoshkevich g_autofree char *buf = g_try_malloc(bufsiz);
348e282010bSIlya Leoshkevich if (buf == NULL) {
349e282010bSIlya Leoshkevich gdb_put_packet("E12");
350e282010bSIlya Leoshkevich return;
351e282010bSIlya Leoshkevich }
352e282010bSIlya Leoshkevich
353e282010bSIlya Leoshkevich ssize_t n = pread(fd, buf, bufsiz, offset);
354e282010bSIlya Leoshkevich if (n < 0) {
355*44047207SDominik 'Disconnect3d' Czarnota g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
356e282010bSIlya Leoshkevich gdb_put_strbuf();
357e282010bSIlya Leoshkevich return;
358e282010bSIlya Leoshkevich }
359e282010bSIlya Leoshkevich hostio_reply_with_data(buf, n);
360e282010bSIlya Leoshkevich }
361e282010bSIlya Leoshkevich
gdb_handle_v_file_readlink(GArray * params,void * user_ctx)362e282010bSIlya Leoshkevich void gdb_handle_v_file_readlink(GArray *params, void *user_ctx)
363e282010bSIlya Leoshkevich {
364e282010bSIlya Leoshkevich const char *filename = get_filename_param(params, 0);
365e282010bSIlya Leoshkevich
366e282010bSIlya Leoshkevich g_autofree char *buf = g_try_malloc(BUFSIZ);
367e282010bSIlya Leoshkevich if (buf == NULL) {
368e282010bSIlya Leoshkevich gdb_put_packet("E12");
369e282010bSIlya Leoshkevich return;
370e282010bSIlya Leoshkevich }
371e282010bSIlya Leoshkevich
372e282010bSIlya Leoshkevich #ifdef CONFIG_LINUX
373e282010bSIlya Leoshkevich ssize_t n = do_guest_readlink(filename, buf, BUFSIZ);
374e282010bSIlya Leoshkevich #else
375e282010bSIlya Leoshkevich ssize_t n = readlink(filename, buf, BUFSIZ);
376e282010bSIlya Leoshkevich #endif
377e282010bSIlya Leoshkevich if (n < 0) {
378*44047207SDominik 'Disconnect3d' Czarnota g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
379e282010bSIlya Leoshkevich gdb_put_strbuf();
380e282010bSIlya Leoshkevich return;
381e282010bSIlya Leoshkevich }
382e282010bSIlya Leoshkevich hostio_reply_with_data(buf, n);
383e282010bSIlya Leoshkevich }
384e282010bSIlya Leoshkevich
gdb_handle_query_xfer_exec_file(GArray * params,void * user_ctx)385e282010bSIlya Leoshkevich void gdb_handle_query_xfer_exec_file(GArray *params, void *user_ctx)
386e282010bSIlya Leoshkevich {
387133f202bSGustavo Romero uint32_t pid = gdb_get_cmd_param(params, 0)->val_ul;
388133f202bSGustavo Romero uint32_t offset = gdb_get_cmd_param(params, 1)->val_ul;
389133f202bSGustavo Romero uint32_t length = gdb_get_cmd_param(params, 2)->val_ul;
390e282010bSIlya Leoshkevich
391e282010bSIlya Leoshkevich GDBProcess *process = gdb_get_process(pid);
392e282010bSIlya Leoshkevich if (!process) {
393e282010bSIlya Leoshkevich gdb_put_packet("E00");
394e282010bSIlya Leoshkevich return;
395e282010bSIlya Leoshkevich }
396e282010bSIlya Leoshkevich
397e282010bSIlya Leoshkevich CPUState *cpu = gdb_get_first_cpu_in_process(process);
398e282010bSIlya Leoshkevich if (!cpu) {
399e282010bSIlya Leoshkevich gdb_put_packet("E00");
400e282010bSIlya Leoshkevich return;
401e282010bSIlya Leoshkevich }
402e282010bSIlya Leoshkevich
403e4e5cb4aSIlya Leoshkevich TaskState *ts = get_task_state(cpu);
404e282010bSIlya Leoshkevich if (!ts || !ts->bprm || !ts->bprm->filename) {
405e282010bSIlya Leoshkevich gdb_put_packet("E00");
406e282010bSIlya Leoshkevich return;
407e282010bSIlya Leoshkevich }
408e282010bSIlya Leoshkevich
409e282010bSIlya Leoshkevich size_t total_length = strlen(ts->bprm->filename);
410e282010bSIlya Leoshkevich if (offset > total_length) {
411e282010bSIlya Leoshkevich gdb_put_packet("E00");
412e282010bSIlya Leoshkevich return;
413e282010bSIlya Leoshkevich }
414e282010bSIlya Leoshkevich if (offset + length > total_length) {
415e282010bSIlya Leoshkevich length = total_length - offset;
416e282010bSIlya Leoshkevich }
417e282010bSIlya Leoshkevich
418e282010bSIlya Leoshkevich g_string_printf(gdbserver_state.str_buf, "l%.*s", length,
419e282010bSIlya Leoshkevich ts->bprm->filename + offset);
420e282010bSIlya Leoshkevich gdb_put_strbuf();
421e282010bSIlya Leoshkevich }
4224aad0965SIlya Leoshkevich
gdb_target_sigtrap(void)4234aad0965SIlya Leoshkevich int gdb_target_sigtrap(void)
4244aad0965SIlya Leoshkevich {
4254aad0965SIlya Leoshkevich return TARGET_SIGTRAP;
4264aad0965SIlya Leoshkevich }
427