Commit 35143f01 authored by Andreas Färber's avatar Andreas Färber
Browse files

gdbstub: Fix gdb_register_coprocessor() register counting



Commit a0e372f0 reorganized the register
counting for GDB. While it seems correct not to let the total number of
registers skyrocket in an SMP scenario through a static variable, the
distinction between total register count and 'g' packet register count
(last_reg vs. num_g_regs) got lost among the way.

Fix this by introducing CPUState::gdb_num_g_regs and using that in
gdb_handle_packet().

Reported-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: qemu-stable@nongnu.org (stable-1.6)
Tested-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Tested-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
Tested-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarAndreas Färber <afaerber@suse.de>
parent f2020398
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -621,6 +621,8 @@ void gdb_register_coprocessor(CPUState *cpu,
        if (g_pos != s->base_reg) {
            fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
                    "Expected %d got %d\n", xml, g_pos, s->base_reg);
        } else {
            cpu->gdb_num_g_regs = cpu->gdb_num_regs;
        }
    }
}
@@ -902,7 +904,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
    case 'g':
        cpu_synchronize_state(s->g_cpu);
        len = 0;
        for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) {
        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs; addr++) {
            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
            len += reg_size;
        }
@@ -914,7 +916,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
        registers = mem_buf;
        len = strlen(p) / 2;
        hextomem((uint8_t *)registers, p, len);
        for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) {
        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs && len > 0; addr++) {
            reg_size = gdb_write_register(s->g_cpu, registers, addr);
            len -= reg_size;
            registers += reg_size;
+2 −0
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@ struct kvm_run;
 * @current_tb: Currently executing TB.
 * @gdb_regs: Additional GDB registers.
 * @gdb_num_regs: Number of total registers accessible to GDB.
 * @gdb_num_g_regs: Number of registers in GDB 'g' packets.
 * @next_cpu: Next CPU sharing TB cache.
 * @kvm_fd: vCPU file descriptor for KVM.
 *
@@ -188,6 +189,7 @@ struct CPUState {
    struct TranslationBlock *current_tb;
    struct GDBRegisterState *gdb_regs;
    int gdb_num_regs;
    int gdb_num_g_regs;
    CPUState *next_cpu;

    int kvm_fd;
+1 −1
Original line number Diff line number Diff line
@@ -240,7 +240,7 @@ static void cpu_common_initfn(Object *obj)
    CPUState *cpu = CPU(obj);
    CPUClass *cc = CPU_GET_CLASS(obj);

    cpu->gdb_num_regs = cc->gdb_num_core_regs;
    cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
}

static int64_t cpu_common_get_arch_id(CPUState *cpu)