diff options
Diffstat (limited to 'src/VBox/Runtime/common/string/strformatrt.cpp')
-rw-r--r-- | src/VBox/Runtime/common/string/strformatrt.cpp | 140 |
1 files changed, 133 insertions, 7 deletions
diff --git a/src/VBox/Runtime/common/string/strformatrt.cpp b/src/VBox/Runtime/common/string/strformatrt.cpp index b37710bbc..d2409c457 100644 --- a/src/VBox/Runtime/common/string/strformatrt.cpp +++ b/src/VBox/Runtime/common/string/strformatrt.cpp @@ -1,4 +1,4 @@ -/* $Id: strformatrt.cpp $ */ +/* $Id: strformatrt.cpp 37996 2011-07-18 10:09:19Z vboxsync $ */ /** @file * IPRT - IPRT String Formatter Extensions. */ @@ -30,6 +30,8 @@ *******************************************************************************/ #define LOG_GROUP RTLOGGROUP_STRING #include <iprt/string.h> +#define RT_NO_EXPORT_SYMBOL /* don't slurp <linux/module.h> which then again + slurps arch-specific headers defining symbols */ #include "internal/iprt.h" #include <iprt/log.h> @@ -44,6 +46,10 @@ #include <iprt/time.h> #include <iprt/net.h> #include <iprt/path.h> +#define STRFORMAT_WITH_X86 +#ifdef STRFORMAT_WITH_X86 +# include <iprt/x86.h> +#endif #include "internal/string.h" @@ -63,10 +69,14 @@ * @param fFlags Flags (RTSTR_NTFS_*). * @param chArgSize The argument size specifier, 'l' or 'L'. */ -size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize) +DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, + int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize) { const char *pszFormatOrg = *ppszFormat; - char ch = *(*ppszFormat)++; + char ch = *(*ppszFormat)++; + size_t cch; + char szBuf[80]; + if (ch == 'R') { ch = *(*ppszFormat)++; @@ -204,8 +214,6 @@ size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **p PCRTNETADDR pNetAddr; PCRTUUID pUuid; } u; - char szBuf[80]; - unsigned cch; AssertMsg(!chArgSize, ("Not argument size '%c' for RT types! '%.10s'\n", chArgSize, pszFormatOrg)); @@ -644,8 +652,8 @@ size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **p */ case 'd': { - size_t cch = 0; int off = 0; + cch = 0; if (cchWidth <= 0) cchWidth = 16; @@ -682,7 +690,7 @@ size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **p { if (cchPrecision-- > 0) { - size_t cch = RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%02x", *pu8++); + cch = RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%02x", *pu8++); for (; cchPrecision > 0; cchPrecision--, pu8++) cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, " %02x", *pu8); return cch; @@ -984,6 +992,124 @@ size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **p } #endif /* IN_RING3 */ + + /* + * Groups 6 - CPU Architecture Register Formatters. + * "%RAarch[reg]" + */ + case 'A': + { + char const * const pszArch = *ppszFormat; + const char *pszReg = pszArch; + size_t cchOutput = 0; + int cPrinted = 0; + size_t cchReg; + + /* Parse out the */ + while ((ch = *pszReg++) && ch != '[') + { /* nothing */ } + AssertMsgBreak(ch == '[', ("Malformed IPRT architecture register format type '%.10s'!\n", pszFormatOrg)); + + cchReg = 0; + while ((ch = pszReg[cchReg]) && ch != ']') + cchReg++; + AssertMsgBreak(ch == ']', ("Malformed IPRT architecture register format type '%.10s'!\n", pszFormatOrg)); + + *ppszFormat = &pszReg[cchReg + 1]; + + +#define REG_EQUALS(a_szReg) (sizeof(a_szReg) - 1 == cchReg && !strncmp(a_szReg, pszReg, sizeof(a_szReg) - 1)) +#define REG_OUT_BIT(a_uVal, a_fBitMask, a_szName) \ + do { \ + if ((a_uVal) & (a_fBitMask)) \ + { \ + if (!cPrinted++) \ + cchOutput += pfnOutput(pvArgOutput, "{" a_szName, sizeof(a_szName)); \ + else \ + cchOutput += pfnOutput(pvArgOutput, "," a_szName, sizeof(a_szName)); \ + (a_uVal) &= ~(a_fBitMask); \ + } \ + } while (0) +#define REG_OUT_CLOSE(a_uVal) \ + do { \ + if ((a_uVal)) \ + { \ + cchOutput += pfnOutput(pvArgOutput, !cPrinted ? "{unkn=" : ",unkn=", 6); \ + cch = RTStrFormatNumber(&szBuf[0], (a_uVal), 16, 1, -1, fFlags); \ + cchOutput += pfnOutput(pvArgOutput, szBuf, cch); \ + cPrinted++; \ + } \ + if (cPrinted) \ + cchOutput += pfnOutput(pvArgOutput, "}", 1); \ + } while (0) + + + if (0) + { /* dummy */ } +#ifdef STRFORMAT_WITH_X86 + /* + * X86 & AMD64. + */ + else if ( pszReg - pszArch == 3 + 1 + && pszArch[0] == 'x' + && pszArch[1] == '8' + && pszArch[2] == '6') + { + if (REG_EQUALS("cr0")) + { + uint64_t cr0 = va_arg(*pArgs, uint64_t); + fFlags |= RTSTR_F_64BIT; + cch = RTStrFormatNumber(&szBuf[0], cr0, 16, 8, -1, fFlags | RTSTR_F_ZEROPAD); + cchOutput += pfnOutput(pvArgOutput, szBuf, cch); + REG_OUT_BIT(cr0, X86_CR0_PE, "PE"); + REG_OUT_BIT(cr0, X86_CR0_MP, "MP"); + REG_OUT_BIT(cr0, X86_CR0_EM, "EM"); + REG_OUT_BIT(cr0, X86_CR0_TS, "DE"); + REG_OUT_BIT(cr0, X86_CR0_ET, "ET"); + REG_OUT_BIT(cr0, X86_CR0_NE, "NE"); + REG_OUT_BIT(cr0, X86_CR0_WP, "WP"); + REG_OUT_BIT(cr0, X86_CR0_AM, "AM"); + REG_OUT_BIT(cr0, X86_CR0_NW, "NW"); + REG_OUT_BIT(cr0, X86_CR0_CD, "CD"); + REG_OUT_BIT(cr0, X86_CR0_PG, "PG"); + REG_OUT_CLOSE(cr0); + } + else if (REG_EQUALS("cr4")) + { + uint64_t cr4 = va_arg(*pArgs, uint64_t); + fFlags |= RTSTR_F_64BIT; + cch = RTStrFormatNumber(&szBuf[0], cr4, 16, 8, -1, fFlags | RTSTR_F_ZEROPAD); + cchOutput += pfnOutput(pvArgOutput, szBuf, cch); + REG_OUT_BIT(cr4, X86_CR4_VME, "VME"); + REG_OUT_BIT(cr4, X86_CR4_PVI, "PVI"); + REG_OUT_BIT(cr4, X86_CR4_TSD, "TSD"); + REG_OUT_BIT(cr4, X86_CR4_DE, "DE"); + REG_OUT_BIT(cr4, X86_CR4_PSE, "PSE"); + REG_OUT_BIT(cr4, X86_CR4_PAE, "PAE"); + REG_OUT_BIT(cr4, X86_CR4_MCE, "MCE"); + REG_OUT_BIT(cr4, X86_CR4_PGE, "PGE"); + REG_OUT_BIT(cr4, X86_CR4_PCE, "PCE"); + REG_OUT_BIT(cr4, X86_CR4_OSFSXR, "OSFSXR"); + REG_OUT_BIT(cr4, X86_CR4_OSXMMEEXCPT, "OSXMMEEXCPT"); + REG_OUT_BIT(cr4, X86_CR4_VMXE, "VMXE"); + REG_OUT_BIT(cr4, X86_CR4_SMXE, "SMXE"); + REG_OUT_BIT(cr4, X86_CR4_PCIDE, "PCIDE"); + REG_OUT_BIT(cr4, X86_CR4_OSXSAVE, "OSXSAVE"); + REG_OUT_BIT(cr4, X86_CR4_SMEP, "SMPE"); + REG_OUT_CLOSE(cr4); + } + else + AssertMsgFailed(("Unknown x86 register specified in '%.10s'!\n", pszFormatOrg)); + } +#endif + else + AssertMsgFailed(("Unknown architecture specified in '%.10s'!\n", pszFormatOrg)); +#undef REG_OUT_BIT +#undef REG_OUT_CLOSE +#undef REG_EQUALS + return cchOutput; + } + /* * Invalid/Unknown. Bitch about it. */ |