VirtualBox

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

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

annoying warning

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.9 KB
Line 
1/* $Id: DBGFMem.cpp 13609 2008-10-28 11:56:14Z 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 (
78#if GC_ARCH_BITS > 32
79 ( pAddress->FlatPtr >= _4G
80 || pAddress->FlatPtr + cbRange > _4G)
81 &&
82#endif
83 enmMode != PGMMODE_AMD64
84 && enmMode != PGMMODE_AMD64_NX)
85 return VERR_DBGF_MEM_NOT_FOUND;
86 RTGCUINTPTR GCPtrHit;
87 rc = PGMR3DbgScanVirtual(pVM, pAddress->FlatPtr, cbRange, pabNeedle, cbNeedle, &GCPtrHit);
88 if (RT_SUCCESS(rc))
89 DBGFR3AddrFromFlat(pVM, pHitAddress, GCPtrHit);
90 }
91
92 return rc;
93}
94
95
96/**
97 * Scan guest memory for an exact byte string.
98 *
99 * @returns VBox status codes:
100 * @retval VINF_SUCCESS and *pGCPtrHit on success.
101 * @retval VERR_DBGF_MEM_NOT_FOUND if not found.
102 * @retval VERR_INVALID_POINTER if any of the pointer arguments are invalid.
103 * @retval VERR_INVALID_ARGUMENT if any other arguments are invalid.
104 *
105 * @param pVM The VM handle.
106 * @param pAddress Where to store the mixed address.
107 * @param cbRange The number of bytes to scan.
108 * @param pabNeedle What to search for - exact search.
109 * @param cbNeedle Size of the search byte string.
110 * @param pHitAddress Where to put the address of the first hit.
111 *
112 * @thread Any thread.
113 */
114VMMR3DECL(int) DBGFR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress)
115{
116 PVMREQ pReq;
117 int rc = VMR3ReqCall(pVM, &pReq, RT_INDEFINITE_WAIT, (PFNRT)dbgfR3MemScan, 6,
118 pVM, pAddress, cbRange, pabNeedle, cbNeedle, pHitAddress);
119 if (VBOX_SUCCESS(rc))
120 rc = pReq->iStatus;
121 VMR3ReqFree(pReq);
122
123 return rc;
124}
125
126
127/**
128 * Read guest memory.
129 *
130 * @returns VBox status code.
131 * @param pVM Pointer to the shared VM structure.
132 * @param pAddress Where to start reading.
133 * @param pvBuf Where to store the data we've read.
134 * @param cbRead The number of bytes to read.
135 */
136static DECLCALLBACK(int) dbgfR3MemRead(PVM pVM, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead)
137{
138 /*
139 * Validate the input we use, PGM does the rest.
140 */
141 if (!DBGFR3AddrIsValid(pVM, pAddress))
142 return VERR_INVALID_POINTER;
143 if (!VALID_PTR(pvBuf))
144 return VERR_INVALID_POINTER;
145 if (DBGFADDRESS_IS_HMA(pAddress))
146 return VERR_INVALID_POINTER;
147
148 /*
149 * Select DBGF worker by addressing mode.
150 */
151 int rc;
152 PGMMODE enmMode = PGMGetGuestMode(pVM);
153 if ( enmMode == PGMMODE_REAL
154 || enmMode == PGMMODE_PROTECTED
155 || DBGFADDRESS_IS_PHYS(pAddress) )
156 rc = PGMPhysSimpleReadGCPhys(pVM, pvBuf, pAddress->FlatPtr, cbRead);
157 else
158 {
159 if (
160#if GC_ARCH_BITS > 32
161 ( pAddress->FlatPtr >= _4G
162 || pAddress->FlatPtr + cbRead > _4G)
163 &&
164#endif
165 enmMode != PGMMODE_AMD64
166 && enmMode != PGMMODE_AMD64_NX)
167 return VERR_PAGE_TABLE_NOT_PRESENT;
168 rc = PGMPhysSimpleReadGCPtr(pVM, pvBuf, pAddress->FlatPtr, cbRead);
169 }
170 return rc;
171}
172
173
174/**
175 * Read guest memory.
176 *
177 * @returns VBox status code.
178 * @param pVM Pointer to the shared VM structure.
179 * @param pAddress Where to start reading.
180 * @param pvBuf Where to store the data we've read.
181 * @param cbRead The number of bytes to read.
182 */
183VMMR3DECL(int) DBGFR3MemRead(PVM pVM, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead)
184{
185 PVMREQ pReq;
186 int rc = VMR3ReqCallU(pVM->pUVM, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)dbgfR3MemRead, 4,
187 pVM, pAddress, pvBuf, cbRead);
188 if (VBOX_SUCCESS(rc))
189 rc = pReq->iStatus;
190 VMR3ReqFree(pReq);
191
192 return rc;
193}
194
195
196/**
197 * Read a zero terminated string from guest memory.
198 *
199 * @returns VBox status code.
200 * @param pVM Pointer to the shared VM structure.
201 * @param pAddress Where to start reading.
202 * @param pszBuf Where to store the string.
203 * @param cchBuf The size of the buffer.
204 */
205static DECLCALLBACK(int) dbgfR3MemReadString(PVM pVM, PCDBGFADDRESS pAddress, char *pszBuf, size_t cchBuf)
206{
207 /*
208 * Validate the input we use, PGM does the rest.
209 */
210 if (!DBGFR3AddrIsValid(pVM, pAddress))
211 return VERR_INVALID_POINTER;
212 if (!VALID_PTR(pszBuf))
213 return VERR_INVALID_POINTER;
214 if (DBGFADDRESS_IS_HMA(pAddress))
215 return VERR_INVALID_POINTER;
216
217 /*
218 * Select DBGF worker by addressing mode.
219 */
220 int rc;
221 PGMMODE enmMode = PGMGetGuestMode(pVM);
222 if ( enmMode == PGMMODE_REAL
223 || enmMode == PGMMODE_PROTECTED
224 || DBGFADDRESS_IS_PHYS(pAddress) )
225 rc = PGMPhysSimpleReadGCPhys(pVM, pszBuf, pAddress->FlatPtr, cchBuf);
226 else
227 {
228 if (
229#if GC_ARCH_BITS > 32
230 ( pAddress->FlatPtr >= _4G
231 || pAddress->FlatPtr + cchBuf > _4G)
232 &&
233#endif
234 enmMode != PGMMODE_AMD64
235 && enmMode != PGMMODE_AMD64_NX)
236 return VERR_PAGE_TABLE_NOT_PRESENT;
237 rc = PGMPhysSimpleReadGCPtr(pVM, pszBuf, pAddress->FlatPtr, cchBuf);
238 }
239
240 /*
241 * Make sure the result is terminated and that overflow is signaled.
242 */
243 if (!memchr(pszBuf, '\0', cchBuf))
244 {
245 pszBuf[cchBuf - 1] = '\0';
246 rc = VINF_BUFFER_OVERFLOW;
247 }
248 /*
249 * Handle partial reads (not perfect).
250 */
251 else if (RT_FAILURE(rc))
252 {
253 if (pszBuf[0])
254 rc = VINF_SUCCESS;
255 }
256
257 return rc;
258}
259
260
261/**
262 * Read a zero terminated string from guest memory.
263 *
264 * @returns VBox status code.
265 * @param pVM Pointer to the shared VM structure.
266 * @param pAddress Where to start reading.
267 * @param pszBuf Where to store the string.
268 * @param cchBuf The size of the buffer.
269 */
270VMMR3DECL(int) DBGFR3MemReadString(PVM pVM, PCDBGFADDRESS pAddress, char *pszBuf, size_t cchBuf)
271{
272 /*
273 * Validate and zero output.
274 */
275 if (!VALID_PTR(pszBuf))
276 return VERR_INVALID_POINTER;
277 if (cchBuf <= 0)
278 return VERR_INVALID_PARAMETER;
279 memset(pszBuf, 0, cchBuf);
280
281 /*
282 * Pass it on to the EMT.
283 */
284 PVMREQ pReq;
285 int rc = VMR3ReqCallU(pVM->pUVM, &pReq, RT_INDEFINITE_WAIT, 0, (PFNRT)dbgfR3MemReadString, 4,
286 pVM, pAddress, pszBuf, cchBuf);
287 if (VBOX_SUCCESS(rc))
288 rc = pReq->iStatus;
289 VMR3ReqFree(pReq);
290
291 return rc;
292}
293
Note: See TracBrowser for help on using the repository browser.

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