Changeset 41760 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Jun 15, 2012 3:56:20 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 78577
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r41731 r41760 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 3527 3527 * @callback_method_impl{FNDISREADBYTES} 3528 3528 */ 3529 static DECLCALLBACK(int) cpumR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 3530 { 3531 PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pDisState->pvUser; 3532 Assert(cbToRead > 0); 3529 static DECLCALLBACK(int) cpumR3DisasInstrRead(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 3530 { 3531 PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pDis->pvUser; 3533 3532 for (;;) 3534 3533 { 3535 RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase; 3536 3537 /* Need to update the page translation? */ 3538 if ( !pState->pvPageR3 3539 || (GCPtr >> PAGE_SHIFT) != (pState->pvPageGC >> PAGE_SHIFT)) 3534 RTGCUINTPTR GCPtr = pDis->uInstrAddr + offInstr + pState->GCPtrSegBase; 3535 3536 /* 3537 * Need to update the page translation? 3538 */ 3539 if ( !pState->pvPageR3 3540 || (GCPtr >> PAGE_SHIFT) != (pState->pvPageGC >> PAGE_SHIFT)) 3540 3541 { 3541 3542 int rc = VINF_SUCCESS; … … 3565 3566 } 3566 3567 3567 /* check the segment limit */ 3568 if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit) 3568 /* 3569 * Check the segment limit. 3570 */ 3571 if (!pState->f64Bits && pDis->uInstrAddr + offInstr > pState->cbSegLimit) 3569 3572 return VERR_OUT_OF_SELECTOR_BOUNDS; 3570 3573 3571 /* calc how much we can read */ 3574 /* 3575 * Calc how much we can read. 3576 */ 3572 3577 uint32_t cb = PAGE_SIZE - (GCPtr & PAGE_OFFSET_MASK); 3573 3578 if (!pState->f64Bits) … … 3577 3582 cb = cbSeg; 3578 3583 } 3579 if (cb > cbToRead) 3580 cb = cbToRead; 3581 3582 /* read and advance */ 3583 memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb); 3584 cbToRead -= cb; 3585 if (!cbToRead) 3584 /** @todo read more later. */ 3585 //if (cb > cbMaxRead) - later 3586 // cb = cbMaxRead; 3587 if (cb > cbMinRead) 3588 cb = cbMinRead; 3589 3590 /* 3591 * Read and advance or exit. 3592 */ 3593 memcpy(&pDis->abInstr[offInstr], (uint8_t *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb); 3594 offInstr += (uint8_t)cb; 3595 if (cb >= cbMinRead) 3596 { 3597 pDis->cbCachedInstr = offInstr; 3586 3598 return VINF_SUCCESS; 3587 pbDst += cb; 3588 uSrcAddr += cb; 3599 } 3600 cbMinRead -= (uint8_t)cb; 3601 cbMaxRead -= (uint8_t)cb; 3589 3602 } 3590 3603 } -
trunk/src/VBox/VMM/VMMR3/CSAM.cpp
r41741 r41760 5 5 6 6 /* 7 * Copyright (C) 2006-20 07Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 726 726 * @callback_method_impl{FNDISREADBYTES} 727 727 */ 728 static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDis State, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)729 { 730 PVM pVM = (PVM)pDisState->pvUser;731 RTHCUINTPTR pInstrHC = (RTHCUINTPTR)pDisState->pvUser2;732 RTGCUINTPTR32 pInstrGC = pDisState->uInstrAddr; 733 int orgsize = cbToRead; 734 PVMCPU pVCpu = VMMGetCpu0(pVM);728 static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 729 { 730 PVM pVM = (PVM)pDis->pvUser; 731 int rc = VINF_SUCCESS; 732 733 /** @todo Optimize this code to read more when possible! Add a new PATM call for 734 * reading more than one byte. */ 735 735 736 736 /* We are not interested in patched instructions, so read the original opcode bytes. 737 737 Note! single instruction patches (int3) are checked in CSAMR3AnalyseCallback */ 738 for (int i = 0; i < orgsize; i++)739 { 740 int rc = PATMR3QueryOpcode(pVM, (RTRCPTR)uSrcAddr, pbDst);741 if (RT_FAILURE(rc ))738 while (cbMinRead > 0) 739 { 740 int rc2 = PATMR3QueryOpcode(pVM, (RTRCPTR)pDis->uInstrAddr + offInstr, &pDis->abInstr[offInstr]); 741 if (RT_FAILURE(rc2)) 742 742 break; 743 uSrcAddr++; 744 pbDst++; 745 cbToRead--; 746 } 747 if (cbToRead == 0) 748 return VINF_SUCCESS; 749 750 if (PAGE_ADDRESS(pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbToRead - 1) && !PATMIsPatchGCAddr(pVM, uSrcAddr)) 751 return PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead); 752 753 Assert(pInstrHC); 754 755 /* pInstrHC is the base address; adjust according to the GC pointer. */ 756 pInstrHC = pInstrHC + (uSrcAddr - pInstrGC); 757 758 memcpy(pbDst, (void *)pInstrHC, cbToRead); 759 760 return VINF_SUCCESS; 743 offInstr++; 744 cbMinRead--; 745 cbMaxRead--; 746 } 747 if (cbMinRead > 0) 748 { 749 /* 750 * The current byte isn't a patch instruction byte... 751 */ 752 uint8_t const *pbInstr = (uint8_t const *)pDis->pvUser2; 753 RTUINTPTR uSrcAddr = pDis->uInstrAddr + offInstr; 754 if ( PAGE_ADDRESS(pDis->uInstrAddr) != PAGE_ADDRESS(uSrcAddr + cbMinRead - 1) 755 && !PATMIsPatchGCAddr(pVM, uSrcAddr)) /** @todo does CSAM actually analyze patch code, or is this just a copy&past check? */ 756 { 757 /* Crossed page boundrary, pbInstr is no good.. */ 758 PVMCPU pVCpu = VMMGetCpu0(pVM); 759 rc = PGMPhysSimpleReadGCPtr(pVCpu, &pDis->abInstr[offInstr], uSrcAddr, cbMinRead); 760 offInstr += cbMinRead; 761 } 762 else 763 { 764 /* pbInstr is eqvivalent to uInstrAddr. */ 765 AssertPtr(pbInstr); 766 memcpy(&pDis->abInstr[offInstr], &pbInstr[offInstr], cbMinRead); 767 offInstr += cbMinRead; 768 } 769 } 770 771 pDis->cbCachedInstr = offInstr; 772 return rc; 761 773 } 762 774 -
trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp
r41732 r41760 67 67 void const *pvPageR3; 68 68 /** Pointer to the current page - GC Ptr. */ 69 RTGCPTR pvPageGC;69 RTGCPTR GCPtrPage; 70 70 /** Pointer to the next instruction (relative to GCPtrSegBase). */ 71 71 RTGCUINTPTR GCPtrNext; … … 105 105 pState->cbSegLimit = pSelInfo->cbLimit; 106 106 pState->enmMode = enmMode; 107 pState-> pvPageGC= 0;107 pState->GCPtrPage = 0; 108 108 pState->pvPageR3 = NULL; 109 109 pState->hAs = pSelInfo->fFlags & DBGFSELINFO_FLAGS_HYPER /** @todo Deal more explicitly with RC in DBGFR3Disas*. */ … … 201 201 * @callback_method_impl{FNDISREADBYTES} 202 202 * 203 * @remarks @a uSrcAddris relative to the base address indicated by203 * @remarks The source is relative to the base address indicated by 204 204 * DBGFDISASSTATE::GCPtrSegBase. 205 205 */ 206 static DECLCALLBACK(int) dbgfR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 207 { 208 PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pDisState; 209 Assert(cbToRead > 0); 206 static DECLCALLBACK(int) dbgfR3DisasInstrRead(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 207 { 208 PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pDis; 210 209 for (;;) 211 210 { 212 RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase; 213 214 /* Need to update the page translation? */ 211 RTGCUINTPTR GCPtr = pDis->uInstrAddr + offInstr + pState->GCPtrSegBase; 212 213 /* 214 * Need to update the page translation? 215 */ 215 216 if ( !pState->pvPageR3 216 || (GCPtr >> PAGE_SHIFT) != (pState-> pvPageGC>> PAGE_SHIFT))217 || (GCPtr >> PAGE_SHIFT) != (pState->GCPtrPage >> PAGE_SHIFT)) 217 218 { 218 219 int rc = VINF_SUCCESS; 219 220 220 221 /* translate the address */ 221 pState-> pvPageGC= GCPtr & PAGE_BASE_GC_MASK;222 if (MMHyperIsInsideArea(pState->pVM, pState-> pvPageGC))222 pState->GCPtrPage = GCPtr & PAGE_BASE_GC_MASK; 223 if (MMHyperIsInsideArea(pState->pVM, pState->GCPtrPage)) 223 224 { 224 pState->pvPageR3 = MMHyperRCToR3(pState->pVM, (RTRCPTR)pState-> pvPageGC);225 pState->pvPageR3 = MMHyperRCToR3(pState->pVM, (RTRCPTR)pState->GCPtrPage); 225 226 if (!pState->pvPageR3) 226 227 rc = VERR_INVALID_POINTER; … … 232 233 233 234 if (pState->enmMode <= PGMMODE_PROTECTED) 234 rc = PGMPhysGCPhys2CCPtrReadOnly(pState->pVM, pState-> pvPageGC, &pState->pvPageR3, &pState->PageMapLock);235 rc = PGMPhysGCPhys2CCPtrReadOnly(pState->pVM, pState->GCPtrPage, &pState->pvPageR3, &pState->PageMapLock); 235 236 else 236 rc = PGMPhysGCPtr2CCPtrReadOnly(pState->pVCpu, pState-> pvPageGC, &pState->pvPageR3, &pState->PageMapLock);237 rc = PGMPhysGCPtr2CCPtrReadOnly(pState->pVCpu, pState->GCPtrPage, &pState->pvPageR3, &pState->PageMapLock); 237 238 pState->fLocked = RT_SUCCESS_NP(rc); 238 239 } … … 244 245 } 245 246 246 /* check the segment limit */ 247 if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit) 247 /* 248 * Check the segment limit. 249 */ 250 if (!pState->f64Bits && pDis->uInstrAddr + offInstr > pState->cbSegLimit) 248 251 return VERR_OUT_OF_SELECTOR_BOUNDS; 249 252 250 /* calc how much we can read */ 253 /* 254 * Calc how much we can read, maxing out the read. 255 */ 251 256 uint32_t cb = PAGE_SIZE - (GCPtr & PAGE_OFFSET_MASK); 252 257 if (!pState->f64Bits) … … 256 261 cb = cbSeg; 257 262 } 258 if (cb > cbToRead) 259 cb = cbToRead; 260 261 /* read and advance */ 262 memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb); 263 cbToRead -= cb; 264 if (!cbToRead) 263 if (cb > cbMaxRead) 264 cb = cbMaxRead; 265 266 /* 267 * Read and advance, 268 */ 269 memcpy(&pDis->abInstr[offInstr], (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb); 270 offInstr += (uint8_t)cb; 271 if (cb >= cbMinRead) 272 { 273 pDis->cbCachedInstr = offInstr; 265 274 return VINF_SUCCESS; 266 pbDst += cb; 267 uSrcAddr += cb; 275 } 276 cbMaxRead -= (uint8_t)cb; 277 cbMinRead -= (uint8_t)cb; 268 278 } 269 279 } … … 500 510 else 501 511 { 502 uint32_t cbBits = State.Cpu.cbInstr; 503 uint8_t *pau8Bits = (uint8_t *)alloca(cbBits); 504 rc = dbgfR3DisasInstrRead(&State.Cpu, pau8Bits, GCPtr, cbBits); 505 AssertRC(rc); 512 uint32_t cbInstr = State.Cpu.cbInstr; 513 uint8_t const *pabInstr = State.Cpu.abInstr; 506 514 if (fFlags & DBGF_DISAS_FLAGS_NO_ADDRESS) 507 515 RTStrPrintf(pszOutput, cbOutput, "%.*Rhxs%*s %s", 508 cb Bits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",516 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 509 517 szBuf); 510 518 else if (fRealModeAddress) 511 519 RTStrPrintf(pszOutput, cbOutput, "%04x:%04x %.*Rhxs%*s %s", 512 520 Sel, (unsigned)GCPtr, 513 cb Bits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",521 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 514 522 szBuf); 515 523 else if (Sel == DBGF_SEL_FLAT) … … 518 526 RTStrPrintf(pszOutput, cbOutput, "%RGv %.*Rhxs%*s %s", 519 527 GCPtr, 520 cb Bits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",528 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 521 529 szBuf); 522 530 else 523 531 RTStrPrintf(pszOutput, cbOutput, "%08RX32 %.*Rhxs%*s %s", 524 532 (uint32_t)GCPtr, 525 cb Bits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",533 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 526 534 szBuf); 527 535 } … … 531 539 RTStrPrintf(pszOutput, cbOutput, "%04x:%RGv %.*Rhxs%*s %s", 532 540 Sel, GCPtr, 533 cb Bits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",541 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 534 542 szBuf); 535 543 else 536 544 RTStrPrintf(pszOutput, cbOutput, "%04x:%08RX32 %.*Rhxs%*s %s", 537 545 Sel, (uint32_t)GCPtr, 538 cb Bits, pau8Bits, cbBits < 8 ? (8 - cbBits) * 3 : 0, "",546 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 539 547 szBuf); 540 548 } -
trunk/src/VBox/VMM/VMMR3/PATM.cpp
r41744 r41760 80 80 PVM pVM; 81 81 PPATCHINFO pPatchInfo; 82 R3PTRTYPE(uint8_t *) p InstrHC;82 R3PTRTYPE(uint8_t *) pbInstrHC; 83 83 RTRCPTR pInstrGC; 84 84 uint32_t fReadFlags; … … 534 534 } 535 535 536 DECLCALLBACK(int) patmReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 537 { 538 PATMDISASM *pDisInfo = (PATMDISASM *)pDisState->pvUser; 539 int orgsize = cbToRead; 540 541 Assert(cbToRead); 542 if (cbToRead == 0) 543 return VERR_INVALID_PARAMETER; 544 536 /** 537 * @callback_method_impl{FNDISREADBYTES} 538 */ 539 static DECLCALLBACK(int) patmReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 540 { 541 PATMDISASM *pDisInfo = (PATMDISASM *)pDis->pvUser; 542 543 /** @todo change this to read more! */ 545 544 /* 546 545 * Trap/interrupt handler typically call common code on entry. Which might already have patches inserted. … … 550 549 if (pDisInfo->fReadFlags & PATMREAD_ORGCODE) 551 550 { 552 for ( int i = 0; i < orgsize; i++)553 { 554 int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RT RCPTR)uSrcAddr, pbDst);551 for (;;) 552 { 553 int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTGCPTR32)pDis->uInstrAddr + offInstr, &pDis->abInstr[offInstr]); 555 554 if (RT_FAILURE(rc)) 556 break; 557 uSrcAddr++; 558 pbDst++; 559 cbToRead--; 560 } 561 if (cbToRead == 0) 562 return VINF_SUCCESS; 555 break; /* VERR_PATCH_NOT_FOUND */ 556 offInstr++; 557 cbMinRead--; 558 if (cbMinRead == 0) 559 { 560 pDis->cbCachedInstr = offInstr; 561 return VINF_SUCCESS; 562 } 563 cbMaxRead--; 564 } 565 563 566 #ifdef VBOX_STRICT 564 if ( 565 && 566 { 567 Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr, NULL) == false);568 Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr+cbToRead-1, NULL) == false);567 if ( !(pDisInfo->pPatchInfo->flags & (PATMFL_DUPLICATE_FUNCTION|PATMFL_IDTHANDLER)) 568 && !(pDisInfo->fReadFlags & PATMREAD_NOCHECK)) 569 { 570 Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pDis->uInstrAddr + offInstr, NULL) == false); 571 Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pDis->uInstrAddr + offInstr + cbMinRead-1, NULL) == false); 569 572 } 570 573 #endif 571 574 } 572 575 573 if ( !pDisInfo->pInstrHC 574 || ( PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbToRead - 1) 575 && !PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr))) 576 int rc = VINF_SUCCESS; 577 RTGCPTR32 uSrcAddr = (RTGCPTR32)pDis->uInstrAddr + offInstr; 578 if ( !pDisInfo->pbInstrHC 579 || ( PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbMinRead - 1) 580 && !PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr))) 576 581 { 577 582 Assert(!PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr)); 578 r eturn PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], pbDst, uSrcAddr, cbToRead);579 }580 581 Assert(pDisInfo->pInstrHC);582 583 uint8_t *pInstrHC = pDisInfo->pInstrHC;584 585 Assert(pInstrHC);586 587 /* pInstrHC is the base address; adjust according to the GC pointer. */588 pInstrHC = pInstrHC + (uSrcAddr - pDisInfo->pInstrGC);589 590 memcpy(pbDst, (void *)pInstrHC, cbToRead); 591 592 return VINF_SUCCESS;583 rc = PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], &pDis->abInstr[offInstr], uSrcAddr, cbMinRead); 584 offInstr += cbMinRead; 585 } 586 else 587 { 588 /* pbInstrHC is the base address; adjust according to the GC pointer. */ 589 uint8_t const *pbInstrHC = pDisInfo->pbInstrHC; AssertPtr(pbInstrHC); 590 pbInstrHC += uSrcAddr - pDisInfo->pInstrGC; 591 592 memcpy(&pDis->abInstr[offInstr], pbInstrHC, cbMinRead); 593 offInstr += cbMinRead; 594 } 595 596 pDis->cbCachedInstr = offInstr; 597 return rc; 593 598 } 594 599 … … 600 605 disinfo.pVM = pVM; 601 606 disinfo.pPatchInfo = pPatch; 602 disinfo.p InstrHC= pbInstrHC;607 disinfo.pbInstrHC = pbInstrHC; 603 608 disinfo.pInstrGC = InstrGCPtr32; 604 609 disinfo.fReadFlags = fReadFlags; … … 616 621 disinfo.pVM = pVM; 617 622 disinfo.pPatchInfo = pPatch; 618 disinfo.p InstrHC= pbInstrHC;623 disinfo.pbInstrHC = pbInstrHC; 619 624 disinfo.pInstrGC = InstrGCPtr32; 620 625 disinfo.fReadFlags = fReadFlags; … … 633 638 disinfo.pVM = pVM; 634 639 disinfo.pPatchInfo = pPatch; 635 disinfo.p InstrHC= pbInstrHC;640 disinfo.pbInstrHC = pbInstrHC; 636 641 disinfo.pInstrGC = InstrGCPtr32; 637 642 disinfo.fReadFlags = fReadFlags;
Note:
See TracChangeset
for help on using the changeset viewer.