Changeset 5667 in vbox for trunk/src/VBox
- Timestamp:
- Nov 11, 2007 4:28:47 AM (17 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 6 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/CPUM.cpp
r5605 r5667 1636 1636 RTGCUINTPTR cbSegLimit; 1637 1637 /** Pointer to the current page - HC Ptr. */ 1638 void 1638 void const *pvPageHC; 1639 1639 /** Pointer to the current page - GC Ptr. */ 1640 1640 RTGCPTR pvPageGC; -
trunk/src/VBox/VMM/DBGFAddr.cpp
r4212 r5667 121 121 122 122 /** 123 * Creates a mixed address from a guest physical address. 124 * 125 * @param pVM The VM handle. 126 * @param pAddress Where to store the mixed address. 127 * @param PhysAddr The guest physical address. 128 */ 129 DBGFR3DECL(void) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr) 130 { 131 pAddress->Sel = DBGF_SEL_FLAT; 132 pAddress->off = PhysAddr; 133 pAddress->FlatPtr = PhysAddr; 134 pAddress->fFlags = DBGFADDRESS_FLAGS_PHYS | DBGFADDRESS_FLAGS_VALID; 135 } 136 137 138 /** 123 139 * Checks if the specified address is valid (checks the structure pointer too). 124 140 * -
trunk/src/VBox/VMM/DBGFDisas.cpp
r5624 r5667 62 62 PGMMODE enmMode; 63 63 /** Pointer to the current page - HC Ptr. */ 64 void 64 void const *pvPageHC; 65 65 /** Pointer to the current page - GC Ptr. */ 66 66 RTGCPTR pvPageGC; … … 163 163 * In this context it's always pointer to the Core of a DBGFDISASSTATE. 164 164 */ 165 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTHCUINTPTR PtrSrc, uint8_t *pu8Dst, u nsignedcbRead, void *pvDisCpu)165 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTHCUINTPTR PtrSrc, uint8_t *pu8Dst, uint32_t cbRead, void *pvDisCpu) 166 166 { 167 167 PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pvDisCpu; … … 569 569 else 570 570 { 571 size_tcbBits = State.Cpu.opsize;571 uint32_t cbBits = State.Cpu.opsize; 572 572 uint8_t *pau8Bits = (uint8_t *)alloca(cbBits); 573 573 rc = dbgfR3DisasInstrRead(GCPtr, pau8Bits, cbBits, &State); -
trunk/src/VBox/VMM/DBGFMem.cpp
r5659 r5667 1 1 /* $Id$ */ 2 2 /** @file 3 * VMM DBGF - Debugger Facility, M ixed AddressMethods.3 * VMM DBGF - Debugger Facility, Memory Methods. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 200 6-2007 innotek GmbH7 * Copyright (C) 2007 innotek GmbH 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 22 22 #define LOG_GROUP LOG_GROUP_DBGF 23 23 #include <VBox/dbgf.h> 24 #include <VBox/ selm.h>24 #include <VBox/pgm.h> 25 25 #include "DBGFInternal.h" 26 26 #include <VBox/vm.h> 27 #include <VBox/mm.h>28 27 #include <VBox/err.h> 29 28 #include <VBox/log.h> … … 32 31 33 32 /** 34 * Checks if an address is in the HMA or not.35 * @returns true if it's inside the HMA.36 * @returns flase if it's not inside the HMA.33 * Scan guest memory for an exact byte string. 34 * 35 * @returns VBox status code. 37 36 * @param pVM The VM handle. 38 * @param FlatPtr The address in question. 37 * @param pAddress Where to store the mixed address. 38 * @param cbRange The number of bytes to scan. 39 * @param pabNeedle What to search for - exact search. 40 * @param cbNeedle Size of the search byte string. 41 * @param pHitAddress Where to put the address of the first hit. 39 42 */ 40 DECLINLINE(bool) dbgfR3IsHMA(PVM pVM, RTGCUINTPTR FlatPtr) 43 static DECLCALLBACK(int) dbgfR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, 44 PDBGFADDRESS pHitAddress) 41 45 { 42 return MMHyperIsInsideArea(pVM, FlatPtr); 46 /* 47 * Validate the input we use, PGM does the rest. 48 */ 49 if (!DBGFR3AddrIsValid(pVM, pAddress)) 50 return VERR_INVALID_POINTER; 51 if (!VALID_PTR(pHitAddress)) 52 return VERR_INVALID_POINTER; 53 if (DBGFADDRESS_IS_HMA(pAddress)) 54 return VERR_INVALID_POINTER; 55 56 /* 57 * Select DBGF worker by addressing mode. 58 */ 59 int rc; 60 PGMMODE enmMode = PGMGetGuestMode(pVM); 61 if ( enmMode == PGMMODE_REAL 62 || enmMode == PGMMODE_PROTECTED 63 || DBGFADDRESS_IS_PHYS(pAddress) 64 ) 65 { 66 RTGCPHYS PhysHit; 67 rc = PGMR3DbgScanPhysical(pVM, pAddress->FlatPtr, cbRange, pabNeedle, cbNeedle, &PhysHit); 68 if (RT_SUCCESS(rc)) 69 DBGFR3AddrFromPhys(pVM, pHitAddress, PhysHit); 70 } 71 else 72 { 73 RTGCUINTPTR GCPtrHit; 74 rc = PGMR3DbgScanVirtual(pVM, pAddress->FlatPtr, cbRange, pabNeedle, cbNeedle, &GCPtrHit); 75 if (RT_SUCCESS(rc)) 76 DBGFR3AddrFromFlat(pVM, pHitAddress, GCPtrHit); 77 } 78 79 return rc; 43 80 } 44 81 45 82 46 83 /** 47 * Creates a mixed address from a Sel:off pair.84 * Scan guest memory for an exact byte string. 48 85 * 49 86 * @returns VBox status code. 50 87 * @param pVM The VM handle. 51 88 * @param pAddress Where to store the mixed address. 52 * @param Sel The selector part. 53 * @param off The offset part. 89 * @param cbRange The number of bytes to scan. 90 * @param pabNeedle What to search for - exact search. 91 * @param cbNeedle Size of the search byte string. 92 * @param pHitAddress Where to put the address of the first hit. 93 * 94 * @thread Any thread. 54 95 */ 55 DBGFR3DECL(int) DBGFR3 AddrFromSelOff(PVM pVM, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off)96 DBGFR3DECL(int) DBGFR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress) 56 97 { 57 pAddress->Sel = Sel; 58 pAddress->off = off; 59 if (Sel != DBGF_SEL_FLAT) 60 { 61 SELMSELINFO SelInfo; 62 int rc = SELMR3GetSelectorInfo(pVM, Sel, &SelInfo); 63 if (VBOX_FAILURE(rc)) 64 return rc; 98 PVMREQ pReq; 99 int rc = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT, (PFNRT)dbgfR3MemScan, 6, 100 pVM, pAddress, cbRange, pabNeedle, cbNeedle, pHitAddress); 101 if (VBOX_SUCCESS(rc)) 102 rc = pReq->iStatus; 103 VMR3ReqFree(pReq); 65 104 66 /* check limit. */ 67 if (SELMSelInfoIsExpandDown(&SelInfo)) 68 { 69 if ( !SelInfo.Raw.Gen.u1Granularity 70 && off > UINT32_C(0xffff)) 71 return VERR_OUT_OF_SELECTOR_BOUNDS; 72 if (off <= SelInfo.cbLimit) 73 return VERR_OUT_OF_SELECTOR_BOUNDS; 74 } 75 else if (off > SelInfo.cbLimit) 76 return VERR_OUT_OF_SELECTOR_BOUNDS; 77 78 pAddress->FlatPtr = SelInfo.GCPtrBase + off; 79 /** @todo fix this flat selector test! */ 80 if ( !SelInfo.GCPtrBase 81 && SelInfo.Raw.Gen.u1Granularity 82 && SelInfo.Raw.Gen.u1DefBig) 83 pAddress->fFlags = DBGFADDRESS_FLAGS_FLAT; 84 else if (SelInfo.cbLimit <= UINT32_C(0xffff)) 85 pAddress->fFlags = DBGFADDRESS_FLAGS_FAR16; 86 else if (SelInfo.cbLimit <= UINT32_C(0xffffffff)) 87 pAddress->fFlags = DBGFADDRESS_FLAGS_FAR32; 88 else 89 pAddress->fFlags = DBGFADDRESS_FLAGS_FAR64; 90 } 91 else 92 { 93 pAddress->FlatPtr = off; 94 pAddress->fFlags = DBGFADDRESS_FLAGS_FLAT; 95 } 96 pAddress->fFlags |= DBGFADDRESS_FLAGS_VALID; 97 if (dbgfR3IsHMA(pVM, pAddress->FlatPtr)) 98 pAddress->fFlags |= DBGFADDRESS_FLAGS_HMA; 99 100 return VINF_SUCCESS; 105 return rc; 101 106 } 102 107 103 108 104 /**105 * Creates a mixed address from a flat address.106 *107 * @param pVM The VM handle.108 * @param pAddress Where to store the mixed address.109 * @param FlatPtr The flat pointer.110 */111 DBGFR3DECL(void) DBGFR3AddrFromFlat(PVM pVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr)112 {113 pAddress->Sel = DBGF_SEL_FLAT;114 pAddress->off = FlatPtr;115 pAddress->FlatPtr = FlatPtr;116 pAddress->fFlags = DBGFADDRESS_FLAGS_FLAT | DBGFADDRESS_FLAGS_VALID;117 if (dbgfR3IsHMA(pVM, pAddress->FlatPtr))118 pAddress->fFlags |= DBGFADDRESS_FLAGS_HMA;119 }120 121 122 /**123 * Checks if the specified address is valid (checks the structure pointer too).124 *125 * @returns true if valid.126 * @returns false if invalid.127 * @param pVM The VM handle.128 * @param pAddress The address to validate.129 */130 DBGFR3DECL(bool) DBGFR3AddrIsValid(PVM pVM, PCDBGFADDRESS pAddress)131 {132 if (!VALID_PTR(pAddress))133 return false;134 if (!DBGFADDRESS_IS_VALID(pAddress))135 return false;136 /* more? */137 return true;138 } -
trunk/src/VBox/VMM/Makefile.kmk
r5646 r5667 57 57 DBGFInfo.cpp \ 58 58 DBGFLog.cpp \ 59 DBGFMem.cpp \ 59 60 DBGFStack.cpp \ 60 61 DBGFSym.cpp \ -
trunk/src/VBox/VMM/PGMDbg.cpp
r4665 r5667 26 26 #include <iprt/assert.h> 27 27 #include <iprt/asm.h> 28 #include <iprt/string.h> 28 29 #include <VBox/log.h> 29 30 #include <VBox/param.h> 30 31 #include <VBox/err.h> 31 32 32 33 34 /** 35 * Converts a HC pointer to a GC physical address. 36 * 33 /** The max needle size that we will bother searching for 34 * This must not be more than half a page! */ 35 #define MAX_NEEDLE_SIZE 256 36 37 38 /** 39 * Converts a HC pointer to a GC physical address. 40 * 37 41 * Only for the debugger. 38 42 * … … 40 44 * @retval VINF_SUCCESS on success, *pGCPhys is set. 41 45 * @retval VERR_INVALID_POINTER if the pointer is not within the GC physical memory. 42 * 46 * 43 47 * @param pVM The VM handle. 44 48 * @param HCPtr The HC pointer to convert. … … 93 97 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical page but has no physical backing. 94 98 * @retval VERR_INVALID_POINTER if the pointer is not within the GC physical memory. 95 * 99 * 96 100 * @param pVM The VM handle. 97 101 * @param HCPtr The HC pointer to convert. … … 149 153 /** 150 154 * Converts a HC physical address to a GC physical address. 151 * 155 * 152 156 * Only for the debugger. 153 157 * … … 155 159 * @retval VINF_SUCCESS on success, *pGCPhys is set. 156 160 * @retval VERR_INVALID_POINTER if the HC physical address is not within the GC physical memory. 157 * 161 * 158 162 * @param pVM The VM handle. 159 163 * @param HCPhys The HC physical address to convert. … … 189 193 190 194 195 /** 196 * Scans a page for a byte string, keeping track of potential 197 * cross page matches. 198 * 199 * @returns true and *poff on match. 200 * false on mismatch. 201 * @param pbPage Pointer to the current page. 202 * @param poff Input: The offset into the page. 203 * Output: The page offset of the match on success. 204 * @param cb The number of bytes to search, starting of *poff. 205 * @param pabNeedle The byte string to search for. 206 * @param cbNeedle The length of the byte string. 207 * @param pabPrev The buffer that keeps track of a partial match that we 208 * bring over from the previous page. This buffer must be 209 * at least cbNeedle - 1 big. 210 * @param pcbPrev Input: The number of partial matching bytes from the previous page. 211 * Output: The number of partial matching bytes from this page. 212 * Initialize to 0 before the first call to this function. 213 */ 214 static bool pgmR3DbgScanPage(const uint8_t *pbPage, int32_t *poff, uint32_t cb, 215 const uint8_t *pabNeedle, size_t cbNeedle, 216 uint8_t *pabPrev, size_t *pcbPrev) 217 { 218 /* 219 * Try complete any partial match from the previous page. 220 */ 221 if (*pcbPrev > 0) 222 { 223 size_t cbPrev = *pcbPrev; 224 Assert(!*poff); 225 Assert(cbPrev < cbNeedle); 226 if (!memcmp(pbPage, pabNeedle + cbPrev, cbNeedle - cbPrev)) 227 { 228 if (cbNeedle - cbPrev > cb) 229 return false; 230 *poff = -(int32_t)cbPrev; 231 return true; 232 } 233 234 /* check out the remainder of the previous page. */ 235 const uint8_t *pb = pabPrev; 236 while (cbPrev-- > 0) 237 { 238 pb = (const uint8_t *)memchr(pb + 1, *pabNeedle, cbPrev); 239 if (!pb) 240 break; 241 cbPrev = *pcbPrev - (pb - pabPrev); 242 if ( !memcmp(pb + 1, &pabNeedle[1], cbPrev - 1) 243 && !memcmp(pbPage, pabNeedle + cbPrev, cbNeedle - cbPrev)) 244 { 245 if (cbNeedle - cbPrev > cb) 246 return false; 247 *poff = -(int32_t)cbPrev; 248 return true; 249 } 250 } 251 252 *pcbPrev = 0; 253 } 254 255 /* 256 * Match the body of the page. 257 */ 258 const uint8_t *pb = pbPage + *poff; 259 const uint8_t *pbEnd = pb + cb; 260 for (;;) 261 { 262 pb = (const uint8_t *)memchr(pb, *pabNeedle, cb); 263 if (!pb) 264 break; 265 cb = pbEnd - pb; 266 if (cb <= cbNeedle) 267 { 268 /* match? */ 269 if (!memcmp(pb + 1, &pabNeedle[1], cbNeedle - 1)) 270 { 271 *poff = pb - pbPage; 272 return true; 273 } 274 } 275 else 276 { 277 /* paritial match at the end of the page? */ 278 if (!memcmp(pb + 1, &pabNeedle[1], cb - 1)) 279 { 280 /* We're copying one byte more that we really need here, but wtf. */ 281 memcpy(pabPrev, pb, cb); 282 *pcbPrev = cb; 283 return false; 284 } 285 } 286 287 /* no match, skip a byte ahead. */ 288 if (cb <= 1) 289 break; 290 pb++; 291 } 292 293 return false; 294 } 295 296 297 /** 298 * Scans guest physical memory for a byte string. 299 * 300 * @returns VBox status codes: 301 * @retval VINF_SUCCESS and *pGCPtrHit on success. 302 * @retval VERR_DBGF_MEM_NOT_FOUND if not found. 303 * @retval VERR_INVALID_POINTER if any of the pointer arguments are invalid. 304 * @retval VERR_INVALID_ARGUMENT if any other arguments are invalid. 305 * 306 * @param pVM Pointer to the shared VM structure. 307 * @param GCPhys Where to start searching. 308 * @param cbRange The number of bytes to search. 309 * @param pabNeedle The byte string to search for. 310 * @param cbNeedle The length of the byte string. Max 256 bytes. 311 * @param pGCPhysHit Where to store the address of the first occurence on success. 312 */ 313 PDMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit) 314 { 315 /* 316 * Validate and adjust the input a bit. 317 */ 318 if (!VALID_PTR(pGCPhysHit)) 319 return VERR_INVALID_POINTER; 320 *pGCPhysHit = NIL_RTGCPHYS; 321 322 if ( !VALID_PTR(pabNeedle) 323 || GCPhys == NIL_RTGCPHYS) 324 return VERR_INVALID_POINTER; 325 if (!cbNeedle) 326 return VERR_INVALID_PARAMETER; 327 if (cbRange > MAX_NEEDLE_SIZE) 328 return VERR_INVALID_PARAMETER; 329 330 if (!cbRange) 331 return VERR_DBGF_MEM_NOT_FOUND; 332 if (GCPhys + cbNeedle - 1 < GCPhys) 333 return VERR_DBGF_MEM_NOT_FOUND; 334 335 const RTGCPHYS GCPhysLast = GCPhys + cbRange - 1 >= GCPhys 336 ? GCPhys + cbRange - 1 337 : ~(RTGCPHYS)0; 338 339 /* 340 * Search the memory - ignore MMIO and zero pages, also don't 341 * bother to match across ranges. 342 */ 343 for (PPGMRAMRANGE pRam = CTXSUFF(pVM->pgm.s.pRamRanges); 344 pRam; 345 pRam = CTXSUFF(pRam->pNext)) 346 { 347 /* 348 * If the search range starts prior to the current ram range record, 349 * adjust the search range and possibly conclude the search. 350 */ 351 RTGCPHYS off; 352 if (GCPhys < pRam->GCPhys) 353 { 354 if (GCPhysLast < pRam->GCPhys) 355 break; 356 GCPhys = pRam->GCPhys; 357 off = 0; 358 } 359 else 360 off = GCPhys - pRam->GCPhys; 361 if (off < pRam->cb) 362 { 363 /* 364 * Iterate the relevant pages. 365 */ 366 uint8_t abPrev[MAX_NEEDLE_SIZE]; 367 size_t cbPrev = 0; 368 const uint32_t cPages = pRam->cb >> PAGE_SHIFT; 369 for (uint32_t iPage = off >> PAGE_SHIFT; iPage < cPages; iPage++) 370 { 371 PPGMPAGE pPage = &pRam->aPages[iPage]; 372 if ( !PGM_PAGE_IS_ZERO(pPage) 373 && !PGM_PAGE_IS_MMIO(pPage)) 374 { 375 void const *pvPage; 376 PGMPAGEMAPLOCK Lock; 377 int rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK, &pvPage, &Lock); 378 if (RT_SUCCESS(rc)) 379 { 380 int32_t offPage = (GCPhys & PAGE_OFFSET_MASK); 381 uint32_t cbSearch = (GCPhys ^ GCPhysLast) & ~(RTGCPHYS)PAGE_OFFSET_MASK 382 ? PAGE_SIZE - (uint32_t)offPage 383 : (GCPhysLast & PAGE_OFFSET_MASK) + 1 - (uint32_t)offPage; 384 bool fRc = pgmR3DbgScanPage((uint8_t const *)pvPage, &offPage, cbSearch, 385 pabNeedle, cbNeedle, &abPrev[0], &cbPrev); 386 PGMPhysReleasePageMappingLock(pVM, &Lock); 387 if (fRc) 388 { 389 *pGCPhysHit = (GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK) + offPage; 390 return VINF_SUCCESS; 391 } 392 } 393 else 394 cbPrev = 0; /* ignore error. */ 395 } 396 else 397 cbPrev = 0; 398 399 /* advance to the the next page. */ 400 GCPhys |= PAGE_OFFSET_MASK; 401 if (GCPhys++ >= GCPhysLast) 402 return VERR_DBGF_MEM_NOT_FOUND; 403 } 404 } 405 } 406 return VERR_DBGF_MEM_NOT_FOUND; 407 } 408 409 410 /** 411 * Scans (guest) virtual memory for a byte string. 412 * 413 * @returns VBox status codes: 414 * @retval VINF_SUCCESS and *pGCPtrHit on success. 415 * @retval VERR_DBGF_MEM_NOT_FOUND if not found. 416 * @retval VERR_INVALID_POINTER if any of the pointer arguments are invalid. 417 * @retval VERR_INVALID_ARGUMENT if any other arguments are invalid. 418 * 419 * @param pVM Pointer to the shared VM structure. 420 * @param GCPtr Where to start searching. 421 * @param cbRange The number of bytes to search. Max 256 bytes. 422 * @param pabNeedle The byte string to search for. 423 * @param cbNeedle The length of the byte string. 424 * @param pGCPtrHit Where to store the address of the first occurence on success. 425 */ 426 PDMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, RTGCUINTPTR GCPtr, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPtrHit) 427 { 428 /* 429 * Validate and adjust the input a bit. 430 */ 431 if (!VALID_PTR(pGCPtrHit)) 432 return VERR_INVALID_POINTER; 433 *pGCPtrHit = 0; 434 435 if (!VALID_PTR(pabNeedle)) 436 return VERR_INVALID_POINTER; 437 if (!cbNeedle) 438 return VERR_INVALID_PARAMETER; 439 if (cbRange > MAX_NEEDLE_SIZE) 440 return VERR_INVALID_PARAMETER; 441 442 if (!cbRange) 443 return VERR_DBGF_MEM_NOT_FOUND; 444 if (GCPtr + cbNeedle - 1 < GCPtr) 445 return VERR_DBGF_MEM_NOT_FOUND; 446 447 /* 448 * Search the memory - ignore MMIO, zero and not-present pages. 449 */ 450 uint8_t abPrev[MAX_NEEDLE_SIZE]; 451 size_t cbPrev = 0; 452 const RTGCUINTPTR GCPtrLast = GCPtr + cbRange - 1 >= GCPtr 453 ? GCPtr + cbRange - 1 454 : ~(RTGCUINTPTR)0; 455 RTGCUINTPTR cPages = (((GCPtrLast - GCPtr) + (GCPtr & PAGE_OFFSET_MASK)) >> PAGE_SHIFT) + 1; 456 while (cPages-- > 0) 457 { 458 uint64_t fFlags; 459 RTGCPHYS GCPhys; 460 int rc = PGMGstGetPage(pVM, GCPtr, &fFlags, &GCPhys); 461 if (RT_SUCCESS(rc)) 462 { 463 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys); 464 if ( pPage 465 && !PGM_PAGE_IS_ZERO(pPage) 466 && !PGM_PAGE_IS_MMIO(pPage)) 467 { 468 void const *pvPage; 469 PGMPAGEMAPLOCK Lock; 470 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPtr & ~(RTGCUINTPTR)PAGE_OFFSET_MASK, &pvPage, &Lock); 471 if (RT_SUCCESS(rc)) 472 { 473 int32_t offPage = (GCPtr & PAGE_OFFSET_MASK); 474 uint32_t cbSearch = cPages > 0 475 ? PAGE_SIZE - (uint32_t)offPage 476 : (GCPtrLast & PAGE_OFFSET_MASK) + 1 - (uint32_t)offPage; 477 bool fRc = pgmR3DbgScanPage((uint8_t const *)pvPage, &offPage, cbSearch, 478 pabNeedle, cbNeedle, &abPrev[0], &cbPrev); 479 PGMPhysReleasePageMappingLock(pVM, &Lock); 480 if (fRc) 481 { 482 *pGCPtrHit = (GCPtr & ~(RTGCUINTPTR)PAGE_OFFSET_MASK) + offPage; 483 return VINF_SUCCESS; 484 } 485 } 486 else 487 cbPrev = 0; /* ignore error. */ 488 } 489 else 490 cbPrev = 0; 491 } 492 else 493 cbPrev = 0; /* ignore error. */ 494 } 495 return VERR_DBGF_MEM_NOT_FOUND; 496 } 497 -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r5323 r5667 625 625 * @thread Any thread. 626 626 */ 627 PGMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void * const*ppv, PPGMPAGEMAPLOCK pLock)627 PGMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGMPAGEMAPLOCK pLock) 628 628 { 629 629 /** @todo implement this */ … … 692 692 * @thread EMT 693 693 */ 694 PGMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void * const*ppv, PPGMPAGEMAPLOCK pLock)694 PGMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void const **ppv, PPGMPAGEMAPLOCK pLock) 695 695 { 696 696 RTGCPHYS GCPhys;
Note:
See TracChangeset
for help on using the changeset viewer.