VirtualBox

Changeset 103554 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Feb 23, 2024 11:26:09 PM (13 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
161904
Message:

VMM/IEM: Some simple TB disassembly interface that can be used from the debugger ('info tb'). bugref:10370

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r103516 r103554  
    3131*********************************************************************************************************************************/
    3232#define LOG_GROUP LOG_GROUP_EM
     33#define VMCPU_INCL_CPUM_GST_CTX
    3334#include <VBox/vmm/iem.h>
    3435#include <VBox/vmm/cpum.h>
     
    5152#include <iprt/string.h>
    5253
    53 #if defined(VBOX_WITH_STATISTICS) && defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8)
     54#if defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8)
    5455# include "IEMN8veRecompiler.h"
    5556# include "IEMThreadedFunctions.h"
     57# include "IEMInline.h"
    5658#endif
    5759
     
    6264static FNDBGFINFOARGVINT iemR3InfoITlb;
    6365static FNDBGFINFOARGVINT iemR3InfoDTlb;
     66#if defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8)
     67static FNDBGFINFOARGVINT iemR3InfoTb;
     68#endif
    6469#ifdef VBOX_WITH_DEBUGGER
    6570static void iemR3RegisterDebuggerCommands(void);
     
    575580    DBGFR3InfoRegisterInternalArgv(pVM, "itlb", "IEM instruction TLB", iemR3InfoITlb, DBGFINFO_FLAGS_RUN_ON_EMT);
    576581    DBGFR3InfoRegisterInternalArgv(pVM, "dtlb", "IEM instruction TLB", iemR3InfoDTlb, DBGFINFO_FLAGS_RUN_ON_EMT);
     582#if defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8)
     583    DBGFR3InfoRegisterInternalArgv(pVM, "tb",   "IEM translation block", iemR3InfoTb, DBGFINFO_FLAGS_RUN_ON_EMT);
     584#endif
    577585#ifdef VBOX_WITH_DEBUGGER
    578586    iemR3RegisterDebuggerCommands();
     
    898906}
    899907
     908#if defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8)
     909/**
     910 * @callback_method_impl{FNDBGFINFOARGVINT, dtlb}
     911 */
     912static DECLCALLBACK(void) iemR3InfoTb(PVM pVM, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs)
     913{
     914    /*
     915     * Parse arguments.
     916     */
     917    static RTGETOPTDEF const s_aOptions[] =
     918    {
     919        { "--cpu",              'c', RTGETOPT_REQ_UINT32                          },
     920        { "--vcpu",             'c', RTGETOPT_REQ_UINT32                          },
     921        { "--addr",             'a', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX },
     922        { "--address",          'a', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX },
     923        { "--phys",             'p', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX },
     924        { "--physical",         'p', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX },
     925        { "--phys-addr",        'p', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX },
     926        { "--phys-address",     'p', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX },
     927        { "--physical-address", 'p', RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX },
     928        { "--flags",            'f', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX },
     929    };
     930
     931    RTGETOPTSTATE State;
     932    int rc = RTGetOptInit(&State, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /*iFirst*/, 0 /*fFlags*/);
     933    AssertRCReturnVoid(rc);
     934
     935    PVMCPU const    pVCpuThis   = VMMGetCpu(pVM);
     936    PVMCPU          pVCpu       = pVCpuThis ? pVCpuThis : VMMGetCpuById(pVM, 0);
     937    RTGCPHYS        GCPhysPc    = NIL_RTGCPHYS;
     938    RTGCPHYS        GCVirt      = NIL_RTGCPTR;
     939    uint32_t        fFlags      = UINT32_MAX;
     940
     941    RTGETOPTUNION ValueUnion;
     942    while ((rc = RTGetOpt(&State, &ValueUnion)) != 0)
     943    {
     944        switch (rc)
     945        {
     946            case 'c':
     947                if (ValueUnion.u32 >= pVM->cCpus)
     948                    pHlp->pfnPrintf(pHlp, "error: Invalid CPU ID: %u\n", ValueUnion.u32);
     949                else if (!pVCpu || pVCpu->idCpu != ValueUnion.u32)
     950                    pVCpu = VMMGetCpuById(pVM, ValueUnion.u32);
     951                break;
     952
     953            case 'a':
     954                GCVirt   = ValueUnion.u64;
     955                GCPhysPc = NIL_RTGCPHYS;
     956                break;
     957
     958            case 'p':
     959                GCVirt   = NIL_RTGCPHYS;
     960                GCPhysPc = ValueUnion.u64;
     961                break;
     962
     963            case 'f':
     964                fFlags = ValueUnion.u32;
     965                break;
     966
     967            case 'h':
     968                pHlp->pfnPrintf(pHlp,
     969                                "Usage: info %ctlb [options]\n"
     970                                "\n"
     971                                "Options:\n"
     972                                "  -c<n>, --cpu=<n>, --vcpu=<n>\n"
     973                                "    Selects the CPU which TBs we're looking at. Default: Caller / 0\n"
     974                                "  -a<virt>, --address=<virt>\n"
     975                                "    Shows the TB for the specified guest virtual address.\n"
     976                                "  -p<phys>, --phys=<phys>, --phys-addr=<phys>\n"
     977                                "    Shows the TB for the specified guest physical address.\n"
     978                                "  -f<flags>,--flags=<flags>\n"
     979                                "    The TB flags value (hex) to use when looking up the TB.\n"
     980                                "\n"
     981                                "The default is to use CS:RIP and derive flags from the CPU mode.\n");
     982                return;
     983
     984            default:
     985                pHlp->pfnGetOptError(pHlp, rc, &ValueUnion, &State);
     986                return;
     987        }
     988    }
     989
     990    /* Currently, only do work on the same EMT. */
     991    if (pVCpu != pVCpuThis)
     992    {
     993        pHlp->pfnPrintf(pHlp, "TODO: Cross EMT calling not supported yet: targeting %u, caller on %d\n",
     994                        pVCpu->idCpu, pVCpuThis ? (int)pVCpuThis->idCpu : -1);
     995        return;
     996    }
     997
     998    /*
     999     * Defaults.
     1000     */
     1001    if (GCPhysPc == NIL_RTGCPHYS)
     1002    {
     1003        if (GCVirt == NIL_RTGCPTR)
     1004            GCVirt = CPUMGetGuestFlatPC(pVCpu);
     1005        rc = PGMPhysGCPtr2GCPhys(pVCpu, GCVirt, &GCPhysPc);
     1006        if (RT_FAILURE(rc))
     1007        {
     1008            pHlp->pfnPrintf(pHlp, "Failed to convert %%%RGv to an guest physical address: %Rrc\n", GCVirt, rc);
     1009            return;
     1010        }
     1011    }
     1012    if (fFlags == UINT32_MAX)
     1013    {
     1014        /* Note! This is duplicating code in IEMAllThrdRecompiler. */
     1015        fFlags = iemCalcExecFlags(pVCpu);
     1016        if (pVM->cCpus == 1)
     1017            fFlags |= IEM_F_X86_DISREGARD_LOCK;
     1018        if (CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx))
     1019            fFlags |= IEMTB_F_INHIBIT_SHADOW;
     1020        if (CPUMAreInterruptsInhibitedByNmiEx(&pVCpu->cpum.GstCtx))
     1021            fFlags |= IEMTB_F_INHIBIT_NMI;
     1022        if ((IEM_F_MODE_CPUMODE_MASK & fFlags) != IEMMODE_64BIT)
     1023        {
     1024            int64_t const offFromLim = (int64_t)pVCpu->cpum.GstCtx.cs.u32Limit - (int64_t)pVCpu->cpum.GstCtx.eip;
     1025            if (offFromLim < X86_PAGE_SIZE + 16 - (int32_t)(pVCpu->cpum.GstCtx.cs.u64Base & GUEST_PAGE_OFFSET_MASK))
     1026                fFlags |= IEMTB_F_CS_LIM_CHECKS;
     1027        }
     1028    }
     1029
     1030    /*
     1031     * Do the lookup...
     1032     *
     1033     * Note! This is also duplicating code in IEMAllThrdRecompiler.  We don't
     1034     *       have much choice since we don't want to increase use counters and
     1035     *       trigger native recompilation.
     1036     */
     1037    fFlags &= IEMTB_F_KEY_MASK;
     1038    IEMTBCACHE const * const pTbCache = pVCpu->iem.s.pTbCacheR3;
     1039    uint32_t const           idxHash  = IEMTBCACHE_HASH_NO_KEY_MASK(pTbCache, fFlags, GCPhysPc);
     1040    PCIEMTB                  pTb      = IEMTBCACHE_PTR_GET_TB(pTbCache->apHash[idxHash]);
     1041    while (pTb)
     1042    {
     1043        if (pTb->GCPhysPc == GCPhysPc)
     1044        {
     1045            if ((pTb->fFlags & IEMTB_F_KEY_MASK) == fFlags)
     1046            {
     1047                /// @todo if (pTb->x86.fAttr == (uint16_t)pVCpu->cpum.GstCtx.cs.Attr.u)
     1048                break;
     1049            }
     1050        }
     1051        pTb = pTb->pNext;
     1052    }
     1053    if (!pTb)
     1054        pHlp->pfnPrintf(pHlp, "PC=%RGp fFlags=%#x - no TB found on #%u\n", GCPhysPc, fFlags, pVCpu->idCpu);
     1055    else
     1056    {
     1057        /*
     1058         *
     1059         */
     1060        switch (pTb->fFlags & IEMTB_F_TYPE_MASK)
     1061        {
     1062            case IEMTB_F_TYPE_NATIVE:
     1063                pHlp->pfnPrintf(pHlp, "PC=%RGp fFlags=%#x on #%u: %p - native\n", GCPhysPc, fFlags, pVCpu->idCpu, pTb);
     1064                iemNativeDisassembleTb(pTb, pHlp);
     1065                break;
     1066
     1067            case IEMTB_F_TYPE_THREADED:
     1068                pHlp->pfnPrintf(pHlp, "PC=%RGp fFlags=%#x on #%u: %p - threaded\n", GCPhysPc, fFlags, pVCpu->idCpu, pTb);
     1069                iemThreadedDisassembleTb(pTb, pHlp);
     1070                break;
     1071
     1072            default:
     1073                pHlp->pfnPrintf(pHlp, "PC=%RGp fFlags=%#x on #%u: %p - ??? %#x\n",
     1074                                GCPhysPc, fFlags, pVCpu->idCpu, pTb, pTb->fFlags);
     1075                break;
     1076        }
     1077    }
     1078}
     1079#endif /* VBOX_WITH_IEM_RECOMPILER && !VBOX_VMM_TARGET_ARMV8 */
     1080
    9001081
    9011082#ifdef VBOX_WITH_DEBUGGER
     
    9451126}
    9461127
    947 #endif
    948 
     1128#endif /* VBOX_WITH_DEBUGGER */
     1129
Note: See TracChangeset for help on using the changeset viewer.

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