10
#include "qemu/osdep.h"
11
#include "exec/gdbstub.h"
12
#include "gdbstub/commands.h"
16
#include "linux-user/loader.h"
17
#include "linux-user/qemu.h"
26
static int gdb_signal_table[] = {
186
int gdb_signal_to_target(int sig)
188
if (sig < ARRAY_SIZE(gdb_signal_table)) {
189
return gdb_signal_table[sig];
195
int gdb_target_signal_to_gdb(int sig)
198
for (i = 0; i < ARRAY_SIZE(gdb_signal_table); i++) {
199
if (gdb_signal_table[i] == sig) {
203
return GDB_SIGNAL_UNKNOWN;
206
int gdb_get_cpu_index(CPUState *cpu)
208
TaskState *ts = get_task_state(cpu);
209
return ts ? ts->ts_tid : -1;
216
void gdb_handle_query_offsets(GArray *params, void *user_ctx)
220
ts = get_task_state(gdbserver_state.c_cpu);
221
g_string_printf(gdbserver_state.str_buf,
222
"Text=" TARGET_ABI_FMT_lx
223
";Data=" TARGET_ABI_FMT_lx
224
";Bss=" TARGET_ABI_FMT_lx,
225
ts->info->code_offset,
226
ts->info->data_offset,
227
ts->info->data_offset);
231
#if defined(CONFIG_LINUX)
233
static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
234
uint8_t *buf, int len, bool is_write)
237
cc = CPU_GET_CLASS(cpu);
238
if (cc->memory_rw_debug) {
239
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
241
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
244
void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx)
247
unsigned long offset, len, saved_auxv, auxv_len;
249
if (params->len < 2) {
250
gdb_put_packet("E22");
254
offset = gdb_get_cmd_param(params, 0)->val_ul;
255
len = gdb_get_cmd_param(params, 1)->val_ul;
256
ts = get_task_state(gdbserver_state.c_cpu);
257
saved_auxv = ts->info->saved_auxv;
258
auxv_len = ts->info->auxv_len;
260
if (offset >= auxv_len) {
261
gdb_put_packet("E00");
265
if (len > (MAX_PACKET_LENGTH - 5) / 2) {
266
len = (MAX_PACKET_LENGTH - 5) / 2;
269
if (len < auxv_len - offset) {
270
g_string_assign(gdbserver_state.str_buf, "m");
272
g_string_assign(gdbserver_state.str_buf, "l");
273
len = auxv_len - offset;
276
g_byte_array_set_size(gdbserver_state.mem_buf, len);
277
if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
278
gdbserver_state.mem_buf->data, len, false)) {
279
gdb_put_packet("E14");
283
gdb_memtox(gdbserver_state.str_buf,
284
(const char *)gdbserver_state.mem_buf->data, len);
285
gdb_put_packet_binary(gdbserver_state.str_buf->str,
286
gdbserver_state.str_buf->len, true);
290
static const char *get_filename_param(GArray *params, int i)
292
const char *hex_filename = gdb_get_cmd_param(params, i)->data;
293
gdb_hextomem(gdbserver_state.mem_buf, hex_filename,
294
strlen(hex_filename) / 2);
295
g_byte_array_append(gdbserver_state.mem_buf, (const guint8 *)"", 1);
296
return (const char *)gdbserver_state.mem_buf->data;
299
static void hostio_reply_with_data(const void *buf, size_t n)
301
g_string_printf(gdbserver_state.str_buf, "F%zx;", n);
302
gdb_memtox(gdbserver_state.str_buf, buf, n);
303
gdb_put_packet_binary(gdbserver_state.str_buf->str,
304
gdbserver_state.str_buf->len, true);
307
void gdb_handle_v_file_open(GArray *params, void *user_ctx)
309
const char *filename = get_filename_param(params, 0);
310
uint64_t flags = gdb_get_cmd_param(params, 1)->val_ull;
311
uint64_t mode = gdb_get_cmd_param(params, 2)->val_ull;
314
int fd = do_guest_openat(cpu_env(gdbserver_state.g_cpu), 0, filename,
317
int fd = open(filename, flags, mode);
320
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
322
g_string_printf(gdbserver_state.str_buf, "F%d", fd);
327
void gdb_handle_v_file_close(GArray *params, void *user_ctx)
329
int fd = gdb_get_cmd_param(params, 0)->val_ul;
331
if (close(fd) == -1) {
332
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
337
gdb_put_packet("F00");
340
void gdb_handle_v_file_pread(GArray *params, void *user_ctx)
342
int fd = gdb_get_cmd_param(params, 0)->val_ul;
343
size_t count = gdb_get_cmd_param(params, 1)->val_ull;
344
off_t offset = gdb_get_cmd_param(params, 2)->val_ull;
346
size_t bufsiz = MIN(count, BUFSIZ);
347
g_autofree char *buf = g_try_malloc(bufsiz);
349
gdb_put_packet("E12");
353
ssize_t n = pread(fd, buf, bufsiz, offset);
355
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
359
hostio_reply_with_data(buf, n);
362
void gdb_handle_v_file_readlink(GArray *params, void *user_ctx)
364
const char *filename = get_filename_param(params, 0);
366
g_autofree char *buf = g_try_malloc(BUFSIZ);
368
gdb_put_packet("E12");
373
ssize_t n = do_guest_readlink(filename, buf, BUFSIZ);
375
ssize_t n = readlink(filename, buf, BUFSIZ);
378
g_string_printf(gdbserver_state.str_buf, "F-1,%d", errno);
382
hostio_reply_with_data(buf, n);
385
void gdb_handle_query_xfer_exec_file(GArray *params, void *user_ctx)
387
uint32_t pid = gdb_get_cmd_param(params, 0)->val_ul;
388
uint32_t offset = gdb_get_cmd_param(params, 1)->val_ul;
389
uint32_t length = gdb_get_cmd_param(params, 2)->val_ul;
391
GDBProcess *process = gdb_get_process(pid);
393
gdb_put_packet("E00");
397
CPUState *cpu = gdb_get_first_cpu_in_process(process);
399
gdb_put_packet("E00");
403
TaskState *ts = get_task_state(cpu);
404
if (!ts || !ts->bprm || !ts->bprm->filename) {
405
gdb_put_packet("E00");
409
size_t total_length = strlen(ts->bprm->filename);
410
if (offset > total_length) {
411
gdb_put_packet("E00");
414
if (offset + length > total_length) {
415
length = total_length - offset;
418
g_string_printf(gdbserver_state.str_buf, "l%.*s", length,
419
ts->bprm->filename + offset);
423
int gdb_target_sigtrap(void)
425
return TARGET_SIGTRAP;