#include "qemu.h"
#else
#include "monitor/monitor.h"
-#include "char/char.h"
+#include "sysemu/char.h"
#include "sysemu/sysemu.h"
#include "exec/gdbstub.h"
#endif
#ifdef CONFIG_USER_ONLY
s->running_state = 1;
#else
- vm_start();
+ if (runstate_check(RUN_STATE_GUEST_PANICKED)) {
+ runstate_set(RUN_STATE_DEBUG);
+ }
+ if (!runstate_needs_reset()) {
+ vm_start();
+ }
#endif
}
/* fpscr */
if (gdb_has_xml)
return 0;
- return 4;
+ store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
+ return sizeof(target_ulong);
}
}
return 0;
}
#elif defined (TARGET_LM32)
-#include "hw/lm32_pic.h"
+#include "hw/lm32/lm32_pic.h"
#define NUM_CORE_REGS (32 + 7)
static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
/* Generate the XML description for this CPU. */
if (!target_xml[0]) {
GDBRegisterState *r;
+ CPUArchState *env = first_cpu->env_ptr;
snprintf(target_xml, sizeof(target_xml),
"<?xml version=\"1.0\"?>"
"<xi:include href=\"%s\"/>",
GDB_CORE_XML);
- for (r = first_cpu->gdb_regs; r; r = r->next) {
+ for (r = env->gdb_regs; r; r = r->next) {
pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
pstrcat(target_xml, sizeof(target_xml), r->xml);
pstrcat(target_xml, sizeof(target_xml), "\"/>");
static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
{
+ CPUState *cpu;
CPUArchState *env;
int err = 0;
switch (type) {
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
- for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+ env = cpu->env_ptr;
err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
if (err)
break;
case GDB_WATCHPOINT_WRITE:
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
- for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+ env = cpu->env_ptr;
err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
NULL);
if (err)
static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
{
+ CPUState *cpu;
CPUArchState *env;
int err = 0;
switch (type) {
case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW:
- for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+ env = cpu->env_ptr;
err = cpu_breakpoint_remove(env, addr, BP_GDB);
if (err)
break;
case GDB_WATCHPOINT_WRITE:
case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS:
- for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+ env = cpu->env_ptr;
err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
if (err)
break;
static void gdb_breakpoint_remove_all(void)
{
+ CPUState *cpu;
CPUArchState *env;
if (kvm_enabled()) {
- kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
+ kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));
return;
}
- for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+ env = cpu->env_ptr;
cpu_breakpoint_remove_all(env, BP_GDB);
#ifndef CONFIG_USER_ONLY
cpu_watchpoint_remove_all(env, BP_GDB);
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
{
- cpu_synchronize_state(s->c_cpu);
+ cpu_synchronize_state(ENV_GET_CPU(s->c_cpu));
#if defined(TARGET_I386)
s->c_cpu->eip = pc;
#elif defined (TARGET_PPC)
static CPUArchState *find_cpu(uint32_t thread_id)
{
- CPUArchState *env;
+ CPUState *cpu;
- for (env = first_cpu; env != NULL; env = env->next_cpu) {
- if (cpu_index(env) == thread_id) {
- return env;
+ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+ if (cpu_index(cpu) == thread_id) {
+ return cpu->env_ptr;
}
}
case '?':
/* TODO: Make this return the correct value for user-mode. */
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
- cpu_index(s->c_cpu));
+ cpu_index(ENV_GET_CPU(s->c_cpu)));
put_packet(s, buf);
/* Remove all the breakpoints when this query is issued,
* because gdb is doing and initial connect and the state
}
break;
case 'g':
- cpu_synchronize_state(s->g_cpu);
+ cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
env = s->g_cpu;
len = 0;
for (addr = 0; addr < num_g_regs; addr++) {
put_packet(s, buf);
break;
case 'G':
- cpu_synchronize_state(s->g_cpu);
+ cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
env = s->g_cpu;
registers = mem_buf;
len = strlen(p) / 2;
put_packet(s, "QC1");
break;
} else if (strcmp(p,"fThreadInfo") == 0) {
- s->query_cpu = first_cpu;
+ s->query_cpu = first_cpu->env_ptr;
goto report_cpuinfo;
} else if (strcmp(p,"sThreadInfo") == 0) {
report_cpuinfo:
if (s->query_cpu) {
- snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
+ snprintf(buf, sizeof(buf), "m%x",
+ cpu_index(ENV_GET_CPU(s->query_cpu)));
put_packet(s, buf);
- s->query_cpu = s->query_cpu->next_cpu;
+ s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr;
} else
put_packet(s, "l");
break;
thread = strtoull(p+16, (char **)&p, 16);
env = find_cpu(thread);
if (env != NULL) {
- cpu_synchronize_state(env);
+ CPUState *cpu = ENV_GET_CPU(env);
+ cpu_synchronize_state(cpu);
len = snprintf((char *)mem_buf, sizeof(mem_buf),
- "CPU#%d [%s]", env->cpu_index,
- env->halted ? "halted " : "running");
+ "CPU#%d [%s]", cpu->cpu_index,
+ cpu->halted ? "halted " : "running");
memtohex(buf, mem_buf, len);
put_packet(s, buf);
}
return RS_IDLE;
}
-void gdb_set_stop_cpu(CPUArchState *env)
+void gdb_set_stop_cpu(CPUState *cpu)
{
+ CPUArchState *env = cpu->env_ptr;
+
gdbserver_state->c_cpu = env;
gdbserver_state->g_cpu = env;
}
{
GDBState *s = gdbserver_state;
CPUArchState *env = s->c_cpu;
+ CPUState *cpu = ENV_GET_CPU(env);
char buf[256];
const char *type;
int ret;
}
snprintf(buf, sizeof(buf),
"T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
- GDB_SIGNAL_TRAP, cpu_index(env), type,
+ GDB_SIGNAL_TRAP, cpu_index(cpu), type,
env->watchpoint_hit->vaddr);
env->watchpoint_hit = NULL;
goto send_packet;
ret = GDB_SIGNAL_UNKNOWN;
break;
}
- snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(env));
+ snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu));
send_packet:
put_packet(s, buf);
is still in the running state, which can cause packets to be dropped
and state transition 'T' packets to be sent while the syscall is still
being processed. */
- cpu_exit(s->c_cpu);
+ cpu_exit(ENV_GET_CPU(s->c_cpu));
#endif
}
GDBState *s;
struct sockaddr_in sockaddr;
socklen_t len;
- int val, fd;
+ int fd;
for(;;) {
len = sizeof(sockaddr);
}
/* set short latency */
- val = 1;
- setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
+ socket_set_nodelay(fd);
s = g_malloc0(sizeof(GDBState));
- s->c_cpu = first_cpu;
- s->g_cpu = first_cpu;
+ s->c_cpu = first_cpu->env_ptr;
+ s->g_cpu = first_cpu->env_ptr;
s->fd = fd;
gdb_has_xml = 0;
/* allow fast reuse */
val = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+ qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(port);
if (!chr)
return -1;
+ qemu_chr_fe_claim_no_fail(chr);
qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
gdb_chr_event, NULL);
}
mon_chr = s->mon_chr;
memset(s, 0, sizeof(GDBState));
}
- s->c_cpu = first_cpu;
- s->g_cpu = first_cpu;
+ s->c_cpu = first_cpu->env_ptr;
+ s->g_cpu = first_cpu->env_ptr;
s->chr = chr;
s->state = chr ? RS_IDLE : RS_INACTIVE;
s->mon_chr = mon_chr;