VirtualBox

Changeset 61680 in vbox


Ignore:
Timestamp:
Jun 13, 2016 3:02:28 PM (9 years ago)
Author:
vboxsync
Message:

VMMR3/DBGFR3Type: New API to dump type information and a guest memory buffer formatted for a given type

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/dbgf.h

    r61671 r61680  
    23142314    float            f32;
    23152315    double           f64;
     2316    uint64_t         size; /* For the built-in size_t which can be either 32-bit or 64-bit. */
    23162317    RTGCPTR          GCPtr;
    23172318    /** For embedded structs. */
     
    23282329    /** DBGF built-in type. */
    23292330    DBGFTYPEBUILTIN      enmType;
     2331    /** Size of the type. */
     2332    size_t              cbType;
    23302333    /** Number of entries, for arrays this can be > 1. */
    23312334    uint32_t             cEntries;
     
    24262429} DBGFTYPEREG;
    24272430
     2431/**
     2432 * DBGF typed value dumper callback.
     2433 *
     2434 * @returns VBox status code. Any non VINF_SUCCESS status code will abort the dumping.
     2435 *
     2436 * @param   off             The byte offset of the entry from the start of the type.
     2437 * @param   pszField        The name of the field for the value.
     2438 * @param   iLvl            The current level.
     2439 * @param   enmType         The type enum.
     2440 * @param   cbType          Size of the type.
     2441 * @param   pValBuf         Pointer to the value buffer.
     2442 * @param   cValBufs        Number of value buffers (for arrays).
     2443 * @param   pvUser          Opaque user data.
     2444 */
     2445typedef DECLCALLBACK(int) FNDBGFR3TYPEVALDUMP(uint32_t off, const char *pszField, uint32_t iLvl,
     2446                                              DBGFTYPEBUILTIN enmType, size_t cbType,
     2447                                              PDBGFTYPEVALBUF pValBuf, uint32_t cValBufs,
     2448                                              void *pvUser);
     2449/** Pointer to a FNDBGFR3TYPEVALDUMP. */
     2450typedef FNDBGFR3TYPEVALDUMP *PFNDBGFR3TYPEVALDUMP;
     2451
     2452/**
     2453 * DBGF type information dumper callback.
     2454 *
     2455 * @returns VBox status code. Any non VINF_SUCCESS status code will abort the dumping.
     2456 *
     2457 * @param   off             The byte offset of the entry from the start of the type.
     2458 * @param   pszField        The name of the field for the value.
     2459 * @param   iLvl            The current level.
     2460 * @param   pszType         The type of the field.
     2461 * @param   fTypeFlags      Flags for this type, see DBGFTYPEREGMEMBER_F_XXX.
     2462 * @param   cElements       Number of for the field ( > 0 for arrays).
     2463 * @param   pvUser          Opaque user data.
     2464 */
     2465typedef DECLCALLBACK(int) FNDBGFR3TYPEDUMP(uint32_t off, const char *pszField, uint32_t iLvl,
     2466                                           const char *pszType, uint32_t fTypeFlags,
     2467                                           uint32_t cElements, void *pvUser);
     2468/** Pointer to a FNDBGFR3TYPEDUMP. */
     2469typedef FNDBGFR3TYPEDUMP *PFNDBGFR3TYPEDUMP;
     2470
    24282471VMMR3DECL(int) DBGFR3TypeRegister(  PUVM pUVM, uint32_t cTypes, PCDBGFTYPEREG paTypes);
    24292472VMMR3DECL(int) DBGFR3TypeDeregister(PUVM pUVM, const char *pszType);
     
    24322475VMMR3DECL(int) DBGFR3TypeQuerySize( PUVM pUVM, const char *pszType, size_t *pcbType);
    24332476VMMR3DECL(int) DBGFR3TypeSetSize(   PUVM pUVM, const char *pszType, size_t cbType);
     2477VMMR3DECL(int) DBGFR3TypeDumpEx(    PUVM pUVM, const char *pszType, uint32_t fFlags,
     2478                                    uint32_t cLvlMax, PFNDBGFR3TYPEDUMP pfnDump, void *pvUser);
    24342479VMMR3DECL(int) DBGFR3TypeQueryValByType(PUVM pUVM, PCDBGFADDRESS pAddress, const char *pszType,
    24352480                                        PDBGFTYPEVAL *ppVal);
    24362481VMMR3DECL(void) DBGFR3TypeValFree(PDBGFTYPEVAL pVal);
     2482VMMR3DECL(int)  DBGFR3TypeValDumpEx(PUVM pUVM, PCDBGFADDRESS pAddress, const char *pszType, uint32_t fFlags,
     2483                                    uint32_t cLvlMax, FNDBGFR3TYPEVALDUMP pfnDump, void *pvUser);
    24372484
    24382485/** @} */
  • trunk/src/VBox/VMM/VMMR3/DBGFR3Type.cpp

    r61672 r61680  
    9494/** Pointer to a DBGF type. */
    9595typedef DBGFTYPE *PDBGFTYPE;
    96 
    9796
    9897/*********************************************************************************************************************************
     
    591590        pValEntry->Buf.pVal = pValBuf;
    592591        pValEntry->cEntries = cValBufs;
     592        pValEntry->cbType   = pTypeMember->cbType;
    593593    }
    594594
     
    657657                        cbThisParsed = pTypeMember->cbType;
    658658                        break;
     659                    case DBGFTYPEBUILTIN_SIZE:
     660                        pvVal = &pValBuf->size;
     661                        cbThisParsed = pTypeMember->cbType;
     662                        break;
    659663                    case DBGFTYPEBUILTIN_FLOAT32:
    660664                    case DBGFTYPEBUILTIN_FLOAT64:
     
    676680
    677681            pValBuf++;
     682
    678683            cbParsed += cbThisParsed;
    679684            pbBuf    += cbThisParsed;
     
    746751
    747752/**
     753 * Dumps one level of a typed value.
     754 *
     755 * @returns VBox status code.
     756 * @param   pVal                The value to dump.
     757 * @param   iLvl                The current level.
     758 * @param   cLvlMax             The maximum level.
     759 * @param   pfnDump             The dumper callback.
     760 * @param   pvUser              The opaque user data to pass to the dumper callback.
     761 */
     762static int dbgfR3TypeValDump(PDBGFTYPEVAL pVal, uint32_t iLvl, uint32_t cLvlMax,
     763                             PFNDBGFR3TYPEVALDUMP pfnDump, void *pvUser)
     764{
     765    int rc = VINF_SUCCESS;
     766    PCDBGFTYPEREG pType = pVal->pTypeReg;
     767
     768    for (uint32_t i = 0; i < pVal->cEntries && rc == VINF_SUCCESS; i++)
     769    {
     770        PCDBGFTYPEREGMEMBER pTypeMember = &pType->paMembers[i];
     771        PDBGFTYPEVALENTRY pValEntry = &pVal->aEntries[i];
     772        PDBGFTYPEVALBUF pValBuf = pValEntry->cEntries > 1 ? pValEntry->Buf.pVal : &pValEntry->Buf.Val;
     773
     774        rc = pfnDump(0 /* off */, pTypeMember->pszName, iLvl, pValEntry->enmType, pValEntry->cbType,
     775                     pValBuf, pValEntry->cEntries, pvUser);
     776        if (   rc == VINF_SUCCESS
     777            && pValEntry->enmType == DBGFTYPEBUILTIN_COMPOUND
     778            && iLvl < cLvlMax)
     779        {
     780            /* Print embedded structs. */
     781            for (uint32_t iValBuf = 0; iValBuf < pValEntry->cEntries && rc == VINF_SUCCESS; iValBuf++)
     782                rc = dbgfR3TypeValDump(pValBuf[iValBuf].pVal, iLvl + 1, cLvlMax, pfnDump, pvUser);
     783        }
     784    }
     785
     786    return rc;
     787}
     788
     789/**
     790 * Dumps one level of a type.
     791 *
     792 * @returns VBox status code.
     793 * @param   pUVM                The user mode VM handle.
     794 * @param   pVal                The value to dump.
     795 * @param   iLvl                The current level.
     796 * @param   cLvlMax             The maximum level.
     797 * @param   pfnDump             The dumper callback.
     798 * @param   pvUser              The opaque user data to pass to the dumper callback.
     799 */
     800static int dbgfR3TypeDump(PUVM pUVM, PDBGFTYPE pType, uint32_t iLvl, uint32_t cLvlMax,
     801                          PFNDBGFR3TYPEDUMP pfnDump, void *pvUser)
     802{
     803    int rc = VINF_SUCCESS;
     804    PCDBGFTYPEREG pTypeReg = pType->pReg;
     805
     806    switch (pTypeReg->enmVariant)
     807    {
     808        case DBGFTYPEVARIANT_ALIAS:
     809            rc = VERR_NOT_IMPLEMENTED;
     810            break;
     811        case DBGFTYPEVARIANT_STRUCT:
     812        case DBGFTYPEVARIANT_UNION:
     813            for (uint32_t i = 0; i < pTypeReg->cMembers && rc == VINF_SUCCESS; i++)
     814            {
     815                PCDBGFTYPEREGMEMBER pTypeMember = &pTypeReg->paMembers[i];
     816                PDBGFTYPE pTypeResolved = dbgfR3TypeLookup(pUVM, pTypeMember->pszType);
     817
     818                rc = pfnDump(0 /* off */, pTypeMember->pszName, iLvl, pTypeMember->pszType,
     819                             pTypeMember->fFlags, pTypeMember->cElements, pvUser);
     820                if (   rc == VINF_SUCCESS
     821                    && pTypeResolved->pReg
     822                    && iLvl < cLvlMax)
     823                {
     824                    /* Print embedded structs. */
     825                    rc = dbgfR3TypeDump(pUVM, pTypeResolved, iLvl + 1, cLvlMax, pfnDump, pvUser);
     826                }
     827            }
     828            break;
     829        default:
     830            AssertMsgFailed(("Invalid type variant: %u\n", pTypeReg->enmVariant));
     831            rc = VERR_INVALID_STATE;
     832    }
     833
     834    return rc;
     835}
     836
     837/**
    748838 * Initializes the type database.
    749839 *
     
    843933    AssertPtrReturn(pszType, VERR_INVALID_POINTER);
    844934
     935    int rc = VINF_SUCCESS;
     936    if (!pUVM->dbgf.s.fTypeDbInitialized)
     937    {
     938        rc = dbgfR3TypeInit(pUVM);
     939        if (RT_FAILURE(rc))
     940            return rc;
     941    }
     942
    845943    DBGF_TYPE_DB_LOCK_WRITE(pUVM);
    846     int rc = VINF_SUCCESS;
    847944    PDBGFTYPE pType = dbgfR3TypeLookup(pUVM, pszType);
    848945    if (pType)
     
    877974    AssertPtrReturn(ppTypeReg, VERR_INVALID_POINTER);
    878975
     976    int rc = VINF_SUCCESS;
     977    if (!pUVM->dbgf.s.fTypeDbInitialized)
     978    {
     979        rc = dbgfR3TypeInit(pUVM);
     980        if (RT_FAILURE(rc))
     981            return rc;
     982    }
     983
    879984    DBGF_TYPE_DB_LOCK_READ(pUVM);
    880     int rc = VINF_SUCCESS;
    881985    PDBGFTYPE pType = dbgfR3TypeLookup(pUVM, pszType);
    882986    if (pType)
     
    886990    DBGF_TYPE_DB_UNLOCK_READ(pUVM);
    887991
     992    LogFlowFunc(("-> rc=%Rrc\n", rc));
    888993    return rc;
    889994}
     
    9051010    AssertPtrReturn(pcbType, VERR_INVALID_POINTER);
    9061011
     1012    int rc = VINF_SUCCESS;
     1013    if (!pUVM->dbgf.s.fTypeDbInitialized)
     1014    {
     1015        rc = dbgfR3TypeInit(pUVM);
     1016        if (RT_FAILURE(rc))
     1017            return rc;
     1018    }
     1019
    9071020    DBGF_TYPE_DB_LOCK_READ(pUVM);
    908     int rc = VINF_SUCCESS;
    9091021    PDBGFTYPE pType = dbgfR3TypeLookup(pUVM, pszType);
    9101022    if (pType)
     
    9141026    DBGF_TYPE_DB_UNLOCK_READ(pUVM);
    9151027
     1028    LogFlowFunc(("-> rc=%Rrc\n", rc));
    9161029    return rc;
    9171030}
     
    9371050    AssertReturn(cbType > 0, VERR_INVALID_PARAMETER);
    9381051
     1052    int rc = VINF_SUCCESS;
     1053    if (!pUVM->dbgf.s.fTypeDbInitialized)
     1054    {
     1055        rc = dbgfR3TypeInit(pUVM);
     1056        if (RT_FAILURE(rc))
     1057            return rc;
     1058    }
     1059
    9391060    DBGF_TYPE_DB_LOCK_WRITE(pUVM);
    940     int rc = VINF_SUCCESS;
    9411061    PDBGFTYPE pType = dbgfR3TypeLookup(pUVM, pszType);
    9421062    if (pType)
     
    9591079    DBGF_TYPE_DB_UNLOCK_WRITE(pUVM);
    9601080
     1081    LogFlowFunc(("-> rc=%Rrc\n", rc));
     1082    return rc;
     1083}
     1084
     1085/**
     1086 * Dumps the type information of the given type.
     1087 *
     1088 * @returns VBox status code.
     1089 * @param   pUVM                The user mode VM handle.
     1090 * @param   pszType             The type identifier.
     1091 * @param   fFlags              Flags to control the dumping (reserved, MBZ).
     1092 * @param   cLvlMax             Maximum levels to nest.
     1093 * @param   pfnDump             The dumper callback.
     1094 * @param   pvUser              Opaque user data.
     1095 */
     1096VMMR3DECL(int) DBGFR3TypeDumpEx(PUVM pUVM, const char *pszType, uint32_t fFlags,
     1097                                uint32_t cLvlMax, PFNDBGFR3TYPEDUMP pfnDump, void *pvUser)
     1098{
     1099    LogFlowFunc(("pUVM=%#p pszType=%s fFlags=%#x cLvlMax=%u pfnDump=%#p pvUser=%#p\n",
     1100                 pUVM, pszType, fFlags, cLvlMax, pfnDump, pvUser));
     1101    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
     1102    AssertPtrReturn(pszType, VERR_INVALID_POINTER);
     1103    AssertPtrReturn(pfnDump, VERR_INVALID_POINTER);
     1104
     1105    int rc = VINF_SUCCESS;
     1106    if (!pUVM->dbgf.s.fTypeDbInitialized)
     1107    {
     1108        rc = dbgfR3TypeInit(pUVM);
     1109        if (RT_FAILURE(rc))
     1110            return rc;
     1111    }
     1112
     1113    DBGF_TYPE_DB_LOCK_READ(pUVM);
     1114    PDBGFTYPE pType = dbgfR3TypeLookup(pUVM, pszType);
     1115    if (pType)
     1116        rc = dbgfR3TypeDump(pUVM, pType, 0 /* iLvl */, cLvlMax, pfnDump, pvUser);
     1117    else
     1118        rc = VERR_NOT_FOUND;
     1119    DBGF_TYPE_DB_UNLOCK_READ(pUVM);
     1120
     1121    LogFlowFunc(("-> rc=%Rrc\n", rc));
    9611122    return rc;
    9621123}
     
    9831144    AssertPtrReturn(ppVal, VERR_INVALID_POINTER);
    9841145
     1146    int rc = VINF_SUCCESS;
     1147    if (!pUVM->dbgf.s.fTypeDbInitialized)
     1148    {
     1149        rc = dbgfR3TypeInit(pUVM);
     1150        if (RT_FAILURE(rc))
     1151            return rc;
     1152    }
     1153
    9851154    DBGF_TYPE_DB_LOCK_READ(pUVM);
    986     int rc = VINF_SUCCESS;
    9871155    PDBGFTYPE pType = dbgfR3TypeLookup(pUVM, pszType);
    9881156    if (pType)
     
    10091177    DBGF_TYPE_DB_UNLOCK_READ(pUVM);
    10101178
     1179    LogFlowFunc(("-> rc=%Rrc\n", rc));
    10111180    return rc;
    10121181}
     
    10391208}
    10401209
     1210/**
     1211 * Reads the guest memory with the given type and dumps the content of the type.
     1212 *
     1213 * @returns VBox status code.
     1214 * @param   pUVM                The user mode VM handle.
     1215 * @param   pAddress            The address to start reading from.
     1216 * @param   pszType             The type identifier.
     1217 * @param   fFlags              Flags for tweaking (reserved, must be zero).
     1218 * @param   cLvlMax             Maximum number of levels to expand embedded structs.
     1219 * @param   pfnDump             The dumper callback.
     1220 * @param   pvUser              The opaque user data to pass to the callback.
     1221 */
     1222VMMR3DECL(int) DBGFR3TypeValDumpEx(PUVM pUVM, PCDBGFADDRESS pAddress, const char *pszType, uint32_t fFlags,
     1223                                   uint32_t cLvlMax, FNDBGFR3TYPEVALDUMP pfnDump, void *pvUser)
     1224{
     1225    LogFlowFunc(("pUVM=%#p pAddress=%#p pszType=%s fFlags=%#x pfnDump=%#p pvUser=%#p\n",
     1226                 pUVM, pAddress, pszType, fFlags,pfnDump, pvUser));
     1227    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
     1228    AssertPtrReturn(pAddress, VERR_INVALID_POINTER);
     1229    AssertPtrReturn(pszType, VERR_INVALID_POINTER);
     1230    AssertPtrReturn(pfnDump, VERR_INVALID_POINTER);
     1231    AssertReturn(!fFlags, VERR_INVALID_PARAMETER);
     1232    AssertReturn(cLvlMax >= 1, VERR_INVALID_PARAMETER);
     1233
     1234    PDBGFTYPEVAL pVal = NULL;
     1235    int rc = DBGFR3TypeQueryValByType(pUVM, pAddress, pszType, &pVal);
     1236    if (RT_SUCCESS(rc))
     1237    {
     1238        rc = dbgfR3TypeValDump(pVal, 0 /* iLvl */, cLvlMax, pfnDump, pvUser);
     1239        DBGFR3TypeValFree(pVal);
     1240    }
     1241
     1242    LogFlowFunc(("-> rc=%Rrc\n", rc));
     1243    return rc;
     1244}
     1245
  • trunk/src/VBox/VMM/VMMR3/VMMR3.def

    r61562 r61680  
    137137    DBGFR3StackWalkNext
    138138    DBGFR3StackWalkEnd
     139    DBGFR3TypeDeregister
     140    DBGFR3TypeDumpEx
     141    DBGFR3TypeQueryReg
     142    DBGFR3TypeQuerySize
     143    DBGFR3TypeQueryValByType
     144    DBGFR3TypeRegister
     145    DBGFR3TypeSetSize
     146    DBGFR3TypeValFree
     147    DBGFR3TypeValDumpEx
    139148
    140149    EMR3QueryExecutionPolicy
     
    308317    TMR3TimerLoad
    309318    TMR3TimerSave
     319    TMR3TimerSkip
    310320    TMR3TimerDestroy
    311321    TMTimerFromMicro
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