VirtualBox

Changeset 5667

Show
Ignore:
Timestamp:
11/11/07 05:28:47 (1 year ago)
Author:
vboxsync
Message:

Debugger interface for searching memory. Fixed a const mixup.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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

    r4212 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; 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy