X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=gdbstub.c;h=e80e1d32b10b15aefac006e398ee7101f3642c66;hb=bf0fda346694db1eddecff1d74ff9f4d5eba3461;hp=ef95ac29ba2611fbc3b0830c4c010ca4b4c3f19c;hpb=00e94dbc7fd0110b0555d59592b004333adfb4b8;p=qemu.git diff --git a/gdbstub.c b/gdbstub.c index ef95ac29b..e80e1d32b 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -29,20 +29,21 @@ #include "qemu.h" #else -#include "monitor.h" -#include "qemu-char.h" -#include "sysemu.h" -#include "gdbstub.h" +#include "monitor/monitor.h" +#include "sysemu/char.h" +#include "sysemu/sysemu.h" +#include "exec/gdbstub.h" #endif #define MAX_PACKET_LENGTH 4096 #include "cpu.h" -#include "qemu_socket.h" -#include "kvm.h" +#include "qemu/sockets.h" +#include "sysemu/kvm.h" +#include "qemu/bitops.h" #ifndef TARGET_CPU_MEMORY_RW_DEBUG -static inline int target_memory_rw_debug(CPUState *env, target_ulong addr, +static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, uint8_t *buf, int len, int is_write) { return cpu_memory_rw_debug(env, addr, buf, len, is_write); @@ -284,12 +285,11 @@ enum RSState { RS_GETLINE, RS_CHKSUM1, RS_CHKSUM2, - RS_SYSCALL, }; typedef struct GDBState { - 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 */ + CPUArchState *c_cpu; /* current CPU for step/continue ops */ + CPUArchState *g_cpu; /* current CPU for other ops */ + CPUArchState *query_cpu; /* for q{f|s}ThreadInfo */ enum RSState state; /* parsing state */ char line_buf[MAX_PACKET_LENGTH]; int line_buf_index; @@ -304,6 +304,8 @@ typedef struct GDBState { CharDriverState *chr; CharDriverState *mon_chr; #endif + char syscall_buf[256]; + gdb_syscall_complete_cb current_syscall_cb; } GDBState; /* By default use no IRQs and no timers while single stepping so as to @@ -346,8 +348,6 @@ static int get_char(GDBState *s) } #endif -static gdb_syscall_complete_cb gdb_current_syscall_cb; - static enum { GDB_SYS_UNKNOWN, GDB_SYS_ENABLED, @@ -533,7 +533,7 @@ static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; #define IDX_XMM_REGS (IDX_FP_REGS + 16) #define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS) -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUX86State *env, uint8_t *mem_buf, int n) { if (n < CPU_NB_REGS) { if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { @@ -590,7 +590,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_x86_gdb_load_seg(CPUState *env, int sreg, uint8_t *mem_buf) +static int cpu_x86_gdb_load_seg(CPUX86State *env, int sreg, uint8_t *mem_buf) { uint16_t selector = ldl_p(mem_buf); @@ -615,7 +615,7 @@ static int cpu_x86_gdb_load_seg(CPUState *env, int sreg, uint8_t *mem_buf) return 4; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) { uint32_t tmp; @@ -703,7 +703,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define GDB_CORE_XML "power-core.xml" #endif -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { /* gprs */ @@ -740,7 +740,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { /* gprs */ @@ -781,7 +781,8 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) /* fpscr */ if (gdb_has_xml) return 0; - return 4; + store_fpscr(env, ldtul_p(mem_buf), 0xffffffff); + return sizeof(target_ulong); } } return 0; @@ -801,7 +802,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define GET_REGA(val) GET_REGL(val) #endif -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n) { if (n < 8) { /* g0..g7 */ @@ -860,7 +861,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n) { #if defined(TARGET_ABI32) abi_ulong tmp; @@ -944,7 +945,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define NUM_CORE_REGS 26 #define GDB_CORE_XML "arm-core.xml" -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) { if (n < 16) { /* Core integer register. */ @@ -971,7 +972,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n) { uint32_t tmp; @@ -1014,7 +1015,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define GDB_CORE_XML "cf-core.xml" -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) { if (n < 8) { /* D0-D7 */ @@ -1033,7 +1034,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n) { uint32_t tmp; @@ -1058,7 +1059,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define NUM_CORE_REGS 73 -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) { if (n < 32) { GET_REGL(env->active_tc.gpr[n]); @@ -1104,7 +1105,7 @@ static unsigned int ieee_rm[] = #define RESTORE_ROUNDING_MODE \ set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status) -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) { target_ulong tmp; @@ -1156,6 +1157,68 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) return sizeof(target_ulong); } +#elif defined(TARGET_OPENRISC) + +#define NUM_CORE_REGS (32 + 3) + +static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + GET_REG32(env->gpr[n]); + } else { + switch (n) { + case 32: /* PPC */ + GET_REG32(env->ppc); + break; + + case 33: /* NPC */ + GET_REG32(env->npc); + break; + + case 34: /* SR */ + GET_REG32(env->sr); + break; + + default: + break; + } + } + return 0; +} + +static int cpu_gdb_write_register(CPUOpenRISCState *env, + uint8_t *mem_buf, int n) +{ + uint32_t tmp; + + if (n > NUM_CORE_REGS) { + return 0; + } + + tmp = ldl_p(mem_buf); + + if (n < 32) { + env->gpr[n] = tmp; + } else { + switch (n) { + case 32: /* PPC */ + env->ppc = tmp; + break; + + case 33: /* NPC */ + env->npc = tmp; + break; + + case 34: /* SR */ + env->sr = tmp; + break; + + default: + break; + } + } + return 4; +} #elif defined (TARGET_SH4) /* Hint: Use "set architecture sh4" in GDB to see fpu registers */ @@ -1163,78 +1226,114 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define NUM_CORE_REGS 59 -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) { - if (n < 8) { + switch (n) { + case 0 ... 7: if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { GET_REGL(env->gregs[n + 16]); } else { GET_REGL(env->gregs[n]); } - } else if (n < 16) { + case 8 ... 15: GET_REGL(env->gregs[n]); - } else if (n >= 25 && n < 41) { - GET_REGL(env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)]); - } else if (n >= 43 && n < 51) { - GET_REGL(env->gregs[n - 43]); - } else if (n >= 51 && n < 59) { - GET_REGL(env->gregs[n - (51 - 16)]); - } - switch (n) { - case 16: GET_REGL(env->pc); - case 17: GET_REGL(env->pr); - case 18: GET_REGL(env->gbr); - case 19: GET_REGL(env->vbr); - case 20: GET_REGL(env->mach); - case 21: GET_REGL(env->macl); - case 22: GET_REGL(env->sr); - case 23: GET_REGL(env->fpul); - case 24: GET_REGL(env->fpscr); - case 41: GET_REGL(env->ssr); - case 42: GET_REGL(env->spc); + case 16: + GET_REGL(env->pc); + case 17: + GET_REGL(env->pr); + case 18: + GET_REGL(env->gbr); + case 19: + GET_REGL(env->vbr); + case 20: + GET_REGL(env->mach); + case 21: + GET_REGL(env->macl); + case 22: + GET_REGL(env->sr); + case 23: + GET_REGL(env->fpul); + case 24: + GET_REGL(env->fpscr); + case 25 ... 40: + if (env->fpscr & FPSCR_FR) { + stfl_p(mem_buf, env->fregs[n - 9]); + } else { + stfl_p(mem_buf, env->fregs[n - 25]); + } + return 4; + case 41: + GET_REGL(env->ssr); + case 42: + GET_REGL(env->spc); + case 43 ... 50: + GET_REGL(env->gregs[n - 43]); + case 51 ... 58: + GET_REGL(env->gregs[n - (51 - 16)]); } return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n) { - uint32_t tmp; - - tmp = ldl_p(mem_buf); - - if (n < 8) { + switch (n) { + case 0 ... 7: if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { - env->gregs[n + 16] = tmp; + env->gregs[n + 16] = ldl_p(mem_buf); } else { - env->gregs[n] = tmp; + env->gregs[n] = ldl_p(mem_buf); } - return 4; - } else if (n < 16) { - env->gregs[n] = tmp; - return 4; - } else if (n >= 25 && n < 41) { - env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)] = tmp; - return 4; - } else if (n >= 43 && n < 51) { - env->gregs[n - 43] = tmp; - return 4; - } else if (n >= 51 && n < 59) { - env->gregs[n - (51 - 16)] = tmp; - return 4; - } - switch (n) { - case 16: env->pc = tmp; break; - case 17: env->pr = tmp; break; - case 18: env->gbr = tmp; break; - case 19: env->vbr = tmp; break; - case 20: env->mach = tmp; break; - case 21: env->macl = tmp; break; - case 22: env->sr = tmp; break; - case 23: env->fpul = tmp; break; - case 24: env->fpscr = tmp; break; - case 41: env->ssr = tmp; break; - case 42: env->spc = tmp; break; + break; + case 8 ... 15: + env->gregs[n] = ldl_p(mem_buf); + break; + case 16: + env->pc = ldl_p(mem_buf); + break; + case 17: + env->pr = ldl_p(mem_buf); + break; + case 18: + env->gbr = ldl_p(mem_buf); + break; + case 19: + env->vbr = ldl_p(mem_buf); + break; + case 20: + env->mach = ldl_p(mem_buf); + break; + case 21: + env->macl = ldl_p(mem_buf); + break; + case 22: + env->sr = ldl_p(mem_buf); + break; + case 23: + env->fpul = ldl_p(mem_buf); + break; + case 24: + env->fpscr = ldl_p(mem_buf); + break; + case 25 ... 40: + if (env->fpscr & FPSCR_FR) { + env->fregs[n - 9] = ldfl_p(mem_buf); + } else { + env->fregs[n - 25] = ldfl_p(mem_buf); + } + break; + case 41: + env->ssr = ldl_p(mem_buf); + break; + case 42: + env->spc = ldl_p(mem_buf); + break; + case 43 ... 50: + env->gregs[n - 43] = ldl_p(mem_buf); + break; + case 51 ... 58: + env->gregs[n - (51 - 16)] = ldl_p(mem_buf); + break; default: return 0; } @@ -1244,7 +1343,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define NUM_CORE_REGS (32 + 5) -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) { if (n < 32) { GET_REG32(env->regs[n]); @@ -1254,7 +1353,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) { uint32_t tmp; @@ -1275,7 +1374,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define NUM_CORE_REGS 49 static int -read_register_crisv10(CPUState *env, uint8_t *mem_buf, int n) +read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) { if (n < 15) { GET_REG32(env->regs[n]); @@ -1307,7 +1406,7 @@ read_register_crisv10(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n) { uint8_t srs; @@ -1337,7 +1436,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n) { uint32_t tmp; @@ -1370,7 +1469,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define NUM_CORE_REGS 67 -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n) { uint64_t val; CPU_DoubleU d; @@ -1404,7 +1503,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) GET_REGL(val); } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n) { target_ulong tmp = ldtul_p(mem_buf); CPU_DoubleU d; @@ -1438,33 +1537,40 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_S390X) -#define NUM_CORE_REGS S390_NUM_TOTAL_REGS +#define NUM_CORE_REGS S390_NUM_REGS -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n) { + uint64_t val; + int cc_op; + switch (n) { - case S390_PSWM_REGNUM: GET_REGL(env->psw.mask); break; - case S390_PSWA_REGNUM: GET_REGL(env->psw.addr); break; - case S390_R0_REGNUM ... S390_R15_REGNUM: - GET_REGL(env->regs[n-S390_R0_REGNUM]); break; - case S390_A0_REGNUM ... S390_A15_REGNUM: - GET_REG32(env->aregs[n-S390_A0_REGNUM]); break; - case S390_FPC_REGNUM: GET_REG32(env->fpc); break; - case S390_F0_REGNUM ... S390_F15_REGNUM: - /* XXX */ - break; - case S390_PC_REGNUM: GET_REGL(env->psw.addr); break; - case S390_CC_REGNUM: - env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, - env->cc_vr); - GET_REG32(env->cc_op); - break; + case S390_PSWM_REGNUM: + cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr); + val = deposit64(env->psw.mask, 44, 2, cc_op); + GET_REGL(val); + break; + case S390_PSWA_REGNUM: + GET_REGL(env->psw.addr); + break; + case S390_R0_REGNUM ... S390_R15_REGNUM: + GET_REGL(env->regs[n-S390_R0_REGNUM]); + break; + case S390_A0_REGNUM ... S390_A15_REGNUM: + GET_REG32(env->aregs[n-S390_A0_REGNUM]); + break; + case S390_FPC_REGNUM: + GET_REG32(env->fpc); + break; + case S390_F0_REGNUM ... S390_F15_REGNUM: + GET_REG64(env->fregs[n-S390_F0_REGNUM].ll); + break; } return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n) { target_ulong tmpl; uint32_t tmp32; @@ -1473,28 +1579,38 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) tmp32 = ldl_p(mem_buf); switch (n) { - case S390_PSWM_REGNUM: env->psw.mask = tmpl; break; - case S390_PSWA_REGNUM: env->psw.addr = tmpl; break; - case S390_R0_REGNUM ... S390_R15_REGNUM: - env->regs[n-S390_R0_REGNUM] = tmpl; break; - case S390_A0_REGNUM ... S390_A15_REGNUM: - env->aregs[n-S390_A0_REGNUM] = tmp32; r=4; break; - case S390_FPC_REGNUM: env->fpc = tmp32; r=4; break; - case S390_F0_REGNUM ... S390_F15_REGNUM: - /* XXX */ - break; - case S390_PC_REGNUM: env->psw.addr = tmpl; break; - case S390_CC_REGNUM: env->cc_op = tmp32; r=4; break; + case S390_PSWM_REGNUM: + env->psw.mask = tmpl; + env->cc_op = extract64(tmpl, 44, 2); + break; + case S390_PSWA_REGNUM: + env->psw.addr = tmpl; + break; + case S390_R0_REGNUM ... S390_R15_REGNUM: + env->regs[n-S390_R0_REGNUM] = tmpl; + break; + case S390_A0_REGNUM ... S390_A15_REGNUM: + env->aregs[n-S390_A0_REGNUM] = tmp32; + r = 4; + break; + case S390_FPC_REGNUM: + env->fpc = tmp32; + r = 4; + break; + case S390_F0_REGNUM ... S390_F15_REGNUM: + env->fregs[n-S390_F0_REGNUM].ll = tmpl; + break; + default: + return 0; } - return r; } #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(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n) { if (n < 32) { GET_REG32(env->regs[n]); @@ -1527,7 +1643,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n) { uint32_t tmp; @@ -1573,7 +1689,7 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define NUM_CORE_REGS (env->config->gdb_regmap.num_regs) #define num_g_regs NUM_CORE_REGS -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) { const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; @@ -1599,6 +1715,10 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) GET_REG32(env->uregs[reg->targno & 0xff]); break; + case 4: /*f*/ + GET_REG32(float32_val(env->fregs[reg->targno & 0x0f])); + break; + case 8: /*a*/ GET_REG32(env->regs[reg->targno & 0x0f]); break; @@ -1610,7 +1730,7 @@ static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) } } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n) { uint32_t tmp; const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; @@ -1639,6 +1759,10 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) env->uregs[reg->targno & 0xff] = tmp; break; + case 4: /*f*/ + env->fregs[reg->targno & 0x0f] = make_float32(tmp); + break; + case 8: /*a*/ env->regs[reg->targno & 0x0f] = tmp; break; @@ -1655,12 +1779,12 @@ static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) #define NUM_CORE_REGS 0 -static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n) { return 0; } -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) +static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n) { return 0; } @@ -1736,7 +1860,7 @@ static const char *get_feature_xml(const char *p, const char **newp) } #endif -static int gdb_read_register(CPUState *env, uint8_t *mem_buf, int reg) +static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg) { GDBRegisterState *r; @@ -1751,7 +1875,7 @@ static int gdb_read_register(CPUState *env, uint8_t *mem_buf, int reg) return 0; } -static int gdb_write_register(CPUState *env, uint8_t *mem_buf, int reg) +static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg) { GDBRegisterState *r; @@ -1773,7 +1897,7 @@ static int gdb_write_register(CPUState *env, uint8_t *mem_buf, int reg) gdb reading a CPU register, and set_reg is gdb modifying a CPU register. */ -void gdb_register_coprocessor(CPUState * env, +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) { @@ -1820,7 +1944,7 @@ static const int xlat_gdb_type[] = { static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) { - CPUState *env; + CPUArchState *env; int err = 0; if (kvm_enabled()) @@ -1854,7 +1978,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type) { - CPUState *env; + CPUArchState *env; int err = 0; if (kvm_enabled()) @@ -1887,7 +2011,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type) static void gdb_breakpoint_remove_all(void) { - CPUState *env; + CPUArchState *env; if (kvm_enabled()) { kvm_remove_all_breakpoints(gdbserver_state->c_cpu); @@ -1904,8 +2028,8 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { -#if defined(TARGET_I386) cpu_synchronize_state(s->c_cpu); +#if defined(TARGET_I386) s->c_cpu->eip = pc; #elif defined (TARGET_PPC) s->c_cpu->nip = pc; @@ -1925,12 +2049,13 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) } #elif defined (TARGET_MICROBLAZE) s->c_cpu->sregs[SR_PC] = pc; +#elif defined(TARGET_OPENRISC) + s->c_cpu->pc = pc; #elif defined (TARGET_CRIS) s->c_cpu->pc = pc; #elif defined (TARGET_ALPHA) s->c_cpu->pc = pc; #elif defined (TARGET_S390X) - cpu_synchronize_state(s->c_cpu); s->c_cpu->psw.addr = pc; #elif defined (TARGET_LM32) s->c_cpu->pc = pc; @@ -1939,21 +2064,14 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) #endif } -static inline int gdb_id(CPUState *env) -{ -#if defined(CONFIG_USER_ONLY) && defined(CONFIG_USE_NPTL) - return env->host_tid; -#else - return env->cpu_index + 1; -#endif -} - -static CPUState *find_cpu(uint32_t thread_id) +static CPUArchState *find_cpu(uint32_t thread_id) { - CPUState *env; + CPUArchState *env; + CPUState *cpu; for (env = first_cpu; env != NULL; env = env->next_cpu) { - if (gdb_id(env) == thread_id) { + cpu = ENV_GET_CPU(env); + if (cpu_index(cpu) == thread_id) { return env; } } @@ -1963,7 +2081,7 @@ static CPUState *find_cpu(uint32_t thread_id) static int gdb_handle_packet(GDBState *s, const char *line_buf) { - CPUState *env; + CPUArchState *env; const char *p; uint32_t thread; int ch, reg_size, type, res; @@ -1981,7 +2099,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) case '?': /* TODO: Make this return the correct value for user-mode. */ snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP, - gdb_id(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 @@ -2097,8 +2215,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ',') p++; type = *p; - if (gdb_current_syscall_cb) - gdb_current_syscall_cb(s->c_cpu, ret, err); + if (s->current_syscall_cb) { + s->current_syscall_cb(s->c_cpu, ret, err); + s->current_syscall_cb = NULL; + } if (type == 'C') { put_packet(s, "T02"); } else { @@ -2274,7 +2394,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } else if (strcmp(p,"sThreadInfo") == 0) { report_cpuinfo: if (s->query_cpu) { - snprintf(buf, sizeof(buf), "m%x", gdb_id(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; } else @@ -2284,10 +2405,11 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) thread = strtoull(p+16, (char **)&p, 16); env = find_cpu(thread); if (env != NULL) { + CPUState *cpu = ENV_GET_CPU(env); cpu_synchronize_state(env); 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); } @@ -2383,7 +2505,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) return RS_IDLE; } -void gdb_set_stop_cpu(CPUState *env) +void gdb_set_stop_cpu(CPUArchState *env) { gdbserver_state->c_cpu = env; gdbserver_state->g_cpu = env; @@ -2393,12 +2515,18 @@ void gdb_set_stop_cpu(CPUState *env) static void gdb_vm_state_change(void *opaque, int running, RunState state) { GDBState *s = gdbserver_state; - CPUState *env = s->c_cpu; + CPUArchState *env = s->c_cpu; + CPUState *cpu = ENV_GET_CPU(env); char buf[256]; const char *type; int ret; - if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) { + if (running || s->state == RS_INACTIVE) { + return; + } + /* Is there a GDB syscall waiting to be sent? */ + if (s->current_syscall_cb) { + put_packet(s, s->syscall_buf); return; } switch (state) { @@ -2417,7 +2545,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) } snprintf(buf, sizeof(buf), "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";", - GDB_SIGNAL_TRAP, gdb_id(env), type, + GDB_SIGNAL_TRAP, cpu_index(cpu), type, env->watchpoint_hit->vaddr); env->watchpoint_hit = NULL; goto send_packet; @@ -2450,7 +2578,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) ret = GDB_SIGNAL_UNKNOWN; break; } - snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, gdb_id(env)); + snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu)); send_packet: put_packet(s, buf); @@ -2468,8 +2596,8 @@ send_packet: void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) { va_list va; - char buf[256]; char *p; + char *p_end; target_ulong addr; uint64_t i64; GDBState *s; @@ -2477,14 +2605,13 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) s = gdbserver_state; if (!s) return; - gdb_current_syscall_cb = cb; - s->state = RS_SYSCALL; + s->current_syscall_cb = cb; #ifndef CONFIG_USER_ONLY vm_stop(RUN_STATE_DEBUG); #endif - s->state = RS_IDLE; va_start(va, fmt); - p = buf; + p = s->syscall_buf; + p_end = &s->syscall_buf[sizeof(s->syscall_buf)]; *(p++) = 'F'; while (*fmt) { if (*fmt == '%') { @@ -2492,17 +2619,17 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) switch (*fmt++) { case 'x': addr = va_arg(va, target_ulong); - p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx, addr); + p += snprintf(p, p_end - p, TARGET_FMT_lx, addr); break; case 'l': if (*(fmt++) != 'x') goto bad_format; i64 = va_arg(va, uint64_t); - p += snprintf(p, &buf[sizeof(buf)] - p, "%" PRIx64, i64); + p += snprintf(p, p_end - p, "%" PRIx64, i64); break; case 's': addr = va_arg(va, target_ulong); - p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx "/%x", + p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x", addr, va_arg(va, int)); break; default: @@ -2517,10 +2644,16 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) } *p = 0; va_end(va); - put_packet(s, buf); #ifdef CONFIG_USER_ONLY + put_packet(s, s->syscall_buf); gdb_handlesig(s->c_cpu, 0); #else + /* In this case wait to send the syscall packet until notification that + the CPU has stopped. This must be done because if the packet is sent + now the reply from the syscall request could be received while the CPU + 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); #endif } @@ -2602,7 +2735,7 @@ static void gdb_read_byte(GDBState *s, int ch) } /* Tell the remote gdb that the process has exited. */ -void gdb_exit(CPUState *env, int code) +void gdb_exit(CPUArchState *env, int code) { GDBState *s; char buf[4]; @@ -2642,7 +2775,7 @@ gdb_queuesig (void) } int -gdb_handlesig (CPUState *env, int sig) +gdb_handlesig (CPUArchState *env, int sig) { GDBState *s; char buf[256]; @@ -2691,7 +2824,7 @@ gdb_handlesig (CPUState *env, int sig) } /* Tell the remote gdb that the process has exited due to SIG. */ -void gdb_signalled(CPUState *env, int sig) +void gdb_signalled(CPUArchState *env, int sig) { GDBState *s; char buf[4]; @@ -2709,7 +2842,7 @@ static void gdb_accept(void) GDBState *s; struct sockaddr_in sockaddr; socklen_t len; - int val, fd; + int fd; for(;;) { len = sizeof(sockaddr); @@ -2726,8 +2859,7 @@ static void gdb_accept(void) } /* 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; @@ -2756,7 +2888,7 @@ static int gdbserver_open(int port) /* 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); @@ -2787,7 +2919,7 @@ int gdbserver_start(int port) } /* Disable gdb stub for child processes. */ -void gdbserver_fork(CPUState *env) +void gdbserver_fork(CPUArchState *env) { GDBState *s = gdbserver_state; if (gdbserver_fd < 0 || s->fd < 0) @@ -2893,6 +3025,7 @@ int gdbserver_start(const char *device) 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); } @@ -2919,6 +3052,7 @@ int gdbserver_start(const char *device) s->chr = chr; s->state = chr ? RS_IDLE : RS_INACTIVE; s->mon_chr = mon_chr; + s->current_syscall_cb = NULL; return 0; }