VirtualBox

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

Last change on this file since 5681 was 5677, checked in by vboxsync, 17 years ago

Split out command worker routines and stuffed the variable manipulation routines in with them.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.9 KB
Line 
1/** $Id: DBGCCmdWorkers.cpp 5677 2007-11-11 05:54:53Z vboxsync $ */
2/** @file
3 * DBGC - Debugger Console, Command Worker Routines.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * 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/dbgf.h>
24#include <VBox/vm.h>
25#include <VBox/vmm.h>
26#include <VBox/mm.h>
27#include <VBox/pgm.h>
28#include <VBox/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 dbgcVarSetGCFlat(PDBGCVAR pVar, RTGCPTR GCFlat)
56{
57 if (pVar)
58 {
59 pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
60 pVar->u.GCFlat = GCFlat;
61 pVar->enmRangeType = DBGCVAR_RANGE_NONE;
62 pVar->u64Range = 0;
63 }
64}
65
66
67/** @todo move me!*/
68void dbgcVarSetGCFlatByteRange(PDBGCVAR pVar, RTGCPTR GCFlat, uint64_t cb)
69{
70 if (pVar)
71 {
72 pVar->enmType = DBGCVAR_TYPE_GC_FLAT;
73 pVar->u.GCFlat = GCFlat;
74 pVar->enmRangeType = DBGCVAR_RANGE_BYTES;
75 pVar->u64Range = cb;
76 }
77}
78
79
80/** @todo move me!*/
81void dbgcVarSetVar(PDBGCVAR pVar, PCDBGCVAR pVar2)
82{
83 if (pVar)
84 {
85 if (pVar2)
86 *pVar = *pVar2;
87 else
88 {
89 pVar->enmType = DBGCVAR_TYPE_UNKNOWN;
90 memset(&pVar->u, 0, sizeof(pVar->u));
91 pVar->enmRangeType = DBGCVAR_RANGE_NONE;
92 pVar->u64Range = 0;
93 }
94 }
95}
96
97
98/** @todo move me!*/
99void dbgcVarSetByteRange(PDBGCVAR pVar, uint64_t cb)
100{
101 if (pVar)
102 {
103 pVar->enmRangeType = DBGCVAR_RANGE_BYTES;
104 pVar->u64Range = cb;
105 }
106}
107
108
109/** @todo move me!*/
110void dbgcVarSetNoRange(PDBGCVAR pVar)
111{
112 if (pVar)
113 {
114 pVar->enmRangeType = DBGCVAR_RANGE_NONE;
115 pVar->u64Range = 0;
116 }
117}
118
119
120/**
121 * Converts a DBGC variable to a DBGF address.
122 *
123 * @returns VBox status code.
124 * @param pDbgc The DBGC instance.
125 * @param pVar The variable.
126 * @param pAddress Where to store the address.
127 */
128int dbgcVarToDbgfAddr(PDBGC pDbgc, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
129{
130 AssertReturn(pVar, VERR_INVALID_PARAMETER);
131 switch (pVar->enmType)
132 {
133 case DBGCVAR_TYPE_GC_FLAT:
134 DBGFR3AddrFromFlat(pDbgc->pVM, pAddress, pVar->u.GCFlat);
135 return VINF_SUCCESS;
136
137 case DBGCVAR_TYPE_NUMBER:
138 DBGFR3AddrFromFlat(pDbgc->pVM, pAddress, (RTGCUINTPTR)pVar->u.u64Number);
139 return VINF_SUCCESS;
140
141 case DBGCVAR_TYPE_GC_FAR:
142 return DBGFR3AddrFromSelOff(pDbgc->pVM, pAddress, pVar->u.GCFar.sel, pVar->u.GCFar.sel);
143
144 case DBGCVAR_TYPE_STRING:
145 case DBGCVAR_TYPE_SYMBOL:
146 {
147 DBGCVAR Var;
148 int rc = pDbgc->CmdHlp.pfnEval(&pDbgc->CmdHlp, &Var, "%%(%DV)", pVar);
149 if (VBOX_FAILURE(rc))
150 return rc;
151 return dbgcVarToDbgfAddr(pDbgc, &Var, pAddress);
152 }
153
154 case DBGCVAR_TYPE_GC_PHYS:
155 case DBGCVAR_TYPE_HC_FLAT:
156 case DBGCVAR_TYPE_HC_FAR:
157 case DBGCVAR_TYPE_HC_PHYS:
158 default:
159 return VERR_PARSE_CONVERSION_FAILED;
160 }
161}
162
163
164
165//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
166//
167//
168// B r e a k p o i n t M a n a g e m e n t
169//
170//
171//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//
172
173
174/**
175 * Adds a breakpoint to the DBGC breakpoint list.
176 */
177int dbgcBpAdd(PDBGC pDbgc, RTUINT iBp, const char *pszCmd)
178{
179 /*
180 * Check if it already exists.
181 */
182 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
183 if (pBp)
184 return VERR_DBGC_BP_EXISTS;
185
186 /*
187 * Add the breakpoint.
188 */
189 if (pszCmd)
190 pszCmd = RTStrStripL(pszCmd);
191 size_t cchCmd = pszCmd ? strlen(pszCmd) : 0;
192 pBp = (PDBGCBP)RTMemAlloc(RT_OFFSETOF(DBGCBP, szCmd[cchCmd + 1]));
193 if (!pBp)
194 return VERR_NO_MEMORY;
195 if (cchCmd)
196 memcpy(pBp->szCmd, pszCmd, cchCmd + 1);
197 else
198 pBp->szCmd[0] = '\0';
199 pBp->cchCmd = cchCmd;
200 pBp->iBp = iBp;
201 pBp->pNext = pDbgc->pFirstBp;
202 pDbgc->pFirstBp = pBp;
203
204 return VINF_SUCCESS;
205}
206
207/**
208 * Updates the a breakpoint.
209 *
210 * @returns VBox status code.
211 * @param pDbgc The DBGC instance.
212 * @param iBp The breakpoint to update.
213 * @param pszCmd The new command.
214 */
215int dbgcBpUpdate(PDBGC pDbgc, RTUINT iBp, const char *pszCmd)
216{
217 /*
218 * Find the breakpoint.
219 */
220 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
221 if (!pBp)
222 return VERR_DBGC_BP_NOT_FOUND;
223
224 /*
225 * Do we need to reallocate?
226 */
227 if (pszCmd)
228 pszCmd = RTStrStripL(pszCmd);
229 if (!pszCmd || !*pszCmd)
230 pBp->szCmd[0] = '\0';
231 else
232 {
233 size_t cchCmd = strlen(pszCmd);
234 if (strlen(pBp->szCmd) >= cchCmd)
235 {
236 memcpy(pBp->szCmd, pszCmd, cchCmd + 1);
237 pBp->cchCmd = cchCmd;
238 }
239 else
240 {
241 /*
242 * Yes, let's do it the simple way...
243 */
244 int rc = dbgcBpDelete(pDbgc, iBp);
245 AssertRC(rc);
246 return dbgcBpAdd(pDbgc, iBp, pszCmd);
247 }
248 }
249 return VINF_SUCCESS;
250}
251
252
253/**
254 * Deletes a breakpoint.
255 *
256 * @returns VBox status code.
257 * @param pDbgc The DBGC instance.
258 * @param iBp The breakpoint to delete.
259 */
260int dbgcBpDelete(PDBGC pDbgc, RTUINT iBp)
261{
262 /*
263 * Search thru the list, when found unlink and free it.
264 */
265 PDBGCBP pBpPrev = NULL;
266 PDBGCBP pBp = pDbgc->pFirstBp;
267 for (; pBp; pBp = pBp->pNext)
268 {
269 if (pBp->iBp == iBp)
270 {
271 if (pBpPrev)
272 pBpPrev->pNext = pBp->pNext;
273 else
274 pDbgc->pFirstBp = pBp->pNext;
275 RTMemFree(pBp);
276 return VINF_SUCCESS;
277 }
278 pBpPrev = pBp;
279 }
280
281 return VERR_DBGC_BP_NOT_FOUND;
282}
283
284
285/**
286 * Get a breakpoint.
287 *
288 * @returns Pointer to the breakpoint.
289 * @returns NULL if the breakpoint wasn't found.
290 * @param pDbgc The DBGC instance.
291 * @param iBp The breakpoint to get.
292 */
293PDBGCBP dbgcBpGet(PDBGC pDbgc, RTUINT iBp)
294{
295 /*
296 * Enumerate the list.
297 */
298 PDBGCBP pBp = pDbgc->pFirstBp;
299 for (; pBp; pBp = pBp->pNext)
300 if (pBp->iBp == iBp)
301 return pBp;
302 return NULL;
303}
304
305
306/**
307 * Executes the command of a breakpoint.
308 *
309 * @returns VINF_DBGC_BP_NO_COMMAND if there is no command associated with the breakpoint.
310 * @returns VERR_DBGC_BP_NOT_FOUND if the breakpoint wasn't found.
311 * @returns VERR_BUFFER_OVERFLOW if the is not enough space in the scratch buffer for the command.
312 * @returns VBox status code from dbgcProcessCommand() other wise.
313 * @param pDbgc The DBGC instance.
314 * @param iBp The breakpoint to execute.
315 */
316int dbgcBpExec(PDBGC pDbgc, RTUINT iBp)
317{
318 /*
319 * Find the breakpoint.
320 */
321 PDBGCBP pBp = dbgcBpGet(pDbgc, iBp);
322 if (!pBp)
323 return VERR_DBGC_BP_NOT_FOUND;
324
325 /*
326 * Anything to do?
327 */
328 if (!pBp->cchCmd)
329 return VINF_DBGC_BP_NO_COMMAND;
330
331 /*
332 * Execute the command.
333 * This means copying it to the scratch buffer and process it as if it
334 * were user input. We must save and restore the state of the scratch buffer.
335 */
336 /* Save the scratch state. */
337 char *pszScratch = pDbgc->pszScratch;
338 unsigned iArg = pDbgc->iArg;
339
340 /* Copy the command to the scratch buffer. */
341 size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]);
342 if (pBp->cchCmd >= cbScratch)
343 return VERR_BUFFER_OVERFLOW;
344 memcpy(pDbgc->pszScratch, pBp->szCmd, pBp->cchCmd + 1);
345
346 /* Execute the command. */
347 pDbgc->pszScratch = pDbgc->pszScratch + pBp->cchCmd + 1;
348 int rc = dbgcProcessCommand(pDbgc, pszScratch, pBp->cchCmd);
349
350 /* Restore the scratch state. */
351 pDbgc->iArg = iArg;
352 pDbgc->pszScratch = pszScratch;
353
354 return rc;
355}
356
Note: See TracBrowser for help on using the repository browser.

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