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);