Commit a3867ed24c50824dc454b43f23969b9ea3754e75
1 parent
7e9bbc9f
x86: Enhanced dump of segment registers (Jan Kiszka)
Parse the descriptor flags that segment registers refer to and show the result in a more human-friendly format. The output of info registers eg. then looks like this: [...] ES =007b 00000000 ffffffff 00cff300 DPL=3 DS [-WA] CS =0060 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA] SS =0068 00000000 ffffffff 00c09300 DPL=0 DS [-WA] DS =007b 00000000 ffffffff 00cff300 DPL=3 DS [-WA] FS =0000 00000000 00000000 00000000 GS =0033 b7dd66c0 ffffffff b7dff3dd DPL=3 DS [-WA] LDT=0000 00000000 00000000 00008200 DPL=0 LDT TR =0080 c06da700 0000206b 00008900 DPL=0 TSS32-avl [...] Changes in this version: - refactoring so that only a single helper is used for dumping the segment descriptor cache - tiny typo fixed that broke 64-bit segment type names Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7179 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
64 additions
and
39 deletions
target-i386/cpu.h
@@ -82,9 +82,10 @@ | @@ -82,9 +82,10 @@ | ||
82 | #define DESC_AVL_MASK (1 << 20) | 82 | #define DESC_AVL_MASK (1 << 20) |
83 | #define DESC_P_MASK (1 << 15) | 83 | #define DESC_P_MASK (1 << 15) |
84 | #define DESC_DPL_SHIFT 13 | 84 | #define DESC_DPL_SHIFT 13 |
85 | -#define DESC_DPL_MASK (1 << DESC_DPL_SHIFT) | 85 | +#define DESC_DPL_MASK (3 << DESC_DPL_SHIFT) |
86 | #define DESC_S_MASK (1 << 12) | 86 | #define DESC_S_MASK (1 << 12) |
87 | #define DESC_TYPE_SHIFT 8 | 87 | #define DESC_TYPE_SHIFT 8 |
88 | +#define DESC_TYPE_MASK (15 << DESC_TYPE_SHIFT) | ||
88 | #define DESC_A_MASK (1 << 8) | 89 | #define DESC_A_MASK (1 << 8) |
89 | 90 | ||
90 | #define DESC_CS_MASK (1 << 11) /* 1=code segment 0=data segment */ | 91 | #define DESC_CS_MASK (1 << 11) /* 1=code segment 0=data segment */ |
target-i386/helper.c
@@ -570,6 +570,61 @@ static const char *cc_op_str[] = { | @@ -570,6 +570,61 @@ static const char *cc_op_str[] = { | ||
570 | "SARQ", | 570 | "SARQ", |
571 | }; | 571 | }; |
572 | 572 | ||
573 | +static void | ||
574 | +cpu_x86_dump_seg_cache(CPUState *env, FILE *f, | ||
575 | + int (*cpu_fprintf)(FILE *f, const char *fmt, ...), | ||
576 | + const char *name, struct SegmentCache *sc) | ||
577 | +{ | ||
578 | +#ifdef TARGET_X86_64 | ||
579 | + if (env->hflags & HF_CS64_MASK) { | ||
580 | + cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name, | ||
581 | + sc->selector, sc->base, sc->limit, sc->flags); | ||
582 | + } else | ||
583 | +#endif | ||
584 | + { | ||
585 | + cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector, | ||
586 | + (uint32_t)sc->base, sc->limit, sc->flags); | ||
587 | + } | ||
588 | + | ||
589 | + if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK)) | ||
590 | + goto done; | ||
591 | + | ||
592 | + cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT); | ||
593 | + if (sc->flags & DESC_S_MASK) { | ||
594 | + if (sc->flags & DESC_CS_MASK) { | ||
595 | + cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" : | ||
596 | + ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16")); | ||
597 | + cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-', | ||
598 | + (sc->flags & DESC_R_MASK) ? 'R' : '-'); | ||
599 | + } else { | ||
600 | + cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS " : "DS16"); | ||
601 | + cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-', | ||
602 | + (sc->flags & DESC_W_MASK) ? 'W' : '-'); | ||
603 | + } | ||
604 | + cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-'); | ||
605 | + } else { | ||
606 | + static const char *sys_type_name[2][16] = { | ||
607 | + { /* 32 bit mode */ | ||
608 | + "Reserved", "TSS16-avl", "LDT", "TSS16-busy", | ||
609 | + "CallGate16", "TaskGate", "IntGate16", "TrapGate16", | ||
610 | + "Reserved", "TSS32-avl", "Reserved", "TSS32-busy", | ||
611 | + "CallGate32", "Reserved", "IntGate32", "TrapGate32" | ||
612 | + }, | ||
613 | + { /* 64 bit mode */ | ||
614 | + "<hiword>", "Reserved", "LDT", "Reserved", "Reserved", | ||
615 | + "Reserved", "Reserved", "Reserved", "Reserved", | ||
616 | + "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64", | ||
617 | + "Reserved", "IntGate64", "TrapGate64" | ||
618 | + } | ||
619 | + }; | ||
620 | + cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0] | ||
621 | + [(sc->flags & DESC_TYPE_MASK) | ||
622 | + >> DESC_TYPE_SHIFT]); | ||
623 | + } | ||
624 | +done: | ||
625 | + cpu_fprintf(f, "\n"); | ||
626 | +} | ||
627 | + | ||
573 | void cpu_dump_state(CPUState *env, FILE *f, | 628 | void cpu_dump_state(CPUState *env, FILE *f, |
574 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...), | 629 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...), |
575 | int flags) | 630 | int flags) |
@@ -648,27 +703,15 @@ void cpu_dump_state(CPUState *env, FILE *f, | @@ -648,27 +703,15 @@ void cpu_dump_state(CPUState *env, FILE *f, | ||
648 | env->halted); | 703 | env->halted); |
649 | } | 704 | } |
650 | 705 | ||
706 | + for(i = 0; i < 6; i++) { | ||
707 | + cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i], | ||
708 | + &env->segs[i]); | ||
709 | + } | ||
710 | + cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt); | ||
711 | + cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr); | ||
712 | + | ||
651 | #ifdef TARGET_X86_64 | 713 | #ifdef TARGET_X86_64 |
652 | if (env->hflags & HF_LMA_MASK) { | 714 | if (env->hflags & HF_LMA_MASK) { |
653 | - for(i = 0; i < 6; i++) { | ||
654 | - SegmentCache *sc = &env->segs[i]; | ||
655 | - cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n", | ||
656 | - seg_name[i], | ||
657 | - sc->selector, | ||
658 | - sc->base, | ||
659 | - sc->limit, | ||
660 | - sc->flags); | ||
661 | - } | ||
662 | - cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n", | ||
663 | - env->ldt.selector, | ||
664 | - env->ldt.base, | ||
665 | - env->ldt.limit, | ||
666 | - env->ldt.flags); | ||
667 | - cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n", | ||
668 | - env->tr.selector, | ||
669 | - env->tr.base, | ||
670 | - env->tr.limit, | ||
671 | - env->tr.flags); | ||
672 | cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n", | 715 | cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n", |
673 | env->gdt.base, env->gdt.limit); | 716 | env->gdt.base, env->gdt.limit); |
674 | cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n", | 717 | cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n", |
@@ -685,25 +728,6 @@ void cpu_dump_state(CPUState *env, FILE *f, | @@ -685,25 +728,6 @@ void cpu_dump_state(CPUState *env, FILE *f, | ||
685 | } else | 728 | } else |
686 | #endif | 729 | #endif |
687 | { | 730 | { |
688 | - for(i = 0; i < 6; i++) { | ||
689 | - SegmentCache *sc = &env->segs[i]; | ||
690 | - cpu_fprintf(f, "%s =%04x %08x %08x %08x\n", | ||
691 | - seg_name[i], | ||
692 | - sc->selector, | ||
693 | - (uint32_t)sc->base, | ||
694 | - sc->limit, | ||
695 | - sc->flags); | ||
696 | - } | ||
697 | - cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n", | ||
698 | - env->ldt.selector, | ||
699 | - (uint32_t)env->ldt.base, | ||
700 | - env->ldt.limit, | ||
701 | - env->ldt.flags); | ||
702 | - cpu_fprintf(f, "TR =%04x %08x %08x %08x\n", | ||
703 | - env->tr.selector, | ||
704 | - (uint32_t)env->tr.base, | ||
705 | - env->tr.limit, | ||
706 | - env->tr.flags); | ||
707 | cpu_fprintf(f, "GDT= %08x %08x\n", | 731 | cpu_fprintf(f, "GDT= %08x %08x\n", |
708 | (uint32_t)env->gdt.base, env->gdt.limit); | 732 | (uint32_t)env->gdt.base, env->gdt.limit); |
709 | cpu_fprintf(f, "IDT= %08x %08x\n", | 733 | cpu_fprintf(f, "IDT= %08x %08x\n", |