VirtualBox

Changeset 35550 in vbox for trunk


Ignore:
Timestamp:
Jan 13, 2011 6:08:54 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
69434
Message:

Implemented DBGFR3RegNmQueryAll and MachineDebugger::GetRegisters.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/dbgf.h

    r35513 r35550  
    14491449/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
    14501450VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
    1451 VMMR3DECL(int) DBGFR3RegNmQueryBatch(PVM pVM,VMCPUID idDefCpu, DBGFREGENTRYNM paRegs, size_t cRegs);
     1451VMMR3DECL(int) DBGFR3RegNmQueryBatch(PVM pVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
    14521452VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PVM pVM, size_t *pcRegs);
    1453 VMMR3DECL(int) DBGFR3RegNmQueryAll( PVM pVM,                   DBGFREGENTRYNM paRegs, size_t cRegs);
     1453VMMR3DECL(int) DBGFR3RegNmQueryAll( PVM pVM,                   PDBGFREGENTRYNM paRegs, size_t cRegs);
    14541454VMMR3DECL(int) DBGFR3RegNmPrintf(   PVM pVM, VMCPUID idDefCpu, char pszBuf, size_t cbBuf, const char *pszFormat, ...);
    14551455VMMR3DECL(int) DBGFR3RegNmPrintfV(  PVM pVM, VMCPUID idDefCpu, char pszBuf, size_t cbBuf, const char *pszFormat, ...);
     
    14611461VMMR3DECL(int) DBGFR3RegNmSetU128(  PVM pVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U  u128);
    14621462VMMR3DECL(int) DBGFR3RegNmSetLrd(   PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
    1463 VMMR3DECL(int) DBGFR3RegNmSetBatch( PVM pVM, VMCPUID idDefCpu, DBGFREGENTRYNM paRegs, size_t cRegs);
     1463VMMR3DECL(int) DBGFR3RegNmSetBatch( PVM pVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
    14641464
    14651465/** @todo add enumeration methods.  */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp

    r35508 r35550  
    8585                    Assert(aBstrNames.size() == aBstrValues.size());
    8686
     87                    size_t cchMaxName  = 8;
    8788                    for (size_t i = 0; i < aBstrNames.size(); i++)
    88                         RTPrintf("%ls = %ls\n", aBstrNames[i], aBstrValues[i]);
     89                    {
     90                        size_t cchName = RTUtf16Len(aBstrNames[i]);
     91                        if (cchName > cchMaxName)
     92                            cchMaxName = cchName;
     93                    }
     94
     95                    for (size_t i = 0; i < aBstrNames.size(); i++)
     96                        RTPrintf("%-*ls = %ls\n", cchMaxName, aBstrNames[i], aBstrValues[i]);
    8997                }
    9098                else
  • trunk/src/VBox/Main/src-client/MachineDebuggerImpl.cpp

    r35513 r35550  
    12321232             * Real work.
    12331233             */
    1234             /** @todo query all registers. */
    1235             DBGFREGENTRY aRegs[DBGFREG_ALL_COUNT];
    1236             int vrc = DBGFR3RegCpuQueryAll(ptrVM.raw(), a_idCpu, aRegs, RT_ELEMENTS(aRegs));
     1234            size_t cRegs;
     1235            int vrc = DBGFR3RegNmQueryAllCount(ptrVM.raw(), &cRegs);
    12371236            if (RT_SUCCESS(vrc))
    12381237            {
    1239                 try
     1238                PDBGFREGENTRYNM paRegs = (PDBGFREGENTRYNM)RTMemAllocZ(sizeof(paRegs[0]) * cRegs);
     1239                if (paRegs)
    12401240                {
    1241                     com::SafeArray<BSTR> abstrNames(RT_ELEMENTS(aRegs));
    1242                     com::SafeArray<BSTR> abstrValues(RT_ELEMENTS(aRegs));
    1243 
    1244                     for (uint32_t iReg = 0; iReg < RT_ELEMENTS(aRegs); iReg++)
     1241                    vrc = DBGFR3RegNmQueryAll(ptrVM.raw(), paRegs, cRegs);
     1242                    if (RT_SUCCESS(vrc))
    12451243                    {
    1246                         char szHex[128];
    1247                         Bstr bstrValue;
    1248 
    1249                         hrc = formatRegisterValue(&bstrValue, &aRegs[iReg].Val, aRegs[iReg].enmType);
    1250                         AssertComRC(hrc);
    1251                         bstrValue.detachTo(&abstrValues[iReg]);
    1252 
    1253                         Bstr bstrName(DBGFR3RegCpuName(ptrVM.raw(), aRegs[iReg].enmReg, DBGFREGVALTYPE_INVALID));
    1254                         bstrName.detachTo(&abstrNames[iReg]);
     1244                        try
     1245                        {
     1246                            com::SafeArray<BSTR> abstrNames(cRegs);
     1247                            com::SafeArray<BSTR> abstrValues(cRegs);
     1248
     1249                            for (uint32_t iReg = 0; iReg < cRegs; iReg++)
     1250                            {
     1251                                char szHex[128];
     1252                                Bstr bstrValue;
     1253
     1254                                hrc = formatRegisterValue(&bstrValue, &paRegs[iReg].Val, paRegs[iReg].enmType);
     1255                                AssertComRC(hrc);
     1256                                bstrValue.detachTo(&abstrValues[iReg]);
     1257
     1258                                Bstr bstrName(paRegs[iReg].pszName);
     1259                                bstrName.detachTo(&abstrNames[iReg]);
     1260                            }
     1261
     1262                            abstrNames.detachTo(ComSafeArrayOutArg(a_bstrNames));
     1263                            abstrValues.detachTo(ComSafeArrayOutArg(a_bstrValues));
     1264                        }
     1265                        catch (std::bad_alloc)
     1266                        {
     1267                            hrc = E_OUTOFMEMORY;
     1268                        }
    12551269                    }
    1256 
    1257                     abstrValues.detachTo(ComSafeArrayOutArg(a_bstrNames));
    1258                     abstrValues.detachTo(ComSafeArrayOutArg(a_bstrValues));
     1270                    else
     1271                        hrc = setError(E_FAIL, tr("DBGFR3RegNmQueryAll failed with %Rrc"), vrc);
     1272
     1273                    RTMemFree(paRegs);
    12591274                }
    1260                 catch (std::bad_alloc)
    1261                 {
     1275                else
    12621276                    hrc = E_OUTOFMEMORY;
    1263                 }
    12641277            }
    12651278            else
    1266                 hrc = setError(E_FAIL, tr("DBGFR3RegQueryAll failed with %Rrc"), vrc);
     1279                hrc = setError(E_FAIL, tr("DBGFR3RegNmQueryAllCount failed with %Rrc"), vrc);
    12671280        }
    12681281    }
  • trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp

    r35513 r35550  
    113113    uint32_t                cDescs;
    114114
    115     /** Array of lookup records. */
     115    /** Array of lookup records.
     116     * The first part of the array runs parallel to paDescs, the rest are
     117     * covering for aliases and bitfield variations.  It's done this way to
     118     * simplify the query all operations. */
    116119    struct DBGFREGLOOKUP   *paLookupRecs;
    117120    /** The number of lookup records. */
     
    317320
    318321    /*
    319      * Initialize the lookup records.
     322     * Initialize the lookup records. See DBGFREGSET::paLookupRecs.
    320323     */
    321324    char szName[DBGF_REG_MAX_NAME * 3 + 16];
     
    324327    *pszReg++ = '.';
    325328
     329    /* Array parallel to the descriptors. */
    326330    int             rc = VINF_SUCCESS;
    327331    PDBGFREGLOOKUP  pLookupRec = &pRegSet->paLookupRecs[0];
    328332    for (iDesc = 0; paRegisters[iDesc].pszName != NULL && RT_SUCCESS(rc); iDesc++)
    329333    {
    330         PCDBGFREGALIAS  pCurAlias  = NULL;
     334        strcpy(pszReg, paRegisters[iDesc].pszName);
     335        pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName);
     336        if (!pLookupRec->Core.pszString)
     337            rc = VERR_NO_STR_MEMORY;
     338        pLookupRec->pSet      = pRegSet;
     339        pLookupRec->pDesc     = &paRegisters[iDesc];
     340        pLookupRec->pAlias    = NULL;
     341        pLookupRec->pSubField = NULL;
     342        pLookupRec++;
     343    }
     344
     345    /* Aliases and sub-fields. */
     346    for (iDesc = 0; paRegisters[iDesc].pszName != NULL && RT_SUCCESS(rc); iDesc++)
     347    {
     348        PCDBGFREGALIAS  pCurAlias  = NULL; /* first time we add sub-fields for the real name. */
    331349        PCDBGFREGALIAS  pNextAlias = paRegisters[iDesc].paAliases;
    332350        const char     *pszRegName = paRegisters[iDesc].pszName;
    333351        while (RT_SUCCESS(rc))
    334352        {
    335             size_t cchReg = strlen(pszRegName);
    336             memcpy(pszReg, pszRegName, cchReg + 1);
    337             pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName);
    338             if (!pLookupRec->Core.pszString)
    339                 rc = VERR_NO_STR_MEMORY;
    340             pLookupRec->pSet      = pRegSet;
    341             pLookupRec->pDesc     = &paRegisters[iDesc];
    342             pLookupRec->pAlias    = pCurAlias;
    343             pLookupRec->pSubField = NULL;
    344             pLookupRec++;
    345 
     353            /* Add sub-field records. */
    346354            PCDBGFREGSUBFIELD paSubFields = paRegisters[iDesc].paSubFields;
    347355            if (paSubFields)
    348356            {
     357                size_t cchReg = strlen(pszRegName);
     358                memcpy(pszReg, pszRegName, cchReg);
    349359                char *pszSub = &pszReg[cchReg];
    350360                *pszSub++ = '.';
     
    363373            }
    364374
    365             /* next */
     375            /* Advance to the next alias. */
    366376            pCurAlias = pNextAlias++;
    367377            if (!pCurAlias)
     
    370380            if (!pszRegName)
    371381                break;
     382
     383            /* The alias record. */
     384            strcpy(pszReg, pszRegName);
     385            pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName);
     386            if (!pLookupRec->Core.pszString)
     387                rc = VERR_NO_STR_MEMORY;
     388            pLookupRec->pSet      = pRegSet;
     389            pLookupRec->pDesc     = &paRegisters[iDesc];
     390            pLookupRec->pAlias    = pCurAlias;
     391            pLookupRec->pSubField = NULL;
     392            pLookupRec++;
    372393        }
    373394    }
     
    385406        if (fInserted)
    386407        {
     408            pVM->dbgf.s.cRegs += pRegSet->cDescs;
    387409            if (enmType == DBGFREGSETTYPE_CPU)
     410            {
     411                if (pRegSet->cDescs > DBGFREG_ALL_COUNT)
     412                    pVM->dbgf.s.cRegs -= pRegSet->cDescs - DBGFREG_ALL_COUNT;
    388413                pVM->aCpus[iInstance].dbgf.s.pRegSet = pRegSet;
    389             pVM->dbgf.s.cRegs += pRegSet->cDescs;
     414            }
    390415
    391416            PDBGFREGLOOKUP  paLookupRecs = pRegSet->paLookupRecs;
     
    12741299 *                              Optional.
    12751300 */
    1276 static DECLCALLBACK(int) dbgfR3RegNmQueryWorker(PVM pVM, VMCPUID idDefCpu, const char *pszReg, DBGFREGVALTYPE enmType,
    1277                                                 PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
     1301static int dbgfR3RegNmQueryWorker(PVM pVM, VMCPUID idDefCpu, const char *pszReg, DBGFREGVALTYPE enmType,
     1302                                  PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
    12781303{
    12791304    /*
     
    15661591}
    15671592
    1568 
    1569 VMMR3DECL(int) DBGFR3RegNmQueryAll(PVM pVM, DBGFREGENTRYNM paRegs, size_t cRegs)
    1570 {
    1571     return VERR_NOT_IMPLEMENTED;
     1593/**
     1594 * Argument packet from DBGFR3RegNmQueryAll to dbgfR3RegNmQueryAllWorker.
     1595 */
     1596typedef struct DBGFR3REGNMQUERYALLARGS
     1597{
     1598    /** The output register array. */
     1599    PDBGFREGENTRYNM paRegs;
     1600    /** The number of entries in the output array. */
     1601    size_t          cRegs;
     1602    /** The current register number when enumerating the string space. */
     1603    size_t          iReg;
     1604} DBGFR3REGNMQUERYALLARGS;
     1605/** Pointer to a dbgfR3RegNmQueryAllWorker argument packet. */
     1606typedef DBGFR3REGNMQUERYALLARGS *PDBGFR3REGNMQUERYALLARGS;
     1607
     1608
     1609/**
     1610 * Pad register entries.
     1611 *
     1612 * @param   paRegs          The output array.
     1613 * @param   cRegs           The size of the output array.
     1614 * @param   iReg            The first register to pad.
     1615 * @param   cRegsToPad      The number of registers to pad.
     1616 */
     1617static void dbgfR3RegNmQueryAllPadEntries(PDBGFREGENTRYNM paRegs, size_t cRegs, size_t iReg, size_t cRegsToPad)
     1618{
     1619    if (iReg < cRegs)
     1620    {
     1621        size_t iEndReg = iReg + cRegsToPad;
     1622        if (iEndReg > cRegs)
     1623            iEndReg = cRegs;
     1624        while (iReg < iEndReg)
     1625        {
     1626            paRegs[iReg].pszName = NULL;
     1627            paRegs[iReg].enmType = DBGFREGVALTYPE_END;
     1628            dbgfR3RegValClear(&paRegs[iReg].Val);
     1629            iReg++;
     1630        }
     1631    }
     1632}
     1633
     1634
     1635/**
     1636 * Query all registers in a set.
     1637 *
     1638 * @param   pSet            The set.
     1639 * @param   cRegsToQuery    The number of registers to query.
     1640 * @param   paRegs          The output array.
     1641 * @param   cRegs           The size of the output array.
     1642 */
     1643static void dbgfR3RegNmQueryAllInSet(PCDBGFREGSET pSet, size_t cRegsToQuery, PDBGFREGENTRYNM paRegs, size_t cRegs)
     1644{
     1645    int rc = VINF_SUCCESS;
     1646
     1647    if (cRegsToQuery > pSet->cDescs)
     1648        cRegsToQuery = pSet->cDescs;
     1649    if (cRegsToQuery > cRegs)
     1650        cRegsToQuery = cRegs;
     1651
     1652    for (size_t iReg = 0; iReg < cRegsToQuery; iReg++)
     1653    {
     1654        paRegs[iReg].enmType = pSet->paDescs[iReg].enmType;
     1655        paRegs[iReg].pszName = pSet->paLookupRecs[iReg].Core.pszString;
     1656        dbgfR3RegValClear(&paRegs[iReg].Val);
     1657        int rc2 = pSet->paDescs[iReg].pfnGet(pSet->uUserArg.pv, &pSet->paDescs[iReg], &paRegs[iReg].Val);
     1658        AssertRCSuccess(rc2);
     1659        if (RT_FAILURE(rc2))
     1660            dbgfR3RegValClear(&paRegs[iReg].Val);
     1661    }
     1662}
     1663
     1664
     1665/**
     1666 * @callback_method_impl{FNRTSTRSPACECALLBACK, Worker used by
     1667 *                      dbgfR3RegNmQueryAllWorker}
     1668 */
     1669static DECLCALLBACK(int)  dbgfR3RegNmQueryAllEnum(PRTSTRSPACECORE pStr, void *pvUser)
     1670{
     1671    PCDBGFREGSET pSet = (PCDBGFREGSET)pStr;
     1672    if (pSet->enmType != DBGFREGSETTYPE_CPU)
     1673    {
     1674        PDBGFR3REGNMQUERYALLARGS pArgs  = (PDBGFR3REGNMQUERYALLARGS)pvUser;
     1675        if (pArgs->iReg < pArgs->cRegs)
     1676            dbgfR3RegNmQueryAllInSet(pSet, pSet->cDescs, &pArgs->paRegs[pArgs->iReg], pArgs->cRegs - pArgs->iReg);
     1677        pArgs->iReg += pSet->cDescs;
     1678    }
     1679
     1680    return 0;
     1681}
     1682
     1683
     1684/**
     1685 * @callback_method_impl{FNVMMEMTRENDEZVOUS, Worker used by DBGFR3RegNmQueryAll}
     1686 */
     1687static DECLCALLBACK(VBOXSTRICTRC) dbgfR3RegNmQueryAllWorker(PVM pVM, PVMCPU pVCpu, void *pvUser)
     1688{
     1689    PDBGFR3REGNMQUERYALLARGS    pArgs  = (PDBGFR3REGNMQUERYALLARGS)pvUser;
     1690    PDBGFREGENTRYNM             paRegs = pArgs->paRegs;
     1691    size_t const                cRegs  = pArgs->cRegs;
     1692
     1693    /*
     1694     * My CPU registers.
     1695     */
     1696    size_t iCpuReg = pVCpu->idCpu * DBGFREG_ALL_COUNT;
     1697    if (pVCpu->dbgf.s.pRegSet)
     1698    {
     1699        if (iCpuReg < cRegs)
     1700            dbgfR3RegNmQueryAllInSet(pVCpu->dbgf.s.pRegSet, DBGFREG_ALL_COUNT, &paRegs[iCpuReg], cRegs - iCpuReg);
     1701    }
     1702    else
     1703        dbgfR3RegNmQueryAllPadEntries(paRegs, cRegs, iCpuReg, DBGFREG_ALL_COUNT);
     1704
     1705    /*
     1706     * The primary CPU does all the other registers.
     1707     */
     1708    if (pVCpu->idCpu == 0)
     1709    {
     1710        pArgs->iReg = pVM->cCpus * DBGFREG_ALL_COUNT;
     1711        RTStrSpaceEnumerate(&pVM->dbgf.s.RegSetSpace, dbgfR3RegNmQueryAllEnum, pArgs);
     1712        dbgfR3RegNmQueryAllPadEntries(paRegs, cRegs, pArgs->iReg, cRegs);
     1713    }
     1714
     1715    return VINF_SUCCESS; /* Ignore errors. */
     1716}
     1717
     1718
     1719/**
     1720 * Queries all register.
     1721 *
     1722 * @returns VBox status code.
     1723 * @param   pVM                 The VM handle.
     1724 * @param   paRegs              The output register value array.  The register
     1725 *                              name string is read only and shall not be freed
     1726 *                              or modified.
     1727 * @param   cRegs               The number of entries in @a paRegs.  The
     1728 *                              correct size can be obtained by calling
     1729 *                              DBGFR3RegNmQueryAllCount.
     1730 */
     1731VMMR3DECL(int) DBGFR3RegNmQueryAll(PVM pVM, PDBGFREGENTRYNM paRegs, size_t cRegs)
     1732{
     1733    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     1734    AssertPtrReturn(paRegs, VERR_INVALID_POINTER);
     1735    AssertReturn(cRegs > 0, VERR_OUT_OF_RANGE);
     1736
     1737    DBGFR3REGNMQUERYALLARGS Args;
     1738    Args.paRegs = paRegs;
     1739    Args.cRegs  = cRegs;
     1740
     1741    return VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE, dbgfR3RegNmQueryAllWorker, &Args);
    15721742}
    15731743
  • trunk/src/VBox/VMM/include/DBGFInternal.h

    r35490 r35550  
    279279    /** String space holding the register sets. (Protected by hRegDbLock.)  */
    280280    R3PTRTYPE(RTSTRSPACE)       RegSetSpace;
    281     /** The number of registers (aliases and sub-fields not counted). */
     281    /** The number of registers (aliases, sub-fields and the special CPU
     282     * register aliases (eg AH) are not counted). */
    282283    uint32_t                    cRegs;
    283284    /** For early initialization by . */
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