VirtualBox

source: vbox/trunk/include/VBox/dbg.h@ 41558

Last change on this file since 41558 was 41558, checked in by vboxsync, 13 years ago

DBGC: Hacking the command parsing code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.4 KB
Line 
1/** @file
2 * Debugger Interfaces. (VBoxDbg)
3 *
4 * This header covers all external interfaces of the Debugger module.
5 * However, it does not cover the DBGF interface since that part of the
6 * VMM. Use dbgf.h for that.
7 */
8
9/*
10 * Copyright (C) 2006-2007 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * The contents of this file may alternatively be used under the terms
21 * of the Common Development and Distribution License Version 1.0
22 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23 * VirtualBox OSE distribution, in which case the provisions of the
24 * CDDL are applicable instead of those of the GPL.
25 *
26 * You may elect to license modified versions of this file under the
27 * terms and conditions of either the GPL or the CDDL or both.
28 */
29
30#ifndef ___VBox_dbg_h
31#define ___VBox_dbg_h
32
33#include <VBox/cdefs.h>
34#include <VBox/types.h>
35#include <VBox/vmm/dbgf.h>
36
37#include <iprt/stdarg.h>
38#ifdef IN_RING3
39# include <iprt/err.h>
40#endif
41
42RT_C_DECLS_BEGIN
43
44#ifdef IN_RING3 /* The debugger stuff is ring-3 only. */
45
46/** @def VBOX_WITH_DEBUGGER
47 * The build is with debugger module. Test if this is defined before registering
48 * external debugger commands. This is normally defined in Config.kmk.
49 */
50#ifdef DOXYGEN_RUNNING
51# define VBOX_WITH_DEBUGGER
52#endif
53
54
55/**
56 * DBGC variable category.
57 *
58 * Used to describe an argument to a command or function and a functions
59 * return value.
60 */
61typedef enum DBGCVARCAT
62{
63 /** Any type is fine. */
64 DBGCVAR_CAT_ANY = 0,
65 /** Any kind of pointer or number. */
66 DBGCVAR_CAT_POINTER_NUMBER,
67 /** Any kind of pointer or number, no range. */
68 DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE,
69 /** Any kind of pointer. */
70 DBGCVAR_CAT_POINTER,
71 /** Any kind of pointer with no range option. */
72 DBGCVAR_CAT_POINTER_NO_RANGE,
73 /** GC pointer. */
74 DBGCVAR_CAT_GC_POINTER,
75 /** GC pointer with no range option. */
76 DBGCVAR_CAT_GC_POINTER_NO_RANGE,
77 /** Numeric argument. */
78 DBGCVAR_CAT_NUMBER,
79 /** Numeric argument with no range option. */
80 DBGCVAR_CAT_NUMBER_NO_RANGE,
81 /** String. */
82 DBGCVAR_CAT_STRING,
83 /** Symbol. */
84 DBGCVAR_CAT_SYMBOL,
85 /** Option. */
86 DBGCVAR_CAT_OPTION,
87 /** Option + string. */
88 DBGCVAR_CAT_OPTION_STRING,
89 /** Option + number. */
90 DBGCVAR_CAT_OPTION_NUMBER
91} DBGCVARCAT;
92
93
94/**
95 * DBGC variable type.
96 */
97typedef enum DBGCVARTYPE
98{
99 /** unknown... */
100 DBGCVAR_TYPE_UNKNOWN = 0,
101 /** Flat GC pointer. */
102 DBGCVAR_TYPE_GC_FLAT,
103 /** Segmented GC pointer. */
104 DBGCVAR_TYPE_GC_FAR,
105 /** Physical GC pointer. */
106 DBGCVAR_TYPE_GC_PHYS,
107 /** Flat HC pointer. */
108 DBGCVAR_TYPE_HC_FLAT,
109 /** Physical HC pointer. */
110 DBGCVAR_TYPE_HC_PHYS,
111 /** String. */
112 DBGCVAR_TYPE_STRING,
113 /** Number. */
114 DBGCVAR_TYPE_NUMBER,
115 /** Symbol.
116 * @todo drop this */
117 DBGCVAR_TYPE_SYMBOL,
118 /** Special type used when querying symbols. */
119 DBGCVAR_TYPE_ANY
120} DBGCVARTYPE;
121
122/** @todo Rename to DBGCVAR_IS_xyz. */
123
124/** Checks if the specified variable type is of a pointer persuasion. */
125#define DBGCVAR_ISPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_GC_FLAT && enmType <= DBGCVAR_TYPE_HC_PHYS)
126/** Checks if the specified variable type is of a pointer persuasion. */
127#define DBGCVAR_IS_FAR_PTR(enmType) ((enmType) == DBGCVAR_TYPE_GC_FAR)
128/** Checks if the specified variable type is of a pointer persuasion and of the guest context sort. */
129#define DBGCVAR_ISGCPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_GC_FLAT && (enmType) <= DBGCVAR_TYPE_GC_PHYS)
130/** Checks if the specified variable type is of a pointer persuasion and of the host context sort. */
131#define DBGCVAR_ISHCPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_HC_FLAT && (enmType) <= DBGCVAR_TYPE_HC_PHYS)
132
133
134/**
135 * DBGC variable range type.
136 */
137typedef enum DBGCVARRANGETYPE
138{
139 /** No range appliable or no range specified. */
140 DBGCVAR_RANGE_NONE = 0,
141 /** Number of elements. */
142 DBGCVAR_RANGE_ELEMENTS,
143 /** Number of bytes. */
144 DBGCVAR_RANGE_BYTES
145} DBGCVARRANGETYPE;
146
147
148/**
149 * Variable descriptor.
150 */
151typedef struct DBGCVARDESC
152{
153 /** The minimal number of times this argument may occur.
154 * Use 0 here to inidicate that the argument is optional. */
155 unsigned cTimesMin;
156 /** Maximum number of occurrences.
157 * Use ~0 here to indicate infinite. */
158 unsigned cTimesMax;
159 /** Argument category. */
160 DBGCVARCAT enmCategory;
161 /** Flags, DBGCVD_FLAGS_* */
162 unsigned fFlags;
163 /** Argument name. */
164 const char *pszName;
165 /** Argument name. */
166 const char *pszDescription;
167} DBGCVARDESC;
168/** Pointer to an argument descriptor. */
169typedef DBGCVARDESC *PDBGCVARDESC;
170/** Pointer to a const argument descriptor. */
171typedef const DBGCVARDESC *PCDBGCVARDESC;
172
173/** Variable descriptor flags.
174 * @{ */
175/** Indicates that the variable depends on the previous being present. */
176#define DBGCVD_FLAGS_DEP_PREV RT_BIT(1)
177/** @} */
178
179
180/**
181 * DBGC variable.
182 */
183typedef struct DBGCVAR
184{
185 /** Pointer to the argument descriptor. */
186 PCDBGCVARDESC pDesc;
187 /** Pointer to the next argument. */
188 struct DBGCVAR *pNext;
189
190 /** Argument type. */
191 DBGCVARTYPE enmType;
192 /** Type specific. */
193 union
194 {
195 /** Flat GC Address. (DBGCVAR_TYPE_GC_FLAT) */
196 RTGCPTR GCFlat;
197 /** Far (16:32) GC Address. (DBGCVAR_TYPE_GC_FAR) */
198 RTFAR32 GCFar;
199 /** Physical GC Address. (DBGCVAR_TYPE_GC_PHYS) */
200 RTGCPHYS GCPhys;
201 /** Flat HC Address. (DBGCVAR_TYPE_HC_FLAT) */
202 void *pvHCFlat;
203 /** Physical GC Address. (DBGCVAR_TYPE_HC_PHYS) */
204 RTHCPHYS HCPhys;
205 /** String. (DBGCVAR_TYPE_STRING)
206 * The basic idea is the the this is a pointer to the expression we're
207 * parsing, so no messing with freeing. */
208 const char *pszString;
209 /** Number. (DBGCVAR_TYPE_NUMBER) */
210 uint64_t u64Number;
211 } u;
212
213 /** Range type. */
214 DBGCVARRANGETYPE enmRangeType;
215 /** Range. The use of the content depends on the enmRangeType. */
216 uint64_t u64Range;
217} DBGCVAR;
218/** Pointer to a command argument. */
219typedef DBGCVAR *PDBGCVAR;
220/** Pointer to a const command argument. */
221typedef const DBGCVAR *PCDBGCVAR;
222
223
224/**
225 * Macro for initializing a DBGC variable with defaults.
226 * The result is an unknown variable type without any range.
227 */
228#define DBGCVAR_INIT(pVar) \
229 do { \
230 (pVar)->pDesc = NULL;\
231 (pVar)->pNext = NULL; \
232 (pVar)->enmType = DBGCVAR_TYPE_UNKNOWN; \
233 (pVar)->u.u64Number = 0; \
234 (pVar)->enmRangeType = DBGCVAR_RANGE_NONE; \
235 (pVar)->u64Range = 0; \
236 } while (0)
237
238/**
239 * Macro for initializing a DBGC variable with a HC physical address.
240 */
241#define DBGCVAR_INIT_HC_PHYS(pVar, Phys) \
242 do { \
243 DBGCVAR_INIT(pVar); \
244 (pVar)->enmType = DBGCVAR_TYPE_HC_PHYS; \
245 (pVar)->u.HCPhys = (Phys); \
246 } while (0)
247
248/**
249 * Macro for initializing a DBGC variable with a HC flat address.
250 */
251#define DBGCVAR_INIT_HC_FLAT(pVar, Flat) \
252 do { \
253 DBGCVAR_INIT(pVar); \
254 (pVar)->enmType = DBGCVAR_TYPE_HC_FLAT; \
255 (pVar)->u.pvHCFlat = (Flat); \
256 } while (0)
257
258/**
259 * Macro for initializing a DBGC variable with a GC physical address.
260 */
261#define DBGCVAR_INIT_GC_PHYS(pVar, Phys) \
262 do { \
263 DBGCVAR_INIT(pVar); \
264 (pVar)->enmType = DBGCVAR_TYPE_GC_PHYS; \
265 (pVar)->u.GCPhys = (Phys); \
266 } while (0)
267
268/**
269 * Macro for initializing a DBGC variable with a GC flat address.
270 */
271#define DBGCVAR_INIT_GC_FLAT(pVar, Flat) \
272 do { \
273 DBGCVAR_INIT(pVar); \
274 (pVar)->enmType = DBGCVAR_TYPE_GC_FLAT; \
275 (pVar)->u.GCFlat = (Flat); \
276 } while (0)
277
278/**
279 * Macro for initializing a DBGC variable with a GC flat address.
280 */
281#define DBGCVAR_INIT_GC_FLAT_BYTE_RANGE(pVar, Flat, cbRange) \
282 do { \
283 DBGCVAR_INIT(pVar); \
284 (pVar)->enmType = DBGCVAR_TYPE_GC_FLAT; \
285 (pVar)->u.GCFlat = (Flat); \
286 DBGCVAR_SET_RANGE(pVar, DBGCVAR_RANGE_BYTES, cbRange); \
287 } while (0)
288
289/**
290 * Macro for initializing a DBGC variable with a GC far address.
291 */
292#define DBGCVAR_INIT_GC_FAR(pVar, _sel, _off) \
293 do { \
294 DBGCVAR_INIT(pVar); \
295 (pVar)->enmType = DBGCVAR_TYPE_GC_FAR; \
296 (pVar)->u.GCFar.sel = (_sel); \
297 (pVar)->u.GCFar.off = (_off); \
298 } while (0)
299
300/**
301 * Macro for initializing a DBGC variable with a number.
302 */
303#define DBGCVAR_INIT_NUMBER(pVar, Value) \
304 do { \
305 DBGCVAR_INIT(pVar); \
306 (pVar)->enmType = DBGCVAR_TYPE_NUMBER; \
307 (pVar)->u.u64Number = (Value); \
308 } while (0)
309
310/**
311 * Macro for initializing a DBGC variable with a string.
312 */
313#define DBGCVAR_INIT_STRING(pVar, a_pszString) \
314 do { \
315 DBGCVAR_INIT(pVar); \
316 (pVar)->enmType = DBGCVAR_TYPE_STRING; \
317 (pVar)->enmRangeType = DBGCVAR_RANGE_BYTES; \
318 (pVar)->u.pszString = (a_pszString); \
319 (pVar)->u64Range = strlen(a_pszString); \
320 } while (0)
321
322
323/**
324 * Macro for setting the range of a DBGC variable.
325 * @param pVar The variable.
326 * @param _enmRangeType The range type.
327 * @param Value The range length value.
328 */
329#define DBGCVAR_SET_RANGE(pVar, _enmRangeType, Value) \
330 do { \
331 (pVar)->enmRangeType = (_enmRangeType); \
332 (pVar)->u64Range = (Value); \
333 } while (0)
334
335
336/**
337 * Macro for setting the range of a DBGC variable.
338 * @param a_pVar The variable.
339 * @param a_cbRange The range, in bytes.
340 */
341#define DBGCVAR_SET_BYTE_RANGE(a_pVar, a_cbRange) \
342 DBGCVAR_SET_RANGE(a_pVar, DBGCVAR_RANGE_BYTES, a_cbRange)
343
344
345/**
346 * Macro for resetting the range a DBGC variable.
347 * @param a_pVar The variable.
348 */
349#define DBGCVAR_ZAP_RANGE(a_pVar) \
350 do { \
351 (a_pVar)->enmRangeType = DBGCVAR_RANGE_NONE; \
352 (a_pVar)->u64Range = 0; \
353 } while (0)
354
355
356/**
357 * Macro for assigning one DBGC variable to another.
358 * @param a_pResult The result (target) variable.
359 * @param a_pVar The source variable.
360 */
361#define DBGCVAR_ASSIGN(a_pResult, a_pVar) \
362 do { \
363 *(a_pResult) = *(a_pVar); \
364 } while (0)
365
366
367/** Pointer to command descriptor. */
368typedef struct DBGCCMD *PDBGCCMD;
369/** Pointer to const command descriptor. */
370typedef const struct DBGCCMD *PCDBGCCMD;
371
372/** Pointer to helper functions for commands. */
373typedef struct DBGCCMDHLP *PDBGCCMDHLP;
374
375
376/**
377 * Helper functions for commands.
378 */
379typedef struct DBGCCMDHLP
380{
381 /** Magic value (DBGCCMDHLP_MAGIC). */
382 uint32_t u32Magic;
383
384 /**
385 * Command helper for writing formatted text to the debug console.
386 *
387 * @returns VBox status.
388 * @param pCmdHlp Pointer to the command callback structure.
389 * @param pcb Where to store the number of bytes written.
390 * @param pszFormat The format string. This may use all IPRT extensions as
391 * well as the debugger ones.
392 * @param ... Arguments specified in the format string.
393 */
394 DECLCALLBACKMEMBER(int, pfnPrintf)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, ...);
395
396 /**
397 * Command helper for writing formatted text to the debug console.
398 *
399 * @returns VBox status.
400 * @param pCmdHlp Pointer to the command callback structure.
401 * @param pcb Where to store the number of bytes written.
402 * @param pszFormat The format string. This may use all IPRT extensions as
403 * well as the debugger ones.
404 * @param args Arguments specified in the format string.
405 */
406 DECLCALLBACKMEMBER(int, pfnPrintfV)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args);
407
408 /**
409 * Command helper for formatting a string with debugger format specifiers.
410 *
411 * @returns The number of bytes written.
412 * @param pCmdHlp Pointer to the command callback structure.
413 * @param pszBuf The output buffer.
414 * @param cbBuf The size of the output buffer.
415 * @param pszFormat The format string. This may use all IPRT extensions as
416 * well as the debugger ones.
417 * @param ... Arguments specified in the format string.
418 */
419 DECLCALLBACKMEMBER(size_t, pfnStrPrintf)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
420
421 /**
422 * Command helper for formatting a string with debugger format specifiers.
423 *
424 * @returns The number of bytes written.
425 * @param pCmdHlp Pointer to the command callback structure.
426 * @param pszBuf The output buffer.
427 * @param cbBuf The size of the output buffer.
428 * @param pszFormat The format string. This may use all IPRT extensions as
429 * well as the debugger ones.
430 * @param va Arguments specified in the format string.
431 */
432 DECLCALLBACKMEMBER(size_t, pfnStrPrintfV)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf,
433 const char *pszFormat, va_list va);
434
435 /**
436 * Command helper for formatting and error message for a VBox status code.
437 *
438 * @returns VBox status code appropriate to return from a command.
439 * @param pCmdHlp Pointer to the command callback structure.
440 * @param rc The VBox status code.
441 * @param pszFormat Format string for additional messages. Can be NULL.
442 * @param ... Format arguments, optional.
443 */
444 DECLCALLBACKMEMBER(int, pfnVBoxError)(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...);
445
446 /**
447 * Command helper for formatting and error message for a VBox status code.
448 *
449 * @returns VBox status code appropriate to return from a command.
450 * @param pCmdHlp Pointer to the command callback structure.
451 * @param rc The VBox status code.
452 * @param pcb Where to store the number of bytes written.
453 * @param pszFormat Format string for additional messages. Can be NULL.
454 * @param args Format arguments, optional.
455 */
456 DECLCALLBACKMEMBER(int, pfnVBoxErrorV)(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, va_list args);
457
458 /**
459 * Command helper for reading memory specified by a DBGC variable.
460 *
461 * @returns VBox status code appropriate to return from a command.
462 * @param pCmdHlp Pointer to the command callback structure.
463 * @param pVM VM handle if GC or physical HC address.
464 * @param pvBuffer Where to store the read data.
465 * @param cbRead Number of bytes to read.
466 * @param pVarPointer DBGC variable specifying where to start reading.
467 * @param pcbRead Where to store the number of bytes actually read.
468 * This optional, but it's useful when read GC virtual memory where a
469 * page in the requested range might not be present.
470 * If not specified not-present failure or end of a HC physical page
471 * will cause failure.
472 */
473 DECLCALLBACKMEMBER(int, pfnMemRead)(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead);
474
475 /**
476 * Command helper for writing memory specified by a DBGC variable.
477 *
478 * @returns VBox status code appropriate to return from a command.
479 * @param pCmdHlp Pointer to the command callback structure.
480 * @param pVM VM handle if GC or physical HC address.
481 * @param pvBuffer What to write.
482 * @param cbWrite Number of bytes to write.
483 * @param pVarPointer DBGC variable specifying where to start reading.
484 * @param pcbWritten Where to store the number of bytes written.
485 * This is optional. If NULL be aware that some of the buffer
486 * might have been written to the specified address.
487 */
488 DECLCALLBACKMEMBER(int, pfnMemWrite)(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten);
489
490 /**
491 * Executes command an expression.
492 * (Hopefully the parser and functions are fully reentrant.)
493 *
494 * @returns VBox status code appropriate to return from a command.
495 * @param pCmdHlp Pointer to the command callback structure.
496 * @param pszExpr The expression. Format string with the format DBGC extensions.
497 * @param ... Format arguments.
498 */
499 DECLCALLBACKMEMBER(int, pfnExec)(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...);
500
501 /**
502 * Evaluates an expression.
503 * (Hopefully the parser and functions are fully reentrant.)
504 *
505 * @returns VBox status code appropriate to return from a command.
506 * @param pCmdHlp Pointer to the command callback structure.
507 * @param pResult Where to store the result.
508 * @param pszExpr The expression. Format string with the format DBGC extensions.
509 * @param va Format arguments.
510 */
511 DECLCALLBACKMEMBER(int, pfnEvalV)(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, va_list va);
512
513 /**
514 * Print an error and fail the current command.
515 *
516 * @returns VBox status code to pass upwards.
517 *
518 * @param pCmdHlp Pointer to the command callback structure.
519 * @param pCmd The failing command.
520 * @param pszFormat The error message format string.
521 * @param va Format arguments.
522 */
523 DECLCALLBACKMEMBER(int, pfnFailV)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, va_list va);
524
525 /**
526 * Print an error and fail the current command.
527 *
528 * @returns VBox status code to pass upwards.
529 *
530 * @param pCmdHlp Pointer to the command callback structure.
531 * @param pCmd The failing command.
532 * @param rc The status code indicating the failure. This will
533 * be appended to the message after a colon (': ').
534 * @param pszFormat The error message format string.
535 * @param va Format arguments.
536 *
537 * @see DBGCCmdHlpFailRc
538 */
539 DECLCALLBACKMEMBER(int, pfnFailRcV)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int rc, const char *pszFormat, va_list va);
540
541 /**
542 * Parser error.
543 *
544 * @returns VBox status code to pass upwards.
545 *
546 * @param pCmdHlp Pointer to the command callback structure.
547 * @param pCmd The failing command, can be NULL but shouldn't.
548 * @param iArg The offending argument, -1 when lazy.
549 * @param pszExpr The expression.
550 * @param iLine The line number.
551 */
552 DECLCALLBACKMEMBER(int, pfnParserError)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int iArg, const char *pszExpr, unsigned iLine);
553
554 /**
555 * Converts a DBGC variable to a DBGF address structure.
556 *
557 * @returns VBox status code.
558 * @param pCmdHlp Pointer to the command callback structure.
559 * @param pVar The variable to convert.
560 * @param pAddress The target address.
561 */
562 DECLCALLBACKMEMBER(int, pfnVarToDbgfAddr)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress);
563
564 /**
565 * Converts a DBGF address structure to a DBGC variable.
566 *
567 * @returns VBox status code.
568 * @param pCmdHlp Pointer to the command callback structure.
569 * @param pAddress The source address.
570 * @param pResult The result variable.
571 */
572 DECLCALLBACKMEMBER(int, pfnVarFromDbgfAddr)(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult);
573
574 /**
575 * Converts a DBGC variable to a 64-bit number.
576 *
577 * @returns VBox status code.
578 * @param pCmdHlp Pointer to the command callback structure.
579 * @param pVar The variable to convert.
580 * @param pu64Number Where to store the number.
581 */
582 DECLCALLBACKMEMBER(int, pfnVarToNumber)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number);
583
584 /**
585 * Converts a DBGC variable to a boolean.
586 *
587 * @returns VBox status code.
588 * @param pCmdHlp Pointer to the command callback structure.
589 * @param pVar The variable to convert.
590 * @param pf Where to store the boolean.
591 */
592 DECLCALLBACKMEMBER(int, pfnVarToBool)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf);
593
594 /**
595 * Get the range of a variable in bytes, resolving symbols if necessary.
596 *
597 * @returns VBox status code.
598 * @param pCmdHlp Pointer to the command callback structure.
599 * @param pVar The variable to convert.
600 * @param cbElement Conversion factor for element ranges.
601 * @param cbDefault The default range.
602 * @param pcbRange The length of the range.
603 */
604 DECLCALLBACKMEMBER(int, pfnVarGetRange)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault,
605 uint64_t *pcbRange);
606
607 /**
608 * Converts a variable to one with the specified type.
609 *
610 * This preserves the range.
611 *
612 * @returns VBox status code.
613 * @param pCmdHlp Pointer to the command callback structure.
614 * @param pVar The variable to convert.
615 * @param enmToType The target type.
616 * @param fConvSyms If @c true, then attempt to resolve symbols.
617 * @param pResult The output variable. Can be the same as @a pVar.
618 */
619 DECLCALLBACKMEMBER(int, pfnVarConvert)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, DBGCVARTYPE enmToType, bool fConvSyms,
620 PDBGCVAR pResult);
621
622 /**
623 * Gets a DBGF output helper that directs the output to the debugger
624 * console.
625 *
626 * @returns Pointer to the helper structure.
627 * @param pCmdHlp Pointer to the command callback structure.
628 */
629 DECLCALLBACKMEMBER(PCDBGFINFOHLP, pfnGetDbgfOutputHlp)(PDBGCCMDHLP pCmdHlp);
630
631 /** End marker (DBGCCMDHLP_MAGIC). */
632 uint32_t u32EndMarker;
633} DBGCCMDHLP;
634
635/** Magic value for DBGCCMDHLP::u32Magic. (Fyodor Mikhaylovich Dostoyevsky) */
636#define DBGCCMDHLP_MAGIC UINT32_C(18211111)
637
638
639#ifdef IN_RING3
640
641/**
642 * @copydoc DBGCCMDHLP::pfnPrintf
643 */
644DECLINLINE(int) DBGCCmdHlpPrintf(PDBGCCMDHLP pCmdHlp, const char *pszFormat, ...)
645{
646 va_list va;
647 int rc;
648
649 va_start(va, pszFormat);
650 rc = pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, va);
651 va_end(va);
652
653 return rc;
654}
655
656
657/**
658 * @copydoc DBGCCMDHLP::pfnStrPrintf
659 */
660DECLINLINE(size_t) DBGCCmdHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
661{
662 va_list va;
663 size_t cch;
664
665 va_start(va, pszFormat);
666 cch = pCmdHlp->pfnStrPrintfV(pCmdHlp, pszBuf, cbBuf, pszFormat, va);
667 va_end(va);
668
669 return cch;
670}
671
672/**
673 * @copydoc FNDBGCHLPVBOXERROR
674 */
675DECLINLINE(int) DBGCCmdHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...)
676{
677 va_list va;
678
679 va_start(va, pszFormat);
680 rc = pCmdHlp->pfnVBoxErrorV(pCmdHlp, rc, pszFormat, va);
681 va_end(va);
682
683 return rc;
684}
685
686/**
687 * @copydoc FNDBGCHLPMEMREAD
688 */
689DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead)
690{
691 return pCmdHlp->pfnMemRead(pCmdHlp, pVM, pvBuffer, cbRead, pVarPointer, pcbRead);
692}
693
694/**
695 * Evaluates an expression.
696 * (Hopefully the parser and functions are fully reentrant.)
697 *
698 * @returns VBox status code appropriate to return from a command.
699 * @param pCmdHlp Pointer to the command callback structure.
700 * @param pResult Where to store the result.
701 * @param pszExpr The expression. Format string with the format DBGC extensions.
702 * @param ... Format arguments.
703 */
704DECLINLINE(int) DBGCCmdHlpEval(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, ...)
705{
706 va_list va;
707 int rc;
708
709 va_start(va, pszExpr);
710 rc = pCmdHlp->pfnEvalV(pCmdHlp, pResult, pszExpr, va);
711 va_end(va);
712
713 return rc;
714}
715
716/**
717 * Print an error and fail the current command.
718 *
719 * @returns VBox status code to pass upwards.
720 *
721 * @param pCmdHlp Pointer to the command callback structure.
722 * @param pCmd The failing command.
723 * @param pszFormat The error message format string.
724 * @param ... Format arguments.
725 */
726DECLINLINE(int) DBGCCmdHlpFail(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, ...)
727{
728 va_list va;
729 int rc;
730
731 va_start(va, pszFormat);
732 rc = pCmdHlp->pfnFailV(pCmdHlp, pCmd, pszFormat, va);
733 va_end(va);
734
735 return rc;
736}
737
738/**
739 * Print an error and fail the current command.
740 *
741 * Usage example:
742 * @code
743 int rc = VMMR3Something(pVM);
744 if (RT_FAILURE(rc))
745 return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "VMMR3Something");
746 return VINF_SUCCESS;
747 * @endcode
748 *
749 * @returns VBox status code to pass upwards.
750 *
751 * @param pCmdHlp Pointer to the command callback structure.
752 * @param pCmd The failing command.
753 * @param rc The status code indicating the failure.
754 * @param pszFormat The error message format string.
755 * @param ... Format arguments.
756 */
757DECLINLINE(int) DBGCCmdHlpFailRc(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int rc, const char *pszFormat, ...)
758{
759 va_list va;
760
761 va_start(va, pszFormat);
762 rc = pCmdHlp->pfnFailRcV(pCmdHlp, pCmd, rc, pszFormat, va);
763 va_end(va);
764
765 return rc;
766}
767
768/**
769 * @copydoc DBGCCMDHLP::pfnParserError
770 */
771DECLINLINE(int) DBGCCmdHlpParserError(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int iArg, const char *pszExpr, unsigned iLine)
772{
773 return pCmdHlp->pfnParserError(pCmdHlp, pCmd, iArg, pszExpr, iLine);
774}
775
776/** Assert+return like macro for checking parser sanity.
777 * Returns with failure if the precodition is not met. */
778#define DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, iArg, expr) \
779 do { \
780 if (!(expr)) \
781 return DBGCCmdHlpParserError(pCmdHlp, pCmd, iArg, #expr, __LINE__); \
782 } while (0)
783
784/** Assert+return like macro that the VM handle is present.
785 * Returns with failure if the VM handle is NIL. */
786#define DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM) \
787 do { \
788 if (!(pVM)) \
789 return DBGCCmdHlpFail(pCmdHlp, pCmd, "No VM selected"); \
790 } while (0)
791
792/**
793 * @copydoc DBGCCMDHLP::pfnVarToDbgfAddr
794 */
795DECLINLINE(int) DBGCCmdHlpVarToDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
796{
797 return pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, pAddress);
798}
799
800/**
801 * @copydoc DBGCCMDHLP::pfnVarToDbgfAddr
802 */
803DECLINLINE(int) DBGCCmdHlpVarFromDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult)
804{
805 return pCmdHlp->pfnVarFromDbgfAddr(pCmdHlp, pAddress, pResult);
806}
807
808/**
809 * Converts an variable to a flat address.
810 *
811 * @returns VBox status code.
812 * @param pCmdHlp Pointer to the command callback structure.
813 * @param pVar The variable to convert.
814 * @param pFlatPtr Where to store the flat address.
815 */
816DECLINLINE(int) DBGCCmdHlpVarToFlatAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PRTGCPTR pFlatPtr)
817{
818 DBGFADDRESS Addr;
819 int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, &Addr);
820 if (RT_SUCCESS(rc))
821 *pFlatPtr = Addr.FlatPtr;
822 return rc;
823}
824
825/**
826 * @copydoc DBGCCMDHLP::pfnVarToNumber
827 */
828DECLINLINE(int) DBGCCmdHlpVarToNumber(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number)
829{
830 return pCmdHlp->pfnVarToNumber(pCmdHlp, pVar, pu64Number);
831}
832
833/**
834 * @copydoc DBGCCMDHLP::pfnVarToBool
835 */
836DECLINLINE(int) DBGCCmdHlpVarToBool(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf)
837{
838 return pCmdHlp->pfnVarToBool(pCmdHlp, pVar, pf);
839}
840
841/**
842 * @copydoc DBGCCMDHLP::pfnVarGetRange
843 */
844DECLINLINE(int) DBGCCmdHlpVarGetRange(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault, uint64_t *pcbRange)
845{
846 return pCmdHlp->pfnVarGetRange(pCmdHlp, pVar, cbElement, cbDefault, pcbRange);
847}
848
849/**
850 * @copydoc DBGCCMDHLP::pfnVarConvert
851 */
852DECLINLINE(int) DBGCCmdHlpConvert(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, DBGCVARTYPE enmToType, bool fConvSyms, PDBGCVAR pResult)
853{
854 return pCmdHlp->pfnVarConvert(pCmdHlp, pVar, enmToType, fConvSyms, pResult);
855}
856
857/**
858 * @copydoc DBGCCMDHLP::pfnGetDbgfOutputHlp
859 */
860DECLINLINE(PCDBGFINFOHLP) DBGCCmdHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp)
861{
862 return pCmdHlp->pfnGetDbgfOutputHlp(pCmdHlp);
863}
864
865#endif /* IN_RING3 */
866
867
868
869/**
870 * Command handler.
871 *
872 * The console will call the handler for a command once it's finished
873 * parsing the user input. The command handler function is responsible
874 * for executing the command itself.
875 *
876 * @returns VBox status.
877 * @param pCmd Pointer to the command descriptor (as registered).
878 * @param pCmdHlp Pointer to command helper functions.
879 * @param pVM Pointer to the current VM (if any).
880 * @param paArgs Pointer to (readonly) array of arguments.
881 * @param cArgs Number of arguments in the array.
882 */
883typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
884/** Pointer to a FNDBGCCMD() function. */
885typedef FNDBGCCMD *PFNDBGCCMD;
886
887/**
888 * DBGC command descriptor.
889 *
890 * If a pResultDesc is specified the command can be called and used
891 * as a function too. If it's a pure function, set fFlags to
892 * DBGCCMD_FLAGS_FUNCTION.
893 */
894typedef struct DBGCCMD
895{
896 /** Command string. */
897 const char *pszCmd;
898 /** Minimum number of arguments. */
899 unsigned cArgsMin;
900 /** Max number of arguments. */
901 unsigned cArgsMax;
902 /** Argument descriptors (array). */
903 PCDBGCVARDESC paArgDescs;
904 /** Number of argument descriptors. */
905 unsigned cArgDescs;
906 /** flags. (reserved for now) */
907 unsigned fFlags;
908 /** Handler function. */
909 PFNDBGCCMD pfnHandler;
910 /** Command syntax. */
911 const char *pszSyntax;
912 /** Command description. */
913 const char *pszDescription;
914} DBGCCMD;
915
916/** DBGCCMD Flags.
917 * @{
918 */
919/** @} */
920
921
922
923/** Pointer to a DBGC backend. */
924typedef struct DBGCBACK *PDBGCBACK;
925
926/**
927 * Checks if there is input.
928 *
929 * @returns true if there is input ready.
930 * @returns false if there not input ready.
931 * @param pBack Pointer to the backend structure supplied by
932 * the backend. The backend can use this to find
933 * it's instance data.
934 * @param cMillies Number of milliseconds to wait on input data.
935 */
936typedef DECLCALLBACK(bool) FNDBGCBACKINPUT(PDBGCBACK pBack, uint32_t cMillies);
937/** Pointer to a FNDBGCBACKINPUT() callback. */
938typedef FNDBGCBACKINPUT *PFNDBGCBACKINPUT;
939
940/**
941 * Read input.
942 *
943 * @returns VBox status code.
944 * @param pBack Pointer to the backend structure supplied by
945 * the backend. The backend can use this to find
946 * it's instance data.
947 * @param pvBuf Where to put the bytes we read.
948 * @param cbBuf Maximum nymber of bytes to read.
949 * @param pcbRead Where to store the number of bytes actually read.
950 * If NULL the entire buffer must be filled for a
951 * successful return.
952 */
953typedef DECLCALLBACK(int) FNDBGCBACKREAD(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
954/** Pointer to a FNDBGCBACKREAD() callback. */
955typedef FNDBGCBACKREAD *PFNDBGCBACKREAD;
956
957/**
958 * Write (output).
959 *
960 * @returns VBox status code.
961 * @param pBack Pointer to the backend structure supplied by
962 * the backend. The backend can use this to find
963 * it's instance data.
964 * @param pvBuf What to write.
965 * @param cbBuf Number of bytes to write.
966 * @param pcbWritten Where to store the number of bytes actually written.
967 * If NULL the entire buffer must be successfully written.
968 */
969typedef DECLCALLBACK(int) FNDBGCBACKWRITE(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
970/** Pointer to a FNDBGCBACKWRITE() callback. */
971typedef FNDBGCBACKWRITE *PFNDBGCBACKWRITE;
972
973/**
974 * Ready / busy notification.
975 *
976 * @param pBack Pointer to the backend structure supplied by
977 * the backend. The backend can use this to find
978 * it's instance data.
979 * @param fReady Whether it's ready (true) or busy (false).
980 */
981typedef DECLCALLBACK(void) FNDBGCBACKSETREADY(PDBGCBACK pBack, bool fReady);
982/** Pointer to a FNDBGCBACKSETREADY() callback. */
983typedef FNDBGCBACKSETREADY *PFNDBGCBACKSETREADY;
984
985
986/**
987 * The communication backend provides the console with a number of callbacks
988 * which can be used
989 */
990typedef struct DBGCBACK
991{
992 /** Check for input. */
993 PFNDBGCBACKINPUT pfnInput;
994 /** Read input. */
995 PFNDBGCBACKREAD pfnRead;
996 /** Write output. */
997 PFNDBGCBACKWRITE pfnWrite;
998 /** Ready / busy notification. */
999 PFNDBGCBACKSETREADY pfnSetReady;
1000} DBGCBACK;
1001
1002
1003/**
1004 * Make a console instance.
1005 *
1006 * This will not return until either an 'exit' command is issued or a error code
1007 * indicating connection loss is encountered.
1008 *
1009 * @returns VINF_SUCCESS if console termination caused by the 'exit' command.
1010 * @returns The VBox status code causing the console termination.
1011 *
1012 * @param pVM VM Handle.
1013 * @param pBack Pointer to the backend structure. This must contain
1014 * a full set of function pointers to service the console.
1015 * @param fFlags Reserved, must be zero.
1016 * @remark A forced termination of the console is easiest done by forcing the
1017 * callbacks to return fatal failures.
1018 */
1019DBGDECL(int) DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags);
1020
1021
1022/**
1023 * Register one or more external commands.
1024 *
1025 * @returns VBox status.
1026 * @param paCommands Pointer to an array of command descriptors.
1027 * The commands must be unique. It's not possible
1028 * to register the same commands more than once.
1029 * @param cCommands Number of commands.
1030 */
1031DBGDECL(int) DBGCRegisterCommands(PCDBGCCMD paCommands, unsigned cCommands);
1032
1033
1034/**
1035 * Deregister one or more external commands previously registered by
1036 * DBGCRegisterCommands().
1037 *
1038 * @returns VBox status.
1039 * @param paCommands Pointer to an array of command descriptors
1040 * as given to DBGCRegisterCommands().
1041 * @param cCommands Number of commands.
1042 */
1043DBGDECL(int) DBGCDeregisterCommands(PCDBGCCMD paCommands, unsigned cCommands);
1044
1045
1046/**
1047 * Spawns a new thread with a TCP based debugging console service.
1048 *
1049 * @returns VBox status.
1050 * @param pVM VM handle.
1051 * @param ppvData Where to store the pointer to instance data.
1052 */
1053DBGDECL(int) DBGCTcpCreate(PVM pVM, void **ppvUser);
1054
1055/**
1056 * Terminates any running TCP base debugger console service.
1057 *
1058 * @returns VBox status.
1059 * @param pVM VM handle.
1060 * @param pvData Instance data set by DBGCTcpCreate().
1061 */
1062DBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData);
1063
1064
1065/** @defgroup grp_dbgc_plug_in The DBGC Plug-in Interface
1066 * @{
1067 */
1068
1069/** The plug-in module name prefix. */
1070#define DBGC_PLUG_IN_PREFIX "DBGCPlugIn"
1071
1072/** The name of the plug-in entry point (FNDBGCPLUGIN) */
1073#define DBGC_PLUG_IN_ENTRYPOINT "DBGCPlugInEntry"
1074
1075/**
1076 * DBGC plug-in operations.
1077 */
1078typedef enum DBGCPLUGINOP
1079{
1080 /** The usual invalid first value. */
1081 DBGCPLUGINOP_INVALID,
1082 /** Initialize the plug-in, register all the stuff.
1083 * The plug-in will be unloaded on failure.
1084 * uArg: The VirtualBox version (major+minor). */
1085 DBGCPLUGINOP_INIT,
1086 /** Terminate the plug-ing, deregister all the stuff.
1087 * The plug-in will be unloaded after this call regardless of the return
1088 * code. */
1089 DBGCPLUGINOP_TERM,
1090 /** The usual 32-bit hack. */
1091 DBGCPLUGINOP_32BIT_HACK = 0x7fffffff
1092} DBGCPLUGINOP;
1093
1094/**
1095 * DBGC plug-in main entry point.
1096 *
1097 * @returns VBox status code.
1098 *
1099 * @param enmOperation The operation.
1100 * @param pVM The VM handle. This may be NULL.
1101 * @param uArg Extra argument.
1102 */
1103typedef DECLCALLBACK(int) FNDBGCPLUGIN(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg);
1104/** Pointer to a FNDBGCPLUGIN. */
1105typedef FNDBGCPLUGIN *PFNDBGCPLUGIN;
1106
1107/** @copydoc FNDBGCPLUGIN */
1108DECLEXPORT(int) DBGCPlugInEntry(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg);
1109
1110#endif /* IN_RING3 */
1111
1112/** @} */
1113
1114
1115RT_C_DECLS_END
1116
1117#endif
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