#include "sysemu/kvm.h"
#include "qemu/bitops.h"
-#ifndef TARGET_CPU_MEMORY_RW_DEBUG
-static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr,
- uint8_t *buf, int len, int is_write)
+static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
+ uint8_t *buf, int len, bool is_write)
{
- return cpu_memory_rw_debug(env, addr, buf, len, is_write);
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (cc->memory_rw_debug) {
+ return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
+ }
+ return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
}
-#else
-/* target_memory_rw_debug() defined in cpu.h */
-#endif
enum {
GDB_SIGNAL_0 = 0,
RS_CHKSUM2,
};
typedef struct GDBState {
- CPUArchState *c_cpu; /* current CPU for step/continue ops */
- CPUArchState *g_cpu; /* current CPU for other ops */
+ CPUState *c_cpu; /* current CPU for step/continue ops */
+ CPUState *g_cpu; /* current CPU for other ops */
CPUState *query_cpu; /* for q{f|s}ThreadInfo */
enum RSState state; /* parsing state */
char line_buf[MAX_PACKET_LENGTH];
/* Generate the XML description for this CPU. */
if (!target_xml[0]) {
GDBRegisterState *r;
- CPUArchState *env = first_cpu->env_ptr;
+ CPUState *cpu = first_cpu;
snprintf(target_xml, sizeof(target_xml),
"<?xml version=\"1.0\"?>"
"<xi:include href=\"%s\"/>",
GDB_CORE_XML);
- for (r = env->gdb_regs; r; r = r->next) {
+ for (r = cpu->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), "\"/>");
}
#endif
-static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg)
+static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
{
+ CPUArchState *env = cpu->env_ptr;
GDBRegisterState *r;
if (reg < NUM_CORE_REGS)
return cpu_gdb_read_register(env, mem_buf, reg);
- for (r = env->gdb_regs; r; r = r->next) {
+ for (r = cpu->gdb_regs; r; r = r->next) {
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
return r->get_reg(env, mem_buf, reg - r->base_reg);
}
return 0;
}
-static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg)
+static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
{
+ CPUArchState *env = cpu->env_ptr;
GDBRegisterState *r;
if (reg < NUM_CORE_REGS)
return cpu_gdb_write_register(env, mem_buf, reg);
- for (r = env->gdb_regs; r; r = r->next) {
+ for (r = cpu->gdb_regs; r; r = r->next) {
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
return r->set_reg(env, mem_buf, reg - r->base_reg);
}
gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
*/
-void gdb_register_coprocessor(CPUArchState * env,
- gdb_reg_cb get_reg, gdb_reg_cb set_reg,
- int num_regs, const char *xml, int g_pos)
+void gdb_register_coprocessor(CPUState *cpu,
+ gdb_reg_cb get_reg, gdb_reg_cb set_reg,
+ int num_regs, const char *xml, int g_pos)
{
GDBRegisterState *s;
GDBRegisterState **p;
static int last_reg = NUM_CORE_REGS;
- p = &env->gdb_regs;
+ p = &cpu->gdb_regs;
while (*p) {
/* Check for duplicates. */
if (strcmp((*p)->xml, xml) == 0)
CPUArchState *env;
int err = 0;
- if (kvm_enabled())
+ if (kvm_enabled()) {
return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+ }
switch (type) {
case GDB_BREAKPOINT_SW:
CPUArchState *env;
int err = 0;
- if (kvm_enabled())
+ if (kvm_enabled()) {
return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+ }
switch (type) {
case GDB_BREAKPOINT_SW:
CPUArchState *env;
if (kvm_enabled()) {
- kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));
+ kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
return;
}
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
{
- CPUState *cpu = ENV_GET_CPU(s->c_cpu);
+ CPUState *cpu = s->c_cpu;
CPUClass *cc = CPU_GET_CLASS(cpu);
cpu_synchronize_state(cpu);
}
}
-static CPUArchState *find_cpu(uint32_t thread_id)
+static CPUState *find_cpu(uint32_t thread_id)
{
CPUState *cpu;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
if (cpu_index(cpu) == thread_id) {
- return cpu->env_ptr;
+ return cpu;
}
}
static int gdb_handle_packet(GDBState *s, const char *line_buf)
{
+#ifdef TARGET_XTENSA
CPUArchState *env;
+#endif
+ CPUState *cpu;
const char *p;
uint32_t thread;
int ch, reg_size, type, res;
case '?':
/* TODO: Make this return the correct value for user-mode. */
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
- cpu_index(ENV_GET_CPU(s->c_cpu)));
+ cpu_index(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
}
if (res) {
if (res_thread != -1 && res_thread != 0) {
- env = find_cpu(res_thread);
- if (env == NULL) {
+ cpu = find_cpu(res_thread);
+ if (cpu == NULL) {
put_packet(s, "E22");
break;
}
- s->c_cpu = env;
+ s->c_cpu = cpu;
}
if (res == 's') {
cpu_single_step(s->c_cpu, sstep_flags);
}
break;
case 'g':
- cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
- env = s->g_cpu;
+ cpu_synchronize_state(s->g_cpu);
+#ifdef TARGET_XTENSA
+ env = s->g_cpu->env_ptr;
+#endif
len = 0;
for (addr = 0; addr < num_g_regs; addr++) {
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
put_packet(s, buf);
break;
case 'G':
- cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
- env = s->g_cpu;
+ cpu_synchronize_state(s->g_cpu);
+#ifdef TARGET_XTENSA
+ env = s->g_cpu->env_ptr;
+#endif
registers = mem_buf;
len = strlen(p) / 2;
hextomem((uint8_t *)registers, p, len);
if (*p == ',')
p++;
len = strtoull(p, NULL, 16);
- if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
+ if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) {
put_packet (s, "E14");
} else {
memtohex(buf, mem_buf, len);
if (*p == ':')
p++;
hextomem(mem_buf, p, len);
- if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) {
+ if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
+ true) != 0) {
put_packet(s, "E14");
} else {
put_packet(s, "OK");
put_packet(s, "OK");
break;
}
- env = find_cpu(thread);
- if (env == NULL) {
+ cpu = find_cpu(thread);
+ if (cpu == NULL) {
put_packet(s, "E22");
break;
}
switch (type) {
case 'c':
- s->c_cpu = env;
+ s->c_cpu = cpu;
put_packet(s, "OK");
break;
case 'g':
- s->g_cpu = env;
+ s->g_cpu = cpu;
put_packet(s, "OK");
break;
default:
break;
case 'T':
thread = strtoull(p, (char **)&p, 16);
- env = find_cpu(thread);
+ cpu = find_cpu(thread);
- if (env != NULL) {
+ if (cpu != NULL) {
put_packet(s, "OK");
} else {
put_packet(s, "E22");
break;
} else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
thread = strtoull(p+16, (char **)&p, 16);
- env = find_cpu(thread);
- if (env != NULL) {
- CPUState *cpu = ENV_GET_CPU(env);
+ cpu = find_cpu(thread);
+ if (cpu != NULL) {
cpu_synchronize_state(cpu);
len = snprintf((char *)mem_buf, sizeof(mem_buf),
"CPU#%d [%s]", cpu->cpu_index,
}
#ifdef CONFIG_USER_ONLY
else if (strncmp(p, "Offsets", 7) == 0) {
- TaskState *ts = s->c_cpu->opaque;
+ CPUArchState *env = s->c_cpu->env_ptr;
+ TaskState *ts = env->opaque;
snprintf(buf, sizeof(buf),
"Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
void gdb_set_stop_cpu(CPUState *cpu)
{
- CPUArchState *env = cpu->env_ptr;
-
- gdbserver_state->c_cpu = env;
- gdbserver_state->g_cpu = env;
+ gdbserver_state->c_cpu = cpu;
+ gdbserver_state->g_cpu = cpu;
}
#ifndef CONFIG_USER_ONLY
static void gdb_vm_state_change(void *opaque, int running, RunState state)
{
GDBState *s = gdbserver_state;
- CPUArchState *env = s->c_cpu;
- CPUState *cpu = ENV_GET_CPU(env);
+ CPUArchState *env = s->c_cpu->env_ptr;
+ CPUState *cpu = s->c_cpu;
char buf[256];
const char *type;
int ret;
put_packet(s, buf);
/* disable single step if it was enabled */
- cpu_single_step(env, 0);
+ cpu_single_step(cpu, 0);
}
#endif
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(ENV_GET_CPU(s->c_cpu));
+ cpu_exit(s->c_cpu);
#endif
}
}
int
-gdb_handlesig (CPUArchState *env, int sig)
+gdb_handlesig(CPUState *cpu, int sig)
{
- GDBState *s;
- char buf[256];
- int n;
+ CPUArchState *env = cpu->env_ptr;
+ GDBState *s;
+ char buf[256];
+ int n;
- s = gdbserver_state;
- if (gdbserver_fd < 0 || s->fd < 0)
- return sig;
+ s = gdbserver_state;
+ if (gdbserver_fd < 0 || s->fd < 0) {
+ return sig;
+ }
- /* disable single step if it was enabled */
- cpu_single_step(env, 0);
- tb_flush(env);
+ /* disable single step if it was enabled */
+ cpu_single_step(cpu, 0);
+ tb_flush(env);
- if (sig != 0)
- {
- snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig));
- put_packet(s, buf);
- }
- /* put_packet() might have detected that the peer terminated the
- connection. */
- if (s->fd < 0)
- return sig;
-
- sig = 0;
- s->state = RS_IDLE;
- s->running_state = 0;
- while (s->running_state == 0) {
- n = read (s->fd, buf, 256);
- if (n > 0)
- {
- int i;
+ if (sig != 0) {
+ snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig));
+ put_packet(s, buf);
+ }
+ /* put_packet() might have detected that the peer terminated the
+ connection. */
+ if (s->fd < 0) {
+ return sig;
+ }
- for (i = 0; i < n; i++)
- gdb_read_byte (s, buf[i]);
- }
- else if (n == 0 || errno != EAGAIN)
- {
- /* XXX: Connection closed. Should probably wait for another
- connection before continuing. */
- return sig;
+ sig = 0;
+ s->state = RS_IDLE;
+ s->running_state = 0;
+ while (s->running_state == 0) {
+ n = read(s->fd, buf, 256);
+ if (n > 0) {
+ int i;
+
+ for (i = 0; i < n; i++) {
+ gdb_read_byte(s, buf[i]);
+ }
+ } else if (n == 0 || errno != EAGAIN) {
+ /* XXX: Connection closed. Should probably wait for another
+ connection before continuing. */
+ return sig;
}
- }
- sig = s->signal;
- s->signal = 0;
- return sig;
+ }
+ sig = s->signal;
+ s->signal = 0;
+ return sig;
}
/* Tell the remote gdb that the process has exited due to SIG. */
void gdb_signalled(CPUArchState *env, int sig)
{
- GDBState *s;
- char buf[4];
+ GDBState *s;
+ char buf[4];
- s = gdbserver_state;
- if (gdbserver_fd < 0 || s->fd < 0)
- return;
+ s = gdbserver_state;
+ if (gdbserver_fd < 0 || s->fd < 0) {
+ return;
+ }
- snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
- put_packet(s, buf);
+ snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
+ put_packet(s, buf);
}
static void gdb_accept(void)
socket_set_nodelay(fd);
s = g_malloc0(sizeof(GDBState));
- s->c_cpu = first_cpu->env_ptr;
- s->g_cpu = first_cpu->env_ptr;
+ s->c_cpu = first_cpu;
+ s->g_cpu = first_cpu;
s->fd = fd;
gdb_has_xml = 0;
mon_chr = s->mon_chr;
memset(s, 0, sizeof(GDBState));
}
- s->c_cpu = first_cpu->env_ptr;
- s->g_cpu = first_cpu->env_ptr;
+ s->c_cpu = first_cpu;
+ s->g_cpu = first_cpu;
s->chr = chr;
s->state = chr ? RS_IDLE : RS_INACTIVE;
s->mon_chr = mon_chr;