VirtualBox

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

Last change on this file since 58891 was 58891, checked in by vboxsync, 9 years ago

dbgf.h: Extended DBGFEVENTTYPE with a bunch of events that may be useful. The CPU exceptions (DBGFEVENT_XCPT_XXX) are of immediate use. Events starting with DBGFEVENT_FIRST_SELECTABLE are envisioned being configured via a single API operating on some bitmask and making HM, IOM, ++ notifications calls to let the components update cached state/whatever. The interrupt events would require it's own API, that operates on a 32 byte bitmap with a bit counter for optimizations. The I/O and MMIO events should be added to the DBGFR3BpXxx API and added as two new DBGFBP variants.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 74.1 KB
Line 
1/** @file
2 * DBGF - Debugger Facility.
3 */
4
5/*
6 * Copyright (C) 2006-2015 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 * @ingroup grp_vmm
42 * @{
43 */
44
45#if defined(IN_RC) || defined(IN_RING0)
46/** @defgroup grp_dbgf_rz The RZ DBGF API
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 /** Fatal error.
151 * This notifies a fatal error in the VMM and that the debugger get's a
152 * chance to first hand information about the the problem.
153 */
154 DBGFEVENT_FATAL_ERROR,
155 /** Breakpoint Hit.
156 * This notifies that a breakpoint installed by the debugger was hit. The
157 * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
158 */
159 DBGFEVENT_BREAKPOINT,
160 /** I/O port breakpoint.
161 * @todo not yet implemented. */
162 DBGFEVENT_BREAKPOINT_IO,
163 /** MMIO breakpoint.
164 * @todo not yet implemented. */
165 DBGFEVENT_BREAKPOINT_MMIO,
166 /** Breakpoint Hit in the Hypervisor.
167 * This notifies that a breakpoint installed by the debugger was hit. The
168 * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
169 */
170 DBGFEVENT_BREAKPOINT_HYPER,
171 /** Assertion in the Hypervisor (breakpoint instruction).
172 * This notifies that a breakpoint instruction was hit in the hypervisor context.
173 */
174 DBGFEVENT_ASSERTION_HYPER,
175 /** Single Stepped.
176 * This notifies that a single step operation was completed.
177 */
178 DBGFEVENT_STEPPED,
179 /** Single Stepped.
180 * This notifies that a hypervisor single step operation was completed.
181 */
182 DBGFEVENT_STEPPED_HYPER,
183 /** The developer have used the DBGFSTOP macro or the PDMDeviceDBGFSTOP function
184 * to bring up the debugger at a specific place.
185 */
186 DBGFEVENT_DEV_STOP,
187 /** The VM is powering off.
188 * When this notification is received, the debugger thread should detach ASAP.
189 */
190 DBGFEVENT_POWERING_OFF,
191
192 /** The first selectable event.
193 * Whether the debugger wants or doesn't want these events can be configured
194 * via DBGFR3xxx and queried via DBGFR3yyy. */
195 DBGFEVENT_FIRST_SELECTABLE,
196 /** Tripple fault.
197 * @todo not yet implemented. */
198 DBGFEVENT_TRIPPLE_FAULT = DBGFEVENT_FIRST_SELECTABLE,
199 DBGFEVENT_XCPT_DE, /**< 0x00 - \#DE - Fault - NoErr - Integer divide error (zero/overflow). */
200 DBGFEVENT_XCPT_DB, /**< 0x01 - \#DB - trap/fault - NoErr - debug event. */
201 DBGFEVENT_XCPT_02, /**< 0x02 - Reserved for NMI, see interrupt events. */
202 DBGFEVENT_XCPT_BP, /**< 0x03 - \#BP - Trap - NoErr - Breakpoint, INT 3 instruction. */
203 DBGFEVENT_XCPT_OF, /**< 0x04 - \#OF - Trap - NoErr - Overflow, INTO instruction. */
204 DBGFEVENT_XCPT_BR, /**< 0x05 - \#BR - Fault - NoErr - BOUND Range Exceeded, BOUND instruction. */
205 DBGFEVENT_XCPT_UD, /**< 0x06 - \#UD - Fault - NoErr - Undefined(/Invalid) Opcode. */
206 DBGFEVENT_XCPT_NM, /**< 0x07 - \#NM - Fault - NoErr - Device not available, FP or (F)WAIT instruction. */
207 DBGFEVENT_XCPT_DF, /**< 0x08 - \#DF - Abort - Err=0 - Double fault. */
208 DBGFEVENT_XCPT_09, /**< 0x09 - Int9 - Fault - NoErr - Coprocessor Segment Overrun (obsolete). */
209 DBGFEVENT_XCPT_TS, /**< 0x0a - \#TS - Fault - ErrCd - Invalid TSS, Taskswitch or TSS access. */
210 DBGFEVENT_XCPT_NP, /**< 0x0b - \#NP - Fault - ErrCd - Segment not present. */
211 DBGFEVENT_XCPT_SS, /**< 0x0c - \#SS - Fault - ErrCd - Stack-Segment fault. */
212 DBGFEVENT_XCPT_GP, /**< 0x0d - \#GP - Fault - ErrCd - General protection fault. */
213 DBGFEVENT_XCPT_PF, /**< 0x0e - \#PF - Fault - ErrCd - Page fault. - interrupt gate!!! */
214 DBGFEVENT_XCPT_0f, /**< 0x0f - Rsvd - Resvd - Resvd - Intel Reserved. */
215 DBGFEVENT_XCPT_MF, /**< 0x10 - \#MF - Fault - NoErr - x86 FPU Floating-Point Error (Math fault), FP or (F)WAIT instruction. */
216 DBGFEVENT_XCPT_AC, /**< 0x11 - \#AC - Fault - Err=0 - Alignment Check. */
217 DBGFEVENT_XCPT_MC, /**< 0x12 - \#MC - Abort - NoErr - Machine Check. */
218 DBGFEVENT_XCPT_XM, /**< 0x13 - \#XF - Fault - NoErr - SIMD Floating-Point Exception. */
219 DBGFEVENT_XCPT_VE, /**< 0x14 - \#VE - Fault - Noerr - Virtualization exception. */
220 DBGFEVENT_XCPT_15, /**< 0x15 - Intel Reserved. */
221 DBGFEVENT_XCPT_16, /**< 0x16 - Intel Reserved. */
222 DBGFEVENT_XCPT_17, /**< 0x17 - Intel Reserved. */
223 DBGFEVENT_XCPT_18, /**< 0x18 - Intel Reserved. */
224 DBGFEVENT_XCPT_19, /**< 0x19 - Intel Reserved. */
225 DBGFEVENT_XCPT_1a, /**< 0x1a - Intel Reserved. */
226 DBGFEVENT_XCPT_1b, /**< 0x1b - Intel Reserved. */
227 DBGFEVENT_XCPT_1c, /**< 0x1c - Intel Reserved. */
228 DBGFEVENT_XCPT_1d, /**< 0x1d - Intel Reserved. */
229 DBGFEVENT_XCPT_1e, /**< 0x1e - \#SX - Fault - ErrCd - Security Exception. */
230 DBGFEVENT_XCPT_1f, /**< 0x1f - Intel Reserved. */
231 /** The first exception event. */
232 DBGFEVENT_XCPT_FIRST = DBGFEVENT_XCPT_DE,
233 /** The last exception event. */
234 DBGFEVENT_XCPT_LAST = DBGFEVENT_XCPT_1f,
235 /** Interrupt event.
236 * @todo not yet implemented. */
237 DBGFEVENT_INT,
238 /** Access to an unassigned I/O port.
239 * @todo not yet implemented. */
240 DBGFEVENT_IOPORT_UNASSIGNED,
241 /** Access to an unused I/O port on a device.
242 * @todo not yet implemented. */
243 DBGFEVENT_IOPORT_UNUSED,
244 /** Unassigned memory event.
245 * @todo not yet implemented. */
246 DBGFEVENT_MEMORY_UNASSIGNED,
247 /** Attempt to write to unshadowed ROM.
248 * @todo not yet implemented. */
249 DBGFEVENT_MEMORY_ROM_WRITE,
250
251 /** Exit - Task switch.
252 * @todo not yet implemented. */
253 DBGFEVENT_EXIT_TASK_SWITCH,
254 /** Exit - HALT instruction.
255 * @todo not yet implemented. */
256 DBGFEVENT_EXIT_HALT,
257 /** Exit - MWAIT instruction.
258 * @todo not yet implemented. */
259 DBGFEVENT_EXIT_MWAIT,
260 /** Exit - MONITOR instruction.
261 * @todo not yet implemented. */
262 DBGFEVENT_EXIT_MONITOR,
263 /** Exit - CPUID instruction (missing stuff in raw-mode).
264 * @todo not yet implemented. */
265 DBGFEVENT_EXIT_CPUID,
266 /** Exit - INV instruction.
267 * @todo not yet implemented. */
268 DBGFEVENT_EXIT_INV,
269 /** Exit - WBINVD instruction.
270 * @todo not yet implemented. */
271 DBGFEVENT_EXIT_WBINVD,
272 /** Exit - INVLPG instruction.
273 * @todo not yet implemented. */
274 DBGFEVENT_EXIT_INVLPG,
275 /** Exit - RDTSC instruction.
276 * @todo not yet implemented. */
277 DBGFEVENT_EXIT_RDTSC,
278 /** Exit - RDTSCP instruction.
279 * @todo not yet implemented. */
280 DBGFEVENT_EXIT_RDTSCP,
281 /** Exit - RDPMC instruction.
282 * @todo not yet implemented. */
283 DBGFEVENT_EXIT_RDPMC,
284 /** Exit - RDMSR instruction.
285 * @todo not yet implemented. */
286 DBGFEVENT_EXIT_RDMSR,
287 /** Exit - WRMSR instruction.
288 * @todo not yet implemented. */
289 DBGFEVENT_EXIT_WRMSR,
290 /** Exit - CRx read instruction (missing smsw in raw-mode).
291 * @todo not yet implemented. */
292 DBGFEVENT_EXIT_CRX_READ,
293 /** Exit - CRx write instruction.
294 * @todo not yet implemented. */
295 DBGFEVENT_EXIT_CRX_WRITE,
296 /** Exit - DRx read instruction.
297 * @todo not yet implemented. */
298 DBGFEVENT_EXIT_DRX_READ,
299 /** Exit - DRx write instruction.
300 * @todo not yet implemented. */
301 DBGFEVENT_EXIT_DRx_WRITE,
302 /** Exit - PAUSE instruction (not in raw-mode).
303 * @todo not yet implemented. */
304 DBGFEVENT_EXIT_PAUSE,
305 /** Exit - XSETBV instruction.
306 * @todo not yet implemented. */
307 DBGFEVENT_EXIT_XSETBV,
308 /** Exit - VMCALL (intel) or VMMCALL (AMD) instruction.
309 * @todo not yet implemented. */
310 DBGFEVENT_EXIT_VMM_CALL,
311 /** Exit - VT-x VMCLEAR instruction.
312 * @todo not yet implemented. */
313 DBGFEVENT_EXIT_VTX_VMCLEAR,
314 /** Exit - VT-x VMLAUNCH instruction.
315 * @todo not yet implemented. */
316 DBGFEVENT_EXIT_VTX_VMLAUNCH,
317 /** Exit - VT-x VMPTRLD instruction.
318 * @todo not yet implemented. */
319 DBGFEVENT_EXIT_VTX_VMPTRLD,
320 /** Exit - VT-x VMPTRST instruction.
321 * @todo not yet implemented. */
322 DBGFEVENT_EXIT_VTX_VMPTRST,
323 /** Exit - VT-x VMREAD instruction.
324 * @todo not yet implemented. */
325 DBGFEVENT_EXIT_VTX_VMREAD,
326 /** Exit - VT-x VMRESUME instruction.
327 * @todo not yet implemented. */
328 DBGFEVENT_EXIT_VTX_VMRESUME,
329 /** Exit - VT-x VMWRITE instruction.
330 * @todo not yet implemented. */
331 DBGFEVENT_EXIT_VTX_VMWRITE,
332 /** Exit - VT-x VMXOFF instruction.
333 * @todo not yet implemented. */
334 DBGFEVENT_EXIT_VTX_VMXOFF,
335 /** Exit - VT-x VMXON instruction.
336 * @todo not yet implemented. */
337 DBGFEVENT_EXIT_VTX_VMXON,
338 /** Exit - VT-x VMFUNC instruction.
339 * @todo not yet implemented. */
340 DBGFEVENT_EXIT_VTX_VMFUNC,
341 /** Exit - AMD-V VMRUN instruction.
342 * @todo not yet implemented. */
343 DBGFEVENT_EXIT_SVM_VMRUN,
344 /** Exit - AMD-V VMLOAD instruction.
345 * @todo not yet implemented. */
346 DBGFEVENT_EXIT_SVM_VMLOAD,
347 /** Exit - AMD-V VMSAVE instruction.
348 * @todo not yet implemented. */
349 DBGFEVENT_EXIT_SVM_VMSAVE,
350 /** Exit - AMD-V STGI instruction.
351 * @todo not yet implemented. */
352 DBGFEVENT_EXIT_SVM_STGI,
353 /** Exit - AMD-V CLGI instruction.
354 * @todo not yet implemented. */
355 DBGFEVENT_EXIT_SVM_CLGI,
356
357 /** End of valid event values. */
358 DBGFEVENT_END,
359 /** The usual 32-bit hack. */
360 DBGFEVENT_32BIT_HACK = 0x7fffffff
361} DBGFEVENTTYPE;
362AssertCompile(DBGFEVENT_XCPT_LAST - DBGFEVENT_XCPT_FIRST == 0x1f);
363
364/**
365 * The context of an event.
366 */
367typedef enum DBGFEVENTCTX
368{
369 /** The usual invalid entry. */
370 DBGFEVENTCTX_INVALID = 0,
371 /** Raw mode. */
372 DBGFEVENTCTX_RAW,
373 /** Recompiled mode. */
374 DBGFEVENTCTX_REM,
375 /** VMX / AVT mode. */
376 DBGFEVENTCTX_HM,
377 /** Hypervisor context. */
378 DBGFEVENTCTX_HYPER,
379 /** Other mode */
380 DBGFEVENTCTX_OTHER,
381
382 /** The usual 32-bit hack */
383 DBGFEVENTCTX_32BIT_HACK = 0x7fffffff
384} DBGFEVENTCTX;
385
386/**
387 * VMM Debug Event.
388 */
389typedef struct DBGFEVENT
390{
391 /** Type. */
392 DBGFEVENTTYPE enmType;
393 /** Context */
394 DBGFEVENTCTX enmCtx;
395 /** Type specific data. */
396 union
397 {
398 /** Fatal error details. */
399 struct
400 {
401 /** The GC return code. */
402 int rc;
403 } FatalError;
404
405 /** Source location. */
406 struct
407 {
408 /** File name. */
409 R3PTRTYPE(const char *) pszFile;
410 /** Function name. */
411 R3PTRTYPE(const char *) pszFunction;
412 /** Message. */
413 R3PTRTYPE(const char *) pszMessage;
414 /** Line number. */
415 unsigned uLine;
416 } Src;
417
418 /** Assertion messages. */
419 struct
420 {
421 /** The first message. */
422 R3PTRTYPE(const char *) pszMsg1;
423 /** The second message. */
424 R3PTRTYPE(const char *) pszMsg2;
425 } Assert;
426
427 /** Breakpoint. */
428 struct DBGFEVENTBP
429 {
430 /** The identifier of the breakpoint which was hit. */
431 RTUINT iBp;
432 } Bp;
433 /** Padding for ensuring that the structure is 8 byte aligned. */
434 uint64_t au64Padding[4];
435 } u;
436} DBGFEVENT;
437/** Pointer to VMM Debug Event. */
438typedef DBGFEVENT *PDBGFEVENT;
439/** Pointer to const VMM Debug Event. */
440typedef const DBGFEVENT *PCDBGFEVENT;
441
442#ifdef IN_RING3 /* The event API only works in ring-3. */
443
444/** @def DBGFSTOP
445 * Stops the debugger raising a DBGFEVENT_DEVELOPER_STOP event.
446 *
447 * @returns VBox status code which must be propagated up to EM if not VINF_SUCCESS.
448 * @param pVM The cross context VM structure.
449 */
450# ifdef VBOX_STRICT
451# define DBGFSTOP(pVM) DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
452# else
453# define DBGFSTOP(pVM) VINF_SUCCESS
454# endif
455
456VMMR3_INT_DECL(int) DBGFR3Init(PVM pVM);
457VMMR3_INT_DECL(int) DBGFR3Term(PVM pVM);
458VMMR3_INT_DECL(void) DBGFR3PowerOff(PVM pVM);
459VMMR3_INT_DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta);
460VMMR3_INT_DECL(int) DBGFR3VMMForcedAction(PVM pVM);
461VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent);
462VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
463 const char *pszFunction, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 7);
464VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
465 const char *pszFunction, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 0);
466VMMR3_INT_DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2);
467VMMR3_INT_DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent);
468VMMR3_INT_DECL(int) DBGFR3PrgStep(PVMCPU pVCpu);
469
470VMMR3DECL(int) DBGFR3Attach(PUVM pUVM);
471VMMR3DECL(int) DBGFR3Detach(PUVM pUVM);
472VMMR3DECL(int) DBGFR3EventWait(PUVM pUVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent);
473VMMR3DECL(int) DBGFR3Halt(PUVM pUVM);
474VMMR3DECL(bool) DBGFR3IsHalted(PUVM pUVM);
475VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM);
476VMMR3DECL(int) DBGFR3Resume(PUVM pUVM);
477VMMR3DECL(int) DBGFR3Step(PUVM pUVM, VMCPUID idCpu);
478VMMR3DECL(int) DBGFR3InjectNMI(PUVM pUVM, VMCPUID idCpu);
479
480#endif /* IN_RING3 */
481
482
483
484/** Breakpoint type. */
485typedef enum DBGFBPTYPE
486{
487 /** Free breakpoint entry. */
488 DBGFBPTYPE_FREE = 0,
489 /** Debug register. */
490 DBGFBPTYPE_REG,
491 /** INT 3 instruction. */
492 DBGFBPTYPE_INT3,
493 /** Recompiler. */
494 DBGFBPTYPE_REM,
495 /** ensure 32-bit size. */
496 DBGFBPTYPE_32BIT_HACK = 0x7fffffff
497} DBGFBPTYPE;
498
499
500/**
501 * A Breakpoint.
502 */
503typedef struct DBGFBP
504{
505 /** The number of breakpoint hits. */
506 uint64_t cHits;
507 /** The hit number which starts to trigger the breakpoint. */
508 uint64_t iHitTrigger;
509 /** The hit number which stops triggering the breakpoint (disables it).
510 * Use ~(uint64_t)0 if it should never stop. */
511 uint64_t iHitDisable;
512 /** The Flat GC address of the breakpoint.
513 * (PC register value if REM type?) */
514 RTGCUINTPTR GCPtr;
515 /** The breakpoint id. */
516 uint32_t iBp;
517 /** The breakpoint status - enabled or disabled. */
518 bool fEnabled;
519
520 /** The breakpoint type. */
521 DBGFBPTYPE enmType;
522
523#if GC_ARCH_BITS == 64
524 uint32_t u32Padding;
525#endif
526
527 /** Union of type specific data. */
528 union
529 {
530 /** Debug register data. */
531 struct DBGFBPREG
532 {
533 /** The debug register number. */
534 uint8_t iReg;
535 /** The access type (one of the X86_DR7_RW_* value). */
536 uint8_t fType;
537 /** The access size. */
538 uint8_t cb;
539 } Reg;
540 /** Recompiler breakpoint data. */
541 struct DBGFBPINT3
542 {
543 /** The byte value we replaced by the INT 3 instruction. */
544 uint8_t bOrg;
545 } Int3;
546
547 /** Recompiler breakpoint data. */
548 struct DBGFBPREM
549 {
550 /** nothing yet */
551 uint8_t fDummy;
552 } Rem;
553 /** Paddind to ensure that the size is identical on win32 and linux. */
554 uint64_t u64Padding;
555 } u;
556} DBGFBP;
557
558/** Pointer to a breakpoint. */
559typedef DBGFBP *PDBGFBP;
560/** Pointer to a const breakpoint. */
561typedef const DBGFBP *PCDBGFBP;
562
563#ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */
564VMMR3DECL(int) DBGFR3BpSet(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
565VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
566 uint8_t fType, uint8_t cb, uint32_t *piBp);
567VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
568VMMR3DECL(int) DBGFR3BpClear(PUVM pUVM, uint32_t iBp);
569VMMR3DECL(int) DBGFR3BpEnable(PUVM pUVM, uint32_t iBp);
570VMMR3DECL(int) DBGFR3BpDisable(PUVM pUVM, uint32_t iBp);
571
572/**
573 * Breakpoint enumeration callback function.
574 *
575 * @returns VBox status code. Any failure will stop the enumeration.
576 * @param pUVM The user mode VM handle.
577 * @param pvUser The user argument.
578 * @param pBp Pointer to the breakpoint information. (readonly)
579 */
580typedef DECLCALLBACK(int) FNDBGFBPENUM(PUVM pUVM, void *pvUser, PCDBGFBP pBp);
581/** Pointer to a breakpoint enumeration callback function. */
582typedef FNDBGFBPENUM *PFNDBGFBPENUM;
583
584VMMR3DECL(int) DBGFR3BpEnum(PUVM pUVM, PFNDBGFBPENUM pfnCallback, void *pvUser);
585#endif /* IN_RING3 */
586
587VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM);
588VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM);
589VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM);
590VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM);
591VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM);
592VMM_INT_DECL(bool) DBGFBpIsHwArmed(PVM pVM);
593VMM_INT_DECL(bool) DBGFBpIsHwIoArmed(PVM pVM);
594VMM_INT_DECL(bool) DBGFIsStepping(PVMCPU pVCpu);
595VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue);
596
597
598#ifdef IN_RING3 /* The CPU mode API only works in ring-3. */
599VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu);
600VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM);
601VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu);
602#endif
603
604
605
606#ifdef IN_RING3 /* The info callbacks API only works in ring-3. */
607
608/**
609 * Info helper callback structure.
610 */
611typedef struct DBGFINFOHLP
612{
613 /**
614 * Print formatted string.
615 *
616 * @param pHlp Pointer to this structure.
617 * @param pszFormat The format string.
618 * @param ... Arguments.
619 */
620 DECLCALLBACKMEMBER(void, pfnPrintf)(PCDBGFINFOHLP pHlp, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3);
621
622 /**
623 * Print formatted string.
624 *
625 * @param pHlp Pointer to this structure.
626 * @param pszFormat The format string.
627 * @param args Argument list.
628 */
629 DECLCALLBACKMEMBER(void, pfnPrintfV)(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(2, 0);
630} DBGFINFOHLP;
631
632
633/**
634 * Info handler, device version.
635 *
636 * @param pDevIns The device instance which registered the info.
637 * @param pHlp Callback functions for doing output.
638 * @param pszArgs Argument string. Optional and specific to the handler.
639 */
640typedef DECLCALLBACK(void) FNDBGFHANDLERDEV(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
641/** Pointer to a FNDBGFHANDLERDEV function. */
642typedef FNDBGFHANDLERDEV *PFNDBGFHANDLERDEV;
643
644/**
645 * Info handler, USB device version.
646 *
647 * @param pUsbIns The USB device instance which registered the info.
648 * @param pHlp Callback functions for doing output.
649 * @param pszArgs Argument string. Optional and specific to the handler.
650 */
651typedef DECLCALLBACK(void) FNDBGFHANDLERUSB(PPDMUSBINS pUsbIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
652/** Pointer to a FNDBGFHANDLERUSB function. */
653typedef FNDBGFHANDLERUSB *PFNDBGFHANDLERUSB;
654
655/**
656 * Info handler, driver version.
657 *
658 * @param pDrvIns The driver instance which registered the info.
659 * @param pHlp Callback functions for doing output.
660 * @param pszArgs Argument string. Optional and specific to the handler.
661 */
662typedef DECLCALLBACK(void) FNDBGFHANDLERDRV(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
663/** Pointer to a FNDBGFHANDLERDRV function. */
664typedef FNDBGFHANDLERDRV *PFNDBGFHANDLERDRV;
665
666/**
667 * Info handler, internal version.
668 *
669 * @param pVM The cross context VM structure.
670 * @param pHlp Callback functions for doing output.
671 * @param pszArgs Argument string. Optional and specific to the handler.
672 */
673typedef DECLCALLBACK(void) FNDBGFHANDLERINT(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
674/** Pointer to a FNDBGFHANDLERINT function. */
675typedef FNDBGFHANDLERINT *PFNDBGFHANDLERINT;
676
677/**
678 * Info handler, external version.
679 *
680 * @param pvUser User argument.
681 * @param pHlp Callback functions for doing output.
682 * @param pszArgs Argument string. Optional and specific to the handler.
683 */
684typedef DECLCALLBACK(void) FNDBGFHANDLEREXT(void *pvUser, PCDBGFINFOHLP pHlp, const char *pszArgs);
685/** Pointer to a FNDBGFHANDLEREXT function. */
686typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT;
687
688
689/** @name Flags for the info registration functions.
690 * @{ */
691/** The handler must run on the EMT. */
692#define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0)
693/** @} */
694
695VMMR3_INT_DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
696VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
697VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
698VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
699VMMR3DECL(int) DBGFR3InfoRegisterExternal(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
700VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName);
701VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName);
702VMMR3_INT_DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName);
703VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PUVM pUVM, const char *pszName);
704VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
705VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
706VMMR3DECL(int) DBGFR3InfoLogRel(PUVM pUVM, const char *pszName, const char *pszArgs);
707VMMR3DECL(int) DBGFR3InfoStdErr(PUVM pUVM, const char *pszName, const char *pszArgs);
708VMMR3_INT_DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat,
709 const char *pszSepFmt, PCDBGFINFOHLP pHlp);
710
711/** @def DBGFR3_INFO_LOG
712 * Display a piece of info writing to the log if enabled.
713 *
714 * @param a_pVM The shared VM handle.
715 * @param a_pszName The identifier of the info to display.
716 * @param a_pszArgs Arguments to the info handler.
717 */
718#ifdef LOG_ENABLED
719# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) \
720 do { \
721 if (LogIsEnabled()) \
722 DBGFR3Info((a_pVM)->pUVM, a_pszName, a_pszArgs, NULL); \
723 } while (0)
724#else
725# define DBGFR3_INFO_LOG(a_pVM, a_pszName, a_pszArgs) do { } while (0)
726#endif
727
728/**
729 * Enumeration callback for use with DBGFR3InfoEnum.
730 *
731 * @returns VBox status code.
732 * A status code indicating failure will end the enumeration
733 * and DBGFR3InfoEnum will return with that status code.
734 * @param pUVM The user mode VM handle.
735 * @param pszName Info identifier name.
736 * @param pszDesc The description.
737 */
738typedef DECLCALLBACK(int) FNDBGFINFOENUM(PUVM pUVM, const char *pszName, const char *pszDesc, void *pvUser);
739/** Pointer to a FNDBGFINFOENUM function. */
740typedef FNDBGFINFOENUM *PFNDBGFINFOENUM;
741
742VMMR3DECL(int) DBGFR3InfoEnum(PUVM pUVM, PFNDBGFINFOENUM pfnCallback, void *pvUser);
743VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void);
744VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void);
745
746#endif /* IN_RING3 */
747
748
749#ifdef IN_RING3 /* The log contrl API only works in ring-3. */
750VMMR3DECL(int) DBGFR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings);
751VMMR3DECL(int) DBGFR3LogModifyFlags(PUVM pUVM, const char *pszFlagSettings);
752VMMR3DECL(int) DBGFR3LogModifyDestinations(PUVM pUVM, const char *pszDestSettings);
753#endif /* IN_RING3 */
754
755#ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */
756
757/** Max length (including '\\0') of a symbol name. */
758#define DBGF_SYMBOL_NAME_LENGTH 512
759
760/**
761 * Debug symbol.
762 */
763typedef struct DBGFSYMBOL
764{
765 /** Symbol value (address). */
766 RTGCUINTPTR Value;
767 /** Symbol size. */
768 uint32_t cb;
769 /** Symbol Flags. (reserved). */
770 uint32_t fFlags;
771 /** Symbol name. */
772 char szName[DBGF_SYMBOL_NAME_LENGTH];
773} DBGFSYMBOL;
774/** Pointer to debug symbol. */
775typedef DBGFSYMBOL *PDBGFSYMBOL;
776/** Pointer to const debug symbol. */
777typedef const DBGFSYMBOL *PCDBGFSYMBOL;
778
779/**
780 * Debug line number information.
781 */
782typedef struct DBGFLINE
783{
784 /** Address. */
785 RTGCUINTPTR Address;
786 /** Line number. */
787 uint32_t uLineNo;
788 /** Filename. */
789 char szFilename[260];
790} DBGFLINE;
791/** Pointer to debug line number. */
792typedef DBGFLINE *PDBGFLINE;
793/** Pointer to const debug line number. */
794typedef const DBGFLINE *PCDBGFLINE;
795
796/** @name Address spaces aliases.
797 * @{ */
798/** The guest global address space. */
799#define DBGF_AS_GLOBAL ((RTDBGAS)-1)
800/** The guest kernel address space.
801 * This is usually resolves to the same as DBGF_AS_GLOBAL. */
802#define DBGF_AS_KERNEL ((RTDBGAS)-2)
803/** The physical address space. */
804#define DBGF_AS_PHYS ((RTDBGAS)-3)
805/** Raw-mode context. */
806#define DBGF_AS_RC ((RTDBGAS)-4)
807/** Ring-0 context. */
808#define DBGF_AS_R0 ((RTDBGAS)-5)
809/** Raw-mode context and then global guest context.
810 * When used for looking up information, it works as if the call was first made
811 * with DBGF_AS_RC and then on failure with DBGF_AS_GLOBAL. When called for
812 * making address space changes, it works as if DBGF_AS_RC was used. */
813#define DBGF_AS_RC_AND_GC_GLOBAL ((RTDBGAS)-6)
814
815/** The first special one. */
816#define DBGF_AS_FIRST DBGF_AS_RC_AND_GC_GLOBAL
817/** The last special one. */
818#define DBGF_AS_LAST DBGF_AS_GLOBAL
819#endif
820/** The number of special address space handles. */
821#define DBGF_AS_COUNT (6U)
822#ifdef IN_RING3
823/** Converts an alias handle to an array index. */
824#define DBGF_AS_ALIAS_2_INDEX(hAlias) \
825 ( (uintptr_t)(hAlias) - (uintptr_t)DBGF_AS_FIRST )
826/** Predicat macro that check if the specified handle is an alias. */
827#define DBGF_AS_IS_ALIAS(hAlias) \
828 ( DBGF_AS_ALIAS_2_INDEX(hAlias) < DBGF_AS_COUNT )
829/** Predicat macro that check if the specified alias is a fixed one or not. */
830#define DBGF_AS_IS_FIXED_ALIAS(hAlias) \
831 ( DBGF_AS_ALIAS_2_INDEX(hAlias) < (uintptr_t)DBGF_AS_PHYS - (uintptr_t)DBGF_AS_FIRST + 1U )
832
833/** @} */
834
835VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM);
836
837VMMR3DECL(int) DBGFR3AsAdd(PUVM pUVM, RTDBGAS hDbgAs, RTPROCESS ProcId);
838VMMR3DECL(int) DBGFR3AsDelete(PUVM pUVM, RTDBGAS hDbgAs);
839VMMR3DECL(int) DBGFR3AsSetAlias(PUVM pUVM, RTDBGAS hAlias, RTDBGAS hAliasFor);
840VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PUVM pUVM, RTDBGAS hAlias);
841VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias);
842VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName);
843VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PUVM pUVM, RTPROCESS ProcId);
844
845VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName,
846 RTLDRARCH enmArch, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
847VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags);
848VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
849VMMR3DECL(int) DBGFR3AsUnlinkModuleByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszModName);
850
851VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
852 PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
853VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t Flags,
854 PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
855VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
856
857VMMR3DECL(int) DBGFR3AsLineByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
858 PRTGCINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod);
859VMMR3DECL(PRTDBGLINE) DBGFR3AsLineByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
860 PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
861
862#endif /* IN_RING3 */
863
864#ifdef IN_RING3 /* The stack API only works in ring-3. */
865
866/**
867 * Return type.
868 */
869typedef enum DBGFRETRUNTYPE
870{
871 /** The usual invalid 0 value. */
872 DBGFRETURNTYPE_INVALID = 0,
873 /** Near 16-bit return. */
874 DBGFRETURNTYPE_NEAR16,
875 /** Near 32-bit return. */
876 DBGFRETURNTYPE_NEAR32,
877 /** Near 64-bit return. */
878 DBGFRETURNTYPE_NEAR64,
879 /** Far 16:16 return. */
880 DBGFRETURNTYPE_FAR16,
881 /** Far 16:32 return. */
882 DBGFRETURNTYPE_FAR32,
883 /** Far 16:64 return. */
884 DBGFRETURNTYPE_FAR64,
885 /** 16-bit iret return (e.g. real or 286 protect mode). */
886 DBGFRETURNTYPE_IRET16,
887 /** 32-bit iret return. */
888 DBGFRETURNTYPE_IRET32,
889 /** 32-bit iret return. */
890 DBGFRETURNTYPE_IRET32_PRIV,
891 /** 32-bit iret return to V86 mode. */
892 DBGFRETURNTYPE_IRET32_V86,
893 /** @todo 64-bit iret return. */
894 DBGFRETURNTYPE_IRET64,
895 /** The end of the valid return types. */
896 DBGFRETURNTYPE_END,
897 /** The usual 32-bit blowup. */
898 DBGFRETURNTYPE_32BIT_HACK = 0x7fffffff
899} DBGFRETURNTYPE;
900
901/**
902 * Figures the size of the return state on the stack.
903 *
904 * @returns number of bytes. 0 if invalid parameter.
905 * @param enmRetType The type of return.
906 */
907DECLINLINE(unsigned) DBGFReturnTypeSize(DBGFRETURNTYPE enmRetType)
908{
909 switch (enmRetType)
910 {
911 case DBGFRETURNTYPE_NEAR16: return 2;
912 case DBGFRETURNTYPE_NEAR32: return 4;
913 case DBGFRETURNTYPE_NEAR64: return 8;
914 case DBGFRETURNTYPE_FAR16: return 4;
915 case DBGFRETURNTYPE_FAR32: return 4;
916 case DBGFRETURNTYPE_FAR64: return 8;
917 case DBGFRETURNTYPE_IRET16: return 6;
918 case DBGFRETURNTYPE_IRET32: return 4*3;
919 case DBGFRETURNTYPE_IRET32_PRIV: return 4*5;
920 case DBGFRETURNTYPE_IRET32_V86: return 4*9;
921 case DBGFRETURNTYPE_IRET64:
922 default:
923 return 0;
924 }
925}
926
927
928/** Pointer to stack frame info. */
929typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
930/** Pointer to const stack frame info. */
931typedef struct DBGFSTACKFRAME const *PCDBGFSTACKFRAME;
932/**
933 * Info about a stack frame.
934 */
935typedef struct DBGFSTACKFRAME
936{
937 /** Frame number. */
938 uint32_t iFrame;
939 /** Frame flags. */
940 uint32_t fFlags;
941 /** The frame address.
942 * The off member is [e|r]bp and the Sel member is ss. */
943 DBGFADDRESS AddrFrame;
944 /** The stack address of the frame.
945 * The off member is [e|r]sp and the Sel member is ss. */
946 DBGFADDRESS AddrStack;
947 /** The program counter (PC) address of the frame.
948 * The off member is [e|r]ip and the Sel member is cs. */
949 DBGFADDRESS AddrPC;
950 /** Pointer to the symbol nearest the program counter (PC). NULL if not found. */
951 PRTDBGSYMBOL pSymPC;
952 /** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */
953 PRTDBGLINE pLinePC;
954
955 /** The return frame address.
956 * The off member is [e|r]bp and the Sel member is ss. */
957 DBGFADDRESS AddrReturnFrame;
958 /** The return stack address.
959 * The off member is [e|r]sp and the Sel member is ss. */
960 DBGFADDRESS AddrReturnStack;
961 /** The way this frame returns to the next one. */
962 DBGFRETURNTYPE enmReturnType;
963
964 /** The program counter (PC) address which the frame returns to.
965 * The off member is [e|r]ip and the Sel member is cs. */
966 DBGFADDRESS AddrReturnPC;
967 /** Pointer to the symbol nearest the return PC. NULL if not found. */
968 PRTDBGSYMBOL pSymReturnPC;
969 /** Pointer to the linnumber nearest the return PC. NULL if not found. */
970 PRTDBGLINE pLineReturnPC;
971
972 /** 32-bytes of stack arguments. */
973 union
974 {
975 /** 64-bit view */
976 uint64_t au64[4];
977 /** 32-bit view */
978 uint32_t au32[8];
979 /** 16-bit view */
980 uint16_t au16[16];
981 /** 8-bit view */
982 uint8_t au8[32];
983 } Args;
984
985 /** Pointer to the next frame.
986 * Might not be used in some cases, so consider it internal. */
987 PCDBGFSTACKFRAME pNextInternal;
988 /** Pointer to the first frame.
989 * Might not be used in some cases, so consider it internal. */
990 PCDBGFSTACKFRAME pFirstInternal;
991} DBGFSTACKFRAME;
992
993/** @name DBGFSTACKFRAME Flags.
994 * @{ */
995/** Set if the content of the frame is filled in by DBGFR3StackWalk() and can be used
996 * to construct the next frame. */
997# define DBGFSTACKFRAME_FLAGS_ALL_VALID RT_BIT(0)
998/** This is the last stack frame we can read.
999 * This flag is not set if the walk stop because of max dept or recursion. */
1000# define DBGFSTACKFRAME_FLAGS_LAST RT_BIT(1)
1001/** This is the last record because we detected a loop. */
1002# define DBGFSTACKFRAME_FLAGS_LOOP RT_BIT(2)
1003/** This is the last record because we reached the maximum depth. */
1004# define DBGFSTACKFRAME_FLAGS_MAX_DEPTH RT_BIT(3)
1005/** 16-bit frame. */
1006# define DBGFSTACKFRAME_FLAGS_16BIT RT_BIT(4)
1007/** 32-bit frame. */
1008# define DBGFSTACKFRAME_FLAGS_32BIT RT_BIT(5)
1009/** 64-bit frame. */
1010# define DBGFSTACKFRAME_FLAGS_64BIT RT_BIT(6)
1011/** @} */
1012
1013/** @name DBGFCODETYPE
1014 * @{ */
1015typedef enum DBGFCODETYPE
1016{
1017 /** The usual invalid 0 value. */
1018 DBGFCODETYPE_INVALID = 0,
1019 /** Stack walk for guest code. */
1020 DBGFCODETYPE_GUEST,
1021 /** Stack walk for hypervisor code. */
1022 DBGFCODETYPE_HYPER,
1023 /** Stack walk for ring 0 code. */
1024 DBGFCODETYPE_RING0,
1025 /** The usual 32-bit blowup. */
1026 DBGFCODETYPE_32BIT_HACK = 0x7fffffff
1027} DBGFCODETYPE;
1028/** @} */
1029
1030VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType,
1031 PCDBGFSTACKFRAME *ppFirstFrame);
1032VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
1033 PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC,
1034 DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
1035VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent);
1036VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
1037
1038#endif /* IN_RING3 */
1039
1040
1041#ifdef IN_RING3 /* The disassembly API only works in ring-3. */
1042
1043/** @name Flags to pass to DBGFR3DisasInstrEx().
1044 * @{ */
1045/** Disassemble the current guest instruction, with annotations. */
1046#define DBGF_DISAS_FLAGS_CURRENT_GUEST RT_BIT(0)
1047/** Disassemble the current hypervisor instruction, with annotations. */
1048#define DBGF_DISAS_FLAGS_CURRENT_HYPER RT_BIT(1)
1049/** No annotations for current context. */
1050#define DBGF_DISAS_FLAGS_NO_ANNOTATION RT_BIT(2)
1051/** No symbol lookup. */
1052#define DBGF_DISAS_FLAGS_NO_SYMBOLS RT_BIT(3)
1053/** No instruction bytes. */
1054#define DBGF_DISAS_FLAGS_NO_BYTES RT_BIT(4)
1055/** No address in the output. */
1056#define DBGF_DISAS_FLAGS_NO_ADDRESS RT_BIT(5)
1057/** Probably a hypervisor instruction. */
1058#define DBGF_DISAS_FLAGS_HYPER RT_BIT(6)
1059/** Disassemble original unpatched bytes (PATM). */
1060#define DBGF_DISAS_FLAGS_UNPATCHED_BYTES RT_BIT(7)
1061/** Annotate patched instructions. */
1062#define DBGF_DISAS_FLAGS_ANNOTATE_PATCHED RT_BIT(8)
1063/** Disassemble in the default mode of the specific context. */
1064#define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000)
1065/** Disassemble in 16-bit mode. */
1066#define DBGF_DISAS_FLAGS_16BIT_MODE UINT32_C(0x10000000)
1067/** Disassemble in 16-bit mode with real mode address translation. */
1068#define DBGF_DISAS_FLAGS_16BIT_REAL_MODE UINT32_C(0x20000000)
1069/** Disassemble in 32-bit mode. */
1070#define DBGF_DISAS_FLAGS_32BIT_MODE UINT32_C(0x30000000)
1071/** Disassemble in 64-bit mode. */
1072#define DBGF_DISAS_FLAGS_64BIT_MODE UINT32_C(0x40000000)
1073/** The disassembly mode mask. */
1074#define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000)
1075/** Mask containing the valid flags. */
1076#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x700001ff)
1077/** @} */
1078
1079/** Special flat selector. */
1080#define DBGF_SEL_FLAT 1
1081
1082VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
1083 char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr);
1084VMMR3_INT_DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput);
1085VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix);
1086
1087/** @def DBGFR3_DISAS_INSTR_CUR_LOG
1088 * Disassembles the current guest context instruction and writes it to the log.
1089 * All registers and data will be displayed. Addresses will be attempted resolved to symbols.
1090 */
1091#ifdef LOG_ENABLED
1092# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) \
1093 do { \
1094 if (LogIsEnabled()) \
1095 DBGFR3DisasInstrCurrentLogInternal(pVCpu, pszPrefix); \
1096 } while (0)
1097#else
1098# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) do { } while (0)
1099#endif
1100
1101VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix);
1102
1103/** @def DBGFR3_DISAS_INSTR_LOG
1104 * Disassembles the specified guest context instruction and writes it to the log.
1105 * Addresses will be attempted resolved to symbols.
1106 * @thread Any EMT.
1107 */
1108# ifdef LOG_ENABLED
1109# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) \
1110 do { \
1111 if (LogIsEnabled()) \
1112 DBGFR3DisasInstrLogInternal(pVCpu, Sel, GCPtr, pszPrefix); \
1113 } while (0)
1114# else
1115# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0)
1116# endif
1117#endif
1118
1119
1120#ifdef IN_RING3
1121VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign,
1122 const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress);
1123VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
1124VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
1125VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead);
1126#endif
1127
1128
1129/** @name Flags for DBGFR3PagingDumpEx, PGMR3DumpHierarchyHCEx and
1130 * PGMR3DumpHierarchyGCEx
1131 * @{ */
1132/** The CR3 from the current CPU state. */
1133#define DBGFPGDMP_FLAGS_CURRENT_CR3 RT_BIT_32(0)
1134/** The current CPU paging mode (PSE, PAE, LM, EPT, NX). */
1135#define DBGFPGDMP_FLAGS_CURRENT_MODE RT_BIT_32(1)
1136/** Whether PSE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
1137 * Same value as X86_CR4_PSE. */
1138#define DBGFPGDMP_FLAGS_PSE RT_BIT_32(4) /* */
1139/** Whether PAE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
1140 * Same value as X86_CR4_PAE. */
1141#define DBGFPGDMP_FLAGS_PAE RT_BIT_32(5) /* */
1142/** Whether LME is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
1143 * Same value as MSR_K6_EFER_LME. */
1144#define DBGFPGDMP_FLAGS_LME RT_BIT_32(8)
1145/** Whether nested paging is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
1146#define DBGFPGDMP_FLAGS_NP RT_BIT_32(9)
1147/** Whether extended nested page tables are enabled
1148 * (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
1149#define DBGFPGDMP_FLAGS_EPT RT_BIT_32(10)
1150/** Whether no-execution is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
1151 * Same value as MSR_K6_EFER_NXE. */
1152#define DBGFPGDMP_FLAGS_NXE RT_BIT_32(11)
1153/** Whether to print the CR3. */
1154#define DBGFPGDMP_FLAGS_PRINT_CR3 RT_BIT_32(27)
1155/** Whether to print the header. */
1156#define DBGFPGDMP_FLAGS_HEADER RT_BIT_32(28)
1157/** Whether to dump additional page information. */
1158#define DBGFPGDMP_FLAGS_PAGE_INFO RT_BIT_32(29)
1159/** Dump the shadow tables if set.
1160 * Cannot be used together with DBGFPGDMP_FLAGS_GUEST. */
1161#define DBGFPGDMP_FLAGS_SHADOW RT_BIT_32(30)
1162/** Dump the guest tables if set.
1163 * Cannot be used together with DBGFPGDMP_FLAGS_SHADOW. */
1164#define DBGFPGDMP_FLAGS_GUEST RT_BIT_32(31)
1165/** Mask of valid bits. */
1166#define DBGFPGDMP_FLAGS_VALID_MASK UINT32_C(0xf8000f33)
1167/** The mask of bits controlling the paging mode. */
1168#define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32)
1169/** @} */
1170VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
1171 uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
1172
1173
1174/** @name DBGFR3SelQueryInfo flags.
1175 * @{ */
1176/** Get the info from the guest descriptor table. */
1177#define DBGFSELQI_FLAGS_DT_GUEST UINT32_C(0)
1178/** Get the info from the shadow descriptor table.
1179 * Only works in raw-mode. */
1180#define DBGFSELQI_FLAGS_DT_SHADOW UINT32_C(1)
1181/** If currently executing in in 64-bit mode, blow up data selectors. */
1182#define DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE UINT32_C(2)
1183/** @} */
1184VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo);
1185
1186
1187/**
1188 * Register identifiers.
1189 */
1190typedef enum DBGFREG
1191{
1192 /* General purpose registers: */
1193 DBGFREG_AL = 0,
1194 DBGFREG_AX = DBGFREG_AL,
1195 DBGFREG_EAX = DBGFREG_AL,
1196 DBGFREG_RAX = DBGFREG_AL,
1197
1198 DBGFREG_CL,
1199 DBGFREG_CX = DBGFREG_CL,
1200 DBGFREG_ECX = DBGFREG_CL,
1201 DBGFREG_RCX = DBGFREG_CL,
1202
1203 DBGFREG_DL,
1204 DBGFREG_DX = DBGFREG_DL,
1205 DBGFREG_EDX = DBGFREG_DL,
1206 DBGFREG_RDX = DBGFREG_DL,
1207
1208 DBGFREG_BL,
1209 DBGFREG_BX = DBGFREG_BL,
1210 DBGFREG_EBX = DBGFREG_BL,
1211 DBGFREG_RBX = DBGFREG_BL,
1212
1213 DBGFREG_SPL,
1214 DBGFREG_SP = DBGFREG_SPL,
1215 DBGFREG_ESP = DBGFREG_SPL,
1216 DBGFREG_RSP = DBGFREG_SPL,
1217
1218 DBGFREG_BPL,
1219 DBGFREG_BP = DBGFREG_BPL,
1220 DBGFREG_EBP = DBGFREG_BPL,
1221 DBGFREG_RBP = DBGFREG_BPL,
1222
1223 DBGFREG_SIL,
1224 DBGFREG_SI = DBGFREG_SIL,
1225 DBGFREG_ESI = DBGFREG_SIL,
1226 DBGFREG_RSI = DBGFREG_SIL,
1227
1228 DBGFREG_DIL,
1229 DBGFREG_DI = DBGFREG_DIL,
1230 DBGFREG_EDI = DBGFREG_DIL,
1231 DBGFREG_RDI = DBGFREG_DIL,
1232
1233 DBGFREG_R8,
1234 DBGFREG_R8B = DBGFREG_R8,
1235 DBGFREG_R8W = DBGFREG_R8,
1236 DBGFREG_R8D = DBGFREG_R8,
1237
1238 DBGFREG_R9,
1239 DBGFREG_R9B = DBGFREG_R9,
1240 DBGFREG_R9W = DBGFREG_R9,
1241 DBGFREG_R9D = DBGFREG_R9,
1242
1243 DBGFREG_R10,
1244 DBGFREG_R10B = DBGFREG_R10,
1245 DBGFREG_R10W = DBGFREG_R10,
1246 DBGFREG_R10D = DBGFREG_R10,
1247
1248 DBGFREG_R11,
1249 DBGFREG_R11B = DBGFREG_R11,
1250 DBGFREG_R11W = DBGFREG_R11,
1251 DBGFREG_R11D = DBGFREG_R11,
1252
1253 DBGFREG_R12,
1254 DBGFREG_R12B = DBGFREG_R12,
1255 DBGFREG_R12W = DBGFREG_R12,
1256 DBGFREG_R12D = DBGFREG_R12,
1257
1258 DBGFREG_R13,
1259 DBGFREG_R13B = DBGFREG_R13,
1260 DBGFREG_R13W = DBGFREG_R13,
1261 DBGFREG_R13D = DBGFREG_R13,
1262
1263 DBGFREG_R14,
1264 DBGFREG_R14B = DBGFREG_R14,
1265 DBGFREG_R14W = DBGFREG_R14,
1266 DBGFREG_R14D = DBGFREG_R14,
1267
1268 DBGFREG_R15,
1269 DBGFREG_R15B = DBGFREG_R15,
1270 DBGFREG_R15W = DBGFREG_R15,
1271 DBGFREG_R15D = DBGFREG_R15,
1272
1273 /* Segments and other special registers: */
1274 DBGFREG_CS,
1275 DBGFREG_CS_ATTR,
1276 DBGFREG_CS_BASE,
1277 DBGFREG_CS_LIMIT,
1278
1279 DBGFREG_DS,
1280 DBGFREG_DS_ATTR,
1281 DBGFREG_DS_BASE,
1282 DBGFREG_DS_LIMIT,
1283
1284 DBGFREG_ES,
1285 DBGFREG_ES_ATTR,
1286 DBGFREG_ES_BASE,
1287 DBGFREG_ES_LIMIT,
1288
1289 DBGFREG_FS,
1290 DBGFREG_FS_ATTR,
1291 DBGFREG_FS_BASE,
1292 DBGFREG_FS_LIMIT,
1293
1294 DBGFREG_GS,
1295 DBGFREG_GS_ATTR,
1296 DBGFREG_GS_BASE,
1297 DBGFREG_GS_LIMIT,
1298
1299 DBGFREG_SS,
1300 DBGFREG_SS_ATTR,
1301 DBGFREG_SS_BASE,
1302 DBGFREG_SS_LIMIT,
1303
1304 DBGFREG_IP,
1305 DBGFREG_EIP = DBGFREG_IP,
1306 DBGFREG_RIP = DBGFREG_IP,
1307
1308 DBGFREG_FLAGS,
1309 DBGFREG_EFLAGS = DBGFREG_FLAGS,
1310 DBGFREG_RFLAGS = DBGFREG_FLAGS,
1311
1312 /* FPU: */
1313 DBGFREG_FCW,
1314 DBGFREG_FSW,
1315 DBGFREG_FTW,
1316 DBGFREG_FOP,
1317 DBGFREG_FPUIP,
1318 DBGFREG_FPUCS,
1319 DBGFREG_FPUDP,
1320 DBGFREG_FPUDS,
1321 DBGFREG_MXCSR,
1322 DBGFREG_MXCSR_MASK,
1323
1324 DBGFREG_ST0,
1325 DBGFREG_ST1,
1326 DBGFREG_ST2,
1327 DBGFREG_ST3,
1328 DBGFREG_ST4,
1329 DBGFREG_ST5,
1330 DBGFREG_ST6,
1331 DBGFREG_ST7,
1332
1333 DBGFREG_MM0,
1334 DBGFREG_MM1,
1335 DBGFREG_MM2,
1336 DBGFREG_MM3,
1337 DBGFREG_MM4,
1338 DBGFREG_MM5,
1339 DBGFREG_MM6,
1340 DBGFREG_MM7,
1341
1342 /* SSE: */
1343 DBGFREG_XMM0,
1344 DBGFREG_XMM1,
1345 DBGFREG_XMM2,
1346 DBGFREG_XMM3,
1347 DBGFREG_XMM4,
1348 DBGFREG_XMM5,
1349 DBGFREG_XMM6,
1350 DBGFREG_XMM7,
1351 DBGFREG_XMM8,
1352 DBGFREG_XMM9,
1353 DBGFREG_XMM10,
1354 DBGFREG_XMM11,
1355 DBGFREG_XMM12,
1356 DBGFREG_XMM13,
1357 DBGFREG_XMM14,
1358 DBGFREG_XMM15,
1359 /** @todo add XMM aliases. */
1360
1361 /* System registers: */
1362 DBGFREG_GDTR_BASE,
1363 DBGFREG_GDTR_LIMIT,
1364 DBGFREG_IDTR_BASE,
1365 DBGFREG_IDTR_LIMIT,
1366 DBGFREG_LDTR,
1367 DBGFREG_LDTR_ATTR,
1368 DBGFREG_LDTR_BASE,
1369 DBGFREG_LDTR_LIMIT,
1370 DBGFREG_TR,
1371 DBGFREG_TR_ATTR,
1372 DBGFREG_TR_BASE,
1373 DBGFREG_TR_LIMIT,
1374
1375 DBGFREG_CR0,
1376 DBGFREG_CR2,
1377 DBGFREG_CR3,
1378 DBGFREG_CR4,
1379 DBGFREG_CR8,
1380
1381 DBGFREG_DR0,
1382 DBGFREG_DR1,
1383 DBGFREG_DR2,
1384 DBGFREG_DR3,
1385 DBGFREG_DR6,
1386 DBGFREG_DR7,
1387
1388 /* MSRs: */
1389 DBGFREG_MSR_IA32_APICBASE,
1390 DBGFREG_MSR_IA32_CR_PAT,
1391 DBGFREG_MSR_IA32_PERF_STATUS,
1392 DBGFREG_MSR_IA32_SYSENTER_CS,
1393 DBGFREG_MSR_IA32_SYSENTER_EIP,
1394 DBGFREG_MSR_IA32_SYSENTER_ESP,
1395 DBGFREG_MSR_IA32_TSC,
1396 DBGFREG_MSR_K6_EFER,
1397 DBGFREG_MSR_K6_STAR,
1398 DBGFREG_MSR_K8_CSTAR,
1399 DBGFREG_MSR_K8_FS_BASE,
1400 DBGFREG_MSR_K8_GS_BASE,
1401 DBGFREG_MSR_K8_KERNEL_GS_BASE,
1402 DBGFREG_MSR_K8_LSTAR,
1403 DBGFREG_MSR_K8_SF_MASK,
1404 DBGFREG_MSR_K8_TSC_AUX,
1405
1406 /** The number of registers to pass to DBGFR3RegQueryAll. */
1407 DBGFREG_ALL_COUNT,
1408
1409 /* Misc aliases that doesn't need be part of the 'all' query: */
1410 DBGFREG_AH = DBGFREG_ALL_COUNT,
1411 DBGFREG_CH,
1412 DBGFREG_DH,
1413 DBGFREG_BH,
1414 DBGFREG_GDTR,
1415 DBGFREG_IDTR,
1416
1417 /** The end of the registers. */
1418 DBGFREG_END,
1419 /** The usual 32-bit type hack. */
1420 DBGFREG_32BIT_HACK = 0x7fffffff
1421} DBGFREG;
1422/** Pointer to a register identifier. */
1423typedef DBGFREG *PDBGFREG;
1424/** Pointer to a const register identifier. */
1425typedef DBGFREG const *PCDBGFREG;
1426
1427/**
1428 * Register value type.
1429 */
1430typedef enum DBGFREGVALTYPE
1431{
1432 DBGFREGVALTYPE_INVALID = 0,
1433 /** Unsigned 8-bit register value. */
1434 DBGFREGVALTYPE_U8,
1435 /** Unsigned 16-bit register value. */
1436 DBGFREGVALTYPE_U16,
1437 /** Unsigned 32-bit register value. */
1438 DBGFREGVALTYPE_U32,
1439 /** Unsigned 64-bit register value. */
1440 DBGFREGVALTYPE_U64,
1441 /** Unsigned 128-bit register value. */
1442 DBGFREGVALTYPE_U128,
1443 /** Long double register value. */
1444 DBGFREGVALTYPE_R80,
1445 /** Descriptor table register value. */
1446 DBGFREGVALTYPE_DTR,
1447 /** End of the valid register value types. */
1448 DBGFREGVALTYPE_END,
1449 /** The usual 32-bit type hack. */
1450 DBGFREGVALTYPE_32BIT_HACK = 0x7fffffff
1451} DBGFREGVALTYPE;
1452/** Pointer to a register value type. */
1453typedef DBGFREGVALTYPE *PDBGFREGVALTYPE;
1454
1455/**
1456 * A generic register value type.
1457 */
1458typedef union DBGFREGVAL
1459{
1460 uint64_t au64[2]; /**< The 64-bit array view. First because of the initializer. */
1461 uint32_t au32[4]; /**< The 32-bit array view. */
1462 uint16_t au16[8]; /**< The 16-bit array view. */
1463 uint8_t au8[16]; /**< The 8-bit array view. */
1464
1465 uint8_t u8; /**< The 8-bit view. */
1466 uint16_t u16; /**< The 16-bit view. */
1467 uint32_t u32; /**< The 32-bit view. */
1468 uint64_t u64; /**< The 64-bit view. */
1469 RTUINT128U u128; /**< The 128-bit view. */
1470 RTFLOAT80U r80; /**< The 80-bit floating point view. */
1471 RTFLOAT80U2 r80Ex; /**< The 80-bit floating point view v2. */
1472 /** GDTR or LDTR (DBGFREGVALTYPE_DTR). */
1473 struct
1474 {
1475 /** The table address. */
1476 uint64_t u64Base;
1477 /** The table limit (length minus 1). */
1478 uint32_t u32Limit;
1479 } dtr;
1480
1481 RTUINT128U u;
1482} DBGFREGVAL;
1483/** Pointer to a generic register value type. */
1484typedef DBGFREGVAL *PDBGFREGVAL;
1485/** Pointer to a const generic register value type. */
1486typedef DBGFREGVAL const *PCDBGFREGVAL;
1487
1488/** Initialize a DBGFREGVAL variable to all zeros. */
1489#define DBGFREGVAL_INITIALIZE_ZERO { { 0, 0 } }
1490/** Initialize a DBGFREGVAL variable to all bits set . */
1491#define DBGFREGVAL_INITIALIZE_FFFF { { UINT64_MAX, UINT64_MAX } }
1492
1493
1494VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial);
1495VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType,
1496 unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
1497
1498/**
1499 * Register sub-field descriptor.
1500 */
1501typedef struct DBGFREGSUBFIELD
1502{
1503 /** The name of the sub-field. NULL is used to terminate the array. */
1504 const char *pszName;
1505 /** The index of the first bit. Ignored if pfnGet is set. */
1506 uint8_t iFirstBit;
1507 /** The number of bits. Mandatory. */
1508 uint8_t cBits;
1509 /** The shift count. Not applied when pfnGet is set, but used to
1510 * calculate the minimum type. */
1511 int8_t cShift;
1512 /** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */
1513 uint8_t fFlags;
1514 /** Getter (optional).
1515 * @remarks Does not take the device lock or anything like that.
1516 */
1517 DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue);
1518 /** Setter (optional).
1519 * @remarks Does not take the device lock or anything like that.
1520 */
1521 DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask);
1522} DBGFREGSUBFIELD;
1523/** Pointer to a const register sub-field descriptor. */
1524typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD;
1525
1526/** @name DBGFREGSUBFIELD_FLAGS_XXX
1527 * @{ */
1528/** The sub-field is read-only. */
1529#define DBGFREGSUBFIELD_FLAGS_READ_ONLY UINT8_C(0x01)
1530/** @} */
1531
1532/** Macro for creating a read-write sub-field entry without getters. */
1533#define DBGFREGSUBFIELD_RW(a_szName, a_iFirstBit, a_cBits, a_cShift) \
1534 { a_szName, a_iFirstBit, a_cBits, a_cShift, 0 /*fFlags*/, NULL /*pfnGet*/, NULL /*pfnSet*/ }
1535/** Macro for creating a read-write sub-field entry with getters. */
1536#define DBGFREGSUBFIELD_RW_SG(a_szName, a_cBits, a_cShift, a_pfnGet, a_pfnSet) \
1537 { a_szName, 0 /*iFirstBit*/, a_cBits, a_cShift, 0 /*fFlags*/, a_pfnGet, a_pfnSet }
1538/** Macro for creating a read-only sub-field entry without getters. */
1539#define DBGFREGSUBFIELD_RO(a_szName, a_iFirstBit, a_cBits, a_cShift) \
1540 { a_szName, a_iFirstBit, a_cBits, a_cShift, DBGFREGSUBFIELD_FLAGS_READ_ONLY, NULL /*pfnGet*/, NULL /*pfnSet*/ }
1541/** Macro for creating a terminator sub-field entry. */
1542#define DBGFREGSUBFIELD_TERMINATOR() \
1543 { NULL, 0, 0, 0, 0, NULL, NULL }
1544
1545/**
1546 * Register alias descriptor.
1547 */
1548typedef struct DBGFREGALIAS
1549{
1550 /** The alias name. NULL is used to terminate the array. */
1551 const char *pszName;
1552 /** Set to a valid type if the alias has a different type. */
1553 DBGFREGVALTYPE enmType;
1554} DBGFREGALIAS;
1555/** Pointer to a const register alias descriptor. */
1556typedef DBGFREGALIAS const *PCDBGFREGALIAS;
1557
1558/**
1559 * Register descriptor.
1560 */
1561typedef struct DBGFREGDESC
1562{
1563 /** The normal register name. */
1564 const char *pszName;
1565 /** The register identifier if this is a CPU register. */
1566 DBGFREG enmReg;
1567 /** The default register type. */
1568 DBGFREGVALTYPE enmType;
1569 /** Flags, see DBGFREG_FLAGS_XXX. */
1570 uint32_t fFlags;
1571 /** The internal register indicator.
1572 * For CPU registers this is the offset into the CPUMCTX structure,
1573 * thuse the 'off' prefix. */
1574 uint32_t offRegister;
1575 /** Getter.
1576 * @remarks Does not take the device lock or anything like that.
1577 */
1578 DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGDESC const *pDesc, PDBGFREGVAL pValue);
1579 /** Setter.
1580 * @remarks Does not take the device lock or anything like that.
1581 */
1582 DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask);
1583 /** Aliases (optional). */
1584 PCDBGFREGALIAS paAliases;
1585 /** Sub fields (optional). */
1586 PCDBGFREGSUBFIELD paSubFields;
1587} DBGFREGDESC;
1588
1589/** @name Macros for constructing DBGFREGDESC arrays.
1590 * @{ */
1591#define DBGFREGDESC_RW(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
1592 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
1593#define DBGFREGDESC_RO(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
1594 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
1595#define DBGFREGDESC_RW_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
1596 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
1597#define DBGFREGDESC_RO_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
1598 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
1599#define DBGFREGDESC_RW_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
1600 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
1601#define DBGFREGDESC_RO_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
1602 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
1603#define DBGFREGDESC_RW_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
1604 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
1605#define DBGFREGDESC_RO_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
1606 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
1607#define DBGFREGDESC_TERMINATOR() \
1608 { NULL, DBGFREG_END, DBGFREGVALTYPE_INVALID, 0, 0, NULL, NULL, NULL, NULL }
1609/** @} */
1610
1611
1612/** @name DBGFREG_FLAGS_XXX
1613 * @{ */
1614/** The register is read-only. */
1615#define DBGFREG_FLAGS_READ_ONLY RT_BIT_32(0)
1616/** @} */
1617
1618/**
1619 * Entry in a batch query or set operation.
1620 */
1621typedef struct DBGFREGENTRY
1622{
1623 /** The register identifier. */
1624 DBGFREG enmReg;
1625 /** The size of the value in bytes. */
1626 DBGFREGVALTYPE enmType;
1627 /** The register value. The valid view is indicated by enmType. */
1628 DBGFREGVAL Val;
1629} DBGFREGENTRY;
1630/** Pointer to a register entry in a batch operation. */
1631typedef DBGFREGENTRY *PDBGFREGENTRY;
1632/** Pointer to a const register entry in a batch operation. */
1633typedef DBGFREGENTRY const *PCDBGFREGENTRY;
1634
1635/** Used with DBGFR3Reg* to indicate the hypervisor register set instead of the
1636 * guest. */
1637#define DBGFREG_HYPER_VMCPUID UINT32_C(0x01000000)
1638
1639VMMR3DECL(int) DBGFR3RegCpuQueryU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8);
1640VMMR3DECL(int) DBGFR3RegCpuQueryU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16);
1641VMMR3DECL(int) DBGFR3RegCpuQueryU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32);
1642VMMR3DECL(int) DBGFR3RegCpuQueryU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64);
1643VMMR3DECL(int) DBGFR3RegCpuQueryU128(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128);
1644VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd);
1645VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit);
1646#if 0
1647VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PUVM pUVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
1648VMMR3DECL(int) DBGFR3RegCpuQueryAll( PUVM pUVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
1649
1650VMMR3DECL(int) DBGFR3RegCpuSetU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8);
1651VMMR3DECL(int) DBGFR3RegCpuSetU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16);
1652VMMR3DECL(int) DBGFR3RegCpuSetU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32);
1653VMMR3DECL(int) DBGFR3RegCpuSetU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64);
1654VMMR3DECL(int) DBGFR3RegCpuSetU128( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128);
1655VMMR3DECL(int) DBGFR3RegCpuSetLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd);
1656VMMR3DECL(int) DBGFR3RegCpuSetBatch( PUVM pUVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs);
1657#endif
1658
1659VMMR3DECL(const char *) DBGFR3RegCpuName(PUVM pUVM, DBGFREG enmReg, DBGFREGVALTYPE enmType);
1660
1661VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs);
1662VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns,
1663 const char *pszPrefix, uint32_t iInstance);
1664
1665/**
1666 * Entry in a named batch query or set operation.
1667 */
1668typedef struct DBGFREGENTRYNM
1669{
1670 /** The register name. */
1671 const char *pszName;
1672 /** The size of the value in bytes. */
1673 DBGFREGVALTYPE enmType;
1674 /** The register value. The valid view is indicated by enmType. */
1675 DBGFREGVAL Val;
1676} DBGFREGENTRYNM;
1677/** Pointer to a named register entry in a batch operation. */
1678typedef DBGFREGENTRYNM *PDBGFREGENTRYNM;
1679/** Pointer to a const named register entry in a batch operation. */
1680typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM;
1681
1682VMMR3DECL(int) DBGFR3RegNmValidate( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg);
1683
1684VMMR3DECL(int) DBGFR3RegNmQuery( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType);
1685VMMR3DECL(int) DBGFR3RegNmQueryU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8);
1686VMMR3DECL(int) DBGFR3RegNmQueryU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16);
1687VMMR3DECL(int) DBGFR3RegNmQueryU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32);
1688VMMR3DECL(int) DBGFR3RegNmQueryU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64);
1689VMMR3DECL(int) DBGFR3RegNmQueryU128(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128);
1690/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
1691VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
1692VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
1693VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PUVM pUVM, size_t *pcRegs);
1694VMMR3DECL(int) DBGFR3RegNmQueryAll( PUVM pUVM, PDBGFREGENTRYNM paRegs, size_t cRegs);
1695
1696VMMR3DECL(int) DBGFR3RegNmSet( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType);
1697VMMR3DECL(int) DBGFR3RegNmSetU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8);
1698VMMR3DECL(int) DBGFR3RegNmSetU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16);
1699VMMR3DECL(int) DBGFR3RegNmSetU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32);
1700VMMR3DECL(int) DBGFR3RegNmSetU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64);
1701VMMR3DECL(int) DBGFR3RegNmSetU128( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128);
1702VMMR3DECL(int) DBGFR3RegNmSetLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
1703VMMR3DECL(int) DBGFR3RegNmSetBatch( PUVM pUVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
1704
1705/** @todo add enumeration methods. */
1706
1707VMMR3DECL(int) DBGFR3RegPrintf( PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
1708VMMR3DECL(int) DBGFR3RegPrintfV(PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va);
1709
1710
1711/**
1712 * Guest OS digger interface identifier.
1713 *
1714 * This is for use together with PDBGFR3QueryInterface and is used to
1715 * obtain access to optional interfaces.
1716 */
1717typedef enum DBGFOSINTERFACE
1718{
1719 /** The usual invalid entry. */
1720 DBGFOSINTERFACE_INVALID = 0,
1721 /** Process info. */
1722 DBGFOSINTERFACE_PROCESS,
1723 /** Thread info. */
1724 DBGFOSINTERFACE_THREAD,
1725 /** Kernel message log - DBGFOSIDMESG. */
1726 DBGFOSINTERFACE_DMESG,
1727 /** The end of the valid entries. */
1728 DBGFOSINTERFACE_END,
1729 /** The usual 32-bit type blowup. */
1730 DBGFOSINTERFACE_32BIT_HACK = 0x7fffffff
1731} DBGFOSINTERFACE;
1732/** Pointer to a Guest OS digger interface identifier. */
1733typedef DBGFOSINTERFACE *PDBGFOSINTERFACE;
1734/** Pointer to a const Guest OS digger interface identifier. */
1735typedef DBGFOSINTERFACE const *PCDBGFOSINTERFACE;
1736
1737
1738/**
1739 * Guest OS Digger Registration Record.
1740 *
1741 * This is used with the DBGFR3OSRegister() API.
1742 */
1743typedef struct DBGFOSREG
1744{
1745 /** Magic value (DBGFOSREG_MAGIC). */
1746 uint32_t u32Magic;
1747 /** Flags. Reserved. */
1748 uint32_t fFlags;
1749 /** The size of the instance data. */
1750 uint32_t cbData;
1751 /** Operative System name. */
1752 char szName[24];
1753
1754 /**
1755 * Constructs the instance.
1756 *
1757 * @returns VBox status code.
1758 * @param pUVM The user mode VM handle.
1759 * @param pvData Pointer to the instance data.
1760 */
1761 DECLCALLBACKMEMBER(int, pfnConstruct)(PUVM pUVM, void *pvData);
1762
1763 /**
1764 * Destroys the instance.
1765 *
1766 * @param pUVM The user mode VM handle.
1767 * @param pvData Pointer to the instance data.
1768 */
1769 DECLCALLBACKMEMBER(void, pfnDestruct)(PUVM pUVM, void *pvData);
1770
1771 /**
1772 * Probes the guest memory for OS finger prints.
1773 *
1774 * No setup or so is performed, it will be followed by a call to pfnInit
1775 * or pfnRefresh that should take care of that.
1776 *
1777 * @returns true if is an OS handled by this module, otherwise false.
1778 * @param pUVM The user mode VM handle.
1779 * @param pvData Pointer to the instance data.
1780 */
1781 DECLCALLBACKMEMBER(bool, pfnProbe)(PUVM pUVM, void *pvData);
1782
1783 /**
1784 * Initializes a fresly detected guest, loading symbols and such useful stuff.
1785 *
1786 * This is called after pfnProbe.
1787 *
1788 * @returns VBox status code.
1789 * @param pUVM The user mode VM handle.
1790 * @param pvData Pointer to the instance data.
1791 */
1792 DECLCALLBACKMEMBER(int, pfnInit)(PUVM pUVM, void *pvData);
1793
1794 /**
1795 * Refreshes symbols and stuff following a redetection of the same OS.
1796 *
1797 * This is called after pfnProbe.
1798 *
1799 * @returns VBox status code.
1800 * @param pUVM The user mode VM handle.
1801 * @param pvData Pointer to the instance data.
1802 */
1803 DECLCALLBACKMEMBER(int, pfnRefresh)(PUVM pUVM, void *pvData);
1804
1805 /**
1806 * Terminates an OS when a new (or none) OS has been detected,
1807 * and before destruction.
1808 *
1809 * This is called after pfnProbe and if needed before pfnDestruct.
1810 *
1811 * @param pUVM The user mode VM handle.
1812 * @param pvData Pointer to the instance data.
1813 */
1814 DECLCALLBACKMEMBER(void, pfnTerm)(PUVM pUVM, void *pvData);
1815
1816 /**
1817 * Queries the version of the running OS.
1818 *
1819 * This is only called after pfnInit().
1820 *
1821 * @returns VBox status code.
1822 * @param pUVM The user mode VM handle.
1823 * @param pvData Pointer to the instance data.
1824 * @param pszVersion Where to store the version string.
1825 * @param cchVersion The size of the version string buffer.
1826 */
1827 DECLCALLBACKMEMBER(int, pfnQueryVersion)(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion);
1828
1829 /**
1830 * Queries the pointer to a interface.
1831 *
1832 * This is called after pfnProbe.
1833 *
1834 * The returned interface must be valid until pfnDestruct is called. Two calls
1835 * to this method with the same @a enmIf value must return the same pointer.
1836 *
1837 * @returns Pointer to the interface if available, NULL if not available.
1838 * @param pUVM The user mode VM handle.
1839 * @param pvData Pointer to the instance data.
1840 * @param enmIf The interface identifier.
1841 */
1842 DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf);
1843
1844 /** Trailing magic (DBGFOSREG_MAGIC). */
1845 uint32_t u32EndMagic;
1846} DBGFOSREG;
1847/** Pointer to a Guest OS digger registration record. */
1848typedef DBGFOSREG *PDBGFOSREG;
1849/** Pointer to a const Guest OS digger registration record. */
1850typedef DBGFOSREG const *PCDBGFOSREG;
1851
1852/** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */
1853#define DBGFOSREG_MAGIC 0x19830808
1854
1855
1856/**
1857 * Interface for querying kernel log messages (DBGFOSINTERFACE_DMESG).
1858 */
1859typedef struct DBGFOSIDMESG
1860{
1861 /** Trailing magic (DBGFOSIDMESG_MAGIC). */
1862 uint32_t u32Magic;
1863
1864 /**
1865 * Query the kernel log.
1866 *
1867 * @returns VBox status code.
1868 * @retval VERR_NOT_FOUND if the messages could not be located.
1869 * @retval VERR_INVALID_STATE if the messages was found to have unknown/invalid
1870 * format.
1871 * @retval VERR_BUFFER_OVERFLOW if the buffer isn't large enough, pcbActual
1872 * will be set to the required buffer size. The buffer, however, will
1873 * be filled with as much data as it can hold (properly zero terminated
1874 * of course).
1875 *
1876 * @param pThis Pointer to the interface structure.
1877 * @param pUVM The user mode VM handle.
1878 * @param fFlags Flags reserved for future use, MBZ.
1879 * @param cMessages The number of messages to retrieve, counting from the
1880 * end of the log (i.e. like tail), use UINT32_MAX for all.
1881 * @param pszBuf The output buffer.
1882 * @param cbBuf The buffer size.
1883 * @param pcbActual Where to store the number of bytes actually returned,
1884 * including zero terminator. On VERR_BUFFER_OVERFLOW this
1885 * holds the necessary buffer size. Optional.
1886 */
1887 DECLCALLBACKMEMBER(int, pfnQueryKernelLog)(struct DBGFOSIDMESG *pThis, PUVM pUVM, uint32_t fFlags, uint32_t cMessages,
1888 char *pszBuf, size_t cbBuf, size_t *pcbActual);
1889 /** Trailing magic (DBGFOSIDMESG_MAGIC). */
1890 uint32_t u32EndMagic;
1891} DBGFOSIDMESG;
1892/** Pointer to the interface for query kernel log messages (DBGFOSINTERFACE_DMESG). */
1893typedef DBGFOSIDMESG *PDBGFOSIDMESG;
1894/** Magic value for DBGFOSIDMESG::32Magic and DBGFOSIDMESG::u32EndMagic. (Kenazburo Oe) */
1895#define DBGFOSIDMESG_MAGIC UINT32_C(0x19350131)
1896
1897
1898VMMR3DECL(int) DBGFR3OSRegister(PUVM pUVM, PCDBGFOSREG pReg);
1899VMMR3DECL(int) DBGFR3OSDeregister(PUVM pUVM, PCDBGFOSREG pReg);
1900VMMR3DECL(int) DBGFR3OSDetect(PUVM pUVM, char *pszName, size_t cchName);
1901VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion);
1902VMMR3DECL(void *) DBGFR3OSQueryInterface(PUVM pUVM, DBGFOSINTERFACE enmIf);
1903
1904
1905VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile);
1906
1907
1908#ifdef IN_RING3
1909/** @defgroup grp_dbgf_plug_in The DBGF Plug-in Interface
1910 * @{
1911 */
1912
1913/** The plug-in module name prefix. */
1914#define DBGF_PLUG_IN_PREFIX "DbgPlugIn"
1915
1916/** The name of the plug-in entry point (FNDBGFPLUGIN) */
1917#define DBGF_PLUG_IN_ENTRYPOINT "DbgPlugInEntry"
1918
1919/**
1920 * DBGF plug-in operations.
1921 */
1922typedef enum DBGFPLUGINOP
1923{
1924 /** The usual invalid first value. */
1925 DBGFPLUGINOP_INVALID,
1926 /** Initialize the plug-in for a VM, register all the stuff.
1927 * The plug-in will be unloaded on failure.
1928 * uArg: The full VirtualBox version, see VBox/version.h. */
1929 DBGFPLUGINOP_INIT,
1930 /** Terminate the plug-ing for a VM, deregister all the stuff.
1931 * The plug-in will be unloaded after this call regardless of the return
1932 * code. */
1933 DBGFPLUGINOP_TERM,
1934 /** The usual 32-bit hack. */
1935 DBGFPLUGINOP_32BIT_HACK = 0x7fffffff
1936} DBGFPLUGINOP;
1937
1938/**
1939 * DBGF plug-in main entry point.
1940 *
1941 * @returns VBox status code.
1942 *
1943 * @param enmOperation The operation.
1944 * @param pUVM The user mode VM handle. This may be NULL.
1945 * @param uArg Extra argument.
1946 */
1947typedef DECLCALLBACK(int) FNDBGFPLUGIN(DBGFPLUGINOP enmOperation, PUVM pUVM, uintptr_t uArg);
1948/** Pointer to a FNDBGFPLUGIN. */
1949typedef FNDBGFPLUGIN *PFNDBGFPLUGIN;
1950
1951/** @copydoc FNDBGFPLUGIN */
1952DECLEXPORT(int) DbgPlugInEntry(DBGFPLUGINOP enmOperation, PUVM pUVM, uintptr_t uArg);
1953
1954VMMR3DECL(int) DBGFR3PlugInLoad(PUVM pUVM, const char *pszPlugIn, char *pszActual, size_t cbActual, PRTERRINFO pErrInfo);
1955VMMR3DECL(int) DBGFR3PlugInUnload(PUVM pUVM, const char *pszName);
1956VMMR3DECL(void) DBGFR3PlugInLoadAll(PUVM pUVM);
1957VMMR3DECL(void) DBGFR3PlugInUnloadAll(PUVM pUVM);
1958
1959/** @} */
1960#endif /* IN_RING3 */
1961
1962
1963/** @} */
1964
1965
1966RT_C_DECLS_END
1967
1968#endif
1969
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