2 * Target specific user-mode handling
4 * Copyright (c) 2003-2005 Fabrice Bellard
5 * Copyright (c) 2022 Linaro Ltd
7 * SPDX-License-Identifier: LGPL-2.0+
10 #include "qemu/osdep.h"
11 #include "exec/gdbstub.h"
13 #include "internals.h"
16 * Map target signal numbers to GDB protocol signal numbers and vice
17 * versa. For user emulation's currently supported systems, we can
18 * assume most signals are defined.
21 static int gdb_signal_table[] = {
181 int gdb_signal_to_target(int sig)
183 if (sig < ARRAY_SIZE(gdb_signal_table)) {
184 return gdb_signal_table[sig];
190 int gdb_target_signal_to_gdb(int sig)
193 for (i = 0; i < ARRAY_SIZE(gdb_signal_table); i++) {
194 if (gdb_signal_table[i] == sig) {
198 return GDB_SIGNAL_UNKNOWN;
201 int gdb_get_cpu_index(CPUState *cpu)
203 TaskState *ts = (TaskState *) cpu->opaque;
204 return ts ? ts->ts_tid : -1;
208 * User-mode specific command helpers
211 void gdb_handle_query_offsets(GArray *params, void *user_ctx)
215 ts = gdbserver_state.c_cpu->opaque;
216 g_string_printf(gdbserver_state.str_buf,
217 "Text=" TARGET_ABI_FMT_lx
218 ";Data=" TARGET_ABI_FMT_lx
219 ";Bss=" TARGET_ABI_FMT_lx,
220 ts->info->code_offset,
221 ts->info->data_offset,
222 ts->info->data_offset);
226 #if defined(CONFIG_LINUX)
227 /* Partial user only duplicate of helper in gdbstub.c */
228 static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
229 uint8_t *buf, int len, bool is_write)
232 cc = CPU_GET_CLASS(cpu);
233 if (cc->memory_rw_debug) {
234 return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
236 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
239 void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx)
242 unsigned long offset, len, saved_auxv, auxv_len;
244 if (params->len < 2) {
245 gdb_put_packet("E22");
249 offset = get_param(params, 0)->val_ul;
250 len = get_param(params, 1)->val_ul;
251 ts = gdbserver_state.c_cpu->opaque;
252 saved_auxv = ts->info->saved_auxv;
253 auxv_len = ts->info->auxv_len;
255 if (offset >= auxv_len) {
256 gdb_put_packet("E00");
260 if (len > (MAX_PACKET_LENGTH - 5) / 2) {
261 len = (MAX_PACKET_LENGTH - 5) / 2;
264 if (len < auxv_len - offset) {
265 g_string_assign(gdbserver_state.str_buf, "m");
267 g_string_assign(gdbserver_state.str_buf, "l");
268 len = auxv_len - offset;
271 g_byte_array_set_size(gdbserver_state.mem_buf, len);
272 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
273 gdbserver_state.mem_buf->data, len, false)) {
274 gdb_put_packet("E14");
278 gdb_memtox(gdbserver_state.str_buf,
279 (const char *)gdbserver_state.mem_buf->data, len);
280 gdb_put_packet_binary(gdbserver_state.str_buf->str,
281 gdbserver_state.str_buf->len, true);