VirtualBox

source: vbox/trunk/src/VBox/VMM/DBGFMem.cpp@ 13762

Last change on this file since 13762 was 13755, checked in by vboxsync, 16 years ago

Started with VM request API changes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.8 KB
Line 
1/* $Id: DBGFMem.cpp 13755 2008-11-03 15:49:06Z vboxsync $ */
2/** @file
3 * DBGF - Debugger Facility, Memory Methods.
4 */
5
6/*
7 * Copyright (C) 2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_DBGF
27#include <VBox/dbgf.h>
28#include <VBox/pgm.h>
29#include "DBGFInternal.h"
30#include <VBox/vm.h>
31#include <VBox/err.h>
32#include <VBox/log.h>
33
34
35
36/**
37 * Scan guest memory for an exact byte string.
38 *
39 * @returns VBox status code.
40 * @param pVM The VM handle.
41 * @param pAddress Where to store the mixed address.
42 * @param cbRange The number of bytes to scan.
43 * @param pabNeedle What to search for - exact search.
44 * @param cbNeedle Size of the search byte string.
45 * @param pHitAddress Where to put the address of the first hit.
46 */
47static DECLCALLBACK(int) dbgfR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle,
48 PDBGFADDRESS pHitAddress)
49{
50 /*
51 * Validate the input we use, PGM does the rest.
52 */
53 if (!DBGFR3AddrIsValid(pVM, pAddress))
54 return VERR_INVALID_POINTER;
55 if (!VALID_PTR(pHitAddress))
56 return VERR_INVALID_POINTER;
57 if (DBGFADDRESS_IS_HMA(pAddress))
58 return VERR_INVALID_POINTER;
59
60 /*
61 * Select DBGF worker by addressing mode.
62 */
63 int rc;
64 PGMMODE enmMode = PGMGetGuestMode(pVM);
65 if ( enmMode == PGMMODE_REAL
66 || enmMode == PGMMODE_PROTECTED
67 || DBGFADDRESS_IS_PHYS(pAddress)
68 )
69 {
70 RTGCPHYS PhysHit;
71 rc = PGMR3DbgScanPhysical(pVM, pAddress->FlatPtr, cbRange, pabNeedle, cbNeedle, &PhysHit);
72 if (RT_SUCCESS(rc))
73 DBGFR3AddrFromPhys(pVM, pHitAddress, PhysHit);
74 }
75 else
76 {
77#if GC_ARCH_BITS > 32
78 if ( ( pAddress->FlatPtr >= _4G
79 || pAddress->FlatPtr + cbRange > _4G)
80 && enmMode != PGMMODE_AMD64
81 && enmMode != PGMMODE_AMD64_NX)
82 return VERR_DBGF_MEM_NOT_FOUND;
83#endif
84 RTGCUINTPTR GCPtrHit;
85 rc = PGMR3DbgScanVirtual(pVM, pAddress->FlatPtr, cbRange, pabNeedle, cbNeedle, &GCPtrHit);
86 if (RT_SUCCESS(rc))
87 DBGFR3AddrFromFlat(pVM, pHitAddress, GCPtrHit);
88 }
89
90 return rc;
91}
92
93
94/**
95 * Scan guest memory for an exact byte string.
96 *
97 * @returns VBox status codes:
98 * @retval VINF_SUCCESS and *pGCPtrHit on success.
99 * @retval VERR_DBGF_MEM_NOT_FOUND if not found.
100 * @retval VERR_INVALID_POINTER if any of the pointer arguments are invalid.
101 * @retval VERR_INVALID_ARGUMENT if any other arguments are invalid.
102 *
103 * @param pVM The VM handle.
104 * @param pAddress Where to store the mixed address.
105 * @param cbRange The number of bytes to scan.
106 * @param pabNeedle What to search for - exact search.
107 * @param cbNeedle Size of the search byte string.
108 * @param pHitAddress Where to put the address of the first hit.
109 *
110 * @thread Any thread.
111 */
112VMMR3DECL(int) DBGFR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress)
113{
114 PVMREQ pReq;
115 int rc = VMR3ReqCall(pVM, VMREQDEST_ALL, &pReq, RT_INDEFINITE_WAIT, (PFNRT)dbgfR3MemScan, 6,
116 pVM, pAddress, cbRange, pabNeedle, cbNeedle, pHitAddress);
117 if (VBOX_SUCCESS(rc))
118 rc = pReq->iStatus;
119 VMR3ReqFree(pReq);
120
121 return rc;
122}
123
124
125/**
126 * Read guest memory.
127 *
128 * @returns VBox status code.
129 * @param pVM Pointer to the shared VM structure.
130 * @param pAddress Where to start reading.
131 * @param pvBuf Where to store the data we've read.
132 * @param cbRead The number of bytes to read.
133 */
134static DECLCALLBACK(int) dbgfR3MemRead(PVM pVM, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead)
135{
136 /*
137 * Validate the input we use, PGM does the rest.
138 */
139 if (!DBGFR3AddrIsValid(pVM, pAddress))
140 return VERR_INVALID_POINTER;
141 if (!VALID_PTR(pvBuf))
142 return VERR_INVALID_POINTER;
143 if (DBGFADDRESS_IS_HMA(pAddress))
144 return VERR_INVALID_POINTER;
145
146 /*
147 * Select DBGF worker by addressing mode.
148 */
149 int rc;
150 PGMMODE enmMode = PGMGetGuestMode(pVM);
151 if ( enmMode == PGMMODE_REAL
152 || enmMode == PGMMODE_PROTECTED
153 || DBGFADDRESS_IS_PHYS(pAddress) )
154 rc = PGMPhysSimpleReadGCPhys(pVM, pvBuf, pAddress->FlatPtr, cbRead);
155 else
156 {
157#if GC_ARCH_BITS > 32
158 if ( ( pAddress->FlatPtr >= _4G
159 || pAddress->FlatPtr + cbRead > _4G)
160 && enmMode != PGMMODE_AMD64
161 && enmMode != PGMMODE_AMD64_NX)
162 return VERR_PAGE_TABLE_NOT_PRESENT;
163#endif
164 rc = PGMPhysSimpleReadGCPtr(pVM, pvBuf, pAddress->FlatPtr, cbRead);
165 }
166 return rc;
167}
168
169
170/**
171 * Read guest memory.
172 *
173 * @returns VBox status code.
174 * @param pVM Pointer to the shared VM structure.
175 * @param pAddress Where to start reading.
176 * @param pvBuf Where to store the data we've read.
177 * @param cbRead The number of bytes to read.
178 */
179VMMR3DECL(int) DBGFR3MemRead(PVM pVM, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead)
180{
181 PVMREQ pReq;
182 int rc = VMR3ReqCallU(pVM->pUVM, VMREQDEST_ALL, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)dbgfR3MemRead, 4,
183 pVM, pAddress, pvBuf, cbRead);
184 if (VBOX_SUCCESS(rc))
185 rc = pReq->iStatus;
186 VMR3ReqFree(pReq);
187
188 return rc;
189}
190
191
192/**
193 * Read a zero terminated string from guest memory.
194 *
195 * @returns VBox status code.
196 * @param pVM Pointer to the shared VM structure.
197 * @param pAddress Where to start reading.
198 * @param pszBuf Where to store the string.
199 * @param cchBuf The size of the buffer.
200 */
201static DECLCALLBACK(int) dbgfR3MemReadString(PVM pVM, PCDBGFADDRESS pAddress, char *pszBuf, size_t cchBuf)
202{
203 /*
204 * Validate the input we use, PGM does the rest.
205 */
206 if (!DBGFR3AddrIsValid(pVM, pAddress))
207 return VERR_INVALID_POINTER;
208 if (!VALID_PTR(pszBuf))
209 return VERR_INVALID_POINTER;
210 if (DBGFADDRESS_IS_HMA(pAddress))
211 return VERR_INVALID_POINTER;
212
213 /*
214 * Select DBGF worker by addressing mode.
215 */
216 int rc;
217 PGMMODE enmMode = PGMGetGuestMode(pVM);
218 if ( enmMode == PGMMODE_REAL
219 || enmMode == PGMMODE_PROTECTED
220 || DBGFADDRESS_IS_PHYS(pAddress) )
221 rc = PGMPhysSimpleReadGCPhys(pVM, pszBuf, pAddress->FlatPtr, cchBuf);
222 else
223 {
224#if GC_ARCH_BITS > 32
225 if ( ( pAddress->FlatPtr >= _4G
226 || pAddress->FlatPtr + cchBuf > _4G)
227 && enmMode != PGMMODE_AMD64
228 && enmMode != PGMMODE_AMD64_NX)
229 return VERR_PAGE_TABLE_NOT_PRESENT;
230#endif
231 rc = PGMPhysSimpleReadGCPtr(pVM, pszBuf, pAddress->FlatPtr, cchBuf);
232 }
233
234 /*
235 * Make sure the result is terminated and that overflow is signaled.
236 */
237 if (!memchr(pszBuf, '\0', cchBuf))
238 {
239 pszBuf[cchBuf - 1] = '\0';
240 rc = VINF_BUFFER_OVERFLOW;
241 }
242 /*
243 * Handle partial reads (not perfect).
244 */
245 else if (RT_FAILURE(rc))
246 {
247 if (pszBuf[0])
248 rc = VINF_SUCCESS;
249 }
250
251 return rc;
252}
253
254
255/**
256 * Read a zero terminated string from guest memory.
257 *
258 * @returns VBox status code.
259 * @param pVM Pointer to the shared VM structure.
260 * @param pAddress Where to start reading.
261 * @param pszBuf Where to store the string.
262 * @param cchBuf The size of the buffer.
263 */
264VMMR3DECL(int) DBGFR3MemReadString(PVM pVM, PCDBGFADDRESS pAddress, char *pszBuf, size_t cchBuf)
265{
266 /*
267 * Validate and zero output.
268 */
269 if (!VALID_PTR(pszBuf))
270 return VERR_INVALID_POINTER;
271 if (cchBuf <= 0)
272 return VERR_INVALID_PARAMETER;
273 memset(pszBuf, 0, cchBuf);
274
275 /*
276 * Pass it on to the EMT.
277 */
278 PVMREQ pReq;
279 int rc = VMR3ReqCallU(pVM->pUVM, VMREQDEST_ALL, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)dbgfR3MemReadString, 4,
280 pVM, pAddress, pszBuf, cchBuf);
281 if (VBOX_SUCCESS(rc))
282 rc = pReq->iStatus;
283 VMR3ReqFree(pReq);
284
285 return rc;
286}
287
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use