VirtualBox

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


Ignore:
Timestamp:
Jan 10, 2011 4:36:35 PM (14 years ago)
Author:
vboxsync
Message:

DBGFReg: Query individual registers by name.

Location:
trunk/src/VBox/VMM/VMMR3
Files:
2 edited

Legend:

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

    r35346 r35466  
    135135{
    136136    int rc = dbgfR3InfoInit(pVM);
     137    if (RT_SUCCESS(rc))
     138        rc = dbgfR3RegInit(pVM);
    137139    if (RT_SUCCESS(rc))
    138140        rc = dbgfR3AsInit(pVM);
     
    208210    dbgfR3OSTerm(pVM);
    209211    dbgfR3AsTerm(pVM);
     212    dbgfR3RegTerm(pVM);
    210213    dbgfR3InfoTerm(pVM);
    211214    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp

    r35411 r35466  
    6464
    6565
     66/** The max length of a set, register or sub-field name. */
     67#define DBGF_REG_MAX_NAME       40
     68
    6669
    6770/*******************************************************************************
     
    9295    RTSTRSPACECORE          Core;
    9396    /** The registration record type. */
    94     DBGFREGSETTYPE       enmType;
     97    DBGFREGSETTYPE          enmType;
    9598    /** The user argument for the callbacks. */
    9699    union
     
    109112    size_t                  cDescs;
    110113
     114    /** Array of lookup records. */
     115    struct DBGFREGLOOKUP   *paLookupRecs;
     116    /** The number of lookup records. */
     117    size_t                  cLookupRecs;
     118
    111119    /** The register name prefix. */
    112     char                    szPrefix[32];
     120    char                    szPrefix[1];
    113121} DBGFREGSET;
    114122/** Pointer to a register registration record. */
    115123typedef DBGFREGSET *PDBGFREGSET;
     124/** Pointer to a const register registration record. */
     125typedef DBGFREGSET const *PCDBGFREGSET;
     126
     127
     128/**
     129 * Register lookup record.
     130 */
     131typedef struct DBGFREGLOOKUP
     132{
     133    /** The string space core. */
     134    RTSTRSPACECORE      Core;
     135    /** Pointer to the set. */
     136    PCDBGFREGSET        pSet;
     137    /** Pointer to the register descriptor. */
     138    PCDBGFREGDESC       pDesc;
     139    /** If an alias this points to the alias descriptor, NULL if not. */
     140    PCDBGFREGALIAS      pAlias;
     141    /** If a sub-field this points to the sub-field descriptor, NULL if not. */
     142    PCDBGFREGSUBFIELD   pSubField;
     143} DBGFREGLOOKUP;
     144/** Pointer to a register lookup record. */
     145typedef DBGFREGLOOKUP *PDBGFREGLOOKUP;
     146/** Pointer to a const register lookup record. */
     147typedef DBGFREGLOOKUP const *PCDBGFREGLOOKUP;
     148
     149
     150/**
     151 * Initializes the register database.
     152 *
     153 * @returns VBox status code.
     154 * @param   pVM                 The VM handle.
     155 */
     156int dbgfR3RegInit(PVM pVM)
     157{
     158    return RTSemRWCreate(&pVM->dbgf.s.hRegDbLock);
     159}
     160
     161
     162/**
     163 * Terminates the register database.
     164 *
     165 * @param   pVM                 The VM handle.
     166 */
     167void dbgfR3RegTerm(PVM pVM)
     168{
     169    RTSemRWDestroy(pVM->dbgf.s.hRegDbLock);
     170    pVM->dbgf.s.hRegDbLock = NIL_RTSEMRW;
     171}
    116172
    117173
     
    126182static bool dbgfR3RegIsNameValid(const char *pszName)
    127183{
    128     if (!RT_C_IS_ALPHA(*pszName))
     184    const char *psz = pszName;
     185    if (!RT_C_IS_ALPHA(*psz))
    129186        return false;
    130187    char ch;
    131     while ((ch = *++pszName))
     188    while ((ch = *++psz))
    132189        if (   !RT_C_IS_LOWER(ch)
    133190            && !RT_C_IS_DIGIT(ch)
    134191            && ch != '_')
    135192            return false;
     193    if (psz - pszName > DBGF_REG_MAX_NAME)
     194        return false;
    136195    return true;
    137196}
     
    165224
    166225    /* The descriptors. */
     226    uint32_t cLookupRecs = 0;
    167227    uint32_t iDesc;
    168228    for (iDesc = 0; paRegisters[iDesc].pszName != NULL; iDesc++)
     
    184244        AssertPtrReturn(paRegisters[iDesc].pfnSet, VERR_INVALID_PARAMETER);
    185245
    186         PCDBGFREGALIAS paAliases = paRegisters[iDesc].paAliases;
     246        uint32_t        iAlias    = 0;
     247        PCDBGFREGALIAS  paAliases = paRegisters[iDesc].paAliases;
    187248        if (paAliases)
    188249        {
    189250            AssertPtrReturn(paAliases, VERR_INVALID_PARAMETER);
    190             for (uint32_t j = 0; paAliases[j].pszName; j++)
     251            for (; paAliases[iAlias].pszName; iAlias++)
    191252            {
    192                 AssertMsgReturn(dbgfR3RegIsNameValid(paAliases[j].pszName), ("%s (%s)\n", paAliases[j].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
    193                 AssertReturn(   paAliases[j].enmType > DBGFREGVALTYPE_INVALID
    194                              && paAliases[j].enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER);
     253                AssertMsgReturn(dbgfR3RegIsNameValid(paAliases[iAlias].pszName), ("%s (%s)\n", paAliases[iAlias].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
     254                AssertReturn(   paAliases[iAlias].enmType > DBGFREGVALTYPE_INVALID
     255                             && paAliases[iAlias].enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER);
    195256            }
    196257        }
    197258
     259        uint32_t          iSubField   = 0;
    198260        PCDBGFREGSUBFIELD paSubFields = paRegisters[iDesc].paSubFields;
    199261        if (paSubFields)
    200262        {
    201263            AssertPtrReturn(paSubFields, VERR_INVALID_PARAMETER);
    202             for (uint32_t j = 0; paSubFields[j].pszName; j++)
     264            for (; paSubFields[iSubField].pszName; iSubField++)
    203265            {
    204                 AssertMsgReturn(dbgfR3RegIsNameValid(paSubFields[j].pszName), ("%s (%s)\n", paSubFields[j].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
    205                 AssertReturn(paSubFields[j].iFirstBit + paSubFields[j].cBits <= 128, VERR_INVALID_PARAMETER);
    206                 AssertReturn(paSubFields[j].cBits + paSubFields[j].cShift <= 128, VERR_INVALID_PARAMETER);
    207                 AssertPtrNullReturn(paSubFields[j].pfnGet, VERR_INVALID_POINTER);
    208                 AssertPtrNullReturn(paSubFields[j].pfnSet, VERR_INVALID_POINTER);
     266                AssertMsgReturn(dbgfR3RegIsNameValid(paSubFields[iSubField].pszName), ("%s (%s)\n", paSubFields[iSubField].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
     267                AssertReturn(paSubFields[iSubField].iFirstBit + paSubFields[iSubField].cBits <= 128, VERR_INVALID_PARAMETER);
     268                AssertReturn(paSubFields[iSubField].cBits + paSubFields[iSubField].cShift <= 128, VERR_INVALID_PARAMETER);
     269                AssertPtrNullReturn(paSubFields[iSubField].pfnGet, VERR_INVALID_POINTER);
     270                AssertPtrNullReturn(paSubFields[iSubField].pfnSet, VERR_INVALID_POINTER);
    209271            }
    210272        }
    211     }
     273
     274        cLookupRecs += (1 + iAlias) * (1 + iSubField);
     275    }
     276
     277    /* Check the instance number of the CPUs. */
     278    AssertReturn(enmType != DBGFREGSETTYPE_CPU || iInstance < pVM->cCpus, VERR_INVALID_CPU_ID);
    212279
    213280    /*
    214      * Allocate a new record.
     281     * Allocate a new record and all associated lookup records.
    215282     */
    216     PDBGFREGSET pRegRec = (PDBGFREGSET)MMR3HeapAlloc(pVM, MM_TAG_DBGF_REG, RT_OFFSETOF(DBGFREGSET, szPrefix[cchPrefix + 4 + 1]));
    217     if (!pRegRec)
     283    size_t cbRegSet = RT_OFFSETOF(DBGFREGSET, szPrefix[cchPrefix + 4 + 1]);
     284    cbRegSet = RT_ALIGN_Z(cbRegSet, 32);
     285    size_t const offLookupRecArray = cbRegSet;
     286    cbRegSet += cLookupRecs * sizeof(DBGFREGLOOKUP);
     287
     288    PDBGFREGSET pRegSet = (PDBGFREGSET)MMR3HeapAllocZ(pVM, MM_TAG_DBGF_REG, cbRegSet);
     289    if (!pRegSet)
    218290        return VERR_NO_MEMORY;
    219291
    220     pRegRec->Core.pszString = pRegRec->szPrefix;
    221     pRegRec->enmType        = enmType;
    222     pRegRec->uUserArg.pv    = pvUserArg;
    223     pRegRec->paDescs        = paRegisters;
    224     pRegRec->cDescs         = iDesc;
     292    /*
     293     * Initialize the new record.
     294     */
     295    pRegSet->Core.pszString = pRegSet->szPrefix;
     296    pRegSet->enmType        = enmType;
     297    pRegSet->uUserArg.pv    = pvUserArg;
     298    pRegSet->paDescs        = paRegisters;
     299    pRegSet->cDescs         = iDesc;
     300    pRegSet->cLookupRecs    = cLookupRecs;
     301    pRegSet->paLookupRecs   = (PDBGFREGLOOKUP)((uintptr_t)pRegSet + offLookupRecArray);
    225302    if (fNeedUnderscore)
    226         RTStrPrintf(pRegRec->szPrefix, cchPrefix + 4 + 1, "%s_%u", pszPrefix, iInstance);
     303        RTStrPrintf(pRegSet->szPrefix, cchPrefix + 4 + 1, "%s_%u", pszPrefix, iInstance);
    227304    else
    228         RTStrPrintf(pRegRec->szPrefix, cchPrefix + 4 + 1, "%s%u", pszPrefix, iInstance);
    229 
    230     DBGF_REG_DB_LOCK_WRITE(pVM);
    231     bool fInserted = RTStrSpaceInsert(&pVM->dbgf.s.RegSetSpace, &pRegRec->Core);
    232     DBGF_REG_DB_UNLOCK_WRITE(pVM);
    233     if (fInserted)
    234         return VINF_SUCCESS;
    235 
    236     MMR3HeapFree(pRegRec);
    237     return VERR_DUPLICATE;
     305        RTStrPrintf(pRegSet->szPrefix, cchPrefix + 4 + 1, "%s%u", pszPrefix, iInstance);
     306
     307
     308    /*
     309     * Initialize the lookup records.
     310     */
     311    char szName[DBGF_REG_MAX_NAME * 3 + 16];
     312    strcpy(szName, pRegSet->szPrefix);
     313    char *pszReg = strchr(szName, '\0');
     314    *pszReg++ = '.';
     315
     316    int             rc = VINF_SUCCESS;
     317    PDBGFREGLOOKUP  pLookupRec = &pRegSet->paLookupRecs[0];
     318    for (iDesc = 0; paRegisters[iDesc].pszName != NULL && RT_SUCCESS(rc); iDesc++)
     319    {
     320        PCDBGFREGALIAS  pCurAlias  = NULL;
     321        PCDBGFREGALIAS  pNextAlias = paRegisters[iDesc].paAliases;
     322        const char     *pszRegName = paRegisters[iDesc].pszName;
     323        while (RT_SUCCESS(rc))
     324        {
     325            size_t cchReg = strlen(paRegisters[iDesc].pszName);
     326            memcpy(pszReg, paRegisters[iDesc].pszName, cchReg + 1);
     327            pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName);
     328            if (!pLookupRec->Core.pszString)
     329                rc = VERR_NO_STR_MEMORY;
     330            pLookupRec->pSet      = pRegSet;
     331            pLookupRec->pDesc     = &paRegisters[iDesc];
     332            pLookupRec->pAlias    = pCurAlias;
     333            pLookupRec->pSubField = NULL;
     334
     335            PCDBGFREGSUBFIELD paSubFields = paRegisters[iDesc].paSubFields;
     336            if (paSubFields)
     337            {
     338                char *pszSub = &pszReg[cchReg];
     339                *pszSub++ = '.';
     340                for (uint32_t iSubField = 0; paSubFields[iSubField].pszName && RT_SUCCESS(rc); iSubField++)
     341                {
     342                    strcpy(pszSub, paSubFields[iSubField].pszName);
     343                    pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName);
     344                    if (!pLookupRec->Core.pszString)
     345                        rc = VERR_NO_STR_MEMORY;
     346                    pLookupRec->pSet      = pRegSet;
     347                    pLookupRec->pDesc     = &paRegisters[iDesc];
     348                    pLookupRec->pAlias    = pCurAlias;
     349                    pLookupRec->pSubField = &paSubFields[iSubField];
     350                }
     351            }
     352
     353            /* next */
     354            pCurAlias = pNextAlias++;
     355            if (   !pCurAlias
     356                || !pCurAlias->pszName)
     357                break;
     358            pszRegName = pCurAlias->pszName;
     359        }
     360    }
     361
     362    if (RT_SUCCESS(rc))
     363    {
     364        /*
     365         * Insert the record into the register set string space and optionally into
     366         * the CPU register set cache.
     367         */
     368        DBGF_REG_DB_LOCK_WRITE(pVM);
     369
     370        bool fInserted = RTStrSpaceInsert(&pVM->dbgf.s.RegSetSpace, &pRegSet->Core);
     371        if (fInserted)
     372        {
     373            if (enmType == DBGFREGSETTYPE_CPU)
     374                pVM->aCpus[iInstance].dbgf.s.pRegSet = pRegSet;
     375            pVM->dbgf.s.cRegs += pRegSet->cDescs;
     376
     377            PDBGFREGLOOKUP  paLookupRecs = pRegSet->paLookupRecs;
     378            uint32_t        iLookupRec   = pRegSet->cLookupRecs;
     379            while (iLookupRec-- > 0)
     380            {
     381                bool fInserted2 = RTStrSpaceInsert(&pVM->dbgf.s.RegSpace, &paLookupRecs[iLookupRec].Core);
     382                AssertMsg(fInserted2, ("'%s'", paLookupRecs[iLookupRec].Core.pszString));
     383            }
     384
     385            DBGF_REG_DB_UNLOCK_WRITE(pVM);
     386            return VINF_SUCCESS;
     387        }
     388
     389        DBGF_REG_DB_UNLOCK_WRITE(pVM);
     390        rc = VERR_DUPLICATE;
     391    }
     392
     393    /*
     394     * Bail out.
     395     */
     396    for (uint32_t i = 0; i < pRegSet->cLookupRecs; i++)
     397        MMR3HeapFree((char *)pRegSet->paLookupRecs[i].Core.pszString);
     398    MMR3HeapFree(pRegSet);
     399
     400    return rc;
    238401}
    239402
     
    301464    dbgfR3RegValClear(pValue);
    302465
     466    /* Note! No default cases here as gcc warnings about missing enum values
     467             are desired. */
    303468    switch (enmFromType)
    304469    {
     
    311476                case DBGFREGVALTYPE_U64:    pValue->u64       = InVal.u8; return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    312477                case DBGFREGVALTYPE_U128:   pValue->u128.s.Lo = InVal.u8; return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    313                 case DBGFREGVALTYPE_80:                                   return VERR_DBGF_UNSUPPORTED_CAST;
    314478                case DBGFREGVALTYPE_LRD:    pValue->lrd       = InVal.u8; return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    315479                case DBGFREGVALTYPE_DTR:                                  return VERR_DBGF_UNSUPPORTED_CAST;
     
    330494                case DBGFREGVALTYPE_U64:    pValue->u64       = InVal.u16;  return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    331495                case DBGFREGVALTYPE_U128:   pValue->u128.s.Lo = InVal.u16;  return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    332                 case DBGFREGVALTYPE_80:                                     return VERR_DBGF_UNSUPPORTED_CAST;
    333496                case DBGFREGVALTYPE_LRD:    pValue->lrd       = InVal.u16;  return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    334497                case DBGFREGVALTYPE_DTR:                                    return VERR_DBGF_UNSUPPORTED_CAST;
     
    349512                case DBGFREGVALTYPE_U64:    pValue->u64       = InVal.u32;  return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    350513                case DBGFREGVALTYPE_U128:   pValue->u128.s.Lo = InVal.u32;  return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    351                 case DBGFREGVALTYPE_80:                                     return VERR_DBGF_UNSUPPORTED_CAST;
    352514                case DBGFREGVALTYPE_LRD:    pValue->lrd       = InVal.u32;  return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    353515                case DBGFREGVALTYPE_DTR:                                    return VERR_DBGF_UNSUPPORTED_CAST;
     
    368530                case DBGFREGVALTYPE_U64:    pValue->u64       = InVal.u64;  return VINF_SUCCESS;
    369531                case DBGFREGVALTYPE_U128:   pValue->u128.s.Lo = InVal.u64;  return VINF_DBGF_TRUNCATED_REGISTER;
    370                 case DBGFREGVALTYPE_80:                                     return VERR_DBGF_UNSUPPORTED_CAST;
    371532                case DBGFREGVALTYPE_LRD:    pValue->lrd       = InVal.u64;  return VINF_DBGF_ZERO_EXTENDED_REGISTER;
    372533                case DBGFREGVALTYPE_DTR:                                    return VERR_DBGF_UNSUPPORTED_CAST;
     
    387548                case DBGFREGVALTYPE_U64:    pValue->u64       = InVal.u128.s.Lo;  return VINF_DBGF_TRUNCATED_REGISTER;
    388549                case DBGFREGVALTYPE_U128:   pValue->u128      = InVal.u128;       return VINF_SUCCESS;
    389                 case DBGFREGVALTYPE_80:                                           return VERR_DBGF_UNSUPPORTED_CAST;
    390550                case DBGFREGVALTYPE_LRD:    pValue->lrd       = InVal.u64;        return VINF_DBGF_TRUNCATED_REGISTER;
    391551                case DBGFREGVALTYPE_DTR:                                          return VERR_DBGF_UNSUPPORTED_CAST;
     
    397557            }
    398558            break;
    399 
    400         case DBGFREGVALTYPE_80:
    401             return VERR_DBGF_UNSUPPORTED_CAST;
    402559
    403560        case DBGFREGVALTYPE_LRD:
     
    412569                    pValue->u128.s.Hi = (uint64_t)InVal.lrd / _4G / _4G;
    413570                    return VINF_DBGF_TRUNCATED_REGISTER;
    414                 case DBGFREGVALTYPE_80:                                     return VERR_DBGF_UNSUPPORTED_CAST;
    415571                case DBGFREGVALTYPE_LRD:    pValue->lrd       = InVal.lrd;  return VINF_SUCCESS;
    416572                case DBGFREGVALTYPE_DTR:                                    return VERR_DBGF_UNSUPPORTED_CAST;
     
    431587                case DBGFREGVALTYPE_U64:    pValue->u64       = InVal.dtr.u64Base;  return VINF_DBGF_TRUNCATED_REGISTER;
    432588                case DBGFREGVALTYPE_U128:   pValue->u128.s.Lo = InVal.dtr.u64Base;  return VINF_DBGF_TRUNCATED_REGISTER;
    433                 case DBGFREGVALTYPE_80:                                             return VERR_DBGF_UNSUPPORTED_CAST;
    434589                case DBGFREGVALTYPE_LRD:    pValue->lrd       = InVal.dtr.u64Base;  return VINF_DBGF_TRUNCATED_REGISTER;
    435590                case DBGFREGVALTYPE_DTR:    pValue->dtr       = InVal.dtr;          return VINF_SUCCESS;
     
    460615 * @retval  VERR_INVALID_VM_HANDLE
    461616 * @retval  VERR_INVALID_CPU_ID
    462  * @retval  VERR_DBGF_INVALID_REGISTER
     617 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
    463618 * @retval  VERR_DBGF_UNSUPPORTED_CAST
    464619 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     
    469624 * @param   enmReg              The register to query.
    470625 * @param   enmType             The desired return type.
    471  * @param   puValue             Where to return the register value.
    472  */
    473 static DECLCALLBACK(int) dbgfR3RegCpuQueryWorker(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, DBGFREGVALTYPE enmType, PDBGFREGVAL puValue)
     626 * @param   pValue              Where to return the register value.
     627 */
     628static DECLCALLBACK(int) dbgfR3RegCpuQueryWorker(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, DBGFREGVALTYPE enmType, PDBGFREGVAL pValue)
    474629{
    475630    int rc = VINF_SUCCESS;
     
    477632
    478633    /*
    479      * Look up the register set of the CPU.
     634     * Look up the register set of the specified CPU.
    480635     */
    481     /** @todo optimize this by adding a cpu register set array to DBGF. */
    482     char szSetName[16];
    483     RTStrPrintf(szSetName, sizeof(szSetName), "cpu%u", idCpu);
    484     PDBGFREGSET pSet = (PDBGFREGSET)RTStrSpaceGet(&pVM->dbgf.s.RegSetSpace, szSetName);
     636    PDBGFREGSET pSet = pVM->aCpus[idCpu].dbgf.s.pRegSet;
    485637    if (RT_LIKELY(pSet))
    486638    {
     
    492644            PCDBGFREGDESC pDesc = &pSet->paDescs[enmReg];
    493645
    494             puValue->au64[0] = puValue->au64[1] = 0;
    495             rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, puValue);
     646            pValue->au64[0] = pValue->au64[1] = 0;
     647            rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, pValue);
    496648            if (RT_SUCCESS(rc))
    497649            {
     
    503655                    rc = VINF_SUCCESS;
    504656                else
    505                     rc = dbgfR3RegValCast(puValue, pDesc->enmType, enmType);
     657                    rc = dbgfR3RegValCast(pValue, pDesc->enmType, enmType);
    506658            }
    507659        }
    508660        else
    509             rc = VERR_DBGF_INVALID_REGISTER;
     661            rc = VERR_DBGF_REGISTER_NOT_FOUND;
    510662    }
    511663    else
     
    523675 * @retval  VERR_INVALID_VM_HANDLE
    524676 * @retval  VERR_INVALID_CPU_ID
    525  * @retval  VERR_DBGF_INVALID_REGISTER
     677 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
    526678 * @retval  VERR_DBGF_UNSUPPORTED_CAST
    527679 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     
    554706 * @retval  VERR_INVALID_VM_HANDLE
    555707 * @retval  VERR_INVALID_CPU_ID
    556  * @retval  VERR_DBGF_INVALID_REGISTER
     708 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
    557709 * @retval  VERR_DBGF_UNSUPPORTED_CAST
    558710 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     
    586738 * @retval  VERR_INVALID_VM_HANDLE
    587739 * @retval  VERR_INVALID_CPU_ID
    588  * @retval  VERR_DBGF_INVALID_REGISTER
     740 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
    589741 * @retval  VERR_DBGF_UNSUPPORTED_CAST
    590742 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     
    618770 * @retval  VERR_INVALID_VM_HANDLE
    619771 * @retval  VERR_INVALID_CPU_ID
    620  * @retval  VERR_DBGF_INVALID_REGISTER
     772 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
    621773 * @retval  VERR_DBGF_UNSUPPORTED_CAST
    622774 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     
    648800 *
    649801 * @retval  VINF_SUCCESS
    650  * @retval  VERR_DBGF_INVALID_REGISTER
     802 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
    651803 *
    652804 * @param   pVCpu               The current CPU.
     
    681833
    682834        DBGFREG const enmReg = pReg->enmReg;
    683         AssertMsgReturn(enmReg >= 0 && enmReg <= DBGFREG_END, ("%d (%#x)\n", enmReg, enmReg), VERR_DBGF_INVALID_REGISTER);
     835        AssertMsgReturn(enmReg >= 0 && enmReg <= DBGFREG_END, ("%d (%#x)\n", enmReg, enmReg), VERR_DBGF_REGISTER_NOT_FOUND);
    684836        if (enmReg != DBGFREG_END)
    685837        {
     
    728880 * @retval  VERR_INVALID_VM_HANDLE
    729881 * @retval  VERR_INVALID_CPU_ID
    730  * @retval  VERR_DBGF_INVALID_REGISTER
     882 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
    731883 *
    732884 * @param   pVM                 The VM handle.
     
    751903    {
    752904        DBGFREG enmReg = paRegs[iReg].enmReg;
    753         AssertMsgReturn(enmReg < DBGFREG_END && enmReg >= DBGFREG_AL, ("%d (%#x)", enmReg, enmReg), VERR_DBGF_INVALID_REGISTER);
     905        AssertMsgReturn(enmReg < DBGFREG_END && enmReg >= DBGFREG_AL, ("%d (%#x)", enmReg, enmReg), VERR_DBGF_REGISTER_NOT_FOUND);
    754906    }
    755907
     
    809961 * @returns Pointer to read-only register name (lower case).  NULL if the
    810962 *          parameters are invalid.
     963 *
     964 * @param   pVM                 The VM handle.
    811965 * @param   enmReg              The register identifier.
    812966 * @param   enmType             The register type.  This is for sort out
     
    814968 *                              the standard name.
    815969 */
    816 VMMR3DECL(const char *) DBGFR3RegCpuName(DBGFREG enmReg, DBGFREGVALTYPE enmType)
     970VMMR3DECL(const char *) DBGFR3RegCpuName(PVM pVM, DBGFREG enmReg, DBGFREGVALTYPE enmType)
    817971{
    818972    AssertReturn(enmReg >= DBGFREG_AL && enmReg < DBGFREG_END, NULL);
    819973    AssertReturn(enmType >= DBGFREGVALTYPE_INVALID && enmType < DBGFREGVALTYPE_END, NULL);
    820 
    821 #if 0 /** @todo need the optimization */
    822     PCDBGFREGDESC   pDesc  = &g_aDbgfRegDescs[enmReg];
    823     PCDBGFREGALIAS  pAlias = pDesc->paAliases;
     974    VM_ASSERT_VALID_EXT_RETURN(pVM, NULL);
     975
     976    PCDBGFREGSET    pSet    = pVM->aCpus[0].dbgf.s.pRegSet;
     977    if (RT_UNLIKELY(!pSet))
     978        return NULL;
     979
     980    PCDBGFREGDESC   pDesc   = &pSet->paDescs[enmReg];
     981    PCDBGFREGALIAS  pAlias  = pDesc->paAliases;
    824982    if (   pAlias
    825983        && pDesc->enmType != enmType
     
    835993
    836994    return pDesc->pszName;
    837 #else
    838     return NULL;
    839 #endif
    840 }
    841 
    842 /** @todo Implementing missing APIs. */
     995}
     996
     997
     998/**
     999 * Fold the string to lower case and copy it into the destination buffer.
     1000 *
     1001 * @returns Number of folder characters, -1 on overflow.
     1002 * @param   pszSrc              The source string.
     1003 * @param   cchSrc              How much to fold and copy.
     1004 * @param   pszDst              The output buffer.
     1005 * @param   cbDst               The size of the output buffer.
     1006 */
     1007static ssize_t dbgfR3RegCopyToLower(const char *pszSrc, size_t cchSrc, char *pszDst, size_t cbDst)
     1008{
     1009    ssize_t cchFolded = 0;
     1010    char    ch;
     1011    while (cchSrc-- > 0 && (ch = *pszSrc++))
     1012    {
     1013        if (RT_UNLIKELY(cbDst <= 1))
     1014            return -1;
     1015        cbDst--;
     1016
     1017        char chLower = RT_C_TO_LOWER(ch);
     1018        cchFolded += chLower != ch;
     1019        *pszDst++ = chLower;
     1020    }
     1021    if (RT_UNLIKELY(!cbDst))
     1022        return -1;
     1023    *pszDst = '\0';
     1024    return cchFolded;
     1025}
     1026
     1027
     1028/**
     1029 * Resolves the register name.
     1030 *
     1031 * @returns Lookup record.
     1032 * @param   pVM                 The VM handle.
     1033 * @param   idDefCpu            The default CPU ID set.
     1034 * @param   pszReg              The register name.
     1035 */
     1036static PCDBGFREGLOOKUP dbgfR3RegResolve(PVM pVM, VMCPUID idDefCpu, const char *pszReg)
     1037{
     1038    DBGF_REG_DB_LOCK_READ(pVM);
     1039
     1040    /* Try looking up the name without any case folding or cpu prefixing. */
     1041    PCDBGFREGLOOKUP pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pVM->dbgf.s.RegSpace, pszReg);
     1042    if (!pLookupRec)
     1043    {
     1044        char szName[DBGF_REG_MAX_NAME * 4 + 16];
     1045
     1046        /* Lower case it and try again. */
     1047        ssize_t cchFolded = dbgfR3RegCopyToLower(pszReg, RTSTR_MAX, szName, sizeof(szName) - DBGF_REG_MAX_NAME);
     1048        if (cchFolded > 0)
     1049            pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pVM->dbgf.s.RegSpace, szName);
     1050        if (   !pLookupRec
     1051            && cchFolded >= 0
     1052            && idDefCpu != VMCPUID_ANY)
     1053        {
     1054            /* Prefix it with the specified CPU set. */
     1055            size_t cchCpuSet = RTStrPrintf(szName, sizeof(szName), "cpu%u.", idDefCpu);
     1056            dbgfR3RegCopyToLower(pszReg, RTSTR_MAX, &szName[cchCpuSet], sizeof(szName) - cchCpuSet);
     1057            pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pVM->dbgf.s.RegSpace, szName);
     1058        }
     1059    }
     1060
     1061    DBGF_REG_DB_UNLOCK_READ(pVM);
     1062    return pLookupRec;
     1063}
     1064
     1065
     1066/**
     1067 * Performs a left shift on a RTUINT128U value.
     1068 *
     1069 * @returns pVal.
     1070 * @param   pVal                The value to shift (input/output).
     1071 * @param   cBits               The number of bits to shift it.  Negative
     1072 *                              numbers are treated as right shifts.
     1073 */
     1074static PRTUINT128U dbgfR3RegU128_ShiftLeft(PRTUINT128U pVal, int cBits)
     1075{
     1076    RTUINT128U const InVal = *pVal;
     1077
     1078    if (cBits >= 0)
     1079    {
     1080        if (cBits >= 128)
     1081            pVal->s.Lo  = pVal->s.Hi = 0;
     1082        else if (cBits >= 64)
     1083        {
     1084            pVal->s.Lo  = 0;
     1085            pVal->s.Hi  = InVal.s.Lo << (cBits - 64);
     1086        }
     1087        else
     1088        {
     1089            pVal->s.Hi  = InVal.s.Hi << cBits;
     1090            pVal->s.Hi |= InVal.s.Lo >> (64 - cBits);
     1091            pVal->s.Lo  = InVal.s.Lo << cBits;
     1092        }
     1093    }
     1094    else
     1095    {
     1096        /* (right shift) */
     1097        cBits = -cBits;
     1098        if (cBits >= 128)
     1099            pVal->s.Lo  = pVal->s.Hi = 0;
     1100        else if (cBits >= 64)
     1101        {
     1102            pVal->s.Hi  = 0;
     1103            pVal->s.Lo  = InVal.s.Hi >> (cBits - 64);
     1104        }
     1105        else
     1106        {
     1107            pVal->s.Lo  = InVal.s.Lo >> cBits;
     1108            pVal->s.Lo |= InVal.s.Hi << (64 - cBits);
     1109            pVal->s.Hi  = InVal.s.Hi >> cBits;
     1110        }
     1111    }
     1112    return pVal;
     1113}
     1114
     1115
     1116/**
     1117 * ANDs the RTUINT128U value against a bitmask made up of the first @a cBits
     1118 * bits.
     1119 *
     1120 * @returns pVal.
     1121 * @param   pVal                The value to shift (input/output).
     1122 * @param   cBits               The number of bits in the AND mask.
     1123 */
     1124static PRTUINT128U dbgfR3RegU128_AndNFirstBits(PRTUINT128U pVal, unsigned cBits)
     1125{
     1126    if (cBits <= 64)
     1127    {
     1128        pVal->s.Hi  = 0;
     1129        pVal->s.Lo &= RT_BIT_64(cBits) - 1;
     1130    }
     1131    else if (cBits < 128)
     1132        pVal->s.Hi &= RT_BIT_64(cBits - 64) - 1;
     1133    return pVal;
     1134}
     1135
     1136
     1137/**
     1138 * On CPU worker for the register queries, used by dbgfR3RegNmQueryWorker.
     1139 *
     1140 * @returns VBox status code.
     1141 *
     1142 * @param   pVM                 The VM handle.
     1143 * @param   pLookupRec          The register lookup record.
     1144 * @param   enmType             The desired return type.
     1145 * @param   pValue              Where to return the register value.
     1146 * @param   penmType            Where to store the register value type.
     1147 *                              Optional.
     1148 */
     1149static DECLCALLBACK(int) dbgfR3RegNmQueryWorkerOnCpu(PVM pVM, PCDBGFREGLOOKUP pLookupRec, DBGFREGVALTYPE enmType,
     1150                                                     PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
     1151{
     1152    PCDBGFREGDESC       pDesc        = pLookupRec->pDesc;
     1153    PCDBGFREGSET        pSet         = pLookupRec->pSet;
     1154    PCDBGFREGSUBFIELD   pSubField    = pLookupRec->pSubField;
     1155    DBGFREGVALTYPE      enmValueType = pDesc->enmType;
     1156    int                 rc;
     1157
     1158    /*
     1159     * Get the register or sub-field value.
     1160     */
     1161    dbgfR3RegValClear(pValue);
     1162    if (!pSubField)
     1163        rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, pValue);
     1164    else
     1165    {
     1166        if (pSubField->pfnGet)
     1167        {
     1168            rc = pSubField->pfnGet(pSet->uUserArg.pv, pSubField, &pValue->u128);
     1169            enmValueType = DBGFREGVALTYPE_U128;
     1170        }
     1171        else
     1172        {
     1173            rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, pValue);
     1174            if (RT_SUCCESS(rc))
     1175            {
     1176                rc = dbgfR3RegValCast(pValue, enmValueType, DBGFREGVALTYPE_U128);
     1177                if (RT_SUCCESS(rc))
     1178                {
     1179                    dbgfR3RegU128_ShiftLeft(&pValue->u128, -pSubField->iFirstBit);
     1180                    dbgfR3RegU128_AndNFirstBits(&pValue->u128, pSubField->cBits);
     1181                    if (pSubField->cShift)
     1182                        dbgfR3RegU128_ShiftLeft(&pValue->u128, pSubField->cShift);
     1183                }
     1184            }
     1185        }
     1186        if (RT_SUCCESS(rc))
     1187        {
     1188            unsigned const cBits = pSubField->cBits + pSubField->cShift;
     1189            if (cBits <= 8)
     1190                enmValueType = DBGFREGVALTYPE_U8;
     1191            else if (cBits <= 16)
     1192                enmValueType = DBGFREGVALTYPE_U16;
     1193            else if (cBits <= 32)
     1194                enmValueType = DBGFREGVALTYPE_U32;
     1195            else if (cBits <= 64)
     1196                enmValueType = DBGFREGVALTYPE_U64;
     1197            else
     1198                enmValueType = DBGFREGVALTYPE_U128;
     1199            rc = dbgfR3RegValCast(pValue, DBGFREGVALTYPE_U128, enmValueType);
     1200        }
     1201    }
     1202    if (RT_SUCCESS(rc))
     1203    {
     1204        /*
     1205         * Do the cast if the desired return type doesn't match what
     1206         * the getter returned.
     1207         */
     1208        if (   enmValueType == enmType
     1209            || enmType == DBGFREGVALTYPE_END)
     1210        {
     1211            rc = VINF_SUCCESS;
     1212            if (penmType)
     1213                *penmType = enmValueType;
     1214        }
     1215        else
     1216        {
     1217            rc = dbgfR3RegValCast(pValue, enmValueType, enmType);
     1218            if (penmType)
     1219                *penmType = RT_SUCCESS(rc) ? enmType : enmValueType;
     1220        }
     1221    }
     1222
     1223    return rc;
     1224}
     1225
     1226
     1227/**
     1228 * Worker for the register queries.
     1229 *
     1230 * @returns VBox status code.
     1231 * @retval  VINF_SUCCESS
     1232 * @retval  VERR_INVALID_VM_HANDLE
     1233 * @retval  VERR_INVALID_CPU_ID
     1234 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1235 * @retval  VERR_DBGF_UNSUPPORTED_CAST
     1236 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     1237 * @retval  VINF_DBGF_ZERO_EXTENDED_REGISTER
     1238 *
     1239 * @param   pVM                 The VM handle.
     1240 * @param   idDefCpu            The virtual CPU ID for the default CPU register
     1241 *                              set.
     1242 * @param   pszReg              The register to query.
     1243 * @param   enmType             The desired return type.
     1244 * @param   pValue              Where to return the register value.
     1245 * @param   penmType            Where to store the register value type.
     1246 *                              Optional.
     1247 */
     1248static DECLCALLBACK(int) dbgfR3RegNmQueryWorker(PVM pVM, VMCPUID idDefCpu, const char *pszReg, DBGFREGVALTYPE enmType,
     1249                                                PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
     1250{
     1251    /*
     1252     * Validate input.
     1253     */
     1254    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     1255    AssertReturn(idDefCpu < pVM->cCpus || idDefCpu == VMCPUID_ANY, VERR_INVALID_CPU_ID);
     1256    AssertPtrReturn(pszReg, VERR_INVALID_POINTER);
     1257
     1258    Assert(enmType > DBGFREGVALTYPE_INVALID && enmType <= DBGFREGVALTYPE_END);
     1259    AssertPtr(pValue);
     1260
     1261    /*
     1262     * Resolve the register and call the getter on the relevant CPU.
     1263     */
     1264    PCDBGFREGLOOKUP pLookupRec = dbgfR3RegResolve(pVM, idDefCpu, pszReg);
     1265    if (pLookupRec)
     1266    {
     1267        if (pLookupRec->pSet->enmType == DBGFREGSETTYPE_CPU)
     1268            idDefCpu = pLookupRec->pSet->uUserArg.pVCpu->idCpu;
     1269        return VMR3ReqCallWait(pVM, idDefCpu, (PFNRT)dbgfR3RegNmQueryWorkerOnCpu, 5, pVM, pLookupRec, enmType, pValue, penmType);
     1270    }
     1271    return VERR_DBGF_REGISTER_NOT_FOUND;
     1272}
     1273
     1274
     1275/**
     1276 * Queries a descriptor table register value.
     1277 *
     1278 * @retval  VINF_SUCCESS
     1279 * @retval  VERR_INVALID_VM_HANDLE
     1280 * @retval  VERR_INVALID_CPU_ID
     1281 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1282 *
     1283 * @param   pVM                 The VM handle.
     1284 * @param   idDefCpu            The default target CPU ID, VMCPUID_ANY if not
     1285 *                              applicable.
     1286 * @param   pszReg              The register that's being queried.  Except for
     1287 *                              CPU registers, this must be on the form
     1288 *                              "set.reg[.sub]".
     1289 * @param   pValue              Where to store the register value.
     1290 * @param   penmType            Where to store the register value type.
     1291 */
     1292VMMR3DECL(int) DBGFR3RegNmQuery(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType)
     1293{
     1294    return dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_END, pValue, penmType);
     1295}
     1296
     1297
     1298/**
     1299 * Queries a 8-bit register value.
     1300 *
     1301 * @retval  VINF_SUCCESS
     1302 * @retval  VERR_INVALID_VM_HANDLE
     1303 * @retval  VERR_INVALID_CPU_ID
     1304 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1305 * @retval  VERR_DBGF_UNSUPPORTED_CAST
     1306 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     1307 *
     1308 * @param   pVM                 The VM handle.
     1309 * @param   idDefCpu            The default target CPU ID, VMCPUID_ANY if not
     1310 *                              applicable.
     1311 * @param   pszReg              The register that's being queried.  Except for
     1312 *                              CPU registers, this must be on the form
     1313 *                              "set.reg[.sub]".
     1314 * @param   pu8                 Where to store the register value.
     1315 */
     1316VMMR3DECL(int) DBGFR3RegNmQueryU8(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8)
     1317{
     1318    DBGFREGVAL Value;
     1319    int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U8, &Value, NULL);
     1320    if (RT_SUCCESS(rc))
     1321        *pu8 = Value.u8;
     1322    else
     1323        *pu8 = 0;
     1324    return rc;
     1325}
     1326
     1327
     1328/**
     1329 * Queries a 16-bit register value.
     1330 *
     1331 * @retval  VINF_SUCCESS
     1332 * @retval  VERR_INVALID_VM_HANDLE
     1333 * @retval  VERR_INVALID_CPU_ID
     1334 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1335 * @retval  VERR_DBGF_UNSUPPORTED_CAST
     1336 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     1337 * @retval  VINF_DBGF_ZERO_EXTENDED_REGISTER
     1338 *
     1339 * @param   pVM                 The VM handle.
     1340 * @param   idDefCpu            The default target CPU ID, VMCPUID_ANY if not
     1341 *                              applicable.
     1342 * @param   pszReg              The register that's being queried.  Except for
     1343 *                              CPU registers, this must be on the form
     1344 *                              "set.reg[.sub]".
     1345 * @param   pu16                Where to store the register value.
     1346 */
     1347VMMR3DECL(int) DBGFR3RegNmQueryU16(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16)
     1348{
     1349    DBGFREGVAL Value;
     1350    int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U16, &Value, NULL);
     1351    if (RT_SUCCESS(rc))
     1352        *pu16 = Value.u16;
     1353    else
     1354        *pu16 = 0;
     1355    return rc;
     1356}
     1357
     1358
     1359/**
     1360 * Queries a 32-bit register value.
     1361 *
     1362 * @retval  VINF_SUCCESS
     1363 * @retval  VERR_INVALID_VM_HANDLE
     1364 * @retval  VERR_INVALID_CPU_ID
     1365 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1366 * @retval  VERR_DBGF_UNSUPPORTED_CAST
     1367 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     1368 * @retval  VINF_DBGF_ZERO_EXTENDED_REGISTER
     1369 *
     1370 * @param   pVM                 The VM handle.
     1371 * @param   idDefCpu            The default target CPU ID, VMCPUID_ANY if not
     1372 *                              applicable.
     1373 * @param   pszReg              The register that's being queried.  Except for
     1374 *                              CPU registers, this must be on the form
     1375 *                              "set.reg[.sub]".
     1376 * @param   pu32                Where to store the register value.
     1377 */
     1378VMMR3DECL(int) DBGFR3RegNmQueryU32(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32)
     1379{
     1380    DBGFREGVAL Value;
     1381    int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U32, &Value, NULL);
     1382    if (RT_SUCCESS(rc))
     1383        *pu32 = Value.u32;
     1384    else
     1385        *pu32 = 0;
     1386    return rc;
     1387}
     1388
     1389
     1390/**
     1391 * Queries a 64-bit register value.
     1392 *
     1393 * @retval  VINF_SUCCESS
     1394 * @retval  VERR_INVALID_VM_HANDLE
     1395 * @retval  VERR_INVALID_CPU_ID
     1396 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1397 * @retval  VERR_DBGF_UNSUPPORTED_CAST
     1398 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     1399 * @retval  VINF_DBGF_ZERO_EXTENDED_REGISTER
     1400 *
     1401 * @param   pVM                 The VM handle.
     1402 * @param   idDefCpu            The default target CPU ID, VMCPUID_ANY if not
     1403 *                              applicable.
     1404 * @param   pszReg              The register that's being queried.  Except for
     1405 *                              CPU registers, this must be on the form
     1406 *                              "set.reg[.sub]".
     1407 * @param   pu64                Where to store the register value.
     1408 */
     1409VMMR3DECL(int) DBGFR3RegNmQueryU64(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64)
     1410{
     1411    DBGFREGVAL Value;
     1412    int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U64, &Value, NULL);
     1413    if (RT_SUCCESS(rc))
     1414        *pu64 = Value.u64;
     1415    else
     1416        *pu64 = 0;
     1417    return rc;
     1418}
     1419
     1420
     1421/**
     1422 * Queries a 128-bit register value.
     1423 *
     1424 * @retval  VINF_SUCCESS
     1425 * @retval  VERR_INVALID_VM_HANDLE
     1426 * @retval  VERR_INVALID_CPU_ID
     1427 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1428 * @retval  VERR_DBGF_UNSUPPORTED_CAST
     1429 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     1430 * @retval  VINF_DBGF_ZERO_EXTENDED_REGISTER
     1431 *
     1432 * @param   pVM                 The VM handle.
     1433 * @param   idDefCpu            The default target CPU ID, VMCPUID_ANY if not
     1434 *                              applicable.
     1435 * @param   pszReg              The register that's being queried.  Except for
     1436 *                              CPU registers, this must be on the form
     1437 *                              "set.reg[.sub]".
     1438 * @param   pu128               Where to store the register value.
     1439 */
     1440VMMR3DECL(int) DBGFR3RegNmQueryU128(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128)
     1441{
     1442    DBGFREGVAL Value;
     1443    int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U128, &Value, NULL);
     1444    if (RT_SUCCESS(rc))
     1445        *pu128 = Value.u128;
     1446    else
     1447        pu128->s.Hi = pu128->s.Lo = 0;
     1448    return rc;
     1449}
     1450
     1451
     1452/**
     1453 * Queries a long double register value.
     1454 *
     1455 * @retval  VINF_SUCCESS
     1456 * @retval  VERR_INVALID_VM_HANDLE
     1457 * @retval  VERR_INVALID_CPU_ID
     1458 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1459 * @retval  VERR_DBGF_UNSUPPORTED_CAST
     1460 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     1461 * @retval  VINF_DBGF_ZERO_EXTENDED_REGISTER
     1462 *
     1463 * @param   pVM                 The VM handle.
     1464 * @param   idDefCpu            The default target CPU ID, VMCPUID_ANY if not
     1465 *                              applicable.
     1466 * @param   pszReg              The register that's being queried.  Except for
     1467 *                              CPU registers, this must be on the form
     1468 *                              "set.reg[.sub]".
     1469 * @param   plrd                Where to store the register value.
     1470 */
     1471VMMR3DECL(int) DBGFR3RegNmQueryLrd(PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd)
     1472{
     1473    DBGFREGVAL Value;
     1474    int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_LRD, &Value, NULL);
     1475    if (RT_SUCCESS(rc))
     1476        *plrd = Value.lrd;
     1477    else
     1478        *plrd = 0;
     1479    return rc;
     1480}
     1481
     1482
     1483/**
     1484 * Queries a descriptor table register value.
     1485 *
     1486 * @retval  VINF_SUCCESS
     1487 * @retval  VERR_INVALID_VM_HANDLE
     1488 * @retval  VERR_INVALID_CPU_ID
     1489 * @retval  VERR_DBGF_REGISTER_NOT_FOUND
     1490 * @retval  VERR_DBGF_UNSUPPORTED_CAST
     1491 * @retval  VINF_DBGF_TRUNCATED_REGISTER
     1492 * @retval  VINF_DBGF_ZERO_EXTENDED_REGISTER
     1493 *
     1494 * @param   pVM                 The VM handle.
     1495 * @param   idDefCpu            The default target CPU ID, VMCPUID_ANY if not
     1496 *                              applicable.
     1497 * @param   pszReg              The register that's being queried.  Except for
     1498 *                              CPU registers, this must be on the form
     1499 *                              "set.reg[.sub]".
     1500 * @param   pu64Base            Where to store the register base value.
     1501 * @param   pu32Limit           Where to store the register limit value.
     1502 */
     1503VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint32_t *pu32Limit)
     1504{
     1505    DBGFREGVAL Value;
     1506    int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_DTR, &Value, NULL);
     1507    if (RT_SUCCESS(rc))
     1508    {
     1509        *pu64Base  = Value.dtr.u64Base;
     1510        *pu32Limit = Value.dtr.u32Limit;
     1511    }
     1512    else
     1513    {
     1514        *pu64Base  = 0;
     1515        *pu32Limit = 0;
     1516    }
     1517    return rc;
     1518}
     1519
     1520
     1521/// @todo VMMR3DECL(int) DBGFR3RegNmQueryBatch(PVM pVM,VMCPUID idDefCpu, DBGFREGENTRYNM paRegs, size_t cRegs);
     1522
     1523
     1524/**
     1525 * Gets the number of registers returned by DBGFR3RegNmQueryAll.
     1526 *
     1527 * @returns VBox status code.
     1528 * @param   pVM                 The VM handle.
     1529 * @param   pcRegs              Where to return the register count.
     1530 */
     1531VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PVM pVM, size_t *pcRegs)
     1532{
     1533    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     1534    *pcRegs = pVM->dbgf.s.cRegs;
     1535    return VINF_SUCCESS;
     1536}
     1537
     1538
     1539VMMR3DECL(int) DBGFR3RegNmQueryAll(PVM pVM, DBGFREGENTRYNM paRegs, size_t cRegs)
     1540{
     1541    return VERR_NOT_IMPLEMENTED;
     1542}
     1543
     1544
     1545/// @todo VMMR3DECL(int) DBGFR3RegNmPrintf(PVM pVM, VMCPUID idDefCpu, char pszBuf, size_t cbBuf, const char *pszFormat, ...);
     1546/// @todo VMMR3DECL(int) DBGFR3RegNmPrintfV(PVM pVM, VMCPUID idDefCpu, char pszBuf, size_t cbBuf, const char *pszFormat, ...);
     1547
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