Commit b1631e7a6f63150ce07747a93fc98ff7d5ee766b
Committed by
Anthony Liguori
1 parent
dd32aa10
gdbstub: x86: Refactor register access
Clarify gdb's register set layout by using constants for cpu_gdb_read/write_register. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
1 changed file
with
83 additions
and
73 deletions
gdbstub.c
... | ... | @@ -511,111 +511,121 @@ static const int gpr_map[8] = {0, 1, 2, 3, 4, 5, 6, 7}; |
511 | 511 | |
512 | 512 | #define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25) |
513 | 513 | |
514 | +#define IDX_IP_REG CPU_NB_REGS | |
515 | +#define IDX_FLAGS_REG (IDX_IP_REG + 1) | |
516 | +#define IDX_SEG_REGS (IDX_FLAGS_REG + 1) | |
517 | +#define IDX_FP_REGS (IDX_SEG_REGS + 6) | |
518 | +#define IDX_XMM_REGS (IDX_FP_REGS + 16) | |
519 | +#define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS) | |
520 | + | |
514 | 521 | static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n) |
515 | 522 | { |
516 | 523 | if (n < CPU_NB_REGS) { |
517 | 524 | GET_REGL(env->regs[gpr_map[n]]); |
518 | - } else if (n >= CPU_NB_REGS + 8 && n < CPU_NB_REGS + 16) { | |
519 | - /* FIXME: byteswap float values. */ | |
525 | + } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { | |
520 | 526 | #ifdef USE_X86LDOUBLE |
521 | - memcpy(mem_buf, &env->fpregs[n - (CPU_NB_REGS + 8)], 10); | |
527 | + /* FIXME: byteswap float values - after fixing fpregs layout. */ | |
528 | + memcpy(mem_buf, &env->fpregs[n - IDX_FP_REGS], 10); | |
522 | 529 | #else |
523 | 530 | memset(mem_buf, 0, 10); |
524 | 531 | #endif |
525 | 532 | return 10; |
526 | - } else if (n >= CPU_NB_REGS + 24) { | |
527 | - n -= CPU_NB_REGS + 24; | |
528 | - if (n < CPU_NB_REGS) { | |
529 | - stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0)); | |
530 | - stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1)); | |
531 | - return 16; | |
532 | - } else if (n == CPU_NB_REGS) { | |
533 | - GET_REG32(env->mxcsr); | |
534 | - } | |
533 | + } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { | |
534 | + n -= IDX_XMM_REGS; | |
535 | + stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0)); | |
536 | + stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1)); | |
537 | + return 16; | |
535 | 538 | } else { |
536 | - n -= CPU_NB_REGS; | |
537 | 539 | switch (n) { |
538 | - case 0: GET_REGL(env->eip); | |
539 | - case 1: GET_REG32(env->eflags); | |
540 | - case 2: GET_REG32(env->segs[R_CS].selector); | |
541 | - case 3: GET_REG32(env->segs[R_SS].selector); | |
542 | - case 4: GET_REG32(env->segs[R_DS].selector); | |
543 | - case 5: GET_REG32(env->segs[R_ES].selector); | |
544 | - case 6: GET_REG32(env->segs[R_FS].selector); | |
545 | - case 7: GET_REG32(env->segs[R_GS].selector); | |
546 | - /* 8...15 x87 regs. */ | |
547 | - case 16: GET_REG32(env->fpuc); | |
548 | - case 17: GET_REG32((env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11); | |
549 | - case 18: GET_REG32(0); /* ftag */ | |
550 | - case 19: GET_REG32(0); /* fiseg */ | |
551 | - case 20: GET_REG32(0); /* fioff */ | |
552 | - case 21: GET_REG32(0); /* foseg */ | |
553 | - case 22: GET_REG32(0); /* fooff */ | |
554 | - case 23: GET_REG32(0); /* fop */ | |
555 | - /* 24+ xmm regs. */ | |
540 | + case IDX_IP_REG: GET_REGL(env->eip); | |
541 | + case IDX_FLAGS_REG: GET_REG32(env->eflags); | |
542 | + | |
543 | + case IDX_SEG_REGS: GET_REG32(env->segs[R_CS].selector); | |
544 | + case IDX_SEG_REGS + 1: GET_REG32(env->segs[R_SS].selector); | |
545 | + case IDX_SEG_REGS + 2: GET_REG32(env->segs[R_DS].selector); | |
546 | + case IDX_SEG_REGS + 3: GET_REG32(env->segs[R_ES].selector); | |
547 | + case IDX_SEG_REGS + 4: GET_REG32(env->segs[R_FS].selector); | |
548 | + case IDX_SEG_REGS + 5: GET_REG32(env->segs[R_GS].selector); | |
549 | + | |
550 | + case IDX_FP_REGS + 8: GET_REG32(env->fpuc); | |
551 | + case IDX_FP_REGS + 9: GET_REG32((env->fpus & ~0x3800) | | |
552 | + (env->fpstt & 0x7) << 11); | |
553 | + case IDX_FP_REGS + 10: GET_REG32(0); /* ftag */ | |
554 | + case IDX_FP_REGS + 11: GET_REG32(0); /* fiseg */ | |
555 | + case IDX_FP_REGS + 12: GET_REG32(0); /* fioff */ | |
556 | + case IDX_FP_REGS + 13: GET_REG32(0); /* foseg */ | |
557 | + case IDX_FP_REGS + 14: GET_REG32(0); /* fooff */ | |
558 | + case IDX_FP_REGS + 15: GET_REG32(0); /* fop */ | |
559 | + | |
560 | + case IDX_MXCSR_REG: GET_REG32(env->mxcsr); | |
556 | 561 | } |
557 | 562 | } |
558 | 563 | return 0; |
559 | 564 | } |
560 | 565 | |
561 | -static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int i) | |
566 | +static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n) | |
562 | 567 | { |
563 | 568 | uint32_t tmp; |
564 | 569 | |
565 | - if (i < CPU_NB_REGS) { | |
566 | - env->regs[gpr_map[i]] = ldtul_p(mem_buf); | |
570 | + if (n < CPU_NB_REGS) { | |
571 | + env->regs[gpr_map[n]] = ldtul_p(mem_buf); | |
567 | 572 | return sizeof(target_ulong); |
568 | - } else if (i >= CPU_NB_REGS + 8 && i < CPU_NB_REGS + 16) { | |
569 | - i -= CPU_NB_REGS + 8; | |
573 | + } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { | |
570 | 574 | #ifdef USE_X86LDOUBLE |
571 | - memcpy(&env->fpregs[i], mem_buf, 10); | |
575 | + /* FIXME: byteswap float values - after fixing fpregs layout. */ | |
576 | + memcpy(&env->fpregs[n - IDX_FP_REGS], mem_buf, 10); | |
572 | 577 | #endif |
573 | 578 | return 10; |
574 | - } else if (i >= CPU_NB_REGS + 24) { | |
575 | - i -= CPU_NB_REGS + 24; | |
576 | - if (i < CPU_NB_REGS) { | |
577 | - env->xmm_regs[i].XMM_Q(0) = ldq_p(mem_buf); | |
578 | - env->xmm_regs[i].XMM_Q(1) = ldq_p(mem_buf + 8); | |
579 | - return 16; | |
580 | - } else if (i == CPU_NB_REGS) { | |
581 | - env->mxcsr = ldl_p(mem_buf); | |
582 | - return 4; | |
583 | - } | |
579 | + } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { | |
580 | + n -= IDX_XMM_REGS; | |
581 | + env->xmm_regs[n].XMM_Q(0) = ldq_p(mem_buf); | |
582 | + env->xmm_regs[n].XMM_Q(1) = ldq_p(mem_buf + 8); | |
583 | + return 16; | |
584 | 584 | } else { |
585 | - i -= CPU_NB_REGS; | |
586 | - switch (i) { | |
587 | - case 0: env->eip = ldtul_p(mem_buf); return sizeof(target_ulong); | |
588 | - case 1: env->eflags = ldl_p(mem_buf); return 4; | |
585 | + switch (n) { | |
586 | + case IDX_IP_REG: | |
587 | + env->eip = ldtul_p(mem_buf); | |
588 | + return sizeof(target_ulong); | |
589 | + case IDX_FLAGS_REG: | |
590 | + env->eflags = ldl_p(mem_buf); | |
591 | + return 4; | |
592 | + | |
589 | 593 | #if defined(CONFIG_USER_ONLY) |
590 | 594 | #define LOAD_SEG(index, sreg)\ |
591 | 595 | tmp = ldl_p(mem_buf);\ |
592 | 596 | if (tmp != env->segs[sreg].selector)\ |
593 | - cpu_x86_load_seg(env, sreg, tmp); | |
597 | + cpu_x86_load_seg(env, sreg, tmp);\ | |
598 | + return 4 | |
594 | 599 | #else |
595 | 600 | /* FIXME: Honor segment registers. Needs to avoid raising an exception |
596 | 601 | when the selector is invalid. */ |
597 | -#define LOAD_SEG(index, sreg) do {} while(0) | |
602 | +#define LOAD_SEG(index, sreg) return 4 | |
598 | 603 | #endif |
599 | - case 2: LOAD_SEG(10, R_CS); return 4; | |
600 | - case 3: LOAD_SEG(11, R_SS); return 4; | |
601 | - case 4: LOAD_SEG(12, R_DS); return 4; | |
602 | - case 5: LOAD_SEG(13, R_ES); return 4; | |
603 | - case 6: LOAD_SEG(14, R_FS); return 4; | |
604 | - case 7: LOAD_SEG(15, R_GS); return 4; | |
605 | - /* 8...15 x87 regs. */ | |
606 | - case 16: env->fpuc = ldl_p(mem_buf); return 4; | |
607 | - case 17: | |
608 | - tmp = ldl_p(mem_buf); | |
609 | - env->fpstt = (tmp >> 11) & 7; | |
610 | - env->fpus = tmp & ~0x3800; | |
611 | - return 4; | |
612 | - case 18: /* ftag */ return 4; | |
613 | - case 19: /* fiseg */ return 4; | |
614 | - case 20: /* fioff */ return 4; | |
615 | - case 21: /* foseg */ return 4; | |
616 | - case 22: /* fooff */ return 4; | |
617 | - case 23: /* fop */ return 4; | |
618 | - /* 24+ xmm regs. */ | |
604 | + case IDX_SEG_REGS: LOAD_SEG(10, R_CS); | |
605 | + case IDX_SEG_REGS + 1: LOAD_SEG(11, R_SS); | |
606 | + case IDX_SEG_REGS + 2: LOAD_SEG(12, R_DS); | |
607 | + case IDX_SEG_REGS + 3: LOAD_SEG(13, R_ES); | |
608 | + case IDX_SEG_REGS + 4: LOAD_SEG(14, R_FS); | |
609 | + case IDX_SEG_REGS + 5: LOAD_SEG(15, R_GS); | |
610 | + | |
611 | + case IDX_FP_REGS + 8: | |
612 | + env->fpuc = ldl_p(mem_buf); | |
613 | + return 4; | |
614 | + case IDX_FP_REGS + 9: | |
615 | + tmp = ldl_p(mem_buf); | |
616 | + env->fpstt = (tmp >> 11) & 7; | |
617 | + env->fpus = tmp & ~0x3800; | |
618 | + return 4; | |
619 | + case IDX_FP_REGS + 10: /* ftag */ return 4; | |
620 | + case IDX_FP_REGS + 11: /* fiseg */ return 4; | |
621 | + case IDX_FP_REGS + 12: /* fioff */ return 4; | |
622 | + case IDX_FP_REGS + 13: /* foseg */ return 4; | |
623 | + case IDX_FP_REGS + 14: /* fooff */ return 4; | |
624 | + case IDX_FP_REGS + 15: /* fop */ return 4; | |
625 | + | |
626 | + case IDX_MXCSR_REG: | |
627 | + env->mxcsr = ldl_p(mem_buf); | |
628 | + return 4; | |
619 | 629 | } |
620 | 630 | } |
621 | 631 | /* Unrecognised register. */ | ... | ... |