VirtualBox

Changeset 4209 in vbox


Ignore:
Timestamp:
Aug 18, 2007 12:43:10 AM (17 years ago)
Author:
vboxsync
Message:

Added dt, dl, di and dt (latter not implemented).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGConsole.cpp

    r4199 r4209  
    440440static DECLCALLBACK(int) dbgcCmdTrace(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    441441static DECLCALLBACK(int) dbgcCmdStack(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     442static DECLCALLBACK(int) dbgcCmdDumpDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     443static DECLCALLBACK(int) dbgcCmdDumpIDT(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    442444static DECLCALLBACK(int) dbgcCmdDumpMem(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    443445static DECLCALLBACK(int) dbgcCmdDumpPageDir(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     
    445447static DECLCALLBACK(int) dbgcCmdDumpPageTable(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    446448static DECLCALLBACK(int) dbgcCmdDumpPageTableBoth(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     449static DECLCALLBACK(int) dbgcCmdDumpTSS(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    447450static DECLCALLBACK(int) dbgcCmdInfo(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    448451static DECLCALLBACK(int) dbgcCmdLog(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     
    599602
    600603
     604/** 'dg', 'dga', 'dl', 'dla', 'dt' arguments. */
     605static 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. */
     614static 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
    601621/** 'dpd*' arguments. */
    602622static const DBGCVARDESC    g_aArgDumpPD[] =
     
    765785    { "db",         0,        1,        &g_aArgDumpMem[0],  ELEMENTS(g_aArgDumpMem),    NULL,               0,          dbgcCmdDumpMem,     "[addr]",               "Dump memory in bytes." },
    766786    { "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." },
    767793    { "dpd",        0,        1,        &g_aArgDumpPD[0],   ELEMENTS(g_aArgDumpPD),     NULL,               0,          dbgcCmdDumpPageDir, "[addr] [index]",       "Dumps page directory entries of the default context." },
    768794    { "dpda",       0,        1,        &g_aArgDumpPDAddr[0],ELEMENTS(g_aArgDumpPDAddr),NULL,               0,          dbgcCmdDumpPageDir, "[addr]",               "Dumps specified page directory." },
     
    776802    { "dpth",       1,        1,        &g_aArgDumpPT[0],   ELEMENTS(g_aArgDumpPT),     NULL,               0,          dbgcCmdDumpPageTable,"<addr>",              "Dumps page table entries of the hypervisor." },
    777803    { "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)." },
    778805    { "dw",         0,        1,        &g_aArgDumpMem[0],  ELEMENTS(g_aArgDumpMem),    NULL,               0,          dbgcCmdDumpMem,     "[addr]",               "Dump memory in words." },
    779806    { "exit",       0,        0,        NULL,               0,                          NULL,               0,          dbgcCmdQuit,        "",                     "Exits the debugger." },
     
    24912518
    24922519
    2493 
    2494 /**
    2495  * The 'dd', 'dw' and 'db' commands.
     2520static 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 */
     2536static 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 */
     2688static 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 */
     2809static 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.
    24962924 *
    24972925 * @returns VBox status.
     
    30723500    NOREF(pCmd); NOREF(cArgs); NOREF(pResult);
    30733501    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 */
     3515static 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");
    30743519}
    30753520
     
    57936238                        cb = (SelInfo.Raw.Gen.u1Granularity ? UINT32_C(0xffffffff) : UINT32_C(0xffff)) - Address.off;
    57946239                    }
    5795                     else 
     6240                    else
    57966241                    {
    57976242                        if (Address.off >= SelInfo.cbLimit)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette