qemu

Форк
0
/
system.c 
665 строк · 16.1 Кб
1
/*
2
 * gdb server stub - system specific bits
3
 *
4
 * Debug integration depends on support from the individual
5
 * accelerators so most of this involves calling the ops helpers.
6
 *
7
 * Copyright (c) 2003-2005 Fabrice Bellard
8
 * Copyright (c) 2022 Linaro Ltd
9
 *
10
 * SPDX-License-Identifier: LGPL-2.0+
11
 */
12

13
#include "qemu/osdep.h"
14
#include "qapi/error.h"
15
#include "qemu/error-report.h"
16
#include "qemu/cutils.h"
17
#include "exec/gdbstub.h"
18
#include "gdbstub/syscalls.h"
19
#include "gdbstub/commands.h"
20
#include "exec/hwaddr.h"
21
#include "exec/tb-flush.h"
22
#include "sysemu/cpus.h"
23
#include "sysemu/runstate.h"
24
#include "sysemu/replay.h"
25
#include "hw/core/cpu.h"
26
#include "hw/cpu/cluster.h"
27
#include "hw/boards.h"
28
#include "chardev/char.h"
29
#include "chardev/char-fe.h"
30
#include "monitor/monitor.h"
31
#include "trace.h"
32
#include "internals.h"
33

34
/* System emulation specific state */
35
typedef struct {
36
    CharBackend chr;
37
    Chardev *mon_chr;
38
} GDBSystemState;
39

40
GDBSystemState gdbserver_system_state;
41

42
static void reset_gdbserver_state(void)
43
{
44
    g_free(gdbserver_state.processes);
45
    gdbserver_state.processes = NULL;
46
    gdbserver_state.process_num = 0;
47
    gdbserver_state.allow_stop_reply = false;
48
}
49

50
/*
51
 * Return the GDB index for a given vCPU state.
52
 *
53
 * In system mode GDB numbers CPUs from 1 as 0 is reserved as an "any
54
 * cpu" index.
55
 */
56
int gdb_get_cpu_index(CPUState *cpu)
57
{
58
    return cpu->cpu_index + 1;
59
}
60

61
/*
62
 * We check the status of the last message in the chardev receive code
63
 */
64
bool gdb_got_immediate_ack(void)
65
{
66
    return true;
67
}
68

69
/*
70
 * GDB Connection management. For system emulation we do all of this
71
 * via our existing Chardev infrastructure which allows us to support
72
 * network and unix sockets.
73
 */
74

75
void gdb_put_buffer(const uint8_t *buf, int len)
76
{
77
    /*
78
     * XXX this blocks entire thread. Rewrite to use
79
     * qemu_chr_fe_write and background I/O callbacks
80
     */
81
    qemu_chr_fe_write_all(&gdbserver_system_state.chr, buf, len);
82
}
83

84
static void gdb_chr_event(void *opaque, QEMUChrEvent event)
85
{
86
    int i;
87
    GDBState *s = (GDBState *) opaque;
88

89
    switch (event) {
90
    case CHR_EVENT_OPENED:
91
        /* Start with first process attached, others detached */
92
        for (i = 0; i < s->process_num; i++) {
93
            s->processes[i].attached = !i;
94
        }
95

96
        s->c_cpu = gdb_first_attached_cpu();
97
        s->g_cpu = s->c_cpu;
98

99
        vm_stop(RUN_STATE_PAUSED);
100
        replay_gdb_attached();
101
        break;
102
    default:
103
        break;
104
    }
105
}
106

107
/*
108
 * In system-mode we stop the VM and wait to send the syscall packet
109
 * until notification that the CPU has stopped. This must be done
110
 * because if the packet is sent now the reply from the syscall
111
 * request could be received while the CPU is still in the running
112
 * state, which can cause packets to be dropped and state transition
113
 * 'T' packets to be sent while the syscall is still being processed.
114
 */
115
void gdb_syscall_handling(const char *syscall_packet)
116
{
117
    vm_stop(RUN_STATE_DEBUG);
118
    qemu_cpu_kick(gdbserver_state.c_cpu);
119
}
120

121
static void gdb_vm_state_change(void *opaque, bool running, RunState state)
122
{
123
    CPUState *cpu = gdbserver_state.c_cpu;
124
    g_autoptr(GString) buf = g_string_new(NULL);
125
    g_autoptr(GString) tid = g_string_new(NULL);
126
    const char *type;
127
    int ret;
128

129
    if (running || gdbserver_state.state == RS_INACTIVE) {
130
        return;
131
    }
132

133
    /* Is there a GDB syscall waiting to be sent?  */
134
    if (gdb_handled_syscall()) {
135
        return;
136
    }
137

138
    if (cpu == NULL) {
139
        /* No process attached */
140
        return;
141
    }
142

143
    if (!gdbserver_state.allow_stop_reply) {
144
        return;
145
    }
146

147
    gdb_append_thread_id(cpu, tid);
148

149
    switch (state) {
150
    case RUN_STATE_DEBUG:
151
        if (cpu->watchpoint_hit) {
152
            switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
153
            case BP_MEM_READ:
154
                type = "r";
155
                break;
156
            case BP_MEM_ACCESS:
157
                type = "a";
158
                break;
159
            default:
160
                type = "";
161
                break;
162
            }
163
            trace_gdbstub_hit_watchpoint(type,
164
                                         gdb_get_cpu_index(cpu),
165
                                         cpu->watchpoint_hit->vaddr);
166
            g_string_printf(buf, "T%02xthread:%s;%swatch:%" VADDR_PRIx ";",
167
                            GDB_SIGNAL_TRAP, tid->str, type,
168
                            cpu->watchpoint_hit->vaddr);
169
            cpu->watchpoint_hit = NULL;
170
            goto send_packet;
171
        } else {
172
            trace_gdbstub_hit_break();
173
        }
174
        tb_flush(cpu);
175
        ret = GDB_SIGNAL_TRAP;
176
        break;
177
    case RUN_STATE_PAUSED:
178
        trace_gdbstub_hit_paused();
179
        ret = GDB_SIGNAL_INT;
180
        break;
181
    case RUN_STATE_SHUTDOWN:
182
        trace_gdbstub_hit_shutdown();
183
        ret = GDB_SIGNAL_QUIT;
184
        break;
185
    case RUN_STATE_IO_ERROR:
186
        trace_gdbstub_hit_io_error();
187
        ret = GDB_SIGNAL_STOP;
188
        break;
189
    case RUN_STATE_WATCHDOG:
190
        trace_gdbstub_hit_watchdog();
191
        ret = GDB_SIGNAL_ALRM;
192
        break;
193
    case RUN_STATE_INTERNAL_ERROR:
194
        trace_gdbstub_hit_internal_error();
195
        ret = GDB_SIGNAL_ABRT;
196
        break;
197
    case RUN_STATE_SAVE_VM:
198
    case RUN_STATE_RESTORE_VM:
199
        return;
200
    case RUN_STATE_FINISH_MIGRATE:
201
        ret = GDB_SIGNAL_XCPU;
202
        break;
203
    default:
204
        trace_gdbstub_hit_unknown(state);
205
        ret = GDB_SIGNAL_UNKNOWN;
206
        break;
207
    }
208
    gdb_set_stop_cpu(cpu);
209
    g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
210

211
send_packet:
212
    gdb_put_packet(buf->str);
213
    gdbserver_state.allow_stop_reply = false;
214

215
    /* disable single step if it was enabled */
216
    cpu_single_step(cpu, 0);
217
}
218

219
#ifndef _WIN32
220
static void gdb_sigterm_handler(int signal)
221
{
222
    if (runstate_is_running()) {
223
        vm_stop(RUN_STATE_PAUSED);
224
    }
225
}
226
#endif
227

228
static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
229
{
230
    g_autoptr(GString) hex_buf = g_string_new("O");
231
    gdb_memtohex(hex_buf, buf, len);
232
    gdb_put_packet(hex_buf->str);
233
    return len;
234
}
235

236
static void gdb_monitor_open(Chardev *chr, ChardevBackend *backend,
237
                             bool *be_opened, Error **errp)
238
{
239
    *be_opened = false;
240
}
241

242
static void char_gdb_class_init(ObjectClass *oc, void *data)
243
{
244
    ChardevClass *cc = CHARDEV_CLASS(oc);
245

246
    cc->internal = true;
247
    cc->open = gdb_monitor_open;
248
    cc->chr_write = gdb_monitor_write;
249
}
250

251
#define TYPE_CHARDEV_GDB "chardev-gdb"
252

253
static const TypeInfo char_gdb_type_info = {
254
    .name = TYPE_CHARDEV_GDB,
255
    .parent = TYPE_CHARDEV,
256
    .class_init = char_gdb_class_init,
257
};
258

259
static int gdb_chr_can_receive(void *opaque)
260
{
261
  /*
262
   * We can handle an arbitrarily large amount of data.
263
   * Pick the maximum packet size, which is as good as anything.
264
   */
265
  return MAX_PACKET_LENGTH;
266
}
267

268
static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
269
{
270
    int i;
271

272
    for (i = 0; i < size; i++) {
273
        gdb_read_byte(buf[i]);
274
    }
275
}
276

277
static int find_cpu_clusters(Object *child, void *opaque)
278
{
279
    if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
280
        GDBState *s = (GDBState *) opaque;
281
        CPUClusterState *cluster = CPU_CLUSTER(child);
282
        GDBProcess *process;
283

284
        s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
285

286
        process = &s->processes[s->process_num - 1];
287

288
        /*
289
         * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
290
         * runtime, we enforce here that the machine does not use a cluster ID
291
         * that would lead to PID 0.
292
         */
293
        assert(cluster->cluster_id != UINT32_MAX);
294
        process->pid = cluster->cluster_id + 1;
295
        process->attached = false;
296
        process->target_xml = NULL;
297

298
        return 0;
299
    }
300

301
    return object_child_foreach(child, find_cpu_clusters, opaque);
302
}
303

304
static int pid_order(const void *a, const void *b)
305
{
306
    GDBProcess *pa = (GDBProcess *) a;
307
    GDBProcess *pb = (GDBProcess *) b;
308

309
    if (pa->pid < pb->pid) {
310
        return -1;
311
    } else if (pa->pid > pb->pid) {
312
        return 1;
313
    } else {
314
        return 0;
315
    }
316
}
317

318
static void create_processes(GDBState *s)
319
{
320
    object_child_foreach(object_get_root(), find_cpu_clusters, s);
321

322
    if (gdbserver_state.processes) {
323
        /* Sort by PID */
324
        qsort(gdbserver_state.processes,
325
              gdbserver_state.process_num,
326
              sizeof(gdbserver_state.processes[0]),
327
              pid_order);
328
    }
329

330
    gdb_create_default_process(s);
331
}
332

333
int gdbserver_start(const char *device)
334
{
335
    Chardev *chr = NULL;
336
    Chardev *mon_chr;
337
    g_autoptr(GString) cs = g_string_new(device);
338

339
    if (!first_cpu) {
340
        error_report("gdbstub: meaningless to attach gdb to a "
341
                     "machine without any CPU.");
342
        return -1;
343
    }
344

345
    if (!gdb_supports_guest_debug()) {
346
        error_report("gdbstub: current accelerator doesn't "
347
                     "support guest debugging");
348
        return -1;
349
    }
350

351
    if (cs->len == 0) {
352
        return -1;
353
    }
354

355
    trace_gdbstub_op_start(cs->str);
356

357
    if (g_strcmp0(cs->str, "none") != 0) {
358
        if (g_str_has_prefix(cs->str, "tcp:")) {
359
            /* enforce required TCP attributes */
360
            g_string_append_printf(cs, ",wait=off,nodelay=on,server=on");
361
        }
362
#ifndef _WIN32
363
        else if (strcmp(device, "stdio") == 0) {
364
            struct sigaction act;
365

366
            memset(&act, 0, sizeof(act));
367
            act.sa_handler = gdb_sigterm_handler;
368
            sigaction(SIGINT, &act, NULL);
369
        }
370
#endif
371
        /*
372
         * FIXME: it's a bit weird to allow using a mux chardev here
373
         * and implicitly setup a monitor. We may want to break this.
374
         */
375
        chr = qemu_chr_new_noreplay("gdb", cs->str, true, NULL);
376
        if (!chr) {
377
            return -1;
378
        }
379
    }
380

381
    if (!gdbserver_state.init) {
382
        gdb_init_gdbserver_state();
383

384
        qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
385

386
        /* Initialize a monitor terminal for gdb */
387
        mon_chr = qemu_chardev_new(NULL, TYPE_CHARDEV_GDB,
388
                                   NULL, NULL, &error_abort);
389
        monitor_init_hmp(mon_chr, false, &error_abort);
390
    } else {
391
        qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
392
        mon_chr = gdbserver_system_state.mon_chr;
393
        reset_gdbserver_state();
394
    }
395

396
    create_processes(&gdbserver_state);
397

398
    if (chr) {
399
        qemu_chr_fe_init(&gdbserver_system_state.chr, chr, &error_abort);
400
        qemu_chr_fe_set_handlers(&gdbserver_system_state.chr,
401
                                 gdb_chr_can_receive,
402
                                 gdb_chr_receive, gdb_chr_event,
403
                                 NULL, &gdbserver_state, NULL, true);
404
    }
405
    gdbserver_state.state = chr ? RS_IDLE : RS_INACTIVE;
406
    gdbserver_system_state.mon_chr = mon_chr;
407
    gdb_syscall_reset();
408

409
    return 0;
410
}
411

412
static void register_types(void)
413
{
414
    type_register_static(&char_gdb_type_info);
415
}
416

417
type_init(register_types);
418

419
/* Tell the remote gdb that the process has exited.  */
420
void gdb_exit(int code)
421
{
422
    char buf[4];
423

424
    if (!gdbserver_state.init) {
425
        return;
426
    }
427

428
    trace_gdbstub_op_exiting((uint8_t)code);
429

430
    if (gdbserver_state.allow_stop_reply) {
431
        snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code);
432
        gdb_put_packet(buf);
433
        gdbserver_state.allow_stop_reply = false;
434
    }
435

436
    qemu_chr_fe_deinit(&gdbserver_system_state.chr, true);
437
}
438

439
void gdb_qemu_exit(int code)
440
{
441
    qemu_system_shutdown_request_with_code(SHUTDOWN_CAUSE_GUEST_SHUTDOWN,
442
                                           code);
443
}
444

445
/*
446
 * Memory access
447
 */
448
static int phy_memory_mode;
449

450
int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr,
451
                               uint8_t *buf, int len, bool is_write)
452
{
453
    CPUClass *cc;
454

455
    if (phy_memory_mode) {
456
        if (is_write) {
457
            cpu_physical_memory_write(addr, buf, len);
458
        } else {
459
            cpu_physical_memory_read(addr, buf, len);
460
        }
461
        return 0;
462
    }
463

464
    cc = CPU_GET_CLASS(cpu);
465
    if (cc->memory_rw_debug) {
466
        return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
467
    }
468

469
    return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
470
}
471

472
/*
473
 * cpu helpers
474
 */
475

476
unsigned int gdb_get_max_cpus(void)
477
{
478
    MachineState *ms = MACHINE(qdev_get_machine());
479
    return ms->smp.max_cpus;
480
}
481

482
bool gdb_can_reverse(void)
483
{
484
    return replay_mode == REPLAY_MODE_PLAY;
485
}
486

487
/*
488
 * Softmmu specific command helpers
489
 */
490

491
void gdb_handle_query_qemu_phy_mem_mode(GArray *params,
492
                                        void *ctx)
493
{
494
    g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
495
    gdb_put_strbuf();
496
}
497

498
void gdb_handle_set_qemu_phy_mem_mode(GArray *params, void *ctx)
499
{
500
    if (!params->len) {
501
        gdb_put_packet("E22");
502
        return;
503
    }
504

505
    if (!gdb_get_cmd_param(params, 0)->val_ul) {
506
        phy_memory_mode = 0;
507
    } else {
508
        phy_memory_mode = 1;
509
    }
510
    gdb_put_packet("OK");
511
}
512

513
void gdb_handle_query_rcmd(GArray *params, void *ctx)
514
{
515
    const guint8 zero = 0;
516
    int len;
517

518
    if (!params->len) {
519
        gdb_put_packet("E22");
520
        return;
521
    }
522

523
    len = strlen(gdb_get_cmd_param(params, 0)->data);
524
    if (len % 2) {
525
        gdb_put_packet("E01");
526
        return;
527
    }
528

529
    g_assert(gdbserver_state.mem_buf->len == 0);
530
    len = len / 2;
531
    gdb_hextomem(gdbserver_state.mem_buf, gdb_get_cmd_param(params, 0)->data, len);
532
    g_byte_array_append(gdbserver_state.mem_buf, &zero, 1);
533
    qemu_chr_be_write(gdbserver_system_state.mon_chr,
534
                      gdbserver_state.mem_buf->data,
535
                      gdbserver_state.mem_buf->len);
536
    gdb_put_packet("OK");
537
}
538

539
/*
540
 * Execution state helpers
541
 */
542

543
void gdb_handle_query_attached(GArray *params, void *ctx)
544
{
545
    gdb_put_packet("1");
546
}
547

548
void gdb_continue(void)
549
{
550
    if (!runstate_needs_reset()) {
551
        trace_gdbstub_op_continue();
552
        vm_start();
553
    }
554
}
555

556
/*
557
 * Resume execution, per CPU actions.
558
 */
559
int gdb_continue_partial(char *newstates)
560
{
561
    CPUState *cpu;
562
    int res = 0;
563
    int flag = 0;
564

565
    if (!runstate_needs_reset()) {
566
        bool step_requested = false;
567
        CPU_FOREACH(cpu) {
568
            if (newstates[cpu->cpu_index] == 's') {
569
                step_requested = true;
570
                break;
571
            }
572
        }
573

574
        if (vm_prepare_start(step_requested)) {
575
            return 0;
576
        }
577

578
        CPU_FOREACH(cpu) {
579
            switch (newstates[cpu->cpu_index]) {
580
            case 0:
581
            case 1:
582
                break; /* nothing to do here */
583
            case 's':
584
                trace_gdbstub_op_stepping(cpu->cpu_index);
585
                cpu_single_step(cpu, gdbserver_state.sstep_flags);
586
                cpu_resume(cpu);
587
                flag = 1;
588
                break;
589
            case 'c':
590
                trace_gdbstub_op_continue_cpu(cpu->cpu_index);
591
                cpu_resume(cpu);
592
                flag = 1;
593
                break;
594
            default:
595
                res = -1;
596
                break;
597
            }
598
        }
599
    }
600
    if (flag) {
601
        qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
602
    }
603
    return res;
604
}
605

606
/*
607
 * Signal Handling - in system mode we only need SIGINT and SIGTRAP; other
608
 * signals are not yet supported.
609
 */
610

611
enum {
612
    TARGET_SIGINT = 2,
613
    TARGET_SIGTRAP = 5
614
};
615

616
int gdb_signal_to_target(int sig)
617
{
618
    switch (sig) {
619
    case 2:
620
        return TARGET_SIGINT;
621
    case 5:
622
        return TARGET_SIGTRAP;
623
    default:
624
        return -1;
625
    }
626
}
627

628
/*
629
 * Break/Watch point helpers
630
 */
631

632
bool gdb_supports_guest_debug(void)
633
{
634
    const AccelOpsClass *ops = cpus_get_accel();
635
    if (ops->supports_guest_debug) {
636
        return ops->supports_guest_debug();
637
    }
638
    return false;
639
}
640

641
int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
642
{
643
    const AccelOpsClass *ops = cpus_get_accel();
644
    if (ops->insert_breakpoint) {
645
        return ops->insert_breakpoint(cs, type, addr, len);
646
    }
647
    return -ENOSYS;
648
}
649

650
int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len)
651
{
652
    const AccelOpsClass *ops = cpus_get_accel();
653
    if (ops->remove_breakpoint) {
654
        return ops->remove_breakpoint(cs, type, addr, len);
655
    }
656
    return -ENOSYS;
657
}
658

659
void gdb_breakpoint_remove_all(CPUState *cs)
660
{
661
    const AccelOpsClass *ops = cpus_get_accel();
662
    if (ops->remove_all_breakpoints) {
663
        ops->remove_all_breakpoints(cs);
664
    }
665
}
666

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.