VirtualBox

Changeset 5667 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 11, 2007 4:28:47 AM (17 years ago)
Author:
vboxsync
Message:

Debugger interface for searching memory. Fixed a const mixup.

Location:
trunk/src/VBox/VMM
Files:
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/CPUM.cpp

    r5605 r5667  
    16361636    RTGCUINTPTR     cbSegLimit;
    16371637    /** Pointer to the current page - HC Ptr. */
    1638     void           *pvPageHC;
     1638    void const     *pvPageHC;
    16391639    /** Pointer to the current page - GC Ptr. */
    16401640    RTGCPTR         pvPageGC;
  • trunk/src/VBox/VMM/DBGFAddr.cpp

    r4212 r5667  
    121121
    122122/**
     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 */
     129DBGFR3DECL(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/**
    123139 * Checks if the specified address is valid (checks the structure pointer too).
    124140 *
  • trunk/src/VBox/VMM/DBGFDisas.cpp

    r5624 r5667  
    6262    PGMMODE         enmMode;
    6363    /** Pointer to the current page - HC Ptr. */
    64     void           *pvPageHC;
     64    void const     *pvPageHC;
    6565    /** Pointer to the current page - GC Ptr. */
    6666    RTGCPTR         pvPageGC;
     
    163163 *                      In this context it's always pointer to the Core of a DBGFDISASSTATE.
    164164 */
    165 static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTHCUINTPTR PtrSrc, uint8_t *pu8Dst, unsigned cbRead, void *pvDisCpu)
     165static DECLCALLBACK(int) dbgfR3DisasInstrRead(RTHCUINTPTR PtrSrc, uint8_t *pu8Dst, uint32_t cbRead, void *pvDisCpu)
    166166{
    167167    PDBGFDISASSTATE pState = (PDBGFDISASSTATE)pvDisCpu;
     
    569569    else
    570570    {
    571         size_t cbBits = State.Cpu.opsize;
     571        uint32_t cbBits = State.Cpu.opsize;
    572572        uint8_t *pau8Bits = (uint8_t *)alloca(cbBits);
    573573        rc = dbgfR3DisasInstrRead(GCPtr, pau8Bits, cbBits, &State);
  • trunk/src/VBox/VMM/DBGFMem.cpp

    r5659 r5667  
    11/* $Id$ */
    22/** @file
    3  * VMM DBGF - Debugger Facility, Mixed Address Methods.
     3 * VMM DBGF - Debugger Facility, Memory Methods.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 innotek GmbH
     7 * Copyright (C) 2007 innotek GmbH
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2222#define LOG_GROUP LOG_GROUP_DBGF
    2323#include <VBox/dbgf.h>
    24 #include <VBox/selm.h>
     24#include <VBox/pgm.h>
    2525#include "DBGFInternal.h"
    2626#include <VBox/vm.h>
    27 #include <VBox/mm.h>
    2827#include <VBox/err.h>
    2928#include <VBox/log.h>
     
    3231
    3332/**
    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.
    3736 * @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.
    3942 */
    40 DECLINLINE(bool) dbgfR3IsHMA(PVM pVM, RTGCUINTPTR FlatPtr)
     43static DECLCALLBACK(int) dbgfR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle,
     44                                       PDBGFADDRESS pHitAddress)
    4145{
    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;
    4380}
    4481
    4582
    4683/**
    47  * Creates a mixed address from a Sel:off pair.
     84 * Scan guest memory for an exact byte string.
    4885 *
    4986 * @returns VBox status code.
    5087 * @param   pVM         The VM handle.
    5188 * @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.
    5495 */
    55 DBGFR3DECL(int) DBGFR3AddrFromSelOff(PVM pVM, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off)
     96DBGFR3DECL(int) DBGFR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress)
    5697{
    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);
    65104
    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;
    101106}
    102107
    103108
    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  
    5757        DBGFInfo.cpp \
    5858        DBGFLog.cpp \
     59        DBGFMem.cpp \
    5960        DBGFStack.cpp \
    6061        DBGFSym.cpp \
  • trunk/src/VBox/VMM/PGMDbg.cpp

    r4665 r5667  
    2626#include <iprt/assert.h>
    2727#include <iprt/asm.h>
     28#include <iprt/string.h>
    2829#include <VBox/log.h>
    2930#include <VBox/param.h>
    3031#include <VBox/err.h>
    3132
    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 *
    3741 * Only for the debugger.
    3842 *
     
    4044 * @retval  VINF_SUCCESS on success, *pGCPhys is set.
    4145 * @retval  VERR_INVALID_POINTER if the pointer is not within the GC physical memory.
    42  * 
     46 *
    4347 * @param   pVM     The VM handle.
    4448 * @param   HCPtr   The HC pointer to convert.
     
    9397 * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical page but has no physical backing.
    9498 * @retval  VERR_INVALID_POINTER if the pointer is not within the GC physical memory.
    95  * 
     99 *
    96100 * @param   pVM     The VM handle.
    97101 * @param   HCPtr   The HC pointer to convert.
     
    149153/**
    150154 * Converts a HC physical address to a GC physical address.
    151  * 
     155 *
    152156 * Only for the debugger.
    153157 *
     
    155159 * @retval  VINF_SUCCESS on success, *pGCPhys is set.
    156160 * @retval  VERR_INVALID_POINTER if the HC physical address is not within the GC physical memory.
    157  * 
     161 *
    158162 * @param   pVM     The VM handle.
    159163 * @param   HCPhys  The HC physical address to convert.
     
    189193
    190194
     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 */
     214static 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 */
     313PDMR3DECL(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 */
     426PDMR3DECL(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  
    625625 * @thread  Any thread.
    626626 */
    627 PGMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void * const *ppv, PPGMPAGEMAPLOCK pLock)
     627PGMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGMPAGEMAPLOCK pLock)
    628628{
    629629    /** @todo implement this */
     
    692692 * @thread  EMT
    693693 */
    694 PGMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void * const *ppv, PPGMPAGEMAPLOCK pLock)
     694PGMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void const **ppv, PPGMPAGEMAPLOCK pLock)
    695695{
    696696    RTGCPHYS GCPhys;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette