Changeset 102092 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Nov 14, 2023 11:53:15 PM (16 months ago)
- svn:sync-xref-src-repo-rev:
- 160209
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp
r99070 r102092 386 386 else 387 387 RTStrPrintf(pRegSet->szPrefix, cchPrefix + 4 + 1, "%s%u", pszPrefix, iInstance); 388 389 388 390 389 /* … … 478 477 if (enmType == DBGFREGSETTYPE_CPU) 479 478 { 480 if (pRegSet->cDescs > DBGFREG_ALL_COUNT)481 pUVM->dbgf.s.cRegs -= pRegSet->cDescs - DBGFREG_ALL_COUNT;482 479 if (!strcmp(pszPrefix, "cpu")) 480 { 481 if (!pUVM->dbgf.s.cPerCpuRegs) 482 pUVM->dbgf.s.cPerCpuRegs = pRegSet->cDescs; 483 else 484 AssertLogRelMsgStmt(pUVM->dbgf.s.cPerCpuRegs == pRegSet->cDescs, 485 ("%d vs %d\n", pUVM->dbgf.s.cPerCpuRegs, pRegSet->cDescs), 486 pUVM->dbgf.s.cPerCpuRegs = RT_MAX(pRegSet->cDescs, pUVM->dbgf.s.cPerCpuRegs)); 483 487 pUVM->aCpus[iInstance].dbgf.s.pGuestRegSet = pRegSet; 488 } 484 489 else 490 { 491 Assert(!strcmp(pszPrefix, "hypercpu")); 492 if (!pUVM->dbgf.s.cPerCpuHyperRegs) 493 pUVM->dbgf.s.cPerCpuHyperRegs = pRegSet->cDescs; 494 else 495 AssertLogRelMsgStmt(pUVM->dbgf.s.cPerCpuHyperRegs == pRegSet->cDescs, 496 ("%d vs %d\n", pUVM->dbgf.s.cPerCpuHyperRegs, pRegSet->cDescs), 497 pUVM->dbgf.s.cPerCpuHyperRegs = RT_MAX(pRegSet->cDescs, pUVM->dbgf.s.cPerCpuHyperRegs)); 485 498 pUVM->aCpus[iInstance].dbgf.s.pHyperRegSet = pRegSet; 499 } 486 500 } 487 501 … … 533 547 } 534 548 535 return dbgfR3RegRegisterCommon(pUVM, paRegisters, DBGFREGSETTYPE_CPU, pVCpu,536 549 AssertReturn(fGuestRegs, VERR_RAW_MODE_NOT_SUPPORTED); 550 return dbgfR3RegRegisterCommon(pUVM, paRegisters, DBGFREGSETTYPE_CPU, pVCpu, fGuestRegs ? "cpu" : "hypercpu", pVCpu->idCpu); 537 551 } 538 552 … … 1844 1858 1845 1859 1860 /** 1861 * Gets the number of bits in value of type @a enmValType. 1862 */ 1863 static unsigned dbgfR3RegGetBitsForValType(DBGFREGVALTYPE enmValType) 1864 { 1865 switch (enmValType) 1866 { 1867 case DBGFREGVALTYPE_U8: return 8; 1868 case DBGFREGVALTYPE_U16: return 16; 1869 case DBGFREGVALTYPE_U32: return 32; 1870 case DBGFREGVALTYPE_U64: return 64; 1871 case DBGFREGVALTYPE_U128: return 128; 1872 case DBGFREGVALTYPE_U256: return 256; 1873 case DBGFREGVALTYPE_U512: return 512; 1874 case DBGFREGVALTYPE_R80: return 80; 1875 case DBGFREGVALTYPE_DTR: return 80; 1876 /* no default, want gcc warnings */ 1877 case DBGFREGVALTYPE_32BIT_HACK: 1878 case DBGFREGVALTYPE_END: 1879 case DBGFREGVALTYPE_INVALID: 1880 break; 1881 } 1882 return 512; 1883 } 1884 1885 1886 /** 1887 * On CPU worker for the extended register queries, used by DBGFR3RegNmQueryEx. 1888 * 1889 * @returns VBox status code. 1890 * 1891 * @param pUVM The user mode VM handle. 1892 * @param pLookupRec The register lookup record. 1893 * @param fFlags DBGFR3REG_QUERY_EX_F_XXX 1894 * @param paRegs Where to return the register values. 1895 * @param cRegs The number of register values to return. 1896 * The caller has checked that this is sufficient 1897 * to store the entire result. 1898 */ 1899 static DECLCALLBACK(int) dbgfR3RegNmQueryExWorkerOnCpu(PUVM pUVM, PCDBGFREGLOOKUP pLookupRec, uint32_t fFlags, 1900 PDBGFREGENTRYNM paRegs, size_t cRegs) 1901 { 1902 PCDBGFREGDESC pDesc = pLookupRec->pDesc; 1903 PCDBGFREGSET pSet = pLookupRec->pSet; 1904 Assert(!pLookupRec->pSubField); 1905 NOREF(pUVM); 1906 1907 /* 1908 * The register first. 1909 */ 1910 AssertReturn(cRegs > 0, VERR_BUFFER_OVERFLOW); 1911 dbgfR3RegValClear(&paRegs[0].Val); 1912 paRegs[0].pszName = pLookupRec->Core.pszString; 1913 paRegs[0].enmType = pDesc->enmType; 1914 paRegs[0].u.uInfo = 0; 1915 paRegs[0].u.s.fMain = true; 1916 int rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, &paRegs[0].Val); 1917 AssertRCReturn(rc, rc); 1918 DBGFREGVAL const MainValue = paRegs[0].Val; 1919 uint32_t iReg = 1; 1920 1921 /* If it's a alias we looked up we may have to do some casting and 1922 restricting the number of bits included in the sub-fields. */ 1923 unsigned cMaxBits = sizeof(paRegs[0].Val) * 8; 1924 if (pLookupRec->pAlias) 1925 { 1926 paRegs[0].enmType = pLookupRec->pAlias->enmType; 1927 paRegs[0].u.uInfo = 0; 1928 paRegs[0].u.s.fAlias = true; 1929 if (paRegs[0].enmType != pDesc->enmType) 1930 { 1931 dbgfR3RegValCast(&paRegs[0].Val, pDesc->enmType, paRegs[0].enmType); 1932 cMaxBits = dbgfR3RegGetBitsForValType(paRegs[0].enmType); 1933 } 1934 1935 /* Add the main value as the 2nd entry. */ 1936 paRegs[iReg].pszName = pDesc->pszName; 1937 paRegs[iReg].enmType = pDesc->enmType; 1938 paRegs[iReg].Val = MainValue; 1939 paRegs[iReg].u.uInfo = 0; 1940 paRegs[iReg].u.s.fMain = true; 1941 iReg++; 1942 } 1943 1944 /* 1945 * (Other) Aliases. 1946 */ 1947 if ( (fFlags & DBGFR3REG_QUERY_EX_F_ALIASES) 1948 && pDesc->paAliases) 1949 { 1950 PCDBGFREGALIAS const paAliases = pDesc->paAliases; 1951 for (uint32_t i = 0; paAliases[i].pszName != NULL; i++) 1952 if (&paAliases[i] != pLookupRec->pAlias ) 1953 { 1954 AssertReturn(iReg < cRegs, VERR_BUFFER_OVERFLOW); 1955 paRegs[iReg].pszName = paAliases[i].pszName; 1956 paRegs[iReg].enmType = paAliases[i].enmType; 1957 paRegs[iReg].u.uInfo = 0; 1958 paRegs[iReg].u.s.fAlias = true; 1959 paRegs[iReg].Val = MainValue; 1960 dbgfR3RegValCast(&paRegs[iReg].Val, pDesc->enmType, paAliases[i].enmType); 1961 iReg++; 1962 } 1963 } 1964 1965 /* 1966 * Subfields. 1967 */ 1968 if ( (fFlags & DBGFR3REG_QUERY_EX_F_SUBFIELDS) 1969 && pDesc->paSubFields) 1970 { 1971 PCDBGFREGSUBFIELD const paSubFields = pDesc->paSubFields; 1972 for (uint32_t i = 0; paSubFields[i].pszName != NULL; i++) 1973 if (paSubFields[i].iFirstBit < cMaxBits || paSubFields[i].pfnGet) 1974 { 1975 AssertReturn(iReg < cRegs, VERR_BUFFER_OVERFLOW); 1976 int rc2; 1977 paRegs[iReg].pszName = paSubFields[i].pszName; 1978 paRegs[iReg].u.uInfo = 0; 1979 paRegs[iReg].u.s.fSubField = true; 1980 paRegs[iReg].u.s.cBits = paSubFields[i].cBits + paSubFields[i].cShift; 1981 if (paSubFields[i].pfnGet) 1982 { 1983 dbgfR3RegValClear(&paRegs[iReg].Val); 1984 rc2 = paSubFields[i].pfnGet(pSet->uUserArg.pv, &paSubFields[i], &paRegs[iReg].Val.u128); 1985 } 1986 else 1987 { 1988 paRegs[iReg].Val = MainValue; 1989 rc2 = dbgfR3RegValCast(&paRegs[iReg].Val, pDesc->enmType, DBGFREGVALTYPE_U128); 1990 if (RT_SUCCESS(rc2)) 1991 { 1992 RTUInt128AssignShiftLeft(&paRegs[iReg].Val.u128, -paSubFields[i].iFirstBit); 1993 RTUInt128AssignAndNFirstBits(&paRegs[iReg].Val.u128, paSubFields[i].cBits); 1994 if (paSubFields[i].cShift) 1995 RTUInt128AssignShiftLeft(&paRegs[iReg].Val.u128, paSubFields[i].cShift); 1996 } 1997 } 1998 if (RT_SUCCESS(rc2)) 1999 { 2000 unsigned const cBits = paSubFields[i].cBits + paSubFields[i].cShift; 2001 if (cBits <= 8) 2002 paRegs[iReg].enmType = DBGFREGVALTYPE_U8; 2003 else if (cBits <= 16) 2004 paRegs[iReg].enmType = DBGFREGVALTYPE_U16; 2005 else if (cBits <= 32) 2006 paRegs[iReg].enmType = DBGFREGVALTYPE_U32; 2007 else if (cBits <= 64) 2008 paRegs[iReg].enmType = DBGFREGVALTYPE_U64; 2009 else 2010 paRegs[iReg].enmType = DBGFREGVALTYPE_U128; 2011 rc2 = dbgfR3RegValCast(&paRegs[iReg].Val, DBGFREGVALTYPE_U128, paRegs[iReg].enmType); 2012 } 2013 if (RT_SUCCESS(rc2)) 2014 iReg++; 2015 else 2016 rc = rc2; 2017 } 2018 } 2019 return rc; 2020 } 2021 2022 2023 /** 2024 * Queries a register with aliases and/or sub-fields. 2025 * 2026 * @retval VINF_SUCCESS 2027 * @retval VERR_INVALID_VM_HANDLE 2028 * @retval VERR_INVALID_CPU_ID 2029 * @retval VERR_BUFFER_OVERFLOW w/ *pcRegs set to the required size. 2030 * No other data returned. 2031 * @retval VERR_DBGF_REGISTER_NOT_FOUND 2032 * @retval VERR_DBGF_UNSUPPORTED_CAST 2033 * @retval VINF_DBGF_TRUNCATED_REGISTER 2034 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 2035 * 2036 * @param pUVM The user mode VM handle. 2037 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 2038 * applicable. Can be OR'ed with DBGFREG_HYPER_VMCPUID. 2039 * @param pszReg The register that's being queried. Except for CPU 2040 * registers, this must be on the form "set.reg[.sub]". 2041 * @param fFlags DBGFR3REG_QUERY_EX_F_XXX 2042 * @param paRegs 2043 * @param pcRegs On input this is the size of the paRegs buffer. 2044 * On successful return this is set to the number of 2045 * registers returned. This is set to the required number 2046 * of register entries when VERR_BUFFER_OVERFLOW is 2047 * returned. 2048 */ 2049 VMMR3DECL(int) DBGFR3RegNmQueryEx(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t fFlags, 2050 PDBGFREGENTRYNM paRegs, size_t *pcRegs) 2051 { 2052 /* 2053 * Validate input. 2054 */ 2055 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 2056 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, VERR_INVALID_VM_HANDLE); 2057 AssertReturn((idDefCpu & ~DBGFREG_HYPER_VMCPUID) < pUVM->cCpus || idDefCpu == VMCPUID_ANY, VERR_INVALID_CPU_ID); 2058 AssertPtrReturn(pszReg, VERR_INVALID_POINTER); 2059 AssertReturn(!(fFlags & ~DBGFR3REG_QUERY_EX_F_VALID_MASK), VERR_INVALID_FLAGS); 2060 AssertPtrReturn(pcRegs, VERR_INVALID_POINTER); 2061 AssertPtrNullReturn(paRegs, VERR_INVALID_POINTER); 2062 2063 /* 2064 * Resolve the register and call the getter on the relevant CPU. 2065 */ 2066 bool fGuestRegs = true; 2067 if ((idDefCpu & DBGFREG_HYPER_VMCPUID) && idDefCpu != VMCPUID_ANY) 2068 { 2069 fGuestRegs = false; 2070 idDefCpu &= ~DBGFREG_HYPER_VMCPUID; 2071 } 2072 PCDBGFREGLOOKUP pLookupRec = dbgfR3RegResolve(pUVM, idDefCpu, pszReg, fGuestRegs); 2073 if (pLookupRec) 2074 { 2075 /* 2076 * Determine how many register values we'd be returning. 2077 */ 2078 uint32_t cRegs = 1; /* we always return the direct hit. */ 2079 2080 if ( (fFlags & DBGFR3REG_QUERY_EX_F_ALIASES) 2081 && !pLookupRec->pSubField 2082 && pLookupRec->pDesc->paAliases) 2083 { 2084 PCDBGFREGALIAS const paAliases = pLookupRec->pDesc->paAliases; 2085 for (uint32_t i = 0; paAliases[i].pszName != NULL; i++) 2086 cRegs++; 2087 } 2088 else if (pLookupRec->pAlias) 2089 cRegs++; 2090 2091 if ( (fFlags & DBGFR3REG_QUERY_EX_F_SUBFIELDS) 2092 && !pLookupRec->pSubField 2093 && pLookupRec->pDesc->paSubFields) 2094 { 2095 unsigned const cMaxBits = !pLookupRec->pAlias ? sizeof(paRegs[0].Val) * 8 2096 : dbgfR3RegGetBitsForValType(pLookupRec->pAlias->enmType); 2097 PCDBGFREGSUBFIELD const paSubFields = pLookupRec->pDesc->paSubFields; 2098 for (uint32_t i = 0; paSubFields[i].pszName != NULL; i++) 2099 if (paSubFields[i].iFirstBit < cMaxBits || paSubFields[i].pfnGet) 2100 cRegs++; 2101 } 2102 2103 /* 2104 * Did the caller provide sufficient room for the register values, then 2105 * retrieve the register on the specified CPU. 2106 */ 2107 if (paRegs && *pcRegs >= cRegs) 2108 { 2109 *pcRegs = cRegs; 2110 2111 if (pLookupRec->pSet->enmType == DBGFREGSETTYPE_CPU) 2112 idDefCpu = pLookupRec->pSet->uUserArg.pVCpu->idCpu; 2113 else if (idDefCpu != VMCPUID_ANY) 2114 idDefCpu &= ~DBGFREG_HYPER_VMCPUID; 2115 2116 /* If we hit a sub-field we'll just use the regular worker to get it. */ 2117 if (!pLookupRec->pSubField) 2118 return VMR3ReqPriorityCallWaitU(pUVM, idDefCpu, (PFNRT)dbgfR3RegNmQueryExWorkerOnCpu, 5, 2119 pUVM, pLookupRec, fFlags, paRegs, cRegs); 2120 Assert(cRegs == 1); 2121 paRegs[0].pszName = pLookupRec->Core.pszString; 2122 paRegs[0].enmType = DBGFREGVALTYPE_END; 2123 paRegs[0].u.uInfo = 0; 2124 paRegs[0].u.s.cBits = pLookupRec->pSubField->cBits + pLookupRec->pSubField->cShift; 2125 paRegs[0].u.s.fSubField = true; 2126 dbgfR3RegValClear(&paRegs[0].Val); 2127 return VMR3ReqPriorityCallWaitU(pUVM, idDefCpu, (PFNRT)dbgfR3RegNmQueryWorkerOnCpu, 5, 2128 pUVM, pLookupRec, DBGFREGVALTYPE_END, &paRegs[0].Val, &paRegs[0].enmType); 2129 } 2130 *pcRegs = cRegs; 2131 return VERR_BUFFER_OVERFLOW; 2132 } 2133 return VERR_DBGF_REGISTER_NOT_FOUND; 2134 2135 } 2136 2137 1846 2138 /// @todo VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, DBGFREGENTRYNM paRegs, size_t cRegs); 1847 2139 … … 1881 2173 paRegs[iReg].pszName = NULL; 1882 2174 paRegs[iReg].enmType = DBGFREGVALTYPE_END; 2175 paRegs[iReg].u.uInfo = 0; 1883 2176 dbgfR3RegValClear(&paRegs[iReg].Val); 1884 2177 iReg++; … … 1905 2198 for (size_t iReg = 0; iReg < cRegsToQuery; iReg++) 1906 2199 { 1907 paRegs[iReg].enmType = pSet->paDescs[iReg].enmType; 1908 paRegs[iReg].pszName = pSet->paLookupRecs[iReg].Core.pszString; 2200 paRegs[iReg].enmType = pSet->paDescs[iReg].enmType; 2201 paRegs[iReg].pszName = pSet->paLookupRecs[iReg].Core.pszString; 2202 paRegs[iReg].u.uInfo = 0; 2203 paRegs[iReg].u.s.fMain = true; 1909 2204 dbgfR3RegValClear(&paRegs[iReg].Val); 1910 2205 int rc2 = pSet->paDescs[iReg].pfnGet(pSet->uUserArg.pv, &pSet->paDescs[iReg], &paRegs[iReg].Val); … … 1951 2246 * My guest CPU registers. 1952 2247 */ 1953 size_t iCpuReg = pVCpu->idCpu * DBGFREG_ALL_COUNT;2248 size_t iCpuReg = pVCpu->idCpu * pUVM->dbgf.s.cPerCpuRegs; 1954 2249 if (pUVCpu->dbgf.s.pGuestRegSet) 1955 2250 { 1956 2251 if (iCpuReg < cRegs) 1957 dbgfR3RegNmQueryAllInSet(pUVCpu->dbgf.s.pGuestRegSet, DBGFREG_ALL_COUNT, &paRegs[iCpuReg], cRegs - iCpuReg);2252 dbgfR3RegNmQueryAllInSet(pUVCpu->dbgf.s.pGuestRegSet, pUVM->dbgf.s.cPerCpuRegs, &paRegs[iCpuReg], cRegs - iCpuReg); 1958 2253 } 1959 2254 else 1960 dbgfR3RegNmQueryAllPadEntries(paRegs, cRegs, iCpuReg, DBGFREG_ALL_COUNT);2255 dbgfR3RegNmQueryAllPadEntries(paRegs, cRegs, iCpuReg, pUVM->dbgf.s.cPerCpuRegs); 1961 2256 1962 2257 /* 1963 2258 * My hypervisor CPU registers. 1964 2259 */ 1965 iCpuReg = pUVM->cCpus * DBGFREG_ALL_COUNT + pUVCpu->idCpu * DBGFREG_ALL_COUNT;2260 iCpuReg = pUVM->cCpus * pUVM->dbgf.s.cPerCpuRegs + pUVCpu->idCpu * pUVM->dbgf.s.cPerCpuHyperRegs; 1966 2261 if (pUVCpu->dbgf.s.pHyperRegSet) 1967 2262 { 1968 2263 if (iCpuReg < cRegs) 1969 dbgfR3RegNmQueryAllInSet(pUVCpu->dbgf.s.pHyperRegSet, DBGFREG_ALL_COUNT, &paRegs[iCpuReg], cRegs - iCpuReg);2264 dbgfR3RegNmQueryAllInSet(pUVCpu->dbgf.s.pHyperRegSet, pUVM->dbgf.s.cPerCpuHyperRegs, &paRegs[iCpuReg], cRegs - iCpuReg); 1970 2265 } 1971 2266 else 1972 dbgfR3RegNmQueryAllPadEntries(paRegs, cRegs, iCpuReg, DBGFREG_ALL_COUNT);2267 dbgfR3RegNmQueryAllPadEntries(paRegs, cRegs, iCpuReg, pUVM->dbgf.s.cPerCpuHyperRegs); 1973 2268 1974 2269 /* … … 1977 2272 if (pUVCpu->idCpu == 0) 1978 2273 { 1979 pArgs->iReg = pUVM->cCpus * DBGFREG_ALL_COUNT * 2;2274 pArgs->iReg = pUVM->cCpus * (pUVM->dbgf.s.cPerCpuRegs + pUVM->dbgf.s.cPerCpuHyperRegs); 1980 2275 RTStrSpaceEnumerate(&pUVM->dbgf.s.RegSetSpace, dbgfR3RegNmQueryAllEnum, pArgs); 1981 2276 dbgfR3RegNmQueryAllPadEntries(paRegs, cRegs, pArgs->iReg, cRegs); -
trunk/src/VBox/VMM/VMMR3/VMMR3.def
r100184 r102092 145 145 DBGFR3RegFormatValue 146 146 DBGFR3RegNmQuery 147 DBGFR3RegNmQueryEx 147 148 DBGFR3RegNmQueryAll 148 149 DBGFR3RegNmQueryAllCount
Note:
See TracChangeset
for help on using the changeset viewer.