VirtualBox

source: vbox/trunk/include/VBox/vmm/dbgf.h@ 46159

Last change on this file since 46159 was 46159, checked in by vboxsync, 12 years ago

Patch manager support in the disassembler, making the 'u' command in the debugger always show unpatched instruction and annoate those instructions which have patches associated with them (in any state).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 62.4 KB
Line 
1/** @file
2 * DBGF - Debugger Facility.
3 */
4
5/*
6 * Copyright (C) 2006-2013 Oracle Corporation
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
26#ifndef ___VBox_vmm_dbgf_h
27#define ___VBox_vmm_dbgf_h
28
29#include <VBox/types.h>
30#include <VBox/log.h> /* LOG_ENABLED */
31#include <VBox/vmm/vmm.h>
32#include <VBox/vmm/dbgfsel.h>
33
34#include <iprt/stdarg.h>
35#include <iprt/dbg.h>
36
37RT_C_DECLS_BEGIN
38
39
40/** @defgroup grp_dbgf The Debugger Facility API
41 * @{
42 */
43
44#if defined(IN_RC) || defined(IN_RING0)
45/** @addgroup grp_dbgf_rz The RZ DBGF API
46 * @ingroup grp_dbgf
47 * @{
48 */
49VMMRZ_INT_DECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6);
50VMMRZ_INT_DECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
51/** @} */
52#endif
53
54
55
56#ifdef IN_RING3
57
58/**
59 * Mixed address.
60 */
61typedef struct DBGFADDRESS
62{
63 /** The flat address. */
64 RTGCUINTPTR FlatPtr;
65 /** The selector offset address. */
66 RTGCUINTPTR off;
67 /** The selector. DBGF_SEL_FLAT is a legal value. */
68 RTSEL Sel;
69 /** Flags describing further details about the address. */
70 uint16_t fFlags;
71} DBGFADDRESS;
72/** Pointer to a mixed address. */
73typedef DBGFADDRESS *PDBGFADDRESS;
74/** Pointer to a const mixed address. */
75typedef const DBGFADDRESS *PCDBGFADDRESS;
76
77/** @name DBGFADDRESS Flags.
78 * @{ */
79/** A 16:16 far address. */
80#define DBGFADDRESS_FLAGS_FAR16 0
81/** A 16:32 far address. */
82#define DBGFADDRESS_FLAGS_FAR32 1
83/** A 16:64 far address. */
84#define DBGFADDRESS_FLAGS_FAR64 2
85/** A flat address. */
86#define DBGFADDRESS_FLAGS_FLAT 3
87/** A physical address. */
88#define DBGFADDRESS_FLAGS_PHYS 4
89/** A physical address. */
90#define DBGFADDRESS_FLAGS_RING0 5
91/** The address type mask. */
92#define DBGFADDRESS_FLAGS_TYPE_MASK 7
93
94/** Set if the address is valid. */
95#define DBGFADDRESS_FLAGS_VALID RT_BIT(3)
96
97/** The address is within the hypervisor memoary area (HMA).
98 * If not set, the address can be assumed to be a guest address. */
99#define DBGFADDRESS_FLAGS_HMA RT_BIT(4)
100
101/** Checks if the mixed address is flat or not. */
102#define DBGFADDRESS_IS_FLAT(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FLAT )
103/** Checks if the mixed address is flat or not. */
104#define DBGFADDRESS_IS_PHYS(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_PHYS )
105/** Checks if the mixed address is far 16:16 or not. */
106#define DBGFADDRESS_IS_FAR16(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR16 )
107/** Checks if the mixed address is far 16:32 or not. */
108#define DBGFADDRESS_IS_FAR32(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR32 )
109/** Checks if the mixed address is far 16:64 or not. */
110#define DBGFADDRESS_IS_FAR64(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR64 )
111/** Checks if the mixed address is valid. */
112#define DBGFADDRESS_IS_VALID(pAddress) ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_VALID) )
113/** Checks if the address is flagged as within the HMA. */
114#define DBGFADDRESS_IS_HMA(pAddress) ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_HMA) )
115/** @} */
116
117VMMR3DECL(int) DBGFR3AddrFromSelOff(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off);
118VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PUVM pUVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off);
119VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PUVM pUVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr);
120VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PUVM pUVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
121VMMR3DECL(bool) DBGFR3AddrIsValid(PUVM pUVM, PCDBGFADDRESS pAddress);
122VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
123VMMR3DECL(int) DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys);
124VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr);
125VMMR3DECL(PDBGFADDRESS) DBGFR3AddrAdd(PDBGFADDRESS pAddress, RTGCUINTPTR uAddend);
126VMMR3DECL(PDBGFADDRESS) DBGFR3AddrSub(PDBGFADDRESS pAddress, RTGCUINTPTR uSubtrahend);
127
128#endif /* IN_RING3 */
129
130
131
132/**
133 * VMM Debug Event Type.
134 */
135typedef enum DBGFEVENTTYPE
136{
137 /** Halt completed.
138 * This notifies that a halt command have been successfully completed.
139 */
140 DBGFEVENT_HALT_DONE = 0,
141 /** Detach completed.
142 * This notifies that the detach command have been successfully completed.
143 */
144 DBGFEVENT_DETACH_DONE,
145 /** The command from the debugger is not recognized.
146 * This means internal error or half implemented features.
147 */
148 DBGFEVENT_INVALID_COMMAND,
149
150
151 /** Fatal error.
152 * This notifies a fatal error in the VMM and that the debugger get's a
153 * chance to first hand information about the the problem.
154 */
155 DBGFEVENT_FATAL_ERROR = 100,
156 /** Breakpoint Hit.
157 * This notifies that a breakpoint installed by the debugger was hit. The
158 * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
159 */
160 DBGFEVENT_BREAKPOINT,
161 /** Breakpoint Hit in the Hypervisor.
162 * This notifies that a breakpoint installed by the debugger was hit. The
163 * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
164 */
165 DBGFEVENT_BREAKPOINT_HYPER,
166 /** Assertion in the Hypervisor (breakpoint instruction).
167 * This notifies that a breakpoint instruction was hit in the hypervisor context.
168 */
169 DBGFEVENT_ASSERTION_HYPER,
170 /** Single Stepped.
171 * This notifies that a single step operation was completed.
172 */
173 DBGFEVENT_STEPPED,
174 /** Single Stepped.
175 * This notifies that a hypervisor single step operation was completed.
176 */
177 DBGFEVENT_STEPPED_HYPER,
178 /** The developer have used the DBGFSTOP macro or the PDMDeviceDBGFSTOP function
179 * to bring up the debugger at a specific place.
180 */
181 DBGFEVENT_DEV_STOP,
182 /** The VM is powering off.
183 * When this notification is received, the debugger thread should detach ASAP.
184 */
185 DBGFEVENT_POWERING_OFF,
186
187 /** The usual 32-bit hack. */
188 DBGFEVENT_32BIT_HACK = 0x7fffffff
189} DBGFEVENTTYPE;
190
191
192/**
193 * The context of an event.
194 */
195typedef enum DBGFEVENTCTX
196{
197 /** The usual invalid entry. */
198 DBGFEVENTCTX_INVALID = 0,
199 /** Raw mode. */
200 DBGFEVENTCTX_RAW,
201 /** Recompiled mode. */
202 DBGFEVENTCTX_REM,
203 /** VMX / AVT mode. */
204 DBGFEVENTCTX_HM,
205 /** Hypervisor context. */
206 DBGFEVENTCTX_HYPER,
207 /** Other mode */
208 DBGFEVENTCTX_OTHER,
209
210 /** The usual 32-bit hack */
211 DBGFEVENTCTX_32BIT_HACK = 0x7fffffff
212} DBGFEVENTCTX;
213
214/**
215 * VMM Debug Event.
216 */
217typedef struct DBGFEVENT
218{
219 /** Type. */
220 DBGFEVENTTYPE enmType;
221 /** Context */
222 DBGFEVENTCTX enmCtx;
223 /** Type specific data. */
224 union
225 {
226 /** Fatal error details. */
227 struct
228 {
229 /** The GC return code. */
230 int rc;
231 } FatalError;
232
233 /** Source location. */
234 struct
235 {
236 /** File name. */
237 R3PTRTYPE(const char *) pszFile;
238 /** Function name. */
239 R3PTRTYPE(const char *) pszFunction;
240 /** Message. */
241 R3PTRTYPE(const char *) pszMessage;
242 /** Line number. */
243 unsigned uLine;
244 } Src;
245
246 /** Assertion messages. */
247 struct
248 {
249 /** The first message. */
250 R3PTRTYPE(const char *) pszMsg1;
251 /** The second message. */
252 R3PTRTYPE(const char *) pszMsg2;
253 } Assert;
254
255 /** Breakpoint. */
256 struct DBGFEVENTBP
257 {
258 /** The identifier of the breakpoint which was hit. */
259 RTUINT iBp;
260 } Bp;
261 /** Padding for ensuring that the structure is 8 byte aligned. */
262 uint64_t au64Padding[4];
263 } u;
264} DBGFEVENT;
265/** Pointer to VMM Debug Event. */
266typedef DBGFEVENT *PDBGFEVENT;
267/** Pointer to const VMM Debug Event. */
268typedef const DBGFEVENT *PCDBGFEVENT;
269
270#ifdef IN_RING3 /* The event API only works in ring-3. */
271
272/** @def DBGFSTOP
273 * Stops the debugger raising a DBGFEVENT_DEVELOPER_STOP event.
274 *
275 * @returns VBox status code which must be propagated up to EM if not VINF_SUCCESS.
276 * @param pVM VM Handle.
277 */
278# ifdef VBOX_STRICT
279# define DBGFSTOP(pVM) DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
280# else
281# define DBGFSTOP(pVM) VINF_SUCCESS
282# endif
283
284VMMR3_INT_DECL(int) DBGFR3Init(PVM pVM);
285VMMR3_INT_DECL(int) DBGFR3Term(PVM pVM);
286VMMR3_INT_DECL(void) DBGFR3PowerOff(PVM pVM);
287VMMR3_INT_DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta);
288VMMR3_INT_DECL(int) DBGFR3VMMForcedAction(PVM pVM);
289VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent);
290VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
291 const char *pszFunction, const char *pszFormat, ...);
292VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
293 const char *pszFunction, const char *pszFormat, va_list args);
294VMMR3_INT_DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2);
295VMMR3_INT_DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent);
296VMMR3_INT_DECL(int) DBGFR3PrgStep(PVMCPU pVCpu);
297
298VMMR3DECL(int) DBGFR3Attach(PUVM pUVM);
299VMMR3DECL(int) DBGFR3Detach(PUVM pUVM);
300VMMR3DECL(int) DBGFR3EventWait(PUVM pUVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent);
301VMMR3DECL(int) DBGFR3Halt(PUVM pUVM);
302VMMR3DECL(bool) DBGFR3IsHalted(PUVM pUVM);
303VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM);
304VMMR3DECL(int) DBGFR3Resume(PUVM pUVM);
305VMMR3DECL(int) DBGFR3Step(PUVM pUVM, VMCPUID idCpu);
306VMMR3DECL(int) DBGFR3InjectNMI(PUVM pUVM, VMCPUID idCpu);
307
308#endif /* IN_RING3 */
309
310
311
312/** Breakpoint type. */
313typedef enum DBGFBPTYPE
314{
315 /** Free breakpoint entry. */
316 DBGFBPTYPE_FREE = 0,
317 /** Debug register. */
318 DBGFBPTYPE_REG,
319 /** INT 3 instruction. */
320 DBGFBPTYPE_INT3,
321 /** Recompiler. */
322 DBGFBPTYPE_REM,
323 /** ensure 32-bit size. */
324 DBGFBPTYPE_32BIT_HACK = 0x7fffffff
325} DBGFBPTYPE;
326
327
328/**
329 * A Breakpoint.
330 */
331typedef struct DBGFBP
332{
333 /** The number of breakpoint hits. */
334 uint64_t cHits;
335 /** The hit number which starts to trigger the breakpoint. */
336 uint64_t iHitTrigger;
337 /** The hit number which stops triggering the breakpoint (disables it).
338 * Use ~(uint64_t)0 if it should never stop. */
339 uint64_t iHitDisable;
340 /** The Flat GC address of the breakpoint.
341 * (PC register value if REM type?) */
342 RTGCUINTPTR GCPtr;
343 /** The breakpoint id. */
344 uint32_t iBp;
345 /** The breakpoint status - enabled or disabled. */
346 bool fEnabled;
347
348 /** The breakpoint type. */
349 DBGFBPTYPE enmType;
350
351#if GC_ARCH_BITS == 64
352 uint32_t u32Padding;
353#endif
354
355 /** Union of type specific data. */
356 union
357 {
358 /** Debug register data. */
359 struct DBGFBPREG
360 {
361 /** The debug register number. */
362 uint8_t iReg;
363 /** The access type (one of the X86_DR7_RW_* value). */
364 uint8_t fType;
365 /** The access size. */
366 uint8_t cb;
367 } Reg;
368 /** Recompiler breakpoint data. */
369 struct DBGFBPINT3
370 {
371 /** The byte value we replaced by the INT 3 instruction. */
372 uint8_t bOrg;
373 } Int3;
374
375 /** Recompiler breakpoint data. */
376 struct DBGFBPREM
377 {
378 /** nothing yet */
379 uint8_t fDummy;
380 } Rem;
381 /** Paddind to ensure that the size is identical on win32 and linux. */
382 uint64_t u64Padding;
383 } u;
384} DBGFBP;
385
386/** Pointer to a breakpoint. */
387typedef DBGFBP *PDBGFBP;
388/** Pointer to a const breakpoint. */
389typedef const DBGFBP *PCDBGFBP;
390
391#ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */
392VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
393VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
394 uint8_t fType, uint8_t cb, uint32_t *piBp);
395VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
396VMMR3DECL(int) DBGFR3BpClear(PUVM pUVM, uint32_t iBp);
397VMMR3DECL(int) DBGFR3BpEnable(PUVM pUVM, uint32_t iBp);
398VMMR3DECL(int) DBGFR3BpDisable(PUVM pUVM, uint32_t iBp);
399
400/**
401 * Breakpoint enumeration callback function.
402 *
403 * @returns VBox status code. Any failure will stop the enumeration.
404 * @param pUVM The user mode VM handle.
405 * @param pvUser The user argument.
406 * @param pBp Pointer to the breakpoint information. (readonly)
407 */
408typedef DECLCALLBACK(int) FNDBGFBPENUM(PUVM pUVM, void *pvUser, PCDBGFBP pBp);
409/** Pointer to a breakpoint enumeration callback function. */
410typedef FNDBGFBPENUM *PFNDBGFBPENUM;
411
412VMMR3DECL(int) DBGFR3BpEnum(PUVM pUVM, PFNDBGFBPENUM pfnCallback, void *pvUser);
413#endif /* IN_RING3 */
414
415VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM);
416VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM);
417VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM);
418VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM);
419VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM);
420VMM_INT_DECL(bool) DBGFIsStepping(PVMCPU pVCpu);
421
422
423#ifdef IN_RING3 /* The CPU mode API only works in ring-3. */
424VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu);
425VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM);
426#endif
427
428
429
430#ifdef IN_RING3 /* The info callbacks API only works in ring-3. */
431
432/**
433 * Info helper callback structure.
434 */
435typedef struct DBGFINFOHLP
436{
437 /**
438 * Print formatted string.
439 *
440 * @param pHlp Pointer to this structure.
441 * @param pszFormat The format string.
442 * @param ... Arguments.
443 */
444 DECLCALLBACKMEMBER(void, pfnPrintf)(PCDBGFINFOHLP pHlp, const char *pszFormat, ...);
445
446 /**
447 * Print formatted string.
448 *
449 * @param pHlp Pointer to this structure.
450 * @param pszFormat The format string.
451 * @param args Argument list.
452 */
453 DECLCALLBACKMEMBER(void, pfnPrintfV)(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args);
454} DBGFINFOHLP;
455
456
457/**
458 * Info handler, device version.
459 *
460 * @param pDevIns The device 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 */
464typedef DECLCALLBACK(void) FNDBGFHANDLERDEV(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
465/** Pointer to a FNDBGFHANDLERDEV function. */
466typedef FNDBGFHANDLERDEV *PFNDBGFHANDLERDEV;
467
468/**
469 * Info handler, USB device version.
470 *
471 * @param pUsbIns The USB device instance which registered the info.
472 * @param pHlp Callback functions for doing output.
473 * @param pszArgs Argument string. Optional and specific to the handler.
474 */
475typedef DECLCALLBACK(void) FNDBGFHANDLERUSB(PPDMUSBINS pUsbIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
476/** Pointer to a FNDBGFHANDLERUSB function. */
477typedef FNDBGFHANDLERUSB *PFNDBGFHANDLERUSB;
478
479/**
480 * Info handler, driver version.
481 *
482 * @param pDrvIns The driver instance which registered the info.
483 * @param pHlp Callback functions for doing output.
484 * @param pszArgs Argument string. Optional and specific to the handler.
485 */
486typedef DECLCALLBACK(void) FNDBGFHANDLERDRV(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
487/** Pointer to a FNDBGFHANDLERDRV function. */
488typedef FNDBGFHANDLERDRV *PFNDBGFHANDLERDRV;
489
490/**
491 * Info handler, internal version.
492 *
493 * @param pVM The VM handle.
494 * @param pHlp Callback functions for doing output.
495 * @param pszArgs Argument string. Optional and specific to the handler.
496 */
497typedef DECLCALLBACK(void) FNDBGFHANDLERINT(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
498/** Pointer to a FNDBGFHANDLERINT function. */
499typedef FNDBGFHANDLERINT *PFNDBGFHANDLERINT;
500
501/**
502 * Info handler, external version.
503 *
504 * @param pvUser User argument.
505 * @param pHlp Callback functions for doing output.
506 * @param pszArgs Argument string. Optional and specific to the handler.
507 */
508typedef DECLCALLBACK(void) FNDBGFHANDLEREXT(void *pvUser, PCDBGFINFOHLP pHlp, const char *pszArgs);
509/** Pointer to a FNDBGFHANDLEREXT function. */
510typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT;
511
512
513/** @name Flags for the info registration functions.
514 * @{ */
515/** The handler must run on the EMT. */
516#define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0)
517/** @} */
518
519VMMR3_INT_DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
520VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
521VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
522VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
523VMMR3DECL(int) DBGFR3InfoRegisterExternal(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
524VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName);
525VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName);
526VMMR3_INT_DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName);
527VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PUVM pUVM, const char *pszName);
528VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
529VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
530VMMR3DECL(int) DBGFR3InfoLogRel(PUVM pUVM, const char *pszName, const char *pszArgs);
531VMMR3DECL(int) DBGFR3InfoStdErr(PUVM pUVM, const char *pszName, const char *pszArgs);
532VMMR3_INT_DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat,
533 const char *pszSepFmt, PCDBGFINFOHLP pHlp);
534
535/** @def DBGFR3InfoLog
536 * Display a piece of info writing to the log if enabled.
537 *
538 * @param a_pVM The shared VM handle.
539 * @param a_pszName The identifier of the info to display.
540 * @param a_pszArgs Arguments to the info handler.
541 */
542#ifdef LOG_ENABLED
543# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) \
544 do { \
545 if (LogIsEnabled()) \
546 DBGFR3Info((a_pVM)->pUVM, a_pszName, a_pszArgs, NULL); \
547 } while (0)
548#else
549# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) do { } while (0)
550#endif
551
552/**
553 * Enumeration callback for use with DBGFR3InfoEnum.
554 *
555 * @returns VBox status code.
556 * A status code indicating failure will end the enumeration
557 * and DBGFR3InfoEnum will return with that status code.
558 * @param pUVM The user mode VM handle.
559 * @param pszName Info identifier name.
560 * @param pszDesc The description.
561 */
562typedef DECLCALLBACK(int) FNDBGFINFOENUM(PUVM pUVM, const char *pszName, const char *pszDesc, void *pvUser);
563/** Pointer to a FNDBGFINFOENUM function. */
564typedef FNDBGFINFOENUM *PFNDBGFINFOENUM;
565
566VMMR3DECL(int) DBGFR3InfoEnum(PUVM pUVM, PFNDBGFINFOENUM pfnCallback, void *pvUser);
567VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void);
568VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void);
569
570#endif /* IN_RING3 */
571
572
573#ifdef IN_RING3 /* The log contrl API only works in ring-3. */
574VMMR3DECL(int) DBGFR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings);
575VMMR3DECL(int) DBGFR3LogModifyFlags(PUVM pUVM, const char *pszFlagSettings);
576VMMR3DECL(int) DBGFR3LogModifyDestinations(PUVM pUVM, const char *pszDestSettings);
577#endif /* IN_RING3 */
578
579#ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */
580
581/** Max length (including '\\0') of a symbol name. */
582#define DBGF_SYMBOL_NAME_LENGTH 512
583
584/**
585 * Debug symbol.
586 */
587typedef struct DBGFSYMBOL
588{
589 /** Symbol value (address). */
590 RTGCUINTPTR Value;
591 /** Symbol size. */
592 uint32_t cb;
593 /** Symbol Flags. (reserved). */
594 uint32_t fFlags;
595 /** Symbol name. */
596 char szName[DBGF_SYMBOL_NAME_LENGTH];
597} DBGFSYMBOL;
598/** Pointer to debug symbol. */
599typedef DBGFSYMBOL *PDBGFSYMBOL;
600/** Pointer to const debug symbol. */
601typedef const DBGFSYMBOL *PCDBGFSYMBOL;
602
603/**
604 * Debug line number information.
605 */
606typedef struct DBGFLINE
607{
608 /** Address. */
609 RTGCUINTPTR Address;
610 /** Line number. */
611 uint32_t uLineNo;
612 /** Filename. */
613 char szFilename[260];
614} DBGFLINE;
615/** Pointer to debug line number. */
616typedef DBGFLINE *PDBGFLINE;
617/** Pointer to const debug line number. */
618typedef const DBGFLINE *PCDBGFLINE;
619
620/** @name Address spaces aliases.
621 * @{ */
622/** The guest global address space. */
623#define DBGF_AS_GLOBAL ((RTDBGAS)-1)
624/** The guest kernel address space.
625 * This is usually resolves to the same as DBGF_AS_GLOBAL. */
626#define DBGF_AS_KERNEL ((RTDBGAS)-2)
627/** The physical address space. */
628#define DBGF_AS_PHYS ((RTDBGAS)-3)
629/** Raw-mode context. */
630#define DBGF_AS_RC ((RTDBGAS)-4)
631/** Ring-0 context. */
632#define DBGF_AS_R0 ((RTDBGAS)-5)
633/** Raw-mode context and then global guest context.
634 * When used for looking up information, it works as if the call was first made
635 * with DBGF_AS_RC and then on failure with DBGF_AS_GLOBAL. When called for
636 * making address space changes, it works as if DBGF_AS_RC was used. */
637#define DBGF_AS_RC_AND_GC_GLOBAL ((RTDBGAS)-6)
638
639/** The first special one. */
640#define DBGF_AS_FIRST DBGF_AS_RC_AND_GC_GLOBAL
641/** The last special one. */
642#define DBGF_AS_LAST DBGF_AS_GLOBAL
643#endif
644/** The number of special address space handles. */
645#define DBGF_AS_COUNT (6U)
646#ifdef IN_RING3
647/** Converts an alias handle to an array index. */
648#define DBGF_AS_ALIAS_2_INDEX(hAlias) \
649 ( (uintptr_t)(hAlias) - (uintptr_t)DBGF_AS_FIRST )
650/** Predicat macro that check if the specified handle is an alias. */
651#define DBGF_AS_IS_ALIAS(hAlias) \
652 ( DBGF_AS_ALIAS_2_INDEX(hAlias) < DBGF_AS_COUNT )
653/** Predicat macro that check if the specified alias is a fixed one or not. */
654#define DBGF_AS_IS_FIXED_ALIAS(hAlias) \
655 ( DBGF_AS_ALIAS_2_INDEX(hAlias) < (uintptr_t)DBGF_AS_PHYS - (uintptr_t)DBGF_AS_FIRST + 1U )
656
657/** @} */
658
659VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM);
660
661VMMR3DECL(int) DBGFR3AsAdd(PUVM pUVM, RTDBGAS hDbgAs, RTPROCESS ProcId);
662VMMR3DECL(int) DBGFR3AsDelete(PUVM pUVM, RTDBGAS hDbgAs);
663VMMR3DECL(int) DBGFR3AsSetAlias(PUVM pUVM, RTDBGAS hAlias, RTDBGAS hAliasFor);
664VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PUVM pUVM, RTDBGAS hAlias);
665VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias);
666VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName);
667VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PUVM pUVM, RTPROCESS ProcId);
668
669VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
670VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags);
671VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
672
673VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
674 PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
675VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t Flags,
676 PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
677VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
678
679/* The following are soon to be obsoleted: */
680VMMR3DECL(int) DBGFR3ModuleLoad(PUVM pUVM, const char *pszFilename, RTGCUINTPTR AddressDelta, const char *pszName, RTGCUINTPTR ModuleAddress, unsigned cbImage);
681VMMR3_INT_DECL(void) DBGFR3ModuleRelocate(PVM pVM, RTGCUINTPTR OldImageBase, RTGCUINTPTR NewImageBase, RTGCUINTPTR cbImage,
682 const char *pszFilename, const char *pszName);
683VMMR3_INT_DECL(int) DBGFR3SymbolAdd(PVM pVM, RTGCUINTPTR ModuleAddress, RTGCUINTPTR SymbolAddress, RTUINT cbSymbol, const char *pszSymbol);
684VMMR3_INT_DECL(int) DBGFR3SymbolByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFSYMBOL pSymbol);
685VMMR3_INT_DECL(int) DBGFR3SymbolByName(PVM pVM, const char *pszSymbol, PDBGFSYMBOL pSymbol);
686
687VMMR3DECL(int) DBGFR3LineByAddr(PUVM pUVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFLINE pLine);
688VMMR3DECL(PDBGFLINE) DBGFR3LineByAddrAlloc(PUVM pUVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement);
689VMMR3_INT_DECL(void) DBGFR3LineFree(PDBGFLINE pLine);
690
691#endif /* IN_RING3 */
692
693#ifdef IN_RING3 /* The stack API only works in ring-3. */
694
695/**
696 * Return type.
697 */
698typedef enum DBGFRETRUNTYPE
699{
700 /** The usual invalid 0 value. */
701 DBGFRETURNTYPE_INVALID = 0,
702 /** Near 16-bit return. */
703 DBGFRETURNTYPE_NEAR16,
704 /** Near 32-bit return. */
705 DBGFRETURNTYPE_NEAR32,
706 /** Near 64-bit return. */
707 DBGFRETURNTYPE_NEAR64,
708 /** Far 16:16 return. */
709 DBGFRETURNTYPE_FAR16,
710 /** Far 16:32 return. */
711 DBGFRETURNTYPE_FAR32,
712 /** Far 16:64 return. */
713 DBGFRETURNTYPE_FAR64,
714 /** 16-bit iret return (e.g. real or 286 protect mode). */
715 DBGFRETURNTYPE_IRET16,
716 /** 32-bit iret return. */
717 DBGFRETURNTYPE_IRET32,
718 /** 32-bit iret return. */
719 DBGFRETURNTYPE_IRET32_PRIV,
720 /** 32-bit iret return to V86 mode. */
721 DBGFRETURNTYPE_IRET32_V86,
722 /** @todo 64-bit iret return. */
723 DBGFRETURNTYPE_IRET64,
724 /** The end of the valid return types. */
725 DBGFRETURNTYPE_END,
726 /** The usual 32-bit blowup. */
727 DBGFRETURNTYPE_32BIT_HACK = 0x7fffffff
728} DBGFRETURNTYPE;
729
730/**
731 * Figures the size of the return state on the stack.
732 *
733 * @returns number of bytes. 0 if invalid parameter.
734 * @param enmRetType The type of return.
735 */
736DECLINLINE(unsigned) DBGFReturnTypeSize(DBGFRETURNTYPE enmRetType)
737{
738 switch (enmRetType)
739 {
740 case DBGFRETURNTYPE_NEAR16: return 2;
741 case DBGFRETURNTYPE_NEAR32: return 4;
742 case DBGFRETURNTYPE_NEAR64: return 8;
743 case DBGFRETURNTYPE_FAR16: return 4;
744 case DBGFRETURNTYPE_FAR32: return 4;
745 case DBGFRETURNTYPE_FAR64: return 8;
746 case DBGFRETURNTYPE_IRET16: return 6;
747 case DBGFRETURNTYPE_IRET32: return 4*3;
748 case DBGFRETURNTYPE_IRET32_PRIV: return 4*5;
749 case DBGFRETURNTYPE_IRET32_V86: return 4*9;
750 case DBGFRETURNTYPE_IRET64:
751 default:
752 return 0;
753 }
754}
755
756
757/** Pointer to stack frame info. */
758typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
759/** Pointer to const stack frame info. */
760typedef struct DBGFSTACKFRAME const *PCDBGFSTACKFRAME;
761/**
762 * Info about a stack frame.
763 */
764typedef struct DBGFSTACKFRAME
765{
766 /** Frame number. */
767 uint32_t iFrame;
768 /** Frame flags. */
769 uint32_t fFlags;
770 /** The frame address.
771 * The off member is [e|r]bp and the Sel member is ss. */
772 DBGFADDRESS AddrFrame;
773 /** The stack address of the frame.
774 * The off member is [e|r]sp and the Sel member is ss. */
775 DBGFADDRESS AddrStack;
776 /** The program counter (PC) address of the frame.
777 * The off member is [e|r]ip and the Sel member is cs. */
778 DBGFADDRESS AddrPC;
779 /** Pointer to the symbol nearest the program counter (PC). NULL if not found. */
780 PRTDBGSYMBOL pSymPC;
781 /** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */
782 PDBGFLINE pLinePC;
783
784 /** The return frame address.
785 * The off member is [e|r]bp and the Sel member is ss. */
786 DBGFADDRESS AddrReturnFrame;
787 /** The return stack address.
788 * The off member is [e|r]sp and the Sel member is ss. */
789 DBGFADDRESS AddrReturnStack;
790 /** The way this frame returns to the next one. */
791 DBGFRETURNTYPE enmReturnType;
792
793 /** The program counter (PC) address which the frame returns to.
794 * The off member is [e|r]ip and the Sel member is cs. */
795 DBGFADDRESS AddrReturnPC;
796 /** Pointer to the symbol nearest the return PC. NULL if not found. */
797 PRTDBGSYMBOL pSymReturnPC;
798 /** Pointer to the linnumber nearest the return PC. NULL if not found. */
799 PDBGFLINE pLineReturnPC;
800
801 /** 32-bytes of stack arguments. */
802 union
803 {
804 /** 64-bit view */
805 uint64_t au64[4];
806 /** 32-bit view */
807 uint32_t au32[8];
808 /** 16-bit view */
809 uint16_t au16[16];
810 /** 8-bit view */
811 uint8_t au8[32];
812 } Args;
813
814 /** Pointer to the next frame.
815 * Might not be used in some cases, so consider it internal. */
816 PCDBGFSTACKFRAME pNextInternal;
817 /** Pointer to the first frame.
818 * Might not be used in some cases, so consider it internal. */
819 PCDBGFSTACKFRAME pFirstInternal;
820} DBGFSTACKFRAME;
821
822/** @name DBGFSTACKFRAME Flags.
823 * @{ */
824/** Set if the content of the frame is filled in by DBGFR3StackWalk() and can be used
825 * to construct the next frame. */
826# define DBGFSTACKFRAME_FLAGS_ALL_VALID RT_BIT(0)
827/** This is the last stack frame we can read.
828 * This flag is not set if the walk stop because of max dept or recursion. */
829# define DBGFSTACKFRAME_FLAGS_LAST RT_BIT(1)
830/** This is the last record because we detected a loop. */
831# define DBGFSTACKFRAME_FLAGS_LOOP RT_BIT(2)
832/** This is the last record because we reached the maximum depth. */
833# define DBGFSTACKFRAME_FLAGS_MAX_DEPTH RT_BIT(3)
834/** 16-bit frame. */
835# define DBGFSTACKFRAME_FLAGS_16BIT RT_BIT(4)
836/** 32-bit frame. */
837# define DBGFSTACKFRAME_FLAGS_32BIT RT_BIT(5)
838/** 64-bit frame. */
839# define DBGFSTACKFRAME_FLAGS_64BIT RT_BIT(6)
840/** @} */
841
842/** @name DBGFCODETYPE
843 * @{ */
844typedef enum DBGFCODETYPE
845{
846 /** The usual invalid 0 value. */
847 DBGFCODETYPE_INVALID = 0,
848 /** Stack walk for guest code. */
849 DBGFCODETYPE_GUEST,
850 /** Stack walk for hypervisor code. */
851 DBGFCODETYPE_HYPER,
852 /** Stack walk for ring 0 code. */
853 DBGFCODETYPE_RING0,
854 /** The usual 32-bit blowup. */
855 DBGFCODETYPE_32BIT_HACK = 0x7fffffff
856} DBGFCODETYPE;
857/** @} */
858
859VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType,
860 PCDBGFSTACKFRAME *ppFirstFrame);
861VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
862 PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC,
863 DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
864VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent);
865VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
866
867#endif /* IN_RING3 */
868
869
870#ifdef IN_RING3 /* The disassembly API only works in ring-3. */
871
872/** Flags to pass to DBGFR3DisasInstrEx().
873 * @{ */
874/** Disassemble the current guest instruction, with annotations. */
875#define DBGF_DISAS_FLAGS_CURRENT_GUEST RT_BIT(0)
876/** Disassemble the current hypervisor instruction, with annotations. */
877#define DBGF_DISAS_FLAGS_CURRENT_HYPER RT_BIT(1)
878/** No annotations for current context. */
879#define DBGF_DISAS_FLAGS_NO_ANNOTATION RT_BIT(2)
880/** No symbol lookup. */
881#define DBGF_DISAS_FLAGS_NO_SYMBOLS RT_BIT(3)
882/** No instruction bytes. */
883#define DBGF_DISAS_FLAGS_NO_BYTES RT_BIT(4)
884/** No address in the output. */
885#define DBGF_DISAS_FLAGS_NO_ADDRESS RT_BIT(5)
886/** Probably a hypervisor instruction. */
887#define DBGF_DISAS_FLAGS_HYPER RT_BIT(6)
888/** Disassemble original unpatched bytes (PATM). */
889#define DBGF_DISAS_FLAGS_UNPATCHED_BYTES RT_BIT(7)
890/** Annotate patched instructions. */
891#define DBGF_DISAS_FLAGS_ANNOTATE_PATCHED RT_BIT(8)
892/** Disassemble in the default mode of the specific context. */
893#define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000)
894/** Disassemble in 16-bit mode. */
895#define DBGF_DISAS_FLAGS_16BIT_MODE UINT32_C(0x10000000)
896/** Disassemble in 16-bit mode with real mode address translation. */
897#define DBGF_DISAS_FLAGS_16BIT_REAL_MODE UINT32_C(0x20000000)
898/** Disassemble in 32-bit mode. */
899#define DBGF_DISAS_FLAGS_32BIT_MODE UINT32_C(0x30000000)
900/** Disassemble in 64-bit mode. */
901#define DBGF_DISAS_FLAGS_64BIT_MODE UINT32_C(0x40000000)
902/** The disassembly mode mask. */
903#define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000)
904/** Mask containing the valid flags. */
905#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x700001ff)
906/** @} */
907
908/** Special flat selector. */
909#define DBGF_SEL_FLAT 1
910
911VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
912 char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr);
913VMMR3_INT_DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput);
914VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix);
915
916/** @def DBGFR3DisasInstrCurrentLog
917 * Disassembles the current guest context instruction and writes it to the log.
918 * All registers and data will be displayed. Addresses will be attempted resolved to symbols.
919 */
920#ifdef LOG_ENABLED
921# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) \
922 do { \
923 if (LogIsEnabled()) \
924 DBGFR3DisasInstrCurrentLogInternal(pVCpu, pszPrefix); \
925 } while (0)
926#else
927# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) do { } while (0)
928#endif
929
930VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix);
931
932/** @def DBGFR3DisasInstrLog
933 * Disassembles the specified guest context instruction and writes it to the log.
934 * Addresses will be attempted resolved to symbols.
935 * @thread Any EMT.
936 */
937# ifdef LOG_ENABLED
938# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) \
939 do { \
940 if (LogIsEnabled()) \
941 DBGFR3DisasInstrLogInternal(pVCpu, Sel, GCPtr, pszPrefix); \
942 } while (0)
943# else
944# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0)
945# endif
946#endif
947
948
949#ifdef IN_RING3
950VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign,
951 const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress);
952VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
953VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
954VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead);
955#endif
956
957
958/** @name Flags for DBGFR3PagingDumpEx, PGMR3DumpHierarchyHCEx and
959 * PGMR3DumpHierarchyGCEx
960 * @{ */
961/** The CR3 from the current CPU state. */
962#define DBGFPGDMP_FLAGS_CURRENT_CR3 RT_BIT_32(0)
963/** The current CPU paging mode (PSE, PAE, LM, EPT, NX). */
964#define DBGFPGDMP_FLAGS_CURRENT_MODE RT_BIT_32(1)
965/** Whether PSE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
966 * Same value as X86_CR4_PSE. */
967#define DBGFPGDMP_FLAGS_PSE RT_BIT_32(4) /* */
968/** Whether PAE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
969 * Same value as X86_CR4_PAE. */
970#define DBGFPGDMP_FLAGS_PAE RT_BIT_32(5) /* */
971/** Whether LME is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
972 * Same value as MSR_K6_EFER_LME. */
973#define DBGFPGDMP_FLAGS_LME RT_BIT_32(8)
974/** Whether nested paging is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
975#define DBGFPGDMP_FLAGS_NP RT_BIT_32(9)
976/** Whether extended nested page tables are enabled
977 * (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
978#define DBGFPGDMP_FLAGS_EPT RT_BIT_32(10)
979/** Whether no-execution is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
980 * Same value as MSR_K6_EFER_NXE. */
981#define DBGFPGDMP_FLAGS_NXE RT_BIT_32(11)
982/** Whether to print the CR3. */
983#define DBGFPGDMP_FLAGS_PRINT_CR3 RT_BIT_32(27)
984/** Whether to print the header. */
985#define DBGFPGDMP_FLAGS_HEADER RT_BIT_32(28)
986/** Whether to dump additional page information. */
987#define DBGFPGDMP_FLAGS_PAGE_INFO RT_BIT_32(29)
988/** Dump the shadow tables if set.
989 * Cannot be used together with DBGFPGDMP_FLAGS_GUEST. */
990#define DBGFPGDMP_FLAGS_SHADOW RT_BIT_32(30)
991/** Dump the guest tables if set.
992 * Cannot be used together with DBGFPGDMP_FLAGS_SHADOW. */
993#define DBGFPGDMP_FLAGS_GUEST RT_BIT_32(31)
994/** Mask of valid bits. */
995#define DBGFPGDMP_FLAGS_VALID_MASK UINT32_C(0xf8000f33)
996/** The mask of bits controlling the paging mode. */
997#define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32)
998/** @} */
999VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
1000 uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
1001
1002
1003/** @name DBGFR3SelQueryInfo flags.
1004 * @{ */
1005/** Get the info from the guest descriptor table. */
1006#define DBGFSELQI_FLAGS_DT_GUEST UINT32_C(0)
1007/** Get the info from the shadow descriptor table.
1008 * Only works in raw-mode. */
1009#define DBGFSELQI_FLAGS_DT_SHADOW UINT32_C(1)
1010/** If currently executing in in 64-bit mode, blow up data selectors. */
1011#define DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE UINT32_C(2)
1012/** @} */
1013VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo);
1014
1015
1016/**
1017 * Register identifiers.
1018 */
1019typedef enum DBGFREG
1020{
1021 /* General purpose registers: */
1022 DBGFREG_AL = 0,
1023 DBGFREG_AX = DBGFREG_AL,
1024 DBGFREG_EAX = DBGFREG_AL,
1025 DBGFREG_RAX = DBGFREG_AL,
1026
1027 DBGFREG_CL,
1028 DBGFREG_CX = DBGFREG_CL,
1029 DBGFREG_ECX = DBGFREG_CL,
1030 DBGFREG_RCX = DBGFREG_CL,
1031
1032 DBGFREG_DL,
1033 DBGFREG_DX = DBGFREG_DL,
1034 DBGFREG_EDX = DBGFREG_DL,
1035 DBGFREG_RDX = DBGFREG_DL,
1036
1037 DBGFREG_BL,
1038 DBGFREG_BX = DBGFREG_BL,
1039 DBGFREG_EBX = DBGFREG_BL,
1040 DBGFREG_RBX = DBGFREG_BL,
1041
1042 DBGFREG_SPL,
1043 DBGFREG_SP = DBGFREG_SPL,
1044 DBGFREG_ESP = DBGFREG_SPL,
1045 DBGFREG_RSP = DBGFREG_SPL,
1046
1047 DBGFREG_BPL,
1048 DBGFREG_BP = DBGFREG_BPL,
1049 DBGFREG_EBP = DBGFREG_BPL,
1050 DBGFREG_RBP = DBGFREG_BPL,
1051
1052 DBGFREG_SIL,
1053 DBGFREG_SI = DBGFREG_SIL,
1054 DBGFREG_ESI = DBGFREG_SIL,
1055 DBGFREG_RSI = DBGFREG_SIL,
1056
1057 DBGFREG_DIL,
1058 DBGFREG_DI = DBGFREG_DIL,
1059 DBGFREG_EDI = DBGFREG_DIL,
1060 DBGFREG_RDI = DBGFREG_DIL,
1061
1062 DBGFREG_R8,
1063 DBGFREG_R8B = DBGFREG_R8,
1064 DBGFREG_R8W = DBGFREG_R8,
1065 DBGFREG_R8D = DBGFREG_R8,
1066
1067 DBGFREG_R9,
1068 DBGFREG_R9B = DBGFREG_R9,
1069 DBGFREG_R9W = DBGFREG_R9,
1070 DBGFREG_R9D = DBGFREG_R9,
1071
1072 DBGFREG_R10,
1073 DBGFREG_R10B = DBGFREG_R10,
1074 DBGFREG_R10W = DBGFREG_R10,
1075 DBGFREG_R10D = DBGFREG_R10,
1076
1077 DBGFREG_R11,
1078 DBGFREG_R11B = DBGFREG_R11,
1079 DBGFREG_R11W = DBGFREG_R11,
1080 DBGFREG_R11D = DBGFREG_R11,
1081
1082 DBGFREG_R12,
1083 DBGFREG_R12B = DBGFREG_R12,
1084 DBGFREG_R12W = DBGFREG_R12,
1085 DBGFREG_R12D = DBGFREG_R12,
1086
1087 DBGFREG_R13,
1088 DBGFREG_R13B = DBGFREG_R13,
1089 DBGFREG_R13W = DBGFREG_R13,
1090 DBGFREG_R13D = DBGFREG_R13,
1091
1092 DBGFREG_R14,
1093 DBGFREG_R14B = DBGFREG_R14,
1094 DBGFREG_R14W = DBGFREG_R14,
1095 DBGFREG_R14D = DBGFREG_R14,
1096
1097 DBGFREG_R15,
1098 DBGFREG_R15B = DBGFREG_R15,
1099 DBGFREG_R15W = DBGFREG_R15,
1100 DBGFREG_R15D = DBGFREG_R15,
1101
1102 /* Segments and other special registers: */
1103 DBGFREG_CS,
1104 DBGFREG_CS_ATTR,
1105 DBGFREG_CS_BASE,
1106 DBGFREG_CS_LIMIT,
1107
1108 DBGFREG_DS,
1109 DBGFREG_DS_ATTR,
1110 DBGFREG_DS_BASE,
1111 DBGFREG_DS_LIMIT,
1112
1113 DBGFREG_ES,
1114 DBGFREG_ES_ATTR,
1115 DBGFREG_ES_BASE,
1116 DBGFREG_ES_LIMIT,
1117
1118 DBGFREG_FS,
1119 DBGFREG_FS_ATTR,
1120 DBGFREG_FS_BASE,
1121 DBGFREG_FS_LIMIT,
1122
1123 DBGFREG_GS,
1124 DBGFREG_GS_ATTR,
1125 DBGFREG_GS_BASE,
1126 DBGFREG_GS_LIMIT,
1127
1128 DBGFREG_SS,
1129 DBGFREG_SS_ATTR,
1130 DBGFREG_SS_BASE,
1131 DBGFREG_SS_LIMIT,
1132
1133 DBGFREG_IP,
1134 DBGFREG_EIP = DBGFREG_IP,
1135 DBGFREG_RIP = DBGFREG_IP,
1136
1137 DBGFREG_FLAGS,
1138 DBGFREG_EFLAGS = DBGFREG_FLAGS,
1139 DBGFREG_RFLAGS = DBGFREG_FLAGS,
1140
1141 /* FPU: */
1142 DBGFREG_FCW,
1143 DBGFREG_FSW,
1144 DBGFREG_FTW,
1145 DBGFREG_FOP,
1146 DBGFREG_FPUIP,
1147 DBGFREG_FPUCS,
1148 DBGFREG_FPUDP,
1149 DBGFREG_FPUDS,
1150 DBGFREG_MXCSR,
1151 DBGFREG_MXCSR_MASK,
1152
1153 DBGFREG_ST0,
1154 DBGFREG_ST1,
1155 DBGFREG_ST2,
1156 DBGFREG_ST3,
1157 DBGFREG_ST4,
1158 DBGFREG_ST5,
1159 DBGFREG_ST6,
1160 DBGFREG_ST7,
1161
1162 DBGFREG_MM0,
1163 DBGFREG_MM1,
1164 DBGFREG_MM2,
1165 DBGFREG_MM3,
1166 DBGFREG_MM4,
1167 DBGFREG_MM5,
1168 DBGFREG_MM6,
1169 DBGFREG_MM7,
1170
1171 /* SSE: */
1172 DBGFREG_XMM0,
1173 DBGFREG_XMM1,
1174 DBGFREG_XMM2,
1175 DBGFREG_XMM3,
1176 DBGFREG_XMM4,
1177 DBGFREG_XMM5,
1178 DBGFREG_XMM6,
1179 DBGFREG_XMM7,
1180 DBGFREG_XMM8,
1181 DBGFREG_XMM9,
1182 DBGFREG_XMM10,
1183 DBGFREG_XMM11,
1184 DBGFREG_XMM12,
1185 DBGFREG_XMM13,
1186 DBGFREG_XMM14,
1187 DBGFREG_XMM15,
1188 /** @todo add XMM aliases. */
1189
1190 /* System registers: */
1191 DBGFREG_GDTR_BASE,
1192 DBGFREG_GDTR_LIMIT,
1193 DBGFREG_IDTR_BASE,
1194 DBGFREG_IDTR_LIMIT,
1195 DBGFREG_LDTR,
1196 DBGFREG_LDTR_ATTR,
1197 DBGFREG_LDTR_BASE,
1198 DBGFREG_LDTR_LIMIT,
1199 DBGFREG_TR,
1200 DBGFREG_TR_ATTR,
1201 DBGFREG_TR_BASE,
1202 DBGFREG_TR_LIMIT,
1203
1204 DBGFREG_CR0,
1205 DBGFREG_CR2,
1206 DBGFREG_CR3,
1207 DBGFREG_CR4,
1208 DBGFREG_CR8,
1209
1210 DBGFREG_DR0,
1211 DBGFREG_DR1,
1212 DBGFREG_DR2,
1213 DBGFREG_DR3,
1214 DBGFREG_DR6,
1215 DBGFREG_DR7,
1216
1217 /* MSRs: */
1218 DBGFREG_MSR_IA32_APICBASE,
1219 DBGFREG_MSR_IA32_CR_PAT,
1220 DBGFREG_MSR_IA32_PERF_STATUS,
1221 DBGFREG_MSR_IA32_SYSENTER_CS,
1222 DBGFREG_MSR_IA32_SYSENTER_EIP,
1223 DBGFREG_MSR_IA32_SYSENTER_ESP,
1224 DBGFREG_MSR_IA32_TSC,
1225 DBGFREG_MSR_K6_EFER,
1226 DBGFREG_MSR_K6_STAR,
1227 DBGFREG_MSR_K8_CSTAR,
1228 DBGFREG_MSR_K8_FS_BASE,
1229 DBGFREG_MSR_K8_GS_BASE,
1230 DBGFREG_MSR_K8_KERNEL_GS_BASE,
1231 DBGFREG_MSR_K8_LSTAR,
1232 DBGFREG_MSR_K8_SF_MASK,
1233 DBGFREG_MSR_K8_TSC_AUX,
1234
1235 /** The number of registers to pass to DBGFR3RegQueryAll. */
1236 DBGFREG_ALL_COUNT,
1237
1238 /* Misc aliases that doesn't need be part of the 'all' query: */
1239 DBGFREG_AH = DBGFREG_ALL_COUNT,
1240 DBGFREG_CH,
1241 DBGFREG_DH,
1242 DBGFREG_BH,
1243 DBGFREG_GDTR,
1244 DBGFREG_IDTR,
1245
1246 /** The end of the registers. */
1247 DBGFREG_END,
1248 /** The usual 32-bit type hack. */
1249 DBGFREG_32BIT_HACK = 0x7fffffff
1250} DBGFREG;
1251/** Pointer to a register identifier. */
1252typedef DBGFREG *PDBGFREG;
1253/** Pointer to a const register identifier. */
1254typedef DBGFREG const *PCDBGFREG;
1255
1256/**
1257 * Register value type.
1258 */
1259typedef enum DBGFREGVALTYPE
1260{
1261 DBGFREGVALTYPE_INVALID = 0,
1262 /** Unsigned 8-bit register value. */
1263 DBGFREGVALTYPE_U8,
1264 /** Unsigned 16-bit register value. */
1265 DBGFREGVALTYPE_U16,
1266 /** Unsigned 32-bit register value. */
1267 DBGFREGVALTYPE_U32,
1268 /** Unsigned 64-bit register value. */
1269 DBGFREGVALTYPE_U64,
1270 /** Unsigned 128-bit register value. */
1271 DBGFREGVALTYPE_U128,
1272 /** Long double register value. */
1273 DBGFREGVALTYPE_R80,
1274 /** Descriptor table register value. */
1275 DBGFREGVALTYPE_DTR,
1276 /** End of the valid register value types. */
1277 DBGFREGVALTYPE_END,
1278 /** The usual 32-bit type hack. */
1279 DBGFREGVALTYPE_32BIT_HACK = 0x7fffffff
1280} DBGFREGVALTYPE;
1281/** Pointer to a register value type. */
1282typedef DBGFREGVALTYPE *PDBGFREGVALTYPE;
1283
1284/**
1285 * A generic register value type.
1286 */
1287typedef union DBGFREGVAL
1288{
1289 uint8_t u8; /**< The 8-bit view. */
1290 uint16_t u16; /**< The 16-bit view. */
1291 uint32_t u32; /**< The 32-bit view. */
1292 uint64_t u64; /**< The 64-bit view. */
1293 RTUINT128U u128; /**< The 128-bit view. */
1294 RTFLOAT80U r80; /**< The 80-bit floating point view. */
1295 RTFLOAT80U2 r80Ex; /**< The 80-bit floating point view v2. */
1296 /** GDTR or LDTR (DBGFREGVALTYPE_DTR). */
1297 struct
1298 {
1299 /** The table address. */
1300 uint64_t u64Base;
1301 /** The table limit (length minus 1). */
1302 uint32_t u32Limit;
1303 } dtr;
1304
1305 uint8_t au8[16]; /**< The 8-bit array view. */
1306 uint16_t au16[8]; /**< The 16-bit array view. */
1307 uint32_t au32[4]; /**< The 32-bit array view. */
1308 uint64_t au64[2]; /**< The 64-bit array view. */
1309 RTUINT128U u;
1310} DBGFREGVAL;
1311/** Pointer to a generic register value type. */
1312typedef DBGFREGVAL *PDBGFREGVAL;
1313/** Pointer to a const generic register value type. */
1314typedef DBGFREGVAL const *PCDBGFREGVAL;
1315
1316VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial);
1317VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType,
1318 unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
1319
1320/**
1321 * Register sub-field descriptor.
1322 */
1323typedef struct DBGFREGSUBFIELD
1324{
1325 /** The name of the sub-field. NULL is used to terminate the array. */
1326 const char *pszName;
1327 /** The index of the first bit. Ignored if pfnGet is set. */
1328 uint8_t iFirstBit;
1329 /** The number of bits. Mandatory. */
1330 uint8_t cBits;
1331 /** The shift count. Not applied when pfnGet is set, but used to
1332 * calculate the minimum type. */
1333 int8_t cShift;
1334 /** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */
1335 uint8_t fFlags;
1336 /** Getter (optional).
1337 * @remarks Does not take the device lock or anything like that.
1338 */
1339 DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue);
1340 /** Setter (optional).
1341 * @remarks Does not take the device lock or anything like that.
1342 */
1343 DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask);
1344} DBGFREGSUBFIELD;
1345/** Pointer to a const register sub-field descriptor. */
1346typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD;
1347
1348/** @name DBGFREGSUBFIELD_FLAGS_XXX
1349 * @{ */
1350/** The sub-field is read-only. */
1351#define DBGFREGSUBFIELD_FLAGS_READ_ONLY UINT8_C(0x01)
1352/** @} */
1353
1354/** Macro for creating a read-write sub-field entry without getters. */
1355#define DBGFREGSUBFIELD_RW(a_szName, a_iFirstBit, a_cBits, a_cShift) \
1356 { a_szName, a_iFirstBit, a_cBits, a_cShift, 0 /*fFlags*/, NULL /*pfnGet*/, NULL /*pfnSet*/ }
1357/** Macro for creating a read-write sub-field entry with getters. */
1358#define DBGFREGSUBFIELD_RW_SG(a_szName, a_cBits, a_cShift, a_pfnGet, a_pfnSet) \
1359 { a_szName, 0 /*iFirstBit*/, a_cBits, a_cShift, 0 /*fFlags*/, a_pfnGet, a_pfnSet }
1360/** Macro for creating a read-only sub-field entry without getters. */
1361#define DBGFREGSUBFIELD_RO(a_szName, a_iFirstBit, a_cBits, a_cShift) \
1362 { a_szName, a_iFirstBit, a_cBits, a_cShift, DBGFREGSUBFIELD_FLAGS_READ_ONLY, NULL /*pfnGet*/, NULL /*pfnSet*/ }
1363/** Macro for creating a terminator sub-field entry. */
1364#define DBGFREGSUBFIELD_TERMINATOR() \
1365 { NULL, 0, 0, 0, 0, NULL, NULL }
1366
1367/**
1368 * Register alias descriptor.
1369 */
1370typedef struct DBGFREGALIAS
1371{
1372 /** The alias name. NULL is used to terminate the array. */
1373 const char *pszName;
1374 /** Set to a valid type if the alias has a different type. */
1375 DBGFREGVALTYPE enmType;
1376} DBGFREGALIAS;
1377/** Pointer to a const register alias descriptor. */
1378typedef DBGFREGALIAS const *PCDBGFREGALIAS;
1379
1380/**
1381 * Register descriptor.
1382 */
1383typedef struct DBGFREGDESC
1384{
1385 /** The normal register name. */
1386 const char *pszName;
1387 /** The register identifier if this is a CPU register. */
1388 DBGFREG enmReg;
1389 /** The default register type. */
1390 DBGFREGVALTYPE enmType;
1391 /** Flags, see DBGFREG_FLAGS_XXX. */
1392 uint32_t fFlags;
1393 /** The internal register indicator.
1394 * For CPU registers this is the offset into the CPUMCTX structure,
1395 * thuse the 'off' prefix. */
1396 uint32_t offRegister;
1397 /** Getter.
1398 * @remarks Does not take the device lock or anything like that.
1399 */
1400 DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGDESC const *pDesc, PDBGFREGVAL pValue);
1401 /** Setter.
1402 * @remarks Does not take the device lock or anything like that.
1403 */
1404 DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask);
1405 /** Aliases (optional). */
1406 PCDBGFREGALIAS paAliases;
1407 /** Sub fields (optional). */
1408 PCDBGFREGSUBFIELD paSubFields;
1409} DBGFREGDESC;
1410
1411/** @name Macros for constructing DBGFREGDESC arrays.
1412 * @{ */
1413#define DBGFREGDESC_RW(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
1414 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
1415#define DBGFREGDESC_RO(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
1416 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
1417#define DBGFREGDESC_RW_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
1418 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
1419#define DBGFREGDESC_RO_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
1420 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
1421#define DBGFREGDESC_RW_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
1422 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
1423#define DBGFREGDESC_RO_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
1424 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
1425#define DBGFREGDESC_RW_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
1426 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
1427#define DBGFREGDESC_RO_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
1428 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
1429#define DBGFREGDESC_TERMINATOR() \
1430 { NULL, DBGFREG_END, DBGFREGVALTYPE_INVALID, 0, 0, NULL, NULL, NULL, NULL }
1431/** @} */
1432
1433
1434/** @name DBGFREG_FLAGS_XXX
1435 * @{ */
1436/** The register is read-only. */
1437#define DBGFREG_FLAGS_READ_ONLY RT_BIT_32(0)
1438/** @} */
1439
1440/**
1441 * Entry in a batch query or set operation.
1442 */
1443typedef struct DBGFREGENTRY
1444{
1445 /** The register identifier. */
1446 DBGFREG enmReg;
1447 /** The size of the value in bytes. */
1448 DBGFREGVALTYPE enmType;
1449 /** The register value. The valid view is indicated by enmType. */
1450 DBGFREGVAL Val;
1451} DBGFREGENTRY;
1452/** Pointer to a register entry in a batch operation. */
1453typedef DBGFREGENTRY *PDBGFREGENTRY;
1454/** Pointer to a const register entry in a batch operation. */
1455typedef DBGFREGENTRY const *PCDBGFREGENTRY;
1456
1457/** Used with DBGFR3Reg* to indicate the hypervisor register set instead of the
1458 * guest. */
1459#define DBGFREG_HYPER_VMCPUID UINT32_C(0x01000000)
1460
1461VMMR3DECL(int) DBGFR3RegCpuQueryU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8);
1462VMMR3DECL(int) DBGFR3RegCpuQueryU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16);
1463VMMR3DECL(int) DBGFR3RegCpuQueryU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32);
1464VMMR3DECL(int) DBGFR3RegCpuQueryU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64);
1465VMMR3DECL(int) DBGFR3RegCpuQueryU128(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128);
1466VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd);
1467VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit);
1468#if 0
1469VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PUVM pUVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
1470VMMR3DECL(int) DBGFR3RegCpuQueryAll( PUVM pUVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
1471
1472VMMR3DECL(int) DBGFR3RegCpuSetU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8);
1473VMMR3DECL(int) DBGFR3RegCpuSetU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16);
1474VMMR3DECL(int) DBGFR3RegCpuSetU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32);
1475VMMR3DECL(int) DBGFR3RegCpuSetU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64);
1476VMMR3DECL(int) DBGFR3RegCpuSetU128( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128);
1477VMMR3DECL(int) DBGFR3RegCpuSetLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd);
1478VMMR3DECL(int) DBGFR3RegCpuSetBatch( PUVM pUVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs);
1479#endif
1480
1481VMMR3DECL(const char *) DBGFR3RegCpuName(PUVM pUVM, DBGFREG enmReg, DBGFREGVALTYPE enmType);
1482
1483VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs);
1484VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns,
1485 const char *pszPrefix, uint32_t iInstance);
1486
1487/**
1488 * Entry in a named batch query or set operation.
1489 */
1490typedef struct DBGFREGENTRYNM
1491{
1492 /** The register name. */
1493 const char *pszName;
1494 /** The size of the value in bytes. */
1495 DBGFREGVALTYPE enmType;
1496 /** The register value. The valid view is indicated by enmType. */
1497 DBGFREGVAL Val;
1498} DBGFREGENTRYNM;
1499/** Pointer to a named register entry in a batch operation. */
1500typedef DBGFREGENTRYNM *PDBGFREGENTRYNM;
1501/** Pointer to a const named register entry in a batch operation. */
1502typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM;
1503
1504VMMR3DECL(int) DBGFR3RegNmValidate( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg);
1505
1506VMMR3DECL(int) DBGFR3RegNmQuery( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType);
1507VMMR3DECL(int) DBGFR3RegNmQueryU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8);
1508VMMR3DECL(int) DBGFR3RegNmQueryU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16);
1509VMMR3DECL(int) DBGFR3RegNmQueryU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32);
1510VMMR3DECL(int) DBGFR3RegNmQueryU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64);
1511VMMR3DECL(int) DBGFR3RegNmQueryU128(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128);
1512/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
1513VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
1514VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
1515VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PUVM pUVM, size_t *pcRegs);
1516VMMR3DECL(int) DBGFR3RegNmQueryAll( PUVM pUVM, PDBGFREGENTRYNM paRegs, size_t cRegs);
1517
1518VMMR3DECL(int) DBGFR3RegNmSet( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType);
1519VMMR3DECL(int) DBGFR3RegNmSetU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8);
1520VMMR3DECL(int) DBGFR3RegNmSetU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16);
1521VMMR3DECL(int) DBGFR3RegNmSetU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32);
1522VMMR3DECL(int) DBGFR3RegNmSetU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64);
1523VMMR3DECL(int) DBGFR3RegNmSetU128( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128);
1524VMMR3DECL(int) DBGFR3RegNmSetLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
1525VMMR3DECL(int) DBGFR3RegNmSetBatch( PUVM pUVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
1526
1527/** @todo add enumeration methods. */
1528
1529VMMR3DECL(int) DBGFR3RegPrintf( PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
1530VMMR3DECL(int) DBGFR3RegPrintfV(PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va);
1531
1532
1533/**
1534 * Guest OS digger interface identifier.
1535 *
1536 * This is for use together with PDBGFR3QueryInterface and is used to
1537 * obtain access to optional interfaces.
1538 */
1539typedef enum DBGFOSINTERFACE
1540{
1541 /** The usual invalid entry. */
1542 DBGFOSINTERFACE_INVALID = 0,
1543 /** Process info. */
1544 DBGFOSINTERFACE_PROCESS,
1545 /** Thread info. */
1546 DBGFOSINTERFACE_THREAD,
1547 /** The end of the valid entries. */
1548 DBGFOSINTERFACE_END,
1549 /** The usual 32-bit type blowup. */
1550 DBGFOSINTERFACE_32BIT_HACK = 0x7fffffff
1551} DBGFOSINTERFACE;
1552/** Pointer to a Guest OS digger interface identifier. */
1553typedef DBGFOSINTERFACE *PDBGFOSINTERFACE;
1554/** Pointer to a const Guest OS digger interface identifier. */
1555typedef DBGFOSINTERFACE const *PCDBGFOSINTERFACE;
1556
1557
1558/**
1559 * Guest OS Digger Registration Record.
1560 *
1561 * This is used with the DBGFR3OSRegister() API.
1562 */
1563typedef struct DBGFOSREG
1564{
1565 /** Magic value (DBGFOSREG_MAGIC). */
1566 uint32_t u32Magic;
1567 /** Flags. Reserved. */
1568 uint32_t fFlags;
1569 /** The size of the instance data. */
1570 uint32_t cbData;
1571 /** Operative System name. */
1572 char szName[24];
1573
1574 /**
1575 * Constructs the instance.
1576 *
1577 * @returns VBox status code.
1578 * @param pUVM The user mode VM handle.
1579 * @param pvData Pointer to the instance data.
1580 */
1581 DECLCALLBACKMEMBER(int, pfnConstruct)(PUVM pUVM, void *pvData);
1582
1583 /**
1584 * Destroys the instance.
1585 *
1586 * @param pUVM The user mode VM handle.
1587 * @param pvData Pointer to the instance data.
1588 */
1589 DECLCALLBACKMEMBER(void, pfnDestruct)(PUVM pUVM, void *pvData);
1590
1591 /**
1592 * Probes the guest memory for OS finger prints.
1593 *
1594 * No setup or so is performed, it will be followed by a call to pfnInit
1595 * or pfnRefresh that should take care of that.
1596 *
1597 * @returns true if is an OS handled by this module, otherwise false.
1598 * @param pUVM The user mode VM handle.
1599 * @param pvData Pointer to the instance data.
1600 */
1601 DECLCALLBACKMEMBER(bool, pfnProbe)(PUVM pUVM, void *pvData);
1602
1603 /**
1604 * Initializes a fresly detected guest, loading symbols and such useful stuff.
1605 *
1606 * This is called after pfnProbe.
1607 *
1608 * @returns VBox status code.
1609 * @param pUVM The user mode VM handle.
1610 * @param pvData Pointer to the instance data.
1611 */
1612 DECLCALLBACKMEMBER(int, pfnInit)(PUVM pUVM, void *pvData);
1613
1614 /**
1615 * Refreshes symbols and stuff following a redetection of the same OS.
1616 *
1617 * This is called after pfnProbe.
1618 *
1619 * @returns VBox status code.
1620 * @param pUVM The user mode VM handle.
1621 * @param pvData Pointer to the instance data.
1622 */
1623 DECLCALLBACKMEMBER(int, pfnRefresh)(PUVM pUVM, void *pvData);
1624
1625 /**
1626 * Terminates an OS when a new (or none) OS has been detected,
1627 * and before destruction.
1628 *
1629 * This is called after pfnProbe and if needed before pfnDestruct.
1630 *
1631 * @param pUVM The user mode VM handle.
1632 * @param pvData Pointer to the instance data.
1633 */
1634 DECLCALLBACKMEMBER(void, pfnTerm)(PUVM pUVM, void *pvData);
1635
1636 /**
1637 * Queries the version of the running OS.
1638 *
1639 * This is only called after pfnInit().
1640 *
1641 * @returns VBox status code.
1642 * @param pUVM The user mode VM handle.
1643 * @param pvData Pointer to the instance data.
1644 * @param pszVersion Where to store the version string.
1645 * @param cchVersion The size of the version string buffer.
1646 */
1647 DECLCALLBACKMEMBER(int, pfnQueryVersion)(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion);
1648
1649 /**
1650 * Queries the pointer to a interface.
1651 *
1652 * This is called after pfnProbe.
1653 *
1654 * @returns Pointer to the interface if available, NULL if not available.
1655 * @param pUVM The user mode VM handle.
1656 * @param pvData Pointer to the instance data.
1657 * @param enmIf The interface identifier.
1658 */
1659 DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf);
1660
1661 /** Trailing magic (DBGFOSREG_MAGIC). */
1662 uint32_t u32EndMagic;
1663} DBGFOSREG;
1664/** Pointer to a Guest OS digger registration record. */
1665typedef DBGFOSREG *PDBGFOSREG;
1666/** Pointer to a const Guest OS digger registration record. */
1667typedef DBGFOSREG const *PCDBGFOSREG;
1668
1669/** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */
1670#define DBGFOSREG_MAGIC 0x19830808
1671
1672VMMR3DECL(int) DBGFR3OSRegister(PUVM pUVM, PCDBGFOSREG pReg);
1673VMMR3DECL(int) DBGFR3OSDeregister(PUVM pUVM, PCDBGFOSREG pReg);
1674VMMR3DECL(int) DBGFR3OSDetect(PUVM pUVM, char *pszName, size_t cchName);
1675VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion);
1676VMMR3DECL(void *) DBGFR3OSQueryInterface(PUVM pUVM, DBGFOSINTERFACE enmIf);
1677
1678
1679VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile);
1680
1681/** @} */
1682
1683
1684RT_C_DECLS_END
1685
1686#endif
1687
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette