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 | 82 | #define DESC_AVL_MASK (1 << 20) |
83 | 83 | #define DESC_P_MASK (1 << 15) |
84 | 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 | 86 | #define DESC_S_MASK (1 << 12) |
87 | 87 | #define DESC_TYPE_SHIFT 8 |
88 | +#define DESC_TYPE_MASK (15 << DESC_TYPE_SHIFT) | |
88 | 89 | #define DESC_A_MASK (1 << 8) |
89 | 90 | |
90 | 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 | 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 | 628 | void cpu_dump_state(CPUState *env, FILE *f, |
574 | 629 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...), |
575 | 630 | int flags) |
... | ... | @@ -648,27 +703,15 @@ void cpu_dump_state(CPUState *env, FILE *f, |
648 | 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 | 713 | #ifdef TARGET_X86_64 |
652 | 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 | 715 | cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n", |
673 | 716 | env->gdt.base, env->gdt.limit); |
674 | 717 | cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n", |
... | ... | @@ -685,25 +728,6 @@ void cpu_dump_state(CPUState *env, FILE *f, |
685 | 728 | } else |
686 | 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 | 731 | cpu_fprintf(f, "GDT= %08x %08x\n", |
708 | 732 | (uint32_t)env->gdt.base, env->gdt.limit); |
709 | 733 | cpu_fprintf(f, "IDT= %08x %08x\n", | ... | ... |