📄 gdbstub.c
字号:
env->fsr = tswapl(registers[70]);#else for (i = 0; i < 64; i += 2) { *((uint32_t *)&env->fpr[i]) = tswap32(registers[i/2 + 32] >> 32); *((uint32_t *)&env->fpr[i + 1]) = tswap32(registers[i/2 + 32] & 0xffffffff); } env->pc = tswapl(registers[64]); env->npc = tswapl(registers[65]); env->tstate[env->tl] = tswapl(registers[66]); env->fsr = tswapl(registers[67]); env->fprs = tswapl(registers[68]); env->y = tswapl(registers[69]);#endif}#elif defined (TARGET_ARM)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){ int i; uint8_t *ptr; ptr = mem_buf; /* 16 core integer registers (4 bytes each). */ for (i = 0; i < 16; i++) { *(uint32_t *)ptr = tswapl(env->regs[i]); ptr += 4; } /* 8 FPA registers (12 bytes each), FPS (4 bytes). Not yet implemented. */ memset (ptr, 0, 8 * 12 + 4); ptr += 8 * 12 + 4; /* CPSR (4 bytes). */ *(uint32_t *)ptr = tswapl (cpsr_read(env)); ptr += 4; return ptr - mem_buf;}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){ int i; uint8_t *ptr; ptr = mem_buf; /* Core integer registers. */ for (i = 0; i < 16; i++) { env->regs[i] = tswapl(*(uint32_t *)ptr); ptr += 4; } /* Ignore FPA regs and scr. */ ptr += 8 * 12 + 4; cpsr_write (env, tswapl(*(uint32_t *)ptr), 0xffffffff);}#elif defined (TARGET_M68K)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){ int i; uint8_t *ptr; CPU_DoubleU u; ptr = mem_buf; /* D0-D7 */ for (i = 0; i < 8; i++) { *(uint32_t *)ptr = tswapl(env->dregs[i]); ptr += 4; } /* A0-A7 */ for (i = 0; i < 8; i++) { *(uint32_t *)ptr = tswapl(env->aregs[i]); ptr += 4; } *(uint32_t *)ptr = tswapl(env->sr); ptr += 4; *(uint32_t *)ptr = tswapl(env->pc); ptr += 4; /* F0-F7. The 68881/68040 have 12-bit extended precision registers. ColdFire has 8-bit double precision registers. */ for (i = 0; i < 8; i++) { u.d = env->fregs[i]; *(uint32_t *)ptr = tswap32(u.l.upper); *(uint32_t *)ptr = tswap32(u.l.lower); } /* FP control regs (not implemented). */ memset (ptr, 0, 3 * 4); ptr += 3 * 4; return ptr - mem_buf;}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){ int i; uint8_t *ptr; CPU_DoubleU u; ptr = mem_buf; /* D0-D7 */ for (i = 0; i < 8; i++) { env->dregs[i] = tswapl(*(uint32_t *)ptr); ptr += 4; } /* A0-A7 */ for (i = 0; i < 8; i++) { env->aregs[i] = tswapl(*(uint32_t *)ptr); ptr += 4; } env->sr = tswapl(*(uint32_t *)ptr); ptr += 4; env->pc = tswapl(*(uint32_t *)ptr); ptr += 4; /* F0-F7. The 68881/68040 have 12-bit extended precision registers. ColdFire has 8-bit double precision registers. */ for (i = 0; i < 8; i++) { u.l.upper = tswap32(*(uint32_t *)ptr); u.l.lower = tswap32(*(uint32_t *)ptr); env->fregs[i] = u.d; } /* FP control regs (not implemented). */ ptr += 3 * 4;}#elif defined (TARGET_MIPS)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){ int i; uint8_t *ptr; ptr = mem_buf; for (i = 0; i < 32; i++) { *(uint32_t *)ptr = tswapl(env->gpr[i]); ptr += 4; } *(uint32_t *)ptr = tswapl(env->CP0_Status); ptr += 4; *(uint32_t *)ptr = tswapl(env->LO); ptr += 4; *(uint32_t *)ptr = tswapl(env->HI); ptr += 4; *(uint32_t *)ptr = tswapl(env->CP0_BadVAddr); ptr += 4; *(uint32_t *)ptr = tswapl(env->CP0_Cause); ptr += 4; *(uint32_t *)ptr = tswapl(env->PC); ptr += 4;#ifdef MIPS_USES_FPU for (i = 0; i < 32; i++) { *(uint32_t *)ptr = tswapl(FPR_W (env, i)); ptr += 4; } *(uint32_t *)ptr = tswapl(env->fcr31); ptr += 4; *(uint32_t *)ptr = tswapl(env->fcr0); ptr += 4;#endif /* 32 FP registers, fsr, fir, fp. Not yet implemented. */ /* what's 'fp' mean here? */ return ptr - mem_buf;}/* convert MIPS rounding mode in FCR31 to IEEE library */static unsigned int ieee_rm[] = { float_round_nearest_even, float_round_to_zero, float_round_up, float_round_down };#define RESTORE_ROUNDING_MODE \ set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){ int i; uint8_t *ptr; ptr = mem_buf; for (i = 0; i < 32; i++) { env->gpr[i] = tswapl(*(uint32_t *)ptr); ptr += 4; } env->CP0_Status = tswapl(*(uint32_t *)ptr); ptr += 4; env->LO = tswapl(*(uint32_t *)ptr); ptr += 4; env->HI = tswapl(*(uint32_t *)ptr); ptr += 4; env->CP0_BadVAddr = tswapl(*(uint32_t *)ptr); ptr += 4; env->CP0_Cause = tswapl(*(uint32_t *)ptr); ptr += 4; env->PC = tswapl(*(uint32_t *)ptr); ptr += 4;#ifdef MIPS_USES_FPU for (i = 0; i < 32; i++) { FPR_W (env, i) = tswapl(*(uint32_t *)ptr); ptr += 4; } env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF; ptr += 4; env->fcr0 = tswapl(*(uint32_t *)ptr); ptr += 4; /* set rounding mode */ RESTORE_ROUNDING_MODE;#ifndef CONFIG_SOFTFLOAT /* no floating point exception for native float */ SET_FP_ENABLE(env->fcr31, 0);#endif#endif}#elif defined (TARGET_SH4)static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){ uint32_t *ptr = (uint32_t *)mem_buf; int i;#define SAVE(x) *ptr++=tswapl(x) if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]); } else { for (i = 0; i < 8; i++) SAVE(env->gregs[i]); } for (i = 8; i < 16; i++) SAVE(env->gregs[i]); SAVE (env->pc); SAVE (env->pr); SAVE (env->gbr); SAVE (env->vbr); SAVE (env->mach); SAVE (env->macl); SAVE (env->sr); SAVE (0); /* TICKS */ SAVE (0); /* STALLS */ SAVE (0); /* CYCLES */ SAVE (0); /* INSTS */ SAVE (0); /* PLR */ return ((uint8_t *)ptr - mem_buf);}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){ uint32_t *ptr = (uint32_t *)mem_buf; int i;#define LOAD(x) (x)=*ptr++; if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) { for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]); } else { for (i = 0; i < 8; i++) LOAD(env->gregs[i]); } for (i = 8; i < 16; i++) LOAD(env->gregs[i]); LOAD (env->pc); LOAD (env->pr); LOAD (env->gbr); LOAD (env->vbr); LOAD (env->mach); LOAD (env->macl); LOAD (env->sr);}#elsestatic int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf){ return 0;}static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size){}#endifstatic int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf){ const char *p; int ch, reg_size, type; char buf[4096]; uint8_t mem_buf[2000]; uint32_t *registers; target_ulong addr, len; #ifdef DEBUG_GDB printf("command='%s'\n", line_buf);#endif p = line_buf; ch = *p++; switch(ch) { case '?': /* TODO: Make this return the correct value for user-mode. */ snprintf(buf, sizeof(buf), "S%02x", SIGTRAP); put_packet(s, buf); break; case 'c': if (*p != '\0') { addr = strtoull(p, (char **)&p, 16);#if defined(TARGET_I386) env->eip = addr;#elif defined (TARGET_PPC) env->nip = addr;#elif defined (TARGET_SPARC) env->pc = addr; env->npc = addr + 4;#elif defined (TARGET_ARM) env->regs[15] = addr;#elif defined (TARGET_SH4) env->pc = addr;#endif }#ifdef CONFIG_USER_ONLY s->running_state = 1;#else vm_start();#endif return RS_IDLE; case 's': if (*p != '\0') { addr = strtoul(p, (char **)&p, 16);#if defined(TARGET_I386) env->eip = addr;#elif defined (TARGET_PPC) env->nip = addr;#elif defined (TARGET_SPARC) env->pc = addr; env->npc = addr + 4;#elif defined (TARGET_ARM) env->regs[15] = addr;#elif defined (TARGET_SH4) env->pc = addr;#endif } cpu_single_step(env, 1);#ifdef CONFIG_USER_ONLY s->running_state = 1;#else vm_start();#endif return RS_IDLE; case 'F': { target_ulong ret; target_ulong err; ret = strtoull(p, (char **)&p, 16); if (*p == ',') { p++; err = strtoull(p, (char **)&p, 16); } else { err = 0; } if (*p == ',') p++; type = *p; if (gdb_current_syscall_cb) gdb_current_syscall_cb(s->env, ret, err); if (type == 'C') { put_packet(s, "T02"); } else {#ifdef CONFIG_USER_ONLY s->running_state = 1;#else vm_start();#endif } } break; case 'g': reg_size = cpu_gdb_read_registers(env, mem_buf); memtohex(buf, mem_buf, reg_size); put_packet(s, buf); break; case 'G': registers = (void *)mem_buf; len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); cpu_gdb_write_registers(env, mem_buf, len); put_packet(s, "OK"); break; case 'm': addr = strtoull(p, (char **)&p, 16); if (*p == ',') p++; len = strtoull(p, NULL, 16); if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) { put_packet (s, "E14"); } else { memtohex(buf, mem_buf, len); put_packet(s, buf); } break; case 'M': addr = strtoull(p, (char **)&p, 16); if (*p == ',') p++; len = strtoull(p, (char **)&p, 16);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -