VirtualBox

root/trunk/include/VBox/dbgf.h

Revision 14072, 33.0 kB (checked in by vboxsync, 2 months ago)

MM: The 64-bit MSC warning hunt continues.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /** @file
2  * DBGF - Debugger Facility.
3  */
4
5 /*
6  * Copyright (C) 2006-2007 Sun Microsystems, Inc.
7  *
8  * This file is part of VirtualBox Open Source Edition (OSE), as
9  * available from http://www.virtualbox.org. This file is free software;
10  * you can redistribute it and/or modify it under the terms of the GNU
11  * General Public License (GPL) as published by the Free Software
12  * Foundation, in version 2 as it comes in the "COPYING" file of the
13  * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14  * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15  *
16  * The contents of this file may alternatively be used under the terms
17  * of the Common Development and Distribution License Version 1.0
18  * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19  * VirtualBox OSE distribution, in which case the provisions of the
20  * CDDL are applicable instead of those of the GPL.
21  *
22  * You may elect to license modified versions of this file under the
23  * terms and conditions of either the GPL or the CDDL or both.
24  *
25  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26  * Clara, CA 95054 USA or visit http://www.sun.com if you need
27  * additional information or have any questions.
28  */
29
30 #ifndef ___VBox_dbgf_h
31 #define ___VBox_dbgf_h
32
33 #include <VBox/cdefs.h>
34 #include <VBox/types.h>
35 #include <VBox/vmm.h>
36 #include <VBox/log.h>                   /* LOG_ENABLED */
37
38 #include <iprt/stdarg.h>
39
40 __BEGIN_DECLS
41
42
43 /** @defgroup grp_dbgf     The Debugger Facility API
44  * @{
45  */
46
47 #ifdef IN_RC
48 /** @addgroup grp_dbgf_gc  The GC DBGF API
49  * @ingroup grp_dbgf
50  * @{
51  */
52 VMMRCDECL(int) DBGFGCTrap01Handler(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6);
53 VMMRCDECL(int) DBGFGCTrap03Handler(PVM pVM, PCPUMCTXCORE pRegFrame);
54 /** @} */
55 #endif
56
57 #ifdef IN_RING0
58 /** @addgroup grp_dbgf_gc  The R0 DBGF API
59  * @ingroup grp_dbgf
60  * @{
61  */
62 VMMR0DECL(int) DBGFR0Trap01Handler(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6);
63 VMMR0DECL(int) DBGFR0Trap03Handler(PVM pVM, PCPUMCTXCORE pRegFrame);
64 /** @} */
65 #endif
66
67
68
69 /**
70  * Mixed address.
71  */
72 typedef struct DBGFADDRESS
73 {
74     /** The flat address. */
75     RTGCUINTPTR FlatPtr;
76     /** The selector offset address. */
77     RTGCUINTPTR off;
78     /** The selector. DBGF_SEL_FLAT is a legal value. */
79     RTSEL       Sel;
80     /** Flags describing further details about the address. */
81     uint16_t    fFlags;
82 } DBGFADDRESS;
83 /** Pointer to a mixed address. */
84 typedef DBGFADDRESS *PDBGFADDRESS;
85 /** Pointer to a const mixed address. */
86 typedef const DBGFADDRESS *PCDBGFADDRESS;
87
88 /** @name DBGFADDRESS Flags.
89  * @{ */
90 /** A 16:16 far address. */
91 #define DBGFADDRESS_FLAGS_FAR16         0
92 /** A 16:32 far address. */
93 #define DBGFADDRESS_FLAGS_FAR32         1
94 /** A 16:64 far address. */
95 #define DBGFADDRESS_FLAGS_FAR64         2
96 /** A flat address. */
97 #define DBGFADDRESS_FLAGS_FLAT          3
98 /** A physical address. */
99 #define DBGFADDRESS_FLAGS_PHYS          4
100 /** The address type mask. */
101 #define DBGFADDRESS_FLAGS_TYPE_MASK     7
102
103 /** Set if the address is valid. */
104 #define DBGFADDRESS_FLAGS_VALID         RT_BIT(3)
105
106 /** The address is within the hypervisor memoary area (HMA).
107  * If not set, the address can be assumed to be a guest address. */
108 #define DBGFADDRESS_FLAGS_HMA           RT_BIT(4)
109
110 /** Checks if the mixed address is flat or not. */
111 #define DBGFADDRESS_IS_FLAT(pAddress)    ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FLAT )
112 /** Checks if the mixed address is flat or not. */
113 #define DBGFADDRESS_IS_PHYS(pAddress)    ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_PHYS )
114 /** Checks if the mixed address is far 16:16 or not. */
115 #define DBGFADDRESS_IS_FAR16(pAddress)   ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR16 )
116 /** Checks if the mixed address is far 16:32 or not. */
117 #define DBGFADDRESS_IS_FAR32(pAddress)   ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR32 )
118 /** Checks if the mixed address is far 16:64 or not. */
119 #define DBGFADDRESS_IS_FAR64(pAddress)   ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR64 )
120 /** Checks if the mixed address is valid. */
121 #define DBGFADDRESS_IS_VALID(pAddress)   ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_VALID) )
122 /** Checks if the address is flagged as within the HMA. */
123 #define DBGFADDRESS_IS_HMA(pAddress)     ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_HMA) )
124 /** @} */
125
126 VMMR3DECL(int)  DBGFR3AddrFromSelOff(PVM pVM, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off);
127 VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PVM pVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr);
128 VMMR3DECL(void) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
129 VMMR3DECL(bool) DBGFR3AddrIsValid(PVM pVM, PCDBGFADDRESS pAddress);
130
131
132
133
134 /**
135  * VMM Debug Event Type.
136  */
137 typedef enum DBGFEVENTTYPE
138 {
139     /** Halt completed.
140      * This notifies that a halt command have been successfully completed.
141      */
142     DBGFEVENT_HALT_DONE = 0,
143     /** Detach completed.
144      * This notifies that the detach command have been successfully completed.
145      */
146     DBGFEVENT_DETACH_DONE,
147     /** The command from the debugger is not recognized.
148      * This means internal error or half implemented features.
149      */
150     DBGFEVENT_INVALID_COMMAND,
151
152
153     /** Fatal error.
154      * This notifies a fatal error in the VMM and that the debugger get's a
155      * chance to first hand information about the the problem.
156      */
157     DBGFEVENT_FATAL_ERROR = 100,
158     /** Breakpoint Hit.
159      * This notifies that a breakpoint installed by the debugger was hit. The
160      * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
161      */
162     DBGFEVENT_BREAKPOINT,
163     /** Breakpoint Hit in the Hypervisor.
164      * This notifies that a breakpoint installed by the debugger was hit. The
165      * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
166      */
167     DBGFEVENT_BREAKPOINT_HYPER,
168     /** Assertion in the Hypervisor (breakpoint instruction).
169      * This notifies that a breakpoint instruction was hit in the hypervisor context.
170      */
171     DBGFEVENT_ASSERTION_HYPER,
172     /** Single Stepped.
173      * This notifies that a single step operation was completed.
174      */
175     DBGFEVENT_STEPPED,
176     /** Single Stepped.
177      * This notifies that a hypervisor single step operation was completed.
178      */
179     DBGFEVENT_STEPPED_HYPER,
180     /** The developer have used the DBGFSTOP macro or the PDMDeviceDBGFSTOP function
181      * to bring up the debugger at a specific place.
182      */
183     DBGFEVENT_DEV_STOP,
184     /** The VM is terminating.
185      * When this notification is received, the debugger thread should detach ASAP.
186      */
187     DBGFEVENT_TERMINATING,
188
189     /** The usual 32-bit hack. */
190     DBGFEVENT_32BIT_HACK = 0x7fffffff
191 } DBGFEVENTTYPE;
192
193
194 /**
195  * The context of an event.
196  */
197 typedef enum DBGFEVENTCTX
198 {
199     /** The usual invalid entry. */
200     DBGFEVENTCTX_INVALID = 0,
201     /** Raw mode. */
202     DBGFEVENTCTX_RAW,
203     /** Recompiled mode. */
204     DBGFEVENTCTX_REM,
205     /** VMX / AVT mode. */
206     DBGFEVENTCTX_HWACCL,
207     /** Hypervisor context. */
208     DBGFEVENTCTX_HYPER,
209     /** Other mode */
210     DBGFEVENTCTX_OTHER,
211
212     /** The usual 32-bit hack */
213     DBGFEVENTCTX_32BIT_HACK = 0x7fffffff
214 } DBGFEVENTCTX;
215
216 /**
217  * VMM Debug Event.
218  */
219 typedef struct DBGFEVENT
220 {
221     /** Type. */
222     DBGFEVENTTYPE   enmType;
223     /** Context */
224     DBGFEVENTCTX    enmCtx;
225     /** Type specific data. */
226     union
227     {
228         /** Fatal error details. */
229         struct
230         {
231             /** The GC return code. */
232             int         rc;
233         } FatalError;
234
235         /** Source location. */
236         struct
237         {
238             /** File name. */
239             R3PTRTYPE(const char *) pszFile;
240             /** Function name. */
241             R3PTRTYPE(const char *) pszFunction;
242             /** Message. */
243             R3PTRTYPE(const char *) pszMessage;
244             /** Line number. */
245             unsigned    uLine;
246         } Src;
247
248         /** Assertion messages. */
249         struct
250         {
251             /** The first message. */
252             R3PTRTYPE(const char *) pszMsg1;
253             /** The second message. */
254             R3PTRTYPE(const char *) pszMsg2;
255         } Assert;
256
257         /** Breakpoint. */
258         struct DBGFEVENTBP
259         {
260             /** The identifier of the breakpoint which was hit. */
261             RTUINT      iBp;
262         } Bp;
263         /** Padding for ensuring that the structure is 8 byte aligned. */
264         uint64_t        au64Padding[4];
265     } u;
266 } DBGFEVENT;
267 /** Pointer to VMM Debug Event. */
268 typedef DBGFEVENT *PDBGFEVENT;
269 /** Pointer to const VMM Debug Event. */
270 typedef const DBGFEVENT *PCDBGFEVENT;
271
272
273 /** @def DBGFSTOP
274  * Stops the debugger raising a DBGFEVENT_DEVELOPER_STOP event.
275  *
276  * @returns VBox status code which must be propagated up to EM if not VINF_SUCCESS.
277  * @param   pVM     VM Handle.
278  */
279 #ifdef VBOX_STRICT
280 # define DBGFSTOP(pVM)  DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
281 #else
282 # define DBGFSTOP(pVM)  VINF_SUCCESS
283 #endif
284
285 VMMR3DECL(int)  DBGFR3Init(PVM pVM);
286 VMMR3DECL(int)  DBGFR3Term(PVM pVM);
287 VMMR3DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta);
288 VMMR3DECL(int)  DBGFR3VMMForcedAction(PVM pVM);
289 VMMR3DECL(int)  DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent);
290 VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, ...);
291 VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, va_list args);
292 VMMR3DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2);
293 VMMR3DECL(int)  DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent);
294 VMMR3DECL(int)  DBGFR3Attach(PVM pVM);
295 VMMR3DECL(int)  DBGFR3Detach(PVM pVM);
296 VMMR3DECL(int) DBGFR3EventWait(PVM pVM, unsigned cMillies, PCDBGFEVENT *ppEvent);
297 VMMR3DECL(int)  DBGFR3Halt(PVM pVM);
298 VMMR3DECL(bool) DBGFR3IsHalted(PVM pVM);
299 VMMR3DECL(bool) DBGFR3CanWait(PVM pVM);
300 VMMR3DECL(int)  DBGFR3Resume(PVM pVM);
301 VMMR3DECL(int)  DBGFR3Step(PVM pVM);
302 VMMR3DECL(int)  DBGFR3PrgStep(PVM pVM);
303
304
305 /** Breakpoint type. */
306 typedef enum DBGFBPTYPE
307 {
308     /** Free breakpoint entry. */
309     DBGFBPTYPE_FREE = 0,
310     /** Debug register. */
311     DBGFBPTYPE_REG,
312     /** INT 3 instruction. */
313     DBGFBPTYPE_INT3,
314     /** Recompiler. */
315     DBGFBPTYPE_REM,
316     /** ensure 32-bit size. */
317     DBGFBPTYPE_32BIT_HACK = 0x7fffffff
318 } DBGFBPTYPE;
319
320
321 /**
322  * A Breakpoint.
323  */
324 typedef struct DBGFBP
325 {
326     /** The number of breakpoint hits. */
327     uint64_t        cHits;
328     /** The hit number which starts to trigger the breakpoint. */
329     uint64_t        iHitTrigger;
330     /** The hit number which stops triggering the breakpoint (disables it).
331      * Use ~(uint64_t)0 if it should never stop. */
332     uint64_t        iHitDisable;
333     /** The Flat GC address of the breakpoint.
334      * (PC register value if REM type?) */
335     RTGCUINTPTR     GCPtr;
336     /** The breakpoint id. */
337     RTUINT          iBp;
338     /** The breakpoint status - enabled or disabled. */
339     bool            fEnabled;
340
341     /** The breakpoint type. */
342     DBGFBPTYPE      enmType;
343
344 #if GC_ARCH_BITS == 64
345     uint32_t        u32Padding;
346 #endif
347
348     /** Union of type specific data. */
349     union
350     {
351         /** Debug register data. */
352         struct DBGFBPREG
353         {
354             /** The debug register number. */
355             uint8_t     iReg;
356             /** The access type (one of the X86_DR7_RW_* value). */
357             uint8_t     fType;
358             /** The access size. */
359             uint8_t     cb;
360         } Reg;
361         /** Recompiler breakpoint data. */
362         struct DBGFBPINT3
363         {
364             /** The byte value we replaced by the INT 3 instruction. */
365             uint8_t     bOrg;
366         } Int3;
367
368         /** Recompiler breakpoint data. */
369         struct DBGFBPREM
370         {
371             /** nothing yet */
372             uint8_t fDummy;
373         } Rem;
374         /** Paddind to ensure that the size is identical on win32 and linux. */
375         uint64_t    u64Padding;
376     } u;
377 } DBGFBP;
378
379 /** Pointer to a breakpoint. */
380 typedef DBGFBP *PDBGFBP;
381 /** Pointer to a const breakpoint. */
382 typedef const DBGFBP *PCDBGFBP;
383
384
385 VMMR3DECL(int)  DBGFR3BpSet(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp);
386 VMMR3DECL(int)  DBGFR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
387                                    uint8_t fType, uint8_t cb, PRTUINT piBp);
388 VMMR3DECL(int)  DBGFR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, PRTUINT piBp);
389 VMMR3DECL(int)  DBGFR3BpClear(PVM pVM, RTUINT iBp);
390 VMMR3DECL(int)  DBGFR3BpEnable(PVM pVM, RTUINT iBp);
391 VMMR3DECL(int)  DBGFR3BpDisable(PVM pVM, RTUINT iBp);
392
393 /**
394  * Breakpoint enumeration callback function.
395  *
396  * @returns VBox status code. Any failure will stop the enumeration.
397  * @param   pVM         The VM handle.
398  * @param   pvUser      The user argument.
399  * @param   pBp         Pointer to the breakpoint information. (readonly)
400  */
401 typedef DECLCALLBACK(int) FNDBGFBPENUM(PVM pVM, void *pvUser, PCDBGFBP pBp);
402 /** Pointer to a breakpoint enumeration callback function. */
403 typedef FNDBGFBPENUM *PFNDBGFBPENUM;
404
405 VMMR3DECL(int) DBGFR3BpEnum(PVM pVM, PFNDBGFBPENUM pfnCallback, void *pvUser);
406 VMMDECL(RTGCUINTREG)    DBGFBpGetDR7(PVM pVM);
407 VMMDECL(RTGCUINTREG)    DBGFBpGetDR0(PVM pVM);
408 VMMDECL(RTGCUINTREG)    DBGFBpGetDR1(PVM pVM);
409 VMMDECL(RTGCUINTREG)    DBGFBpGetDR2(PVM pVM);
410 VMMDECL(RTGCUINTREG)    DBGFBpGetDR3(PVM pVM);
411 VMMDECL(bool)           DBGFIsStepping(PVM pVM);
412
413
414
415
416 /** Pointer to a info helper callback structure. */
417 typedef struct DBGFINFOHLP *PDBGFINFOHLP;
418 /** Pointer to a const info helper callback structure. */
419 typedef const struct DBGFINFOHLP *PCDBGFINFOHLP;
420
421 /**
422  * Info helper callback structure.
423  */
424 typedef struct DBGFINFOHLP
425 {
426     /**
427      * Print formatted string.
428      *
429      * @param   pHlp        Pointer to this structure.
430      * @param   pszFormat   The format string.
431      * @param   ...         Arguments.
432      */
433     DECLCALLBACKMEMBER(void, pfnPrintf)(PCDBGFINFOHLP pHlp, const char *pszFormat, ...);
434
435     /**
436      * Print formatted string.
437      *
438      * @param   pHlp        Pointer to this structure.
439      * @param   pszFormat   The format string.
440      * @param   args        Argument list.
441      */
442     DECLCALLBACKMEMBER(void, pfnPrintfV)(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args);
443 } DBGFINFOHLP;
444
445
446 /**
447  * Info handler, device version.
448  *
449  * @param   pDevIns     Device instance which registered the info.
450  * @param   pHlp        Callback functions for doing output.
451  * @param   pszArgs     Argument string. Optional and specific to the handler.
452  */
453 typedef DECLCALLBACK(void) FNDBGFHANDLERDEV(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
454 /** Pointer to a FNDBGFHANDLERDEV function. */
455 typedef FNDBGFHANDLERDEV  *PFNDBGFHANDLERDEV;
456
457 /**
458  * Info handler, driver version.
459  *
460  * @param   pDrvIns     Driver instance which registered the info.
461  * @param   pHlp        Callback functions for doing output.
462  * @param   pszArgs     Argument string. Optional and specific to the handler.
463  */
464 typedef DECLCALLBACK(void) FNDBGFHANDLERDRV(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
465 /** Pointer to a FNDBGFHANDLERDRV function. */
466 typedef FNDBGFHANDLERDRV  *PFNDBGFHANDLERDRV;
467
468 /**
469  * Info handler, internal version.
470  *
471  * @param   pVM         The VM handle.
472  * @param   pHlp        Callback functions for doing output.
473  * @param   pszArgs     Argument string. Optional and specific to the handler.
474  */
475 typedef DECLCALLBACK(void) FNDBGFHANDLERINT(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
476 /** Pointer to a FNDBGFHANDLERINT function. */
477 typedef FNDBGFHANDLERINT  *PFNDBGFHANDLERINT;
478
479 /**
480  * Info handler, external version.
481  *
482  * @param   pvUser      User argument.
483  * @param   pHlp        Callback functions for doing output.
484  * @param   pszArgs     Argument string. Optional and specific to the handler.
485  */
486 typedef DECLCALLBACK(void) FNDBGFHANDLEREXT(void *pvUser, PCDBGFINFOHLP pHlp, const char *pszArgs);
487 /** Pointer to a FNDBGFHANDLEREXT function. */
488 typedef FNDBGFHANDLEREXT  *PFNDBGFHANDLEREXT;
489
490
491 /** @name Flags for the info registration functions.
492  * @{ */
493 /** The handler must run on the EMT. */
494 #define DBGFINFO_FLAGS_RUN_ON_EMT       RT_BIT(0)
495 /** @} */
496
497 VMMR3DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
498 VMMR3DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
499 VMMR3DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
500 VMMR3DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
501 VMMR3DECL(int) DBGFR3InfoRegisterExternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
502 VMMR3DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName);
503 VMMR3DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName);
504 VMMR3DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName);
505 VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PVM pVM, const char *pszName);
506 VMMR3DECL(int) DBGFR3Info(PVM pVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
507
508 /** @def DBGFR3InfoLog
509  * Display a piece of info writing to the log if enabled.
510  *
511  * @param   pVM         VM handle.
512  * @param   pszName     The identifier of the info to display.
513  * @param   pszArgs     Arguments to the info handler.
514  */
515 #ifdef LOG_ENABLED
516 #define DBGFR3InfoLog(pVM, pszName, pszArgs) \
517     do { \
518         if (LogIsEnabled()) \
519             DBGFR3Info(pVM, pszName, pszArgs, NULL); \
520     } while (0)
521 #else
522 #define DBGFR3InfoLog(pVM, pszName, pszArgs) do { } while (0)
523 #endif
524
525 /**
526  * Enumeration callback for use with DBGFR3InfoEnum.
527  *
528  * @returns VBox status code.
529  *          A status code indicating failure will end the enumeration
530  *          and DBGFR3InfoEnum will return with that status code.
531  * @param   pVM         VM handle.
532  * @param   pszName     Info identifier name.
533  * @param   pszDesc     The description.
534  */
535 typedef DECLCALLBACK(int) FNDBGFINFOENUM(PVM pVM, const char *pszName, const char *pszDesc, void *pvUser);
536 /** Pointer to a FNDBGFINFOENUM function. */
537 typedef FNDBGFINFOENUM *PFNDBGFINFOENUM;
538
539 VMMR3DECL(int) DBGFR3InfoEnum(PVM pVM, PFNDBGFINFOENUM pfnCallback, void *pvUser);
540 VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void);
541 VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void);
542
543
544
545 VMMR3DECL(int) DBGFR3LogModifyGroups(PVM pVM, const char *pszGroupSettings);
546 VMMR3DECL(int) DBGFR3LogModifyFlags(PVM pVM, const char *pszFlagSettings);
547 VMMR3DECL(int) DBGFR3LogModifyDestinations(PVM pVM, const char *pszDestSettings);
548
549
550
551 /** Max length (including '\\0') of a symbol name. */
552 #define DBGF_SYMBOL_NAME_LENGTH   512
553
554 /**
555  * Debug symbol.
556  */
557 typedef struct DBGFSYMBOL
558 {
559     /** Symbol value (address). */
560     RTGCUINTPTR         Value;
561     /** Symbol size. */
562     uint32_t            cb;
563     /** Symbol Flags. (reserved). */
564     uint32_t            fFlags;
565     /** Symbol name. */
566     char                szName[DBGF_SYMBOL_NAME_LENGTH];
567 } DBGFSYMBOL;
568 /** Pointer to debug symbol. */
569 typedef DBGFSYMBOL *PDBGFSYMBOL;
570 /** Pointer to const debug symbol. */
571 typedef const DBGFSYMBOL *PCDBGFSYMBOL;
572
573 /**
574  * Debug line number information.
575  */
576 typedef struct DBGFLINE
577 {
578     /** Address. */
579     RTGCUINTPTR         Address;
580     /** Line number. */
581     uint32_t            uLineNo;
582     /** Filename. */
583     char                szFilename[260];
584 } DBGFLINE;
585 /** Pointer to debug line number. */
586 typedef DBGFLINE *PDBGFLINE;
587 /** Pointer to const debug line number. */
588 typedef const DBGFLINE *PCDBGFLINE;
589
590 VMMR3DECL(int) DBGFR3ModuleLoad(PVM pVM, const char *pszFilename, RTGCUINTPTR AddressDelta, const char *pszName, RTGCUINTPTR ModuleAddress, unsigned cbImage);
591 VMMR3DECL(void)         DBGFR3ModuleRelocate(PVM pVM, RTGCUINTPTR OldImageBase, RTGCUINTPTR NewImageBase, RTGCUINTPTR cbImage,
592                                              const char *pszFilename, const char *pszName);
593 VMMR3DECL(int) DBGFR3SymbolAdd(PVM pVM, RTGCUINTPTR ModuleAddress, RTGCUINTPTR SymbolAddress, RTUINT cbSymbol, const char *pszSymbol);
594 VMMR3DECL(int)          DBGFR3SymbolByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFSYMBOL pSymbol);
595 VMMR3DECL(int) DBGFR3SymbolByName(PVM pVM, const char *pszSymbol, PDBGFSYMBOL pSymbol);
596 VMMR3DECL(PDBGFSYMBOL)  DBGFR3SymbolByAddrAlloc(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement);
597 VMMR3DECL(PDBGFSYMBOL) DBGFR3SymbolByNameAlloc(PVM pVM, const char *pszSymbol);
598 VMMR3DECL(void)         DBGFR3SymbolFree(PDBGFSYMBOL pSymbol);
599 VMMR3DECL(int)          DBGFR3LineByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFLINE pLine);
600 VMMR3DECL(PDBGFLINE)    DBGFR3LineByAddrAlloc(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement);
601 VMMR3DECL(void)         DBGFR3LineFree(PDBGFLINE pLine);
602
603
604 /**
605  * Return type.
606  */
607 typedef enum DBGFRETRUNTYPE
608 {
609     /** The usual invalid 0 value. */
610     DBGFRETURNTYPE_INVALID = 0,
611     /** Near 16-bit return. */
612     DBGFRETURNTYPE_NEAR16,
613     /** Near 32-bit return. */
614     DBGFRETURNTYPE_NEAR32,
615     /** Near 64-bit return. */
616     DBGFRETURNTYPE_NEAR64,
617     /** Far 16:16 return. */
618     DBGFRETURNTYPE_FAR16,
619     /** Far 16:32 return. */
620     DBGFRETURNTYPE_FAR32,
621     /** Far 16:64 return. */
622     DBGFRETURNTYPE_FAR64,
623     /** 16-bit iret return (e.g. real or 286 protect mode). */
624     DBGFRETURNTYPE_IRET16,
625     /** 32-bit iret return. */
626     DBGFRETURNTYPE_IRET32,
627     /** 32-bit iret return. */
628     DBGFRETURNTYPE_IRET32_PRIV,
629     /** 32-bit iret return to V86 mode. */
630     DBGFRETURNTYPE_IRET32_V86,
631     /** @todo 64-bit iret return. */
632     DBGFRETURNTYPE_IRET64,
633     /** The usual 32-bit blowup. */
634     DBGFRETURNTYPE_32BIT_HACK = 0x7fffffff
635 } DBGFRETURNTYPE;
636
637 /**
638  * Figures the size of the return state on the stack.
639  *
640  * @returns number of bytes. 0 if invalid parameter.
641  * @param   enmRetType  The type of return.
642  */
643 DECLINLINE(unsigned) DBGFReturnTypeSize(DBGFRETURNTYPE enmRetType)
644 {
645     switch (enmRetType)
646     {
647         case DBGFRETURNTYPE_NEAR16:         return 2;
648         case DBGFRETURNTYPE_NEAR32:         return 4;
649         case DBGFRETURNTYPE_NEAR64:         return 8;
650         case DBGFRETURNTYPE_FAR16:          return 4;
651         case DBGFRETURNTYPE_FAR32:          return 4;
652         case DBGFRETURNTYPE_FAR64:          return 8;
653         case DBGFRETURNTYPE_IRET16:         return 6;
654         case DBGFRETURNTYPE_IRET32:         return 4*3;
655         case DBGFRETURNTYPE_IRET32_PRIV:    return 4*5;
656         case DBGFRETURNTYPE_IRET32_V86:     return 4*9;
657         case DBGFRETURNTYPE_IRET64:
658         default:
659             return 0;
660     }
661 }
662
663
664 /** Pointer to stack frame info. */
665 typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
666 /**
667  * Info about a stack frame.
668  */
669 typedef struct DBGFSTACKFRAME
670 {
671     /** Frame number. */
672     RTUINT          iFrame;
673     /** Frame flags. */
674     RTUINT          fFlags;
675     /** The frame address.
676      * The off member is [e|r]bp and the Sel member is ss. */
677     DBGFADDRESS     AddrFrame;
678     /** The stack address of the frame.
679      * The off member is [e|r]sp and the Sel member is ss. */
680     DBGFADDRESS     AddrStack;
681     /** The program counter (PC) address of the frame.
682      * The off member is [e|r]ip and the Sel member is cs. */
683     DBGFADDRESS     AddrPC;
684     /** Pointer to the symbol nearest the program counter (PC). NULL if not found. */
685     PDBGFSYMBOL     pSymPC;
686     /** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */
687     PDBGFLINE       pLinePC;
688
689     /** The return frame address.
690      * The off member is [e|r]bp and the Sel member is ss. */
691     DBGFADDRESS     AddrReturnFrame;
692     /** The return stack address.
693      * The off member is [e|r]sp and the Sel member is ss. */
694     DBGFADDRESS     AddrReturnStack;
695     /** The way this frame returns to the next one. */
696     DBGFRETURNTYPE  enmReturnType;
697
698     /** The program counter (PC) address which the frame returns to.
699      * The off member is [e|r]ip and the Sel member is cs. */
700     DBGFADDRESS     AddrReturnPC;
701     /** Pointer to the symbol nearest the return PC. NULL if not found. */
702     PDBGFSYMBOL     pSymReturnPC;
703     /** Pointer to the linnumber nearest the return PC. NULL if not found. */
704     PDBGFLINE       pLineReturnPC;
705
706     /** 32-bytes of stack arguments. */
707     union
708     {
709         /** 64-bit view */
710         uint64_t    au64[4];
711         /** 32-bit view */
712         uint32_t    au32[8];
713         /** 16-bit view */
714         uint16_t    au16[16];
715         /** 8-bit view */
716         uint8_t     au8[32];
717     } Args;
718
719     /** Pointer to the next frame.
720      * Might not be used in some cases, so consider it internal. */
721     PDBGFSTACKFRAME pNext;
722     /** Pointer to the first frame.
723      * Might not be used in some cases, so consider it internal. */
724     PDBGFSTACKFRAME pFirst;
725 } DBGFSTACKFRAME;
726
727 /** @name DBGFSTACKFRAME Flags.
728  * @{ */
729 /** Set if the content of the frame is filled in by DBGFR3StackWalk() and can be used
730  * to construct the next frame. */
731 #define DBGFSTACKFRAME_FLAGS_ALL_VALID  RT_BIT(0)
732 /** This is the last stack frame we can read.
733  * This flag is not set if the walk stop because of max dept or recursion. */
734 #define DBGFSTACKFRAME_FLAGS_LAST       RT_BIT(1)
735 /** This is the last record because we detected a loop. */
736 #define DBGFSTACKFRAME_FLAGS_LOOP       RT_BIT(2)
737 /** This is the last record because we reached the maximum depth. */
738 #define DBGFSTACKFRAME_FLAGS_MAX_DEPTH  RT_BIT(3)
739 /** @} */
740
741 VMMR3DECL(int) DBGFR3StackWalkBeginGuest(PVM pVM, PDBGFSTACKFRAME pFrame);
742 VMMR3DECL(int) DBGFR3StackWalkBeginHyper(PVM pVM, PDBGFSTACKFRAME pFrame);
743 VMMR3DECL(int) DBGFR3StackWalkNext(PVM pVM, PDBGFSTACKFRAME pFrame);
744 VMMR3DECL(void) DBGFR3StackWalkEnd(PVM pVM, PDBGFSTACKFRAME pFrame);
745
746
747
748
749 /** Flags to pass to DBGFR3DisasInstrEx().
750  * @{ */
751 /** Disassemble the current guest instruction, with annotations. */
752 #define DBGF_DISAS_FLAGS_CURRENT_GUEST      RT_BIT(0)
753 /** Disassemble the current hypervisor instruction, with annotations. */
754 #define DBGF_DISAS_FLAGS_CURRENT_HYPER      RT_BIT(1)
755 /** No annotations for current context. */
756 #define DBGF_DISAS_FLAGS_NO_ANNOTATION      RT_BIT(2)
757 /** No symbol lookup. */
758 #define DBGF_DISAS_FLAGS_NO_SYMBOLS         RT_BIT(3)
759 /** No instruction bytes. */
760 #define DBGF_DISAS_FLAGS_NO_BYTES           RT_BIT(4)
761 /** No address in the output. */
762 #define DBGF_DISAS_FLAGS_NO_ADDRESS         RT_BIT(5)
763 /** @} */
764
765 /** Special flat selector. */
766 #define DBGF_SEL_FLAT                       1
767
768 VMMR3DECL(int) DBGFR3DisasInstrEx(PVM pVM, RTSEL Sel, RTGCPTR GCPtr, unsigned fFlags, char *pszOutput, uint32_t cchOutput, uint32_t *pcbInstr);
769 VMMR3DECL(int) DBGFR3DisasInstr(PVM pVM, RTSEL Sel, RTGCPTR GCPtr, char *pszOutput, uint32_t cbOutput);
770 VMMR3DECL(int) DBGFR3DisasInstrCurrent(PVM pVM, char *pszOutput, uint32_t cbOutput);
771 VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVM pVM, const char *pszPrefix);
772
773 /** @def DBGFR3DisasInstrCurrentLog
774  * Disassembles the current guest context instruction and writes it to the log.
775  * All registers and data will be displayed. Addresses will be attempted resolved to symbols.
776  */
777 #ifdef LOG_ENABLED
778 # define DBGFR3DisasInstrCurrentLog(pVM, pszPrefix) \
779     do { \
780         if (LogIsEnabled()) \
781             DBGFR3DisasInstrCurrentLogInternal(pVM, pszPrefix); \
782     } while (0)
783 #else
784 # define DBGFR3DisasInstrCurrentLog(pVM, pszPrefix) do { } while (0)
785 #endif
786
787 VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVM pVM, RTSEL Sel, RTGCPTR GCPtr);
788
789 /** @def DBGFR3DisasInstrLog
790  * Disassembles the specified guest context instruction and writes it to the log.
791  * Addresses will be attempted resolved to symbols.
792  */
793 #ifdef LOG_ENABLED
794 # define DBGFR3DisasInstrLog(pVM, Sel, GCPtr) \
795     do { \
796         if (LogIsEnabled()) \
797             DBGFR3DisasInstrLogInternal(pVM, Sel, GCPtr); \
798     } while (0)
799 #else
800 # define DBGFR3DisasInstrLog(pVM, Sel, GCPtr) do { } while (0)
801 #endif
802
803
804 VMMR3DECL(int) DBGFR3MemScan(PVM pVM, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress);
805 VMMR3DECL(int) DBGFR3MemRead(PVM pVM, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
806 VMMR3DECL(int) DBGFR3MemReadString(PVM pVM, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
807
808
809 /**
810  * Guest OS digger interface identifier.
811  *
812  * This is for use together with PDBGFR3QueryInterface and is used to
813  * obtain access to optional interfaces.
814  */
815 typedef enum DBGFOSINTERFACE
816 {
817     /** The usual invalid entry. */
818     DBGFOSINTERFACE_INVALID = 0,
819     /** Process info. */
820     DBGFOSINTERFACE_PROCESS,
821     /** Thread info. */
822     DBGFOSINTERFACE_THREAD,
823     /** The end of the valid entries. */
824     DBGFOSINTERFACE_END,
825     /** The usual 32-bit type blowup. */
826     DBGFOSINTERFACE_32BIT_HACK = 0x7fffffff
827 } DBGFOSINTERFACE;
828 /** Pointer to a Guest OS digger interface identifier. */
829 typedef DBGFOSINTERFACE *PDBGFOSINTERFACE;
830 /** Pointer to a const Guest OS digger interface identifier. */
831 typedef DBGFOSINTERFACE const *PCDBGFOSINTERFACE;
832
833
834 /**
835  * Guest OS Digger Registration Record.
836  *
837  * This is used with the DBGFR3OSRegister() API.
838  */
839 typedef struct DBGFOSREG
840 {
841     /** Magic value (DBGFOSREG_MAGIC). */
842     uint32_t u32Magic;
843     /** Flags. Reserved. */
844     uint32_t fFlags;
845     /** The size of the instance data. */
846     uint32_t cbData;
847     /** Operative System name. */
848     char szName[24];
849
850     /**
851      * Constructs th