VirtualBox

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

Last change on this file since 55461 was 54218, checked in by vboxsync, 10 years ago

DBGF,DBGC: Added dmesg command and implemented it for linux guests.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 64.6 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, bool fAltStepping);
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) DBGFBpIsHwArmed(PVM pVM);
421VMM_INT_DECL(bool) DBGFBpIsHwIoArmed(PVM pVM);
422VMM_INT_DECL(bool) DBGFIsStepping(PVMCPU pVCpu);
423VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue);
424
425
426#ifdef IN_RING3 /* The CPU mode API only works in ring-3. */
427VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu);
428VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM);
429VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu);
430#endif
431
432
433
434#ifdef IN_RING3 /* The info callbacks API only works in ring-3. */
435
436/**
437 * Info helper callback structure.
438 */
439typedef struct DBGFINFOHLP
440{
441 /**
442 * Print formatted string.
443 *
444 * @param pHlp Pointer to this structure.
445 * @param pszFormat The format string.
446 * @param ... Arguments.
447 */
448 DECLCALLBACKMEMBER(void, pfnPrintf)(PCDBGFINFOHLP pHlp, const char *pszFormat, ...);
449
450 /**
451 * Print formatted string.
452 *
453 * @param pHlp Pointer to this structure.
454 * @param pszFormat The format string.
455 * @param args Argument list.
456 */
457 DECLCALLBACKMEMBER(void, pfnPrintfV)(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args);
458} DBGFINFOHLP;
459
460
461/**
462 * Info handler, device version.
463 *
464 * @param pDevIns The device instance which registered the info.
465 * @param pHlp Callback functions for doing output.
466 * @param pszArgs Argument string. Optional and specific to the handler.
467 */
468typedef DECLCALLBACK(void) FNDBGFHANDLERDEV(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
469/** Pointer to a FNDBGFHANDLERDEV function. */
470typedef FNDBGFHANDLERDEV *PFNDBGFHANDLERDEV;
471
472/**
473 * Info handler, USB device version.
474 *
475 * @param pUsbIns The USB device instance which registered the info.
476 * @param pHlp Callback functions for doing output.
477 * @param pszArgs Argument string. Optional and specific to the handler.
478 */
479typedef DECLCALLBACK(void) FNDBGFHANDLERUSB(PPDMUSBINS pUsbIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
480/** Pointer to a FNDBGFHANDLERUSB function. */
481typedef FNDBGFHANDLERUSB *PFNDBGFHANDLERUSB;
482
483/**
484 * Info handler, driver version.
485 *
486 * @param pDrvIns The driver instance which registered the info.
487 * @param pHlp Callback functions for doing output.
488 * @param pszArgs Argument string. Optional and specific to the handler.
489 */
490typedef DECLCALLBACK(void) FNDBGFHANDLERDRV(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
491/** Pointer to a FNDBGFHANDLERDRV function. */
492typedef FNDBGFHANDLERDRV *PFNDBGFHANDLERDRV;
493
494/**
495 * Info handler, internal version.
496 *
497 * @param pVM The VM handle.
498 * @param pHlp Callback functions for doing output.
499 * @param pszArgs Argument string. Optional and specific to the handler.
500 */
501typedef DECLCALLBACK(void) FNDBGFHANDLERINT(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
502/** Pointer to a FNDBGFHANDLERINT function. */
503typedef FNDBGFHANDLERINT *PFNDBGFHANDLERINT;
504
505/**
506 * Info handler, external version.
507 *
508 * @param pvUser User argument.
509 * @param pHlp Callback functions for doing output.
510 * @param pszArgs Argument string. Optional and specific to the handler.
511 */
512typedef DECLCALLBACK(void) FNDBGFHANDLEREXT(void *pvUser, PCDBGFINFOHLP pHlp, const char *pszArgs);
513/** Pointer to a FNDBGFHANDLEREXT function. */
514typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT;
515
516
517/** @name Flags for the info registration functions.
518 * @{ */
519/** The handler must run on the EMT. */
520#define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0)
521/** @} */
522
523VMMR3_INT_DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
524VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
525VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
526VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
527VMMR3DECL(int) DBGFR3InfoRegisterExternal(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
528VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName);
529VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName);
530VMMR3_INT_DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName);
531VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PUVM pUVM, const char *pszName);
532VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
533VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
534VMMR3DECL(int) DBGFR3InfoLogRel(PUVM pUVM, const char *pszName, const char *pszArgs);
535VMMR3DECL(int) DBGFR3InfoStdErr(PUVM pUVM, const char *pszName, const char *pszArgs);
536VMMR3_INT_DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat,
537 const char *pszSepFmt, PCDBGFINFOHLP pHlp);
538
539/** @def DBGFR3_INFO_LOG
540 * Display a piece of info writing to the log if enabled.
541 *
542 * @param a_pVM The shared VM handle.
543 * @param a_pszName The identifier of the info to display.
544 * @param a_pszArgs Arguments to the info handler.
545 */
546#ifdef LOG_ENABLED
547# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) \
548 do { \
549 if (LogIsEnabled()) \
550 DBGFR3Info((a_pVM)->pUVM, a_pszName, a_pszArgs, NULL); \
551 } while (0)
552#else
553# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) do { } while (0)
554#endif
555
556/**
557 * Enumeration callback for use with DBGFR3InfoEnum.
558 *
559 * @returns VBox status code.
560 * A status code indicating failure will end the enumeration
561 * and DBGFR3InfoEnum will return with that status code.
562 * @param pUVM The user mode VM handle.
563 * @param pszName Info identifier name.
564 * @param pszDesc The description.
565 */
566typedef DECLCALLBACK(int) FNDBGFINFOENUM(PUVM pUVM, const char *pszName, const char *pszDesc, void *pvUser);
567/** Pointer to a FNDBGFINFOENUM function. */
568typedef FNDBGFINFOENUM *PFNDBGFINFOENUM;
569
570VMMR3DECL(int) DBGFR3InfoEnum(PUVM pUVM, PFNDBGFINFOENUM pfnCallback, void *pvUser);
571VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void);
572VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void);
573
574#endif /* IN_RING3 */
575
576
577#ifdef IN_RING3 /* The log contrl API only works in ring-3. */
578VMMR3DECL(int) DBGFR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings);
579VMMR3DECL(int) DBGFR3LogModifyFlags(PUVM pUVM, const char *pszFlagSettings);
580VMMR3DECL(int) DBGFR3LogModifyDestinations(PUVM pUVM, const char *pszDestSettings);
581#endif /* IN_RING3 */
582
583#ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */
584
585/** Max length (including '\\0') of a symbol name. */
586#define DBGF_SYMBOL_NAME_LENGTH 512
587
588/**
589 * Debug symbol.
590 */
591typedef struct DBGFSYMBOL
592{
593 /** Symbol value (address). */
594 RTGCUINTPTR Value;
595 /** Symbol size. */
596 uint32_t cb;
597 /** Symbol Flags. (reserved). */
598 uint32_t fFlags;
599 /** Symbol name. */
600 char szName[DBGF_SYMBOL_NAME_LENGTH];
601} DBGFSYMBOL;
602/** Pointer to debug symbol. */
603typedef DBGFSYMBOL *PDBGFSYMBOL;
604/** Pointer to const debug symbol. */
605typedef const DBGFSYMBOL *PCDBGFSYMBOL;
606
607/**
608 * Debug line number information.
609 */
610typedef struct DBGFLINE
611{
612 /** Address. */
613 RTGCUINTPTR Address;
614 /** Line number. */
615 uint32_t uLineNo;
616 /** Filename. */
617 char szFilename[260];
618} DBGFLINE;
619/** Pointer to debug line number. */
620typedef DBGFLINE *PDBGFLINE;
621/** Pointer to const debug line number. */
622typedef const DBGFLINE *PCDBGFLINE;
623
624/** @name Address spaces aliases.
625 * @{ */
626/** The guest global address space. */
627#define DBGF_AS_GLOBAL ((RTDBGAS)-1)
628/** The guest kernel address space.
629 * This is usually resolves to the same as DBGF_AS_GLOBAL. */
630#define DBGF_AS_KERNEL ((RTDBGAS)-2)
631/** The physical address space. */
632#define DBGF_AS_PHYS ((RTDBGAS)-3)
633/** Raw-mode context. */
634#define DBGF_AS_RC ((RTDBGAS)-4)
635/** Ring-0 context. */
636#define DBGF_AS_R0 ((RTDBGAS)-5)
637/** Raw-mode context and then global guest context.
638 * When used for looking up information, it works as if the call was first made
639 * with DBGF_AS_RC and then on failure with DBGF_AS_GLOBAL. When called for
640 * making address space changes, it works as if DBGF_AS_RC was used. */
641#define DBGF_AS_RC_AND_GC_GLOBAL ((RTDBGAS)-6)
642
643/** The first special one. */
644#define DBGF_AS_FIRST DBGF_AS_RC_AND_GC_GLOBAL
645/** The last special one. */
646#define DBGF_AS_LAST DBGF_AS_GLOBAL
647#endif
648/** The number of special address space handles. */
649#define DBGF_AS_COUNT (6U)
650#ifdef IN_RING3
651/** Converts an alias handle to an array index. */
652#define DBGF_AS_ALIAS_2_INDEX(hAlias) \
653 ( (uintptr_t)(hAlias) - (uintptr_t)DBGF_AS_FIRST )
654/** Predicat macro that check if the specified handle is an alias. */
655#define DBGF_AS_IS_ALIAS(hAlias) \
656 ( DBGF_AS_ALIAS_2_INDEX(hAlias) < DBGF_AS_COUNT )
657/** Predicat macro that check if the specified alias is a fixed one or not. */
658#define DBGF_AS_IS_FIXED_ALIAS(hAlias) \
659 ( DBGF_AS_ALIAS_2_INDEX(hAlias) < (uintptr_t)DBGF_AS_PHYS - (uintptr_t)DBGF_AS_FIRST + 1U )
660
661/** @} */
662
663VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM);
664
665VMMR3DECL(int) DBGFR3AsAdd(PUVM pUVM, RTDBGAS hDbgAs, RTPROCESS ProcId);
666VMMR3DECL(int) DBGFR3AsDelete(PUVM pUVM, RTDBGAS hDbgAs);
667VMMR3DECL(int) DBGFR3AsSetAlias(PUVM pUVM, RTDBGAS hAlias, RTDBGAS hAliasFor);
668VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PUVM pUVM, RTDBGAS hAlias);
669VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias);
670VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName);
671VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PUVM pUVM, RTPROCESS ProcId);
672
673VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName,
674 RTLDRARCH enmArch, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
675VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags);
676VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
677VMMR3DECL(int) DBGFR3AsUnlinkModuleByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszModName);
678
679VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
680 PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
681VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t Flags,
682 PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
683VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
684
685VMMR3DECL(int) DBGFR3AsLineByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
686 PRTGCINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod);
687VMMR3DECL(PRTDBGLINE) DBGFR3AsLineByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
688 PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
689
690#endif /* IN_RING3 */
691
692#ifdef IN_RING3 /* The stack API only works in ring-3. */
693
694/**
695 * Return type.
696 */
697typedef enum DBGFRETRUNTYPE
698{
699 /** The usual invalid 0 value. */
700 DBGFRETURNTYPE_INVALID = 0,
701 /** Near 16-bit return. */
702 DBGFRETURNTYPE_NEAR16,
703 /** Near 32-bit return. */
704 DBGFRETURNTYPE_NEAR32,
705 /** Near 64-bit return. */
706 DBGFRETURNTYPE_NEAR64,
707 /** Far 16:16 return. */
708 DBGFRETURNTYPE_FAR16,
709 /** Far 16:32 return. */
710 DBGFRETURNTYPE_FAR32,
711 /** Far 16:64 return. */
712 DBGFRETURNTYPE_FAR64,
713 /** 16-bit iret return (e.g. real or 286 protect mode). */
714 DBGFRETURNTYPE_IRET16,
715 /** 32-bit iret return. */
716 DBGFRETURNTYPE_IRET32,
717 /** 32-bit iret return. */
718 DBGFRETURNTYPE_IRET32_PRIV,
719 /** 32-bit iret return to V86 mode. */
720 DBGFRETURNTYPE_IRET32_V86,
721 /** @todo 64-bit iret return. */
722 DBGFRETURNTYPE_IRET64,
723 /** The end of the valid return types. */
724 DBGFRETURNTYPE_END,
725 /** The usual 32-bit blowup. */
726 DBGFRETURNTYPE_32BIT_HACK = 0x7fffffff
727} DBGFRETURNTYPE;
728
729/**
730 * Figures the size of the return state on the stack.
731 *
732 * @returns number of bytes. 0 if invalid parameter.
733 * @param enmRetType The type of return.
734 */
735DECLINLINE(unsigned) DBGFReturnTypeSize(DBGFRETURNTYPE enmRetType)
736{
737 switch (enmRetType)
738 {
739 case DBGFRETURNTYPE_NEAR16: return 2;
740 case DBGFRETURNTYPE_NEAR32: return 4;
741 case DBGFRETURNTYPE_NEAR64: return 8;
742 case DBGFRETURNTYPE_FAR16: return 4;
743 case DBGFRETURNTYPE_FAR32: return 4;
744 case DBGFRETURNTYPE_FAR64: return 8;
745 case DBGFRETURNTYPE_IRET16: return 6;
746 case DBGFRETURNTYPE_IRET32: return 4*3;
747 case DBGFRETURNTYPE_IRET32_PRIV: return 4*5;
748 case DBGFRETURNTYPE_IRET32_V86: return 4*9;
749 case DBGFRETURNTYPE_IRET64:
750 default:
751 return 0;
752 }
753}
754
755
756/** Pointer to stack frame info. */
757typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
758/** Pointer to const stack frame info. */
759typedef struct DBGFSTACKFRAME const *PCDBGFSTACKFRAME;
760/**
761 * Info about a stack frame.
762 */
763typedef struct DBGFSTACKFRAME
764{
765 /** Frame number. */
766 uint32_t iFrame;
767 /** Frame flags. */
768 uint32_t fFlags;
769 /** The frame address.
770 * The off member is [e|r]bp and the Sel member is ss. */
771 DBGFADDRESS AddrFrame;
772 /** The stack address of the frame.
773 * The off member is [e|r]sp and the Sel member is ss. */
774 DBGFADDRESS AddrStack;
775 /** The program counter (PC) address of the frame.
776 * The off member is [e|r]ip and the Sel member is cs. */
777 DBGFADDRESS AddrPC;
778 /** Pointer to the symbol nearest the program counter (PC). NULL if not found. */
779 PRTDBGSYMBOL pSymPC;
780 /** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */
781 PRTDBGLINE pLinePC;
782
783 /** The return frame address.
784 * The off member is [e|r]bp and the Sel member is ss. */
785 DBGFADDRESS AddrReturnFrame;
786 /** The return stack address.
787 * The off member is [e|r]sp and the Sel member is ss. */
788 DBGFADDRESS AddrReturnStack;
789 /** The way this frame returns to the next one. */
790 DBGFRETURNTYPE enmReturnType;
791
792 /** The program counter (PC) address which the frame returns to.
793 * The off member is [e|r]ip and the Sel member is cs. */
794 DBGFADDRESS AddrReturnPC;
795 /** Pointer to the symbol nearest the return PC. NULL if not found. */
796 PRTDBGSYMBOL pSymReturnPC;
797 /** Pointer to the linnumber nearest the return PC. NULL if not found. */
798 PRTDBGLINE pLineReturnPC;
799
800 /** 32-bytes of stack arguments. */
801 union
802 {
803 /** 64-bit view */
804 uint64_t au64[4];
805 /** 32-bit view */
806 uint32_t au32[8];
807 /** 16-bit view */
808 uint16_t au16[16];
809 /** 8-bit view */
810 uint8_t au8[32];
811 } Args;
812
813 /** Pointer to the next frame.
814 * Might not be used in some cases, so consider it internal. */
815 PCDBGFSTACKFRAME pNextInternal;
816 /** Pointer to the first frame.
817 * Might not be used in some cases, so consider it internal. */
818 PCDBGFSTACKFRAME pFirstInternal;
819} DBGFSTACKFRAME;
820
821/** @name DBGFSTACKFRAME Flags.
822 * @{ */
823/** Set if the content of the frame is filled in by DBGFR3StackWalk() and can be used
824 * to construct the next frame. */
825# define DBGFSTACKFRAME_FLAGS_ALL_VALID RT_BIT(0)
826/** This is the last stack frame we can read.
827 * This flag is not set if the walk stop because of max dept or recursion. */
828# define DBGFSTACKFRAME_FLAGS_LAST RT_BIT(1)
829/** This is the last record because we detected a loop. */
830# define DBGFSTACKFRAME_FLAGS_LOOP RT_BIT(2)
831/** This is the last record because we reached the maximum depth. */
832# define DBGFSTACKFRAME_FLAGS_MAX_DEPTH RT_BIT(3)
833/** 16-bit frame. */
834# define DBGFSTACKFRAME_FLAGS_16BIT RT_BIT(4)
835/** 32-bit frame. */
836# define DBGFSTACKFRAME_FLAGS_32BIT RT_BIT(5)
837/** 64-bit frame. */
838# define DBGFSTACKFRAME_FLAGS_64BIT RT_BIT(6)
839/** @} */
840
841/** @name DBGFCODETYPE
842 * @{ */
843typedef enum DBGFCODETYPE
844{
845 /** The usual invalid 0 value. */
846 DBGFCODETYPE_INVALID = 0,
847 /** Stack walk for guest code. */
848 DBGFCODETYPE_GUEST,
849 /** Stack walk for hypervisor code. */
850 DBGFCODETYPE_HYPER,
851 /** Stack walk for ring 0 code. */
852 DBGFCODETYPE_RING0,
853 /** The usual 32-bit blowup. */
854 DBGFCODETYPE_32BIT_HACK = 0x7fffffff
855} DBGFCODETYPE;
856/** @} */
857
858VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType,
859 PCDBGFSTACKFRAME *ppFirstFrame);
860VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
861 PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC,
862 DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
863VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent);
864VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
865
866#endif /* IN_RING3 */
867
868
869#ifdef IN_RING3 /* The disassembly API only works in ring-3. */
870
871/** Flags to pass to DBGFR3DisasInstrEx().
872 * @{ */
873/** Disassemble the current guest instruction, with annotations. */
874#define DBGF_DISAS_FLAGS_CURRENT_GUEST RT_BIT(0)
875/** Disassemble the current hypervisor instruction, with annotations. */
876#define DBGF_DISAS_FLAGS_CURRENT_HYPER RT_BIT(1)
877/** No annotations for current context. */
878#define DBGF_DISAS_FLAGS_NO_ANNOTATION RT_BIT(2)
879/** No symbol lookup. */
880#define DBGF_DISAS_FLAGS_NO_SYMBOLS RT_BIT(3)
881/** No instruction bytes. */
882#define DBGF_DISAS_FLAGS_NO_BYTES RT_BIT(4)
883/** No address in the output. */
884#define DBGF_DISAS_FLAGS_NO_ADDRESS RT_BIT(5)
885/** Probably a hypervisor instruction. */
886#define DBGF_DISAS_FLAGS_HYPER RT_BIT(6)
887/** Disassemble original unpatched bytes (PATM). */
888#define DBGF_DISAS_FLAGS_UNPATCHED_BYTES RT_BIT(7)
889/** Annotate patched instructions. */
890#define DBGF_DISAS_FLAGS_ANNOTATE_PATCHED RT_BIT(8)
891/** Disassemble in the default mode of the specific context. */
892#define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000)
893/** Disassemble in 16-bit mode. */
894#define DBGF_DISAS_FLAGS_16BIT_MODE UINT32_C(0x10000000)
895/** Disassemble in 16-bit mode with real mode address translation. */
896#define DBGF_DISAS_FLAGS_16BIT_REAL_MODE UINT32_C(0x20000000)
897/** Disassemble in 32-bit mode. */
898#define DBGF_DISAS_FLAGS_32BIT_MODE UINT32_C(0x30000000)
899/** Disassemble in 64-bit mode. */
900#define DBGF_DISAS_FLAGS_64BIT_MODE UINT32_C(0x40000000)
901/** The disassembly mode mask. */
902#define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000)
903/** Mask containing the valid flags. */
904#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x700001ff)
905/** @} */
906
907/** Special flat selector. */
908#define DBGF_SEL_FLAT 1
909
910VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
911 char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr);
912VMMR3_INT_DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput);
913VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix);
914
915/** @def DBGFR3_DISAS_INSTR_CUR_LOG
916 * Disassembles the current guest context instruction and writes it to the log.
917 * All registers and data will be displayed. Addresses will be attempted resolved to symbols.
918 */
919#ifdef LOG_ENABLED
920# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) \
921 do { \
922 if (LogIsEnabled()) \
923 DBGFR3DisasInstrCurrentLogInternal(pVCpu, pszPrefix); \
924 } while (0)
925#else
926# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) do { } while (0)
927#endif
928
929VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix);
930
931/** @def DBGFR3_DISAS_INSTR_LOG
932 * Disassembles the specified guest context instruction and writes it to the log.
933 * Addresses will be attempted resolved to symbols.
934 * @thread Any EMT.
935 */
936# ifdef LOG_ENABLED
937# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) \
938 do { \
939 if (LogIsEnabled()) \
940 DBGFR3DisasInstrLogInternal(pVCpu, Sel, GCPtr, pszPrefix); \
941 } while (0)
942# else
943# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0)
944# endif
945#endif
946
947
948#ifdef IN_RING3
949VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign,
950 const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress);
951VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
952VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
953VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead);
954#endif
955
956
957/** @name Flags for DBGFR3PagingDumpEx, PGMR3DumpHierarchyHCEx and
958 * PGMR3DumpHierarchyGCEx
959 * @{ */
960/** The CR3 from the current CPU state. */
961#define DBGFPGDMP_FLAGS_CURRENT_CR3 RT_BIT_32(0)
962/** The current CPU paging mode (PSE, PAE, LM, EPT, NX). */
963#define DBGFPGDMP_FLAGS_CURRENT_MODE RT_BIT_32(1)
964/** Whether PSE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
965 * Same value as X86_CR4_PSE. */
966#define DBGFPGDMP_FLAGS_PSE RT_BIT_32(4) /* */
967/** Whether PAE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
968 * Same value as X86_CR4_PAE. */
969#define DBGFPGDMP_FLAGS_PAE RT_BIT_32(5) /* */
970/** Whether LME is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
971 * Same value as MSR_K6_EFER_LME. */
972#define DBGFPGDMP_FLAGS_LME RT_BIT_32(8)
973/** Whether nested paging is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
974#define DBGFPGDMP_FLAGS_NP RT_BIT_32(9)
975/** Whether extended nested page tables are enabled
976 * (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
977#define DBGFPGDMP_FLAGS_EPT RT_BIT_32(10)
978/** Whether no-execution is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
979 * Same value as MSR_K6_EFER_NXE. */
980#define DBGFPGDMP_FLAGS_NXE RT_BIT_32(11)
981/** Whether to print the CR3. */
982#define DBGFPGDMP_FLAGS_PRINT_CR3 RT_BIT_32(27)
983/** Whether to print the header. */
984#define DBGFPGDMP_FLAGS_HEADER RT_BIT_32(28)
985/** Whether to dump additional page information. */
986#define DBGFPGDMP_FLAGS_PAGE_INFO RT_BIT_32(29)
987/** Dump the shadow tables if set.
988 * Cannot be used together with DBGFPGDMP_FLAGS_GUEST. */
989#define DBGFPGDMP_FLAGS_SHADOW RT_BIT_32(30)
990/** Dump the guest tables if set.
991 * Cannot be used together with DBGFPGDMP_FLAGS_SHADOW. */
992#define DBGFPGDMP_FLAGS_GUEST RT_BIT_32(31)
993/** Mask of valid bits. */
994#define DBGFPGDMP_FLAGS_VALID_MASK UINT32_C(0xf8000f33)
995/** The mask of bits controlling the paging mode. */
996#define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32)
997/** @} */
998VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
999 uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
1000
1001
1002/** @name DBGFR3SelQueryInfo flags.
1003 * @{ */
1004/** Get the info from the guest descriptor table. */
1005#define DBGFSELQI_FLAGS_DT_GUEST UINT32_C(0)
1006/** Get the info from the shadow descriptor table.
1007 * Only works in raw-mode. */
1008#define DBGFSELQI_FLAGS_DT_SHADOW UINT32_C(1)
1009/** If currently executing in in 64-bit mode, blow up data selectors. */
1010#define DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE UINT32_C(2)
1011/** @} */
1012VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo);
1013
1014
1015/**
1016 * Register identifiers.
1017 */
1018typedef enum DBGFREG
1019{
1020 /* General purpose registers: */
1021 DBGFREG_AL = 0,
1022 DBGFREG_AX = DBGFREG_AL,
1023 DBGFREG_EAX = DBGFREG_AL,
1024 DBGFREG_RAX = DBGFREG_AL,
1025
1026 DBGFREG_CL,
1027 DBGFREG_CX = DBGFREG_CL,
1028 DBGFREG_ECX = DBGFREG_CL,
1029 DBGFREG_RCX = DBGFREG_CL,
1030
1031 DBGFREG_DL,
1032 DBGFREG_DX = DBGFREG_DL,
1033 DBGFREG_EDX = DBGFREG_DL,
1034 DBGFREG_RDX = DBGFREG_DL,
1035
1036 DBGFREG_BL,
1037 DBGFREG_BX = DBGFREG_BL,
1038 DBGFREG_EBX = DBGFREG_BL,
1039 DBGFREG_RBX = DBGFREG_BL,
1040
1041 DBGFREG_SPL,
1042 DBGFREG_SP = DBGFREG_SPL,
1043 DBGFREG_ESP = DBGFREG_SPL,
1044 DBGFREG_RSP = DBGFREG_SPL,
1045
1046 DBGFREG_BPL,
1047 DBGFREG_BP = DBGFREG_BPL,
1048 DBGFREG_EBP = DBGFREG_BPL,
1049 DBGFREG_RBP = DBGFREG_BPL,
1050
1051 DBGFREG_SIL,
1052 DBGFREG_SI = DBGFREG_SIL,
1053 DBGFREG_ESI = DBGFREG_SIL,
1054 DBGFREG_RSI = DBGFREG_SIL,
1055
1056 DBGFREG_DIL,
1057 DBGFREG_DI = DBGFREG_DIL,
1058 DBGFREG_EDI = DBGFREG_DIL,
1059 DBGFREG_RDI = DBGFREG_DIL,
1060
1061 DBGFREG_R8,
1062 DBGFREG_R8B = DBGFREG_R8,
1063 DBGFREG_R8W = DBGFREG_R8,
1064 DBGFREG_R8D = DBGFREG_R8,
1065
1066 DBGFREG_R9,
1067 DBGFREG_R9B = DBGFREG_R9,
1068 DBGFREG_R9W = DBGFREG_R9,
1069 DBGFREG_R9D = DBGFREG_R9,
1070
1071 DBGFREG_R10,
1072 DBGFREG_R10B = DBGFREG_R10,
1073 DBGFREG_R10W = DBGFREG_R10,
1074 DBGFREG_R10D = DBGFREG_R10,
1075
1076 DBGFREG_R11,
1077 DBGFREG_R11B = DBGFREG_R11,
1078 DBGFREG_R11W = DBGFREG_R11,
1079 DBGFREG_R11D = DBGFREG_R11,
1080
1081 DBGFREG_R12,
1082 DBGFREG_R12B = DBGFREG_R12,
1083 DBGFREG_R12W = DBGFREG_R12,
1084 DBGFREG_R12D = DBGFREG_R12,
1085
1086 DBGFREG_R13,
1087 DBGFREG_R13B = DBGFREG_R13,
1088 DBGFREG_R13W = DBGFREG_R13,
1089 DBGFREG_R13D = DBGFREG_R13,
1090
1091 DBGFREG_R14,
1092 DBGFREG_R14B = DBGFREG_R14,
1093 DBGFREG_R14W = DBGFREG_R14,
1094 DBGFREG_R14D = DBGFREG_R14,
1095
1096 DBGFREG_R15,
1097 DBGFREG_R15B = DBGFREG_R15,
1098 DBGFREG_R15W = DBGFREG_R15,
1099 DBGFREG_R15D = DBGFREG_R15,
1100
1101 /* Segments and other special registers: */
1102 DBGFREG_CS,
1103 DBGFREG_CS_ATTR,
1104 DBGFREG_CS_BASE,
1105 DBGFREG_CS_LIMIT,
1106
1107 DBGFREG_DS,
1108 DBGFREG_DS_ATTR,
1109 DBGFREG_DS_BASE,
1110 DBGFREG_DS_LIMIT,
1111
1112 DBGFREG_ES,
1113 DBGFREG_ES_ATTR,
1114 DBGFREG_ES_BASE,
1115 DBGFREG_ES_LIMIT,
1116
1117 DBGFREG_FS,
1118 DBGFREG_FS_ATTR,
1119 DBGFREG_FS_BASE,
1120 DBGFREG_FS_LIMIT,
1121
1122 DBGFREG_GS,
1123 DBGFREG_GS_ATTR,
1124 DBGFREG_GS_BASE,
1125 DBGFREG_GS_LIMIT,
1126
1127 DBGFREG_SS,
1128 DBGFREG_SS_ATTR,
1129 DBGFREG_SS_BASE,
1130 DBGFREG_SS_LIMIT,
1131
1132 DBGFREG_IP,
1133 DBGFREG_EIP = DBGFREG_IP,
1134 DBGFREG_RIP = DBGFREG_IP,
1135
1136 DBGFREG_FLAGS,
1137 DBGFREG_EFLAGS = DBGFREG_FLAGS,
1138 DBGFREG_RFLAGS = DBGFREG_FLAGS,
1139
1140 /* FPU: */
1141 DBGFREG_FCW,
1142 DBGFREG_FSW,
1143 DBGFREG_FTW,
1144 DBGFREG_FOP,
1145 DBGFREG_FPUIP,
1146 DBGFREG_FPUCS,
1147 DBGFREG_FPUDP,
1148 DBGFREG_FPUDS,
1149 DBGFREG_MXCSR,
1150 DBGFREG_MXCSR_MASK,
1151
1152 DBGFREG_ST0,
1153 DBGFREG_ST1,
1154 DBGFREG_ST2,
1155 DBGFREG_ST3,
1156 DBGFREG_ST4,
1157 DBGFREG_ST5,
1158 DBGFREG_ST6,
1159 DBGFREG_ST7,
1160
1161 DBGFREG_MM0,
1162 DBGFREG_MM1,
1163 DBGFREG_MM2,
1164 DBGFREG_MM3,
1165 DBGFREG_MM4,
1166 DBGFREG_MM5,
1167 DBGFREG_MM6,
1168 DBGFREG_MM7,
1169
1170 /* SSE: */
1171 DBGFREG_XMM0,
1172 DBGFREG_XMM1,
1173 DBGFREG_XMM2,
1174 DBGFREG_XMM3,
1175 DBGFREG_XMM4,
1176 DBGFREG_XMM5,
1177 DBGFREG_XMM6,
1178 DBGFREG_XMM7,
1179 DBGFREG_XMM8,
1180 DBGFREG_XMM9,
1181 DBGFREG_XMM10,
1182 DBGFREG_XMM11,
1183 DBGFREG_XMM12,
1184 DBGFREG_XMM13,
1185 DBGFREG_XMM14,
1186 DBGFREG_XMM15,
1187 /** @todo add XMM aliases. */
1188
1189 /* System registers: */
1190 DBGFREG_GDTR_BASE,
1191 DBGFREG_GDTR_LIMIT,
1192 DBGFREG_IDTR_BASE,
1193 DBGFREG_IDTR_LIMIT,
1194 DBGFREG_LDTR,
1195 DBGFREG_LDTR_ATTR,
1196 DBGFREG_LDTR_BASE,
1197 DBGFREG_LDTR_LIMIT,
1198 DBGFREG_TR,
1199 DBGFREG_TR_ATTR,
1200 DBGFREG_TR_BASE,
1201 DBGFREG_TR_LIMIT,
1202
1203 DBGFREG_CR0,
1204 DBGFREG_CR2,
1205 DBGFREG_CR3,
1206 DBGFREG_CR4,
1207 DBGFREG_CR8,
1208
1209 DBGFREG_DR0,
1210 DBGFREG_DR1,
1211 DBGFREG_DR2,
1212 DBGFREG_DR3,
1213 DBGFREG_DR6,
1214 DBGFREG_DR7,
1215
1216 /* MSRs: */
1217 DBGFREG_MSR_IA32_APICBASE,
1218 DBGFREG_MSR_IA32_CR_PAT,
1219 DBGFREG_MSR_IA32_PERF_STATUS,
1220 DBGFREG_MSR_IA32_SYSENTER_CS,
1221 DBGFREG_MSR_IA32_SYSENTER_EIP,
1222 DBGFREG_MSR_IA32_SYSENTER_ESP,
1223 DBGFREG_MSR_IA32_TSC,
1224 DBGFREG_MSR_K6_EFER,
1225 DBGFREG_MSR_K6_STAR,
1226 DBGFREG_MSR_K8_CSTAR,
1227 DBGFREG_MSR_K8_FS_BASE,
1228 DBGFREG_MSR_K8_GS_BASE,
1229 DBGFREG_MSR_K8_KERNEL_GS_BASE,
1230 DBGFREG_MSR_K8_LSTAR,
1231 DBGFREG_MSR_K8_SF_MASK,
1232 DBGFREG_MSR_K8_TSC_AUX,
1233
1234 /** The number of registers to pass to DBGFR3RegQueryAll. */
1235 DBGFREG_ALL_COUNT,
1236
1237 /* Misc aliases that doesn't need be part of the 'all' query: */
1238 DBGFREG_AH = DBGFREG_ALL_COUNT,
1239 DBGFREG_CH,
1240 DBGFREG_DH,
1241 DBGFREG_BH,
1242 DBGFREG_GDTR,
1243 DBGFREG_IDTR,
1244
1245 /** The end of the registers. */
1246 DBGFREG_END,
1247 /** The usual 32-bit type hack. */
1248 DBGFREG_32BIT_HACK = 0x7fffffff
1249} DBGFREG;
1250/** Pointer to a register identifier. */
1251typedef DBGFREG *PDBGFREG;
1252/** Pointer to a const register identifier. */
1253typedef DBGFREG const *PCDBGFREG;
1254
1255/**
1256 * Register value type.
1257 */
1258typedef enum DBGFREGVALTYPE
1259{
1260 DBGFREGVALTYPE_INVALID = 0,
1261 /** Unsigned 8-bit register value. */
1262 DBGFREGVALTYPE_U8,
1263 /** Unsigned 16-bit register value. */
1264 DBGFREGVALTYPE_U16,
1265 /** Unsigned 32-bit register value. */
1266 DBGFREGVALTYPE_U32,
1267 /** Unsigned 64-bit register value. */
1268 DBGFREGVALTYPE_U64,
1269 /** Unsigned 128-bit register value. */
1270 DBGFREGVALTYPE_U128,
1271 /** Long double register value. */
1272 DBGFREGVALTYPE_R80,
1273 /** Descriptor table register value. */
1274 DBGFREGVALTYPE_DTR,
1275 /** End of the valid register value types. */
1276 DBGFREGVALTYPE_END,
1277 /** The usual 32-bit type hack. */
1278 DBGFREGVALTYPE_32BIT_HACK = 0x7fffffff
1279} DBGFREGVALTYPE;
1280/** Pointer to a register value type. */
1281typedef DBGFREGVALTYPE *PDBGFREGVALTYPE;
1282
1283/**
1284 * A generic register value type.
1285 */
1286typedef union DBGFREGVAL
1287{
1288 uint64_t au64[2]; /**< The 64-bit array view. First because of the initializer. */
1289 uint32_t au32[4]; /**< The 32-bit array view. */
1290 uint16_t au16[8]; /**< The 16-bit array view. */
1291 uint8_t au8[16]; /**< The 8-bit array view. */
1292
1293 uint8_t u8; /**< The 8-bit view. */
1294 uint16_t u16; /**< The 16-bit view. */
1295 uint32_t u32; /**< The 32-bit view. */
1296 uint64_t u64; /**< The 64-bit view. */
1297 RTUINT128U u128; /**< The 128-bit view. */
1298 RTFLOAT80U r80; /**< The 80-bit floating point view. */
1299 RTFLOAT80U2 r80Ex; /**< The 80-bit floating point view v2. */
1300 /** GDTR or LDTR (DBGFREGVALTYPE_DTR). */
1301 struct
1302 {
1303 /** The table address. */
1304 uint64_t u64Base;
1305 /** The table limit (length minus 1). */
1306 uint32_t u32Limit;
1307 } dtr;
1308
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
1316/** Initialize a DBGFREGVAL variable to all zeros. */
1317#define DBGFREGVAL_INITIALIZE_ZERO { { 0, 0 } }
1318/** Initialize a DBGFREGVAL variable to all bits set . */
1319#define DBGFREGVAL_INITIALIZE_FFFF { { UINT64_MAX, UINT64_MAX } }
1320
1321
1322VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial);
1323VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType,
1324 unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
1325
1326/**
1327 * Register sub-field descriptor.
1328 */
1329typedef struct DBGFREGSUBFIELD
1330{
1331 /** The name of the sub-field. NULL is used to terminate the array. */
1332 const char *pszName;
1333 /** The index of the first bit. Ignored if pfnGet is set. */
1334 uint8_t iFirstBit;
1335 /** The number of bits. Mandatory. */
1336 uint8_t cBits;
1337 /** The shift count. Not applied when pfnGet is set, but used to
1338 * calculate the minimum type. */
1339 int8_t cShift;
1340 /** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */
1341 uint8_t fFlags;
1342 /** Getter (optional).
1343 * @remarks Does not take the device lock or anything like that.
1344 */
1345 DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue);
1346 /** Setter (optional).
1347 * @remarks Does not take the device lock or anything like that.
1348 */
1349 DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask);
1350} DBGFREGSUBFIELD;
1351/** Pointer to a const register sub-field descriptor. */
1352typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD;
1353
1354/** @name DBGFREGSUBFIELD_FLAGS_XXX
1355 * @{ */
1356/** The sub-field is read-only. */
1357#define DBGFREGSUBFIELD_FLAGS_READ_ONLY UINT8_C(0x01)
1358/** @} */
1359
1360/** Macro for creating a read-write sub-field entry without getters. */
1361#define DBGFREGSUBFIELD_RW(a_szName, a_iFirstBit, a_cBits, a_cShift) \
1362 { a_szName, a_iFirstBit, a_cBits, a_cShift, 0 /*fFlags*/, NULL /*pfnGet*/, NULL /*pfnSet*/ }
1363/** Macro for creating a read-write sub-field entry with getters. */
1364#define DBGFREGSUBFIELD_RW_SG(a_szName, a_cBits, a_cShift, a_pfnGet, a_pfnSet) \
1365 { a_szName, 0 /*iFirstBit*/, a_cBits, a_cShift, 0 /*fFlags*/, a_pfnGet, a_pfnSet }
1366/** Macro for creating a read-only sub-field entry without getters. */
1367#define DBGFREGSUBFIELD_RO(a_szName, a_iFirstBit, a_cBits, a_cShift) \
1368 { a_szName, a_iFirstBit, a_cBits, a_cShift, DBGFREGSUBFIELD_FLAGS_READ_ONLY, NULL /*pfnGet*/, NULL /*pfnSet*/ }
1369/** Macro for creating a terminator sub-field entry. */
1370#define DBGFREGSUBFIELD_TERMINATOR() \
1371 { NULL, 0, 0, 0, 0, NULL, NULL }
1372
1373/**
1374 * Register alias descriptor.
1375 */
1376typedef struct DBGFREGALIAS
1377{
1378 /** The alias name. NULL is used to terminate the array. */
1379 const char *pszName;
1380 /** Set to a valid type if the alias has a different type. */
1381 DBGFREGVALTYPE enmType;
1382} DBGFREGALIAS;
1383/** Pointer to a const register alias descriptor. */
1384typedef DBGFREGALIAS const *PCDBGFREGALIAS;
1385
1386/**
1387 * Register descriptor.
1388 */
1389typedef struct DBGFREGDESC
1390{
1391 /** The normal register name. */
1392 const char *pszName;
1393 /** The register identifier if this is a CPU register. */
1394 DBGFREG enmReg;
1395 /** The default register type. */
1396 DBGFREGVALTYPE enmType;
1397 /** Flags, see DBGFREG_FLAGS_XXX. */
1398 uint32_t fFlags;
1399 /** The internal register indicator.
1400 * For CPU registers this is the offset into the CPUMCTX structure,
1401 * thuse the 'off' prefix. */
1402 uint32_t offRegister;
1403 /** Getter.
1404 * @remarks Does not take the device lock or anything like that.
1405 */
1406 DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGDESC const *pDesc, PDBGFREGVAL pValue);
1407 /** Setter.
1408 * @remarks Does not take the device lock or anything like that.
1409 */
1410 DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask);
1411 /** Aliases (optional). */
1412 PCDBGFREGALIAS paAliases;
1413 /** Sub fields (optional). */
1414 PCDBGFREGSUBFIELD paSubFields;
1415} DBGFREGDESC;
1416
1417/** @name Macros for constructing DBGFREGDESC arrays.
1418 * @{ */
1419#define DBGFREGDESC_RW(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
1420 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
1421#define DBGFREGDESC_RO(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
1422 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
1423#define DBGFREGDESC_RW_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
1424 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
1425#define DBGFREGDESC_RO_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
1426 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
1427#define DBGFREGDESC_RW_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
1428 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
1429#define DBGFREGDESC_RO_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
1430 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
1431#define DBGFREGDESC_RW_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
1432 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
1433#define DBGFREGDESC_RO_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
1434 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
1435#define DBGFREGDESC_TERMINATOR() \
1436 { NULL, DBGFREG_END, DBGFREGVALTYPE_INVALID, 0, 0, NULL, NULL, NULL, NULL }
1437/** @} */
1438
1439
1440/** @name DBGFREG_FLAGS_XXX
1441 * @{ */
1442/** The register is read-only. */
1443#define DBGFREG_FLAGS_READ_ONLY RT_BIT_32(0)
1444/** @} */
1445
1446/**
1447 * Entry in a batch query or set operation.
1448 */
1449typedef struct DBGFREGENTRY
1450{
1451 /** The register identifier. */
1452 DBGFREG enmReg;
1453 /** The size of the value in bytes. */
1454 DBGFREGVALTYPE enmType;
1455 /** The register value. The valid view is indicated by enmType. */
1456 DBGFREGVAL Val;
1457} DBGFREGENTRY;
1458/** Pointer to a register entry in a batch operation. */
1459typedef DBGFREGENTRY *PDBGFREGENTRY;
1460/** Pointer to a const register entry in a batch operation. */
1461typedef DBGFREGENTRY const *PCDBGFREGENTRY;
1462
1463/** Used with DBGFR3Reg* to indicate the hypervisor register set instead of the
1464 * guest. */
1465#define DBGFREG_HYPER_VMCPUID UINT32_C(0x01000000)
1466
1467VMMR3DECL(int) DBGFR3RegCpuQueryU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8);
1468VMMR3DECL(int) DBGFR3RegCpuQueryU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16);
1469VMMR3DECL(int) DBGFR3RegCpuQueryU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32);
1470VMMR3DECL(int) DBGFR3RegCpuQueryU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64);
1471VMMR3DECL(int) DBGFR3RegCpuQueryU128(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128);
1472VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd);
1473VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit);
1474#if 0
1475VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PUVM pUVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
1476VMMR3DECL(int) DBGFR3RegCpuQueryAll( PUVM pUVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
1477
1478VMMR3DECL(int) DBGFR3RegCpuSetU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8);
1479VMMR3DECL(int) DBGFR3RegCpuSetU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16);
1480VMMR3DECL(int) DBGFR3RegCpuSetU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32);
1481VMMR3DECL(int) DBGFR3RegCpuSetU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64);
1482VMMR3DECL(int) DBGFR3RegCpuSetU128( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128);
1483VMMR3DECL(int) DBGFR3RegCpuSetLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd);
1484VMMR3DECL(int) DBGFR3RegCpuSetBatch( PUVM pUVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs);
1485#endif
1486
1487VMMR3DECL(const char *) DBGFR3RegCpuName(PUVM pUVM, DBGFREG enmReg, DBGFREGVALTYPE enmType);
1488
1489VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs);
1490VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns,
1491 const char *pszPrefix, uint32_t iInstance);
1492
1493/**
1494 * Entry in a named batch query or set operation.
1495 */
1496typedef struct DBGFREGENTRYNM
1497{
1498 /** The register name. */
1499 const char *pszName;
1500 /** The size of the value in bytes. */
1501 DBGFREGVALTYPE enmType;
1502 /** The register value. The valid view is indicated by enmType. */
1503 DBGFREGVAL Val;
1504} DBGFREGENTRYNM;
1505/** Pointer to a named register entry in a batch operation. */
1506typedef DBGFREGENTRYNM *PDBGFREGENTRYNM;
1507/** Pointer to a const named register entry in a batch operation. */
1508typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM;
1509
1510VMMR3DECL(int) DBGFR3RegNmValidate( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg);
1511
1512VMMR3DECL(int) DBGFR3RegNmQuery( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType);
1513VMMR3DECL(int) DBGFR3RegNmQueryU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8);
1514VMMR3DECL(int) DBGFR3RegNmQueryU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16);
1515VMMR3DECL(int) DBGFR3RegNmQueryU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32);
1516VMMR3DECL(int) DBGFR3RegNmQueryU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64);
1517VMMR3DECL(int) DBGFR3RegNmQueryU128(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128);
1518/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
1519VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
1520VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
1521VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PUVM pUVM, size_t *pcRegs);
1522VMMR3DECL(int) DBGFR3RegNmQueryAll( PUVM pUVM, PDBGFREGENTRYNM paRegs, size_t cRegs);
1523
1524VMMR3DECL(int) DBGFR3RegNmSet( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType);
1525VMMR3DECL(int) DBGFR3RegNmSetU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8);
1526VMMR3DECL(int) DBGFR3RegNmSetU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16);
1527VMMR3DECL(int) DBGFR3RegNmSetU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32);
1528VMMR3DECL(int) DBGFR3RegNmSetU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64);
1529VMMR3DECL(int) DBGFR3RegNmSetU128( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128);
1530VMMR3DECL(int) DBGFR3RegNmSetLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
1531VMMR3DECL(int) DBGFR3RegNmSetBatch( PUVM pUVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
1532
1533/** @todo add enumeration methods. */
1534
1535VMMR3DECL(int) DBGFR3RegPrintf( PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
1536VMMR3DECL(int) DBGFR3RegPrintfV(PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va);
1537
1538
1539/**
1540 * Guest OS digger interface identifier.
1541 *
1542 * This is for use together with PDBGFR3QueryInterface and is used to
1543 * obtain access to optional interfaces.
1544 */
1545typedef enum DBGFOSINTERFACE
1546{
1547 /** The usual invalid entry. */
1548 DBGFOSINTERFACE_INVALID = 0,
1549 /** Process info. */
1550 DBGFOSINTERFACE_PROCESS,
1551 /** Thread info. */
1552 DBGFOSINTERFACE_THREAD,
1553 /** Kernel message log - DBGFOSIDMESG. */
1554 DBGFOSINTERFACE_DMESG,
1555 /** The end of the valid entries. */
1556 DBGFOSINTERFACE_END,
1557 /** The usual 32-bit type blowup. */
1558 DBGFOSINTERFACE_32BIT_HACK = 0x7fffffff
1559} DBGFOSINTERFACE;
1560/** Pointer to a Guest OS digger interface identifier. */
1561typedef DBGFOSINTERFACE *PDBGFOSINTERFACE;
1562/** Pointer to a const Guest OS digger interface identifier. */
1563typedef DBGFOSINTERFACE const *PCDBGFOSINTERFACE;
1564
1565
1566/**
1567 * Guest OS Digger Registration Record.
1568 *
1569 * This is used with the DBGFR3OSRegister() API.
1570 */
1571typedef struct DBGFOSREG
1572{
1573 /** Magic value (DBGFOSREG_MAGIC). */
1574 uint32_t u32Magic;
1575 /** Flags. Reserved. */
1576 uint32_t fFlags;
1577 /** The size of the instance data. */
1578 uint32_t cbData;
1579 /** Operative System name. */
1580 char szName[24];
1581
1582 /**
1583 * Constructs the instance.
1584 *
1585 * @returns VBox status code.
1586 * @param pUVM The user mode VM handle.
1587 * @param pvData Pointer to the instance data.
1588 */
1589 DECLCALLBACKMEMBER(int, pfnConstruct)(PUVM pUVM, void *pvData);
1590
1591 /**
1592 * Destroys the instance.
1593 *
1594 * @param pUVM The user mode VM handle.
1595 * @param pvData Pointer to the instance data.
1596 */
1597 DECLCALLBACKMEMBER(void, pfnDestruct)(PUVM pUVM, void *pvData);
1598
1599 /**
1600 * Probes the guest memory for OS finger prints.
1601 *
1602 * No setup or so is performed, it will be followed by a call to pfnInit
1603 * or pfnRefresh that should take care of that.
1604 *
1605 * @returns true if is an OS handled by this module, otherwise false.
1606 * @param pUVM The user mode VM handle.
1607 * @param pvData Pointer to the instance data.
1608 */
1609 DECLCALLBACKMEMBER(bool, pfnProbe)(PUVM pUVM, void *pvData);
1610
1611 /**
1612 * Initializes a fresly detected guest, loading symbols and such useful stuff.
1613 *
1614 * This is called after pfnProbe.
1615 *
1616 * @returns VBox status code.
1617 * @param pUVM The user mode VM handle.
1618 * @param pvData Pointer to the instance data.
1619 */
1620 DECLCALLBACKMEMBER(int, pfnInit)(PUVM pUVM, void *pvData);
1621
1622 /**
1623 * Refreshes symbols and stuff following a redetection of the same OS.
1624 *
1625 * This is called after pfnProbe.
1626 *
1627 * @returns VBox status code.
1628 * @param pUVM The user mode VM handle.
1629 * @param pvData Pointer to the instance data.
1630 */
1631 DECLCALLBACKMEMBER(int, pfnRefresh)(PUVM pUVM, void *pvData);
1632
1633 /**
1634 * Terminates an OS when a new (or none) OS has been detected,
1635 * and before destruction.
1636 *
1637 * This is called after pfnProbe and if needed before pfnDestruct.
1638 *
1639 * @param pUVM The user mode VM handle.
1640 * @param pvData Pointer to the instance data.
1641 */
1642 DECLCALLBACKMEMBER(void, pfnTerm)(PUVM pUVM, void *pvData);
1643
1644 /**
1645 * Queries the version of the running OS.
1646 *
1647 * This is only called after pfnInit().
1648 *
1649 * @returns VBox status code.
1650 * @param pUVM The user mode VM handle.
1651 * @param pvData Pointer to the instance data.
1652 * @param pszVersion Where to store the version string.
1653 * @param cchVersion The size of the version string buffer.
1654 */
1655 DECLCALLBACKMEMBER(int, pfnQueryVersion)(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion);
1656
1657 /**
1658 * Queries the pointer to a interface.
1659 *
1660 * This is called after pfnProbe.
1661 *
1662 * The returned interface must be valid until pfnDestruct is called. Two calls
1663 * to this method with the same @a enmIf value must return the same pointer.
1664 *
1665 * @returns Pointer to the interface if available, NULL if not available.
1666 * @param pUVM The user mode VM handle.
1667 * @param pvData Pointer to the instance data.
1668 * @param enmIf The interface identifier.
1669 */
1670 DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf);
1671
1672 /** Trailing magic (DBGFOSREG_MAGIC). */
1673 uint32_t u32EndMagic;
1674} DBGFOSREG;
1675/** Pointer to a Guest OS digger registration record. */
1676typedef DBGFOSREG *PDBGFOSREG;
1677/** Pointer to a const Guest OS digger registration record. */
1678typedef DBGFOSREG const *PCDBGFOSREG;
1679
1680/** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */
1681#define DBGFOSREG_MAGIC 0x19830808
1682
1683
1684/**
1685 * Interface for querying kernel log messages (DBGFOSINTERFACE_DMESG).
1686 */
1687typedef struct DBGFOSIDMESG
1688{
1689 /** Trailing magic (DBGFOSIDMESG_MAGIC). */
1690 uint32_t u32Magic;
1691
1692 /**
1693 * Query the kernel log.
1694 *
1695 * @returns VBox status code.
1696 * @retval VERR_NOT_FOUND if the messages could not be located.
1697 * @retval VERR_INVALID_STATE if the messages was found to have unknown/invalid
1698 * format.
1699 * @retval VERR_BUFFER_OVERFLOW if the buffer isn't large enough, pcbActual
1700 * will be set to the required buffer size. The buffer, however, will
1701 * be filled with as much data as it can hold (properly zero terminated
1702 * of course).
1703 *
1704 * @param pThis Pointer to the interface structure.
1705 * @param pUVM The user mode VM handle.
1706 * @param fFlags Flags reserved for future use, MBZ.
1707 * @param cMessages The number of messages to retrieve, counting from the
1708 * end of the log (i.e. like tail), use UINT32_MAX for all.
1709 * @param pszBuf The output buffer.
1710 * @param cbBuf The buffer size.
1711 * @param pcbActual Where to store the number of bytes actually returned,
1712 * including zero terminator. On VERR_BUFFER_OVERFLOW this
1713 * holds the necessary buffer size. Optional.
1714 */
1715 DECLCALLBACKMEMBER(int, pfnQueryKernelLog)(struct DBGFOSIDMESG *pThis, PUVM pUVM, uint32_t fFlags, uint32_t cMessages,
1716 char *pszBuf, size_t cbBuf, size_t *pcbActual);
1717 /** Trailing magic (DBGFOSIDMESG_MAGIC). */
1718 uint32_t u32EndMagic;
1719} DBGFOSIDMESG;
1720/** Pointer to the interface for query kernel log messages (DBGFOSINTERFACE_DMESG). */
1721typedef DBGFOSIDMESG *PDBGFOSIDMESG;
1722/** Magic value for DBGFOSIDMESG::32Magic and DBGFOSIDMESG::u32EndMagic. (Kenazburo Oe) */
1723#define DBGFOSIDMESG_MAGIC UINT32_C(0x19350131)
1724
1725
1726VMMR3DECL(int) DBGFR3OSRegister(PUVM pUVM, PCDBGFOSREG pReg);
1727VMMR3DECL(int) DBGFR3OSDeregister(PUVM pUVM, PCDBGFOSREG pReg);
1728VMMR3DECL(int) DBGFR3OSDetect(PUVM pUVM, char *pszName, size_t cchName);
1729VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion);
1730VMMR3DECL(void *) DBGFR3OSQueryInterface(PUVM pUVM, DBGFOSINTERFACE enmIf);
1731
1732
1733VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile);
1734
1735/** @} */
1736
1737
1738RT_C_DECLS_END
1739
1740#endif
1741
Note: See TracBrowser for help on using the repository browser.

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