PGMDbg.cpp revision 6a9b5d2a23485ebbd7b1063849d37bc5a8ef44d4
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/* $Id$ */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** @file
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * PGM - Page Manager and Monitor - Debugger & Debugging APIs.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/*
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * available from http://www.virtualbox.org. This file is free software;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * you can redistribute it and/or modify it under the terms of the GNU
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * General Public License (GPL) as published by the Free Software
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * additional information or have any questions.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/*******************************************************************************
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync* Header Files *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync*******************************************************************************/
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#define LOG_GROUP LOG_GROUP_PGM
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#include <VBox/pgm.h>
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#include <VBox/stam.h>
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#include "PGMInternal.h"
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#include <VBox/vm.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <iprt/assert.h>
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync#include <iprt/asm.h>
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#include <iprt/string.h>
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#include <VBox/log.h>
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#include <VBox/param.h>
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#include <VBox/err.h>
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/** The max needle size that we will bother searching for
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * This must not be more than half a page! */
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync#define MAX_NEEDLE_SIZE 256
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/**
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Converts a R3 pointer to a GC physical address.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Only for the debugger.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VBox status code.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @retval VINF_SUCCESS on success, *pGCPhys is set.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @retval VERR_INVALID_POINTER if the pointer is not within the GC physical memory.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param R3Ptr The R3 pointer to convert.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pGCPhys Where to store the GC physical address on success.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync */
060711075893fd64c1eaaefe41f318d83011e4e3vboxsyncVMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PVM pVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys)
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync{
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync#ifdef VBOX_WITH_NEW_PHYS_CODE
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync *pGCPhys = NIL_RTGCPHYS;
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync return VERR_NOT_IMPLEMENTED;
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync#else
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync pRam;
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync pRam = pRam->CTX_SUFF(pNext))
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync {
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync if (pRam->fFlags & MM_RAM_FLAGS_DYNAMIC_ALLOC)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (unsigned iChunk = 0; iChunk < (pRam->cb >> PGM_DYNAMIC_CHUNK_SHIFT); iChunk++)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (pRam->paChunkR3Ptrs[iChunk])
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTR3UINTPTR off = (RTR3UINTPTR)R3Ptr - pRam->paChunkR3Ptrs[iChunk];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (off < PGM_DYNAMIC_CHUNK_SIZE)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pGCPhys = pRam->GCPhys + iChunk*PGM_DYNAMIC_CHUNK_SIZE + off;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VINF_SUCCESS;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync else if (pRam->pvR3)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTR3UINTPTR off = (RTR3UINTPTR)R3Ptr - (RTR3UINTPTR)pRam->pvR3;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (off < pRam->cb)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pGCPhys = pRam->GCPhys + off;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VINF_SUCCESS;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_POINTER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#endif
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync}
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/**
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Converts a R3 pointer to a HC physical address.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Only for the debugger.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VBox status code.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @retval VINF_SUCCESS on success, *pHCPhys is set.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid GC physical page but has no physical backing.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @retval VERR_INVALID_POINTER if the pointer is not within the GC physical memory.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param R3Ptr The R3 pointer to convert.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pHCPhys Where to store the HC physical address on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncVMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PVM pVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync{
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#ifdef VBOX_WITH_NEW_PHYS_CODE
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pHCPhys = NIL_RTHCPHYS;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_NOT_IMPLEMENTED;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#else
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync pRam;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync pRam = pRam->CTX_SUFF(pNext))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (pRam->fFlags & MM_RAM_FLAGS_DYNAMIC_ALLOC)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (unsigned iChunk = 0; iChunk < (pRam->cb >> PGM_DYNAMIC_CHUNK_SHIFT); iChunk++)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (pRam->paChunkR3Ptrs[iChunk])
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTR3UINTPTR off = (RTR3UINTPTR)R3Ptr - pRam->paChunkR3Ptrs[iChunk];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (off < PGM_DYNAMIC_CHUNK_SIZE)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync PPGMPAGE pPage = &pRam->aPages[off >> PAGE_SHIFT];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (PGM_PAGE_IS_RESERVED(pPage))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_PGM_PHYS_PAGE_RESERVED;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pHCPhys = PGM_PAGE_GET_HCPHYS(pPage)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync | (off & PAGE_OFFSET_MASK);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VINF_SUCCESS;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync else if (pRam->pvR3)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTR3UINTPTR off = (RTR3UINTPTR)R3Ptr - (RTR3UINTPTR)pRam->pvR3;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (off < pRam->cb)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync PPGMPAGE pPage = &pRam->aPages[off >> PAGE_SHIFT];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (PGM_PAGE_IS_RESERVED(pPage))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_PGM_PHYS_PAGE_RESERVED;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pHCPhys = PGM_PAGE_GET_HCPHYS(pPage)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync | (off & PAGE_OFFSET_MASK);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VINF_SUCCESS;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_POINTER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync#endif
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync}
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/**
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Converts a HC physical address to a GC physical address.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync *
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * Only for the debugger.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync *
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @returns VBox status code
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @retval VINF_SUCCESS on success, *pGCPhys is set.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * @retval VERR_INVALID_POINTER if the HC physical address is not within the GC physical memory.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM The VM handle.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param HCPhys The HC physical address to convert.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pGCPhys Where to store the GC physical address on success.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync */
060711075893fd64c1eaaefe41f318d83011e4e3vboxsyncVMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys)
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync{
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync /*
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * Validate and adjust the input a bit.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync */
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync if (HCPhys == NIL_RTHCPHYS)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_POINTER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync unsigned off = HCPhys & PAGE_OFFSET_MASK;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync HCPhys &= X86_PTE_PAE_PG_MASK;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (HCPhys == 0)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_POINTER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync pRam;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync pRam = pRam->CTX_SUFF(pNext))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync uint32_t iPage = pRam->cb >> PAGE_SHIFT;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync while (iPage-- > 0)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if ( PGM_PAGE_GET_HCPHYS(&pRam->aPages[iPage]) == HCPhys
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync && !PGM_PAGE_IS_RESERVED(&pRam->aPages[iPage]))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pGCPhys = pRam->GCPhys + (iPage << PAGE_SHIFT) + off;
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync return VINF_SUCCESS;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_POINTER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync}
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/**
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Scans a page for a byte string, keeping track of potential
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * cross page matches.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns true and *poff on match.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * false on mismatch.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pbPage Pointer to the current page.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param poff Input: The offset into the page.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Output: The page offset of the match on success.
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync * @param cb The number of bytes to search, starting of *poff.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pabNeedle The byte string to search for.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param cbNeedle The length of the byte string.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pabPrev The buffer that keeps track of a partial match that we
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * bring over from the previous page. This buffer must be
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * at least cbNeedle - 1 big.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pcbPrev Input: The number of partial matching bytes from the previous page.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Output: The number of partial matching bytes from this page.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Initialize to 0 before the first call to this function.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
060711075893fd64c1eaaefe41f318d83011e4e3vboxsyncstatic bool pgmR3DbgScanPage(const uint8_t *pbPage, int32_t *poff, uint32_t cb,
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync const uint8_t *pabNeedle, size_t cbNeedle,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync uint8_t *pabPrev, size_t *pcbPrev)
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync{
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync /*
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync * Try complete any partial match from the previous page.
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync */
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync if (*pcbPrev > 0)
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync {
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync size_t cbPrev = *pcbPrev;
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync Assert(!*poff);
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync Assert(cbPrev < cbNeedle);
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync if (!memcmp(pbPage, pabNeedle + cbPrev, cbNeedle - cbPrev))
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (cbNeedle - cbPrev > cb)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return false;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *poff = -(int32_t)cbPrev;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return true;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /* check out the remainder of the previous page. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync const uint8_t *pb = pabPrev;
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync while (cbPrev-- > 0)
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync {
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync pb = (const uint8_t *)memchr(pb + 1, *pabNeedle, cbPrev);
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync if (!pb)
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync break;
060711075893fd64c1eaaefe41f318d83011e4e3vboxsync cbPrev = *pcbPrev - (pb - pabPrev);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if ( !memcmp(pb + 1, &pabNeedle[1], cbPrev - 1)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync && !memcmp(pbPage, pabNeedle + cbPrev, cbNeedle - cbPrev))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (cbNeedle - cbPrev > cb)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return false;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *poff = -(int32_t)cbPrev;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return true;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pcbPrev = 0;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /*
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Match the body of the page.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync const uint8_t *pb = pbPage + *poff;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync const uint8_t *pbEnd = pb + cb;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (;;)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync pb = (const uint8_t *)memchr(pb, *pabNeedle, cb);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (!pb)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync break;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync cb = pbEnd - pb;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (cb >= cbNeedle)
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync {
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync /* match? */
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync if (!memcmp(pb + 1, &pabNeedle[1], cbNeedle - 1))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *poff = pb - pbPage;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return true;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync else
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /* paritial match at the end of the page? */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (!memcmp(pb + 1, &pabNeedle[1], cb - 1))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /* We're copying one byte more that we really need here, but wtf. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync memcpy(pabPrev, pb, cb);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pcbPrev = cb;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return false;
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /* no match, skip a byte ahead. */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (cb <= 1)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync break;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync pb++;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync cb--;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return false;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync}
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync/**
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Scans guest physical memory for a byte string.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @returns VBox status codes:
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @retval VINF_SUCCESS and *pGCPtrHit on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @retval VERR_DBGF_MEM_NOT_FOUND if not found.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @retval VERR_INVALID_POINTER if any of the pointer arguments are invalid.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @retval VERR_INVALID_ARGUMENT if any other arguments are invalid.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pVM Pointer to the shared VM structure.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param GCPhys Where to start searching.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param cbRange The number of bytes to search.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pabNeedle The byte string to search for.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param cbNeedle The length of the byte string. Max 256 bytes.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * @param pGCPhysHit Where to store the address of the first occurence on success.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsyncVMMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync{
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /*
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Validate and adjust the input a bit.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (!VALID_PTR(pGCPhysHit))
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_POINTER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pGCPhysHit = NIL_RTGCPHYS;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if ( !VALID_PTR(pabNeedle)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync || GCPhys == NIL_RTGCPHYS)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_POINTER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (!cbNeedle)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_PARAMETER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (cbNeedle > MAX_NEEDLE_SIZE)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_INVALID_PARAMETER;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (!cbRange)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_DBGF_MEM_NOT_FOUND;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (GCPhys + cbNeedle - 1 < GCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VERR_DBGF_MEM_NOT_FOUND;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync const RTGCPHYS GCPhysLast = GCPhys + cbRange - 1 >= GCPhys
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync ? GCPhys + cbRange - 1
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync : ~(RTGCPHYS)0;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /*
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Search the memory - ignore MMIO and zero pages, also don't
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync * bother to match across ranges.
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync */
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync for (PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges);
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync pRam;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync pRam = pRam->CTX_SUFF(pNext))
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /*
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * If the search range starts prior to the current ram range record,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * adjust the search range and possibly conclude the search.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync RTGCPHYS off;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (GCPhys < pRam->GCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (GCPhysLast < pRam->GCPhys)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync break;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync GCPhys = pRam->GCPhys;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync off = 0;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync else
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync off = GCPhys - pRam->GCPhys;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (off < pRam->cb)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync /*
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync * Iterate the relevant pages.
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync */
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync uint8_t abPrev[MAX_NEEDLE_SIZE];
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync size_t cbPrev = 0;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync const uint32_t cPages = pRam->cb >> PAGE_SHIFT;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync for (uint32_t iPage = off >> PAGE_SHIFT; iPage < cPages; iPage++)
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync {
a898eb6a3ace2594099a60b478ae5cc164bfe3dcvboxsync PPGMPAGE pPage = &pRam->aPages[iPage];
a898eb6a3ace2594099a60b478ae5cc164bfe3dcvboxsync if ( /** @todo !PGM_PAGE_IS_ZERO(pPage)
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync &&*/ !PGM_PAGE_IS_MMIO(pPage))
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync {
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync void const *pvPage;
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync PGMPAGEMAPLOCK Lock;
3864d226a840ec3ae21abc27459c3cbbc7ef21a3vboxsync int rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK, &pvPage, &Lock);
a898eb6a3ace2594099a60b478ae5cc164bfe3dcvboxsync if (RT_SUCCESS(rc))
a898eb6a3ace2594099a60b478ae5cc164bfe3dcvboxsync {
a898eb6a3ace2594099a60b478ae5cc164bfe3dcvboxsync int32_t offPage = (GCPhys & PAGE_OFFSET_MASK);
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync uint32_t cbSearch = (GCPhys ^ GCPhysLast) & ~(RTGCPHYS)PAGE_OFFSET_MASK
8b90eb0585fa16024709ca374c69f1eb5d5a5a7cvboxsync ? PAGE_SIZE - (uint32_t)offPage
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync : (GCPhysLast & PAGE_OFFSET_MASK) + 1 - (uint32_t)offPage;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync bool fRc = pgmR3DbgScanPage((uint8_t const *)pvPage, &offPage, cbSearch,
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync pabNeedle, cbNeedle, &abPrev[0], &cbPrev);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync PGMPhysReleasePageMappingLock(pVM, &Lock);
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync if (fRc)
6b539f36e5988ef31d4a7341eeb40efe12585388vboxsync {
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync *pGCPhysHit = (GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK) + offPage;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync return VINF_SUCCESS;
9dca051a5f8ff457ef1692990f6ecfa280daf265vboxsync }
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync }
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync else
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync cbPrev = 0; /* ignore error. */
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync }
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync else
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync cbPrev = 0;
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync /* advance to the the next page. */
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync GCPhys |= PAGE_OFFSET_MASK;
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync if (GCPhys++ >= GCPhysLast)
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync return VERR_DBGF_MEM_NOT_FOUND;
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync }
96a7e06717e2d7398642eadb5ebab1bf13fbe2dbvboxsync }
}
return VERR_DBGF_MEM_NOT_FOUND;
}
/**
* Scans (guest) virtual memory for a byte string.
*
* @returns VBox status codes:
* @retval VINF_SUCCESS and *pGCPtrHit on success.
* @retval VERR_DBGF_MEM_NOT_FOUND if not found.
* @retval VERR_INVALID_POINTER if any of the pointer arguments are invalid.
* @retval VERR_INVALID_ARGUMENT if any other arguments are invalid.
*
* @param pVM Pointer to the shared VM structure.
* @param GCPtr Where to start searching.
* @param cbRange The number of bytes to search. Max 256 bytes.
* @param pabNeedle The byte string to search for.
* @param cbNeedle The length of the byte string.
* @param pGCPtrHit Where to store the address of the first occurence on success.
*/
VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, RTGCUINTPTR GCPtr, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPtrHit)
{
/*
* Validate and adjust the input a bit.
*/
if (!VALID_PTR(pGCPtrHit))
return VERR_INVALID_POINTER;
*pGCPtrHit = 0;
if (!VALID_PTR(pabNeedle))
return VERR_INVALID_POINTER;
if (!cbNeedle)
return VERR_INVALID_PARAMETER;
if (cbNeedle > MAX_NEEDLE_SIZE)
return VERR_INVALID_PARAMETER;
if (!cbRange)
return VERR_DBGF_MEM_NOT_FOUND;
if (GCPtr + cbNeedle - 1 < GCPtr)
return VERR_DBGF_MEM_NOT_FOUND;
/*
* Search the memory - ignore MMIO, zero and not-present pages.
*/
uint8_t abPrev[MAX_NEEDLE_SIZE];
size_t cbPrev = 0;
const RTGCUINTPTR GCPtrLast = GCPtr + cbRange - 1 >= GCPtr
? GCPtr + cbRange - 1
: ~(RTGCUINTPTR)0;
RTGCUINTPTR cPages = (((GCPtrLast - GCPtr) + (GCPtr & PAGE_OFFSET_MASK)) >> PAGE_SHIFT) + 1;
while (cPages-- > 0)
{
RTGCPHYS GCPhys;
int rc = PGMPhysGCPtr2GCPhys(pVM, GCPtr, &GCPhys);
if (RT_SUCCESS(rc))
{
PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
if ( pPage
///@todo && !PGM_PAGE_IS_ZERO(pPage)
&& !PGM_PAGE_IS_MMIO(pPage))
{
void const *pvPage;
PGMPAGEMAPLOCK Lock;
rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys & ~(RTGCUINTPTR)PAGE_OFFSET_MASK, &pvPage, &Lock);
if (RT_SUCCESS(rc))
{
int32_t offPage = (GCPtr & PAGE_OFFSET_MASK);
uint32_t cbSearch = cPages > 0
? PAGE_SIZE - (uint32_t)offPage
: (GCPtrLast & PAGE_OFFSET_MASK) + 1 - (uint32_t)offPage;
bool fRc = pgmR3DbgScanPage((uint8_t const *)pvPage, &offPage, cbSearch,
pabNeedle, cbNeedle, &abPrev[0], &cbPrev);
PGMPhysReleasePageMappingLock(pVM, &Lock);
if (fRc)
{
*pGCPtrHit = (GCPtr & ~(RTGCUINTPTR)PAGE_OFFSET_MASK) + offPage;
return VINF_SUCCESS;
}
}
else
cbPrev = 0; /* ignore error. */
}
else
cbPrev = 0;
}
else
cbPrev = 0; /* ignore error. */
/* advance to the the next page. */
GCPtr |= PAGE_OFFSET_MASK;
GCPtr++;
}
return VERR_DBGF_MEM_NOT_FOUND;
}