Changeset 48898 in vbox
- Timestamp:
- Oct 4, 2013 8:01:01 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
include/VBox/vmm/dbgf.h (modified) (3 diffs)
-
src/VBox/Debugger/DBGCCmdHlp.cpp (modified) (2 diffs)
-
src/VBox/Debugger/DBGCEmulateCodeView.cpp (modified) (5 diffs)
-
src/VBox/VMM/VMMR3/DBGFReg.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/dbgf.h
r48694 r48898 1286 1286 typedef union DBGFREGVAL 1287 1287 { 1288 uint64_t au64[2]; /**< The 64-bit array view. First because of the initializer. */ 1289 uint32_t au32[4]; /**< The 32-bit array view. */ 1290 uint16_t au16[8]; /**< The 16-bit array view. */ 1291 uint8_t au8[16]; /**< The 8-bit array view. */ 1292 1288 1293 uint8_t u8; /**< The 8-bit view. */ 1289 1294 uint16_t u16; /**< The 16-bit view. */ … … 1302 1307 } dtr; 1303 1308 1304 uint8_t au8[16]; /**< The 8-bit array view. */1305 uint16_t au16[8]; /**< The 16-bit array view. */1306 uint32_t au32[4]; /**< The 32-bit array view. */1307 uint64_t au64[2]; /**< The 64-bit array view. */1308 1309 RTUINT128U u; 1309 1310 } DBGFREGVAL; … … 1312 1313 /** Pointer to a const generic register value type. */ 1313 1314 typedef DBGFREGVAL const *PCDBGFREGVAL; 1315 1316 /** Initialize a DBGFREGVAL variable to all zeros. */ 1317 #define DBGFREGVAL_INITIALIZE_ZERO { { 0, 0 } } 1318 /** Initialize a DBGFREGVAL variable to all bits set . */ 1319 #define DBGFREGVAL_INITIALIZE_FFFF { { UINT64_MAX, UINT64_MAX } } 1320 1314 1321 1315 1322 VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial); -
trunk/src/VBox/Debugger/DBGCCmdHlp.cpp
r47564 r48898 723 723 724 724 /** 725 * @copydoc DBGCCMDHLP::pfnParserError 726 */ 727 static DECLCALLBACK(int) dbgcHlpParserError(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int iArg, const char *pszExpr, unsigned iLine) 728 { 729 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); 730 731 /* 732 * Do the formatting and output. 733 */ 734 pDbgc->rcOutput = VINF_SUCCESS; 735 RTStrFormat(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, "%s: parser error: iArg=%d iLine=%u pszExpr=%s\n", 736 pCmd->pszCmd, iArg, iLine, pszExpr); 737 if (RT_FAILURE(pDbgc->rcOutput)) 738 return pDbgc->rcOutput; 739 return VERR_DBGC_COMMAND_FAILED; 740 } 741 742 743 /** 725 744 * @interface_method_impl{DBGCCMDHLP,pfnVarToDbgfAddr} 726 745 */ … … 1345 1364 pDbgc->CmdHlp.pfnFailV = dbgcHlpFailV; 1346 1365 pDbgc->CmdHlp.pfnFailRcV = dbgcHlpFailRcV; 1366 pDbgc->CmdHlp.pfnParserError = dbgcHlpParserError; 1347 1367 pDbgc->CmdHlp.pfnVarToDbgfAddr = dbgcHlpVarToDbgfAddr; 1348 1368 pDbgc->CmdHlp.pfnVarFromDbgfAddr = dbgcHlpVarFromDbgfAddr; -
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r48017 r48898 248 248 /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */ 249 249 { 0, 1, DBGCVAR_CAT_SYMBOL, 0, "register", "Register to show or set." }, 250 { 0, 1, DBGCVAR_CAT_NUMBER_NO_RANGE, DBGCVD_FLAGS_DEP_PREV, "value", "New register value." }, 250 { 0, 1, DBGCVAR_CAT_STRING, DBGCVD_FLAGS_DEP_PREV, "=", "Equal sign." }, 251 { 0, 1, DBGCVAR_CAT_NUMBER, DBGCVD_FLAGS_DEP_PREV, "value", "New register value." }, 251 252 }; 252 253 … … 348 349 { "ls", 0, 1, &g_aArgListSource[0],RT_ELEMENTS(g_aArgListSource), 0, dbgcCmdListSource, "[addr]", "Source." }, 349 350 { "m", 1, 1, &g_aArgMemoryInfo[0],RT_ELEMENTS(g_aArgMemoryInfo), 0, dbgcCmdMemoryInfo, "<addr>", "Display information about that piece of memory." }, 350 { "r", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdReg, "[reg [newval]]","Show or set register(s) - active reg set." },351 { "rg", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdRegGuest, "[reg [newval]]","Show or set register(s) - guest reg set." },351 { "r", 0, 3, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdReg, "[reg [[=] newval]]", "Show or set register(s) - active reg set." }, 352 { "rg", 0, 3, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdRegGuest, "[reg [[=] newval]]", "Show or set register(s) - guest reg set." }, 352 353 { "rg32", 0, 0, NULL, 0, 0, dbgcCmdRegGuest, "", "Show 32-bit guest registers." }, 353 354 { "rg64", 0, 0, NULL, 0, 0, dbgcCmdRegGuest, "", "Show 64-bit guest registers." }, 354 { "rh", 0, 2, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdRegHyper, "[reg [newval]]","Show or set register(s) - hypervisor reg set." },355 { "rh", 0, 3, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdRegHyper, "[reg [[=] newval]]", "Show or set register(s) - hypervisor reg set." }, 355 356 { "rt", 0, 0, NULL, 0, 0, dbgcCmdRegTerse, "", "Toggles terse / verbose register info." }, 356 357 { "s", 0, ~0U, &g_aArgSearchMem[0], RT_ELEMENTS(g_aArgSearchMem), 0, dbgcCmdSearchMem, "[options] <range> <pattern>", "Continue last search." }, … … 1331 1332 { 1332 1333 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); 1333 Assert(cArgs == 1 || cArgs == 2); /* cArgs == 0 is handled by the caller */ 1334 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, cArgs == 1 || cArgs == 2); 1334 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, cArgs == 1 || cArgs == 2 || cArgs == 3); 1335 1335 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, paArgs[0].enmType == DBGCVAR_TYPE_STRING 1336 1336 || paArgs[0].enmType == DBGCVAR_TYPE_SYMBOL); … … 1378 1378 rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegFormatValue failed: %Rrc.\n", rc); 1379 1379 } 1380 else if (cArgs == 2) 1381 { 1380 else 1381 { 1382 DBGCVAR NewValueTmp; 1383 PCDBGCVAR pNewValue; 1384 if (cArgs == 3) 1385 { 1386 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, paArgs[1].enmType == DBGCVAR_TYPE_STRING); 1387 if (strcmp(paArgs[1].u.pszString, "=")) 1388 return DBGCCmdHlpFail(pCmdHlp, pCmd, "Second argument must be '='."); 1389 pNewValue = &paArgs[2]; 1390 } 1391 else 1392 { 1393 /* Not possible to convince the parser to support both codeview and 1394 windbg syntax and make the equal sign optional. Try help it. */ 1395 /** @todo make DBGCCmdHlpConvert do more with strings. */ 1396 rc = DBGCCmdHlpConvert(pCmdHlp, &paArgs[1], DBGCVAR_TYPE_NUMBER, true /*fConvSyms*/, &NewValueTmp); 1397 if (RT_FAILURE(rc)) 1398 return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "The last argument must be a value or valid symbol."); 1399 pNewValue = &NewValueTmp; 1400 } 1401 1382 1402 /* 1383 1403 * Modify the register. 1384 1404 */ 1385 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, paArgs[1].enmType == DBGCVAR_TYPE_STRING 1386 || paArgs[1].enmType == DBGCVAR_TYPE_SYMBOL); 1405 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 1, pNewValue->enmType == DBGCVAR_TYPE_NUMBER); 1387 1406 if (enmType != DBGFREGVALTYPE_DTR) 1388 1407 { 1389 1408 enmType = DBGFREGVALTYPE_U64; 1390 rc = DBGCCmdHlpVarToNumber(pCmdHlp, &paArgs[1], &Value.u64);1409 rc = DBGCCmdHlpVarToNumber(pCmdHlp, pNewValue, &Value.u64); 1391 1410 } 1392 1411 else 1393 1412 { 1394 1413 enmType = DBGFREGVALTYPE_DTR; 1395 rc = DBGCCmdHlpVarToNumber(pCmdHlp, &paArgs[1], &Value.dtr.u64Base);1396 if (RT_SUCCESS(rc) && p aArgs[1].enmRangeType != DBGCVAR_RANGE_NONE)1397 Value.dtr.u32Limit = (uint32_t)p aArgs[1].u64Range;1414 rc = DBGCCmdHlpVarToNumber(pCmdHlp, pNewValue, &Value.dtr.u64Base); 1415 if (RT_SUCCESS(rc) && pNewValue->enmRangeType != DBGCVAR_RANGE_NONE) 1416 Value.dtr.u32Limit = (uint32_t)pNewValue->u64Range; 1398 1417 } 1399 1418 if (RT_SUCCESS(rc)) … … 1406 1425 else 1407 1426 rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegFormatValue failed: %Rrc.\n", rc); 1408 }1409 else1410 {1411 NOREF(pCmd); NOREF(paArgs);1412 rc = DBGCCmdHlpPrintf(pCmdHlp, "Huh? cArgs=%d Expected 0, 1 or 2!\n", cArgs);1413 1427 } 1414 1428 return rc; -
trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp
r46155 r48898 1901 1901 1902 1902 1903 /** 1904 * On CPU worker for the register modifications, used by DBGFR3RegNmSet. 1905 * 1906 * @returns VBox status code. 1907 * 1908 * @param pUVM The user mode VM handle. 1909 * @param pLookupRec The register lookup record. Maybe be modified, 1910 * so please pass a copy of the user's one. 1911 * @param pValue The new register value. 1912 * @param enmType The register value type. 1913 */ 1914 static DECLCALLBACK(int) dbgfR3RegNmSetWorkerOnCpu(PUVM pUVM, PDBGFREGLOOKUP pLookupRec, 1915 PCDBGFREGVAL pValue, PCDBGFREGVAL pMask) 1916 { 1917 PCDBGFREGSUBFIELD pSubField = pLookupRec->pSubField; 1918 if (pSubField && pSubField->pfnSet) 1919 return pSubField->pfnSet(pLookupRec->pSet->uUserArg.pv, pSubField, pValue->u128, pMask->u128); 1920 return pLookupRec->pDesc->pfnSet(pLookupRec->pSet->uUserArg.pv, pLookupRec->pDesc, pValue, pMask); 1921 } 1922 1923 1924 /** 1925 * Worker for the register setting. 1926 * 1927 * @returns VBox status code. 1928 * @retval VINF_SUCCESS 1929 * @retval VERR_INVALID_VM_HANDLE 1930 * @retval VERR_INVALID_CPU_ID 1931 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1932 * @retval VERR_DBGF_UNSUPPORTED_CAST 1933 * @retval VINF_DBGF_TRUNCATED_REGISTER 1934 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 1935 * 1936 * @param pUVM The user mode VM handle. 1937 * @param idDefCpu The virtual CPU ID for the default CPU register 1938 * set. Can be OR'ed with DBGFREG_HYPER_VMCPUID. 1939 * @param pszReg The register to query. 1940 * @param pValue The value to set 1941 * @param enmType How to interpret the value in @a pValue. 1942 */ 1903 1943 VMMR3DECL(int) DBGFR3RegNmSet(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType) 1904 1944 { 1905 NOREF(pUVM); NOREF(idDefCpu); NOREF(pszReg); NOREF(pValue); NOREF(enmType); 1906 return VERR_NOT_IMPLEMENTED; 1945 /* 1946 * Validate input. 1947 */ 1948 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 1949 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, VERR_INVALID_VM_HANDLE); 1950 AssertReturn((idDefCpu & ~DBGFREG_HYPER_VMCPUID) < pUVM->cCpus || idDefCpu == VMCPUID_ANY, VERR_INVALID_CPU_ID); 1951 AssertPtrReturn(pszReg, VERR_INVALID_POINTER); 1952 AssertReturn(enmType > DBGFREGVALTYPE_INVALID && enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER); 1953 AssertPtrReturn(pValue, VERR_INVALID_PARAMETER); 1954 1955 /* 1956 * Resolve the register and check that it is writable. 1957 */ 1958 bool fGuestRegs = true; 1959 if ((idDefCpu & DBGFREG_HYPER_VMCPUID) && idDefCpu != VMCPUID_ANY) 1960 { 1961 fGuestRegs = false; 1962 idDefCpu &= ~DBGFREG_HYPER_VMCPUID; 1963 } 1964 PCDBGFREGLOOKUP pLookupRec = dbgfR3RegResolve(pUVM, idDefCpu, pszReg, fGuestRegs); 1965 if (pLookupRec) 1966 { 1967 PCDBGFREGDESC pDesc = pLookupRec->pDesc; 1968 PCDBGFREGSET pSet = pLookupRec->pSet; 1969 PCDBGFREGSUBFIELD pSubField = pLookupRec->pSubField; 1970 1971 if ( !(pDesc->fFlags & DBGFREG_FLAGS_READ_ONLY) 1972 && (pSubField 1973 ? !(pSubField->fFlags & DBGFREGSUBFIELD_FLAGS_READ_ONLY) 1974 && (pSubField->pfnSet != NULL || pDesc->pfnSet != NULL) 1975 : pDesc->pfnSet != NULL) ) 1976 { 1977 /* 1978 * Calculate the modification mask and cast the input value to the 1979 * type of the target register. 1980 */ 1981 DBGFREGVAL Mask = DBGFREGVAL_INITIALIZE_ZERO; 1982 DBGFREGVAL Value = DBGFREGVAL_INITIALIZE_ZERO; 1983 switch (enmType) 1984 { 1985 case DBGFREGVALTYPE_U8: 1986 Value.u8 = pValue->u8; 1987 Mask.u8 = UINT8_MAX; 1988 break; 1989 case DBGFREGVALTYPE_U16: 1990 Value.u16 = pValue->u16; 1991 Mask.u16 = UINT16_MAX; 1992 break; 1993 case DBGFREGVALTYPE_U32: 1994 Value.u32 = pValue->u32; 1995 Mask.u32 = UINT32_MAX; 1996 break; 1997 case DBGFREGVALTYPE_U64: 1998 Value.u64 = pValue->u64; 1999 Mask.u64 = UINT64_MAX; 2000 break; 2001 case DBGFREGVALTYPE_U128: 2002 Value.u128 = pValue->u128; 2003 Mask.u128.s.Lo = UINT64_MAX; 2004 Mask.u128.s.Hi = UINT64_MAX; 2005 break; 2006 case DBGFREGVALTYPE_R80: 2007 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE 2008 Value.r80Ex.lrd = pValue->r80Ex.lrd; 2009 #else 2010 Value.r80Ex.au64[0] = pValue->r80Ex.au64[0]; 2011 Value.r80Ex.au16[4] = pValue->r80Ex.au16[4]; 2012 #endif 2013 Value.r80Ex.au64[0] = UINT64_MAX; 2014 Value.r80Ex.au16[4] = UINT16_MAX; 2015 break; 2016 case DBGFREGVALTYPE_DTR: 2017 Value.dtr.u32Limit = pValue->dtr.u32Limit; 2018 Value.dtr.u64Base = pValue->dtr.u64Base; 2019 Mask.dtr.u32Limit = UINT32_MAX; 2020 Mask.dtr.u64Base = UINT64_MAX; 2021 break; 2022 case DBGFREGVALTYPE_32BIT_HACK: 2023 case DBGFREGVALTYPE_END: 2024 case DBGFREGVALTYPE_INVALID: 2025 AssertFailedReturn(VERR_INTERNAL_ERROR_3); 2026 } 2027 2028 int rc = VINF_SUCCESS; 2029 DBGFREGVALTYPE enmRegType = pDesc->enmType; 2030 if (pSubField) 2031 { 2032 unsigned const cBits = pSubField->cBits + pSubField->cShift; 2033 if (cBits <= 8) 2034 enmRegType = DBGFREGVALTYPE_U8; 2035 else if (cBits <= 16) 2036 enmRegType = DBGFREGVALTYPE_U16; 2037 else if (cBits <= 32) 2038 enmRegType = DBGFREGVALTYPE_U32; 2039 else if (cBits <= 64) 2040 enmRegType = DBGFREGVALTYPE_U64; 2041 else 2042 enmRegType = DBGFREGVALTYPE_U128; 2043 } 2044 else if (pLookupRec->pAlias) 2045 { 2046 /* Restrict the input to the size of the alias register. */ 2047 DBGFREGVALTYPE enmAliasType = pLookupRec->pAlias->enmType; 2048 if (enmAliasType != enmType) 2049 { 2050 rc = dbgfR3RegValCast(&Value, enmType, enmAliasType); 2051 if (RT_FAILURE(rc)) 2052 return rc; 2053 dbgfR3RegValCast(&Mask, enmType, enmAliasType); 2054 enmType = enmAliasType; 2055 } 2056 } 2057 2058 if (enmType != enmRegType) 2059 { 2060 int rc2 = dbgfR3RegValCast(&Value, enmType, enmRegType); 2061 if (RT_FAILURE(rc2)) 2062 return rc2; 2063 if (rc2 != VINF_SUCCESS && rc == VINF_SUCCESS) 2064 rc2 = VINF_SUCCESS; 2065 dbgfR3RegValCast(&Mask, enmType, enmRegType); 2066 } 2067 2068 /* 2069 * Subfields needs some extra processing if there is no subfield 2070 * setter, since we'll be feeding it to the normal register setter 2071 * instead. The mask and value must be shifted and truncated to the 2072 * subfield position. 2073 */ 2074 if (pSubField && !pSubField->pfnSet) 2075 { 2076 /* The shift factor is for displaying a subfield value 2077 2**cShift times larger than the stored value. We have 2078 to undo this before adjusting value and mask. */ 2079 if (pSubField->cShift) 2080 { 2081 /* Warn about trunction of the lower bits that get 2082 shifted out below. */ 2083 if (rc == VINF_SUCCESS) 2084 { 2085 DBGFREGVAL Value2 = Value; 2086 RTUInt128AssignAndNFirstBits(&Value2.u128, -pSubField->cShift); 2087 if (!RTUInt128BitAreAllClear(&Value2.u128)) 2088 rc = VINF_DBGF_TRUNCATED_REGISTER; 2089 } 2090 RTUInt128AssignShiftRight(&Value.u128, pSubField->cShift); 2091 } 2092 2093 DBGFREGVAL Value3 = Value; 2094 RTUInt128AssignAndNFirstBits(&Value.u128, pSubField->cBits); 2095 if (rc == VINF_SUCCESS && RTUInt128IsNotEqual(&Value.u128, &Value.u128)) 2096 rc = VINF_DBGF_TRUNCATED_REGISTER; 2097 RTUInt128AssignAndNFirstBits(&Mask.u128, pSubField->cBits); 2098 2099 RTUInt128AssignShiftLeft(&Value.u128, pSubField->iFirstBit); 2100 RTUInt128AssignShiftLeft(&Mask.u128, pSubField->iFirstBit); 2101 } 2102 2103 /* 2104 * Do the actual work on an EMT. 2105 */ 2106 if (pSet->enmType == DBGFREGSETTYPE_CPU) 2107 idDefCpu = pSet->uUserArg.pVCpu->idCpu; 2108 else if (idDefCpu != VMCPUID_ANY) 2109 idDefCpu &= ~DBGFREG_HYPER_VMCPUID; 2110 2111 int rc2 = VMR3ReqPriorityCallWaitU(pUVM, idDefCpu, (PFNRT)dbgfR3RegNmSetWorkerOnCpu, 4, 2112 pUVM, pLookupRec, &Value, &Mask); 2113 2114 if (rc == VINF_SUCCESS || RT_FAILURE(rc2)) 2115 rc = rc2; 2116 return rc; 2117 } 2118 return VERR_DBGF_READ_ONLY_REGISTER; 2119 } 2120 return VERR_DBGF_REGISTER_NOT_FOUND; 1907 2121 } 1908 2122
Note:
See TracChangeset
for help on using the changeset viewer.

