VirtualBox

source: vbox/trunk/src/VBox/Debugger/DBGCCmdHlp.cpp@ 5999

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

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.8 KB
Line 
1/** $Id: DBGCCmdHlp.cpp 5999 2007-12-07 15:05:06Z vboxsync $ */
2/** @file
3 * DBGC - Debugger Console, Command Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * innotek GmbH 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 * Command helper for writing text to the debug console.
41 *
42 * @returns VBox status.
43 * @param pCmdHlp Pointer to the command callback structure.
44 * @param pvBuf What to write.
45 * @param cbBuf Number of bytes to write.
46 * @param pcbWritten Where to store the number of bytes actually written.
47 * If NULL the entire buffer must be successfully written.
48 */
49static DECLCALLBACK(int) dbgcHlpWrite(PDBGCCMDHLP pCmdHlp, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
50{
51 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
52 return pDbgc->pBack->pfnWrite(pDbgc->pBack, pvBuf, cbBuf, pcbWritten);
53}
54
55
56/**
57 * Command helper for writing formatted text to the debug console.
58 *
59 * @returns VBox status.
60 * @param pCmdHlp Pointer to the command callback structure.
61 * @param pcb Where to store the number of bytes written.
62 * @param pszFormat The format string.
63 * This is using the log formatter, so it's format extensions can be used.
64 * @param ... Arguments specified in the format string.
65 */
66static DECLCALLBACK(int) dbgcHlpPrintf(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, ...)
67{
68 /*
69 * Do the formatting and output.
70 */
71 va_list args;
72 va_start(args, pszFormat);
73 int rc = pCmdHlp->pfnPrintfV(pCmdHlp, pcbWritten, pszFormat, args);
74 va_end(args);
75
76 return rc;
77}
78
79/**
80 * Callback to format non-standard format specifiers.
81 *
82 * @returns The number of bytes formatted.
83 * @param pvArg Formatter argument.
84 * @param pfnOutput Pointer to output function.
85 * @param pvArgOutput Argument for the output function.
86 * @param ppszFormat Pointer to the format string pointer. Advance this till the char
87 * after the format specifier.
88 * @param pArgs Pointer to the argument list. Use this to fetch the arguments.
89 * @param cchWidth Format Width. -1 if not specified.
90 * @param cchPrecision Format Precision. -1 if not specified.
91 * @param fFlags Flags (RTSTR_NTFS_*).
92 * @param chArgSize The argument size specifier, 'l' or 'L'.
93 */
94static DECLCALLBACK(size_t) dbgcStringFormatter(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
95 const char **ppszFormat, va_list *pArgs, int cchWidth,
96 int cchPrecision, unsigned fFlags, char chArgSize)
97{
98 NOREF(cchWidth); NOREF(cchPrecision); NOREF(fFlags); NOREF(chArgSize); NOREF(pvArg);
99 if (**ppszFormat != 'D')
100 {
101 (*ppszFormat)++;
102 return 0;
103 }
104
105 (*ppszFormat)++;
106 switch (**ppszFormat)
107 {
108 /*
109 * Print variable without range.
110 * The argument is a const pointer to the variable.
111 */
112 case 'V':
113 {
114 (*ppszFormat)++;
115 PCDBGCVAR pVar = va_arg(*pArgs, PCDBGCVAR);
116 switch (pVar->enmType)
117 {
118 case DBGCVAR_TYPE_GC_FLAT:
119 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%VGv", pVar->u.GCFlat);
120 case DBGCVAR_TYPE_GC_FAR:
121 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%04x:%08x", pVar->u.GCFar.sel, pVar->u.GCFar.off);
122 case DBGCVAR_TYPE_GC_PHYS:
123 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%%%VGp", pVar->u.GCPhys);
124 case DBGCVAR_TYPE_HC_FLAT:
125 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%#%VHv", (uintptr_t)pVar->u.pvHCFlat);
126 case DBGCVAR_TYPE_HC_FAR:
127 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%04x:%08x", pVar->u.HCFar.sel, pVar->u.HCFar.off);
128 case DBGCVAR_TYPE_HC_PHYS:
129 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%%%%%VHp", pVar->u.HCPhys);
130 case DBGCVAR_TYPE_STRING:
131 return pfnOutput(pvArgOutput, pVar->u.pszString, (size_t)pVar->u64Range);
132 case DBGCVAR_TYPE_NUMBER:
133 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%llx", pVar->u.u64Number);
134
135 case DBGCVAR_TYPE_UNKNOWN:
136 default:
137 return pfnOutput(pvArgOutput, "??", 2);
138 }
139 }
140
141 /*
142 * Print variable with range.
143 * The argument is a const pointer to the variable.
144 */
145 case 'v':
146 {
147 (*ppszFormat)++;
148 PCDBGCVAR pVar = va_arg(*pArgs, PCDBGCVAR);
149
150 char szRange[32];
151 switch (pVar->enmRangeType)
152 {
153 case DBGCVAR_RANGE_NONE:
154 szRange[0] = '\0';
155 break;
156 case DBGCVAR_RANGE_ELEMENTS:
157 RTStrPrintf(szRange, sizeof(szRange), " L %llx", pVar->u64Range);
158 break;
159 case DBGCVAR_RANGE_BYTES:
160 RTStrPrintf(szRange, sizeof(szRange), " LB %llx", pVar->u64Range);
161 break;
162 }
163
164 switch (pVar->enmType)
165 {
166 case DBGCVAR_TYPE_GC_FLAT:
167 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%VGv%s", pVar->u.GCFlat, szRange);
168 case DBGCVAR_TYPE_GC_FAR:
169 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%04x:%08x%s", pVar->u.GCFar.sel, pVar->u.GCFar.off, szRange);
170 case DBGCVAR_TYPE_GC_PHYS:
171 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%%%%VGp%s", pVar->u.GCPhys, szRange);
172 case DBGCVAR_TYPE_HC_FLAT:
173 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%%#%VHv%s", (uintptr_t)pVar->u.pvHCFlat, szRange);
174 case DBGCVAR_TYPE_HC_FAR:
175 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%04x:%08x%s", pVar->u.HCFar.sel, pVar->u.HCFar.off, szRange);
176 case DBGCVAR_TYPE_HC_PHYS:
177 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "#%%%%%VHp%s", pVar->u.HCPhys, szRange);
178 case DBGCVAR_TYPE_STRING:
179 return pfnOutput(pvArgOutput, pVar->u.pszString, (size_t)pVar->u64Range);
180 case DBGCVAR_TYPE_NUMBER:
181 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%llx%s", pVar->u.u64Number, szRange);
182
183 case DBGCVAR_TYPE_UNKNOWN:
184 default:
185 return pfnOutput(pvArgOutput, "??", 2);
186 }
187 }
188
189 default:
190 AssertMsgFailed(("Invalid format type '%s'!\n", **ppszFormat));
191 return 0;
192 }
193}
194
195
196/**
197 * Output callback.
198 *
199 * @returns number of bytes written.
200 * @param pvArg User argument.
201 * @param pachChars Pointer to an array of utf-8 characters.
202 * @param cbChars Number of bytes in the character array pointed to by pachChars.
203 */
204static DECLCALLBACK(size_t) dbgcFormatOutput(void *pvArg, const char *pachChars, size_t cbChars)
205{
206 PDBGC pDbgc = (PDBGC)pvArg;
207 if (cbChars)
208 {
209 int rc = pDbgc->pBack->pfnWrite(pDbgc->pBack, pachChars, cbChars, NULL);
210 if (VBOX_FAILURE(rc))
211 {
212 pDbgc->rcOutput = rc;
213 cbChars = 0;
214 }
215 }
216
217 return cbChars;
218}
219
220
221
222/**
223 * Command helper for writing formatted text to the debug console.
224 *
225 * @returns VBox status.
226 * @param pCmdHlp Pointer to the command callback structure.
227 * @param pcb Where to store the number of bytes written.
228 * @param pszFormat The format string.
229 * This is using the log formatter, so it's format extensions can be used.
230 * @param args Arguments specified in the format string.
231 */
232static DECLCALLBACK(int) dbgcHlpPrintfV(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args)
233{
234 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
235
236 /*
237 * Do the formatting and output.
238 */
239 pDbgc->rcOutput = 0;
240 size_t cb = RTStrFormatV(dbgcFormatOutput, pDbgc, dbgcStringFormatter, pDbgc, pszFormat, args);
241
242 if (pcbWritten)
243 *pcbWritten = cb;
244
245 return pDbgc->rcOutput;
246}
247
248
249/**
250 * Reports an error from a DBGF call.
251 *
252 * @returns VBox status code appropriate to return from a command.
253 * @param pCmdHlp Pointer to command helpers.
254 * @param rc The VBox status code returned by a DBGF call.
255 * @param pszFormat Format string for additional messages. Can be NULL.
256 * @param ... Format arguments, optional.
257 */
258static DECLCALLBACK(int) dbgcHlpVBoxErrorV(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, va_list args)
259{
260 switch (rc)
261 {
262 case VINF_SUCCESS:
263 break;
264
265 default:
266 rc = pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: %Vrc: %s", rc, pszFormat ? " " : "\n");
267 if (RT_SUCCESS(rc) && pszFormat)
268 rc = pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, args);
269 if (RT_SUCCESS(rc))
270 rc = VERR_DBGC_COMMAND_FAILED;
271 break;
272 }
273 return rc;
274}
275
276
277/**
278 * Reports an error from a DBGF call.
279 *
280 * @returns VBox status code appropriate to return from a command.
281 * @param pCmdHlp Pointer to command helpers.
282 * @param rc The VBox status code returned by a DBGF call.
283 * @param pszFormat Format string for additional messages. Can be NULL.
284 * @param ... Format arguments, optional.
285 */
286static DECLCALLBACK(int) dbgcHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...)
287{
288 va_list args;
289 va_start(args, pszFormat);
290 int rcRet = pCmdHlp->pfnVBoxErrorV(pCmdHlp, rc, pszFormat, args);
291 va_end(args);
292 return rcRet;
293}
294
295
296/**
297 * Command helper for reading memory specified by a DBGC variable.
298 *
299 * @returns VBox status code appropriate to return from a command.
300 * @param pCmdHlp Pointer to the command callback structure.
301 * @param pVM VM handle if GC or physical HC address.
302 * @param pvBuffer Where to store the read data.
303 * @param cbRead Number of bytes to read.
304 * @param pVarPointer DBGC variable specifying where to start reading.
305 * @param pcbRead Where to store the number of bytes actually read.
306 * This optional, but it's useful when read GC virtual memory where a
307 * page in the requested range might not be present.
308 * If not specified not-present failure or end of a HC physical page
309 * will cause failure.
310 */
311static DECLCALLBACK(int) dbgcHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead)
312{
313 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
314
315 /*
316 * Dummy check.
317 */
318 if (cbRead == 0)
319 {
320 if (*pcbRead)
321 *pcbRead = 0;
322 return VINF_SUCCESS;
323 }
324
325 /*
326 * Convert Far addresses getting size and the correct base address.
327 * Getting and checking the size is what makes this messy and slow.
328 */
329 DBGCVAR Var = *pVarPointer;
330 switch (pVarPointer->enmType)
331 {
332 case DBGCVAR_TYPE_GC_FAR:
333 {
334 /* Use DBGFR3AddrFromSelOff for the conversion. */
335 Assert(pDbgc->pVM);
336 DBGFADDRESS Address;
337 int rc = DBGFR3AddrFromSelOff(pDbgc->pVM, &Address, Var.u.GCFar.sel, Var.u.GCFar.off);
338 if (VBOX_FAILURE(rc))
339 return rc;
340
341 /* don't bother with flat selectors (for now). */
342 if (!DBGFADDRESS_IS_FLAT(&Address))
343 {
344 SELMSELINFO SelInfo;
345 rc = SELMR3GetSelectorInfo(pDbgc->pVM, Address.Sel, &SelInfo);
346 if (VBOX_SUCCESS(rc))
347 {
348 RTGCUINTPTR cb; /* -1 byte */
349 if (SELMSelInfoIsExpandDown(&SelInfo))
350 {
351 if ( !SelInfo.Raw.Gen.u1Granularity
352 && Address.off > UINT16_C(0xffff))
353 return VERR_OUT_OF_SELECTOR_BOUNDS;
354 if (Address.off <= SelInfo.cbLimit)
355 return VERR_OUT_OF_SELECTOR_BOUNDS;
356 cb = (SelInfo.Raw.Gen.u1Granularity ? UINT32_C(0xffffffff) : UINT32_C(0xffff)) - Address.off;
357 }
358 else
359 {
360 if (Address.off > SelInfo.cbLimit)
361 return VERR_OUT_OF_SELECTOR_BOUNDS;
362 cb = SelInfo.cbLimit - Address.off;
363 }
364 if (cbRead - 1 > cb)
365 {
366 if (!pcbRead)
367 return VERR_OUT_OF_SELECTOR_BOUNDS;
368 cbRead = cb + 1;
369 }
370 }
371
372 Var.enmType = DBGCVAR_TYPE_GC_FLAT;
373 Var.u.GCFlat = Address.FlatPtr;
374 }
375 break;
376 }
377
378 case DBGCVAR_TYPE_GC_FLAT:
379 case DBGCVAR_TYPE_GC_PHYS:
380 case DBGCVAR_TYPE_HC_FLAT:
381 case DBGCVAR_TYPE_HC_PHYS:
382 break;
383
384 case DBGCVAR_TYPE_HC_FAR: /* not supported yet! */
385 default:
386 return VERR_NOT_IMPLEMENTED;
387 }
388
389
390
391 /*
392 * Copy page by page.
393 */
394 size_t cbLeft = cbRead;
395 for (;;)
396 {
397 /*
398 * Calc read size.
399 */
400 size_t cb = RT_MIN(PAGE_SIZE, cbLeft);
401 switch (pVarPointer->enmType)
402 {
403 case DBGCVAR_TYPE_GC_FLAT: cb = RT_MIN(cb, PAGE_SIZE - (Var.u.GCFlat & PAGE_OFFSET_MASK)); break;
404 case DBGCVAR_TYPE_GC_PHYS: cb = RT_MIN(cb, PAGE_SIZE - (Var.u.GCPhys & PAGE_OFFSET_MASK)); break;
405 case DBGCVAR_TYPE_HC_FLAT: cb = RT_MIN(cb, PAGE_SIZE - ((uintptr_t)Var.u.pvHCFlat & PAGE_OFFSET_MASK)); break;
406 case DBGCVAR_TYPE_HC_PHYS: cb = RT_MIN(cb, PAGE_SIZE - ((size_t)Var.u.HCPhys & PAGE_OFFSET_MASK)); break; /* size_t: MSC has braindead loss of data warnings! */
407 default: break;
408 }
409
410 /*
411 * Perform read.
412 */
413 int rc;
414 switch (Var.enmType)
415 {
416 case DBGCVAR_TYPE_GC_FLAT:
417 rc = MMR3ReadGCVirt(pVM, pvBuffer, Var.u.GCFlat, cb);
418 break;
419 case DBGCVAR_TYPE_GC_PHYS:
420 rc = PGMPhysReadGCPhys(pVM, pvBuffer, Var.u.GCPhys, cb);
421 break;
422
423 case DBGCVAR_TYPE_HC_PHYS:
424 case DBGCVAR_TYPE_HC_FLAT:
425 case DBGCVAR_TYPE_HC_FAR:
426 {
427 DBGCVAR Var2;
428 rc = dbgcOpAddrFlat(pDbgc, &Var, &Var2);
429 if (VBOX_SUCCESS(rc))
430 {
431 /** @todo protect this!!! */
432 memcpy(pvBuffer, Var2.u.pvHCFlat, cb);
433 rc = 0;
434 }
435 else
436 rc = VERR_INVALID_POINTER;
437 break;
438 }
439
440 default:
441 rc = VERR_PARSE_INCORRECT_ARG_TYPE;
442 }
443
444 /*
445 * Check for failure.
446 */
447 if (VBOX_FAILURE(rc))
448 {
449 if (pcbRead && (*pcbRead = cbRead - cbLeft) > 0)
450 return VINF_SUCCESS;
451 return rc;
452 }
453
454 /*
455 * Next.
456 */
457 cbLeft -= cb;
458 if (!cbLeft)
459 break;
460 pvBuffer = (char *)pvBuffer + cb;
461 rc = pCmdHlp->pfnEval(pCmdHlp, &Var, "%DV + %d", &Var, cb);
462 if (VBOX_FAILURE(rc))
463 {
464 if (pcbRead && (*pcbRead = cbRead - cbLeft) > 0)
465 return VINF_SUCCESS;
466 return rc;
467 }
468 }
469
470 /*
471 * Done
472 */
473 if (pcbRead)
474 *pcbRead = cbRead;
475 return 0;
476}
477
478/**
479 * Command helper for writing memory specified by a DBGC variable.
480 *
481 * @returns VBox status code appropriate to return from a command.
482 * @param pCmdHlp Pointer to the command callback structure.
483 * @param pVM VM handle if GC or physical HC address.
484 * @param pvBuffer What to write.
485 * @param cbWrite Number of bytes to write.
486 * @param pVarPointer DBGC variable specifying where to start reading.
487 * @param pcbWritten Where to store the number of bytes written.
488 * This is optional. If NULL be aware that some of the buffer
489 * might have been written to the specified address.
490 */
491static DECLCALLBACK(int) dbgcHlpMemWrite(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten)
492{
493 NOREF(pCmdHlp); NOREF(pVM); NOREF(pvBuffer); NOREF(cbWrite); NOREF(pVarPointer); NOREF(pcbWritten);
494 return VERR_NOT_IMPLEMENTED;
495}
496
497
498/**
499 * Evaluates an expression.
500 * (Hopefully the parser and functions are fully reentrant.)
501 *
502 * @returns VBox status code appropriate to return from a command.
503 * @param pCmdHlp Pointer to the command callback structure.
504 * @param pResult Where to store the result.
505 * @param pszExpr The expression. Format string with the format DBGC extensions.
506 * @param ... Format arguments.
507 */
508static DECLCALLBACK(int) dbgcHlpEval(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, ...)
509{
510 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
511
512 /*
513 * Format the expression.
514 */
515 char szExprFormatted[2048];
516 va_list args;
517 va_start(args, pszExpr);
518 size_t cb = RTStrPrintfExV(dbgcStringFormatter, pDbgc, szExprFormatted, sizeof(szExprFormatted), pszExpr, args);
519 va_end(args);
520 /* ignore overflows. */
521
522 return dbgcEvalSub(pDbgc, &szExprFormatted[0], cb, pResult);
523}
524
525
526/**
527 * Executes one command expression.
528 * (Hopefully the parser and functions are fully reentrant.)
529 *
530 * @returns VBox status code appropriate to return from a command.
531 * @param pCmdHlp Pointer to the command callback structure.
532 * @param pszExpr The expression. Format string with the format DBGC extensions.
533 * @param ... Format arguments.
534 */
535static DECLCALLBACK(int) dbgcHlpExec(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...)
536{
537 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
538 /* Save the scratch state. */
539 char *pszScratch = pDbgc->pszScratch;
540 unsigned iArg = pDbgc->iArg;
541
542 /*
543 * Format the expression.
544 */
545 va_list args;
546 va_start(args, pszExpr);
547 size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]);
548 size_t cb = RTStrPrintfExV(dbgcStringFormatter, pDbgc, pDbgc->pszScratch, cbScratch, pszExpr, args);
549 va_end(args);
550 if (cb >= cbScratch)
551 return VERR_BUFFER_OVERFLOW;
552
553 /*
554 * Execute the command.
555 * We save and restore the arg index and scratch buffer pointer.
556 */
557 pDbgc->pszScratch = pDbgc->pszScratch + cb + 1;
558 int rc = dbgcProcessCommand(pDbgc, pszScratch, cb, false /* fNoExecute */);
559
560 /* Restore the scratch state. */
561 pDbgc->iArg = iArg;
562 pDbgc->pszScratch = pszScratch;
563
564 return rc;
565}
566
567
568/**
569 * Converts a DBGC variable to a DBGF address structure.
570 *
571 * @returns VBox status code.
572 * @param pCmdHlp Pointer to the command callback structure.
573 * @param pVar The variable to convert.
574 * @param pAddress The target address.
575 */
576static DECLCALLBACK(int) dbgcHlpVarToDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
577{
578 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
579 return dbgcVarToDbgfAddr(pDbgc, pVar, pAddress);
580}
581
582
583/**
584 * Converts a DBGC variable to a boolean.
585 *
586 * @returns VBox status code.
587 * @param pCmdHlp Pointer to the command callback structure.
588 * @param pVar The variable to convert.
589 * @param pf Where to store the boolean.
590 */
591static DECLCALLBACK(int) dbgcHlpVarToBool(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf)
592{
593 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
594 NOREF(pDbgc);
595
596 switch (pVar->enmType)
597 {
598 case DBGCVAR_TYPE_STRING:
599 /** @todo add strcasecmp / stricmp wrappers to iprt/string.h. */
600 if ( !strcmp(pVar->u.pszString, "true")
601 || !strcmp(pVar->u.pszString, "True")
602 || !strcmp(pVar->u.pszString, "TRUE")
603 || !strcmp(pVar->u.pszString, "on")
604 || !strcmp(pVar->u.pszString, "On")
605 || !strcmp(pVar->u.pszString, "oN")
606 || !strcmp(pVar->u.pszString, "ON")
607 || !strcmp(pVar->u.pszString, "enabled")
608 || !strcmp(pVar->u.pszString, "Enabled")
609 || !strcmp(pVar->u.pszString, "DISABLED"))
610 {
611 *pf = true;
612 return VINF_SUCCESS;
613 }
614 if ( !strcmp(pVar->u.pszString, "false")
615 || !strcmp(pVar->u.pszString, "False")
616 || !strcmp(pVar->u.pszString, "FALSE")
617 || !strcmp(pVar->u.pszString, "off")
618 || !strcmp(pVar->u.pszString, "Off")
619 || !strcmp(pVar->u.pszString, "OFF")
620 || !strcmp(pVar->u.pszString, "disabled")
621 || !strcmp(pVar->u.pszString, "Disabled")
622 || !strcmp(pVar->u.pszString, "DISABLED"))
623 {
624 *pf = false;
625 return VINF_SUCCESS;
626 }
627 return VERR_PARSE_INCORRECT_ARG_TYPE; /** @todo better error code! */
628
629 case DBGCVAR_TYPE_GC_FLAT:
630 case DBGCVAR_TYPE_GC_PHYS:
631 case DBGCVAR_TYPE_HC_FLAT:
632 case DBGCVAR_TYPE_HC_PHYS:
633 case DBGCVAR_TYPE_NUMBER:
634 *pf = pVar->u.u64Number != 0;
635 return VINF_SUCCESS;
636
637 case DBGCVAR_TYPE_HC_FAR:
638 case DBGCVAR_TYPE_GC_FAR:
639 case DBGCVAR_TYPE_SYMBOL:
640 default:
641 return VERR_PARSE_INCORRECT_ARG_TYPE;
642 }
643}
644
645
646/**
647 * Initializes the Command Helpers for a DBGC instance.
648 *
649 * @param pDbgc Pointer to the DBGC instance.
650 */
651void dbgcInitCmdHlp(PDBGC pDbgc)
652{
653 pDbgc->CmdHlp.pfnWrite = dbgcHlpWrite;
654 pDbgc->CmdHlp.pfnPrintfV = dbgcHlpPrintfV;
655 pDbgc->CmdHlp.pfnPrintf = dbgcHlpPrintf;
656 pDbgc->CmdHlp.pfnVBoxErrorV = dbgcHlpVBoxErrorV;
657 pDbgc->CmdHlp.pfnVBoxError = dbgcHlpVBoxError;
658 pDbgc->CmdHlp.pfnMemRead = dbgcHlpMemRead;
659 pDbgc->CmdHlp.pfnMemWrite = dbgcHlpMemWrite;
660 pDbgc->CmdHlp.pfnEval = dbgcHlpEval;
661 pDbgc->CmdHlp.pfnExec = dbgcHlpExec;
662 pDbgc->CmdHlp.pfnVarToDbgfAddr = dbgcHlpVarToDbgfAddr;
663 pDbgc->CmdHlp.pfnVarToBool = dbgcHlpVarToBool;
664}
665
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