Index: /trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp	(revision 35589)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp	(revision 35590)
@@ -1220,5 +1220,5 @@
 /**
  * On CPU worker for the register queries, used by dbgfR3RegNmQueryWorker and
- * dbgfR3RegNmPrintfCbFormat.
+ * dbgfR3RegNmPrintfCbFormatNormal.
  *
  * @returns VBox status code.
@@ -1843,5 +1843,5 @@
 {
     /*
-     * Format to temporary buffer using worker shared with dbgfR3RegNmPrintfCbFormat.
+     * Format to temporary buffer using worker shared with dbgfR3RegNmPrintfCbFormatNormal.
      */
     char szTmp[160];
@@ -1905,4 +1905,134 @@
 
 /**
+ * Format a register using special hacks as well as sub-field specifications
+ * (the latter isn't implemented yet).
+ */
+static size_t
+dbgfR3RegNmPrintfCbFormatField(PDBGFR3REGNMPRINTFARGS pThis, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                               PCDBGFREGLOOKUP pLookupRec, int cchWidth, int cchPrecision, unsigned fFlags)
+{
+    char szTmp[160];
+
+    /*
+     * Retrieve the register value.
+     */
+    DBGFREGVAL      Value;
+    DBGFREGVALTYPE  enmType;
+    int rc = dbgfR3RegNmQueryWorkerOnCpu(pThis->pVM, pLookupRec, DBGFREGVALTYPE_END, &Value, &enmType);
+    if (RT_FAILURE(rc))
+    {
+        PCRTSTATUSMSG pErr = RTErrGet(rc);
+        if (pErr)
+            return pfnOutput(pvArgOutput, pErr->pszDefine, strlen(pErr->pszDefine));
+        return pfnOutput(pvArgOutput, szTmp, RTStrPrintf(szTmp, sizeof(szTmp), "rc=%d", rc));
+    }
+
+    char *psz = szTmp;
+
+    /*
+     * Special case: Format eflags.
+     */
+    if (   pLookupRec->pSet->enmType == DBGFREGSETTYPE_CPU
+        && pLookupRec->pDesc->enmReg == DBGFREG_RFLAGS
+        && pLookupRec->pSubField     == NULL)
+    {
+        rc = dbgfR3RegValCast(&Value, enmType, DBGFREGVALTYPE_U32);
+        AssertRC(rc);
+        uint32_t const efl = Value.u32;
+
+        /* the iopl */
+        psz += RTStrPrintf(psz, sizeof(szTmp) / 2, "iopl=%u ", X86_EFL_GET_IOPL(efl));
+
+        /* add flags */
+        static const struct
+        {
+            const char *pszSet;
+            const char *pszClear;
+            uint32_t fFlag;
+        } aFlags[] =
+        {
+            { "vip",NULL, X86_EFL_VIP },
+            { "vif",NULL, X86_EFL_VIF },
+            { "ac", NULL, X86_EFL_AC },
+            { "vm", NULL, X86_EFL_VM },
+            { "rf", NULL, X86_EFL_RF },
+            { "nt", NULL, X86_EFL_NT },
+            { "ov", "nv", X86_EFL_OF },
+            { "dn", "up", X86_EFL_DF },
+            { "ei", "di", X86_EFL_IF },
+            { "tf", NULL, X86_EFL_TF },
+            { "ng", "pl", X86_EFL_SF },
+            { "zr", "nz", X86_EFL_ZF },
+            { "ac", "na", X86_EFL_AF },
+            { "po", "pe", X86_EFL_PF },
+            { "cy", "nc", X86_EFL_CF },
+        };
+        for (unsigned i = 0; i < RT_ELEMENTS(aFlags); i++)
+        {
+            const char *pszAdd = aFlags[i].fFlag & efl ? aFlags[i].pszSet : aFlags[i].pszClear;
+            if (pszAdd)
+            {
+                *psz++ = *pszAdd++;
+                *psz++ = *pszAdd++;
+                if (*pszAdd)
+                    *psz++ = *pszAdd++;
+                *psz++ = ' ';
+            }
+        }
+
+        /* drop trailing space */
+        psz--;
+    }
+    else
+    {
+        /*
+         * General case.
+         */
+        AssertMsgFailed(("Not implemented: %s\n", pLookupRec->Core.pszString));
+        return pfnOutput(pvArgOutput, pLookupRec->Core.pszString, pLookupRec->Core.cchString);
+    }
+
+    /* Output the string. */
+    return pfnOutput(pvArgOutput, szTmp, psz - &szTmp[0]);
+}
+
+
+/**
+ * Formats a register having parsed up to the register name.
+ */
+static size_t
+dbgfR3RegNmPrintfCbFormatNormal(PDBGFR3REGNMPRINTFARGS pThis, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+                                PCDBGFREGLOOKUP pLookupRec, unsigned uBase, int cchWidth, int cchPrecision, unsigned fFlags)
+{
+    char szTmp[160];
+
+    /*
+     * Get the register value.
+     */
+    DBGFREGVAL      Value;
+    DBGFREGVALTYPE  enmType;
+    int rc = dbgfR3RegNmQueryWorkerOnCpu(pThis->pVM, pLookupRec, DBGFREGVALTYPE_END, &Value, &enmType);
+    if (RT_FAILURE(rc))
+    {
+        PCRTSTATUSMSG pErr = RTErrGet(rc);
+        if (pErr)
+            return pfnOutput(pvArgOutput, pErr->pszDefine, strlen(pErr->pszDefine));
+        return pfnOutput(pvArgOutput, szTmp, RTStrPrintf(szTmp, sizeof(szTmp), "rc=%d", rc));
+    }
+
+    /*
+     * Format the value.
+     */
+    ssize_t cchOutput = dbgfR3RegFormatValueInt(szTmp, sizeof(szTmp), &Value, enmType, uBase, cchWidth, cchPrecision, fFlags);
+    if (RT_UNLIKELY(cchOutput <= 0))
+    {
+        AssertFailed();
+        return pfnOutput(pvArgOutput, "internal-error", sizeof("internal-error") - 1);
+    }
+    return pfnOutput(pvArgOutput, szTmp, cchOutput);
+}
+
+
+/**
  * @callback_method_impl{FNSTRFORMAT}
  */
@@ -1912,10 +2042,8 @@
                           int cchPrecision, unsigned fFlags, char chArgSize)
 {
+    /*
+     * Parse the format type and hand the job to the appropriate worker.
+     */
     PDBGFR3REGNMPRINTFARGS pThis = (PDBGFR3REGNMPRINTFARGS)pvArg;
-
-    /*
-     * Parse out the register bits of the register format type.  Noisily reject
-     * unknown format types.
-     */
     const char *pszFormat = *ppszFormat;
     if (    pszFormat[0] != 'V'
@@ -1925,27 +2053,19 @@
         return 0;
     }
-    unsigned uBase;
-    if (pszFormat[2] == '{')
-        uBase = 16;
-    else if (   pszFormat[2] == 'U'
-             && pszFormat[3] == '{')
-        uBase = 10;
-    else if (   pszFormat[2] == 'O'
-             && pszFormat[3] == '{')
-        uBase = 8;
-    else if (   pszFormat[2] == 'B'
-             && pszFormat[3] == '{')
-        uBase = 2;
-    else
-    {
-        AssertMsgFailed(("'%s'\n", pszFormat));
-        return 0;
-    }
-
-    const char * const  pachReg = &pszFormat[3];
-    const char         *pszEnd = strchr(&pachReg[3], '}');
+    unsigned offCurly = 2;
+    if (pszFormat[offCurly] != '{')
+    {
+        AssertMsgReturn(pszFormat[offCurly], ("'%s'\n", pszFormat), 0);
+        offCurly++;
+        AssertMsgReturn(pszFormat[offCurly] == '{', ("'%s'\n", pszFormat), 0);
+    }
+    const char *pachReg = &pszFormat[offCurly + 1];
+
+    /*
+     * The end and length of the register.
+     */
+    const char *pszEnd = strchr(&pachReg[3], '}');
     AssertMsgReturn(pszEnd, ("Missing closing curly bracket: '%s'\n", pszFormat), 0);
-
-    size_t const cchReg = pachReg - pszEnd;
+    size_t const cchReg = pszEnd - pachReg;
 
     /*
@@ -1953,6 +2073,4 @@
      * input string termination.
      */
-    char szTmp[DBGF_REG_MAX_NAME * 4 + 64];
-
     /* Try looking up the name without any case folding or cpu prefixing. */
     PCDBGFREGLOOKUP pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGetN(&pThis->pVM->dbgf.s.RegSpace, pachReg, cchReg);
@@ -1960,7 +2078,8 @@
     {
         /* Lower case it and try again. */
-        ssize_t cchFolded = dbgfR3RegCopyToLower(pachReg, cchReg, szTmp, sizeof(szTmp) - DBGF_REG_MAX_NAME);
+        char szName[DBGF_REG_MAX_NAME * 4 + 16];
+        ssize_t cchFolded = dbgfR3RegCopyToLower(pachReg, cchReg, szName, sizeof(szName) - DBGF_REG_MAX_NAME);
         if (cchFolded > 0)
-            pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pThis->pVM->dbgf.s.RegSpace, szTmp);
+            pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pThis->pVM->dbgf.s.RegSpace, szName);
         if (   !pLookupRec
             && cchFolded >= 0
@@ -1968,7 +2087,7 @@
         {
             /* Prefix it with the specified CPU set. */
-            size_t cchCpuSet = RTStrPrintf(szTmp, sizeof(szTmp), "cpu%u.", pThis->idCpu);
-            dbgfR3RegCopyToLower(pachReg, cchReg, &szTmp[cchCpuSet], sizeof(szTmp) - cchCpuSet);
-            pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pThis->pVM->dbgf.s.RegSpace, szTmp);
+            size_t cchCpuSet = RTStrPrintf(szName, sizeof(szName), "cpu%u.", pThis->idCpu);
+            dbgfR3RegCopyToLower(pachReg, cchReg, &szName[cchCpuSet], sizeof(szName) - cchCpuSet);
+            pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pThis->pVM->dbgf.s.RegSpace, szName);
         }
     }
@@ -1979,32 +2098,36 @@
                     0);
 
-    /* Commit the format type parsing so we can return more freely below. */
-    *ppszFormat = pszFormat;
-
-    /*
-     * Get the register value.
-     */
-    DBGFREGVAL      Value;
-    DBGFREGVALTYPE  enmType;
-    int rc = dbgfR3RegNmQueryWorkerOnCpu(pThis->pVM, pLookupRec, DBGFREGVALTYPE_END, &Value, &enmType);
-    if (RT_FAILURE(rc))
-    {
-        PCRTSTATUSMSG pErr = RTErrGet(rc);
-        if (pErr)
-            return pfnOutput(pvArgOutput, pErr->pszDefine, strlen(pErr->pszDefine));
-        return pfnOutput(pvArgOutput, szTmp, RTStrPrintf(szTmp, sizeof(szTmp), "rc=%d", rc));
-    }
-
-    /*
-     * Format the value.
-     */
-    ssize_t cchOutput = dbgfR3RegFormatValueInt(szTmp, sizeof(szTmp), &Value, enmType, uBase, cchWidth, cchPrecision, fFlags);
-    if (RT_UNLIKELY(cchOutput <= 0))
-    {
-        AssertFailed();
-        return pfnOutput(pvArgOutput, "internal-error", sizeof("internal-error") - 1);
-    }
-    return pfnOutput(pvArgOutput, szTmp, cchOutput);
-}
+    /*
+     * Commit the parsed format string.  Up to this point it is nice to know
+     * what register lookup failed and such, so we've delayed comitting.
+     */
+    *ppszFormat = pszEnd + 1;
+
+    /*
+     * Call the responsible worker.
+     */
+    switch (pszFormat[offCurly - 1])
+    {
+        case 'R': /* %VR{} */
+        case 'X': /* %VRX{} */
+            return dbgfR3RegNmPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
+                                                   16, cchWidth, cchPrecision, fFlags);
+        case 'U':
+            return dbgfR3RegNmPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
+                                                   10, cchWidth, cchPrecision, fFlags);
+        case 'O':
+            return dbgfR3RegNmPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
+                                                   8, cchWidth, cchPrecision, fFlags);
+        case 'B':
+            return dbgfR3RegNmPrintfCbFormatNormal(pThis, pfnOutput, pvArgOutput, pLookupRec,
+                                                   2, cchWidth, cchPrecision, fFlags);
+        case 'F':
+            return dbgfR3RegNmPrintfCbFormatField(pThis, pfnOutput, pvArgOutput, pLookupRec, cchWidth, cchPrecision, fFlags);
+        default:
+            AssertFailed();
+            return 0;
+    }
+}
+
 
 
