Changeset 102092 in vbox for trunk/src/VBox
- Timestamp:
- Nov 14, 2023 11:53:15 PM (18 months ago)
- svn:sync-xref-src-repo-rev:
- 160209
- Location:
- trunk/src/VBox
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r99739 r102092 499 499 { "pc", 0, 0, &g_aArgStepTrace[0], RT_ELEMENTS(g_aArgStepTrace), 0, dbgcCmdStepTrace, "[count] [cmds]", "Step to the next call instruction." }, 500 500 { "pt", 0, 0, &g_aArgStepTrace[0], RT_ELEMENTS(g_aArgStepTrace), 0, dbgcCmdStepTrace, "[count] [cmds]", "Step to the next return instruction." }, 501 { "r", 0, 3, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdReg, "[reg [[=] newval]]", "Show or set register(s) - active reg set. " },502 { "rg", 0, 3, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdRegGuest, "[reg [[=] newval]]", "Show or set register(s) - guest reg set. " },501 { "r", 0, 3, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdReg, "[reg [[=] newval]]", "Show or set register(s) - active reg set. Special 'all' register for showing all. Append a dot '.' to display sub-fields and aliases." }, 502 { "rg", 0, 3, &g_aArgReg[0], RT_ELEMENTS(g_aArgReg), 0, dbgcCmdRegGuest, "[reg [[=] newval]]", "Show or set register(s) - guest reg set. Special 'all' register for showing all. Append a dot '.' to display sub-fields and aliases." }, 503 503 { "rg32", 0, 0, NULL, 0, 0, dbgcCmdRegGuest, "", "Show 32-bit guest registers." }, 504 504 { "rg64", 0, 0, NULL, 0, 0, dbgcCmdRegGuest, "", "Show 64-bit guest registers." }, … … 2431 2431 { 2432 2432 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); 2433 int rc; 2433 2434 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, cArgs == 1 || cArgs == 2 || cArgs == 3); 2434 2435 DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, 0, paArgs[0].enmType == DBGCVAR_TYPE_STRING … … 2438 2439 * Parse the register name and kind. 2439 2440 */ 2440 const char *pszReg = paArgs[0].u.pszString; 2441 bool const fAllRegs = strcmp(paArgs[0].u.pszString, "all") == 0; 2442 const char *pszReg = paArgs[0].u.pszString; 2441 2443 if (*pszReg == '@') 2442 2444 pszReg++; … … 2450 2452 } 2451 2453 const char * const pszActualPrefix = idCpu & DBGFREG_HYPER_VMCPUID ? "." : ""; 2452 2453 /*2454 * Query the register type & value (the setter needs the type).2455 */2456 DBGFREGVALTYPE enmType;2457 DBGFREGVAL Value;2458 int rc = DBGFR3RegNmQuery(pUVM, idCpu, pszReg, &Value, &enmType);2459 if (RT_FAILURE(rc))2460 {2461 if (rc == VERR_DBGF_REGISTER_NOT_FOUND)2462 return DBGCCmdHlpVBoxError(pCmdHlp, VERR_INVALID_PARAMETER, "Unknown register: '%s%s'.\n",2463 pszActualPrefix, pszReg);2464 return DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegNmQuery failed querying '%s%s': %Rrc.\n",2465 pszActualPrefix, pszReg, rc);2466 }2467 2454 if (cArgs == 1) 2468 2455 { 2469 2456 /* 2470 2457 * Show the register. 2458 * 2459 * If it ends with a '.' or '.*', we'll show any subfields and aliases as 2460 * well. This is a special VBox twist. 2471 2461 */ 2462 size_t cchReg = strlen(pszReg); 2463 size_t cchSuffix = 0; 2464 if (cchReg >= 2 && pszReg[cchReg - 1] == '.') 2465 cchSuffix = 1; 2466 else if (cchReg >= 3 && pszReg[cchReg - 1] == '*' && pszReg[cchReg - 2] == '.') 2467 cchSuffix = 2; 2468 2472 2469 char szValue[160]; 2473 rc = DBGFR3RegFormatValue(szValue, sizeof(szValue), &Value, enmType, true /*fSpecial*/); 2474 if (RT_SUCCESS(rc)) 2475 rc = DBGCCmdHlpPrintf(pCmdHlp, "%s%s=%s\n", pszActualPrefix, pszReg, szValue); 2470 if (!cchSuffix && !fAllRegs) 2471 { 2472 DBGFREGVALTYPE enmType; 2473 DBGFREGVAL Value; 2474 rc = DBGFR3RegNmQuery(pUVM, idCpu, pszReg, &Value, &enmType); 2475 if (RT_FAILURE(rc)) 2476 { 2477 if (rc == VERR_DBGF_REGISTER_NOT_FOUND) 2478 return DBGCCmdHlpVBoxError(pCmdHlp, VERR_INVALID_PARAMETER, "Unknown register: '%s%s'.\n", 2479 pszActualPrefix, pszReg); 2480 return DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegNmQuery failed querying '%s%s': %Rrc.\n", 2481 pszActualPrefix, pszReg, rc); 2482 } 2483 2484 rc = DBGFR3RegFormatValue(szValue, sizeof(szValue), &Value, enmType, true /*fSpecial*/); 2485 if (RT_SUCCESS(rc)) 2486 rc = DBGCCmdHlpPrintf(pCmdHlp, "%s%s=%s\n", pszActualPrefix, pszReg, szValue); 2487 else 2488 rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegFormatValue failed: %Rrc.\n", rc); 2489 } 2476 2490 else 2477 rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegFormatValue failed: %Rrc.\n", rc); 2491 { 2492 /* 2493 * Register + aliases + subfields OR 'all'. 2494 */ 2495 /* Duplicate the register specifier sans suffix. */ 2496 char *pszRegBase = RTStrDupN(pszReg, cchReg - cchSuffix); 2497 AssertReturn(pszRegBase, VERR_NO_STR_MEMORY); 2498 2499 /* Make a rough guess on how many entires we need, or query it in the case of 'all'. */ 2500 size_t cRegsAlloc = 128; 2501 if (fAllRegs) 2502 DBGFR3RegNmQueryAllCount(pUVM, &cRegsAlloc); 2503 PDBGFREGENTRYNM paRegs = (PDBGFREGENTRYNM)RTMemTmpAlloc(sizeof(paRegs[0]) * cRegsAlloc); 2504 AssertReturnStmt(paRegs, RTStrFree(pszRegBase), VERR_NO_TMP_MEMORY); 2505 size_t cRegs = cRegsAlloc; 2506 2507 /* Query the registers.*/ 2508 if (fAllRegs) 2509 rc = DBGFR3RegNmQueryAll(pUVM, paRegs, cRegs); 2510 else 2511 rc = DBGFR3RegNmQueryEx(pUVM, idCpu, pszRegBase, DBGFR3REG_QUERY_EX_F_SUBFIELDS | DBGFR3REG_QUERY_EX_F_ALIASES, 2512 paRegs, &cRegs); 2513 if (rc == VERR_BUFFER_OVERFLOW && !fAllRegs) 2514 { 2515 RTMemTmpFree(paRegs); 2516 cRegsAlloc = cRegs; 2517 paRegs = (PDBGFREGENTRYNM)RTMemTmpAlloc(sizeof(paRegs[0]) * cRegsAlloc); 2518 AssertReturnStmt(paRegs, RTStrFree(pszRegBase), VERR_NO_TMP_MEMORY); 2519 rc = DBGFR3RegNmQueryEx(pUVM, idCpu, pszRegBase, 2520 DBGFR3REG_QUERY_EX_F_SUBFIELDS | DBGFR3REG_QUERY_EX_F_ALIASES, paRegs, &cRegs); 2521 } 2522 if (RT_SUCCESS(rc)) 2523 { 2524 /* Find max lengths and sizes for producing pretty columns. */ 2525 size_t cchMaxNm = 2; 2526 size_t cchMaxSubFieldNm = 2; 2527 size_t cMaxSubFieldBits = 1; 2528 if (*pszActualPrefix == '\0') 2529 for (uint32_t iReg = 0; iReg < cRegs; iReg++) 2530 { 2531 size_t const cchName = strlen(paRegs[iReg].pszName); 2532 if (cchMaxNm < cchName) 2533 cchMaxNm = cchName; 2534 if (paRegs[iReg].u.s.fSubField) 2535 { 2536 cchMaxSubFieldNm = RT_MAX(cchMaxSubFieldNm, cchName); 2537 cMaxSubFieldBits = RT_MAX(cMaxSubFieldBits, paRegs[iReg].u.s.cBits); 2538 } 2539 } 2540 2541 /* Output the registers. */ 2542 size_t cchMaxSubFieldValue = 2 + (cMaxSubFieldBits + 3) / 4; 2543 size_t cMaxSameLine = 80 / (2 + cchMaxSubFieldNm + 1 + cchMaxSubFieldValue); 2544 unsigned iSameLine = 0; 2545 for (uint32_t iReg = 0; iReg < cRegs; iReg++) 2546 { 2547 if ( !paRegs[iReg].u.s.fSubField 2548 || !paRegs[iReg].u.s.cBits) 2549 rc = DBGFR3RegFormatValue(szValue, sizeof(szValue), &paRegs[iReg].Val, 2550 paRegs[iReg].enmType, true /*fSpecial*/); 2551 else 2552 rc = DBGFR3RegFormatValueEx(szValue, sizeof(szValue), &paRegs[iReg].Val, paRegs[iReg].enmType, 2553 16, 2554 (paRegs[iReg].u.s.cBits + 3) / 4, 2555 0, 2556 (paRegs[iReg].u.s.cBits == 1 ? 0 : RTSTR_F_SPECIAL) | RTSTR_F_WIDTH); 2557 if (RT_SUCCESS(rc)) 2558 { 2559 if (!paRegs[iReg].u.s.fSubField) 2560 { 2561 if (iSameLine > 0) 2562 rc = DBGCCmdHlpPrintf(pCmdHlp, "\n"); 2563 if (*pszActualPrefix == '\0') 2564 rc = DBGCCmdHlpPrintf(pCmdHlp, "%*s=%s\n", cchMaxNm, paRegs[iReg].pszName, szValue); 2565 else 2566 rc = DBGCCmdHlpPrintf(pCmdHlp, "%s%s=%s\n", pszActualPrefix, paRegs[iReg].pszName, szValue); 2567 iSameLine = 0; 2568 } 2569 else 2570 { 2571 if (*pszActualPrefix == '\0') 2572 rc = DBGCCmdHlpPrintf(pCmdHlp, " %*s=%s", cchMaxSubFieldNm, paRegs[iReg].pszName, szValue); 2573 else 2574 rc = DBGCCmdHlpPrintf(pCmdHlp, " %s%s=%s", pszActualPrefix, paRegs[iReg].pszName, szValue); 2575 iSameLine++; 2576 if (iSameLine < cMaxSameLine) 2577 { 2578 size_t cchValue = strlen(szValue); 2579 if (cchValue < cchMaxSubFieldValue) 2580 rc = DBGCCmdHlpPrintf(pCmdHlp, "%*s", cchMaxSubFieldValue - cchValue, ""); 2581 } 2582 else 2583 { 2584 rc = DBGCCmdHlpPrintf(pCmdHlp, "\n"); 2585 iSameLine = 0; 2586 } 2587 } 2588 } 2589 else 2590 rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegFormatValue[Ex] failed for %s: %Rrc.\n", 2591 paRegs[iReg].pszName, rc); 2592 } 2593 if (iSameLine > 0) 2594 rc = DBGCCmdHlpPrintf(pCmdHlp, "\n"); 2595 } 2596 else if (fAllRegs) 2597 rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegNmQueryAll failed: %Rrc.\n", 2598 pszActualPrefix, rc); 2599 else if (rc == VERR_DBGF_REGISTER_NOT_FOUND) 2600 rc = DBGCCmdHlpVBoxError(pCmdHlp, VERR_INVALID_PARAMETER, "Unknown register: '%s%s'.\n", 2601 pszActualPrefix, pszRegBase); 2602 else 2603 rc = DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegNmQueryEx failed querying '%s%s': %Rrc.\n", 2604 pszActualPrefix, pszRegBase, rc); 2605 RTStrFree(pszRegBase); 2606 RTMemTmpFree(paRegs); 2607 } 2478 2608 } 2479 2609 else 2480 2610 { 2611 /* 2612 * We're about to modify the register. 2613 * 2614 * First we need to query the register type (see below). 2615 */ 2616 DBGFREGVALTYPE enmType; 2617 DBGFREGVAL Value; 2618 rc = DBGFR3RegNmQuery(pUVM, idCpu, pszReg, &Value, &enmType); 2619 if (RT_FAILURE(rc)) 2620 { 2621 if (rc == VERR_DBGF_REGISTER_NOT_FOUND) 2622 return DBGCCmdHlpVBoxError(pCmdHlp, VERR_INVALID_PARAMETER, "Unknown register: '%s%s'.\n", 2623 pszActualPrefix, pszReg); 2624 return DBGCCmdHlpVBoxError(pCmdHlp, rc, "DBGFR3RegNmQuery failed querying '%s%s': %Rrc.\n", 2625 pszActualPrefix, pszReg, rc); 2626 } 2627 2481 2628 DBGCVAR NewValueTmp; 2482 2629 PCDBGCVAR pNewValue; -
trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
r100940 r102092 302 302 return VERR_DBGF_REGISTER_NOT_FOUND; 303 303 } 304 VMMR3DECL(int) DBGFR3RegNmQueryEx(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t fFlags, 305 PDBGFREGENTRYNM paRegs, size_t *pcRegs) 306 { 307 return VERR_INTERNAL_ERROR; 308 } 309 VMMR3DECL(int) DBGFR3RegNmQueryAll(PUVM pUVM, PDBGFREGENTRYNM paRegs, size_t cRegs) 310 { 311 return VERR_INTERNAL_ERROR; 312 } 313 VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PUVM pUVM, size_t *pcRegs) 314 { 315 *pcRegs = 99; 316 return VINF_SUCCESS; 317 } 304 318 VMMR3DECL(int) DBGFR3RegPrintf(PUVM pUVM, VMCPUID idCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...) 305 319 { … … 308 322 VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial) 309 323 { 324 return VERR_INTERNAL_ERROR; 325 } 326 VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, 327 unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags) 328 { 329 RT_NOREF(pszBuf, cbBuf, pValue, enmType, uBase, cchWidth, cchPrecision, fFlags); 310 330 return VERR_INTERNAL_ERROR; 311 331 } -
trunk/src/VBox/Main/src-client/MachineDebuggerImpl.cpp
r98278 r102092 1115 1115 aValues.resize(cRegs); 1116 1116 aNames.resize(cRegs); 1117 for (uint32_t iReg = 0; iReg < cRegs; iReg++) 1117 uint32_t iDst = 0; 1118 for (uint32_t iSrc = 0; iSrc < cRegs; iSrc++) 1119 if (paRegs[iSrc].pszName) /* skip padding entries */ 1120 { 1121 char szHex[160]; 1122 szHex[159] = szHex[0] = '\0'; 1123 ssize_t cch = ptrVM.vtable()->pfnDBGFR3RegFormatValue(szHex, sizeof(szHex), &paRegs[iSrc].Val, 1124 paRegs[iSrc].enmType, true /*fSpecial*/); 1125 Assert(cch > 0); NOREF(cch); 1126 aNames[iDst] = paRegs[iSrc].pszName; 1127 aValues[iDst] = szHex; 1128 iDst++; 1129 } 1130 1131 /* If we skipped padding entries, resize the return arrays to the actual return size. */ 1132 if (iDst < cRegs) 1118 1133 { 1119 char szHex[160]; 1120 szHex[159] = szHex[0] = '\0'; 1121 ssize_t cch = ptrVM.vtable()->pfnDBGFR3RegFormatValue(szHex, sizeof(szHex), &paRegs[iReg].Val, 1122 paRegs[iReg].enmType, true /*fSpecial*/); 1123 Assert(cch > 0); NOREF(cch); 1124 aNames[iReg] = paRegs[iReg].pszName; 1125 aValues[iReg] = szHex; 1134 aValues.resize(iDst); 1135 aNames.resize(iDst); 1126 1136 } 1127 1137 } -
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 -
trunk/src/VBox/VMM/include/DBGFInternal.h
r98103 r102092 1358 1358 * register aliases (eg AH) are not counted). */ 1359 1359 uint32_t cRegs; 1360 /** Number of registers per CPU. */ 1361 uint16_t cPerCpuRegs; 1362 /** Number of hypervisor register per CPU. */ 1363 uint8_t cPerCpuHyperRegs; 1360 1364 /** For early initialization by . */ 1361 1365 bool volatile fRegDbInitialized; 1362 /** Alignment padding. */1363 bool afAlignment2[3];1364 1366 1365 1367 /** Critical section protecting the Guest OS Digger data, the info handlers
Note:
See TracChangeset
for help on using the changeset viewer.