Index: trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp	(revision 35470)
+++ trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp	(revision 35490)
@@ -30,4 +30,5 @@
 #include <iprt/ctype.h>
 #include <iprt/string.h>
+#include <iprt/uint128.h>
 
 
@@ -156,5 +157,11 @@
 int dbgfR3RegInit(PVM pVM)
 {
-    return RTSemRWCreate(&pVM->dbgf.s.hRegDbLock);
+    int rc = VINF_SUCCESS;
+    if (!pVM->dbgf.s.fRegDbInitialized)
+    {
+        rc = RTSemRWCreate(&pVM->dbgf.s.hRegDbLock);
+        pVM->dbgf.s.fRegDbInitialized = RT_SUCCESS(rc);
+    }
+    return rc;
 }
 
@@ -169,4 +176,5 @@
     RTSemRWDestroy(pVM->dbgf.s.hRegDbLock);
     pVM->dbgf.s.hRegDbLock = NIL_RTSEMRW;
+    pVM->dbgf.s.fRegDbInitialized = false;
 }
 
@@ -179,6 +187,7 @@
  * @returns true if valid, false if not.
  * @param   pszName             The register name to validate.
- */
-static bool dbgfR3RegIsNameValid(const char *pszName)
+ * @param   chDot               Set to '.' if accepted, otherwise 0.
+ */
+static bool dbgfR3RegIsNameValid(const char *pszName, char chDot)
 {
     const char *psz = pszName;
@@ -189,5 +198,6 @@
         if (   !RT_C_IS_LOWER(ch)
             && !RT_C_IS_DIGIT(ch)
-            && ch != '_')
+            && ch != '_'
+            && ch != chDot)
             return false;
     if (psz - pszName > DBGF_REG_MAX_NAME)
@@ -215,5 +225,5 @@
      */
     /* The name components. */
-    AssertMsgReturn(dbgfR3RegIsNameValid(pszPrefix), ("%s\n", pszPrefix), VERR_INVALID_NAME);
+    AssertMsgReturn(dbgfR3RegIsNameValid(pszPrefix, 0), ("%s\n", pszPrefix), VERR_INVALID_NAME);
     const char  *psz             = RTStrEnd(pszPrefix, RTSTR_MAX);
     bool const   fNeedUnderscore = RT_C_IS_DIGIT(psz[-1]);
@@ -228,5 +238,5 @@
     for (iDesc = 0; paRegisters[iDesc].pszName != NULL; iDesc++)
     {
-        AssertMsgReturn(dbgfR3RegIsNameValid(paRegisters[iDesc].pszName), ("%s (#%u)\n", paRegisters[iDesc].pszName, iDesc), VERR_INVALID_NAME);
+        AssertMsgReturn(dbgfR3RegIsNameValid(paRegisters[iDesc].pszName, 0), ("%s (#%u)\n", paRegisters[iDesc].pszName, iDesc), VERR_INVALID_NAME);
 
         if (enmType == DBGFREGSETTYPE_CPU)
@@ -238,5 +248,5 @@
         AssertReturn(   paRegisters[iDesc].enmType > DBGFREGVALTYPE_INVALID
                      && paRegisters[iDesc].enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER);
-        AssertMsgReturn(paRegisters[iDesc].fFlags & ~DBGFREG_FLAGS_READ_ONLY,
+        AssertMsgReturn(!(paRegisters[iDesc].fFlags & ~DBGFREG_FLAGS_READ_ONLY),
                         ("%#x (#%u)\n", paRegisters[iDesc].fFlags, iDesc),
                         VERR_INVALID_PARAMETER);
@@ -251,5 +261,5 @@
             for (; paAliases[iAlias].pszName; iAlias++)
             {
-                AssertMsgReturn(dbgfR3RegIsNameValid(paAliases[iAlias].pszName), ("%s (%s)\n", paAliases[iAlias].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
+                AssertMsgReturn(dbgfR3RegIsNameValid(paAliases[iAlias].pszName, 0), ("%s (%s)\n", paAliases[iAlias].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
                 AssertReturn(   paAliases[iAlias].enmType > DBGFREGVALTYPE_INVALID
                              && paAliases[iAlias].enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER);
@@ -264,5 +274,5 @@
             for (; paSubFields[iSubField].pszName; iSubField++)
             {
-                AssertMsgReturn(dbgfR3RegIsNameValid(paSubFields[iSubField].pszName), ("%s (%s)\n", paSubFields[iSubField].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
+                AssertMsgReturn(dbgfR3RegIsNameValid(paSubFields[iSubField].pszName, '.'), ("%s (%s)\n", paSubFields[iSubField].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);
                 AssertReturn(paSubFields[iSubField].iFirstBit + paSubFields[iSubField].cBits <= 128, VERR_INVALID_PARAMETER);
                 AssertReturn(paSubFields[iSubField].cBits + paSubFields[iSubField].cShift <= 128, VERR_INVALID_PARAMETER);
@@ -323,6 +333,6 @@
         while (RT_SUCCESS(rc))
         {
-            size_t cchReg = strlen(paRegisters[iDesc].pszName);
-            memcpy(pszReg, paRegisters[iDesc].pszName, cchReg + 1);
+            size_t cchReg = strlen(pszRegName);
+            memcpy(pszReg, pszRegName, cchReg + 1);
             pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName);
             if (!pLookupRec->Core.pszString)
@@ -332,4 +342,5 @@
             pLookupRec->pAlias    = pCurAlias;
             pLookupRec->pSubField = NULL;
+            pLookupRec++;
 
             PCDBGFREGSUBFIELD paSubFields = paRegisters[iDesc].paSubFields;
@@ -348,4 +359,5 @@
                     pLookupRec->pAlias    = pCurAlias;
                     pLookupRec->pSubField = &paSubFields[iSubField];
+                    pLookupRec++;
                 }
             }
@@ -353,10 +365,12 @@
             /* next */
             pCurAlias = pNextAlias++;
-            if (   !pCurAlias
-                || !pCurAlias->pszName)
+            if (!pCurAlias)
                 break;
             pszRegName = pCurAlias->pszName;
+            if (!pszRegName)
+                break;
         }
     }
+    Assert(pLookupRec == &pRegSet->paLookupRecs[pRegSet->cLookupRecs]);
 
     if (RT_SUCCESS(rc))
@@ -406,10 +420,18 @@
  *
  * @returns VBox status code.
+ * @param   pVM             The VM handle.
  * @param   pVCpu           The virtual CPU handle.
  * @param   paRegisters     The register descriptors.
  */
-VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVMCPU pVCpu, PCDBGFREGDESC paRegisters)
-{
-    return dbgfR3RegRegisterCommon(pVCpu->pVMR3, paRegisters, DBGFREGSETTYPE_CPU, pVCpu, "cpu", pVCpu->idCpu);
+VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters)
+{
+    if (!pVM->dbgf.s.fRegDbInitialized)
+    {
+        int rc = dbgfR3RegInit(pVM);
+        if (RT_FAILURE(rc))
+            return rc;
+    }
+
+    return dbgfR3RegRegisterCommon(pVM, paRegisters, DBGFREGSETTYPE_CPU, pVCpu, "cpu", pVCpu->idCpu);
 }
 
@@ -1065,75 +1087,4 @@
 
 /**
- * Performs a left shift on a RTUINT128U value.
- *
- * @returns pVal.
- * @param   pVal                The value to shift (input/output).
- * @param   cBits               The number of bits to shift it.  Negative
- *                              numbers are treated as right shifts.
- */
-static PRTUINT128U dbgfR3RegU128_ShiftLeft(PRTUINT128U pVal, int cBits)
-{
-    RTUINT128U const InVal = *pVal;
-
-    if (cBits >= 0)
-    {
-        if (cBits >= 128)
-            pVal->s.Lo  = pVal->s.Hi = 0;
-        else if (cBits >= 64)
-        {
-            pVal->s.Lo  = 0;
-            pVal->s.Hi  = InVal.s.Lo << (cBits - 64);
-        }
-        else
-        {
-            pVal->s.Hi  = InVal.s.Hi << cBits;
-            pVal->s.Hi |= InVal.s.Lo >> (64 - cBits);
-            pVal->s.Lo  = InVal.s.Lo << cBits;
-        }
-    }
-    else
-    {
-        /* (right shift) */
-        cBits = -cBits;
-        if (cBits >= 128)
-            pVal->s.Lo  = pVal->s.Hi = 0;
-        else if (cBits >= 64)
-        {
-            pVal->s.Hi  = 0;
-            pVal->s.Lo  = InVal.s.Hi >> (cBits - 64);
-        }
-        else
-        {
-            pVal->s.Lo  = InVal.s.Lo >> cBits;
-            pVal->s.Lo |= InVal.s.Hi << (64 - cBits);
-            pVal->s.Hi  = InVal.s.Hi >> cBits;
-        }
-    }
-    return pVal;
-}
-
-
-/**
- * ANDs the RTUINT128U value against a bitmask made up of the first @a cBits
- * bits.
- *
- * @returns pVal.
- * @param   pVal                The value to shift (input/output).
- * @param   cBits               The number of bits in the AND mask.
- */
-static PRTUINT128U dbgfR3RegU128_AndNFirstBits(PRTUINT128U pVal, unsigned cBits)
-{
-    if (cBits <= 64)
-    {
-        pVal->s.Hi  = 0;
-        pVal->s.Lo &= RT_BIT_64(cBits) - 1;
-    }
-    else if (cBits < 128)
-        pVal->s.Hi &= RT_BIT_64(cBits - 64) - 1;
-    return pVal;
-}
-
-
-/**
  * On CPU worker for the register queries, used by dbgfR3RegNmQueryWorker.
  *
@@ -1177,8 +1128,8 @@
                 if (RT_SUCCESS(rc))
                 {
-                    dbgfR3RegU128_ShiftLeft(&pValue->u128, -pSubField->iFirstBit);
-                    dbgfR3RegU128_AndNFirstBits(&pValue->u128, pSubField->cBits);
+                    RTUInt128AssignShiftLeft(&pValue->u128, -pSubField->iFirstBit);
+                    RTUInt128AssignAndNFirstBits(&pValue->u128, pSubField->cBits);
                     if (pSubField->cShift)
-                        dbgfR3RegU128_ShiftLeft(&pValue->u128, pSubField->cShift);
+                        RTUInt128AssignShiftLeft(&pValue->u128, pSubField->cShift);
                 }
             }
