Changeset 41658 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jun 11, 2012 10:21:44 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 78464
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r41072 r41658 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 … … 282 282 283 283 /** 284 * Read callback for disassembly function; supports reading bytes that cross a page boundary 285 * 286 * @returns VBox status code. 287 * @param pSrc GC source pointer 288 * @param pDest HC destination pointer 289 * @param cb Number of bytes to read 290 * @param dwUserdata Callback specific user data (pDis) 291 * 292 */ 293 static DECLCALLBACK(int) emReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned cb, void *pvUserdata) 294 { 295 PDISCPUSTATE pDis = (PDISCPUSTATE)pvUserdata; 296 PEMDISSTATE pState = (PEMDISSTATE)pDis->apvUserData[0]; 284 * @callback_method_impl{FNDISREADBYTES} 285 */ 286 static DECLCALLBACK(int) emReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 287 { 288 PEMDISSTATE pState = (PEMDISSTATE)pDisState->apvUserData[0]; 297 289 # ifndef IN_RING0 298 290 PVM pVM = pState->pVM; … … 304 296 305 297 if ( pState->GCPtr 306 && pSrc + cb<= pState->GCPtr + sizeof(pState->aOpcode))307 { 308 unsigned offset = pSrc- pState->GCPtr;309 Assert( pSrc>= pState->GCPtr);310 311 for (unsigned i = 0; i < cb ; i++)312 p Dest[i] = pState->aOpcode[offset + i];298 && uSrcAddr + cbToRead <= pState->GCPtr + sizeof(pState->aOpcode)) 299 { 300 unsigned offset = uSrcAddr - pState->GCPtr; 301 Assert(uSrcAddr >= pState->GCPtr); 302 303 for (unsigned i = 0; i < cbToRead; i++) 304 pbDst[i] = pState->aOpcode[offset + i]; 313 305 return VINF_SUCCESS; 314 306 } 315 307 316 rc = PGMPhysSimpleReadGCPtr(pVCpu, p Dest, pSrc, cb);317 AssertMsgRC(rc, ("PGMPhysSimpleReadGCPtr failed for pSrc=%RGv cb=%x rc=%d\n", pSrc, cb, rc));308 rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead); 309 AssertMsgRC(rc, ("PGMPhysSimpleReadGCPtr failed for uSrcAddr=%RTptr cbToRead=%x rc=%d\n", uSrcAddr, cbToRead, rc)); 318 310 # elif defined(IN_RING3) 319 if (!PATMIsPatchGCAddr(pVM, pSrc))320 { 321 int rc = PGMPhysSimpleReadGCPtr(pVCpu, p Dest, pSrc, cb);311 if (!PATMIsPatchGCAddr(pVM, uSrcAddr)) 312 { 313 int rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead); 322 314 AssertRC(rc); 323 315 } 324 316 else 325 memcpy(p Dest, PATMR3GCPtrToHCPtr(pVM, pSrc), cb);317 memcpy(pbDst, PATMR3GCPtrToHCPtr(pVM, uSrcAddr), cbToRead); 326 318 327 319 # elif defined(IN_RC) 328 if (!PATMIsPatchGCAddr(pVM, pSrc))329 { 330 int rc = MMGCRamRead(pVM, p Dest, (void *)(uintptr_t)pSrc, cb);320 if (!PATMIsPatchGCAddr(pVM, uSrcAddr)) 321 { 322 int rc = MMGCRamRead(pVM, pbDst, (void *)(uintptr_t)uSrcAddr, cbToRead); 331 323 if (rc == VERR_ACCESS_DENIED) 332 324 { 333 325 /* Recently flushed; access the data manually. */ 334 rc = PGMPhysSimpleReadGCPtr(pVCpu, p Dest, pSrc, cb);326 rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead); 335 327 AssertRC(rc); 336 328 } 337 329 } 338 330 else /* the hypervisor region is always present. */ 339 memcpy(p Dest, (RTRCPTR)(uintptr_t)pSrc, cb);331 memcpy(pbDst, (RTRCPTR)(uintptr_t)uSrcAddr, cbToRead); 340 332 341 333 # endif /* IN_RING3 */ … … 343 335 } 344 336 345 346 337 #ifndef IN_RC 338 347 339 DECLINLINE(int) emDisCoreOne(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, RTGCUINTPTR InstrGC, uint32_t *pOpsize) 348 340 { … … 467 459 #endif 468 460 469 rc = DISCoreOneEx(GCPtrInstr, SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs, (PCPUMSELREGHID)&pCtxCore->csHid), 461 rc = DISCoreOneEx(GCPtrInstr, 462 SELMGetCpuModeFromSelector(pVCpu, pCtxCore->eflags, pCtxCore->cs, (PCPUMSELREGHID)&pCtxCore->csHid), 470 463 emReadBytes, &State, 471 464 pDis, pcbInstr); … … 659 652 Assert(!CPUMIsGuestIn64BitCode(pVCpu, pRegFrame)); 660 653 /** @todo Rainy day: Test what happens when VERR_EM_INTERPRETER is returned by 661 * this function. F airethat it may guru on us, thus not converted to654 * this function. Fear that it may guru on us, thus not converted to 662 655 * IEM. */ 663 656 -
trunk/src/VBox/VMM/VMMR3/CPUM.cpp
r41310 r41658 906 906 pCPUM->aGuestCpuIdCentaur[i] = pCPUM->GuestCpuIdDef; 907 907 908 /* 908 /* 909 909 * Hypervisor identification. 910 910 * … … 3525 3525 3526 3526 /** 3527 * Instruction reader. 3528 * 3529 * @returns VBox status code. 3530 * @param PtrSrc Address to read from. 3531 * In our case this is relative to the selector pointed to by the 2nd user argument of uDisCpu. 3532 * @param pu8Dst Where to store the bytes. 3533 * @param cbRead Number of bytes to read. 3534 * @param uDisCpu Pointer to the disassembler cpu state. 3535 * In this context it's always pointer to the Core of a DBGFDISASSTATE. 3536 */ 3537 static DECLCALLBACK(int) cpumR3DisasInstrRead(RTUINTPTR PtrSrc, uint8_t *pu8Dst, unsigned cbRead, void *uDisCpu) 3538 { 3539 PDISCPUSTATE pCpu = (PDISCPUSTATE)uDisCpu; 3540 PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pCpu->apvUserData[0]; 3541 Assert(cbRead > 0); 3527 * @callback_method_impl{FNDISREADBYTES} 3528 */ 3529 static DECLCALLBACK(int) cpumR3DisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 3530 { 3531 PCPUMDISASSTATE pState = (PCPUMDISASSTATE)pDisState->apvUserData[0]; 3532 Assert(cbToRead > 0); 3542 3533 for (;;) 3543 3534 { 3544 RTGCUINTPTR GCPtr = PtrSrc+ pState->GCPtrSegBase;3535 RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase; 3545 3536 3546 3537 /* Need to update the page translation? */ … … 3575 3566 3576 3567 /* check the segment limit */ 3577 if (!pState->f64Bits && PtrSrc> pState->cbSegLimit)3568 if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit) 3578 3569 return VERR_OUT_OF_SELECTOR_BOUNDS; 3579 3570 … … 3586 3577 cb = cbSeg; 3587 3578 } 3588 if (cb > cb Read)3589 cb = cb Read;3579 if (cb > cbToRead) 3580 cb = cbToRead; 3590 3581 3591 3582 /* read and advance */ 3592 memcpy(p u8Dst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);3593 cb Read -= cb;3594 if (!cb Read)3583 memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb); 3584 cbToRead -= cb; 3585 if (!cbToRead) 3595 3586 return VINF_SUCCESS; 3596 p u8Dst+= cb;3597 PtrSrc+= cb;3587 pbDst += cb; 3588 uSrcAddr += cb; 3598 3589 } 3599 3590 } … … 3629 3620 * Get selector information. 3630 3621 */ 3622 DISCPUMODE enmDisCpuMode; 3631 3623 if ( (pCtx->cr0 & X86_CR0_PE) 3632 3624 && pCtx->eflags.Bits.u1VM == 0) … … 3638 3630 State.GCPtrSegEnd = pCtx->csHid.u32Limit + 1 + (RTGCUINTPTR)pCtx->csHid.u64Base; 3639 3631 State.cbSegLimit = pCtx->csHid.u32Limit; 3640 pCpu->mode= (State.f64Bits)3632 enmDisCpuMode = (State.f64Bits) 3641 3633 ? CPUMODE_64BIT 3642 3634 : pCtx->csHid.Attr.n.u1DefBig … … 3667 3659 State.GCPtrSegEnd = SelInfo.cbLimit + 1 + (RTGCUINTPTR)SelInfo.GCPtrBase; 3668 3660 State.cbSegLimit = SelInfo.cbLimit; 3669 pCpu->mode= SelInfo.u.Raw.Gen.u1DefBig ? CPUMODE_32BIT : CPUMODE_16BIT;3661 enmDisCpuMode = SelInfo.u.Raw.Gen.u1DefBig ? CPUMODE_32BIT : CPUMODE_16BIT; 3670 3662 } 3671 3663 } … … 3673 3665 { 3674 3666 /* real or V86 mode */ 3675 pCpu->mode= CPUMODE_16BIT;3667 enmDisCpuMode = CPUMODE_16BIT; 3676 3668 State.GCPtrSegBase = pCtx->cs * 16; 3677 3669 State.GCPtrSegEnd = 0xFFFFFFFF; … … 3682 3674 * Disassemble the instruction. 3683 3675 */ 3684 pCpu->pfnReadBytes = cpumR3DisasInstrRead;3685 pCpu->apvUserData[0] = &State;3686 3687 3676 uint32_t cbInstr; 3688 3677 #ifndef LOG_ENABLED 3689 rc = DISInstr (pCpu, GCPtrPC, 0, &cbInstr, NULL);3678 rc = DISInstrWithReader(GCPtrPC, enmDisCpuMode, cpumR3DisasInstrRead, &State, pCpu, &cbInstr, NULL); 3690 3679 if (RT_SUCCESS(rc)) 3691 3680 { 3692 3681 #else 3693 3682 char szOutput[160]; 3694 rc = DISInstr (pCpu, GCPtrPC, 0, &cbInstr, &szOutput[0]);3683 rc = DISInstrWithReader(GCPtrPC, enmDisCpuMode, cpumR3DisasInstrRead, &State, pCpu, &cbInstr, szOutput); 3695 3684 if (RT_SUCCESS(rc)) 3696 3685 { -
trunk/src/VBox/VMM/VMMR3/CSAM.cpp
r40449 r41658 724 724 725 725 /** 726 * Read callback for disassembly function; supports reading bytes that cross a page boundary 727 * 728 * @returns VBox status code. 729 * @param pSrc GC source pointer 730 * @param pDest HC destination pointer 731 * @param size Number of bytes to read 732 * @param dwUserdata Callback specific user data (pCpu) 733 * 734 */ 735 static DECLCALLBACK(int) CSAMR3ReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata) 736 { 737 DISCPUSTATE *pCpu = (DISCPUSTATE *)pvUserdata; 738 PVM pVM = (PVM)pCpu->apvUserData[0]; 739 RTHCUINTPTR pInstrHC = (RTHCUINTPTR)pCpu->apvUserData[1]; 740 RTGCUINTPTR32 pInstrGC = (uintptr_t)pCpu->apvUserData[2]; 741 int orgsize = size; 742 Assert(pVM->cCpus == 1); 743 PVMCPU pVCpu = VMMGetCpu0(pVM); 744 745 /* We are not interested in patched instructions, so read the original opcode bytes. */ 746 /** @note single instruction patches (int3) are checked in CSAMR3AnalyseCallback */ 747 for (int i=0;i<orgsize;i++) 748 { 749 int rc = PATMR3QueryOpcode(pVM, (RTRCPTR)pSrc, pDest); 750 if (RT_SUCCESS(rc)) 751 { 752 pSrc++; 753 pDest++; 754 size--; 755 } 756 else 726 * @callback_method_impl{FNDISREADBYTES} 727 */ 728 static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 729 { 730 PVM pVM = (PVM)pDisState->apvUserData[0]; 731 RTHCUINTPTR pInstrHC = (RTHCUINTPTR)pDisState->apvUserData[1]; 732 RTGCUINTPTR32 pInstrGC = pDisState->uInstrAddr; 733 int orgsize = cbToRead; 734 PVMCPU pVCpu = VMMGetCpu0(pVM); 735 736 /* We are not interested in patched instructions, so read the original opcode bytes. 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)) 757 742 break; 758 } 759 if (size == 0) 743 uSrcAddr++; 744 pbDst++; 745 cbToRead--; 746 } 747 if (cbToRead == 0) 760 748 return VINF_SUCCESS; 761 749 762 if (PAGE_ADDRESS(pInstrGC) != PAGE_ADDRESS(pSrc + size - 1) && !PATMIsPatchGCAddr(pVM, pSrc)) 763 { 764 return PGMPhysSimpleReadGCPtr(pVCpu, pDest, pSrc, size); 765 } 766 else 767 { 768 Assert(pInstrHC); 769 770 /* pInstrHC is the base address; adjust according to the GC pointer. */ 771 pInstrHC = pInstrHC + (pSrc - pInstrGC); 772 773 memcpy(pDest, (void *)pInstrHC, size); 774 } 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); 775 759 776 760 return VINF_SUCCESS; 777 761 } 778 762 779 inline int CSAMR3DISInstr(PVM pVM, DISCPUSTATE *pCpu, RTRCPTR InstrGC, uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput) 780 { 781 (pCpu)->pfnReadBytes = CSAMR3ReadBytes; 782 (pCpu)->apvUserData[0] = pVM; 763 DECLINLINE(int) CSAMR3DISInstr(PVM pVM, RTRCPTR InstrGC, uint8_t *InstrHC, DISCPUMODE enmCpuMode, 764 PDISCPUSTATE pCpu, uint32_t *pcbInstr, char *pszOutput) 765 { 783 766 (pCpu)->apvUserData[1] = InstrHC; 784 767 (pCpu)->apvUserData[2] = (void *)(uintptr_t)InstrGC; Assert(sizeof(InstrGC) <= sizeof(pCpu->apvUserData[0])); 785 768 #ifdef DEBUG 786 return DISInstrEx(pCpu, InstrGC, 0, pOpsize, pszOutput, OPTYPE_ALL); 769 return DISInstrEx(InstrGC, 0, enmCpuMode, CSAMR3ReadBytes, pVM, OPTYPE_ALL, 770 pCpu, pcbInstr, pszOutput); 787 771 #else 788 772 /* We are interested in everything except harmless stuff */ 789 return DISInstrEx(pCpu, InstrGC, 0, pOpsize, pszOutput, ~(OPTYPE_INVALID | OPTYPE_HARMLESS | OPTYPE_RRM_MASK)); 773 return DISInstrEx(InstrGC, 0, enmCpuMode, CSAMR3ReadBytes, pVM, ~(OPTYPE_INVALID | OPTYPE_HARMLESS | OPTYPE_RRM_MASK), 774 pCpu, pcbInstr, pszOutput); 790 775 #endif 791 776 } … … 883 868 Assert(VALID_PTR(pCurInstrHC)); 884 869 885 cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;886 rc = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL);870 rc = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT, 871 &cpu, &opsize, NULL); 887 872 } 888 873 AssertRC(rc); … … 1054 1039 * - push ebp after the filler (can extend this later); aligned at at least a 4 byte boundary 1055 1040 */ 1056 for (int j =0;j<16;j++)1041 for (int j = 0; j < 16; j++) 1057 1042 { 1058 1043 uint8_t *pCurInstrHC = (uint8_t *)CSAMGCVirtToHCVirt(pVM, pCacheRec, pCurInstrGC); … … 1064 1049 Assert(VALID_PTR(pCurInstrHC)); 1065 1050 1066 cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;1067 1051 STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a); 1068 1052 #ifdef DEBUG 1069 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, szOutput); 1053 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT, 1054 &cpu, &opsize, szOutput); 1070 1055 if (RT_SUCCESS(rc2)) Log(("CSAM Call Analysis: %s", szOutput)); 1071 1056 #else 1072 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL); 1057 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT, 1058 &cpu, &opsize, NULL); 1073 1059 #endif 1074 1060 STAM_PROFILE_STOP(&pVM->csam.s.StatTimeDisasm, a); … … 1276 1262 Assert(VALID_PTR(pCurInstrHC)); 1277 1263 1278 cpu.mode = (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT;1279 1264 STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a); 1280 1265 #ifdef DEBUG 1281 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, szOutput); 1266 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT, 1267 &cpu, &opsize, szOutput); 1282 1268 if (RT_SUCCESS(rc2)) Log(("CSAM Analysis: %s", szOutput)); 1283 1269 #else 1284 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, &opsize, NULL); 1270 rc2 = CSAMR3DISInstr(pVM, &cpu, pCurInstrGC, pCurInstrHC, (fCode32) ? CPUMODE_32BIT : CPUMODE_16BIT, 1271 &cpu, &opsize, NULL); 1285 1272 #endif 1286 1273 STAM_PROFILE_STOP(&pVM->csam.s.StatTimeDisasm, a); -
trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp
r38838 r41658 82 82 * Internal Functions * 83 83 *******************************************************************************/ 84 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTUINTPTR pSrc, uint8_t *pDest, uint32_t size, void *pvUserdata);84 static FNDISREADBYTES dbgfR3DisasInstrRead; 85 85 86 86 … … 199 199 200 200 /** 201 * Instruction reader. 202 * 203 * @returns VBox status code. (Why this is a int32_t and not just an int is also beyond me.) 204 * @param PtrSrc Address to read from. 205 * In our case this is relative to the selector pointed to by the 2nd user argument of uDisCpu. 206 * @param pu8Dst Where to store the bytes. 207 * @param cbRead Number of bytes to read. 208 * @param uDisCpu Pointer to the disassembler cpu state. (Why this is a VBOXHUINTPTR is beyond me...) 209 * In this context it's always pointer to the Core of a DBGFDISASSTATE. 210 */ 211 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTUINTPTR PtrSrc, uint8_t *pu8Dst, uint32_t cbRead, void *pvDisCpu) 212 { 213 PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pvDisCpu; 214 Assert(cbRead > 0); 201 * @callback_method_impl{FNDISREADBYTES} 202 * 203 * @remarks @a uSrcAddr is relative to the base address indicated by 204 * DBGFDISASSTATE::GCPtrSegBase. 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); 215 210 for (;;) 216 211 { 217 RTGCUINTPTR GCPtr = PtrSrc+ pState->GCPtrSegBase;212 RTGCUINTPTR GCPtr = uSrcAddr + pState->GCPtrSegBase; 218 213 219 214 /* Need to update the page translation? */ … … 250 245 251 246 /* check the segment limit */ 252 if (!pState->f64Bits && PtrSrc> pState->cbSegLimit)247 if (!pState->f64Bits && uSrcAddr > pState->cbSegLimit) 253 248 return VERR_OUT_OF_SELECTOR_BOUNDS; 254 249 … … 261 256 cb = cbSeg; 262 257 } 263 if (cb > cb Read)264 cb = cb Read;258 if (cb > cbToRead) 259 cb = cbToRead; 265 260 266 261 /* read and advance */ 267 memcpy(p u8Dst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb);268 cb Read -= cb;269 if (!cb Read)262 memcpy(pbDst, (char *)pState->pvPageR3 + (GCPtr & PAGE_OFFSET_MASK), cb); 263 cbToRead -= cb; 264 if (!cbToRead) 270 265 return VINF_SUCCESS; 271 p u8Dst+= cb;272 PtrSrc+= cb;266 pbDst += cb; 267 uSrcAddr += cb; 273 268 } 274 269 } … … 507 502 uint32_t cbBits = State.Cpu.opsize; 508 503 uint8_t *pau8Bits = (uint8_t *)alloca(cbBits); 509 rc = dbgfR3DisasInstrRead( GCPtr, pau8Bits, cbBits, &State);504 rc = dbgfR3DisasInstrRead(&State.Cpu, pau8Bits, GCPtr, cbBits); 510 505 AssertRC(rc); 511 506 if (fFlags & DBGF_DISAS_FLAGS_NO_ADDRESS) -
trunk/src/VBox/VMM/VMMR3/PATM.cpp
r39417 r41658 517 517 } 518 518 519 /** 520 * Read callback for disassembly function; supports reading bytes that cross a page boundary 521 * 522 * @returns VBox status code. 523 * @param pSrc GC source pointer 524 * @param pDest HC destination pointer 525 * @param size Number of bytes to read 526 * @param pvUserdata Callback specific user data (pCpu) 527 * 528 */ 529 int patmReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata) 530 { 531 DISCPUSTATE *pCpu = (DISCPUSTATE *)pvUserdata; 532 PATMDISASM *pDisInfo = (PATMDISASM *)pCpu->apvUserData[0]; 533 int orgsize = size; 534 535 Assert(size); 536 if (size == 0) 519 DECLCALLBACK(int) patmReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 520 { 521 PATMDISASM *pDisInfo = (PATMDISASM *)pDisState->apvUserData[0]; 522 int orgsize = cbToRead; 523 524 Assert(cbToRead); 525 if (cbToRead == 0) 537 526 return VERR_INVALID_PARAMETER; 538 527 … … 544 533 if (pDisInfo->fReadFlags & PATMREAD_ORGCODE) 545 534 { 546 for (int i=0;i<orgsize;i++) 547 { 548 int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTRCPTR)pSrc, pDest); 549 if (RT_SUCCESS(rc)) 550 { 551 pSrc++; 552 pDest++; 553 size--; 554 } 555 else break; 556 } 557 if (size == 0) 535 for (int i = 0; i < orgsize; i++) 536 { 537 int rc = PATMR3QueryOpcode(pDisInfo->pVM, (RTRCPTR)uSrcAddr, pbDst); 538 if (RT_FAILURE(rc)) 539 break; 540 uSrcAddr++; 541 pbDst++; 542 cbToRead--; 543 } 544 if (cbToRead == 0) 558 545 return VINF_SUCCESS; 559 546 #ifdef VBOX_STRICT … … 561 548 && !(pDisInfo->fReadFlags & PATMREAD_NOCHECK)) 562 549 { 563 Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pSrc, NULL) == false);564 Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, pSrc+size-1, NULL) == false);550 Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr, NULL) == false); 551 Assert(PATMR3IsInsidePatchJump(pDisInfo->pVM, uSrcAddr+cbToRead-1, NULL) == false); 565 552 } 566 553 #endif … … 568 555 569 556 if ( !pDisInfo->pInstrHC 570 || ( PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(pSrc + size - 1) 571 && !PATMIsPatchGCAddr(pDisInfo->pVM, pSrc))) 572 { 573 Assert(!PATMIsPatchGCAddr(pDisInfo->pVM, pSrc)); 574 return PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], pDest, pSrc, size); 575 } 576 else 577 { 578 Assert(pDisInfo->pInstrHC); 579 580 uint8_t *pInstrHC = pDisInfo->pInstrHC; 581 582 Assert(pInstrHC); 583 584 /* pInstrHC is the base address; adjust according to the GC pointer. */ 585 pInstrHC = pInstrHC + (pSrc - pDisInfo->pInstrGC); 586 587 memcpy(pDest, (void *)pInstrHC, size); 588 } 557 || ( PAGE_ADDRESS(pDisInfo->pInstrGC) != PAGE_ADDRESS(uSrcAddr + cbToRead - 1) 558 && !PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr))) 559 { 560 Assert(!PATMIsPatchGCAddr(pDisInfo->pVM, uSrcAddr)); 561 return PGMPhysSimpleReadGCPtr(&pDisInfo->pVM->aCpus[0], pbDst, uSrcAddr, cbToRead); 562 } 563 564 Assert(pDisInfo->pInstrHC); 565 566 uint8_t *pInstrHC = pDisInfo->pInstrHC; 567 568 Assert(pInstrHC); 569 570 /* pInstrHC is the base address; adjust according to the GC pointer. */ 571 pInstrHC = pInstrHC + (uSrcAddr - pDisInfo->pInstrGC); 572 573 memcpy(pbDst, (void *)pInstrHC, cbToRead); 589 574 590 575 return VINF_SUCCESS; … … 2837 2822 if (pPatch->flags & PATMFL_INT3_REPLACEMENT_BLOCK) 2838 2823 { 2839 /*uint8_t ASMInt3 = 0xCC; - unused */2824 /*uint8_t bASMInt3 = 0xCC; - unused */ 2840 2825 2841 2826 Log(("PATMR3PatchBlock %RRv -> int 3 callable patch.\n", pPatch->pPrivInstrGC)); … … 3786 3771 static int patmActivateInt3Patch(PVM pVM, PPATCHINFO pPatch) 3787 3772 { 3788 uint8_t ASMInt3 = 0xCC;3773 uint8_t bASMInt3 = 0xCC; 3789 3774 int rc; 3790 3775 … … 3793 3778 3794 3779 /* Replace first opcode byte with 'int 3'. */ 3795 rc = PGMPhysSimpleDirtyWriteGCPtr(VMMGetCpu0(pVM), pPatch->pPrivInstrGC, & ASMInt3, sizeof(ASMInt3));3780 rc = PGMPhysSimpleDirtyWriteGCPtr(VMMGetCpu0(pVM), pPatch->pPrivInstrGC, &bASMInt3, sizeof(bASMInt3)); 3796 3781 AssertRC(rc); 3797 3782 3798 pPatch->cbPatchJump = sizeof( ASMInt3);3783 pPatch->cbPatchJump = sizeof(bASMInt3); 3799 3784 3800 3785 return rc; … … 3823 3808 3824 3809 /** 3825 * Replace an instruction with a breakpoint (0xCC), that is handled dynamically in the guest context. 3810 * Replace an instruction with a breakpoint (0xCC), that is handled dynamically 3811 * in the raw-mode context. 3826 3812 * 3827 3813 * @returns VBox status code. … … 3835 3821 * 3836 3822 */ 3837 VMMR3DECL(int) PATMR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu, PPATCHINFO pPatch) 3838 { 3839 uint8_t ASMInt3 = 0xCC; 3823 VMMR3DECL(int) PATMR3PatchInstrInt3(PVM pVM, RTRCPTR pInstrGC, R3PTRTYPE(uint8_t *) pInstrHC, DISCPUSTATE *pCpu, 3824 PPATCHINFO pPatch) 3825 { 3826 uint8_t bASMInt3 = 0xCC; 3840 3827 int rc; 3841 3828 … … 3855 3842 rc = PGMPhysSimpleReadGCPtr(VMMGetCpu0(pVM), pPatch->aPrivInstr, pPatch->pPrivInstrGC, pPatch->cbPrivInstr); 3856 3843 AssertRC(rc); 3857 pPatch->cbPatchJump = sizeof( ASMInt3); /* bit of a misnomer in this case; size of replacement instruction. */3844 pPatch->cbPatchJump = sizeof(bASMInt3); /* bit of a misnomer in this case; size of replacement instruction. */ 3858 3845 3859 3846 pPatch->flags |= PATMFL_INT3_REPLACEMENT; -
trunk/src/VBox/VMM/VMMR3/VMMSwitcher.cpp
r39402 r41658 837 837 uint32_t cbInstr = 0; 838 838 char szDisas[256]; 839 if (RT_SUCCESS(DISInstr(&Cpu, (uintptr_t)pu8CodeR3 + offCode, uBase - (uintptr_t)pu8CodeR3, &cbInstr, szDisas))) 839 if (RT_SUCCESS(DISInstrWithOff(&Cpu, (uintptr_t)pu8CodeR3 + offCode, uBase - (uintptr_t)pu8CodeR3, 840 &cbInstr, szDisas))) 840 841 RTLogPrintf(" %04x: %s", offCode, szDisas); //for whatever reason szDisas includes '\n'. 841 842 else -
trunk/src/VBox/VMM/VMMRC/PATMRC.cpp
r40453 r41658 1 1 /* $Id$ */ 2 2 /** @file 3 * PATM - Dynamic Guest OS Patching Manager - Guest Context3 * PATM - Dynamic Guest OS Patching Manager - Raw-mode Context. 4 4 */ 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 … … 21 21 *******************************************************************************/ 22 22 #define LOG_GROUP LOG_GROUP_PATM 23 #include <VBox/vmm/patm.h> 23 24 #include <VBox/vmm/cpum.h> 24 25 #include <VBox/vmm/stam.h> 25 #include <VBox/vmm/patm.h>26 26 #include <VBox/vmm/pgm.h> 27 27 #include <VBox/vmm/mm.h> 28 #include <VBox/sup.h> 28 #include <VBox/vmm/em.h> 29 #ifdef VBOX_WITH_IEM 30 # include <VBox/vmm/iem.h> 31 #endif 32 #include <VBox/vmm/selm.h> 29 33 #include <VBox/vmm/mm.h> 30 #include <VBox/param.h>31 #include <iprt/avl.h>32 34 #include "PATMInternal.h" 33 35 #include "PATMA.h" … … 36 38 #include <VBox/dis.h> 37 39 #include <VBox/disopcode.h> 38 #include <VBox/vmm/em.h>39 40 #include <VBox/err.h> 40 #include <VBox/vmm/selm.h>41 41 #include <VBox/log.h> 42 42 #include <iprt/assert.h> … … 441 441 * Checks if the int 3 was caused by a patched instruction 442 442 * 443 * @returns VBox status 443 * @returns Strict VBox status, includes all statuses that 444 * EMInterpretInstructionDisasState and 445 * @retval VINF_SUCCESS 446 * @retval VINF_PATM_PATCH_INT3 447 * @retval VINF_EM_RAW_EMULATE_INSTR 444 448 * 445 449 * @param pVM The VM handle. 446 450 * @param pCtxCore The relevant core context. 447 451 */ 448 VMM DECL(int) PATMHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame)452 VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame) 449 453 { 450 454 PPATMPATCHREC pRec; … … 456 460 if (PATMIsPatchGCAddr(pVM, pRegFrame->eip)) 457 461 { 458 /* @note hardcoded assumption about it being a single byte int 3 instruction. */462 /* Note! Hardcoded assumption about it being a single byte int 3 instruction. */ 459 463 pRegFrame->eip--; 460 464 return VINF_PATM_PATCH_INT3; … … 512 516 return VINF_EM_RAW_EMULATE_INSTR; 513 517 } 514 rc = DISCoreOne(&cpu, (uintptr_t)&pRec->patch.aPrivInstr[0], &cbOp); 518 519 #ifdef VBOX_WITH_IEM 520 VBOXSTRICTRC rcStrict; 521 rcStrict = IEMExecOneWithOpcodes(VMMGetCpu0(pVM), pRegFrame, pRec->patch.pPrivInstrGC, 522 pRec->patch.aPrivInstr, pRec->patch.cbPrivInstr); 523 rc = VBOXSTRICTRC_TODO(rcStrict); 524 #else 525 rc = DISCoreOneEx((uintptr_t)&pRec->patch.aPrivInstr[0], cpu.mode, NULL /*pfnReadBytes*/, NULL /*pvUser*/, 526 &cpu, &cbOp); 515 527 if (RT_FAILURE(rc)) 516 528 { … … 523 535 rc = EMInterpretInstructionDisasState(VMMGetCpu0(pVM), &cpu, pRegFrame, 0 /* not relevant here */, 524 536 EMCODETYPE_SUPERVISOR); 525 if (rc != VINF_SUCCESS) 537 #endif 538 if (RT_FAILURE(rc)) 526 539 { 527 540 Log(("EMInterpretInstructionCPU failed with %Rrc\n", rc)); … … 530 543 return VINF_EM_RAW_EMULATE_INSTR; 531 544 } 532 return VINF_SUCCESS;545 return rc; 533 546 } 534 547 } -
trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
r40486 r41658 421 421 && !pRegFrame->eflags.Bits.u1VM) 422 422 { 423 rc = PATMHandleInt3PatchTrap(pVM, pRegFrame); 424 if (rc == VINF_SUCCESS || rc == VINF_EM_RAW_EMULATE_INSTR || rc == VINF_PATM_PATCH_INT3 || rc == VINF_PATM_DUPLICATE_FUNCTION) 423 rc = PATMRCHandleInt3PatchTrap(pVM, pRegFrame); 424 if ( rc == VINF_SUCCESS 425 || rc == VINF_EM_RAW_EMULATE_INSTR 426 || rc == VINF_PATM_PATCH_INT3 427 || rc == VINF_PATM_DUPLICATE_FUNCTION) 425 428 { 426 429 rc = trpmGCExitTrap(pVM, pVCpu, rc, pRegFrame); … … 745 748 { 746 749 /* Int 3 replacement patch? */ 747 if (PATM HandleInt3PatchTrap(pVM, pRegFrame) == VINF_SUCCESS)750 if (PATMRCHandleInt3PatchTrap(pVM, pRegFrame) == VINF_SUCCESS) 748 751 { 749 752 AssertFailed(); -
trunk/src/VBox/VMM/include/PATMInternal.h
r36801 r41658 273 273 /** Size of the patch jump in the guest code. */ 274 274 uint32_t cbPatchJump; 275 /* Only valid for PATMFL_JUMP_CONFLICT patches */275 /** Only valid for PATMFL_JUMP_CONFLICT patches */ 276 276 RTRCPTR pPatchJumpDestGC; 277 277 /** Offset of the patch code from the beginning of the patch memory area. */ … … 675 675 676 676 677 /** 678 * Read callback for disassembly function; supports reading bytes that cross a page boundary 679 * 680 * @returns VBox status code. 681 * @param pSrc GC source pointer 682 * @param pDest HC destination pointer 683 * @param size Number of bytes to read 684 * @param pvUserdata Callback specific user data (pCpu) 685 * 686 */ 687 int patmReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned size, void *pvUserdata); 677 FNDISREADBYTES patmReadBytes; 688 678 689 679 … … 706 696 } PATMDISASM, *PPATMDISASM; 707 697 708 inline bool PATMR3DISInstr(PVM pVM, PPATCHINFO pPatch, DISCPUSTATE *pCpu, RTRCPTR InstrGC,709 uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput,710 uint32_t fReadFlags = PATMREAD_ORGCODE)698 DECLINLINE(bool) PATMR3DISInstr(PVM pVM, PPATCHINFO pPatch, PDISCPUSTATE pCpu, RTRCPTR InstrGC, 699 uint8_t *InstrHC, uint32_t *pOpsize, char *pszOutput, 700 uint32_t fReadFlags = PATMREAD_ORGCODE) 711 701 { 712 702 PATMDISASM disinfo; … … 718 708 (pCpu)->pfnReadBytes = patmReadBytes; 719 709 (pCpu)->apvUserData[0] = &disinfo; 720 return RT_SUCCESS(DISInstr (pCpu, InstrGC, 0, pOpsize, pszOutput));710 return RT_SUCCESS(DISInstrWithReader(InstrGC, pCpu->mode, patmReadBytes, &disinfo, pCpu, pOpsize, pszOutput)); 721 711 } 722 712 #endif /* !IN_RC */ -
trunk/src/VBox/VMM/testcase/tstCompiler.cpp
r38636 r41658 204 204 205 205 memset(&Cpu, 0, sizeof(Cpu)); 206 Cpu.mode = CPUMODE_32BIT;207 206 do 208 207 { 209 208 char sz[256]; 210 209 uint32_t cbInstr = 0; 211 if (RT_SUCCESS(DISInstr( &Cpu, uCur, 0, &cbInstr, sz)))210 if (RT_SUCCESS(DISInstr(uCur, CPUMODE_32BIT, &Cpu, &cbInstr, sz))) 212 211 { 213 212 RTPrintf("tstBitFields: %s", sz);
Note:
See TracChangeset
for help on using the changeset viewer.