Changeset 4209 in vbox
- Timestamp:
- Aug 18, 2007 12:43:10 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGConsole.cpp
r4199 r4209 440 440 static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 441 441 static DECLCALLBACK(int) dbgcCmdStack(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 442 static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 443 static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 442 444 static DECLCALLBACK(int) dbgcCmdDumpMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 443 445 static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); … … 445 447 static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 446 448 static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 449 static DECLCALLBACK(int) dbgcCmdDumpTSS(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 447 450 static DECLCALLBACK(int) dbgcCmdInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 448 451 static DECLCALLBACK(int) dbgcCmdLog(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); … … 599 602 600 603 604 /** 'dg', 'dga', 'dl', 'dla', 'dt' arguments. */ 605 static const DBGCVARDESC g_aArgDumpDT[] = 606 { 607 /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */ 608 { 0, ~0, DBGCVAR_CAT_NUMBER, 0, "sel", "Selector or selector range." }, 609 { 0, ~0, DBGCVAR_CAT_POINTER, 0, "address", "Far address which selector should be dumped." }, 610 }; 611 612 613 /** 'di', 'dia' arguments. */ 614 static const DBGCVARDESC g_aArgDumpIDT[] = 615 { 616 /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */ 617 { 0, ~0, DBGCVAR_CAT_NUMBER, 0, "int", "The interrupt vector or interrupt vector range." }, 618 }; 619 620 601 621 /** 'dpd*' arguments. */ 602 622 static const DBGCVARDESC g_aArgDumpPD[] = … … 765 785 { "db", 0, 1, &g_aArgDumpMem[0], ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory in bytes." }, 766 786 { "dd", 0, 1, &g_aArgDumpMem[0], ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory in double words." }, 787 { "dg", 0, ~0, &g_aArgDumpDT[0], ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the global descriptor table (GDT)." }, 788 { "dga", 0, ~0, &g_aArgDumpDT[0], ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the global descriptor table (GDT) including not-present entries." }, 789 { "di", 0, ~0, &g_aArgDumpIDT[0], ELEMENTS(g_aArgDumpIDT), NULL, 0, dbgcCmdDumpIDT, "[int [..]]", "Dump the interrupt descriptor table (IDT)." }, 790 { "dia", 0, ~0, &g_aArgDumpIDT[0], ELEMENTS(g_aArgDumpIDT), NULL, 0, dbgcCmdDumpIDT, "[int [..]]", "Dump the interrupt descriptor table (IDT) including not-present entries." }, 791 { "dl", 0, ~0, &g_aArgDumpDT[0], ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the local descriptor table (LDT)." }, 792 { "dla", 0, ~0, &g_aArgDumpDT[0], ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpDT, "[sel [..]]", "Dump the local descriptor table (LDT) including not-present entries." }, 767 793 { "dpd", 0, 1, &g_aArgDumpPD[0], ELEMENTS(g_aArgDumpPD), NULL, 0, dbgcCmdDumpPageDir, "[addr] [index]", "Dumps page directory entries of the default context." }, 768 794 { "dpda", 0, 1, &g_aArgDumpPDAddr[0],ELEMENTS(g_aArgDumpPDAddr),NULL, 0, dbgcCmdDumpPageDir, "[addr]", "Dumps specified page directory." }, … … 776 802 { "dpth", 1, 1, &g_aArgDumpPT[0], ELEMENTS(g_aArgDumpPT), NULL, 0, dbgcCmdDumpPageTable,"<addr>", "Dumps page table entries of the hypervisor." }, 777 803 { "dq", 0, 1, &g_aArgDumpMem[0], ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory in quad words." }, 804 { "dt", 0, ~0, &g_aArgDumpDT[0], ELEMENTS(g_aArgDumpDT), NULL, 0, dbgcCmdDumpTSS, "[sel [..]]", "Dump the task switch segment (TSS)." }, 778 805 { "dw", 0, 1, &g_aArgDumpMem[0], ELEMENTS(g_aArgDumpMem), NULL, 0, dbgcCmdDumpMem, "[addr]", "Dump memory in words." }, 779 806 { "exit", 0, 0, NULL, 0, NULL, 0, dbgcCmdQuit, "", "Exits the debugger." }, … … 2491 2518 2492 2519 2493 2494 /** 2495 * The 'dd', 'dw' and 'db' commands. 2520 static int dbgcCmdDumpDTWorker64(PDBGCCMDHLP /*pCmdHlp*/, PCX86DESC64 /*pDesc*/, unsigned /*iEntry*/, bool /* fHyper */, bool * /*fDblEntry*/) 2521 { 2522 /* GUEST64 */ 2523 return VINF_SUCCESS; 2524 } 2525 2526 2527 /** 2528 * Wroker function that displays one descriptor entry (GDT, LDT, IDT). 2529 * 2530 * @returns pfnPrintf status code. 2531 * @param pCmdHlp The DBGC command helpers. 2532 * @param pDesc The descriptor to display. 2533 * @param iEntry The descriptor entry number. 2534 * @param fHyper Whether the selector belongs to the hypervisor or not. 2535 */ 2536 static int dbgcCmdDumpDTWorker32(PDBGCCMDHLP pCmdHlp, PCX86DESC pDesc, unsigned iEntry, bool fHyper) 2537 { 2538 int rc; 2539 2540 const char *pszHyper = fHyper ? " HYPER" : ""; 2541 const char *pszPresent = pDesc->Gen.u1Present ? "P " : "NP"; 2542 if (pDesc->Gen.u1DescType) 2543 { 2544 static const char * const s_apszTypes[] = 2545 { 2546 "DataRO", /* 0 Read-Only */ 2547 "DataRO", /* 1 Read-Only - Accessed */ 2548 "DataRW", /* 2 Read/Write */ 2549 "DataRW", /* 3 Read/Write - Accessed */ 2550 "DownRO", /* 4 Expand-down, Read-Only */ 2551 "DownRO", /* 5 Expand-down, Read-Only - Accessed */ 2552 "DownRW", /* 6 Expand-down, Read/Write */ 2553 "DownRO", /* 7 Expand-down, Read/Write - Accessed */ 2554 "CodeEO", /* 8 Execute-Only */ 2555 "CodeEO", /* 9 Execute-Only - Accessed */ 2556 "CodeER", /* A Execute/Readable */ 2557 "CodeER", /* B Execute/Readable - Accessed */ 2558 "ConfE0", /* C Conforming, Execute-Only */ 2559 "ConfE0", /* D Conforming, Execute-Only - Accessed */ 2560 "ConfER", /* E Conforming, Execute/Readable */ 2561 "ConfER" /* F Conforming, Execute/Readable - Accessed */ 2562 }; 2563 const char *pszAccessed = pDesc->Gen.u4Type & BIT(0) ? "A " : "NA"; 2564 const char *pszGranularity = pDesc->Gen.u1Granularity ? "G" : " "; 2565 const char *pszBig = pDesc->Gen.u1DefBig ? "BIG" : " "; 2566 uint32_t u32Base = pDesc->Gen.u16BaseLow 2567 | ((uint32_t)pDesc->Gen.u8BaseHigh1 << 16) 2568 | ((uint32_t)pDesc->Gen.u8BaseHigh2 << 24); 2569 uint32_t cbLimit = pDesc->Gen.u16LimitLow | (pDesc->Gen.u4LimitHigh << 16); 2570 if (pDesc->Gen.u1Granularity) 2571 cbLimit <<= PAGE_SHIFT; 2572 2573 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x %s Bas=%08x Lim=%08x DPL=%d %s %s %s %s AVL=%d R=%d%s\n", 2574 iEntry, s_apszTypes[pDesc->Gen.u4Type], u32Base, cbLimit, 2575 pDesc->Gen.u2Dpl, pszPresent, pszAccessed, pszGranularity, pszBig, 2576 pDesc->Gen.u1Available, pDesc->Gen.u1Reserved, pszHyper); 2577 } 2578 else 2579 { 2580 static const char * const s_apszTypes[] = 2581 { 2582 "Ill-0 ", /* 0 0000 Reserved (Illegal) */ 2583 "Tss16A", /* 1 0001 Available 16-bit TSS */ 2584 "LDT ", /* 2 0010 LDT */ 2585 "Tss16B", /* 3 0011 Busy 16-bit TSS */ 2586 "Call16", /* 4 0100 16-bit Call Gate */ 2587 "TaskG ", /* 5 0101 Task Gate */ 2588 "Int16 ", /* 6 0110 16-bit Interrupt Gate */ 2589 "Trap16", /* 7 0111 16-bit Trap Gate */ 2590 "Ill-8 ", /* 8 1000 Reserved (Illegal) */ 2591 "Tss32A", /* 9 1001 Available 32-bit TSS */ 2592 "Ill-A ", /* A 1010 Reserved (Illegal) */ 2593 "Tss32B", /* B 1011 Busy 32-bit TSS */ 2594 "Call32", /* C 1100 32-bit Call Gate */ 2595 "Ill-D ", /* D 1101 Reserved (Illegal) */ 2596 "Int32 ", /* E 1110 32-bit Interrupt Gate */ 2597 "Trap32" /* F 1111 32-bit Trap Gate */ 2598 }; 2599 switch (pDesc->Gen.u4Type) 2600 { 2601 /* raw */ 2602 case X86_SEL_TYPE_SYS_UNDEFINED: 2603 case X86_SEL_TYPE_SYS_UNDEFINED2: 2604 case X86_SEL_TYPE_SYS_UNDEFINED4: 2605 case X86_SEL_TYPE_SYS_UNDEFINED3: 2606 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x %s %.8Rhxs DPL=%d %s%s\n", 2607 iEntry, s_apszTypes[pDesc->Gen.u4Type], pDesc, 2608 pDesc->Gen.u2Dpl, pszPresent, pszHyper); 2609 break; 2610 2611 case X86_SEL_TYPE_SYS_286_TSS_AVAIL: 2612 case X86_SEL_TYPE_SYS_386_TSS_AVAIL: 2613 case X86_SEL_TYPE_SYS_286_TSS_BUSY: 2614 case X86_SEL_TYPE_SYS_386_TSS_BUSY: 2615 case X86_SEL_TYPE_SYS_LDT: 2616 { 2617 const char *pszGranularity = pDesc->Gen.u1Granularity ? "G" : " "; 2618 const char *pszBusy = pDesc->Gen.u4Type & BIT(1) ? "B " : "NB"; 2619 const char *pszBig = pDesc->Gen.u1DefBig ? "BIG" : " "; 2620 uint32_t u32Base = pDesc->Gen.u16BaseLow 2621 | ((uint32_t)pDesc->Gen.u8BaseHigh1 << 16) 2622 | ((uint32_t)pDesc->Gen.u8BaseHigh2 << 24); 2623 uint32_t cbLimit = pDesc->Gen.u16LimitLow | (pDesc->Gen.u4LimitHigh << 16); 2624 if (pDesc->Gen.u1Granularity) 2625 cbLimit <<= PAGE_SHIFT; 2626 2627 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x %s Bas=%08x Lim=%08x DPL=%d %s %s %s %s AVL=%d R=%d%s\n", 2628 iEntry, s_apszTypes[pDesc->Gen.u4Type], u32Base, cbLimit, 2629 pDesc->Gen.u2Dpl, pszPresent, pszBusy, pszGranularity, pszBig, 2630 pDesc->Gen.u1Available, pDesc->Gen.u1Reserved | (pDesc->Gen.u1DefBig << 1), 2631 pszHyper); 2632 break; 2633 } 2634 2635 case X86_SEL_TYPE_SYS_TASK_GATE: 2636 { 2637 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x %s TSS=%04x DPL=%d %s%s\n", 2638 iEntry, s_apszTypes[pDesc->Gen.u4Type], pDesc->au16[1], 2639 pDesc->Gen.u2Dpl, pszPresent, pszHyper); 2640 break; 2641 } 2642 2643 case X86_SEL_TYPE_SYS_286_CALL_GATE: 2644 case X86_SEL_TYPE_SYS_386_CALL_GATE: 2645 { 2646 unsigned cParams = pDesc->au8[0] & 0x1f; 2647 const char *pszCountOf = pDesc->Gen.u4Type & BIT(3) ? "DC" : "WC"; 2648 RTSEL sel = pDesc->au16[1]; 2649 uint32_t off = pDesc->au16[0] | ((uint32_t)pDesc->au16[3] << 16); 2650 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x %s Sel:Off=%04x:%08x DPL=%d %s %s=%d%s\n", 2651 iEntry, s_apszTypes[pDesc->Gen.u4Type], sel, off, 2652 pDesc->Gen.u2Dpl, pszPresent, pszCountOf, cParams, pszHyper); 2653 break; 2654 } 2655 2656 case X86_SEL_TYPE_SYS_286_INT_GATE: 2657 case X86_SEL_TYPE_SYS_386_INT_GATE: 2658 case X86_SEL_TYPE_SYS_286_TRAP_GATE: 2659 case X86_SEL_TYPE_SYS_386_TRAP_GATE: 2660 { 2661 RTSEL sel = pDesc->au16[1]; 2662 uint32_t off = pDesc->au16[0] | ((uint32_t)pDesc->au16[3] << 16); 2663 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x %s Sel:Off=%04x:%08x DPL=%d %s%s\n", 2664 iEntry, s_apszTypes[pDesc->Gen.u4Type], sel, off, 2665 pDesc->Gen.u2Dpl, pszPresent, pszHyper); 2666 break; 2667 } 2668 2669 /* impossible, just it's necessary to keep gcc happy. */ 2670 default: 2671 return VINF_SUCCESS; 2672 } 2673 } 2674 return rc; 2675 } 2676 2677 2678 /** 2679 * The 'dg', 'dga', 'dl' and 'dla' commands. 2680 * 2681 * @returns VBox status. 2682 * @param pCmd Pointer to the command descriptor (as registered). 2683 * @param pCmdHlp Pointer to command helper functions. 2684 * @param pVM Pointer to the current VM (if any). 2685 * @param paArgs Pointer to (readonly) array of arguments. 2686 * @param cArgs Number of arguments in the array. 2687 */ 2688 static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult) 2689 { 2690 /* 2691 * Validate input. 2692 */ 2693 if (!pVM) 2694 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: No VM.\n"); 2695 2696 /* 2697 * Get the CPU mode, check which command variation this is 2698 * and fix a default parameter if needed. 2699 */ 2700 CPUMMODE enmMode = CPUMGetGuestMode(pVM); 2701 bool fGdt = pCmd->pszCmd[1] == 'g'; 2702 bool fAll = pCmd->pszCmd[2] == 'a'; 2703 2704 DBGCVAR Var; 2705 if (!cArgs) 2706 { 2707 cArgs = 1; 2708 paArgs = &Var; 2709 Var.enmType = DBGCVAR_TYPE_NUMBER; 2710 Var.u.u64Number = fGdt ? 0 : 4; 2711 Var.enmRangeType = DBGCVAR_RANGE_ELEMENTS; 2712 Var.u64Range = 1024; 2713 } 2714 2715 /* 2716 * Process the arguments. 2717 */ 2718 for (unsigned i = 0; i < cArgs; i++) 2719 { 2720 /* 2721 * Retrive the selector value from the argument. 2722 * The parser may confuse pointers and numbers if more than one 2723 * argument is given, that that into account. 2724 */ 2725 /* check that what've got makes sense as we don't trust the parser yet. */ 2726 if ( paArgs[i].enmType != DBGCVAR_TYPE_NUMBER 2727 && !DBGCVAR_ISPOINTER(paArgs[i].enmType)) 2728 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: arg #%u isn't of number or pointer type but %d.\n", i, paArgs[i].enmType); 2729 unsigned u64; 2730 unsigned cSels = 1; 2731 switch (paArgs[i].enmType) 2732 { 2733 case DBGCVAR_TYPE_NUMBER: 2734 u64 = paArgs[i].u.u64Number; 2735 if (paArgs[i].enmRangeType != DBGCVAR_RANGE_NONE) 2736 cSels = RT_MIN(paArgs[i].u64Range, 1024); 2737 break; 2738 case DBGCVAR_TYPE_GC_FAR: u64 = paArgs[i].u.GCFar.sel; break; 2739 case DBGCVAR_TYPE_GC_FLAT: u64 = paArgs[i].u.GCFlat; break; 2740 case DBGCVAR_TYPE_GC_PHYS: u64 = paArgs[i].u.GCPhys; break; 2741 case DBGCVAR_TYPE_HC_FAR: u64 = paArgs[i].u.HCFar.sel; break; 2742 case DBGCVAR_TYPE_HC_FLAT: u64 = (uintptr_t)paArgs[i].u.pvHCFlat; break; 2743 case DBGCVAR_TYPE_HC_PHYS: u64 = paArgs[i].u.HCPhys; break; 2744 default: u64 = _64K; break; 2745 } 2746 if (u64 < _64K) 2747 { 2748 unsigned Sel = (RTSEL)u64; 2749 2750 /* 2751 * Dump the specified range. 2752 */ 2753 bool fSingle = cSels == 1; 2754 while ( cSels-- > 0 2755 && Sel < _64K) 2756 { 2757 SELMSELINFO SelInfo; 2758 int rc = SELMR3GetSelectorInfo(pVM, Sel, &SelInfo); 2759 if (RT_SUCCESS(rc)) 2760 { 2761 if (SelInfo.fRealMode) 2762 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x RealM Bas=%04x Lim=%04x\n", 2763 Sel, (unsigned)SelInfo.GCPtrBase, (unsigned)SelInfo.cbLimit); 2764 else if (fAll || fSingle || SelInfo.Raw.Gen.u1Present) 2765 { 2766 if (enmMode == CPUMMODE_PROTECTED) 2767 rc = dbgcCmdDumpDTWorker32(pCmdHlp, (PX86DESC)&SelInfo.Raw, Sel, SelInfo.fHyper); 2768 else 2769 { 2770 bool fDblSkip = false; 2771 rc = dbgcCmdDumpDTWorker64(pCmdHlp, (PX86DESC64)&SelInfo.Raw, Sel, SelInfo.fHyper, &fDblSkip); 2772 if (fDblSkip) 2773 Sel += 4; 2774 } 2775 } 2776 } 2777 else 2778 { 2779 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x %Vrc\n", Sel, rc); 2780 if (!fAll) 2781 return rc; 2782 } 2783 if (RT_FAILURE(rc)) 2784 return rc; 2785 2786 /* next */ 2787 Sel += 4; 2788 } 2789 } 2790 else 2791 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: %llx is out of bounds\n", u64); 2792 } 2793 2794 NOREF(pResult); 2795 return VINF_SUCCESS; 2796 } 2797 2798 2799 /** 2800 * The 'di' and 'dia' commands. 2801 * 2802 * @returns VBox status. 2803 * @param pCmd Pointer to the command descriptor (as registered). 2804 * @param pCmdHlp Pointer to command helper functions. 2805 * @param pVM Pointer to the current VM (if any). 2806 * @param paArgs Pointer to (readonly) array of arguments. 2807 * @param cArgs Number of arguments in the array. 2808 */ 2809 static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult) 2810 { 2811 /* 2812 * Validate input. 2813 */ 2814 if (!pVM) 2815 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: No VM.\n"); 2816 2817 /* 2818 * Establish some stuff like the current IDTR and CPU mode, 2819 * and fix a default parameter. 2820 */ 2821 uint16_t cbLimit; 2822 RTGCUINTPTR GCPtrBase = CPUMGetGuestIDTR(pVM, &cbLimit); 2823 CPUMMODE enmMode = CPUMGetGuestMode(pVM); 2824 size_t cbEntry; 2825 switch (enmMode) 2826 { 2827 case CPUMMODE_REAL: cbEntry = sizeof(RTFAR16); break; 2828 case CPUMMODE_PROTECTED: cbEntry = sizeof(X86DESC); break; 2829 case CPUMMODE_LONG: cbEntry = sizeof(X86DESC64); break; 2830 default: 2831 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid CPU mode %d.\n", enmMode); 2832 } 2833 2834 bool fAll = pCmd->pszCmd[2] == 'a'; 2835 DBGCVAR Var; 2836 if (!cArgs) 2837 { 2838 cArgs = 1; 2839 paArgs = &Var; 2840 Var.enmType = DBGCVAR_TYPE_NUMBER; 2841 Var.u.u64Number = 0; 2842 Var.enmRangeType = DBGCVAR_RANGE_ELEMENTS; 2843 Var.u64Range = 256; 2844 } 2845 2846 /* 2847 * Process the arguments. 2848 */ 2849 for (unsigned i = 0; i < cArgs; i++) 2850 { 2851 /* check that what've got makes sense as we don't trust the parser yet. */ 2852 if (paArgs[i].enmType != DBGCVAR_TYPE_NUMBER) 2853 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: arg #%u isn't of number type but %d.\n", i, paArgs[i].enmType); 2854 if (paArgs[i].u.u64Number < 256) 2855 { 2856 RTGCUINTPTR iInt = paArgs[i].u.u64Number; 2857 unsigned cInts = paArgs[i].enmRangeType != DBGCVAR_RANGE_NONE 2858 ? paArgs[i].u64Range 2859 : 1; 2860 bool fSingle = cInts == 1; 2861 while ( cInts-- > 0 2862 && iInt < 256) 2863 { 2864 /* 2865 * Try read it. 2866 */ 2867 union 2868 { 2869 RTFAR16 Real; 2870 X86DESC Prot; 2871 X86DESC64 Long; 2872 } u; 2873 if (iInt * cbEntry + (cbEntry - 1) > cbLimit) 2874 { 2875 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x not within the IDT\n", (unsigned)iInt); 2876 if (!fAll && !fSingle) 2877 return VINF_SUCCESS; 2878 } 2879 DBGCVAR AddrVar; 2880 AddrVar.enmType = DBGCVAR_TYPE_GC_FLAT; 2881 AddrVar.u.GCFlat = GCPtrBase + iInt * cbEntry; 2882 AddrVar.enmRangeType = DBGCVAR_RANGE_NONE; 2883 int rc = pCmdHlp->pfnMemRead(pCmdHlp, pVM, &u, cbEntry, &AddrVar, NULL); 2884 if (VBOX_FAILURE(rc)) 2885 return pCmdHlp->pfnVBoxError(pCmdHlp, rc, "Reading IDT entry %#04x.\n", (unsigned)iInt); 2886 2887 /* 2888 * Display it. 2889 */ 2890 switch (enmMode) 2891 { 2892 case CPUMMODE_REAL: 2893 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "%04x %RTfp16\n", (unsigned)iInt, u.Real); 2894 /** @todo resolve 16:16 IDTE to a symbol */ 2895 break; 2896 case CPUMMODE_PROTECTED: 2897 if (fAll || fSingle || u.Prot.Gen.u1Present) 2898 rc = dbgcCmdDumpDTWorker32(pCmdHlp, &u.Prot, iInt, false); 2899 break; 2900 case CPUMMODE_LONG: 2901 if (fAll || fSingle || u.Long.Gen.u1Present) 2902 rc = dbgcCmdDumpDTWorker64(pCmdHlp, &u.Long, iInt, false, NULL); 2903 break; 2904 default: break; /* to shut up gcc */ 2905 } 2906 if (RT_FAILURE(rc)) 2907 return rc; 2908 2909 /* next */ 2910 iInt++; 2911 } 2912 } 2913 else 2914 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: %llx is out of bounds (max 256)\n", paArgs[i].u.u64Number); 2915 } 2916 2917 NOREF(pResult); 2918 return VINF_SUCCESS; 2919 } 2920 2921 2922 /** 2923 * The 'da', 'dq', 'dd', 'dw' and 'db' commands. 2496 2924 * 2497 2925 * @returns VBox status. … … 3072 3500 NOREF(pCmd); NOREF(cArgs); NOREF(pResult); 3073 3501 return rc2; 3502 } 3503 3504 3505 /** 3506 * The 'dt' command. 3507 * 3508 * @returns VBox status. 3509 * @param pCmd Pointer to the command descriptor (as registered). 3510 * @param pCmdHlp Pointer to command helper functions. 3511 * @param pVM Pointer to the current VM (if any). 3512 * @param paArgs Pointer to (readonly) array of arguments. 3513 * @param cArgs Number of arguments in the array. 3514 */ 3515 static DECLCALLBACK(int) dbgcCmdDumpTSS(PCDBGCCMD /*pCmd*/, PDBGCCMDHLP pCmdHlp, PVM /*pVM*/, PCDBGCVAR /*paArgs*/, unsigned /*cArgs*/, PDBGCVAR /*pResult*/) 3516 { 3517 /** @todo */ 3518 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "dt is not implemented yet, feel free to do it. \n"); 3074 3519 } 3075 3520 … … 5793 6238 cb = (SelInfo.Raw.Gen.u1Granularity ? UINT32_C(0xffffffff) : UINT32_C(0xffff)) - Address.off; 5794 6239 } 5795 else 6240 else 5796 6241 { 5797 6242 if (Address.off >= SelInfo.cbLimit)
Note:
See TracChangeset
for help on using the changeset viewer.