Commit a3867ed24c50824dc454b43f23969b9ea3754e75

Authored by aliguori
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
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",
... ...