X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=gdbstub.c;h=28f9b440c9a8f68bd40fa34275cc63360d6560a5;hb=51996525c77e61a050562900a499798ded8981d0;hp=62c1db297dda1f84d02db766bff6bc7706ca41db;hpb=5a5012ecbdcd341bb1d2e8200db91f6212aa44df;p=qemu diff --git a/gdbstub.c b/gdbstub.c index 62c1db2..28f9b44 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1,6 +1,6 @@ /* * gdb server stub - * + * * Copyright (c) 2003-2005 Fabrice Bellard * * This library is free software; you can redistribute it and/or @@ -252,7 +252,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) registers[41] = 0; /* foseg */ registers[42] = 0; /* fooff */ registers[43] = 0; /* fop */ - + for(i = 0; i < 16; i++) tswapls(®isters[i]); for(i = 36; i < 44; i++) @@ -383,7 +383,10 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) } registers[64] = tswapl(env->pc); registers[65] = tswapl(env->npc); - registers[66] = tswapl(env->tstate[env->tl]); + registers[66] = tswapl(((uint64_t)GET_CCR(env) << 32) | + ((env->asi & 0xff) << 24) | + ((env->pstate & 0xfff) << 8) | + GET_CWP64(env)); registers[67] = tswapl(env->fsr); registers[68] = tswapl(env->fprs); registers[69] = tswapl(env->y); @@ -427,7 +430,14 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) } env->pc = tswapl(registers[64]); env->npc = tswapl(registers[65]); - env->tstate[env->tl] = tswapl(registers[66]); + { + uint64_t tmp = tswapl(registers[66]); + + PUT_CCR(env, tmp >> 32); + env->asi = (tmp >> 24) & 0xff; + env->pstate = (tmp >> 8) & 0xfff; + PUT_CWP64(env, tmp & 0xff); + } env->fsr = tswapl(registers[67]); env->fprs = tswapl(registers[68]); env->y = tswapl(registers[69]); @@ -533,7 +543,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) /* 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.upper = tswap32(*(uint32_t *)ptr); u.l.lower = tswap32(*(uint32_t *)ptr); env->fregs[i] = u.d; } @@ -549,41 +559,41 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) ptr = mem_buf; for (i = 0; i < 32; i++) { - *(uint32_t *)ptr = tswapl(env->gpr[i]); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->gpr[i][env->current_tc]); + ptr += sizeof(target_ulong); } - *(uint32_t *)ptr = tswapl(env->CP0_Status); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->CP0_Status); + ptr += sizeof(target_ulong); - *(uint32_t *)ptr = tswapl(env->LO); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->LO[0][env->current_tc]); + ptr += sizeof(target_ulong); - *(uint32_t *)ptr = tswapl(env->HI); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->HI[0][env->current_tc]); + ptr += sizeof(target_ulong); - *(uint32_t *)ptr = tswapl(env->CP0_BadVAddr); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->CP0_BadVAddr); + ptr += sizeof(target_ulong); - *(uint32_t *)ptr = tswapl(env->CP0_Cause); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->CP0_Cause); + ptr += sizeof(target_ulong); - *(uint32_t *)ptr = tswapl(env->PC); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->PC[env->current_tc]); + ptr += sizeof(target_ulong); if (env->CP0_Config1 & (1 << CP0C1_FP)) { for (i = 0; i < 32; i++) { - *(uint32_t *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].fs[FP_ENDIAN_IDX]); + ptr += sizeof(target_ulong); } - *(uint32_t *)ptr = tswapl(env->fcr31); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->fpu->fcr31); + ptr += sizeof(target_ulong); - *(uint32_t *)ptr = tswapl(env->fcr0); - ptr += 4; + *(target_ulong *)ptr = tswapl(env->fpu->fcr0); + ptr += sizeof(target_ulong); } /* 32 FP registers, fsr, fir, fp. Not yet implemented. */ @@ -601,7 +611,7 @@ static unsigned int ieee_rm[] = float_round_down }; #define RESTORE_ROUNDING_MODE \ - set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status) + set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status) static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) { @@ -611,41 +621,41 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) ptr = mem_buf; for (i = 0; i < 32; i++) { - env->gpr[i] = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->gpr[i][env->current_tc] = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); } - env->CP0_Status = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->CP0_Status = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); - env->LO = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->LO[0][env->current_tc] = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); - env->HI = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->HI[0][env->current_tc] = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); - env->CP0_BadVAddr = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->CP0_BadVAddr = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); - env->CP0_Cause = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->CP0_Cause = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); - env->PC = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->PC[env->current_tc] = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); if (env->CP0_Config1 & (1 << CP0C1_FP)) { for (i = 0; i < 32; i++) { - env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->fpu->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); } - env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF; - ptr += 4; + env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF; + ptr += sizeof(target_ulong); - env->fcr0 = tswapl(*(uint32_t *)ptr); - ptr += 4; + env->fpu->fcr0 = tswapl(*(target_ulong *)ptr); + ptr += sizeof(target_ulong); /* set rounding mode */ RESTORE_ROUNDING_MODE; @@ -657,6 +667,9 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) } } #elif defined (TARGET_SH4) + +/* Hint: Use "set architecture sh4" in GDB to see fpu registers */ + static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) { uint32_t *ptr = (uint32_t *)mem_buf; @@ -676,12 +689,14 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) SAVE (env->mach); SAVE (env->macl); SAVE (env->sr); - SAVE (0); /* TICKS */ - SAVE (0); /* STALLS */ - SAVE (0); /* CYCLES */ - SAVE (0); /* INSTS */ - SAVE (0); /* PLR */ - + SAVE (env->fpul); + SAVE (env->fpscr); + for (i = 0; i < 16; i++) + SAVE(env->fregs[i + ((env->fpscr & FPSCR_FR) ? 16 : 0)]); + SAVE (env->ssr); + SAVE (env->spc); + for (i = 0; i < 8; i++) SAVE(env->gregs[i]); + for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]); return ((uint8_t *)ptr - mem_buf); } @@ -704,6 +719,14 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) LOAD (env->mach); LOAD (env->macl); LOAD (env->sr); + LOAD (env->fpul); + LOAD (env->fpscr); + for (i = 0; i < 16; i++) + LOAD(env->fregs[i + ((env->fpscr & FPSCR_FR) ? 16 : 0)]); + LOAD (env->ssr); + LOAD (env->spc); + for (i = 0; i < 8; i++) LOAD(env->gregs[i]); + for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]); } #else static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -725,7 +748,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) uint8_t mem_buf[2000]; uint32_t *registers; target_ulong addr, len; - + #ifdef DEBUG_GDB printf("command='%s'\n", line_buf); #endif @@ -750,7 +773,9 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) #elif defined (TARGET_ARM) env->regs[15] = addr; #elif defined (TARGET_SH4) - env->pc = addr; + env->pc = addr; +#elif defined (TARGET_MIPS) + env->PC[env->current_tc] = addr; #endif } #ifdef CONFIG_USER_ONLY @@ -761,7 +786,7 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) return RS_IDLE; case 's': if (*p != '\0') { - addr = strtoul(p, (char **)&p, 16); + addr = strtoull(p, (char **)&p, 16); #if defined(TARGET_I386) env->eip = addr; #elif defined (TARGET_PPC) @@ -772,7 +797,9 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) #elif defined (TARGET_ARM) env->regs[15] = addr; #elif defined (TARGET_SH4) - env->pc = addr; + env->pc = addr; +#elif defined (TARGET_MIPS) + env->PC[env->current_tc] = addr; #endif } cpu_single_step(env, 1); @@ -895,8 +922,11 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) if (strncmp(p, "Offsets", 7) == 0) { TaskState *ts = env->opaque; - sprintf(buf, "Text=%x;Data=%x;Bss=%x", ts->info->code_offset, - ts->info->data_offset, ts->info->data_offset); + sprintf(buf, + "Text=" TARGET_FMT_lx ";Data=" TARGET_FMT_lx ";Bss=" TARGET_FMT_lx, + ts->info->code_offset, + ts->info->data_offset, + ts->info->data_offset); put_packet(s, buf); break; } @@ -950,14 +980,16 @@ static void gdb_vm_stopped(void *opaque, int reason) /* Send a gdb syscall request. This accepts limited printf-style format specifiers, specifically: - %x - target_ulong argument printed in hex. - %s - string pointer (target_ulong) and length (int) pair. */ + %x - target_ulong argument printed in hex. + %lx - 64-bit argument printed in hex. + %s - string pointer (target_ulong) and length (int) pair. */ void gdb_do_syscall(gdb_syscall_complete_cb cb, char *fmt, ...) { va_list va; char buf[256]; char *p; target_ulong addr; + uint64_t i64; GDBState *s; s = gdb_syscall_state; @@ -980,11 +1012,18 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, char *fmt, ...) addr = va_arg(va, target_ulong); p += sprintf(p, TARGET_FMT_lx, addr); break; + case 'l': + if (*(fmt++) != 'x') + goto bad_format; + i64 = va_arg(va, uint64_t); + p += sprintf(p, "%" PRIx64, i64); + break; case 's': addr = va_arg(va, target_ulong); p += sprintf(p, TARGET_FMT_lx "/%x", addr, va_arg(va, int)); break; default: + bad_format: fprintf(stderr, "gdbstub: Bad syscall format string '%s'\n", fmt - 1); break; @@ -993,6 +1032,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, char *fmt, ...) *(p++) = *(fmt++); } } + *p = 0; va_end(va); put_packet(s, buf); #ifdef CONFIG_USER_ONLY @@ -1033,7 +1073,7 @@ static void gdb_read_byte(GDBState *s, int ch) /* when the CPU is running, we cannot do anything except stop it when receiving a char */ vm_stop(EXCP_INTERRUPT); - } else + } else #endif { switch(s->state) { @@ -1161,7 +1201,7 @@ static void gdb_accept(void *opaque) /* set short latency */ val = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); - + s = &gdbserver_state; memset (s, 0, sizeof (GDBState)); s->env = first_cpu; /* XXX: allow to change CPU */ @@ -1213,12 +1253,12 @@ int gdbserver_start(int port) return 0; } #else -static int gdb_chr_can_recieve(void *opaque) +static int gdb_chr_can_receive(void *opaque) { return 1; } -static void gdb_chr_recieve(void *opaque, const uint8_t *buf, int size) +static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size) { GDBState *s = opaque; int i; @@ -1269,7 +1309,7 @@ int gdbserver_start(const char *port) } s->env = first_cpu; /* XXX: allow to change CPU */ s->chr = chr; - qemu_chr_add_handlers(chr, gdb_chr_can_recieve, gdb_chr_recieve, + qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive, gdb_chr_event, s); qemu_add_vm_stop_handler(gdb_vm_stopped, s); return 0;