Changeset 41760 in vbox
- Timestamp:
- Jun 15, 2012 3:56:20 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
-
include/VBox/dis.h (modified) (1 diff)
-
src/VBox/Devices/PC/BIOS-new/MakeDebianBiosAssembly.cpp (modified) (1 diff)
-
src/VBox/Disassembler/DisasmCore.cpp (modified) (3 diffs)
-
src/VBox/Disassembler/testcase/tstDisasm-2.cpp (modified) (3 diffs)
-
src/VBox/Runtime/testcase/tstLdr-3.cpp (modified) (1 diff)
-
src/VBox/Runtime/testcase/tstLdr-4.cpp (modified) (1 diff)
-
src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMAll/EMAll.cpp (modified) (4 diffs)
-
src/VBox/VMM/VMMR3/CPUM.cpp (modified) (4 diffs)
-
src/VBox/VMM/VMMR3/CSAM.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMR3/DBGFDisas.cpp (modified) (9 diffs)
-
src/VBox/VMM/VMMR3/PATM.cpp (modified) (6 diffs)
-
src/VBox/VMM/include/PATMInternal.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/dis.h
r41747 r41760 497 497 498 498 /** 499 * Callback for reading opcode bytes. 500 * 501 * @param pDisState Pointer to the CPU state. The primary user argument 502 * can be retrived from DISCPUSTATE::pvUser. If 503 * more is required these can be passed in the 504 * subsequent slots. 505 * @param pbDst Pointer to output buffer. 506 * @param uSrcAddr The address to start reading at. 507 * @param cbToRead The number of bytes to read. 508 */ 509 typedef DECLCALLBACK(int) FNDISREADBYTES(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead); 499 * Callback for reading instruction bytes. 500 * 501 * @returns VBox status code, bytes in DISCPUSTATE::abInstr and byte count in 502 * DISCPUSTATE::cbCachedInstr. 503 * @param pDis Pointer to the disassembler state. The user 504 * argument can be found in DISCPUSTATE::pvUser if 505 * needed. 506 * @param offInstr The offset relative to the start of the instruction. 507 * 508 * To get the source address, add this to 509 * DISCPUSTATE::uInstrAddr. 510 * 511 * To calculate the destination buffer address, use it 512 * as an index into DISCPUSTATE::abInstr. 513 * 514 * @param cbMinRead The minimum number of bytes to read. 515 * @param cbMaxRead The maximum number of bytes that may be read. 516 */ 517 typedef DECLCALLBACK(int) FNDISREADBYTES(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead); 510 518 /** Pointer to a opcode byte reader. */ 511 519 typedef FNDISREADBYTES *PFNDISREADBYTES; -
trunk/src/VBox/Devices/PC/BIOS-new/MakeDebianBiosAssembly.cpp
r41734 r41760 908 908 * @remarks @a uSrcAddr is the flat address. 909 909 */ 910 static DECLCALLBACK(int) disReadOpcodeBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 911 { 912 if (uSrcAddr + cbToRead >= VBOX_BIOS_BASE + _64K) 913 { 914 RT_BZERO(pbDst, cbToRead); 915 if (uSrcAddr >= VBOX_BIOS_BASE + _64K) 910 static DECLCALLBACK(int) disReadOpcodeBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 911 { 912 RTUINTPTR offBios = pDis->uInstrAddr + offInstr - VBOX_BIOS_BASE; 913 size_t cbToRead = cbMaxRead; 914 if (offBios + cbToRead > _64K) 915 { 916 if (offBios >= _64K) 916 917 cbToRead = 0; 917 918 else 918 cbToRead = VBOX_BIOS_BASE + _64K - uSrcAddr;919 } 920 memcpy( pbDst, &g_pbImg[uSrcAddr - VBOX_BIOS_BASE], cbToRead);921 NOREF(pDisState);919 cbToRead = _64K - offBios; 920 } 921 memcpy(&pDis->abInstr[offInstr], &g_pbImg[offBios], cbToRead); 922 pDis->cbCachedInstr = offInstr + cbToRead; 922 923 return VINF_SUCCESS; 923 924 } -
trunk/src/VBox/Disassembler/DisasmCore.cpp
r41753 r41760 65 65 static uint32_t disReadDWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress); 66 66 static uint64_t disReadQWord(PDISCPUSTATE pCpu, RTUINTPTR pAddress); 67 static DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE p Cpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead);67 static DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead); 68 68 69 69 … … 2390 2390 2391 2391 2392 static DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE p Cpu, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)2392 static DECLCALLBACK(int) disReadBytesDefault(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 2393 2393 { 2394 2394 #ifdef IN_RING0 2395 2395 AssertMsgFailed(("disReadWord with no read callback in ring 0!!\n")); 2396 RT_BZERO(pbDst, cbToRead); 2396 RT_BZERO(&pDis->abInstr[offInstr], cbMaxRead); 2397 pDis->cbCachedInstr = offInstr + cbMaxRead; 2397 2398 return VERR_DIS_NO_READ_CALLBACK; 2398 2399 #else 2399 memcpy(pbDst, (void const *)(uintptr_t)uSrcAddr, cbToRead); 2400 memcpy(&pDis->abInstr[offInstr], (uint8_t const *)(uintptr_t)pDis->uInstrAddr + offInstr, cbMaxRead); 2401 pDis->cbCachedInstr = offInstr + cbMaxRead; 2400 2402 return VINF_SUCCESS; 2401 2403 #endif … … 2437 2439 2438 2440 /* 2439 * Do the read. No need to zero anything, abInstr is already zeroed by the 2440 * DISInstrEx API. 2441 * Do the read. 2442 * (No need to zero anything on failure as abInstr is already zeroed by the 2443 * DISInstrEx API.) 2441 2444 */ 2442 /** @todo Change the callback API so it can read more, thus avoid lots of 2443 * calls or it doing its own caching. */ 2444 int rc = pCpu->pfnReadBytes(pCpu, &pCpu->abInstr[off], pCpu->uInstrAddr + off, cbMin); 2445 if (RT_FAILURE(rc)) 2445 int rc = pCpu->pfnReadBytes(pCpu, off, cbMin, sizeof(pCpu->abInstr) - off); 2446 if (RT_SUCCESS(rc)) 2447 { 2448 Assert(pCpu->cbCachedInstr >= off + cbMin); 2449 Assert(pCpu->cbCachedInstr <= sizeof(pCpu->abInstr)); 2450 } 2451 else 2446 2452 { 2447 2453 Log(("disReadMore failed with rc=%Rrc!!\n", rc)); 2448 2454 pCpu->rc = VERR_DIS_MEM_READ; 2449 2455 } 2450 pCpu->cbCachedInstr = off + cbMin;2451 2456 } 2452 2457 -
trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp
r41737 r41760 167 167 /** 168 168 * Callback for reading bytes. 169 * 170 * @todo This should check that the disassembler doesn't do unnecessary reads, 171 * however the current doesn't do this and is just complicated... 172 */ 173 static DECLCALLBACK(int) MyDisasInstrRead(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 174 { 175 PMYDISSTATE pState = (PMYDISSTATE)pDisState; 169 */ 170 static DECLCALLBACK(int) MyDisasInstrRead(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 171 { 172 PMYDISSTATE pState = (PMYDISSTATE)pDis; 173 RTUINTPTR uSrcAddr = pState->Cpu.uInstrAddr + offInstr; 176 174 if (RT_LIKELY( pState->uNextAddr == uSrcAddr 177 && pState->cbLeft >= cb ToRead))175 && pState->cbLeft >= cbMinRead)) 178 176 { 179 177 /* 180 178 * Straight forward reading. 181 179 */ 182 if (cbToRead == 1) 180 //size_t cbToRead = cbMaxRead; 181 size_t cbToRead = cbMinRead; 182 memcpy(&pState->Cpu.abInstr[offInstr], pState->pbNext, cbToRead); 183 pState->Cpu.cbCachedInstr = offInstr + cbToRead; 184 pState->pbNext += cbToRead; 185 pState->cbLeft -= cbToRead; 186 pState->uNextAddr += cbToRead; 187 return VINF_SUCCESS; 188 } 189 190 if (pState->uNextAddr == uSrcAddr) 191 { 192 /* 193 * Reading too much. 194 */ 195 if (pState->cbLeft > 0) 183 196 { 184 pState->cbLeft--; 185 *pbDst = *pState->pbNext++; 186 pState->uNextAddr++; 197 memcpy(&pState->Cpu.abInstr[offInstr], pState->pbNext, pState->cbLeft); 198 offInstr += (uint8_t)pState->cbLeft; 199 cbMinRead -= (uint8_t)pState->cbLeft; 200 pState->pbNext += pState->cbLeft; 201 pState->uNextAddr += pState->cbLeft; 202 pState->cbLeft = 0; 187 203 } 188 else 189 { 190 memcpy(pbDst, pState->pbNext, cbToRead); 191 pState->pbNext += cbToRead; 192 pState->cbLeft -= cbToRead; 193 pState->uNextAddr += cbToRead; 194 } 204 memset(&pState->Cpu.abInstr[offInstr], 0xcc, cbMinRead); 205 pState->rc = VERR_EOF; 195 206 } 196 207 else 197 208 { 198 209 /* 199 * Jumping up the stream. 200 * This occurs when the byte sequence is added to the output string. 210 * Non-sequential read, that's an error. 201 211 */ 202 uint64_t offReq64 = uSrcAddr - pState->uAddress; 203 if (offReq64 < 32) 204 { 205 uint32_t offReq = offReq64; 206 uintptr_t off = pState->pbNext - pState->pbInstr; 207 if (off + pState->cbLeft <= offReq) 208 { 209 pState->pbNext += pState->cbLeft; 210 pState->uNextAddr += pState->cbLeft; 211 pState->cbLeft = 0; 212 213 memset(pbDst, 0xcc, cbToRead); 214 pState->rc = VERR_EOF; 215 return VERR_EOF; 216 } 217 218 /* reset the stream. */ 219 pState->cbLeft += off; 220 pState->pbNext = pState->pbInstr; 221 pState->uNextAddr = pState->uAddress; 222 223 /* skip ahead. */ 224 pState->cbLeft -= offReq; 225 pState->pbNext += offReq; 226 pState->uNextAddr += offReq; 227 228 /* do the reading. */ 229 if (pState->cbLeft >= cbToRead) 230 { 231 memcpy(pbDst, pState->pbNext, cbToRead); 232 pState->cbLeft -= cbToRead; 233 pState->pbNext += cbToRead; 234 pState->uNextAddr += cbToRead; 235 } 236 else 237 { 238 if (pState->cbLeft > 0) 239 { 240 memcpy(pbDst, pState->pbNext, pState->cbLeft); 241 pbDst += pState->cbLeft; 242 cbToRead -= (uint32_t)pState->cbLeft; 243 pState->pbNext += pState->cbLeft; 244 pState->uNextAddr += pState->cbLeft; 245 pState->cbLeft = 0; 246 } 247 memset(pbDst, 0xcc, cbToRead); 248 pState->rc = VERR_EOF; 249 return VERR_EOF; 250 } 251 } 252 else 253 { 254 RTStrmPrintf(g_pStdErr, "Reading before current instruction!\n"); 255 memset(pbDst, 0x90, cbToRead); 256 pState->rc = VERR_INTERNAL_ERROR; 257 return VERR_INTERNAL_ERROR; 258 } 259 } 260 261 return VINF_SUCCESS; 212 RTStrmPrintf(g_pStdErr, "Reading before current instruction!\n"); 213 memset(&pState->Cpu.abInstr[offInstr], 0x90, cbMinRead); 214 pState->rc = VERR_INTERNAL_ERROR; 215 } 216 pState->Cpu.cbCachedInstr = offInstr + cbMinRead; 217 return pState->rc; 262 218 } 263 219 … … 340 296 || State.Cpu.pCurInstr->uOpcode == OP_INVALID 341 297 || State.Cpu.pCurInstr->uOpcode == OP_ILLUD2 342 || ( State.enmUndefOp == kUndefOp_DefineByte298 || ( State.enmUndefOp == kUndefOp_DefineByte 343 299 && !MyDisasIsValidInstruction(&State.Cpu)); 344 300 if (State.fUndefOp && State.enmUndefOp == kUndefOp_DefineByte) … … 347 303 { 348 304 State.Cpu.abInstr[0] = 0; 349 State.Cpu.pfnReadBytes(&State.Cpu, &State.Cpu.abInstr[0], State.uAddress, 1);305 State.Cpu.pfnReadBytes(&State.Cpu, 0, 1, 1); 350 306 State.cbInstr = 1; 351 307 } -
trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp
r41736 r41760 147 147 * @callback_method_impl{FNDISREADBYTES} 148 148 */ 149 static DECLCALLBACK(int) MyReadBytes(PDISCPUSTATE pDisState, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead) 150 { 151 memcpy(pbDst, (uint8_t const *)((uintptr_t)uSrcAddr + (uintptr_t)pDisState->pvUser), cbToRead); 149 static DECLCALLBACK(int) MyReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 150 { 151 uint8_t const *pbSrc = (uint8_t const *)((uintptr_t)pDis->uInstrAddr + (uintptr_t)pDis->pvUser + offInstr); 152 memcpy(&pDis->abInstr[offInstr], pbSrc, cbMinRead); 153 pDis->cbCachedInstr = offInstr + cbMinRead; 152 154 return VINF_SUCCESS; 153 155 } -
trunk/src/VBox/Runtime/testcase/tstLdr-4.cpp
r38636 r41760 61 61 else if (!strcmp(pszSymbol, "RTAssertMsg2Weak") || !strcmp(pszSymbol, "_RTAssertMsg2Weak")) 62 62 *pValue = (uintptr_t)RTAssertMsg1Weak; 63 else if (!strcmp(pszSymbol, "RTAssertMsg1") || !strcmp(pszSymbol, "_RTAssertMsg1")) 64 *pValue = (uintptr_t)RTAssertMsg1; 65 else if (!strcmp(pszSymbol, "RTAssertMsg2") || !strcmp(pszSymbol, "_RTAssertMsg2")) 66 *pValue = (uintptr_t)RTAssertMsg2; 67 else if (!strcmp(pszSymbol, "RTAssertMsg2V") || !strcmp(pszSymbol, "_RTAssertMsg2V")) 68 *pValue = (uintptr_t)RTAssertMsg2V; 69 else if (!strcmp(pszSymbol, "RTAssertMayPanic") || !strcmp(pszSymbol, "_RTAssertMayPanic")) 70 *pValue = (uintptr_t)RTAssertMayPanic; 63 71 else if (!strcmp(pszSymbol, "RTLogDefaultInstance") || !strcmp(pszSymbol, "_RTLogDefaultInstance")) 64 72 *pValue = (uintptr_t)RTLogDefaultInstance; -
trunk/src/VBox/Runtime/testcase/tstLdrDisasmTest.cpp
r41737 r41760 83 83 * @callback_method_impl{FNDISREADBYTES} 84 84 */ 85 static DECLCALLBACK(int) DisasmTest1ReadCode(PDISCPUSTATE pDis State, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)85 static DECLCALLBACK(int) DisasmTest1ReadCode(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 86 86 { 87 NOREF(pDisState); 88 while (cbToRead > 0) 89 { 90 *pbDst = g_ab32BitCode[uSrcAddr]; 91 92 /* next */ 93 pbDst++; 94 uSrcAddr++; 95 cbToRead--; 96 } 97 return 0; 87 size_t cb = cbMaxRead; 88 if (cb + pDis->uInstrAddr + offInstr > sizeof(g_ab32BitCode)) 89 cb = cbMinRead; 90 memcpy(&pDis->abInstr[offInstr], &g_ab32BitCode[pDis->uInstrAddr + offInstr], cb); 91 pDis->cbCachedInstr = offInstr + cb; 92 return VINF_SUCCESS; 98 93 } 99 94 -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r41744 r41760 284 284 * @callback_method_impl{FNDISREADBYTES} 285 285 */ 286 static DECLCALLBACK(int) emReadBytes(PDISCPUSTATE pDis State, uint8_t *pbDst, RTUINTPTR uSrcAddr, uint32_t cbToRead)287 { 288 PEMDISSTATE pState = (PEMDISSTATE)pDis State->pvUser;286 static DECLCALLBACK(int) emReadBytes(PDISCPUSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead) 287 { 288 PEMDISSTATE pState = (PEMDISSTATE)pDis->pvUser; 289 289 # ifndef IN_RING0 290 290 PVM pVM = pState->pVM; 291 291 # endif 292 292 PVMCPU pVCpu = pState->pVCpu; 293 /** @todo Rewrite this to make full use of the abInstr buffer and drop our extra 294 * caching buffer. Just playing safe at first... */ 295 uint8_t *pbDst = &pDis->abInstr[offInstr]; 296 RTUINTPTR uSrcAddr = pDis->uInstrAddr + offInstr; 297 size_t cbToRead = cbMinRead; 293 298 294 299 # ifdef IN_RING0 295 int rc;300 int rc; 296 301 297 302 if ( pState->GCPtr … … 303 308 for (unsigned i = 0; i < cbToRead; i++) 304 309 pbDst[i] = pState->aOpcode[offset + i]; 310 pDis->cbCachedInstr = offInstr + cbToRead; 305 311 return VINF_SUCCESS; 306 312 } … … 308 314 rc = PGMPhysSimpleReadGCPtr(pVCpu, pbDst, uSrcAddr, cbToRead); 309 315 AssertMsgRC(rc, ("PGMPhysSimpleReadGCPtr failed for uSrcAddr=%RTptr cbToRead=%x rc=%d\n", uSrcAddr, cbToRead, rc)); 316 310 317 # elif defined(IN_RING3) 311 318 if (!PATMIsPatchGCAddr(pVM, uSrcAddr)) … … 332 339 333 340 # endif /* IN_RING3 */ 341 pDis->cbCachedInstr = offInstr + cbToRead; 334 342 return VINF_SUCCESS; 335 343 } -
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 ( !(pDisInfo->pPatchInfo->flags & (PATMFL_DUPLICATE_FUNCTION|PATMFL_IDTHANDLER))565 && !(pDisInfo->fReadFlags & PATMREAD_NOCHECK))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; -
trunk/src/VBox/VMM/include/PATMInternal.h
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 … … 675 675 676 676 677 FNDISREADBYTES patmReadBytes;678 679 677 680 678 RT_C_DECLS_BEGIN
Note:
See TracChangeset
for help on using the changeset viewer.

