VirtualBox

source: vbox/trunk/src/VBox/Debugger/DBGCCmdWorkers.cpp@ 35627

最後變更 在這個檔案從35627是 35626,由 vboxsync 提交於 14 年 前

Debugger Console: Drop the HC_FAR type.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 11.0 KB
 
1/* $Id: DBGCCmdWorkers.cpp 35626 2011-01-19 12:29:20Z vboxsync $ */
2/** @file
3 * DBGC - Debugger Console, Command Worker Routines.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.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
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#define LOG_GROUP LOG_GROUP_DBGC
22#include <VBox/dbg.h>
23#include <VBox/vmm/dbgf.h>
24#include <VBox/vmm/vm.h>
25#include <VBox/vmm/vmm.h>
26#include <VBox/vmm/mm.h>
27#include <VBox/vmm/pgm.h>
28#include <VBox/vmm/selm.h>
29#include <VBox/dis.h>
30#include <VBox/param.h>
31#include <VBox/err.h>
32#include <VBox/log.h>
33
34#include <iprt/alloc.h>
35#include <iprt/alloca.h>
36#include <iprt/string.h>
37#include <iprt/assert.h>
38#include <iprt/ctype.h>
39
40#include "DBGCInternal.h"
41
42
43
44//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
45//
46//
47// V a r i a b l e M a n i p u l a t i o n
48//
49//
50//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
51
52
53
54/** @todo move me!*/
55void dbgcVarInit(PDBGCVAR pVar)
56{
57 if (pVar)
58 {
59 memset(pVar, 0, sizeof(*pVar));
60 AssertCompile(DBGCVAR_TYPE_UNKNOWN == 0);
61 AssertCompile(DBGCVAR_RANGE_NONE == 0);
62 }
63}
64
65
66/** @todo move me!*/
67void dbgcVarSetGCFlat(PDBGCVAR pVar, RTGCPTR GCFlat)
68{
69 if (pVar)
70 {
71 pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
72 memset(&pVar->u, 0, sizeof(pVar->u));
73 pVar->u.GCFlat = GCFlat;
74 pVar->enmRangeType = DBGCVAR_RANGE_NONE;
75 pVar->u64Range = 0;
76 }
77}
78
79
80/** @todo move me!*/
81void dbgcVarSetGCFlatByteRange(PDBGCVAR pVar, RTGCPTR GCFlat, uint64_t cb)
82{
83 if (pVar)
84 {
85 pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
86 memset(&pVar->u, 0, sizeof(pVar->u));
87 pVar->u.GCFlat = GCFlat;
88 pVar->enmRangeType = DBGCVAR_RANGE_BYTES;
89 pVar->u64Range = cb;
90 }
91}
92
93
94/** @todo move me!*/
95void dbgcVarSetU64(PDBGCVAR pVar, uint64_t u64)
96{
97 if (pVar)
98 {
99 pVar->enmType = DBGCVAR_TYPE_NUMBER;
100 memset(&pVar->u, 0, sizeof(pVar->u));
101 pVar->u.u64Number = u64;
102 pVar->enmRangeType = DBGCVAR_RANGE_NONE;
103 pVar->u64Range = 0;
104 }
105}
106
107
108/** @todo move me!*/
109void dbgcVarSetVar(PDBGCVAR pVar, PCDBGCVAR pVar2)
110{
111 if (pVar)
112 {
113 if (pVar2)
114 *pVar = *pVar2;
115 else
116 {
117 pVar->enmType = DBGCVAR_TYPE_UNKNOWN;
118 memset(&pVar->u, 0, sizeof(pVar->u));
119 pVar->enmRangeType = DBGCVAR_RANGE_NONE;
120 pVar->u64Range = 0;
121 }
122 }
123}
124
125/** @todo move me!*/
126void dbgcVarSetDbgfAddr(PDBGCVAR pVar, PCDBGFADDRESS pAddress)
127{
128 if (pVar)
129 {
130 memset(&pVar->u, 0, sizeof(pVar->u));
131
132 Assert(!pAddress || DBGFADDRESS_IS_VALID(pAddress));
133 if (pAddress && DBGFADDRESS_IS_VALID(pAddress))
134 {
135 switch (pAddress->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK)
136 {
137 case DBGFADDRESS_FLAGS_FAR16:
138 case DBGFADDRESS_FLAGS_FAR32:
139 case DBGFADDRESS_FLAGS_FAR64:
140 pVar->enmType = DBGCVAR_TYPE_GC_FAR;
141 pVar->u.GCFar.off = pAddress->off;
142 pVar->u.GCFar.sel = pAddress->Sel;
143 break;
144
145 case DBGFADDRESS_FLAGS_FLAT:
146 pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
147 pVar->u.GCFlat = pAddress->FlatPtr;
148 break;
149
150 case DBGFADDRESS_FLAGS_PHYS:
151 pVar->enmType = DBGCVAR_TYPE_GC_PHYS;
152 pVar->u.GCPhys = pAddress->FlatPtr;
153 break;
154
155 default:
156 AssertFailed();
157 pVar->enmType = DBGCVAR_TYPE_UNKNOWN;
158 break;
159 }
160 }
161 else
162 pVar->enmType = DBGCVAR_TYPE_UNKNOWN;
163 pVar->enmRangeType = DBGCVAR_RANGE_NONE;
164 pVar->u64Range = 0;
165 }
166}
167
168
169/** @todo move me!*/
170void dbgcVarSetByteRange(PDBGCVAR pVar, uint64_t cb)
171{
172 if (pVar)
173 {
174 pVar->enmRangeType = DBGCVAR_RANGE_BYTES;
175 pVar->u64Range = cb;
176 }
177}
178
179
180/** @todo move me!*/
181void dbgcVarSetNoRange(PDBGCVAR pVar)
182{
183 if (pVar)
184 {
185 pVar->enmRangeType = DBGCVAR_RANGE_NONE;
186 pVar->u64Range = 0;
187 }
188}
189
190
191/**
192 * Converts a DBGC variable to a DBGF address.
193 *
194 * @returns VBox status code.
195 * @param pDbgc The DBGC instance.
196 * @param pVar The variable.
197 * @param pAddress Where to store the address.
198 */
199int dbgcVarToDbgfAddr(PDBGC pDbgc, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
200{
201 AssertReturn(pVar, VERR_INVALID_PARAMETER);
202 switch (pVar->enmType)
203 {
204 case DBGCVAR_TYPE_GC_FLAT:
205 DBGFR3AddrFromFlat(pDbgc->pVM, pAddress, pVar->u.GCFlat);
206 return VINF_SUCCESS;
207
208 case DBGCVAR_TYPE_NUMBER:
209 DBGFR3AddrFromFlat(pDbgc->pVM, pAddress, (RTGCUINTPTR)pVar->u.u64Number);
210 return VINF_SUCCESS;
211
212 case DBGCVAR_TYPE_GC_FAR:
213 return DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, pAddress, pVar->u.GCFar.sel, pVar->u.GCFar.off);
214
215 case DBGCVAR_TYPE_GC_PHYS:
216 DBGFR3AddrFromPhys(pDbgc->pVM, pAddress, pVar->u.GCPhys);
217 return VINF_SUCCESS;
218
219 case DBGCVAR_TYPE_STRING:
220 case DBGCVAR_TYPE_SYMBOL:
221 {
222 DBGCVAR Var;
223 int rc = DBGCCmdHlpEval(&pDbgc->CmdHlp, &Var, "%%(%DV)", pVar);
224 if (RT_FAILURE(rc))
225 return rc;
226 return dbgcVarToDbgfAddr(pDbgc, &Var, pAddress);
227 }
228
229 case DBGCVAR_TYPE_HC_FLAT:
230 case DBGCVAR_TYPE_HC_PHYS:
231 default:
232 return VERR_PARSE_CONVERSION_FAILED;
233 }
234}
235
236
237
238//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
239//
240//
241// B r e a k p o i n t M a n a g e m e n t
242//
243//
244//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
245
246
247/**
248 * Adds a breakpoint to the DBGC breakpoint list.
249 */
250int dbgcBpAdd(PDBGC pDbgc, RTUINT iBp, const char *pszCmd)
251{
252 /*
253 * Check if it already exists.
254 */
255 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
256 if (pBp)
257 return VERR_DBGC_BP_EXISTS;
258
259 /*
260 * Add the breakpoint.
261 */
262 if (pszCmd)
263 pszCmd = RTStrStripL(pszCmd);
264 size_t cchCmd = pszCmd ? strlen(pszCmd) : 0;
265 pBp = (PDBGCBP)RTMemAlloc(RT_OFFSETOF(DBGCBP, szCmd[cchCmd + 1]));
266 if (!pBp)
267 return VERR_NO_MEMORY;
268 if (cchCmd)
269 memcpy(pBp->szCmd, pszCmd, cchCmd + 1);
270 else
271 pBp->szCmd[0] = '\0';
272 pBp->cchCmd = cchCmd;
273 pBp->iBp = iBp;
274 pBp->pNext = pDbgc->pFirstBp;
275 pDbgc->pFirstBp = pBp;
276
277 return VINF_SUCCESS;
278}
279
280/**
281 * Updates the a breakpoint.
282 *
283 * @returns VBox status code.
284 * @param pDbgc The DBGC instance.
285 * @param iBp The breakpoint to update.
286 * @param pszCmd The new command.
287 */
288int dbgcBpUpdate(PDBGC pDbgc, RTUINT iBp, const char *pszCmd)
289{
290 /*
291 * Find the breakpoint.
292 */
293 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
294 if (!pBp)
295 return VERR_DBGC_BP_NOT_FOUND;
296
297 /*
298 * Do we need to reallocate?
299 */
300 if (pszCmd)
301 pszCmd = RTStrStripL(pszCmd);
302 if (!pszCmd || !*pszCmd)
303 pBp->szCmd[0] = '\0';
304 else
305 {
306 size_t cchCmd = strlen(pszCmd);
307 if (strlen(pBp->szCmd) >= cchCmd)
308 {
309 memcpy(pBp->szCmd, pszCmd, cchCmd + 1);
310 pBp->cchCmd = cchCmd;
311 }
312 else
313 {
314 /*
315 * Yes, let's do it the simple way...
316 */
317 int rc = dbgcBpDelete(pDbgc, iBp);
318 AssertRC(rc);
319 return dbgcBpAdd(pDbgc, iBp, pszCmd);
320 }
321 }
322 return VINF_SUCCESS;
323}
324
325
326/**
327 * Deletes a breakpoint.
328 *
329 * @returns VBox status code.
330 * @param pDbgc The DBGC instance.
331 * @param iBp The breakpoint to delete.
332 */
333int dbgcBpDelete(PDBGC pDbgc, RTUINT iBp)
334{
335 /*
336 * Search thru the list, when found unlink and free it.
337 */
338 PDBGCBP pBpPrev = NULL;
339 PDBGCBP pBp = pDbgc->pFirstBp;
340 for (; pBp; pBp = pBp->pNext)
341 {
342 if (pBp->iBp == iBp)
343 {
344 if (pBpPrev)
345 pBpPrev->pNext = pBp->pNext;
346 else
347 pDbgc->pFirstBp = pBp->pNext;
348 RTMemFree(pBp);
349 return VINF_SUCCESS;
350 }
351 pBpPrev = pBp;
352 }
353
354 return VERR_DBGC_BP_NOT_FOUND;
355}
356
357
358/**
359 * Get a breakpoint.
360 *
361 * @returns Pointer to the breakpoint.
362 * @returns NULL if the breakpoint wasn't found.
363 * @param pDbgc The DBGC instance.
364 * @param iBp The breakpoint to get.
365 */
366PDBGCBP dbgcBpGet(PDBGC pDbgc, RTUINT iBp)
367{
368 /*
369 * Enumerate the list.
370 */
371 PDBGCBP pBp = pDbgc->pFirstBp;
372 for (; pBp; pBp = pBp->pNext)
373 if (pBp->iBp == iBp)
374 return pBp;
375 return NULL;
376}
377
378
379/**
380 * Executes the command of a breakpoint.
381 *
382 * @returns VINF_DBGC_BP_NO_COMMAND if there is no command associated with the breakpoint.
383 * @returns VERR_DBGC_BP_NOT_FOUND if the breakpoint wasn't found.
384 * @returns VERR_BUFFER_OVERFLOW if the is not enough space in the scratch buffer for the command.
385 * @returns VBox status code from dbgcProcessCommand() other wise.
386 * @param pDbgc The DBGC instance.
387 * @param iBp The breakpoint to execute.
388 */
389int dbgcBpExec(PDBGC pDbgc, RTUINT iBp)
390{
391 /*
392 * Find the breakpoint.
393 */
394 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
395 if (!pBp)
396 return VERR_DBGC_BP_NOT_FOUND;
397
398 /*
399 * Anything to do?
400 */
401 if (!pBp->cchCmd)
402 return VINF_DBGC_BP_NO_COMMAND;
403
404 /*
405 * Execute the command.
406 * This means copying it to the scratch buffer and process it as if it
407 * were user input. We must save and restore the state of the scratch buffer.
408 */
409 /* Save the scratch state. */
410 char *pszScratch = pDbgc->pszScratch;
411 unsigned iArg = pDbgc->iArg;
412
413 /* Copy the command to the scratch buffer. */
414 size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]);
415 if (pBp->cchCmd >= cbScratch)
416 return VERR_BUFFER_OVERFLOW;
417 memcpy(pDbgc->pszScratch, pBp->szCmd, pBp->cchCmd + 1);
418
419 /* Execute the command. */
420 pDbgc->pszScratch = pDbgc->pszScratch + pBp->cchCmd + 1;
421 int rc = dbgcProcessCommand(pDbgc, pszScratch, pBp->cchCmd, false /* fNoExecute */);
422
423 /* Restore the scratch state. */
424 pDbgc->iArg = iArg;
425 pDbgc->pszScratch = pszScratch;
426
427 return rc;
428}
429
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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