VirtualBox

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

Last change on this file since 61570 was 61570, checked in by vboxsync, 8 years ago

DBGFR3Info*: Added DBGFINFO_FLAGS_ALL_EMTS flag for cpum, apic and others dealing with per-vcpu state. Also got rid of some redundant VMR3ReqCallWaitU calls when we're already on the rigth EMT, and replacing them with priority calls when we actually need them. Didn't make sense to only do priority calls from DBGFR3InfoEx.

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