Changeset 35466 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Jan 10, 2011 4:36:35 PM (14 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/DBGF.cpp
r35346 r35466 135 135 { 136 136 int rc = dbgfR3InfoInit(pVM); 137 if (RT_SUCCESS(rc)) 138 rc = dbgfR3RegInit(pVM); 137 139 if (RT_SUCCESS(rc)) 138 140 rc = dbgfR3AsInit(pVM); … … 208 210 dbgfR3OSTerm(pVM); 209 211 dbgfR3AsTerm(pVM); 212 dbgfR3RegTerm(pVM); 210 213 dbgfR3InfoTerm(pVM); 211 214 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMR3/DBGFReg.cpp
r35411 r35466 64 64 65 65 66 /** The max length of a set, register or sub-field name. */ 67 #define DBGF_REG_MAX_NAME 40 68 66 69 67 70 /******************************************************************************* … … 92 95 RTSTRSPACECORE Core; 93 96 /** The registration record type. */ 94 DBGFREGSETTYPE enmType;97 DBGFREGSETTYPE enmType; 95 98 /** The user argument for the callbacks. */ 96 99 union … … 109 112 size_t cDescs; 110 113 114 /** Array of lookup records. */ 115 struct DBGFREGLOOKUP *paLookupRecs; 116 /** The number of lookup records. */ 117 size_t cLookupRecs; 118 111 119 /** The register name prefix. */ 112 char szPrefix[ 32];120 char szPrefix[1]; 113 121 } DBGFREGSET; 114 122 /** Pointer to a register registration record. */ 115 123 typedef DBGFREGSET *PDBGFREGSET; 124 /** Pointer to a const register registration record. */ 125 typedef DBGFREGSET const *PCDBGFREGSET; 126 127 128 /** 129 * Register lookup record. 130 */ 131 typedef struct DBGFREGLOOKUP 132 { 133 /** The string space core. */ 134 RTSTRSPACECORE Core; 135 /** Pointer to the set. */ 136 PCDBGFREGSET pSet; 137 /** Pointer to the register descriptor. */ 138 PCDBGFREGDESC pDesc; 139 /** If an alias this points to the alias descriptor, NULL if not. */ 140 PCDBGFREGALIAS pAlias; 141 /** If a sub-field this points to the sub-field descriptor, NULL if not. */ 142 PCDBGFREGSUBFIELD pSubField; 143 } DBGFREGLOOKUP; 144 /** Pointer to a register lookup record. */ 145 typedef DBGFREGLOOKUP *PDBGFREGLOOKUP; 146 /** Pointer to a const register lookup record. */ 147 typedef DBGFREGLOOKUP const *PCDBGFREGLOOKUP; 148 149 150 /** 151 * Initializes the register database. 152 * 153 * @returns VBox status code. 154 * @param pVM The VM handle. 155 */ 156 int dbgfR3RegInit(PVM pVM) 157 { 158 return RTSemRWCreate(&pVM->dbgf.s.hRegDbLock); 159 } 160 161 162 /** 163 * Terminates the register database. 164 * 165 * @param pVM The VM handle. 166 */ 167 void dbgfR3RegTerm(PVM pVM) 168 { 169 RTSemRWDestroy(pVM->dbgf.s.hRegDbLock); 170 pVM->dbgf.s.hRegDbLock = NIL_RTSEMRW; 171 } 116 172 117 173 … … 126 182 static bool dbgfR3RegIsNameValid(const char *pszName) 127 183 { 128 if (!RT_C_IS_ALPHA(*pszName)) 184 const char *psz = pszName; 185 if (!RT_C_IS_ALPHA(*psz)) 129 186 return false; 130 187 char ch; 131 while ((ch = *++psz Name))188 while ((ch = *++psz)) 132 189 if ( !RT_C_IS_LOWER(ch) 133 190 && !RT_C_IS_DIGIT(ch) 134 191 && ch != '_') 135 192 return false; 193 if (psz - pszName > DBGF_REG_MAX_NAME) 194 return false; 136 195 return true; 137 196 } … … 165 224 166 225 /* The descriptors. */ 226 uint32_t cLookupRecs = 0; 167 227 uint32_t iDesc; 168 228 for (iDesc = 0; paRegisters[iDesc].pszName != NULL; iDesc++) … … 184 244 AssertPtrReturn(paRegisters[iDesc].pfnSet, VERR_INVALID_PARAMETER); 185 245 186 PCDBGFREGALIAS paAliases = paRegisters[iDesc].paAliases; 246 uint32_t iAlias = 0; 247 PCDBGFREGALIAS paAliases = paRegisters[iDesc].paAliases; 187 248 if (paAliases) 188 249 { 189 250 AssertPtrReturn(paAliases, VERR_INVALID_PARAMETER); 190 for ( uint32_t j = 0; paAliases[j].pszName; j++)251 for (; paAliases[iAlias].pszName; iAlias++) 191 252 { 192 AssertMsgReturn(dbgfR3RegIsNameValid(paAliases[ j].pszName), ("%s (%s)\n", paAliases[j].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);193 AssertReturn( paAliases[ j].enmType > DBGFREGVALTYPE_INVALID194 && paAliases[ j].enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER);253 AssertMsgReturn(dbgfR3RegIsNameValid(paAliases[iAlias].pszName), ("%s (%s)\n", paAliases[iAlias].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME); 254 AssertReturn( paAliases[iAlias].enmType > DBGFREGVALTYPE_INVALID 255 && paAliases[iAlias].enmType < DBGFREGVALTYPE_END, VERR_INVALID_PARAMETER); 195 256 } 196 257 } 197 258 259 uint32_t iSubField = 0; 198 260 PCDBGFREGSUBFIELD paSubFields = paRegisters[iDesc].paSubFields; 199 261 if (paSubFields) 200 262 { 201 263 AssertPtrReturn(paSubFields, VERR_INVALID_PARAMETER); 202 for ( uint32_t j = 0; paSubFields[j].pszName; j++)264 for (; paSubFields[iSubField].pszName; iSubField++) 203 265 { 204 AssertMsgReturn(dbgfR3RegIsNameValid(paSubFields[ j].pszName), ("%s (%s)\n", paSubFields[j].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME);205 AssertReturn(paSubFields[ j].iFirstBit + paSubFields[j].cBits <= 128, VERR_INVALID_PARAMETER);206 AssertReturn(paSubFields[ j].cBits + paSubFields[j].cShift <= 128, VERR_INVALID_PARAMETER);207 AssertPtrNullReturn(paSubFields[ j].pfnGet, VERR_INVALID_POINTER);208 AssertPtrNullReturn(paSubFields[ j].pfnSet, VERR_INVALID_POINTER);266 AssertMsgReturn(dbgfR3RegIsNameValid(paSubFields[iSubField].pszName), ("%s (%s)\n", paSubFields[iSubField].pszName, paRegisters[iDesc].pszName), VERR_INVALID_NAME); 267 AssertReturn(paSubFields[iSubField].iFirstBit + paSubFields[iSubField].cBits <= 128, VERR_INVALID_PARAMETER); 268 AssertReturn(paSubFields[iSubField].cBits + paSubFields[iSubField].cShift <= 128, VERR_INVALID_PARAMETER); 269 AssertPtrNullReturn(paSubFields[iSubField].pfnGet, VERR_INVALID_POINTER); 270 AssertPtrNullReturn(paSubFields[iSubField].pfnSet, VERR_INVALID_POINTER); 209 271 } 210 272 } 211 } 273 274 cLookupRecs += (1 + iAlias) * (1 + iSubField); 275 } 276 277 /* Check the instance number of the CPUs. */ 278 AssertReturn(enmType != DBGFREGSETTYPE_CPU || iInstance < pVM->cCpus, VERR_INVALID_CPU_ID); 212 279 213 280 /* 214 * Allocate a new record .281 * Allocate a new record and all associated lookup records. 215 282 */ 216 PDBGFREGSET pRegRec = (PDBGFREGSET)MMR3HeapAlloc(pVM, MM_TAG_DBGF_REG, RT_OFFSETOF(DBGFREGSET, szPrefix[cchPrefix + 4 + 1])); 217 if (!pRegRec) 283 size_t cbRegSet = RT_OFFSETOF(DBGFREGSET, szPrefix[cchPrefix + 4 + 1]); 284 cbRegSet = RT_ALIGN_Z(cbRegSet, 32); 285 size_t const offLookupRecArray = cbRegSet; 286 cbRegSet += cLookupRecs * sizeof(DBGFREGLOOKUP); 287 288 PDBGFREGSET pRegSet = (PDBGFREGSET)MMR3HeapAllocZ(pVM, MM_TAG_DBGF_REG, cbRegSet); 289 if (!pRegSet) 218 290 return VERR_NO_MEMORY; 219 291 220 pRegRec->Core.pszString = pRegRec->szPrefix; 221 pRegRec->enmType = enmType; 222 pRegRec->uUserArg.pv = pvUserArg; 223 pRegRec->paDescs = paRegisters; 224 pRegRec->cDescs = iDesc; 292 /* 293 * Initialize the new record. 294 */ 295 pRegSet->Core.pszString = pRegSet->szPrefix; 296 pRegSet->enmType = enmType; 297 pRegSet->uUserArg.pv = pvUserArg; 298 pRegSet->paDescs = paRegisters; 299 pRegSet->cDescs = iDesc; 300 pRegSet->cLookupRecs = cLookupRecs; 301 pRegSet->paLookupRecs = (PDBGFREGLOOKUP)((uintptr_t)pRegSet + offLookupRecArray); 225 302 if (fNeedUnderscore) 226 RTStrPrintf(pReg Rec->szPrefix, cchPrefix + 4 + 1, "%s_%u", pszPrefix, iInstance);303 RTStrPrintf(pRegSet->szPrefix, cchPrefix + 4 + 1, "%s_%u", pszPrefix, iInstance); 227 304 else 228 RTStrPrintf(pRegRec->szPrefix, cchPrefix + 4 + 1, "%s%u", pszPrefix, iInstance); 229 230 DBGF_REG_DB_LOCK_WRITE(pVM); 231 bool fInserted = RTStrSpaceInsert(&pVM->dbgf.s.RegSetSpace, &pRegRec->Core); 232 DBGF_REG_DB_UNLOCK_WRITE(pVM); 233 if (fInserted) 234 return VINF_SUCCESS; 235 236 MMR3HeapFree(pRegRec); 237 return VERR_DUPLICATE; 305 RTStrPrintf(pRegSet->szPrefix, cchPrefix + 4 + 1, "%s%u", pszPrefix, iInstance); 306 307 308 /* 309 * Initialize the lookup records. 310 */ 311 char szName[DBGF_REG_MAX_NAME * 3 + 16]; 312 strcpy(szName, pRegSet->szPrefix); 313 char *pszReg = strchr(szName, '\0'); 314 *pszReg++ = '.'; 315 316 int rc = VINF_SUCCESS; 317 PDBGFREGLOOKUP pLookupRec = &pRegSet->paLookupRecs[0]; 318 for (iDesc = 0; paRegisters[iDesc].pszName != NULL && RT_SUCCESS(rc); iDesc++) 319 { 320 PCDBGFREGALIAS pCurAlias = NULL; 321 PCDBGFREGALIAS pNextAlias = paRegisters[iDesc].paAliases; 322 const char *pszRegName = paRegisters[iDesc].pszName; 323 while (RT_SUCCESS(rc)) 324 { 325 size_t cchReg = strlen(paRegisters[iDesc].pszName); 326 memcpy(pszReg, paRegisters[iDesc].pszName, cchReg + 1); 327 pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName); 328 if (!pLookupRec->Core.pszString) 329 rc = VERR_NO_STR_MEMORY; 330 pLookupRec->pSet = pRegSet; 331 pLookupRec->pDesc = &paRegisters[iDesc]; 332 pLookupRec->pAlias = pCurAlias; 333 pLookupRec->pSubField = NULL; 334 335 PCDBGFREGSUBFIELD paSubFields = paRegisters[iDesc].paSubFields; 336 if (paSubFields) 337 { 338 char *pszSub = &pszReg[cchReg]; 339 *pszSub++ = '.'; 340 for (uint32_t iSubField = 0; paSubFields[iSubField].pszName && RT_SUCCESS(rc); iSubField++) 341 { 342 strcpy(pszSub, paSubFields[iSubField].pszName); 343 pLookupRec->Core.pszString = MMR3HeapStrDup(pVM, MM_TAG_DBGF_REG, szName); 344 if (!pLookupRec->Core.pszString) 345 rc = VERR_NO_STR_MEMORY; 346 pLookupRec->pSet = pRegSet; 347 pLookupRec->pDesc = &paRegisters[iDesc]; 348 pLookupRec->pAlias = pCurAlias; 349 pLookupRec->pSubField = &paSubFields[iSubField]; 350 } 351 } 352 353 /* next */ 354 pCurAlias = pNextAlias++; 355 if ( !pCurAlias 356 || !pCurAlias->pszName) 357 break; 358 pszRegName = pCurAlias->pszName; 359 } 360 } 361 362 if (RT_SUCCESS(rc)) 363 { 364 /* 365 * Insert the record into the register set string space and optionally into 366 * the CPU register set cache. 367 */ 368 DBGF_REG_DB_LOCK_WRITE(pVM); 369 370 bool fInserted = RTStrSpaceInsert(&pVM->dbgf.s.RegSetSpace, &pRegSet->Core); 371 if (fInserted) 372 { 373 if (enmType == DBGFREGSETTYPE_CPU) 374 pVM->aCpus[iInstance].dbgf.s.pRegSet = pRegSet; 375 pVM->dbgf.s.cRegs += pRegSet->cDescs; 376 377 PDBGFREGLOOKUP paLookupRecs = pRegSet->paLookupRecs; 378 uint32_t iLookupRec = pRegSet->cLookupRecs; 379 while (iLookupRec-- > 0) 380 { 381 bool fInserted2 = RTStrSpaceInsert(&pVM->dbgf.s.RegSpace, &paLookupRecs[iLookupRec].Core); 382 AssertMsg(fInserted2, ("'%s'", paLookupRecs[iLookupRec].Core.pszString)); 383 } 384 385 DBGF_REG_DB_UNLOCK_WRITE(pVM); 386 return VINF_SUCCESS; 387 } 388 389 DBGF_REG_DB_UNLOCK_WRITE(pVM); 390 rc = VERR_DUPLICATE; 391 } 392 393 /* 394 * Bail out. 395 */ 396 for (uint32_t i = 0; i < pRegSet->cLookupRecs; i++) 397 MMR3HeapFree((char *)pRegSet->paLookupRecs[i].Core.pszString); 398 MMR3HeapFree(pRegSet); 399 400 return rc; 238 401 } 239 402 … … 301 464 dbgfR3RegValClear(pValue); 302 465 466 /* Note! No default cases here as gcc warnings about missing enum values 467 are desired. */ 303 468 switch (enmFromType) 304 469 { … … 311 476 case DBGFREGVALTYPE_U64: pValue->u64 = InVal.u8; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 312 477 case DBGFREGVALTYPE_U128: pValue->u128.s.Lo = InVal.u8; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 313 case DBGFREGVALTYPE_80: return VERR_DBGF_UNSUPPORTED_CAST;314 478 case DBGFREGVALTYPE_LRD: pValue->lrd = InVal.u8; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 315 479 case DBGFREGVALTYPE_DTR: return VERR_DBGF_UNSUPPORTED_CAST; … … 330 494 case DBGFREGVALTYPE_U64: pValue->u64 = InVal.u16; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 331 495 case DBGFREGVALTYPE_U128: pValue->u128.s.Lo = InVal.u16; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 332 case DBGFREGVALTYPE_80: return VERR_DBGF_UNSUPPORTED_CAST;333 496 case DBGFREGVALTYPE_LRD: pValue->lrd = InVal.u16; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 334 497 case DBGFREGVALTYPE_DTR: return VERR_DBGF_UNSUPPORTED_CAST; … … 349 512 case DBGFREGVALTYPE_U64: pValue->u64 = InVal.u32; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 350 513 case DBGFREGVALTYPE_U128: pValue->u128.s.Lo = InVal.u32; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 351 case DBGFREGVALTYPE_80: return VERR_DBGF_UNSUPPORTED_CAST;352 514 case DBGFREGVALTYPE_LRD: pValue->lrd = InVal.u32; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 353 515 case DBGFREGVALTYPE_DTR: return VERR_DBGF_UNSUPPORTED_CAST; … … 368 530 case DBGFREGVALTYPE_U64: pValue->u64 = InVal.u64; return VINF_SUCCESS; 369 531 case DBGFREGVALTYPE_U128: pValue->u128.s.Lo = InVal.u64; return VINF_DBGF_TRUNCATED_REGISTER; 370 case DBGFREGVALTYPE_80: return VERR_DBGF_UNSUPPORTED_CAST;371 532 case DBGFREGVALTYPE_LRD: pValue->lrd = InVal.u64; return VINF_DBGF_ZERO_EXTENDED_REGISTER; 372 533 case DBGFREGVALTYPE_DTR: return VERR_DBGF_UNSUPPORTED_CAST; … … 387 548 case DBGFREGVALTYPE_U64: pValue->u64 = InVal.u128.s.Lo; return VINF_DBGF_TRUNCATED_REGISTER; 388 549 case DBGFREGVALTYPE_U128: pValue->u128 = InVal.u128; return VINF_SUCCESS; 389 case DBGFREGVALTYPE_80: return VERR_DBGF_UNSUPPORTED_CAST;390 550 case DBGFREGVALTYPE_LRD: pValue->lrd = InVal.u64; return VINF_DBGF_TRUNCATED_REGISTER; 391 551 case DBGFREGVALTYPE_DTR: return VERR_DBGF_UNSUPPORTED_CAST; … … 397 557 } 398 558 break; 399 400 case DBGFREGVALTYPE_80:401 return VERR_DBGF_UNSUPPORTED_CAST;402 559 403 560 case DBGFREGVALTYPE_LRD: … … 412 569 pValue->u128.s.Hi = (uint64_t)InVal.lrd / _4G / _4G; 413 570 return VINF_DBGF_TRUNCATED_REGISTER; 414 case DBGFREGVALTYPE_80: return VERR_DBGF_UNSUPPORTED_CAST;415 571 case DBGFREGVALTYPE_LRD: pValue->lrd = InVal.lrd; return VINF_SUCCESS; 416 572 case DBGFREGVALTYPE_DTR: return VERR_DBGF_UNSUPPORTED_CAST; … … 431 587 case DBGFREGVALTYPE_U64: pValue->u64 = InVal.dtr.u64Base; return VINF_DBGF_TRUNCATED_REGISTER; 432 588 case DBGFREGVALTYPE_U128: pValue->u128.s.Lo = InVal.dtr.u64Base; return VINF_DBGF_TRUNCATED_REGISTER; 433 case DBGFREGVALTYPE_80: return VERR_DBGF_UNSUPPORTED_CAST;434 589 case DBGFREGVALTYPE_LRD: pValue->lrd = InVal.dtr.u64Base; return VINF_DBGF_TRUNCATED_REGISTER; 435 590 case DBGFREGVALTYPE_DTR: pValue->dtr = InVal.dtr; return VINF_SUCCESS; … … 460 615 * @retval VERR_INVALID_VM_HANDLE 461 616 * @retval VERR_INVALID_CPU_ID 462 * @retval VERR_DBGF_ INVALID_REGISTER617 * @retval VERR_DBGF_REGISTER_NOT_FOUND 463 618 * @retval VERR_DBGF_UNSUPPORTED_CAST 464 619 * @retval VINF_DBGF_TRUNCATED_REGISTER … … 469 624 * @param enmReg The register to query. 470 625 * @param enmType The desired return type. 471 * @param p uValueWhere to return the register value.472 */ 473 static DECLCALLBACK(int) dbgfR3RegCpuQueryWorker(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, DBGFREGVALTYPE enmType, PDBGFREGVAL p uValue)626 * @param pValue Where to return the register value. 627 */ 628 static DECLCALLBACK(int) dbgfR3RegCpuQueryWorker(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, DBGFREGVALTYPE enmType, PDBGFREGVAL pValue) 474 629 { 475 630 int rc = VINF_SUCCESS; … … 477 632 478 633 /* 479 * Look up the register set of the CPU.634 * Look up the register set of the specified CPU. 480 635 */ 481 /** @todo optimize this by adding a cpu register set array to DBGF. */ 482 char szSetName[16]; 483 RTStrPrintf(szSetName, sizeof(szSetName), "cpu%u", idCpu); 484 PDBGFREGSET pSet = (PDBGFREGSET)RTStrSpaceGet(&pVM->dbgf.s.RegSetSpace, szSetName); 636 PDBGFREGSET pSet = pVM->aCpus[idCpu].dbgf.s.pRegSet; 485 637 if (RT_LIKELY(pSet)) 486 638 { … … 492 644 PCDBGFREGDESC pDesc = &pSet->paDescs[enmReg]; 493 645 494 p uValue->au64[0] = puValue->au64[1] = 0;495 rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, p uValue);646 pValue->au64[0] = pValue->au64[1] = 0; 647 rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, pValue); 496 648 if (RT_SUCCESS(rc)) 497 649 { … … 503 655 rc = VINF_SUCCESS; 504 656 else 505 rc = dbgfR3RegValCast(p uValue, pDesc->enmType, enmType);657 rc = dbgfR3RegValCast(pValue, pDesc->enmType, enmType); 506 658 } 507 659 } 508 660 else 509 rc = VERR_DBGF_ INVALID_REGISTER;661 rc = VERR_DBGF_REGISTER_NOT_FOUND; 510 662 } 511 663 else … … 523 675 * @retval VERR_INVALID_VM_HANDLE 524 676 * @retval VERR_INVALID_CPU_ID 525 * @retval VERR_DBGF_ INVALID_REGISTER677 * @retval VERR_DBGF_REGISTER_NOT_FOUND 526 678 * @retval VERR_DBGF_UNSUPPORTED_CAST 527 679 * @retval VINF_DBGF_TRUNCATED_REGISTER … … 554 706 * @retval VERR_INVALID_VM_HANDLE 555 707 * @retval VERR_INVALID_CPU_ID 556 * @retval VERR_DBGF_ INVALID_REGISTER708 * @retval VERR_DBGF_REGISTER_NOT_FOUND 557 709 * @retval VERR_DBGF_UNSUPPORTED_CAST 558 710 * @retval VINF_DBGF_TRUNCATED_REGISTER … … 586 738 * @retval VERR_INVALID_VM_HANDLE 587 739 * @retval VERR_INVALID_CPU_ID 588 * @retval VERR_DBGF_ INVALID_REGISTER740 * @retval VERR_DBGF_REGISTER_NOT_FOUND 589 741 * @retval VERR_DBGF_UNSUPPORTED_CAST 590 742 * @retval VINF_DBGF_TRUNCATED_REGISTER … … 618 770 * @retval VERR_INVALID_VM_HANDLE 619 771 * @retval VERR_INVALID_CPU_ID 620 * @retval VERR_DBGF_ INVALID_REGISTER772 * @retval VERR_DBGF_REGISTER_NOT_FOUND 621 773 * @retval VERR_DBGF_UNSUPPORTED_CAST 622 774 * @retval VINF_DBGF_TRUNCATED_REGISTER … … 648 800 * 649 801 * @retval VINF_SUCCESS 650 * @retval VERR_DBGF_ INVALID_REGISTER802 * @retval VERR_DBGF_REGISTER_NOT_FOUND 651 803 * 652 804 * @param pVCpu The current CPU. … … 681 833 682 834 DBGFREG const enmReg = pReg->enmReg; 683 AssertMsgReturn(enmReg >= 0 && enmReg <= DBGFREG_END, ("%d (%#x)\n", enmReg, enmReg), VERR_DBGF_ INVALID_REGISTER);835 AssertMsgReturn(enmReg >= 0 && enmReg <= DBGFREG_END, ("%d (%#x)\n", enmReg, enmReg), VERR_DBGF_REGISTER_NOT_FOUND); 684 836 if (enmReg != DBGFREG_END) 685 837 { … … 728 880 * @retval VERR_INVALID_VM_HANDLE 729 881 * @retval VERR_INVALID_CPU_ID 730 * @retval VERR_DBGF_ INVALID_REGISTER882 * @retval VERR_DBGF_REGISTER_NOT_FOUND 731 883 * 732 884 * @param pVM The VM handle. … … 751 903 { 752 904 DBGFREG enmReg = paRegs[iReg].enmReg; 753 AssertMsgReturn(enmReg < DBGFREG_END && enmReg >= DBGFREG_AL, ("%d (%#x)", enmReg, enmReg), VERR_DBGF_ INVALID_REGISTER);905 AssertMsgReturn(enmReg < DBGFREG_END && enmReg >= DBGFREG_AL, ("%d (%#x)", enmReg, enmReg), VERR_DBGF_REGISTER_NOT_FOUND); 754 906 } 755 907 … … 809 961 * @returns Pointer to read-only register name (lower case). NULL if the 810 962 * parameters are invalid. 963 * 964 * @param pVM The VM handle. 811 965 * @param enmReg The register identifier. 812 966 * @param enmType The register type. This is for sort out … … 814 968 * the standard name. 815 969 */ 816 VMMR3DECL(const char *) DBGFR3RegCpuName( DBGFREG enmReg, DBGFREGVALTYPE enmType)970 VMMR3DECL(const char *) DBGFR3RegCpuName(PVM pVM, DBGFREG enmReg, DBGFREGVALTYPE enmType) 817 971 { 818 972 AssertReturn(enmReg >= DBGFREG_AL && enmReg < DBGFREG_END, NULL); 819 973 AssertReturn(enmType >= DBGFREGVALTYPE_INVALID && enmType < DBGFREGVALTYPE_END, NULL); 820 821 #if 0 /** @todo need the optimization */ 822 PCDBGFREGDESC pDesc = &g_aDbgfRegDescs[enmReg]; 823 PCDBGFREGALIAS pAlias = pDesc->paAliases; 974 VM_ASSERT_VALID_EXT_RETURN(pVM, NULL); 975 976 PCDBGFREGSET pSet = pVM->aCpus[0].dbgf.s.pRegSet; 977 if (RT_UNLIKELY(!pSet)) 978 return NULL; 979 980 PCDBGFREGDESC pDesc = &pSet->paDescs[enmReg]; 981 PCDBGFREGALIAS pAlias = pDesc->paAliases; 824 982 if ( pAlias 825 983 && pDesc->enmType != enmType … … 835 993 836 994 return pDesc->pszName; 837 #else 838 return NULL; 839 #endif 840 } 841 842 /** @todo Implementing missing APIs. */ 995 } 996 997 998 /** 999 * Fold the string to lower case and copy it into the destination buffer. 1000 * 1001 * @returns Number of folder characters, -1 on overflow. 1002 * @param pszSrc The source string. 1003 * @param cchSrc How much to fold and copy. 1004 * @param pszDst The output buffer. 1005 * @param cbDst The size of the output buffer. 1006 */ 1007 static ssize_t dbgfR3RegCopyToLower(const char *pszSrc, size_t cchSrc, char *pszDst, size_t cbDst) 1008 { 1009 ssize_t cchFolded = 0; 1010 char ch; 1011 while (cchSrc-- > 0 && (ch = *pszSrc++)) 1012 { 1013 if (RT_UNLIKELY(cbDst <= 1)) 1014 return -1; 1015 cbDst--; 1016 1017 char chLower = RT_C_TO_LOWER(ch); 1018 cchFolded += chLower != ch; 1019 *pszDst++ = chLower; 1020 } 1021 if (RT_UNLIKELY(!cbDst)) 1022 return -1; 1023 *pszDst = '\0'; 1024 return cchFolded; 1025 } 1026 1027 1028 /** 1029 * Resolves the register name. 1030 * 1031 * @returns Lookup record. 1032 * @param pVM The VM handle. 1033 * @param idDefCpu The default CPU ID set. 1034 * @param pszReg The register name. 1035 */ 1036 static PCDBGFREGLOOKUP dbgfR3RegResolve(PVM pVM, VMCPUID idDefCpu, const char *pszReg) 1037 { 1038 DBGF_REG_DB_LOCK_READ(pVM); 1039 1040 /* Try looking up the name without any case folding or cpu prefixing. */ 1041 PCDBGFREGLOOKUP pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pVM->dbgf.s.RegSpace, pszReg); 1042 if (!pLookupRec) 1043 { 1044 char szName[DBGF_REG_MAX_NAME * 4 + 16]; 1045 1046 /* Lower case it and try again. */ 1047 ssize_t cchFolded = dbgfR3RegCopyToLower(pszReg, RTSTR_MAX, szName, sizeof(szName) - DBGF_REG_MAX_NAME); 1048 if (cchFolded > 0) 1049 pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pVM->dbgf.s.RegSpace, szName); 1050 if ( !pLookupRec 1051 && cchFolded >= 0 1052 && idDefCpu != VMCPUID_ANY) 1053 { 1054 /* Prefix it with the specified CPU set. */ 1055 size_t cchCpuSet = RTStrPrintf(szName, sizeof(szName), "cpu%u.", idDefCpu); 1056 dbgfR3RegCopyToLower(pszReg, RTSTR_MAX, &szName[cchCpuSet], sizeof(szName) - cchCpuSet); 1057 pLookupRec = (PCDBGFREGLOOKUP)RTStrSpaceGet(&pVM->dbgf.s.RegSpace, szName); 1058 } 1059 } 1060 1061 DBGF_REG_DB_UNLOCK_READ(pVM); 1062 return pLookupRec; 1063 } 1064 1065 1066 /** 1067 * Performs a left shift on a RTUINT128U value. 1068 * 1069 * @returns pVal. 1070 * @param pVal The value to shift (input/output). 1071 * @param cBits The number of bits to shift it. Negative 1072 * numbers are treated as right shifts. 1073 */ 1074 static PRTUINT128U dbgfR3RegU128_ShiftLeft(PRTUINT128U pVal, int cBits) 1075 { 1076 RTUINT128U const InVal = *pVal; 1077 1078 if (cBits >= 0) 1079 { 1080 if (cBits >= 128) 1081 pVal->s.Lo = pVal->s.Hi = 0; 1082 else if (cBits >= 64) 1083 { 1084 pVal->s.Lo = 0; 1085 pVal->s.Hi = InVal.s.Lo << (cBits - 64); 1086 } 1087 else 1088 { 1089 pVal->s.Hi = InVal.s.Hi << cBits; 1090 pVal->s.Hi |= InVal.s.Lo >> (64 - cBits); 1091 pVal->s.Lo = InVal.s.Lo << cBits; 1092 } 1093 } 1094 else 1095 { 1096 /* (right shift) */ 1097 cBits = -cBits; 1098 if (cBits >= 128) 1099 pVal->s.Lo = pVal->s.Hi = 0; 1100 else if (cBits >= 64) 1101 { 1102 pVal->s.Hi = 0; 1103 pVal->s.Lo = InVal.s.Hi >> (cBits - 64); 1104 } 1105 else 1106 { 1107 pVal->s.Lo = InVal.s.Lo >> cBits; 1108 pVal->s.Lo |= InVal.s.Hi << (64 - cBits); 1109 pVal->s.Hi = InVal.s.Hi >> cBits; 1110 } 1111 } 1112 return pVal; 1113 } 1114 1115 1116 /** 1117 * ANDs the RTUINT128U value against a bitmask made up of the first @a cBits 1118 * bits. 1119 * 1120 * @returns pVal. 1121 * @param pVal The value to shift (input/output). 1122 * @param cBits The number of bits in the AND mask. 1123 */ 1124 static PRTUINT128U dbgfR3RegU128_AndNFirstBits(PRTUINT128U pVal, unsigned cBits) 1125 { 1126 if (cBits <= 64) 1127 { 1128 pVal->s.Hi = 0; 1129 pVal->s.Lo &= RT_BIT_64(cBits) - 1; 1130 } 1131 else if (cBits < 128) 1132 pVal->s.Hi &= RT_BIT_64(cBits - 64) - 1; 1133 return pVal; 1134 } 1135 1136 1137 /** 1138 * On CPU worker for the register queries, used by dbgfR3RegNmQueryWorker. 1139 * 1140 * @returns VBox status code. 1141 * 1142 * @param pVM The VM handle. 1143 * @param pLookupRec The register lookup record. 1144 * @param enmType The desired return type. 1145 * @param pValue Where to return the register value. 1146 * @param penmType Where to store the register value type. 1147 * Optional. 1148 */ 1149 static DECLCALLBACK(int) dbgfR3RegNmQueryWorkerOnCpu(PVM pVM, PCDBGFREGLOOKUP pLookupRec, DBGFREGVALTYPE enmType, 1150 PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType) 1151 { 1152 PCDBGFREGDESC pDesc = pLookupRec->pDesc; 1153 PCDBGFREGSET pSet = pLookupRec->pSet; 1154 PCDBGFREGSUBFIELD pSubField = pLookupRec->pSubField; 1155 DBGFREGVALTYPE enmValueType = pDesc->enmType; 1156 int rc; 1157 1158 /* 1159 * Get the register or sub-field value. 1160 */ 1161 dbgfR3RegValClear(pValue); 1162 if (!pSubField) 1163 rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, pValue); 1164 else 1165 { 1166 if (pSubField->pfnGet) 1167 { 1168 rc = pSubField->pfnGet(pSet->uUserArg.pv, pSubField, &pValue->u128); 1169 enmValueType = DBGFREGVALTYPE_U128; 1170 } 1171 else 1172 { 1173 rc = pDesc->pfnGet(pSet->uUserArg.pv, pDesc, pValue); 1174 if (RT_SUCCESS(rc)) 1175 { 1176 rc = dbgfR3RegValCast(pValue, enmValueType, DBGFREGVALTYPE_U128); 1177 if (RT_SUCCESS(rc)) 1178 { 1179 dbgfR3RegU128_ShiftLeft(&pValue->u128, -pSubField->iFirstBit); 1180 dbgfR3RegU128_AndNFirstBits(&pValue->u128, pSubField->cBits); 1181 if (pSubField->cShift) 1182 dbgfR3RegU128_ShiftLeft(&pValue->u128, pSubField->cShift); 1183 } 1184 } 1185 } 1186 if (RT_SUCCESS(rc)) 1187 { 1188 unsigned const cBits = pSubField->cBits + pSubField->cShift; 1189 if (cBits <= 8) 1190 enmValueType = DBGFREGVALTYPE_U8; 1191 else if (cBits <= 16) 1192 enmValueType = DBGFREGVALTYPE_U16; 1193 else if (cBits <= 32) 1194 enmValueType = DBGFREGVALTYPE_U32; 1195 else if (cBits <= 64) 1196 enmValueType = DBGFREGVALTYPE_U64; 1197 else 1198 enmValueType = DBGFREGVALTYPE_U128; 1199 rc = dbgfR3RegValCast(pValue, DBGFREGVALTYPE_U128, enmValueType); 1200 } 1201 } 1202 if (RT_SUCCESS(rc)) 1203 { 1204 /* 1205 * Do the cast if the desired return type doesn't match what 1206 * the getter returned. 1207 */ 1208 if ( enmValueType == enmType 1209 || enmType == DBGFREGVALTYPE_END) 1210 { 1211 rc = VINF_SUCCESS; 1212 if (penmType) 1213 *penmType = enmValueType; 1214 } 1215 else 1216 { 1217 rc = dbgfR3RegValCast(pValue, enmValueType, enmType); 1218 if (penmType) 1219 *penmType = RT_SUCCESS(rc) ? enmType : enmValueType; 1220 } 1221 } 1222 1223 return rc; 1224 } 1225 1226 1227 /** 1228 * Worker for the register queries. 1229 * 1230 * @returns VBox status code. 1231 * @retval VINF_SUCCESS 1232 * @retval VERR_INVALID_VM_HANDLE 1233 * @retval VERR_INVALID_CPU_ID 1234 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1235 * @retval VERR_DBGF_UNSUPPORTED_CAST 1236 * @retval VINF_DBGF_TRUNCATED_REGISTER 1237 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 1238 * 1239 * @param pVM The VM handle. 1240 * @param idDefCpu The virtual CPU ID for the default CPU register 1241 * set. 1242 * @param pszReg The register to query. 1243 * @param enmType The desired return type. 1244 * @param pValue Where to return the register value. 1245 * @param penmType Where to store the register value type. 1246 * Optional. 1247 */ 1248 static DECLCALLBACK(int) dbgfR3RegNmQueryWorker(PVM pVM, VMCPUID idDefCpu, const char *pszReg, DBGFREGVALTYPE enmType, 1249 PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType) 1250 { 1251 /* 1252 * Validate input. 1253 */ 1254 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1255 AssertReturn(idDefCpu < pVM->cCpus || idDefCpu == VMCPUID_ANY, VERR_INVALID_CPU_ID); 1256 AssertPtrReturn(pszReg, VERR_INVALID_POINTER); 1257 1258 Assert(enmType > DBGFREGVALTYPE_INVALID && enmType <= DBGFREGVALTYPE_END); 1259 AssertPtr(pValue); 1260 1261 /* 1262 * Resolve the register and call the getter on the relevant CPU. 1263 */ 1264 PCDBGFREGLOOKUP pLookupRec = dbgfR3RegResolve(pVM, idDefCpu, pszReg); 1265 if (pLookupRec) 1266 { 1267 if (pLookupRec->pSet->enmType == DBGFREGSETTYPE_CPU) 1268 idDefCpu = pLookupRec->pSet->uUserArg.pVCpu->idCpu; 1269 return VMR3ReqCallWait(pVM, idDefCpu, (PFNRT)dbgfR3RegNmQueryWorkerOnCpu, 5, pVM, pLookupRec, enmType, pValue, penmType); 1270 } 1271 return VERR_DBGF_REGISTER_NOT_FOUND; 1272 } 1273 1274 1275 /** 1276 * Queries a descriptor table register value. 1277 * 1278 * @retval VINF_SUCCESS 1279 * @retval VERR_INVALID_VM_HANDLE 1280 * @retval VERR_INVALID_CPU_ID 1281 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1282 * 1283 * @param pVM The VM handle. 1284 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 1285 * applicable. 1286 * @param pszReg The register that's being queried. Except for 1287 * CPU registers, this must be on the form 1288 * "set.reg[.sub]". 1289 * @param pValue Where to store the register value. 1290 * @param penmType Where to store the register value type. 1291 */ 1292 VMMR3DECL(int) DBGFR3RegNmQuery(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType) 1293 { 1294 return dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_END, pValue, penmType); 1295 } 1296 1297 1298 /** 1299 * Queries a 8-bit register value. 1300 * 1301 * @retval VINF_SUCCESS 1302 * @retval VERR_INVALID_VM_HANDLE 1303 * @retval VERR_INVALID_CPU_ID 1304 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1305 * @retval VERR_DBGF_UNSUPPORTED_CAST 1306 * @retval VINF_DBGF_TRUNCATED_REGISTER 1307 * 1308 * @param pVM The VM handle. 1309 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 1310 * applicable. 1311 * @param pszReg The register that's being queried. Except for 1312 * CPU registers, this must be on the form 1313 * "set.reg[.sub]". 1314 * @param pu8 Where to store the register value. 1315 */ 1316 VMMR3DECL(int) DBGFR3RegNmQueryU8(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8) 1317 { 1318 DBGFREGVAL Value; 1319 int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U8, &Value, NULL); 1320 if (RT_SUCCESS(rc)) 1321 *pu8 = Value.u8; 1322 else 1323 *pu8 = 0; 1324 return rc; 1325 } 1326 1327 1328 /** 1329 * Queries a 16-bit register value. 1330 * 1331 * @retval VINF_SUCCESS 1332 * @retval VERR_INVALID_VM_HANDLE 1333 * @retval VERR_INVALID_CPU_ID 1334 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1335 * @retval VERR_DBGF_UNSUPPORTED_CAST 1336 * @retval VINF_DBGF_TRUNCATED_REGISTER 1337 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 1338 * 1339 * @param pVM The VM handle. 1340 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 1341 * applicable. 1342 * @param pszReg The register that's being queried. Except for 1343 * CPU registers, this must be on the form 1344 * "set.reg[.sub]". 1345 * @param pu16 Where to store the register value. 1346 */ 1347 VMMR3DECL(int) DBGFR3RegNmQueryU16(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16) 1348 { 1349 DBGFREGVAL Value; 1350 int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U16, &Value, NULL); 1351 if (RT_SUCCESS(rc)) 1352 *pu16 = Value.u16; 1353 else 1354 *pu16 = 0; 1355 return rc; 1356 } 1357 1358 1359 /** 1360 * Queries a 32-bit register value. 1361 * 1362 * @retval VINF_SUCCESS 1363 * @retval VERR_INVALID_VM_HANDLE 1364 * @retval VERR_INVALID_CPU_ID 1365 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1366 * @retval VERR_DBGF_UNSUPPORTED_CAST 1367 * @retval VINF_DBGF_TRUNCATED_REGISTER 1368 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 1369 * 1370 * @param pVM The VM handle. 1371 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 1372 * applicable. 1373 * @param pszReg The register that's being queried. Except for 1374 * CPU registers, this must be on the form 1375 * "set.reg[.sub]". 1376 * @param pu32 Where to store the register value. 1377 */ 1378 VMMR3DECL(int) DBGFR3RegNmQueryU32(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32) 1379 { 1380 DBGFREGVAL Value; 1381 int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U32, &Value, NULL); 1382 if (RT_SUCCESS(rc)) 1383 *pu32 = Value.u32; 1384 else 1385 *pu32 = 0; 1386 return rc; 1387 } 1388 1389 1390 /** 1391 * Queries a 64-bit register value. 1392 * 1393 * @retval VINF_SUCCESS 1394 * @retval VERR_INVALID_VM_HANDLE 1395 * @retval VERR_INVALID_CPU_ID 1396 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1397 * @retval VERR_DBGF_UNSUPPORTED_CAST 1398 * @retval VINF_DBGF_TRUNCATED_REGISTER 1399 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 1400 * 1401 * @param pVM The VM handle. 1402 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 1403 * applicable. 1404 * @param pszReg The register that's being queried. Except for 1405 * CPU registers, this must be on the form 1406 * "set.reg[.sub]". 1407 * @param pu64 Where to store the register value. 1408 */ 1409 VMMR3DECL(int) DBGFR3RegNmQueryU64(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64) 1410 { 1411 DBGFREGVAL Value; 1412 int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U64, &Value, NULL); 1413 if (RT_SUCCESS(rc)) 1414 *pu64 = Value.u64; 1415 else 1416 *pu64 = 0; 1417 return rc; 1418 } 1419 1420 1421 /** 1422 * Queries a 128-bit register value. 1423 * 1424 * @retval VINF_SUCCESS 1425 * @retval VERR_INVALID_VM_HANDLE 1426 * @retval VERR_INVALID_CPU_ID 1427 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1428 * @retval VERR_DBGF_UNSUPPORTED_CAST 1429 * @retval VINF_DBGF_TRUNCATED_REGISTER 1430 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 1431 * 1432 * @param pVM The VM handle. 1433 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 1434 * applicable. 1435 * @param pszReg The register that's being queried. Except for 1436 * CPU registers, this must be on the form 1437 * "set.reg[.sub]". 1438 * @param pu128 Where to store the register value. 1439 */ 1440 VMMR3DECL(int) DBGFR3RegNmQueryU128(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128) 1441 { 1442 DBGFREGVAL Value; 1443 int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_U128, &Value, NULL); 1444 if (RT_SUCCESS(rc)) 1445 *pu128 = Value.u128; 1446 else 1447 pu128->s.Hi = pu128->s.Lo = 0; 1448 return rc; 1449 } 1450 1451 1452 /** 1453 * Queries a long double register value. 1454 * 1455 * @retval VINF_SUCCESS 1456 * @retval VERR_INVALID_VM_HANDLE 1457 * @retval VERR_INVALID_CPU_ID 1458 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1459 * @retval VERR_DBGF_UNSUPPORTED_CAST 1460 * @retval VINF_DBGF_TRUNCATED_REGISTER 1461 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 1462 * 1463 * @param pVM The VM handle. 1464 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 1465 * applicable. 1466 * @param pszReg The register that's being queried. Except for 1467 * CPU registers, this must be on the form 1468 * "set.reg[.sub]". 1469 * @param plrd Where to store the register value. 1470 */ 1471 VMMR3DECL(int) DBGFR3RegNmQueryLrd(PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd) 1472 { 1473 DBGFREGVAL Value; 1474 int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_LRD, &Value, NULL); 1475 if (RT_SUCCESS(rc)) 1476 *plrd = Value.lrd; 1477 else 1478 *plrd = 0; 1479 return rc; 1480 } 1481 1482 1483 /** 1484 * Queries a descriptor table register value. 1485 * 1486 * @retval VINF_SUCCESS 1487 * @retval VERR_INVALID_VM_HANDLE 1488 * @retval VERR_INVALID_CPU_ID 1489 * @retval VERR_DBGF_REGISTER_NOT_FOUND 1490 * @retval VERR_DBGF_UNSUPPORTED_CAST 1491 * @retval VINF_DBGF_TRUNCATED_REGISTER 1492 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER 1493 * 1494 * @param pVM The VM handle. 1495 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not 1496 * applicable. 1497 * @param pszReg The register that's being queried. Except for 1498 * CPU registers, this must be on the form 1499 * "set.reg[.sub]". 1500 * @param pu64Base Where to store the register base value. 1501 * @param pu32Limit Where to store the register limit value. 1502 */ 1503 VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint32_t *pu32Limit) 1504 { 1505 DBGFREGVAL Value; 1506 int rc = dbgfR3RegNmQueryWorker(pVM, idDefCpu, pszReg, DBGFREGVALTYPE_DTR, &Value, NULL); 1507 if (RT_SUCCESS(rc)) 1508 { 1509 *pu64Base = Value.dtr.u64Base; 1510 *pu32Limit = Value.dtr.u32Limit; 1511 } 1512 else 1513 { 1514 *pu64Base = 0; 1515 *pu32Limit = 0; 1516 } 1517 return rc; 1518 } 1519 1520 1521 /// @todo VMMR3DECL(int) DBGFR3RegNmQueryBatch(PVM pVM,VMCPUID idDefCpu, DBGFREGENTRYNM paRegs, size_t cRegs); 1522 1523 1524 /** 1525 * Gets the number of registers returned by DBGFR3RegNmQueryAll. 1526 * 1527 * @returns VBox status code. 1528 * @param pVM The VM handle. 1529 * @param pcRegs Where to return the register count. 1530 */ 1531 VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PVM pVM, size_t *pcRegs) 1532 { 1533 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1534 *pcRegs = pVM->dbgf.s.cRegs; 1535 return VINF_SUCCESS; 1536 } 1537 1538 1539 VMMR3DECL(int) DBGFR3RegNmQueryAll(PVM pVM, DBGFREGENTRYNM paRegs, size_t cRegs) 1540 { 1541 return VERR_NOT_IMPLEMENTED; 1542 } 1543 1544 1545 /// @todo VMMR3DECL(int) DBGFR3RegNmPrintf(PVM pVM, VMCPUID idDefCpu, char pszBuf, size_t cbBuf, const char *pszFormat, ...); 1546 /// @todo VMMR3DECL(int) DBGFR3RegNmPrintfV(PVM pVM, VMCPUID idDefCpu, char pszBuf, size_t cbBuf, const char *pszFormat, ...); 1547
Note:
See TracChangeset
for help on using the changeset viewer.