VirtualBox

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

Last change on this file since 31510 was 31510, checked in by vboxsync, 14 years ago

The debugger is back in the OSE.

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