File: dbg.h

package info (click to toggle)
virtualbox-ose 1.6.6-dfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 91,740 kB
  • ctags: 207,046
  • sloc: ansic: 541,507; cpp: 462,042; asm: 22,594; sh: 8,644; makefile: 6,630; perl: 1,359; objc: 612; xml: 524; sed: 229; cs: 226; python: 34
file content (723 lines) | stat: -rw-r--r-- 25,000 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
/** @file
 * Debugger Interfaces.
 *
 * This header covers all external interfaces of the Debugger module.
 * However, it does not cover the DBGF interface since that part of the
 * VMM. Use dbgf.h for that.
 */

/*
 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 *
 * The contents of this file may alternatively be used under the terms
 * of the Common Development and Distribution License Version 1.0
 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
 * VirtualBox OSE distribution, in which case the provisions of the
 * CDDL are applicable instead of those of the GPL.
 *
 * You may elect to license modified versions of this file under the
 * terms and conditions of either the GPL or the CDDL or both.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 USA or visit http://www.sun.com if you need
 * additional information or have any questions.
 */

#ifndef ___VBox_dbg_h
#define ___VBox_dbg_h

#include <VBox/cdefs.h>
#include <VBox/types.h>
#include <VBox/dbgf.h>

#include <iprt/stdarg.h>

__BEGIN_DECLS

/** @def VBOX_WITH_DEBUGGER
 * The build is with debugger module. Test if this is defined before
 * registering external debugger commands.
 */
#ifndef VBOX_WITH_DEBUGGER
# ifdef DEBUG
#  define VBOX_WITH_DEBUGGER
# endif
#endif


/**
 * DBGC variable category.
 *
 * Used to describe an argument to a command or function and a functions
 * return value.
 */
typedef enum DBGCVARCAT
{
    /** Any type is fine. */
    DBGCVAR_CAT_ANY = 0,
    /** Any kind of pointer. */
    DBGCVAR_CAT_POINTER,
    /** Any kind of pointer with no range option. */
    DBGCVAR_CAT_POINTER_NO_RANGE,
    /** GC pointer. */
    DBGCVAR_CAT_GC_POINTER,
    /** GC pointer with no range option. */
    DBGCVAR_CAT_GC_POINTER_NO_RANGE,
    /** Numeric argument. */
    DBGCVAR_CAT_NUMBER,
    /** Numeric argument with no range option. */
    DBGCVAR_CAT_NUMBER_NO_RANGE,
    /** String. */
    DBGCVAR_CAT_STRING,
    /** Symbol. */
    DBGCVAR_CAT_SYMBOL,
    /** Option. */
    DBGCVAR_CAT_OPTION,
    /** Option + string. */
    DBGCVAR_CAT_OPTION_STRING,
    /** Option + number. */
    DBGCVAR_CAT_OPTION_NUMBER
} DBGCVARCAT;


/**
 * DBGC variable type.
 */
typedef enum DBGCVARTYPE
{
    /** unknown... */
    DBGCVAR_TYPE_UNKNOWN = 0,
    /** Flat GC pointer. */
    DBGCVAR_TYPE_GC_FLAT,
    /** Segmented GC pointer. */
    DBGCVAR_TYPE_GC_FAR,
    /** Physical GC pointer. */
    DBGCVAR_TYPE_GC_PHYS,
    /** Flat HC pointer. */
    DBGCVAR_TYPE_HC_FLAT,
    /** Segmented HC pointer. */
    DBGCVAR_TYPE_HC_FAR,
    /** Physical HC pointer. */
    DBGCVAR_TYPE_HC_PHYS,
    /** String. */
    DBGCVAR_TYPE_STRING,
    /** Number. */
    DBGCVAR_TYPE_NUMBER,
    /** Symbol. */
    DBGCVAR_TYPE_SYMBOL,
    /** Special type used when querying symbols. */
    DBGCVAR_TYPE_ANY
} DBGCVARTYPE;

/** @todo Rename to DBGCVAR_IS_xyz. */

/** Checks if the specified variable type is of a pointer persuasion. */
#define DBGCVAR_ISPOINTER(enmType)      ((enmType) >= DBGCVAR_TYPE_GC_FLAT && enmType <= DBGCVAR_TYPE_HC_PHYS)
/** Checks if the specified variable type is of a pointer persuasion. */
#define DBGCVAR_IS_FAR_PTR(enmType)     ((enmType) == DBGCVAR_TYPE_GC_FAR || (enmType) == DBGCVAR_TYPE_HC_FAR)
/** Checks if the specified variable type is of a pointer persuasion and of the guest context sort. */
#define DBGCVAR_ISGCPOINTER(enmType)    ((enmType) >= DBGCVAR_TYPE_GC_FLAT && (enmType) <= DBGCVAR_TYPE_GC_PHYS)
/** Checks if the specified variable type is of a pointer persuasion and of the host context sort. */
#define DBGCVAR_ISHCPOINTER(enmType)    ((enmType) >= DBGCVAR_TYPE_HC_FLAT && (enmType) <= DBGCVAR_TYPE_HC_PHYS)


/**
 * DBGC variable range type.
 */
typedef enum DBGCVARRANGETYPE
{
    /** No range appliable or no range specified. */
    DBGCVAR_RANGE_NONE = 0,
    /** Number of elements. */
    DBGCVAR_RANGE_ELEMENTS,
    /** Number of bytes. */
    DBGCVAR_RANGE_BYTES
} DBGCVARRANGETYPE;


/**
 * Variable descriptor.
 */
typedef struct DBGCVARDESC
{
    /** The minimal number of times this argument may occur.
     * Use 0 here to inidicate that the argument is optional. */
    unsigned    cTimesMin;
    /** Maximum number of occurences.
     * Use ~0 here to indicate infinite. */
    unsigned    cTimesMax;
    /** Argument category. */
    DBGCVARCAT  enmCategory;
    /** Flags, DBGCVD_FLAGS_* */
    unsigned    fFlags;
    /** Argument name. */
    const char *pszName;
    /** Argument name. */
    const char *pszDescription;
} DBGCVARDESC;
/** Pointer to an argument descriptor. */
typedef DBGCVARDESC *PDBGCVARDESC;
/** Pointer to a const argument descriptor. */
typedef const DBGCVARDESC *PCDBGCVARDESC;

/** Variable descriptor flags.
 * @{ */
/** Indicates that the variable depends on the previous being present. */
#define DBGCVD_FLAGS_DEP_PREV       RT_BIT(1)
/** @} */


/**
 * DBGC variable.
 */
typedef struct DBGCVAR
{
    /** Pointer to the argument descriptor. */
    PCDBGCVARDESC   pDesc;
    /** Pointer to the next argument. */
    struct DBGCVAR *pNext;

    /** Argument type. */
    DBGCVARTYPE     enmType;
    /** Type specific. */
    union
    {
        /** Flat GC Address.        (DBGCVAR_TYPE_GC_FLAT) */
        RTGCPTR         GCFlat;
        /** Far (16:32) GC Address. (DBGCVAR_TYPE_GC_FAR) */
        RTFAR32         GCFar;
        /** Physical GC Address.    (DBGCVAR_TYPE_GC_PHYS) */
        RTGCPHYS        GCPhys;
        /** Flat HC Address.        (DBGCVAR_TYPE_HC_FLAT) */
        void           *pvHCFlat;
        /** Far (16:32) HC Address. (DBGCVAR_TYPE_HC_FAR) */
        RTFAR32         HCFar;
        /** Physical GC Address.    (DBGCVAR_TYPE_HC_PHYS) */
        RTHCPHYS        HCPhys;
        /** String.                 (DBGCVAR_TYPE_STRING)
         * The basic idea is the the this is a pointer to the expression we're
         * parsing, so no messing with freeing. */
        const char     *pszString;
        /** Number.                 (DBGCVAR_TYPE_NUMBER) */
        uint64_t        u64Number;
    } u;

    /** Range type. */
    DBGCVARRANGETYPE    enmRangeType;
    /** Range. The use of the content depends on the enmRangeType. */
    uint64_t            u64Range;
} DBGCVAR;
/** Pointer to a command argument. */
typedef DBGCVAR *PDBGCVAR;
/** Pointer to a const command argument. */
typedef const DBGCVAR *PCDBGCVAR;


/**
 * Macro for initializing a DBGC variable with defaults.
 * The result is an unknown variable type without any range.
 */
#define DBGCVAR_INIT(pVar) \
        do { \
            (pVar)->pDesc = NULL;\
            (pVar)->pNext = NULL; \
            (pVar)->enmType = DBGCVAR_TYPE_UNKNOWN; \
            (pVar)->u.u64Number = 0; \
            (pVar)->enmRangeType = DBGCVAR_RANGE_NONE; \
            (pVar)->u64Range = 0; \
        } while (0)

/**
 * Macro for initializing a DBGC variable with a HC physical address.
 */
#define DBGCVAR_INIT_HC_PHYS(pVar, Phys) \
        do { \
            DBGCVAR_INIT(pVar); \
            (pVar)->enmType = DBGCVAR_TYPE_HC_PHYS; \
            (pVar)->u.HCPhys = (Phys); \
        } while (0)

/**
 * Macro for initializing a DBGC variable with a HC flat address.
 */
#define DBGCVAR_INIT_HC_FLAT(pVar, Flat) \
        do { \
            DBGCVAR_INIT(pVar); \
            (pVar)->enmType = DBGCVAR_TYPE_HC_FLAT; \
            (pVar)->u.pvHCFlat = (Flat); \
        } while (0)

/**
 * Macro for initializing a DBGC variable with a GC physical address.
 */
#define DBGCVAR_INIT_GC_PHYS(pVar, Phys) \
        do { \
            DBGCVAR_INIT(pVar); \
            (pVar)->enmType = DBGCVAR_TYPE_GC_PHYS; \
            (pVar)->u.GCPhys = (Phys); \
        } while (0)

/**
 * Macro for initializing a DBGC variable with a GC flat address.
 */
#define DBGCVAR_INIT_GC_FLAT(pVar, Flat) \
        do { \
            DBGCVAR_INIT(pVar); \
            (pVar)->enmType = DBGCVAR_TYPE_GC_FLAT; \
            (pVar)->u.GCFlat = (Flat); \
        } while (0)

/**
 * Macro for initializing a DBGC variable with a GC far address.
 */
#define DBGCVAR_INIT_GC_FAR(pVar, _sel, _off) \
        do { \
            DBGCVAR_INIT(pVar); \
            (pVar)->enmType = DBGCVAR_TYPE_GC_FAR; \
            (pVar)->u.GCFar.sel = (_sel); \
            (pVar)->u.GCFar.off = (_off); \
        } while (0)

/**
 * Macro for initializing a DBGC variable with a number
 */
#define DBGCVAR_INIT_NUMBER(pVar, Value) \
        do { \
            DBGCVAR_INIT(pVar); \
            (pVar)->enmType = DBGCVAR_TYPE_NUMBER; \
            (pVar)->u.u64 = (Value); \
        } while (0)


/** Pointer to helper functions for commands. */
typedef struct DBGCCMDHLP *PDBGCCMDHLP;

/**
 * Command helper for writing text to the debug console.
 *
 * @returns VBox status.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pvBuf       What to write.
 * @param   cbBuf       Number of bytes to write.
 * @param   pcbWritten  Where to store the number of bytes actually written.
 *                      If NULL the entire buffer must be successfully written.
 */
typedef DECLCALLBACK(int) FNDBGCHLPWRITE(PDBGCCMDHLP pCmdHlp, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
/** Pointer to a FNDBGCHLPWRITE() function. */
typedef FNDBGCHLPWRITE *PFNDBGCHLPWRITE;

/**
 * Command helper for writing formatted text to the debug console.
 *
 * @returns VBox status.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pcb         Where to store the number of bytes written.
 * @param   pszFormat   The format string.
 *                      This is using the log formatter, so it's format extensions can be used.
 * @param   ...         Arguments specified in the format string.
 */
typedef DECLCALLBACK(int) FNDBGCHLPPRINTF(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, ...);
/** Pointer to a FNDBGCHLPPRINTF() function. */
typedef FNDBGCHLPPRINTF *PFNDBGCHLPPRINTF;

/**
 * Command helper for writing formatted text to the debug console.
 *
 * @returns VBox status.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pcb         Where to store the number of bytes written.
 * @param   pszFormat   The format string.
 *                      This is using the log formatter, so it's format extensions can be used.
 * @param   args        Arguments specified in the format string.
 */
typedef DECLCALLBACK(int) FNDBGCHLPPRINTFV(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args);
/** Pointer to a FNDBGCHLPPRINTFV() function. */
typedef FNDBGCHLPPRINTFV *PFNDBGCHLPPRINTFV;

/**
 * Command helper for formatting and error message for a VBox status code.
 *
 * @returns VBox status code appropriate to return from a command.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   rc          The VBox status code.
 * @param   pcb         Where to store the number of bytes written.
 * @param   pszFormat   Format string for additional messages. Can be NULL.
 * @param   ...         Format arguments, optional.
 */
typedef DECLCALLBACK(int) FNDBGCHLPVBOXERROR(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...);
/** Pointer to a FNDBGCHLPVBOXERROR() function. */
typedef FNDBGCHLPVBOXERROR *PFNDBGCHLPVBOXERROR;

/**
 * Command helper for formatting and error message for a VBox status code.
 *
 * @returns VBox status code appropriate to return from a command.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   rc          The VBox status code.
 * @param   pcb         Where to store the number of bytes written.
 * @param   pszFormat   Format string for additional messages. Can be NULL.
 * @param   args        Format arguments, optional.
 */
typedef DECLCALLBACK(int) FNDBGCHLPVBOXERRORV(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, va_list args);
/** Pointer to a FNDBGCHLPVBOXERRORV() function. */
typedef FNDBGCHLPVBOXERRORV *PFNDBGCHLPVBOXERRORV;

/**
 * Command helper for reading memory specified by a DBGC variable.
 *
 * @returns VBox status code appropriate to return from a command.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pVM         VM handle if GC or physical HC address.
 * @param   pvBuffer    Where to store the read data.
 * @param   cbRead      Number of bytes to read.
 * @param   pVarPointer DBGC variable specifying where to start reading.
 * @param   pcbRead     Where to store the number of bytes actually read.
 *                      This optional, but it's useful when read GC virtual memory where a
 *                      page in the requested range might not be present.
 *                      If not specified not-present failure or end of a HC physical page
 *                      will cause failure.
 */
typedef DECLCALLBACK(int) FNDBGCHLPMEMREAD(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead);
/** Pointer to a FNDBGCHLPMEMREAD() function. */
typedef FNDBGCHLPMEMREAD *PFNDBGCHLPMEMREAD;

/**
 * Command helper for writing memory specified by a DBGC variable.
 *
 * @returns VBox status code appropriate to return from a command.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pVM         VM handle if GC or physical HC address.
 * @param   pvBuffer    What to write.
 * @param   cbWrite     Number of bytes to write.
 * @param   pVarPointer DBGC variable specifying where to start reading.
 * @param   pcbWritten  Where to store the number of bytes written.
 *                      This is optional. If NULL be aware that some of the buffer
 *                      might have been written to the specified address.
 */
typedef DECLCALLBACK(int) FNDBGCHLPMEMWRITE(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten);
/** Pointer to a FNDBGCHLPMEMWRITE() function. */
typedef FNDBGCHLPMEMWRITE *PFNDBGCHLPMEMWRITE;


/**
 * Evaluates an expression.
 * (Hopefully the parser and functions are fully reentrant.)
 *
 * @returns VBox status code appropriate to return from a command.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pResult     Where to store the result.
 * @param   pszExpr     The expression. Format string with the format DBGC extensions.
 * @param   ...         Format arguments.
 */
typedef DECLCALLBACK(int) FNDBGCHLPEVAL(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, ...);
/** Pointer to a FNDBGCHLPEVAL() function. */
typedef FNDBGCHLPEVAL *PFNDBGCHLPEVAL;


/**
 * Executes command an expression.
 * (Hopefully the parser and functions are fully reentrant.)
 *
 * @returns VBox status code appropriate to return from a command.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pszExpr     The expression. Format string with the format DBGC extensions.
 * @param   ...         Format arguments.
 */
typedef DECLCALLBACK(int) FNDBGCHLPEXEC(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...);
/** Pointer to a FNDBGCHLPEVAL() function. */
typedef FNDBGCHLPEXEC *PFNDBGCHLPEXEC;


/**
 * Helper functions for commands.
 */
typedef struct DBGCCMDHLP
{
    /** Pointer to a FNDBCHLPWRITE() function. */
    PFNDBGCHLPWRITE         pfnWrite;
    /** Pointer to a FNDBGCHLPPRINTF() function. */
    PFNDBGCHLPPRINTF        pfnPrintf;
    /** Pointer to a FNDBGCHLPPRINTFV() function. */
    PFNDBGCHLPPRINTFV       pfnPrintfV;
    /** Pointer to a FNDBGCHLPVBOXERROR() function. */
    PFNDBGCHLPVBOXERROR     pfnVBoxError;
    /** Pointer to a FNDBGCHLPVBOXERRORV() function. */
    PFNDBGCHLPVBOXERRORV    pfnVBoxErrorV;
    /** Pointer to a FNDBGCHLPMEMREAD() function. */
    PFNDBGCHLPMEMREAD       pfnMemRead;
    /** Pointer to a FNDBGCHLPMEMWRITE() function. */
    PFNDBGCHLPMEMWRITE      pfnMemWrite;
    /** Pointer to a FNDBGCHLPEVAL() function. */
    PFNDBGCHLPEVAL          pfnEval;
    /** Pointer to a FNDBGCHLPEXEC() function. */
    PFNDBGCHLPEXEC          pfnExec;

    /**
     * Converts a DBGC variable to a DBGF address structure.
     *
     * @returns VBox status code.
     * @param   pCmdHlp     Pointer to the command callback structure.
     * @param   pVar        The variable to convert.
     * @param   pAddress    The target address.
     */
    DECLCALLBACKMEMBER(int, pfnVarToDbgfAddr)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress);

    /**
     * Converts a DBGC variable to a boolean.
     *
     * @returns VBox status code.
     * @param   pCmdHlp     Pointer to the command callback structure.
     * @param   pVar        The variable to convert.
     * @param   pf          Where to store the boolean.
     */
    DECLCALLBACKMEMBER(int, pfnVarToBool)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf);

} DBGCCMDHLP;


#ifdef IN_RING3
/**
 * Command helper for writing formatted text to the debug console.
 *
 * @returns VBox status.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pszFormat   The format string.
 *                      This is using the log formatter, so it's format extensions can be used.
 * @param   ...         Arguments specified in the format string.
 */
DECLINLINE(int) DBGCCmdHlpPrintf(PDBGCCMDHLP pCmdHlp, const char *pszFormat, ...)
{
    va_list va;
    int rc;
    va_start(va, pszFormat);
    rc = pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, va);
    va_end(va);
    return rc;
}

/**
 * @copydoc FNDBGCHLPVBOXERROR
 */
DECLINLINE(int) DBGCCmdHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...)
{
    va_list va;
    va_start(va, pszFormat);
    rc = pCmdHlp->pfnVBoxErrorV(pCmdHlp, rc, pszFormat, va);
    va_end(va);
    return rc;
}

/**
 * @copydoc FNDBGCHLPMEMREAD
 */
DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead)
{
    return pCmdHlp->pfnMemRead(pCmdHlp, pVM, pvBuffer, cbRead, pVarPointer, pcbRead);
}
#endif /* IN_RING3 */


/** Pointer to command descriptor. */
typedef struct DBGCCMD *PDBGCCMD;
/** Pointer to const command descriptor. */
typedef const struct DBGCCMD *PCDBGCCMD;

/**
 * Command handler.
 *
 * The console will call the handler for a command once it's finished
 * parsing the user input. The command handler function is responsible
 * for executing the command itself.
 *
 * @returns VBox status.
 * @param   pCmd        Pointer to the command descriptor (as registered).
 * @param   pCmdHlp     Pointer to command helper functions.
 * @param   pVM         Pointer to the current VM (if any).
 * @param   paArgs      Pointer to (readonly) array of arguments.
 * @param   cArgs       Number of arguments in the array.
 * @param   pResult     Where to store the result. NULL if no result descriptor was specified.
 */
typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR pArgs, unsigned cArgs, PDBGCVAR pResult);
/** Pointer to a FNDBGCCMD() function. */
typedef FNDBGCCMD *PFNDBGCCMD;

/**
 * DBGC command descriptor.
 *
 * If a pResultDesc is specified the command can be called and used
 * as a function too. If it's a pure function, set fFlags to
 * DBGCCMD_FLAGS_FUNCTION.
 */
typedef struct DBGCCMD
{
    /** Command string. */
    const char     *pszCmd;
    /** Minimum number of arguments. */
    unsigned        cArgsMin;
    /** Max number of arguments. */
    unsigned        cArgsMax;
    /** Argument descriptors (array). */
    PCDBGCVARDESC   paArgDescs;
    /** Number of argument descriptors. */
    unsigned        cArgDescs;
    /** Result descriptor. */
    PCDBGCVARDESC   pResultDesc;
    /** flags. (reserved for now) */
    unsigned        fFlags;
    /** Handler function. */
    PFNDBGCCMD      pfnHandler;
    /** Command syntax. */
    const char     *pszSyntax;
    /** Command description. */
    const char     *pszDescription;
} DBGCCMD;

/** DBGCCMD Flags.
 * @{
 */
/** The description is of a pure function which cannot be invoked
 * as a command from the commandline. */
#define DBGCCMD_FLAGS_FUNCTION  1
/** @} */



/** Pointer to a DBGC backend. */
typedef struct DBGCBACK *PDBGCBACK;

/**
 * Checks if there is input.
 *
 * @returns true if there is input ready.
 * @returns false if there not input ready.
 * @param   pBack       Pointer to the backend structure supplied by
 *                      the backend. The backend can use this to find
 *                      it's instance data.
 * @param   cMillies    Number of milliseconds to wait on input data.
 */
typedef DECLCALLBACK(bool) FNDBGCBACKINPUT(PDBGCBACK pBack, uint32_t cMillies);
/** Pointer to a FNDBGCBACKINPUT() callback. */
typedef FNDBGCBACKINPUT *PFNDBGCBACKINPUT;

/**
 * Read input.
 *
 * @returns VBox status code.
 * @param   pBack       Pointer to the backend structure supplied by
 *                      the backend. The backend can use this to find
 *                      it's instance data.
 * @param   pvBuf       Where to put the bytes we read.
 * @param   cbBuf       Maximum nymber of bytes to read.
 * @param   pcbRead     Where to store the number of bytes actually read.
 *                      If NULL the entire buffer must be filled for a
 *                      successful return.
 */
typedef DECLCALLBACK(int) FNDBGCBACKREAD(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
/** Pointer to a FNDBGCBACKREAD() callback. */
typedef FNDBGCBACKREAD *PFNDBGCBACKREAD;

/**
 * Write (output).
 *
 * @returns VBox status code.
 * @param   pBack       Pointer to the backend structure supplied by
 *                      the backend. The backend can use this to find
 *                      it's instance data.
 * @param   pvBuf       What to write.
 * @param   cbBuf       Number of bytes to write.
 * @param   pcbWritten  Where to store the number of bytes actually written.
 *                      If NULL the entire buffer must be successfully written.
 */
typedef DECLCALLBACK(int) FNDBGCBACKWRITE(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
/** Pointer to a FNDBGCBACKWRITE() callback. */
typedef FNDBGCBACKWRITE *PFNDBGCBACKWRITE;


/**
 * The communication backend provides the console with a number of callbacks
 * which can be used
 */
typedef struct DBGCBACK
{
    /** Check for input. */
    PFNDBGCBACKINPUT    pfnInput;
    /** Read input. */
    PFNDBGCBACKREAD     pfnRead;
    /** Write output. */
    PFNDBGCBACKWRITE    pfnWrite;
} DBGCBACK;


/**
 * Make a console instance.
 *
 * This will not return until either an 'exit' command is issued or a error code
 * indicating connection loss is encountered.
 *
 * @returns VINF_SUCCESS if console termination caused by the 'exit' command.
 * @returns The VBox status code causing the console termination.
 *
 * @param   pVM         VM Handle.
 * @param   pBack       Pointer to the backend structure. This must contain
 *                      a full set of function pointers to service the console.
 * @param   fFlags      Reserved, must be zero.
 * @remark  A forced termination of the console is easiest done by forcing the
 *          callbacks to return fatal failures.
 */
DBGDECL(int)    DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags);


/**
 * Register one or more external commands.
 *
 * @returns VBox status.
 * @param   paCommands      Pointer to an array of command descriptors.
 *                          The commands must be unique. It's not possible
 *                          to register the same commands more than once.
 * @param   cCommands       Number of commands.
 */
DBGDECL(int)    DBGCRegisterCommands(PCDBGCCMD paCommands, unsigned cCommands);


/**
 * Deregister one or more external commands previously registered by
 * DBGCRegisterCommands().
 *
 * @returns VBox status.
 * @param   paCommands      Pointer to an array of command descriptors
 *                          as given to DBGCRegisterCommands().
 * @param   cCommands       Number of commands.
 */
DBGDECL(int)    DBGCDeregisterCommands(PCDBGCCMD paCommands, unsigned cCommands);


/**
 * Spawns a new thread with a TCP based debugging console service.
 *
 * @returns VBox status.
 * @param   pVM         VM handle.
 * @param   ppvData     Where to store the pointer to instance data.
 */
DBGDECL(int)    DBGCTcpCreate(PVM pVM, void **ppvUser);

/**
 * Terminates any running TCP base debugger consolse service.
 *
 * @returns VBox status.
 * @param   pVM         VM handle.
 * @param   pvData      Instance data set by DBGCTcpCreate().
 */
DBGDECL(int)    DBGCTcpTerminate(PVM pVM, void *pvData);


__END_DECLS

#endif