Changeset 46159 in vbox
- Timestamp:
- May 18, 2013 7:56:08 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/dbgf.h
r46155 r46159 886 886 /** Probably a hypervisor instruction. */ 887 887 #define DBGF_DISAS_FLAGS_HYPER RT_BIT(6) 888 /** Disassemble original unpatched bytes (PATM). */ 889 #define DBGF_DISAS_FLAGS_UNPATCHED_BYTES RT_BIT(7) 890 /** Annotate patched instructions. */ 891 #define DBGF_DISAS_FLAGS_ANNOTATE_PATCHED RT_BIT(8) 888 892 /** Disassemble in the default mode of the specific context. */ 889 893 #define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000) … … 899 903 #define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000) 900 904 /** Mask containing the valid flags. */ 901 #define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x70000 07f)905 #define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x700001ff) 902 906 /** @} */ 903 907 -
trunk/include/VBox/vmm/patm.h
r46134 r46159 211 211 212 212 VMMR3_INT_DECL(void) PATMR3DbgPopulateAddrSpace(PVM pVM, RTDBGAS hDbgAs); 213 VMMR3_INT_DECL(void) PATMR3DbgAnnotatePatchedInstruction(PVM pVM, RTRCPTR RCPtr, uint8_t cbInstr, 214 char *pszBuf, size_t cbBuf); 213 215 214 216 /** @} */ -
trunk/src/VBox/Debugger/DBGCEmulateCodeView.cpp
r46158 r46159 919 919 * Check the desired mode. 920 920 */ 921 unsigned fFlags = DBGF_DISAS_FLAGS_NO_ADDRESS ;921 unsigned fFlags = DBGF_DISAS_FLAGS_NO_ADDRESS | DBGF_DISAS_FLAGS_UNPATCHED_BYTES | DBGF_DISAS_FLAGS_ANNOTATE_PATCHED; 922 922 switch (pCmd->pszCmd[1]) 923 923 { -
trunk/src/VBox/VMM/VMMR3/DBGF.cpp
r46155 r46159 974 974 * Check if attached. 975 975 */ 976 AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED); 976 if (!pVM->dbgf.s.fAttached) 977 return VERR_DBGF_NOT_ATTACHED; 977 978 978 979 /* … … 1116 1117 if (pVM->enmVMState >= VMSTATE_DESTROYING) 1117 1118 return VERR_INVALID_VM_HANDLE; 1118 AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED); 1119 if (!pVM->dbgf.s.fAttached) 1120 return VERR_DBGF_NOT_ATTACHED; 1119 1121 1120 1122 if (!RTSemPongShouldWait(&pVM->dbgf.s.PingPong)) -
trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp
r46155 r46159 26 26 #include <VBox/vmm/pgm.h> 27 27 #include <VBox/vmm/cpum.h> 28 #ifdef VBOX_WITH_RAW_MODE 29 # include <VBox/vmm/patm.h> 30 #endif 28 31 #include "DBGFInternal.h" 29 32 #include <VBox/dis.h> … … 57 60 PVMCPU pVCpu; 58 61 /** The address space for resolving symbol. */ 59 RTDBGAS h As;62 RTDBGAS hDbgAs; 60 63 /** Pointer to the first byte in the segment. */ 61 64 RTGCUINTPTR GCPtrSegBase; … … 78 81 /** 64 bits mode or not. */ 79 82 bool f64Bits; 83 /** Read original unpatched bytes from the patch manager. */ 84 bool fUnpatchedBytes; 85 /** Set when fUnpatchedBytes is active and we encounter patched bytes. */ 86 bool fPatchedInstr; 80 87 } DBGFDISASSTATE, *PDBGFDISASSTATE; 81 88 … … 109 116 pState->GCPtrPage = 0; 110 117 pState->pvPageR3 = NULL; 111 pState->h As = pSelInfo->fFlags & DBGFSELINFO_FLAGS_HYPER /** @todo Deal more explicitly with RC in DBGFR3Disas*. */118 pState->hDbgAs = !HMIsEnabled(pVM) 112 119 ? DBGF_AS_RC_AND_GC_GLOBAL 113 120 : DBGF_AS_GLOBAL; … … 116 123 pState->fLocked = false; 117 124 pState->f64Bits = enmMode >= PGMMODE_AMD64 && pSelInfo->u.Raw.Gen.u1Long; 125 #ifdef VBOX_WITH_RAW_MODE 126 pState->fUnpatchedBytes = RT_BOOL(fFlags & DBGF_DISAS_FLAGS_UNPATCHED_BYTES); 127 pState->fPatchedInstr = false; 128 #endif 118 129 119 130 DISCPUMODE enmCpuMode; … … 267 278 cb = cbMaxRead; 268 279 280 #ifdef VBOX_WITH_RAW_MODE 281 /* 282 * Read original bytes from PATM if asked to do so. 283 */ 284 if (pState->fUnpatchedBytes) 285 { 286 size_t cbRead = cb; 287 int rc = PATMR3ReadOrgInstr(pState->pVM, GCPtr, &pDis->abInstr[offInstr], cbRead, &cbRead); 288 if (RT_SUCCESS(rc)) 289 { 290 pState->fPatchedInstr = true; 291 if (cbRead >= cbMinRead) 292 { 293 pDis->cbCachedInstr = offInstr + (uint8_t)cbRead; 294 return rc; 295 } 296 297 cbMinRead -= (uint8_t)cbRead; 298 cbMaxRead -= (uint8_t)cbRead; 299 cb -= (uint8_t)cbRead; 300 offInstr += (uint8_t)cbRead; 301 GCPtr += cbRead; 302 if (!cb) 303 continue; 304 } 305 } 306 #endif /* VBOX_WITH_RAW_MODE */ 307 269 308 /* 270 309 * Read and advance, … … 301 340 rc = DBGFR3AddrFromSelInfoOff(pState->pVM->pUVM, &Addr, pSelInfo, uAddress); 302 341 if (RT_SUCCESS(rc)) 303 rc = DBGFR3AsSymbolByAddr(pState->pVM->pUVM, pState->h As, &Addr, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL,342 rc = DBGFR3AsSymbolByAddr(pState->pVM->pUVM, pState->hDbgAs, &Addr, RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL, 304 343 &off, &Sym, NULL /*phMod*/); 305 344 } … … 507 546 &SelInfo); 508 547 548 #ifdef VBOX_WITH_RAW_MODE 549 /* 550 * Patched instruction annotations. 551 */ 552 char szPatchAnnotations[256]; 553 szPatchAnnotations[0] = '\0'; 554 if (fFlags & DBGF_DISAS_FLAGS_ANNOTATE_PATCHED) 555 PATMR3DbgAnnotatePatchedInstruction(pVM, GCPtr, State.Cpu.cbInstr, szPatchAnnotations, sizeof(szPatchAnnotations)); 556 #endif 557 509 558 /* 510 559 * Print it to the user specified buffer. 511 560 */ 561 size_t cch; 512 562 if (fFlags & DBGF_DISAS_FLAGS_NO_BYTES) 513 563 { 514 564 if (fFlags & DBGF_DISAS_FLAGS_NO_ADDRESS) 515 RTStrPrintf(pszOutput, cbOutput, "%s", szBuf);565 cch = RTStrPrintf(pszOutput, cbOutput, "%s", szBuf); 516 566 else if (fRealModeAddress) 517 RTStrPrintf(pszOutput, cbOutput, "%04x:%04x %s", Sel, (unsigned)GCPtr, szBuf);567 cch = RTStrPrintf(pszOutput, cbOutput, "%04x:%04x %s", Sel, (unsigned)GCPtr, szBuf); 518 568 else if (Sel == DBGF_SEL_FLAT) 519 569 { 520 570 if (enmMode >= PGMMODE_AMD64) 521 RTStrPrintf(pszOutput, cbOutput, "%RGv %s", GCPtr, szBuf);571 cch = RTStrPrintf(pszOutput, cbOutput, "%RGv %s", GCPtr, szBuf); 522 572 else 523 RTStrPrintf(pszOutput, cbOutput, "%08RX32 %s", (uint32_t)GCPtr, szBuf);573 cch = RTStrPrintf(pszOutput, cbOutput, "%08RX32 %s", (uint32_t)GCPtr, szBuf); 524 574 } 525 575 else 526 576 { 527 577 if (enmMode >= PGMMODE_AMD64) 528 RTStrPrintf(pszOutput, cbOutput, "%04x:%RGv %s", Sel, GCPtr, szBuf);578 cch = RTStrPrintf(pszOutput, cbOutput, "%04x:%RGv %s", Sel, GCPtr, szBuf); 529 579 else 530 RTStrPrintf(pszOutput, cbOutput, "%04x:%08RX32 %s", Sel, (uint32_t)GCPtr, szBuf);580 cch = RTStrPrintf(pszOutput, cbOutput, "%04x:%08RX32 %s", Sel, (uint32_t)GCPtr, szBuf); 531 581 } 532 582 } … … 536 586 uint8_t const *pabInstr = State.Cpu.abInstr; 537 587 if (fFlags & DBGF_DISAS_FLAGS_NO_ADDRESS) 538 RTStrPrintf(pszOutput, cbOutput, "%.*Rhxs%*s %s",539 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",540 szBuf);588 cch = RTStrPrintf(pszOutput, cbOutput, "%.*Rhxs%*s %s", 589 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 590 szBuf); 541 591 else if (fRealModeAddress) 542 RTStrPrintf(pszOutput, cbOutput, "%04x:%04x %.*Rhxs%*s %s",543 Sel, (unsigned)GCPtr,544 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",545 szBuf);592 cch = RTStrPrintf(pszOutput, cbOutput, "%04x:%04x %.*Rhxs%*s %s", 593 Sel, (unsigned)GCPtr, 594 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 595 szBuf); 546 596 else if (Sel == DBGF_SEL_FLAT) 547 597 { 548 598 if (enmMode >= PGMMODE_AMD64) 549 RTStrPrintf(pszOutput, cbOutput, "%RGv %.*Rhxs%*s %s",550 GCPtr,551 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",552 szBuf);599 cch = RTStrPrintf(pszOutput, cbOutput, "%RGv %.*Rhxs%*s %s", 600 GCPtr, 601 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 602 szBuf); 553 603 else 554 RTStrPrintf(pszOutput, cbOutput, "%08RX32 %.*Rhxs%*s %s",555 (uint32_t)GCPtr,556 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",557 szBuf);604 cch = RTStrPrintf(pszOutput, cbOutput, "%08RX32 %.*Rhxs%*s %s", 605 (uint32_t)GCPtr, 606 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 607 szBuf); 558 608 } 559 609 else 560 610 { 561 611 if (enmMode >= PGMMODE_AMD64) 562 RTStrPrintf(pszOutput, cbOutput, "%04x:%RGv %.*Rhxs%*s %s",563 Sel, GCPtr,564 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "",565 szBuf);612 cch = RTStrPrintf(pszOutput, cbOutput, "%04x:%RGv %.*Rhxs%*s %s", 613 Sel, GCPtr, 614 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 615 szBuf); 566 616 else 567 RTStrPrintf(pszOutput, cbOutput, "%04x:%08RX32 %.*Rhxs%*s %s", 568 Sel, (uint32_t)GCPtr, 569 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 570 szBuf); 571 } 572 } 617 cch = RTStrPrintf(pszOutput, cbOutput, "%04x:%08RX32 %.*Rhxs%*s %s", 618 Sel, (uint32_t)GCPtr, 619 cbInstr, pabInstr, cbInstr < 8 ? (8 - cbInstr) * 3 : 0, "", 620 szBuf); 621 } 622 } 623 624 #ifdef VBOX_WITH_RAW_MODE 625 if (szPatchAnnotations[0] && cch + 1 < cbOutput) 626 RTStrPrintf(pszOutput + cch, cbOutput - cch, " ; %s", szPatchAnnotations); 627 #endif 573 628 574 629 if (pcbInstr) -
trunk/src/VBox/VMM/VMMR3/PATM.cpp
r46150 r46159 3780 3780 3781 3781 /* Add relocation record for cached data access. */ 3782 if (patmPatchAddReloc32(pVM, pPatch, &pPB[pCpu->cbInstr - sizeof(RTRCPTR)], FIXUP_ABSOLUTE, pPatch->pPrivInstrGC, pVM->patm.s.mmio.pCachedData) != VINF_SUCCESS) 3782 if (patmPatchAddReloc32(pVM, pPatch, &pPB[pCpu->cbInstr - sizeof(RTRCPTR)], FIXUP_ABSOLUTE, pPatch->pPrivInstrGC, 3783 pVM->patm.s.mmio.pCachedData) != VINF_SUCCESS) 3783 3784 { 3784 3785 Log(("Relocation failed for cached mmio address!!\n")); … … 3794 3795 3795 3796 /* Replace address with that of the cached item. */ 3796 rc = PGMPhysSimpleDirtyWriteGCPtr(VMMGetCpu0(pVM), pInstrGC + pCpu->cbInstr - sizeof(RTRCPTR), &pVM->patm.s.mmio.pCachedData, sizeof(RTRCPTR)); 3797 rc = PGMPhysSimpleDirtyWriteGCPtr(VMMGetCpu0(pVM), pInstrGC + pCpu->cbInstr - sizeof(RTRCPTR), 3798 &pVM->patm.s.mmio.pCachedData, sizeof(RTRCPTR)); 3797 3799 AssertRC(rc); 3798 3800 if (RT_FAILURE(rc)) -
trunk/src/VBox/VMM/VMMR3/PATMR3Dbg.cpp
r46150 r46159 96 96 97 97 98 static size_t patmR3DbgDescribePatchAsSymbol(PPATMPATCHREC pPatchRec, char *pszName, size_t cbLeft) 99 { 100 char * const pszNameStart = pszName; 101 #define ADD_SZ(a_sz) \ 102 do { \ 103 if (cbLeft >= sizeof(a_sz)) \ 104 { \ 105 memcpy(pszName, a_sz, sizeof(a_sz)); \ 106 pszName += sizeof(a_sz) - 1; \ 107 cbLeft -= sizeof(a_sz) - 1;\ 108 }\ 109 } while (0) 110 111 /* Start the name off with the address of the guest code. */ 112 size_t cch = RTStrPrintf(pszName, cbLeft, "Patch_%#08x", pPatchRec->patch.pPrivInstrGC); 113 cbLeft -= cch; 114 pszName += cch; 115 116 /* Append flags. */ 117 uint64_t fFlags = pPatchRec->patch.flags; 118 if (fFlags & PATMFL_INTHANDLER) 119 ADD_SZ("_IntHandler"); 120 if (fFlags & PATMFL_SYSENTER) 121 ADD_SZ("_SysEnter"); 122 if (fFlags & PATMFL_GUEST_SPECIFIC) 123 ADD_SZ("_GuestSpecific"); 124 if (fFlags & PATMFL_USER_MODE) 125 ADD_SZ("_UserMode"); 126 if (fFlags & PATMFL_IDTHANDLER) 127 ADD_SZ("_IdtHnd"); 128 if (fFlags & PATMFL_TRAPHANDLER) 129 ADD_SZ("_TrapHnd"); 130 if (fFlags & PATMFL_DUPLICATE_FUNCTION) 131 ADD_SZ("_DupFunc"); 132 if (fFlags & PATMFL_REPLACE_FUNCTION_CALL) 133 ADD_SZ("_ReplFunc"); 134 if (fFlags & PATMFL_TRAPHANDLER_WITH_ERRORCODE) 135 ADD_SZ("_TrapHndErrCd"); 136 if (fFlags & PATMFL_MMIO_ACCESS) 137 ADD_SZ("_MmioAccess"); 138 if (fFlags & PATMFL_SYSENTER_XP) 139 ADD_SZ("_SysEnterXP"); 140 if (fFlags & PATMFL_INT3_REPLACEMENT) 141 ADD_SZ("_Int3Repl"); 142 if (fFlags & PATMFL_SUPPORT_CALLS) 143 ADD_SZ("_SupCalls"); 144 if (fFlags & PATMFL_SUPPORT_INDIRECT_CALLS) 145 ADD_SZ("_SupIndirCalls"); 146 if (fFlags & PATMFL_IDTHANDLER_WITHOUT_ENTRYPOINT) 147 ADD_SZ("_IdtHandlerWE"); 148 if (fFlags & PATMFL_INHIBIT_IRQS) 149 ADD_SZ("_InhibitIrqs"); 150 if (fFlags & PATMFL_RECOMPILE_NEXT) 151 ADD_SZ("_RecompileNext"); 152 if (fFlags & PATMFL_CALLABLE_AS_FUNCTION) 153 ADD_SZ("_Callable"); 154 if (fFlags & PATMFL_TRAMPOLINE) 155 ADD_SZ("_Trampoline"); 156 if (fFlags & PATMFL_PATCHED_GUEST_CODE) 157 ADD_SZ("_PatchedGuestCode"); 158 if (fFlags & PATMFL_MUST_INSTALL_PATCHJMP) 159 ADD_SZ("_MustInstallPatchJmp"); 160 if (fFlags & PATMFL_INT3_REPLACEMENT_BLOCK) 161 ADD_SZ("_Int3ReplBlock"); 162 if (fFlags & PATMFL_EXTERNAL_JUMP_INSIDE) 163 ADD_SZ("_ExtJmp"); 164 if (fFlags & PATMFL_CODE_REFERENCED) 165 ADD_SZ("_CodeRefed"); 166 167 return pszName - pszNameStart; 168 } 169 170 98 171 /** 99 172 * Called when a new patch is added or when first populating the address space. … … 112 185 * state considerations right now (I don't recall if we're still 113 186 * depending on structure layout there or not). */ 114 int rc; 115 char szName[256]; 116 117 #define ADD_SZ(a_sz) \ 118 do { \ 119 if (cbLeft >= sizeof(a_sz)) \ 120 { \ 121 memcpy(pszName, a_sz, sizeof(a_sz)); \ 122 pszName += sizeof(a_sz); \ 123 cbLeft -= sizeof(a_sz);\ 124 }\ 125 } while (0) 126 127 /* Start the name off with the address of the guest code. */ 128 size_t cch = RTStrPrintf(szName, sizeof(szName), "Patch_%#08x", pPatchRec->patch.pPrivInstrGC); 129 char *pszName = &szName[cch]; 130 size_t cbLeft = sizeof(szName) - cch; 131 132 /* Append flags. */ 133 uint64_t fFlags = pPatchRec->patch.flags; 134 if (fFlags & PATMFL_INTHANDLER) 135 ADD_SZ("_IntHandler"); 136 if (fFlags & PATMFL_SYSENTER) 137 ADD_SZ("_SysEnter"); 138 if (fFlags & PATMFL_GUEST_SPECIFIC) 139 ADD_SZ("_GuestSpecific"); 140 if (fFlags & PATMFL_USER_MODE) 141 ADD_SZ("_UserMode"); 142 if (fFlags & PATMFL_IDTHANDLER) 143 ADD_SZ("_IdtHandler"); 144 if (fFlags & PATMFL_TRAPHANDLER) 145 ADD_SZ("_TrapHandler"); 146 if (fFlags & PATMFL_DUPLICATE_FUNCTION) 147 ADD_SZ("_DupFunc"); 148 if (fFlags & PATMFL_REPLACE_FUNCTION_CALL) 149 ADD_SZ("_ReplFunc"); 150 if (fFlags & PATMFL_TRAPHANDLER_WITH_ERRORCODE) 151 ADD_SZ("_TrapHandlerErrCd"); 152 if (fFlags & PATMFL_MMIO_ACCESS) 153 ADD_SZ("_MmioAccess"); 154 if (fFlags & PATMFL_SYSENTER_XP) 155 ADD_SZ("_SysEnterXP"); 156 if (fFlags & PATMFL_INT3_REPLACEMENT) 157 ADD_SZ("_Int3Replacement"); 158 if (fFlags & PATMFL_SUPPORT_CALLS) 159 ADD_SZ("_SupportCalls"); 160 if (fFlags & PATMFL_SUPPORT_INDIRECT_CALLS) 161 ADD_SZ("_SupportIndirectCalls"); 162 if (fFlags & PATMFL_IDTHANDLER_WITHOUT_ENTRYPOINT) 163 ADD_SZ("_IdtHandlerWE"); 164 if (fFlags & PATMFL_INHIBIT_IRQS) 165 ADD_SZ("_InhibitIrqs"); 166 if (fFlags & PATMFL_RECOMPILE_NEXT) 167 ADD_SZ("_RecompileNext"); 168 if (fFlags & PATMFL_CALLABLE_AS_FUNCTION) 169 ADD_SZ("_Callable"); 170 if (fFlags & PATMFL_TRAMPOLINE) 171 ADD_SZ("_Trampoline"); 172 if (fFlags & PATMFL_PATCHED_GUEST_CODE) 173 ADD_SZ("_PatchedGuestCode"); 174 if (fFlags & PATMFL_MUST_INSTALL_PATCHJMP) 175 ADD_SZ("_MustInstallPatchJmp"); 176 if (fFlags & PATMFL_INT3_REPLACEMENT_BLOCK) 177 ADD_SZ("_Int3ReplacementBlock"); 178 if (fFlags & PATMFL_EXTERNAL_JUMP_INSIDE) 179 ADD_SZ("_ExtJmp"); 180 if (fFlags & PATMFL_CODE_REFERENCED) 181 ADD_SZ("_CodeRefed"); 187 char szName[256]; 188 size_t off = patmR3DbgDescribePatchAsSymbol(pPatchRec, szName, sizeof(szName)); 182 189 183 190 /* If we have a symbol near the guest address, append that. */ 184 if ( cbLeft > 8)191 if (off + 8 <= sizeof(szName)) 185 192 { 186 193 DBGFSYMBOL Symbol; 187 194 RTGCINTPTR offDisp; 188 195 189 rc = DBGFR3SymbolByAddr(pVM, pPatchRec->patch.pPrivInstrGC, &offDisp, &Symbol);196 int rc = DBGFR3SymbolByAddr(pVM, pPatchRec->patch.pPrivInstrGC, &offDisp, &Symbol); 190 197 if (RT_SUCCESS(rc)) 191 198 { 192 ADD_SZ("__"); 193 RTStrCopy(pszName, cbLeft, Symbol.szName); 199 szName[off++] = '_'; 200 szName[off++] = '_'; 201 RTStrCopy(&szName[off], sizeof(szName) - off, Symbol.szName); 194 202 } 195 203 } … … 200 208 pPatchRec->patch.cbPatchBlockSize, 201 209 0 /*fFlags*/, NULL /*piOrdinal*/); 202 203 210 } 204 211 } … … 300 307 301 308 309 /** 310 * Annotates an instruction if patched. 311 * 312 * @param pVM The VM handle. 313 * @param RCPtr The instruction address. 314 * @param cbInstr The instruction length. 315 * @param pszBuf The output buffer. This will be an empty string 316 * if the instruction wasn't patched. If it's 317 * patched, it will hold a symbol-like string 318 * describing the patch. 319 * @param cbBuf The size of the output buffer. 320 */ 321 VMMR3_INT_DECL(void) PATMR3DbgAnnotatePatchedInstruction(PVM pVM, RTRCPTR RCPtr, uint8_t cbInstr, char *pszBuf, size_t cbBuf) 322 { 323 /* 324 * Always zero the buffer. 325 */ 326 AssertReturnVoid(cbBuf > 0); 327 *pszBuf = '\0'; 328 329 /* 330 * Drop out immediately if it cannot be a patched instruction. 331 */ 332 if (!PATMIsEnabled(pVM)) 333 return; 334 if ( RCPtr < pVM->patm.s.pPatchedInstrGCLowest 335 || RCPtr > pVM->patm.s.pPatchedInstrGCHighest) 336 return; 337 338 /* 339 * Look for a patch record covering any part of the instruction. 340 * 341 * The first query results in a patched less or equal to RCPtr. While the 342 * second results in one that's greater than RCPtr. 343 */ 344 PPATMPATCHREC pPatchRec; 345 pPatchRec = (PPATMPATCHREC)RTAvloU32GetBestFit(&pVM->patm.s.PatchLookupTreeHC->PatchTree, RCPtr, false /*fFromAbove*/); 346 if ( !pPatchRec 347 || RCPtr - pPatchRec->patch.pPrivInstrGC > pPatchRec->patch.cbPrivInstr) 348 { 349 pPatchRec = (PPATMPATCHREC)RTAvloU32GetBestFit(&pVM->patm.s.PatchLookupTreeHC->PatchTree, RCPtr, true /*fFromAbove*/); 350 if ( !pPatchRec 351 || (RTRCPTR)(RCPtr + cbInstr) < pPatchRec->patch.pPrivInstrGC ) 352 return; 353 } 354 355 /* 356 * Lazy bird uses the symbol name generation code for describing the patch. 357 */ 358 size_t off = patmR3DbgDescribePatchAsSymbol(pPatchRec, pszBuf, cbBuf); 359 if (off + 1 < cbBuf) 360 { 361 const char *pszState; 362 switch (pPatchRec->patch.uState) 363 { 364 case PATCH_REFUSED: pszState = "Refused"; break; 365 case PATCH_DISABLED: pszState = "Disabled"; break; 366 case PATCH_ENABLED: pszState = "Enabled"; break; 367 case PATCH_UNUSABLE: pszState = "Unusable"; break; 368 case PATCH_DIRTY: pszState = "Dirty"; break; 369 case PATCH_DISABLE_PENDING: pszState = "DisablePending"; break; 370 default: pszState = "State???"; AssertFailed(); break; 371 } 372 373 if (pPatchRec->patch.cbPatchBlockSize > 0) 374 off += RTStrPrintf(&pszBuf[off], cbBuf - off, " - %s (%u b) - %#x LB %#x", 375 pszState, pPatchRec->patch.cbPatchJump, 376 pPatchRec->patch.pPatchBlockOffset + pVM->patm.s.pPatchMemGC, 377 pPatchRec->patch.cbPatchBlockSize); 378 else 379 off += RTStrPrintf(&pszBuf[off], cbBuf - off, " - %s (%u b)", pszState, pPatchRec->patch.cbPatchJump); 380 } 381 382 } 383
Note:
See TracChangeset
for help on using the changeset viewer.