VirtualBox

Changeset 35550 in vbox for trunk/src/VBox/VMM


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/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • 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