Commit 6da41eafc40c543c581d8b585a906691beca43b0
1 parent
0124311e
added CPU callbacks
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@493 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
103 additions
and
37 deletions
gdbstub.c
| ... | ... | @@ -248,6 +248,23 @@ static int put_packet(char *buf) |
| 248 | 248 | return 0; |
| 249 | 249 | } |
| 250 | 250 | |
| 251 | + /* better than nothing for SOFTMMU : we use physical addresses */ | |
| 252 | +#ifdef CONFIG_SOFTMMU | |
| 253 | +static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write) | |
| 254 | +{ | |
| 255 | + uint8_t *ptr; | |
| 256 | + | |
| 257 | + if (addr >= phys_ram_size || | |
| 258 | + ((int64_t)addr + len > phys_ram_size)) | |
| 259 | + return -1; | |
| 260 | + ptr = phys_ram_base + addr; | |
| 261 | + if (is_write) | |
| 262 | + memcpy(ptr, buf, len); | |
| 263 | + else | |
| 264 | + memcpy(buf, ptr, len); | |
| 265 | + return 0; | |
| 266 | +} | |
| 267 | +#else | |
| 251 | 268 | static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write) |
| 252 | 269 | { |
| 253 | 270 | int l, flags; |
| ... | ... | @@ -276,13 +293,91 @@ static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write) |
| 276 | 293 | } |
| 277 | 294 | return 0; |
| 278 | 295 | } |
| 296 | +#endif | |
| 297 | + | |
| 298 | +#if defined(TARGET_I386) | |
| 299 | + | |
| 300 | +static void to_le32(uint8_t *p, int v) | |
| 301 | +{ | |
| 302 | + p[0] = v; | |
| 303 | + p[1] = v >> 8; | |
| 304 | + p[2] = v >> 16; | |
| 305 | + p[3] = v >> 24; | |
| 306 | +} | |
| 307 | + | |
| 308 | +static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) | |
| 309 | +{ | |
| 310 | + int i, fpus; | |
| 311 | + | |
| 312 | + for(i = 0; i < 8; i++) { | |
| 313 | + to_le32(mem_buf + i * 4, env->regs[i]); | |
| 314 | + } | |
| 315 | + to_le32(mem_buf + 8 * 4, env->eip); | |
| 316 | + to_le32(mem_buf + 9 * 4, env->eflags); | |
| 317 | + to_le32(mem_buf + 10 * 4, env->segs[R_CS].selector); | |
| 318 | + to_le32(mem_buf + 11 * 4, env->segs[R_SS].selector); | |
| 319 | + to_le32(mem_buf + 12 * 4, env->segs[R_DS].selector); | |
| 320 | + to_le32(mem_buf + 13 * 4, env->segs[R_ES].selector); | |
| 321 | + to_le32(mem_buf + 14 * 4, env->segs[R_FS].selector); | |
| 322 | + to_le32(mem_buf + 15 * 4, env->segs[R_GS].selector); | |
| 323 | + /* XXX: convert floats */ | |
| 324 | + for(i = 0; i < 8; i++) { | |
| 325 | + memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10); | |
| 326 | + } | |
| 327 | + to_le32(mem_buf + 36 * 4, env->fpuc); | |
| 328 | + fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; | |
| 329 | + to_le32(mem_buf + 37 * 4, fpus); | |
| 330 | + to_le32(mem_buf + 38 * 4, 0); /* XXX: convert tags */ | |
| 331 | + to_le32(mem_buf + 39 * 4, 0); /* fiseg */ | |
| 332 | + to_le32(mem_buf + 40 * 4, 0); /* fioff */ | |
| 333 | + to_le32(mem_buf + 41 * 4, 0); /* foseg */ | |
| 334 | + to_le32(mem_buf + 42 * 4, 0); /* fooff */ | |
| 335 | + to_le32(mem_buf + 43 * 4, 0); /* fop */ | |
| 336 | + return 44 * 4; | |
| 337 | +} | |
| 338 | + | |
| 339 | +static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) | |
| 340 | +{ | |
| 341 | + uint32_t *registers = (uint32_t *)mem_buf; | |
| 342 | + int i; | |
| 343 | + | |
| 344 | + for(i = 0; i < 8; i++) { | |
| 345 | + env->regs[i] = tswapl(registers[i]); | |
| 346 | + } | |
| 347 | + env->eip = registers[8]; | |
| 348 | + env->eflags = registers[9]; | |
| 349 | +#if defined(CONFIG_USER_ONLY) | |
| 350 | +#define LOAD_SEG(index, sreg)\ | |
| 351 | + if (tswapl(registers[index]) != env->segs[sreg].selector)\ | |
| 352 | + cpu_x86_load_seg(env, sreg, tswapl(registers[index])); | |
| 353 | + LOAD_SEG(10, R_CS); | |
| 354 | + LOAD_SEG(11, R_SS); | |
| 355 | + LOAD_SEG(12, R_DS); | |
| 356 | + LOAD_SEG(13, R_ES); | |
| 357 | + LOAD_SEG(14, R_FS); | |
| 358 | + LOAD_SEG(15, R_GS); | |
| 359 | +#endif | |
| 360 | +} | |
| 361 | + | |
| 362 | +#else | |
| 363 | + | |
| 364 | +static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) | |
| 365 | +{ | |
| 366 | + return 0; | |
| 367 | +} | |
| 368 | + | |
| 369 | +static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) | |
| 370 | +{ | |
| 371 | +} | |
| 372 | + | |
| 373 | +#endif | |
| 279 | 374 | |
| 280 | 375 | /* port = 0 means default port */ |
| 281 | 376 | int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) |
| 282 | 377 | { |
| 283 | 378 | CPUState *env; |
| 284 | 379 | const char *p; |
| 285 | - int ret, ch, nb_regs, i, type; | |
| 380 | + int ret, ch, reg_size, type; | |
| 286 | 381 | char buf[4096]; |
| 287 | 382 | uint8_t mem_buf[2000]; |
| 288 | 383 | uint32_t *registers; |
| ... | ... | @@ -339,47 +434,16 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) |
| 339 | 434 | break; |
| 340 | 435 | case 'g': |
| 341 | 436 | env = cpu_gdbstub_get_env(opaque); |
| 342 | - registers = (void *)mem_buf; | |
| 343 | -#if defined(TARGET_I386) | |
| 344 | - for(i = 0; i < 8; i++) { | |
| 345 | - registers[i] = tswapl(env->regs[i]); | |
| 346 | - } | |
| 347 | - registers[8] = env->eip; | |
| 348 | - registers[9] = env->eflags; | |
| 349 | - registers[10] = env->segs[R_CS].selector; | |
| 350 | - registers[11] = env->segs[R_SS].selector; | |
| 351 | - registers[12] = env->segs[R_DS].selector; | |
| 352 | - registers[13] = env->segs[R_ES].selector; | |
| 353 | - registers[14] = env->segs[R_FS].selector; | |
| 354 | - registers[15] = env->segs[R_GS].selector; | |
| 355 | - nb_regs = 16; | |
| 356 | -#endif | |
| 357 | - memtohex(buf, (const uint8_t *)registers, | |
| 358 | - sizeof(registers[0]) * nb_regs); | |
| 437 | + reg_size = cpu_gdb_read_registers(env, mem_buf); | |
| 438 | + memtohex(buf, mem_buf, reg_size); | |
| 359 | 439 | put_packet(buf); |
| 360 | 440 | break; |
| 361 | 441 | case 'G': |
| 362 | 442 | env = cpu_gdbstub_get_env(opaque); |
| 363 | 443 | registers = (void *)mem_buf; |
| 364 | -#if defined(TARGET_I386) | |
| 365 | - hextomem((uint8_t *)registers, p, 16 * 4); | |
| 366 | - for(i = 0; i < 8; i++) { | |
| 367 | - env->regs[i] = tswapl(registers[i]); | |
| 368 | - } | |
| 369 | - env->eip = registers[8]; | |
| 370 | - env->eflags = registers[9]; | |
| 371 | -#if defined(CONFIG_USER_ONLY) | |
| 372 | -#define LOAD_SEG(index, sreg)\ | |
| 373 | - if (tswapl(registers[index]) != env->segs[sreg].selector)\ | |
| 374 | - cpu_x86_load_seg(env, sreg, tswapl(registers[index])); | |
| 375 | - LOAD_SEG(10, R_CS); | |
| 376 | - LOAD_SEG(11, R_SS); | |
| 377 | - LOAD_SEG(12, R_DS); | |
| 378 | - LOAD_SEG(13, R_ES); | |
| 379 | - LOAD_SEG(14, R_FS); | |
| 380 | - LOAD_SEG(15, R_GS); | |
| 381 | -#endif | |
| 382 | -#endif | |
| 444 | + len = strlen(p) / 2; | |
| 445 | + hextomem((uint8_t *)registers, p, len); | |
| 446 | + cpu_gdb_write_registers(env, mem_buf, len); | |
| 383 | 447 | put_packet("OK"); |
| 384 | 448 | break; |
| 385 | 449 | case 'm': |
| ... | ... | @@ -445,6 +509,8 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) |
| 445 | 509 | put_packet("OK"); |
| 446 | 510 | } else if (!strncmp(p, "TStart", 6)) { |
| 447 | 511 | /* start log (gdb 'tstart' command) */ |
| 512 | + env = cpu_gdbstub_get_env(opaque); | |
| 513 | + tb_flush(env); | |
| 448 | 514 | cpu_set_log(CPU_LOG_ALL); |
| 449 | 515 | put_packet("OK"); |
| 450 | 516 | } else if (!strncmp(p, "TStop", 5)) { | ... | ... |