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", | ... | ... |