VirtualBox

Changeset 5667 in vbox


Ignore:
Timestamp:
Nov 11, 2007 4:28:47 AM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
26011
Message:

Debugger interface for searching memory. Fixed a const mixup.

Location:
trunk
Files:
9 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/dbgf.h

    r5605 r5667  
    131131/** A flat address. */
    132132#define DBGFADDRESS_FLAGS_FLAT          3
     133/** A physical address. */
     134#define DBGFADDRESS_FLAGS_PHYS          4
    133135/** The address type mask. */
    134 #define DBGFADDRESS_FLAGS_TYPE_MASK     3
     136#define DBGFADDRESS_FLAGS_TYPE_MASK     7
    135137
    136138/** Set if the address is valid. */
    137 #define DBGFADDRESS_FLAGS_VALID         RT_BIT(2)
     139#define DBGFADDRESS_FLAGS_VALID         RT_BIT(3)
    138140
    139141/** The address is within the hypervisor memoary area (HMA).
    140142 * If not set, the address can be assumed to be a guest address. */
    141 #define DBGFADDRESS_FLAGS_HMA           RT_BIT(3)
     143#define DBGFADDRESS_FLAGS_HMA           RT_BIT(4)
    142144
    143145/** Checks if the mixed address is flat or not. */
    144146#define DBGFADDRESS_IS_FLAT(pAddress)    ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FLAT )
     147/** Checks if the mixed address is flat or not. */
     148#define DBGFADDRESS_IS_PHYS(pAddress)    ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_PHYS )
    145149/** Checks if the mixed address is far 16:16 or not. */
    146150#define DBGFADDRESS_IS_FAR16(pAddress)   ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR16 )
     
    150154#define DBGFADDRESS_IS_FAR64(pAddress)   ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR64 )
    151155/** Checks if the mixed address is valid. */
    152 #define DBGFADDRESS_IS_VALID(pAddress)   ( (pAddress)->fFlags & DBGFADDRESS_FLAGS_VALID )
     156#define DBGFADDRESS_IS_VALID(pAddress)   ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_VALID) )
     157/** Checks if the address is flagged as within the HMA. */
     158#define DBGFADDRESS_IS_HMA(pAddress)     ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_HMA) )
    153159/** @} */
    154160
     
    172178 */
    173179DBGFR3DECL(void) DBGFR3AddrFromFlat(PVM pVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr);
     180
     181/**
     182 * Creates a mixed address from a guest physical address.
     183 *
     184 * @param   pVM         The VM handle.
     185 * @param   pAddress    Where to store the mixed address.
     186 * @param   PhysAddr    The guest physical address.
     187 */
     188DBGFR3DECL(void) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
    174189
    175190/**
  • trunk/include/VBox/err.h

    r5513 r5667  
    224224/** The breakpoint already exists. */
    225225#define VINF_DBGF_BP_ALREADY_EXIST          1207
     226/** The byte string was not found. */
     227#define VERR_DBGF_MEM_NOT_FOUND             (-1208)
    226228/** @} */
    227229
  • trunk/include/VBox/pgm.h

    r5040 r5667  
    810810/**
    811811 * Invalidates the GC page mapping TLB.
    812  * 
     812 *
    813813 * @param   pVM     The VM handle.
    814814 */
     
    817817/**
    818818 * Invalidates the ring-0 page mapping TLB.
    819  * 
     819 *
    820820 * @param   pVM     The VM handle.
    821821 */
     
    824824/**
    825825 * Invalidates the ring-3 page mapping TLB.
    826  * 
     826 *
    827827 * @param   pVM     The VM handle.
    828828 */
    829829PDMDECL(void) PGMPhysInvalidatePageR3MapTLB(PVM pVM);
    830830
    831 /** 
     831/**
    832832 * Page mapping lock.
    833  * 
    834  * @remarks This doesn't work in structures shared between 
     833 *
     834 * @remarks This doesn't work in structures shared between
    835835 *          ring-3, ring-0 and/or GC.
    836836 */
     
    857857 * scarse resources (R0 and GC) in the mapping cache. When you're done
    858858 * with the page, call PGMPhysReleasePageMappingLock() ASAP to release it.
    859  * 
    860  * This API will assume your intention is to write to the page, and will 
    861  * therefore replace shared and zero pages. If you do not intend to modify 
     859 *
     860 * This API will assume your intention is to write to the page, and will
     861 * therefore replace shared and zero pages. If you do not intend to modify
    862862 * the page, use the PGMPhysGCPhys2CCPtrReadOnly() API.
    863863 *
     
    899899 * @thread  Any thread.
    900900 */
    901 PGMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void * const *ppv, PPGMPAGEMAPLOCK pLock);
     901PGMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGMPAGEMAPLOCK pLock);
    902902
    903903/**
     
    908908 * with the page, call PGMPhysReleasePageMappingLock() ASAP to release it.
    909909 *
    910  * This API will assume your intention is to write to the page, and will 
    911  * therefore replace shared and zero pages. If you do not intend to modify 
     910 * This API will assume your intention is to write to the page, and will
     911 * therefore replace shared and zero pages. If you do not intend to modify
    912912 * the page, use the PGMPhysGCPtr2CCPtrReadOnly() API.
    913913 *
     
    953953 * @thread  EMT
    954954 */
    955 PGMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void * const *ppv, PPGMPAGEMAPLOCK pLock);
     955PGMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void const **ppv, PPGMPAGEMAPLOCK pLock);
    956956
    957957/**
    958958 * Release the mapping of a guest page.
    959  * 
     959 *
    960960 * This is the counter part of PGMPhysGCPhys2CCPtr, PGMPhysGCPhys2CCPtrReadOnly
    961961 * PGMPhysGCPtr2CCPtr and PGMPhysGCPtr2CCPtrReadOnly.
     
    969969/**
    970970 * Checks if the lock structure is valid
    971  * 
     971 *
    972972 * @param   pVM         The VM handle.
    973973 * @param   pLock       The lock structure initialized by the mapping function.
     
    13111311 * @{
    13121312 */
    1313 /** 
     1313/**
    13141314 * Worker function for PGMR3PhysAllocateHandyPages and pgmPhysEnsureHandyPage.
    1315  * 
     1315 *
    13161316 * @returns The following VBox status codes.
    13171317 * @retval  VINF_SUCCESS on success. FF cleared.
    13181318 * @retval  VINF_EM_NO_MEMORY if we're out of memory. The FF is set in this case.
    1319  * 
    1320  * @param   pVM         The VM handle.
    1321  * 
     1319 *
     1320 * @param   pVM         The VM handle.
     1321 *
    13221322 * @remarks Must be called from within the PGM critical section.
    13231323 */
     
    13251325
    13261326/** @} */
    1327 #endif 
     1327#endif
    13281328
    13291329
     
    17841784/**
    17851785 * For VMMCALLHOST_PGM_MAP_CHUNK, considered internal.
    1786  * 
     1786 *
    17871787 * @returns see pgmR3PhysChunkMap.
    17881788 * @param   pVM         The VM handle.
     
    17931793/**
    17941794 * Invalidates the TLB for the ring-3 mapping cache.
    1795  * 
     1795 *
    17961796 * @param   pVM         The VM handle.
    17971797 */
     
    18001800/**
    18011801 * Response to VM_FF_PGM_NEED_HANDY_PAGES and VMMCALLHOST_PGM_ALLOCATE_HANDY_PAGES.
    1802  * 
     1802 *
    18031803 * @returns VBox status code.
    18041804 * @retval  VINF_SUCCESS on success. FF cleared.
    18051805 * @retval  VINF_EM_NO_MEMORY if we're out of memory. The FF is not cleared in this case.
    1806  * 
     1806 *
    18071807 * @param   pVM         The VM handle.
    18081808 */
     
    18191819
    18201820/**
    1821  * Converts a HC pointer to a GC physical address. 
    1822  * 
     1821 * Converts a HC pointer to a GC physical address.
     1822 *
    18231823 * Only for the debugger.
    18241824 *
     
    18261826 * @retval  VINF_SUCCESS on success, *pGCPhys is set.
    18271827 * @retval  VERR_INVALID_POINTER if the pointer is not within the GC physical memory.
    1828  * 
     1828 *
    18291829 * @param   pVM     The VM handle.
    18301830 * @param   HCPtr   The HC pointer to convert.
     
    18401840 * @retval  VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical page but has no physical backing.
    18411841 * @retval  VERR_INVALID_POINTER if the pointer is not within the GC physical memory.
    1842  * 
     1842 *
    18431843 * @param   pVM     The VM handle.
    18441844 * @param   HCPtr   The HC pointer to convert.
     
    18491849/**
    18501850 * Converts a HC physical address to a GC physical address.
    1851  * 
     1851 *
    18521852 * Only for the debugger.
    18531853 *
     
    18551855 * @retval  VINF_SUCCESS on success, *pGCPhys is set.
    18561856 * @retval  VERR_INVALID_POINTER if the HC physical address is not within the GC physical memory.
    1857  * 
     1857 *
    18581858 * @param   pVM     The VM handle.
    18591859 * @param   HCPhys  The HC physical address to convert.
     
    18621862PGMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys);
    18631863
     1864/**
     1865 * Scans guest physical memory for a byte string.
     1866 *
     1867 * Only for the debugger.
     1868 *
     1869 * @returns VBox status codes:
     1870 * @retval  VINF_SUCCESS and *pGCPtrHit on success.
     1871 * @retval  VERR_DBGF_MEM_NOT_FOUND if not found.
     1872 * @retval  VERR_INVALID_POINTER if any of the pointer arguments are invalid.
     1873 * @retval  VERR_INVALID_ARGUMENT if any other arguments are invalid.
     1874 *
     1875 * @param   pVM             Pointer to the shared VM structure.
     1876 * @param   GCPhys          Where to start searching.
     1877 * @param   cbRange         The number of bytes to search. Max 256 bytes.
     1878 * @param   pabNeedle       The byte string to search for.
     1879 * @param   cbNeedle        The length of the byte string.
     1880 * @param   pGCPhysHit      Where to store the address of the first occurence on success.
     1881 */
     1882PDMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit);
     1883
     1884/**
     1885 * Scans virtual memory for a byte string.
     1886 *
     1887 * Only for the debugger.
     1888 *
     1889 * @returns VBox status codes:
     1890 * @retval  VINF_SUCCESS and *pGCPtrHit on success.
     1891 * @retval  VERR_DBGF_MEM_NOT_FOUND if not found.
     1892 * @retval  VERR_INVALID_POINTER if any of the pointer arguments are invalid.
     1893 * @retval  VERR_INVALID_ARGUMENT if any other arguments are invalid.
     1894 *
     1895 * @param   pVM             Pointer to the shared VM structure.
     1896 * @param   GCPtr           Where to start searching.
     1897 * @param   cbRange         The number of bytes to search. Max 256 bytes.
     1898 * @param   pabNeedle       The byte string to search for.
     1899 * @param   cbNeedle        The length of the byte string.
     1900 * @param   pGCPtrHit       Where to store the address of the first occurence on success.
     1901 */
     1902PDMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, RTGCUINTPTR GCPtr, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit);
     1903
    18641904/** @} */
    18651905
  • 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