Changeset 41769 in vbox for trunk/src/VBox/VMM/VMMR3/CSAM.cpp
- Timestamp:
- Jun 15, 2012 7:16:10 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/CSAM.cpp
r41760 r41769 726 726 * @callback_method_impl{FNDISREADBYTES} 727 727 */ 728 static DECLCALLBACK(int) CSAMR3ReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead)728 static DECLCALLBACK(int) csamR3ReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 729 729 { 730 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 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 while (cbMinRead > 0) 739 { 740 int rc2 = PATMR3QueryOpcode(pVM, (RTRCPTR)pDis->uInstrAddr + offInstr, &pDis->abInstr[offInstr]); 741 if (RT_FAILURE(rc2)) 742 break; 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 } 731 732 /* 733 * We are not interested in patched instructions, so read the original opcode bytes. 734 * 735 * Note! single instruction patches (int3) are checked in CSAMR3AnalyseCallback 736 * 737 * Since we're decoding one instruction at the time, we don't need to be 738 * concerned about any patched instructions following the first one. We 739 * could in fact probably skip this PATM call for offInstr != 0. 740 */ 741 size_t cbRead = cbMaxRead; 742 RTUINTPTR uSrcAddr = pDis->uInstrAddr + offInstr; 743 int rc = PATMR3ReadOrgInstr(pVM, pDis->uInstrAddr + offInstr, &pDis->abInstr[offInstr], cbRead, &cbRead); 744 if (RT_SUCCESS(rc)) 745 { 746 if (cbRead >= cbMinRead) 747 { 748 pDis->cbCachedInstr = offInstr + cbRead; 749 return rc; 750 } 751 752 cbMinRead -= cbRead; 753 cbMaxRead -= cbRead; 754 offInstr += cbRead; 755 uSrcAddr += cbRead; 756 } 757 758 /* 759 * The current byte isn't a patch instruction byte. 760 */ 761 uint8_t const *pbSrcInstr = (uint8_t const *)pDis->pvUser2; AssertPtr(pbSrcInstr); 762 if ((pDis->uInstrAddr >> PAGE_SHIFT) == ((uSrcAddr + cbMaxRead - 1) >> PAGE_SHIFT)) 763 { 764 memcpy(&pDis->abInstr[offInstr], &pbSrcInstr[offInstr], cbMaxRead); 765 offInstr += cbMaxRead; 766 rc = VINF_SUCCESS; 767 } 768 else if ( (pDis->uInstrAddr >> PAGE_SHIFT) == ((uSrcAddr + cbMinRead - 1) >> PAGE_SHIFT) 769 || PATMIsPatchGCAddr(pVM, uSrcAddr) /** @todo does CSAM actually analyze patch code, or is this just a copy&past check? */ 770 ) 771 { 772 memcpy(&pDis->abInstr[offInstr], &pbSrcInstr[offInstr], cbMaxRead); 773 offInstr += cbMinRead; 774 rc = VINF_SUCCESS; 775 } 776 else 777 { 778 /* Crossed page boundrary, pbSrcInstr is no good... */ 779 rc = PGMPhysSimpleReadGCPtr(VMMGetCpu0(pVM), &pDis->abInstr[offInstr], uSrcAddr, cbMinRead); 780 offInstr += cbMinRead; 769 781 } 770 782 … … 773 785 } 774 786 775 DECLINLINE(int) CSAMR3DISInstr(PVM pVM, RTRCPTR InstrGC, uint8_t *InstrHC, DISCPUMODE enmCpuMode,787 DECLINLINE(int) csamR3DISInstr(PVM pVM, RTRCPTR InstrGC, uint8_t *InstrHC, DISCPUMODE enmCpuMode, 776 788 PDISCPUSTATE pCpu, uint32_t *pcbInstr, char *pszOutput, size_t cbOutput) 777 789 { 790 /** @todo Put pVM and pbInstrHC in a stack structure and pass it to 791 * csamR3ReadBytes via pvUser. This is the last pvUser2 usage. */ 778 792 pCpu->pvUser2 = InstrHC; 779 793 #ifdef DEBUG 780 return DISInstrToStrEx(InstrGC, enmCpuMode, CSAMR3ReadBytes, pVM, DISOPTYPE_ALL,794 return DISInstrToStrEx(InstrGC, enmCpuMode, csamR3ReadBytes, pVM, DISOPTYPE_ALL, 781 795 pCpu, pcbInstr, pszOutput, cbOutput); 782 796 #else 783 797 /* We are interested in everything except harmless stuff */ 784 798 if (pszOutput) 785 return DISInstrToStrEx(InstrGC, enmCpuMode, CSAMR3ReadBytes, pVM, ~(DISOPTYPE_INVALID | DISOPTYPE_HARMLESS | DISOPTYPE_RRM_MASK),799 return DISInstrToStrEx(InstrGC, enmCpuMode, csamR3ReadBytes, pVM, ~(DISOPTYPE_INVALID | DISOPTYPE_HARMLESS | DISOPTYPE_RRM_MASK), 786 800 pCpu, pcbInstr, pszOutput, cbOutput); 787 return DISInstEx(InstrGC, enmCpuMode, ~(DISOPTYPE_INVALID | DISOPTYPE_HARMLESS | DISOPTYPE_RRM_MASK), CSAMR3ReadBytes, pVM,801 return DISInstEx(InstrGC, enmCpuMode, ~(DISOPTYPE_INVALID | DISOPTYPE_HARMLESS | DISOPTYPE_RRM_MASK), csamR3ReadBytes, pVM, 788 802 pCpu, pcbInstr); 789 803 #endif … … 882 896 Assert(VALID_PTR(pCurInstrHC)); 883 897 884 rc = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,898 rc = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT, 885 899 &cpu, &cbCurInstr, NULL, 0); 886 900 } … … 1065 1079 STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a); 1066 1080 #ifdef DEBUG 1067 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,1081 rc2 = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT, 1068 1082 &cpu, &cbInstr, szOutput, sizeof(szOutput)); 1069 1083 if (RT_SUCCESS(rc2)) Log(("CSAM Call Analysis: %s", szOutput)); 1070 1084 #else 1071 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,1085 rc2 = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, (fCode32) ? DISCPUMODE_32BIT : DISCPUMODE_16BIT, 1072 1086 &cpu, &cbInstr, NULL, 0); 1073 1087 #endif … … 1278 1292 STAM_PROFILE_START(&pVM->csam.s.StatTimeDisasm, a); 1279 1293 #ifdef DEBUG 1280 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, fCode32 ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,1294 rc2 = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, fCode32 ? DISCPUMODE_32BIT : DISCPUMODE_16BIT, 1281 1295 &cpu, &cbInstr, szOutput, sizeof(szOutput)); 1282 1296 if (RT_SUCCESS(rc2)) Log(("CSAM Analysis: %s", szOutput)); 1283 1297 #else 1284 rc2 = CSAMR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, fCode32 ? DISCPUMODE_32BIT : DISCPUMODE_16BIT,1298 rc2 = csamR3DISInstr(pVM, pCurInstrGC, pCurInstrHC, fCode32 ? DISCPUMODE_32BIT : DISCPUMODE_16BIT, 1285 1299 &cpu, &cbInstr, NULL, 0); 1286 1300 #endif
Note:
See TracChangeset
for help on using the changeset viewer.