VirtualBox

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

Last change on this file since 89381 was 88366, checked in by vboxsync, 4 years ago

VMM/DBGFR3Flow: Add ability to put call instructions into separate basic blocks which will aid the flow tracing code to instrument calls to other functions more easily

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 129.8 KB
Line 
1/** @file
2 * DBGF - Debugger Facility.
3 */
4
5/*
6 * Copyright (C) 2006-2020 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_INCLUDED_vmm_dbgf_h
27#define VBOX_INCLUDED_vmm_dbgf_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <VBox/types.h>
33#include <VBox/log.h> /* LOG_ENABLED */
34#include <VBox/vmm/vmm.h>
35#include <VBox/vmm/dbgfsel.h>
36
37#include <iprt/stdarg.h>
38#include <iprt/dbg.h>
39
40RT_C_DECLS_BEGIN
41
42
43/** @defgroup grp_dbgf The Debugger Facility API
44 * @ingroup grp_vmm
45 * @{
46 */
47
48/** @defgroup grp_dbgf_r0 The R0 DBGF API
49 * @{
50 */
51VMMR0_INT_DECL(void) DBGFR0InitPerVMData(PGVM pGVM);
52VMMR0_INT_DECL(void) DBGFR0CleanupVM(PGVM pGVM);
53
54/**
55 * Request buffer for DBGFR0TracerCreateReqHandler / VMMR0_DO_DBGF_TRACER_CREATE.
56 * @see DBGFR0TracerCreateReqHandler.
57 */
58typedef struct DBGFTRACERCREATEREQ
59{
60 /** The header. */
61 SUPVMMR0REQHDR Hdr;
62 /** Out: Where to return the address of the ring-3 tracer instance. */
63 PDBGFTRACERINSR3 pTracerInsR3;
64
65 /** Number of bytes for the shared event ring buffer. */
66 uint32_t cbRingBuf;
67
68 /** Set if the raw-mode component is desired. */
69 bool fRCEnabled;
70 /** Explicit padding. */
71 bool afReserved[3];
72
73} DBGFTRACERCREATEREQ;
74/** Pointer to a DBGFR0TracerCreate / VMMR0_DO_DBGF_TRACER_CREATE request buffer. */
75typedef DBGFTRACERCREATEREQ *PDBGFTRACERCREATEREQ;
76
77VMMR0_INT_DECL(int) DBGFR0TracerCreateReqHandler(PGVM pGVM, PDBGFTRACERCREATEREQ pReq);
78
79/**
80 * Request buffer for DBGFR0BpInitReqHandler / VMMR0_DO_DBGF_BP_INIT.
81 * @see DBGFR0BpInitReqHandler.
82 */
83typedef struct DBGFBPINITREQ
84{
85 /** The header. */
86 SUPVMMR0REQHDR Hdr;
87 /** Out: Ring-3 pointer of the L1 lookup table on success. */
88 R3PTRTYPE(volatile uint32_t *) paBpLocL1R3;
89} DBGFBPINITREQ;
90/** Pointer to a DBGFR0BpInitReqHandler / VMMR0_DO_DBGF_BP_INIT request buffer. */
91typedef DBGFBPINITREQ *PDBGFBPINITREQ;
92
93VMMR0_INT_DECL(int) DBGFR0BpInitReqHandler(PGVM pGVM, PDBGFBPINITREQ pReq);
94
95/**
96 * Request buffer for DBGFR0BpOwnerInitReqHandler / VMMR0_DO_DBGF_BP_OWNER_INIT.
97 * @see DBGFR0BpOwnerInitReqHandler.
98 */
99typedef struct DBGFBPOWNERINITREQ
100{
101 /** The header. */
102 SUPVMMR0REQHDR Hdr;
103 /** Out: Ring-3 pointer of the breakpoint owner table on success. */
104 R3PTRTYPE(void *) paBpOwnerR3;
105} DBGFBPOWNERINITREQ;
106/** Pointer to a DBGFR0BpOwnerInitReqHandler / VMMR0_DO_DBGF_BP_INIT request buffer. */
107typedef DBGFBPOWNERINITREQ *PDBGFBPOWNERINITREQ;
108
109VMMR0_INT_DECL(int) DBGFR0BpOwnerInitReqHandler(PGVM pGVM, PDBGFBPOWNERINITREQ pReq);
110
111/**
112 * Request buffer for DBGFR0BpChunkAllocReqHandler / VMMR0_DO_DBGF_CHUNK_ALLOC.
113 * @see DBGFR0BpChunkAllocReqHandler.
114 */
115typedef struct DBGFBPCHUNKALLOCREQ
116{
117 /** The header. */
118 SUPVMMR0REQHDR Hdr;
119 /** Out: Ring-3 pointer of the chunk base on success. */
120 R3PTRTYPE(void *) pChunkBaseR3;
121
122 /** The chunk ID to allocate. */
123 uint32_t idChunk;
124} DBGFBPCHUNKALLOCREQ;
125/** Pointer to a DBGFR0BpChunkAllocReqHandler / VMMR0_DO_DBGF_CHUNK_ALLOC request buffer. */
126typedef DBGFBPCHUNKALLOCREQ *PDBGFBPCHUNKALLOCREQ;
127
128VMMR0_INT_DECL(int) DBGFR0BpChunkAllocReqHandler(PGVM pGVM, PDBGFBPCHUNKALLOCREQ pReq);
129
130/**
131 * Request buffer for DBGFR0BpL2TblChunkAllocReqHandler / VMMR0_DO_DBGF_L2_TBL_CHUNK_ALLOC.
132 * @see DBGFR0BpL2TblChunkAllocReqHandler.
133 */
134typedef struct DBGFBPL2TBLCHUNKALLOCREQ
135{
136 /** The header. */
137 SUPVMMR0REQHDR Hdr;
138 /** Out: Ring-3 pointer of the chunk base on success. */
139 R3PTRTYPE(void *) pChunkBaseR3;
140
141 /** The chunk ID to allocate. */
142 uint32_t idChunk;
143} DBGFBPL2TBLCHUNKALLOCREQ;
144/** Pointer to a DBGFR0BpChunkAllocReqHandler / VMMR0_DO_DBGF_L2_TBL_CHUNK_ALLOC request buffer. */
145typedef DBGFBPL2TBLCHUNKALLOCREQ *PDBGFBPL2TBLCHUNKALLOCREQ;
146
147VMMR0_INT_DECL(int) DBGFR0BpL2TblChunkAllocReqHandler(PGVM pGVM, PDBGFBPL2TBLCHUNKALLOCREQ pReq);
148/** @} */
149
150
151#ifdef IN_RING3
152
153/**
154 * Mixed address.
155 */
156typedef struct DBGFADDRESS
157{
158 /** The flat address. */
159 RTGCUINTPTR FlatPtr;
160 /** The selector offset address. */
161 RTGCUINTPTR off;
162 /** The selector. DBGF_SEL_FLAT is a legal value. */
163 RTSEL Sel;
164 /** Flags describing further details about the address. */
165 uint16_t fFlags;
166} DBGFADDRESS;
167/** Pointer to a mixed address. */
168typedef DBGFADDRESS *PDBGFADDRESS;
169/** Pointer to a const mixed address. */
170typedef const DBGFADDRESS *PCDBGFADDRESS;
171
172/** @name DBGFADDRESS Flags.
173 * @{ */
174/** A 16:16 far address. */
175#define DBGFADDRESS_FLAGS_FAR16 0
176/** A 16:32 far address. */
177#define DBGFADDRESS_FLAGS_FAR32 1
178/** A 16:64 far address. */
179#define DBGFADDRESS_FLAGS_FAR64 2
180/** A flat address. */
181#define DBGFADDRESS_FLAGS_FLAT 3
182/** A physical address. */
183#define DBGFADDRESS_FLAGS_PHYS 4
184/** A ring-0 host address (internal use only). */
185#define DBGFADDRESS_FLAGS_RING0 5
186/** The address type mask. */
187#define DBGFADDRESS_FLAGS_TYPE_MASK 7
188
189/** Set if the address is valid. */
190#define DBGFADDRESS_FLAGS_VALID RT_BIT(3)
191
192/** Checks if the mixed address is flat or not. */
193#define DBGFADDRESS_IS_FLAT(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FLAT )
194/** Checks if the mixed address is flat or not. */
195#define DBGFADDRESS_IS_PHYS(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_PHYS )
196/** Checks if the mixed address is far 16:16 or not. */
197#define DBGFADDRESS_IS_FAR16(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR16 )
198/** Checks if the mixed address is far 16:32 or not. */
199#define DBGFADDRESS_IS_FAR32(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR32 )
200/** Checks if the mixed address is far 16:64 or not. */
201#define DBGFADDRESS_IS_FAR64(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR64 )
202/** Checks if the mixed address is any kind of far address. */
203#define DBGFADDRESS_IS_FAR(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) <= DBGFADDRESS_FLAGS_FAR64 )
204/** Checks if the mixed address host context ring-0 (special). */
205#define DBGFADDRESS_IS_R0_HC(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_RING0 )
206/** Checks if the mixed address a virtual guest context address (incl HMA). */
207#define DBGFADDRESS_IS_VIRT_GC(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) <= DBGFADDRESS_FLAGS_FLAT )
208/** Checks if the mixed address is valid. */
209#define DBGFADDRESS_IS_VALID(pAddress) RT_BOOL((pAddress)->fFlags & DBGFADDRESS_FLAGS_VALID)
210/** @} */
211
212VMMR3DECL(int) DBGFR3AddrFromSelOff(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off);
213VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PUVM pUVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off);
214VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PUVM pUVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr);
215VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PUVM pUVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
216VMMR3_INT_DECL(PDBGFADDRESS) DBGFR3AddrFromHostR0(PDBGFADDRESS pAddress, RTR0UINTPTR R0Ptr);
217VMMR3DECL(bool) DBGFR3AddrIsValid(PUVM pUVM, PCDBGFADDRESS pAddress);
218VMMR3DECL(int) DBGFR3AddrToPhys(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
219VMMR3DECL(int) DBGFR3AddrToHostPhys(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys);
220VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr);
221VMMR3DECL(PDBGFADDRESS) DBGFR3AddrAdd(PDBGFADDRESS pAddress, RTGCUINTPTR uAddend);
222VMMR3DECL(PDBGFADDRESS) DBGFR3AddrSub(PDBGFADDRESS pAddress, RTGCUINTPTR uSubtrahend);
223
224#endif /* IN_RING3 */
225
226
227
228/**
229 * VMM Debug Event Type.
230 */
231typedef enum DBGFEVENTTYPE
232{
233 /** Halt completed.
234 * This notifies that a halt command have been successfully completed.
235 */
236 DBGFEVENT_HALT_DONE = 0,
237 /** Detach completed.
238 * This notifies that the detach command have been successfully completed.
239 */
240 DBGFEVENT_DETACH_DONE,
241 /** The command from the debugger is not recognized.
242 * This means internal error or half implemented features.
243 */
244 DBGFEVENT_INVALID_COMMAND,
245
246 /** Fatal error.
247 * This notifies a fatal error in the VMM and that the debugger get's a
248 * chance to first hand information about the the problem.
249 */
250 DBGFEVENT_FATAL_ERROR,
251 /** Breakpoint Hit.
252 * This notifies that a breakpoint installed by the debugger was hit. The
253 * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
254 */
255 DBGFEVENT_BREAKPOINT,
256 /** I/O port breakpoint.
257 * @todo not yet implemented. */
258 DBGFEVENT_BREAKPOINT_IO,
259 /** MMIO breakpoint.
260 * @todo not yet implemented. */
261 DBGFEVENT_BREAKPOINT_MMIO,
262 /** Breakpoint Hit in the Hypervisor.
263 * This notifies that a breakpoint installed by the debugger was hit. The
264 * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
265 * @todo raw-mode: remove this
266 */
267 DBGFEVENT_BREAKPOINT_HYPER,
268 /** Assertion in the Hypervisor (breakpoint instruction).
269 * This notifies that a breakpoint instruction was hit in the hypervisor context.
270 */
271 DBGFEVENT_ASSERTION_HYPER,
272 /** Single Stepped.
273 * This notifies that a single step operation was completed.
274 */
275 DBGFEVENT_STEPPED,
276 /** Single Stepped.
277 * This notifies that a hypervisor single step operation was completed.
278 */
279 DBGFEVENT_STEPPED_HYPER,
280 /** The developer have used the DBGFSTOP macro or the PDMDeviceDBGFSTOP function
281 * to bring up the debugger at a specific place.
282 */
283 DBGFEVENT_DEV_STOP,
284 /** The VM is powering off.
285 * When this notification is received, the debugger thread should detach ASAP.
286 */
287 DBGFEVENT_POWERING_OFF,
288
289 /** Hardware Interrupt break.
290 * @todo not yet implemented. */
291 DBGFEVENT_INTERRUPT_HARDWARE,
292 /** Software Interrupt break.
293 * @todo not yet implemented. */
294 DBGFEVENT_INTERRUPT_SOFTWARE,
295
296 /** The first selectable event.
297 * Whether the debugger wants or doesn't want these events can be configured
298 * via DBGFR3xxx and queried via DBGFR3yyy. */
299 DBGFEVENT_FIRST_SELECTABLE,
300 /** Tripple fault. */
301 DBGFEVENT_TRIPLE_FAULT = DBGFEVENT_FIRST_SELECTABLE,
302
303 /** @name Exception events
304 * The exception events normally represents guest exceptions, but depending on
305 * the execution mode some virtualization exceptions may occure (no nested
306 * paging, raw-mode, ++). When necessary, we will request additional VM exits.
307 * @{ */
308 DBGFEVENT_XCPT_FIRST, /**< The first exception event. */
309 DBGFEVENT_XCPT_DE /**< 0x00 - \#DE - Fault - NoErr - Integer divide error (zero/overflow). */
310 = DBGFEVENT_XCPT_FIRST,
311 DBGFEVENT_XCPT_DB, /**< 0x01 - \#DB - trap/fault - NoErr - debug event. */
312 DBGFEVENT_XCPT_02, /**< 0x02 - Reserved for NMI, see interrupt events. */
313 DBGFEVENT_XCPT_BP, /**< 0x03 - \#BP - Trap - NoErr - Breakpoint, INT 3 instruction. */
314 DBGFEVENT_XCPT_OF, /**< 0x04 - \#OF - Trap - NoErr - Overflow, INTO instruction. */
315 DBGFEVENT_XCPT_BR, /**< 0x05 - \#BR - Fault - NoErr - BOUND Range Exceeded, BOUND instruction. */
316 DBGFEVENT_XCPT_UD, /**< 0x06 - \#UD - Fault - NoErr - Undefined(/Invalid) Opcode. */
317 DBGFEVENT_XCPT_NM, /**< 0x07 - \#NM - Fault - NoErr - Device not available, FP or (F)WAIT instruction. */
318 DBGFEVENT_XCPT_DF, /**< 0x08 - \#DF - Abort - Err=0 - Double fault. */
319 DBGFEVENT_XCPT_09, /**< 0x09 - Int9 - Fault - NoErr - Coprocessor Segment Overrun (obsolete). */
320 DBGFEVENT_XCPT_TS, /**< 0x0a - \#TS - Fault - ErrCd - Invalid TSS, Taskswitch or TSS access. */
321 DBGFEVENT_XCPT_NP, /**< 0x0b - \#NP - Fault - ErrCd - Segment not present. */
322 DBGFEVENT_XCPT_SS, /**< 0x0c - \#SS - Fault - ErrCd - Stack-Segment fault. */
323 DBGFEVENT_XCPT_GP, /**< 0x0d - \#GP - Fault - ErrCd - General protection fault. */
324 DBGFEVENT_XCPT_PF, /**< 0x0e - \#PF - Fault - ErrCd - Page fault. - interrupt gate!!! */
325 DBGFEVENT_XCPT_0f, /**< 0x0f - Rsvd - Resvd - Resvd - Intel Reserved. */
326 DBGFEVENT_XCPT_MF, /**< 0x10 - \#MF - Fault - NoErr - x86 FPU Floating-Point Error (Math fault), FP or (F)WAIT instruction. */
327 DBGFEVENT_XCPT_AC, /**< 0x11 - \#AC - Fault - Err=0 - Alignment Check. */
328 DBGFEVENT_XCPT_MC, /**< 0x12 - \#MC - Abort - NoErr - Machine Check. */
329 DBGFEVENT_XCPT_XF, /**< 0x13 - \#XF - Fault - NoErr - SIMD Floating-Point Exception. */
330 DBGFEVENT_XCPT_VE, /**< 0x14 - \#VE - Fault - Noerr - Virtualization exception. */
331 DBGFEVENT_XCPT_15, /**< 0x15 - Intel Reserved. */
332 DBGFEVENT_XCPT_16, /**< 0x16 - Intel Reserved. */
333 DBGFEVENT_XCPT_17, /**< 0x17 - Intel Reserved. */
334 DBGFEVENT_XCPT_18, /**< 0x18 - Intel Reserved. */
335 DBGFEVENT_XCPT_19, /**< 0x19 - Intel Reserved. */
336 DBGFEVENT_XCPT_1a, /**< 0x1a - Intel Reserved. */
337 DBGFEVENT_XCPT_1b, /**< 0x1b - Intel Reserved. */
338 DBGFEVENT_XCPT_1c, /**< 0x1c - Intel Reserved. */
339 DBGFEVENT_XCPT_1d, /**< 0x1d - Intel Reserved. */
340 DBGFEVENT_XCPT_SX, /**< 0x1e - \#SX - Fault - ErrCd - Security Exception. */
341 DBGFEVENT_XCPT_1f, /**< 0x1f - Intel Reserved. */
342 DBGFEVENT_XCPT_LAST /**< The last exception event. */
343 = DBGFEVENT_XCPT_1f,
344 /** @} */
345
346 /** @name Instruction events
347 * The instruction events exerts all possible effort to intercept the
348 * relevant instructions. However, in some execution modes we won't be able
349 * to catch them. So it goes.
350 * @{ */
351 DBGFEVENT_INSTR_FIRST, /**< The first VM instruction event. */
352 DBGFEVENT_INSTR_HALT /**< Instruction: HALT */
353 = DBGFEVENT_INSTR_FIRST,
354 DBGFEVENT_INSTR_MWAIT, /**< Instruction: MWAIT */
355 DBGFEVENT_INSTR_MONITOR, /**< Instruction: MONITOR */
356 DBGFEVENT_INSTR_CPUID, /**< Instruction: CPUID (missing stuff in raw-mode). */
357 DBGFEVENT_INSTR_INVD, /**< Instruction: INVD */
358 DBGFEVENT_INSTR_WBINVD, /**< Instruction: WBINVD */
359 DBGFEVENT_INSTR_INVLPG, /**< Instruction: INVLPG */
360 DBGFEVENT_INSTR_RDTSC, /**< Instruction: RDTSC */
361 DBGFEVENT_INSTR_RDTSCP, /**< Instruction: RDTSCP */
362 DBGFEVENT_INSTR_RDPMC, /**< Instruction: RDPMC */
363 DBGFEVENT_INSTR_RDMSR, /**< Instruction: RDMSR */
364 DBGFEVENT_INSTR_WRMSR, /**< Instruction: WRMSR */
365 DBGFEVENT_INSTR_CRX_READ, /**< Instruction: CRx read instruction (missing smsw in raw-mode, and reads in general in VT-x). */
366 DBGFEVENT_INSTR_CRX_WRITE, /**< Instruction: CRx write */
367 DBGFEVENT_INSTR_DRX_READ, /**< Instruction: DRx read */
368 DBGFEVENT_INSTR_DRX_WRITE, /**< Instruction: DRx write */
369 DBGFEVENT_INSTR_PAUSE, /**< Instruction: PAUSE instruction (not in raw-mode). */
370 DBGFEVENT_INSTR_XSETBV, /**< Instruction: XSETBV */
371 DBGFEVENT_INSTR_SIDT, /**< Instruction: SIDT */
372 DBGFEVENT_INSTR_LIDT, /**< Instruction: LIDT */
373 DBGFEVENT_INSTR_SGDT, /**< Instruction: SGDT */
374 DBGFEVENT_INSTR_LGDT, /**< Instruction: LGDT */
375 DBGFEVENT_INSTR_SLDT, /**< Instruction: SLDT */
376 DBGFEVENT_INSTR_LLDT, /**< Instruction: LLDT */
377 DBGFEVENT_INSTR_STR, /**< Instruction: STR */
378 DBGFEVENT_INSTR_LTR, /**< Instruction: LTR */
379 DBGFEVENT_INSTR_GETSEC, /**< Instruction: GETSEC */
380 DBGFEVENT_INSTR_RSM, /**< Instruction: RSM */
381 DBGFEVENT_INSTR_RDRAND, /**< Instruction: RDRAND */
382 DBGFEVENT_INSTR_RDSEED, /**< Instruction: RDSEED */
383 DBGFEVENT_INSTR_XSAVES, /**< Instruction: XSAVES */
384 DBGFEVENT_INSTR_XRSTORS, /**< Instruction: XRSTORS */
385 DBGFEVENT_INSTR_VMM_CALL, /**< Instruction: VMCALL (intel) or VMMCALL (AMD) */
386 DBGFEVENT_INSTR_LAST_COMMON /**< Instruction: the last common event. */
387 = DBGFEVENT_INSTR_VMM_CALL,
388 DBGFEVENT_INSTR_VMX_FIRST, /**< Instruction: VT-x - First. */
389 DBGFEVENT_INSTR_VMX_VMCLEAR /**< Instruction: VT-x VMCLEAR */
390 = DBGFEVENT_INSTR_VMX_FIRST,
391 DBGFEVENT_INSTR_VMX_VMLAUNCH, /**< Instruction: VT-x VMLAUNCH */
392 DBGFEVENT_INSTR_VMX_VMPTRLD, /**< Instruction: VT-x VMPTRLD */
393 DBGFEVENT_INSTR_VMX_VMPTRST, /**< Instruction: VT-x VMPTRST */
394 DBGFEVENT_INSTR_VMX_VMREAD, /**< Instruction: VT-x VMREAD */
395 DBGFEVENT_INSTR_VMX_VMRESUME, /**< Instruction: VT-x VMRESUME */
396 DBGFEVENT_INSTR_VMX_VMWRITE, /**< Instruction: VT-x VMWRITE */
397 DBGFEVENT_INSTR_VMX_VMXOFF, /**< Instruction: VT-x VMXOFF */
398 DBGFEVENT_INSTR_VMX_VMXON, /**< Instruction: VT-x VMXON */
399 DBGFEVENT_INSTR_VMX_VMFUNC, /**< Instruction: VT-x VMFUNC */
400 DBGFEVENT_INSTR_VMX_INVEPT, /**< Instruction: VT-x INVEPT */
401 DBGFEVENT_INSTR_VMX_INVVPID, /**< Instruction: VT-x INVVPID */
402 DBGFEVENT_INSTR_VMX_INVPCID, /**< Instruction: VT-x INVPCID */
403 DBGFEVENT_INSTR_VMX_LAST /**< Instruction: VT-x - Last. */
404 = DBGFEVENT_INSTR_VMX_INVPCID,
405 DBGFEVENT_INSTR_SVM_FIRST, /**< Instruction: AMD-V - first */
406 DBGFEVENT_INSTR_SVM_VMRUN /**< Instruction: AMD-V VMRUN */
407 = DBGFEVENT_INSTR_SVM_FIRST,
408 DBGFEVENT_INSTR_SVM_VMLOAD, /**< Instruction: AMD-V VMLOAD */
409 DBGFEVENT_INSTR_SVM_VMSAVE, /**< Instruction: AMD-V VMSAVE */
410 DBGFEVENT_INSTR_SVM_STGI, /**< Instruction: AMD-V STGI */
411 DBGFEVENT_INSTR_SVM_CLGI, /**< Instruction: AMD-V CLGI */
412 DBGFEVENT_INSTR_SVM_LAST /**< Instruction: The last ADM-V VM exit event. */
413 = DBGFEVENT_INSTR_SVM_CLGI,
414 DBGFEVENT_INSTR_LAST /**< Instruction: The last instruction event. */
415 = DBGFEVENT_INSTR_SVM_LAST,
416 /** @} */
417
418
419 /** @name VM exit events.
420 * VM exits events for VT-x and AMD-V execution mode. Many of the VM exits
421 * behind these events are also directly translated into instruction events, but
422 * the difference here is that the exit events will not try provoke the exits.
423 * @{ */
424 DBGFEVENT_EXIT_FIRST, /**< The first VM exit event. */
425 DBGFEVENT_EXIT_TASK_SWITCH /**< Exit: Task switch. */
426 = DBGFEVENT_EXIT_FIRST,
427 DBGFEVENT_EXIT_HALT, /**< Exit: HALT instruction. */
428 DBGFEVENT_EXIT_MWAIT, /**< Exit: MWAIT instruction. */
429 DBGFEVENT_EXIT_MONITOR, /**< Exit: MONITOR instruction. */
430 DBGFEVENT_EXIT_CPUID, /**< Exit: CPUID instruction (missing stuff in raw-mode). */
431 DBGFEVENT_EXIT_INVD, /**< Exit: INVD instruction. */
432 DBGFEVENT_EXIT_WBINVD, /**< Exit: WBINVD instruction. */
433 DBGFEVENT_EXIT_INVLPG, /**< Exit: INVLPG instruction. */
434 DBGFEVENT_EXIT_RDTSC, /**< Exit: RDTSC instruction. */
435 DBGFEVENT_EXIT_RDTSCP, /**< Exit: RDTSCP instruction. */
436 DBGFEVENT_EXIT_RDPMC, /**< Exit: RDPMC instruction. */
437 DBGFEVENT_EXIT_RDMSR, /**< Exit: RDMSR instruction. */
438 DBGFEVENT_EXIT_WRMSR, /**< Exit: WRMSR instruction. */
439 DBGFEVENT_EXIT_CRX_READ, /**< Exit: CRx read instruction (missing smsw in raw-mode, and reads in general in VT-x). */
440 DBGFEVENT_EXIT_CRX_WRITE, /**< Exit: CRx write instruction. */
441 DBGFEVENT_EXIT_DRX_READ, /**< Exit: DRx read instruction. */
442 DBGFEVENT_EXIT_DRX_WRITE, /**< Exit: DRx write instruction. */
443 DBGFEVENT_EXIT_PAUSE, /**< Exit: PAUSE instruction (not in raw-mode). */
444 DBGFEVENT_EXIT_XSETBV, /**< Exit: XSETBV instruction. */
445 DBGFEVENT_EXIT_SIDT, /**< Exit: SIDT instruction. */
446 DBGFEVENT_EXIT_LIDT, /**< Exit: LIDT instruction. */
447 DBGFEVENT_EXIT_SGDT, /**< Exit: SGDT instruction. */
448 DBGFEVENT_EXIT_LGDT, /**< Exit: LGDT instruction. */
449 DBGFEVENT_EXIT_SLDT, /**< Exit: SLDT instruction. */
450 DBGFEVENT_EXIT_LLDT, /**< Exit: LLDT instruction. */
451 DBGFEVENT_EXIT_STR, /**< Exit: STR instruction. */
452 DBGFEVENT_EXIT_LTR, /**< Exit: LTR instruction. */
453 DBGFEVENT_EXIT_GETSEC, /**< Exit: GETSEC instruction. */
454 DBGFEVENT_EXIT_RSM, /**< Exit: RSM instruction. */
455 DBGFEVENT_EXIT_RDRAND, /**< Exit: RDRAND instruction. */
456 DBGFEVENT_EXIT_RDSEED, /**< Exit: RDSEED instruction. */
457 DBGFEVENT_EXIT_XSAVES, /**< Exit: XSAVES instruction. */
458 DBGFEVENT_EXIT_XRSTORS, /**< Exit: XRSTORS instruction. */
459 DBGFEVENT_EXIT_VMM_CALL, /**< Exit: VMCALL (intel) or VMMCALL (AMD) instruction. */
460 DBGFEVENT_EXIT_LAST_COMMON /**< Exit: the last common event. */
461 = DBGFEVENT_EXIT_VMM_CALL,
462 DBGFEVENT_EXIT_VMX_FIRST, /**< Exit: VT-x - First. */
463 DBGFEVENT_EXIT_VMX_VMCLEAR /**< Exit: VT-x VMCLEAR instruction. */
464 = DBGFEVENT_EXIT_VMX_FIRST,
465 DBGFEVENT_EXIT_VMX_VMLAUNCH, /**< Exit: VT-x VMLAUNCH instruction. */
466 DBGFEVENT_EXIT_VMX_VMPTRLD, /**< Exit: VT-x VMPTRLD instruction. */
467 DBGFEVENT_EXIT_VMX_VMPTRST, /**< Exit: VT-x VMPTRST instruction. */
468 DBGFEVENT_EXIT_VMX_VMREAD, /**< Exit: VT-x VMREAD instruction. */
469 DBGFEVENT_EXIT_VMX_VMRESUME, /**< Exit: VT-x VMRESUME instruction. */
470 DBGFEVENT_EXIT_VMX_VMWRITE, /**< Exit: VT-x VMWRITE instruction. */
471 DBGFEVENT_EXIT_VMX_VMXOFF, /**< Exit: VT-x VMXOFF instruction. */
472 DBGFEVENT_EXIT_VMX_VMXON, /**< Exit: VT-x VMXON instruction. */
473 DBGFEVENT_EXIT_VMX_VMFUNC, /**< Exit: VT-x VMFUNC instruction. */
474 DBGFEVENT_EXIT_VMX_INVEPT, /**< Exit: VT-x INVEPT instruction. */
475 DBGFEVENT_EXIT_VMX_INVVPID, /**< Exit: VT-x INVVPID instruction. */
476 DBGFEVENT_EXIT_VMX_INVPCID, /**< Exit: VT-x INVPCID instruction. */
477 DBGFEVENT_EXIT_VMX_EPT_VIOLATION, /**< Exit: VT-x EPT violation. */
478 DBGFEVENT_EXIT_VMX_EPT_MISCONFIG, /**< Exit: VT-x EPT misconfiguration. */
479 DBGFEVENT_EXIT_VMX_VAPIC_ACCESS, /**< Exit: VT-x Virtual APIC page access. */
480 DBGFEVENT_EXIT_VMX_VAPIC_WRITE, /**< Exit: VT-x Virtual APIC write. */
481 DBGFEVENT_EXIT_VMX_LAST /**< Exit: VT-x - Last. */
482 = DBGFEVENT_EXIT_VMX_VAPIC_WRITE,
483 DBGFEVENT_EXIT_SVM_FIRST, /**< Exit: AMD-V - first */
484 DBGFEVENT_EXIT_SVM_VMRUN /**< Exit: AMD-V VMRUN instruction. */
485 = DBGFEVENT_EXIT_SVM_FIRST,
486 DBGFEVENT_EXIT_SVM_VMLOAD, /**< Exit: AMD-V VMLOAD instruction. */
487 DBGFEVENT_EXIT_SVM_VMSAVE, /**< Exit: AMD-V VMSAVE instruction. */
488 DBGFEVENT_EXIT_SVM_STGI, /**< Exit: AMD-V STGI instruction. */
489 DBGFEVENT_EXIT_SVM_CLGI, /**< Exit: AMD-V CLGI instruction. */
490 DBGFEVENT_EXIT_SVM_LAST /**< Exit: The last ADM-V VM exit event. */
491 = DBGFEVENT_EXIT_SVM_CLGI,
492 DBGFEVENT_EXIT_LAST /**< Exit: The last VM exit event. */
493 = DBGFEVENT_EXIT_SVM_LAST,
494 /** @} */
495
496
497 /** Access to an unassigned I/O port.
498 * @todo not yet implemented. */
499 DBGFEVENT_IOPORT_UNASSIGNED,
500 /** Access to an unused I/O port on a device.
501 * @todo not yet implemented. */
502 DBGFEVENT_IOPORT_UNUSED,
503 /** Unassigned memory event.
504 * @todo not yet implemented. */
505 DBGFEVENT_MEMORY_UNASSIGNED,
506 /** Attempt to write to unshadowed ROM.
507 * @todo not yet implemented. */
508 DBGFEVENT_MEMORY_ROM_WRITE,
509
510 /** Windows guest reported BSOD via hyperv MSRs. */
511 DBGFEVENT_BSOD_MSR,
512 /** Windows guest reported BSOD via EFI variables. */
513 DBGFEVENT_BSOD_EFI,
514 /** Windows guest reported BSOD via VMMDev. */
515 DBGFEVENT_BSOD_VMMDEV,
516
517 /** End of valid event values. */
518 DBGFEVENT_END,
519 /** The usual 32-bit hack. */
520 DBGFEVENT_32BIT_HACK = 0x7fffffff
521} DBGFEVENTTYPE;
522AssertCompile(DBGFEVENT_XCPT_LAST - DBGFEVENT_XCPT_FIRST == 0x1f);
523
524/**
525 * The context of an event.
526 */
527typedef enum DBGFEVENTCTX
528{
529 /** The usual invalid entry. */
530 DBGFEVENTCTX_INVALID = 0,
531 /** Raw mode. */
532 DBGFEVENTCTX_RAW,
533 /** Recompiled mode. */
534 DBGFEVENTCTX_REM,
535 /** VMX / AVT mode. */
536 DBGFEVENTCTX_HM,
537 /** Hypervisor context. */
538 DBGFEVENTCTX_HYPER,
539 /** Other mode */
540 DBGFEVENTCTX_OTHER,
541
542 /** The usual 32-bit hack */
543 DBGFEVENTCTX_32BIT_HACK = 0x7fffffff
544} DBGFEVENTCTX;
545
546/**
547 * VMM Debug Event.
548 */
549typedef struct DBGFEVENT
550{
551 /** Type. */
552 DBGFEVENTTYPE enmType;
553 /** Context */
554 DBGFEVENTCTX enmCtx;
555 /** The vCPU/EMT which generated the event. */
556 VMCPUID idCpu;
557 /** Reserved. */
558 uint32_t uReserved;
559 /** Type specific data. */
560 union
561 {
562 /** Fatal error details. */
563 struct
564 {
565 /** The GC return code. */
566 int rc;
567 } FatalError;
568
569 /** Source location. */
570 struct
571 {
572 /** File name. */
573 R3PTRTYPE(const char *) pszFile;
574 /** Function name. */
575 R3PTRTYPE(const char *) pszFunction;
576 /** Message. */
577 R3PTRTYPE(const char *) pszMessage;
578 /** Line number. */
579 unsigned uLine;
580 } Src;
581
582 /** Assertion messages. */
583 struct
584 {
585 /** The first message. */
586 R3PTRTYPE(const char *) pszMsg1;
587 /** The second message. */
588 R3PTRTYPE(const char *) pszMsg2;
589 } Assert;
590
591 /** Breakpoint. */
592 struct DBGFEVENTBP
593 {
594 /** The handle of the breakpoint which was hit. */
595 DBGFBP hBp;
596 } Bp;
597
598 /** Generic debug event. */
599 struct DBGFEVENTGENERIC
600 {
601 /** Number of arguments. */
602 uint8_t cArgs;
603 /** Alignment padding. */
604 uint8_t uPadding[7];
605 /** Arguments. */
606 uint64_t auArgs[5];
607 } Generic;
608
609 /** Padding for ensuring that the structure is 8 byte aligned. */
610 uint64_t au64Padding[6];
611 } u;
612} DBGFEVENT;
613AssertCompileSizeAlignment(DBGFEVENT, 8);
614AssertCompileSize(DBGFEVENT, 64);
615/** Pointer to VMM Debug Event. */
616typedef DBGFEVENT *PDBGFEVENT;
617/** Pointer to const VMM Debug Event. */
618typedef const DBGFEVENT *PCDBGFEVENT;
619
620#ifdef IN_RING3 /* The event API only works in ring-3. */
621
622/** @def DBGFSTOP
623 * Stops the debugger raising a DBGFEVENT_DEVELOPER_STOP event.
624 *
625 * @returns VBox status code which must be propagated up to EM if not VINF_SUCCESS.
626 * @param pVM The cross context VM structure.
627 */
628# ifdef VBOX_STRICT
629# define DBGFSTOP(pVM) DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
630# else
631# define DBGFSTOP(pVM) VINF_SUCCESS
632# endif
633
634VMMR3_INT_DECL(int) DBGFR3Init(PVM pVM);
635VMMR3_INT_DECL(int) DBGFR3Term(PVM pVM);
636VMMR3DECL(void) DBGFR3TermUVM(PUVM pUVM);
637VMMR3_INT_DECL(void) DBGFR3PowerOff(PVM pVM);
638VMMR3_INT_DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta);
639
640VMMR3_INT_DECL(int) DBGFR3VMMForcedAction(PVM pVM, PVMCPU pVCpu);
641VMMR3_INT_DECL(VBOXSTRICTRC) DBGFR3EventHandlePending(PVM pVM, PVMCPU pVCpu);
642VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent);
643VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
644 const char *pszFunction, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 7);
645VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine,
646 const char *pszFunction, const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR_MAYBE_NULL(6, 0);
647VMMR3_INT_DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2);
648VMMR3_INT_DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent);
649
650VMMR3_INT_DECL(int) DBGFR3PrgStep(PVMCPU pVCpu);
651
652VMMR3DECL(int) DBGFR3Attach(PUVM pUVM);
653VMMR3DECL(int) DBGFR3Detach(PUVM pUVM);
654VMMR3DECL(int) DBGFR3EventWait(PUVM pUVM, RTMSINTERVAL cMillies, PDBGFEVENT pEvent);
655VMMR3DECL(int) DBGFR3Halt(PUVM pUVM, VMCPUID idCpu);
656VMMR3DECL(bool) DBGFR3IsHalted(PUVM pUVM, VMCPUID idCpu);
657VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM);
658VMMR3DECL(int) DBGFR3Resume(PUVM pUVM, VMCPUID idCpu);
659VMMR3DECL(int) DBGFR3InjectNMI(PUVM pUVM, VMCPUID idCpu);
660VMMR3DECL(int) DBGFR3Step(PUVM pUVM, VMCPUID idCpu);
661VMMR3DECL(int) DBGFR3StepEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, PCDBGFADDRESS pStopPcAddr,
662 PCDBGFADDRESS pStopPopAddr, RTGCUINTPTR cbStopPop, uint32_t cMaxSteps);
663
664/** @name DBGF_STEP_F_XXX - Flags for DBGFR3StepEx.
665 *
666 * @note The stop filters are not applied to the starting instruction.
667 *
668 * @{ */
669/** Step into CALL, INT, SYSCALL and SYSENTER instructions. */
670#define DBGF_STEP_F_INTO RT_BIT_32(0)
671/** Step over CALL, INT, SYSCALL and SYSENTER instruction when considering
672 * what's "next". */
673#define DBGF_STEP_F_OVER RT_BIT_32(1)
674
675/** Stop on the next CALL, INT, SYSCALL, SYSENTER instruction. */
676#define DBGF_STEP_F_STOP_ON_CALL RT_BIT_32(8)
677/** Stop on the next RET, IRET, SYSRET, SYSEXIT instruction. */
678#define DBGF_STEP_F_STOP_ON_RET RT_BIT_32(9)
679/** Stop after the next RET, IRET, SYSRET, SYSEXIT instruction. */
680#define DBGF_STEP_F_STOP_AFTER_RET RT_BIT_32(10)
681/** Stop on the given address.
682 * The comparison will be made using effective (flat) addresses. */
683#define DBGF_STEP_F_STOP_ON_ADDRESS RT_BIT_32(11)
684/** Stop when the stack pointer pops to or past the given address.
685 * The comparison will be made using effective (flat) addresses. */
686#define DBGF_STEP_F_STOP_ON_STACK_POP RT_BIT_32(12)
687/** Mask of stop filter flags. */
688#define DBGF_STEP_F_STOP_FILTER_MASK UINT32_C(0x00001f00)
689
690/** Mask of valid flags. */
691#define DBGF_STEP_F_VALID_MASK UINT32_C(0x00001f03)
692/** @} */
693
694/**
695 * Event configuration array element, see DBGFR3EventConfigEx.
696 */
697typedef struct DBGFEVENTCONFIG
698{
699 /** The event to configure */
700 DBGFEVENTTYPE enmType;
701 /** The new state. */
702 bool fEnabled;
703 /** Unused. */
704 uint8_t abUnused[3];
705} DBGFEVENTCONFIG;
706/** Pointer to an event config. */
707typedef DBGFEVENTCONFIG *PDBGFEVENTCONFIG;
708/** Pointer to a const event config. */
709typedef const DBGFEVENTCONFIG *PCDBGFEVENTCONFIG;
710
711VMMR3DECL(int) DBGFR3EventConfigEx(PUVM pUVM, PCDBGFEVENTCONFIG paConfigs, size_t cConfigs);
712VMMR3DECL(int) DBGFR3EventConfig(PUVM pUVM, DBGFEVENTTYPE enmEvent, bool fEnabled);
713VMMR3DECL(bool) DBGFR3EventIsEnabled(PUVM pUVM, DBGFEVENTTYPE enmEvent);
714VMMR3DECL(int) DBGFR3EventQuery(PUVM pUVM, PDBGFEVENTCONFIG paConfigs, size_t cConfigs);
715
716/** @name DBGFINTERRUPTSTATE_XXX - interrupt break state.
717 * @{ */
718#define DBGFINTERRUPTSTATE_DISABLED 0
719#define DBGFINTERRUPTSTATE_ENABLED 1
720#define DBGFINTERRUPTSTATE_DONT_TOUCH 2
721/** @} */
722
723/**
724 * Interrupt break state configuration entry.
725 */
726typedef struct DBGFINTERRUPTCONFIG
727{
728 /** The interrupt number. */
729 uint8_t iInterrupt;
730 /** The hardware interrupt state (DBGFINTERRUPTSTATE_XXX). */
731 uint8_t enmHardState;
732 /** The software interrupt state (DBGFINTERRUPTSTATE_XXX). */
733 uint8_t enmSoftState;
734} DBGFINTERRUPTCONFIG;
735/** Pointer to an interrupt break state config entyr. */
736typedef DBGFINTERRUPTCONFIG *PDBGFINTERRUPTCONFIG;
737/** Pointer to a const interrupt break state config entyr. */
738typedef DBGFINTERRUPTCONFIG const *PCDBGFINTERRUPTCONFIG;
739
740VMMR3DECL(int) DBGFR3InterruptConfigEx(PUVM pUVM, PCDBGFINTERRUPTCONFIG paConfigs, size_t cConfigs);
741VMMR3DECL(int) DBGFR3InterruptHardwareConfig(PUVM pUVM, uint8_t iInterrupt, bool fEnabled);
742VMMR3DECL(int) DBGFR3InterruptSoftwareConfig(PUVM pUVM, uint8_t iInterrupt, bool fEnabled);
743VMMR3DECL(int) DBGFR3InterruptHardwareIsEnabled(PUVM pUVM, uint8_t iInterrupt);
744VMMR3DECL(int) DBGFR3InterruptSoftwareIsEnabled(PUVM pUVM, uint8_t iInterrupt);
745
746#endif /* IN_RING3 */
747
748/** @def DBGF_IS_EVENT_ENABLED
749 * Checks if a selectable debug event is enabled or not (fast).
750 *
751 * @returns true/false.
752 * @param a_pVM Pointer to the cross context VM structure.
753 * @param a_enmEvent The selectable event to check.
754 * @remarks Only for use internally in the VMM. Use DBGFR3EventIsEnabled elsewhere.
755 */
756#if defined(VBOX_STRICT) && defined(RT_COMPILER_SUPPORTS_LAMBDA)
757# define DBGF_IS_EVENT_ENABLED(a_pVM, a_enmEvent) \
758 ([](PVM a_pLambdaVM, DBGFEVENTTYPE a_enmLambdaEvent) -> bool { \
759 Assert( a_enmLambdaEvent >= DBGFEVENT_FIRST_SELECTABLE \
760 || a_enmLambdaEvent == DBGFEVENT_INTERRUPT_HARDWARE \
761 || a_enmLambdaEvent == DBGFEVENT_INTERRUPT_SOFTWARE); \
762 Assert(a_enmLambdaEvent < DBGFEVENT_END); \
763 return ASMBitTest(&a_pLambdaVM->dbgf.ro.bmSelectedEvents, a_enmLambdaEvent); \
764 }(a_pVM, a_enmEvent))
765#elif defined(VBOX_STRICT) && defined(__GNUC__)
766# define DBGF_IS_EVENT_ENABLED(a_pVM, a_enmEvent) \
767 __extension__ ({ \
768 Assert( (a_enmEvent) >= DBGFEVENT_FIRST_SELECTABLE \
769 || (a_enmEvent) == DBGFEVENT_INTERRUPT_HARDWARE \
770 || (a_enmEvent) == DBGFEVENT_INTERRUPT_SOFTWARE); \
771 Assert((a_enmEvent) < DBGFEVENT_END); \
772 ASMBitTest(&(a_pVM)->dbgf.ro.bmSelectedEvents, (a_enmEvent)); \
773 })
774#else
775# define DBGF_IS_EVENT_ENABLED(a_pVM, a_enmEvent) \
776 ASMBitTest(&(a_pVM)->dbgf.ro.bmSelectedEvents, (a_enmEvent))
777#endif
778
779
780/** @def DBGF_IS_HARDWARE_INT_ENABLED
781 * Checks if hardware interrupt interception is enabled or not for an interrupt.
782 *
783 * @returns true/false.
784 * @param a_pVM Pointer to the cross context VM structure.
785 * @param a_iInterrupt Interrupt to check.
786 * @remarks Only for use internally in the VMM. Use
787 * DBGFR3InterruptHardwareIsEnabled elsewhere.
788 */
789#define DBGF_IS_HARDWARE_INT_ENABLED(a_pVM, a_iInterrupt) \
790 ASMBitTest(&(a_pVM)->dbgf.ro.bmHardIntBreakpoints, (uint8_t)(a_iInterrupt))
791
792/** @def DBGF_IS_SOFTWARE_INT_ENABLED
793 * Checks if software interrupt interception is enabled or not for an interrupt.
794 *
795 * @returns true/false.
796 * @param a_pVM Pointer to the cross context VM structure.
797 * @param a_iInterrupt Interrupt to check.
798 * @remarks Only for use internally in the VMM. Use
799 * DBGFR3InterruptSoftwareIsEnabled elsewhere.
800 */
801#define DBGF_IS_SOFTWARE_INT_ENABLED(a_pVM, a_iInterrupt) \
802 ASMBitTest(&(a_pVM)->dbgf.ro.bmSoftIntBreakpoints, (uint8_t)(a_iInterrupt))
803
804
805
806/** Breakpoint type. */
807typedef enum DBGFBPTYPE
808{
809 /** Invalid breakpoint type. */
810 DBGFBPTYPE_INVALID = 0,
811 /** Debug register. */
812 DBGFBPTYPE_REG,
813 /** INT 3 instruction. */
814 DBGFBPTYPE_INT3,
815 /** Port I/O breakpoint. */
816 DBGFBPTYPE_PORT_IO,
817 /** Memory mapped I/O breakpoint. */
818 DBGFBPTYPE_MMIO,
819 /** ensure 32-bit size. */
820 DBGFBPTYPE_32BIT_HACK = 0x7fffffff
821} DBGFBPTYPE;
822
823
824/** @name DBGFBPIOACCESS_XXX - I/O (port + mmio) access types.
825 * @{ */
826/** Byte sized read accesses. */
827#define DBGFBPIOACCESS_READ_BYTE UINT32_C(0x00000001)
828/** Word sized accesses. */
829#define DBGFBPIOACCESS_READ_WORD UINT32_C(0x00000002)
830/** Double word sized accesses. */
831#define DBGFBPIOACCESS_READ_DWORD UINT32_C(0x00000004)
832/** Quad word sized accesses - not available for I/O ports. */
833#define DBGFBPIOACCESS_READ_QWORD UINT32_C(0x00000008)
834/** Other sized accesses - not available for I/O ports. */
835#define DBGFBPIOACCESS_READ_OTHER UINT32_C(0x00000010)
836/** Read mask. */
837#define DBGFBPIOACCESS_READ_MASK UINT32_C(0x0000001f)
838
839/** Byte sized write accesses. */
840#define DBGFBPIOACCESS_WRITE_BYTE UINT32_C(0x00000100)
841/** Word sized write accesses. */
842#define DBGFBPIOACCESS_WRITE_WORD UINT32_C(0x00000200)
843/** Double word sized write accesses. */
844#define DBGFBPIOACCESS_WRITE_DWORD UINT32_C(0x00000400)
845/** Quad word sized write accesses - not available for I/O ports. */
846#define DBGFBPIOACCESS_WRITE_QWORD UINT32_C(0x00000800)
847/** Other sized write accesses - not available for I/O ports. */
848#define DBGFBPIOACCESS_WRITE_OTHER UINT32_C(0x00001000)
849/** Write mask. */
850#define DBGFBPIOACCESS_WRITE_MASK UINT32_C(0x00001f00)
851
852/** All kind of access (read, write, all sizes). */
853#define DBGFBPIOACCESS_ALL UINT32_C(0x00001f1f)
854
855/** The acceptable mask for I/O ports. */
856#define DBGFBPIOACCESS_VALID_MASK_PORT_IO UINT32_C(0x00000303)
857/** The acceptable mask for MMIO. */
858#define DBGFBPIOACCESS_VALID_MASK_MMIO UINT32_C(0x00001f1f)
859/** @} */
860
861/**
862 * The visible breakpoint state (read-only).
863 */
864typedef struct DBGFBPPUB
865{
866 /** The number of breakpoint hits. */
867 uint64_t cHits;
868 /** The hit number which starts to trigger the breakpoint. */
869 uint64_t iHitTrigger;
870 /** The hit number which stops triggering the breakpoint (disables it).
871 * Use ~(uint64_t)0 if it should never stop. */
872 uint64_t iHitDisable;
873 /** The breakpoint owner handle (a nil owner defers the breakpoint to the
874 * debugger). */
875 DBGFBPOWNER hOwner;
876 /** Breakpoint type stored as a 16bit integer to stay within size limits. */
877 uint16_t u16Type;
878 /** Breakpoint flags. */
879 uint16_t fFlags;
880
881 /** Union of type specific data. */
882 union
883 {
884 /** The flat GC address breakpoint address for REG and INT3 breakpoints. */
885 RTGCUINTPTR GCPtr;
886
887 /** Debug register data. */
888 struct DBGFBPREG
889 {
890 /** The flat GC address of the breakpoint. */
891 RTGCUINTPTR GCPtr;
892 /** The debug register number. */
893 uint8_t iReg;
894 /** The access type (one of the X86_DR7_RW_* value). */
895 uint8_t fType;
896 /** The access size. */
897 uint8_t cb;
898 } Reg;
899
900 /** INT3 breakpoint data. */
901 struct DBGFBPINT3
902 {
903 /** The flat GC address of the breakpoint. */
904 RTGCUINTPTR GCPtr;
905 /** The physical address of the breakpoint. */
906 RTGCPHYS PhysAddr;
907 /** The byte value we replaced by the INT 3 instruction. */
908 uint8_t bOrg;
909 } Int3;
910
911 /** I/O port breakpoint data. */
912 struct DBGFBPPORTIO
913 {
914 /** The first port. */
915 RTIOPORT uPort;
916 /** The number of ports. */
917 RTIOPORT cPorts;
918 /** Valid DBGFBPIOACCESS_XXX selection, max DWORD size. */
919 uint32_t fAccess;
920 } PortIo;
921
922 /** Memory mapped I/O breakpoint data. */
923 struct DBGFBPMMIO
924 {
925 /** The first MMIO address. */
926 RTGCPHYS PhysAddr;
927 /** The size of the MMIO range in bytes. */
928 uint32_t cb;
929 /** Valid DBGFBPIOACCESS_XXX selection, max QWORD size. */
930 uint32_t fAccess;
931 } Mmio;
932
933 /** Padding to the anticipated size. */
934 uint64_t u64Padding[3];
935 } u;
936} DBGFBPPUB;
937AssertCompileSize(DBGFBPPUB, 64 - 8);
938AssertCompileMembersAtSameOffset(DBGFBPPUB, u.GCPtr, DBGFBPPUB, u.Reg.GCPtr);
939AssertCompileMembersAtSameOffset(DBGFBPPUB, u.GCPtr, DBGFBPPUB, u.Int3.GCPtr);
940
941/** Pointer to the visible breakpoint state. */
942typedef DBGFBPPUB *PDBGFBPPUB;
943/** Pointer to a const visible breakpoint state. */
944typedef const DBGFBPPUB *PCDBGFBPPUB;
945
946/** Sets the DBGFPUB::u16Type member. */
947#define DBGF_BP_PUB_MAKE_TYPE(a_enmType) ((uint16_t)(a_enmType))
948/** Returns the type of the DBGFPUB::u16Type member. */
949#define DBGF_BP_PUB_GET_TYPE(a_pBp) ((DBGFBPTYPE)((a_pBp)->u16Type))
950/** Returns the enabled status of DBGFPUB::fFlags member. */
951#define DBGF_BP_PUB_IS_ENABLED(a_pBp) RT_BOOL((a_pBp)->fFlags & DBGF_BP_F_ENABLED)
952/** Returns whether DBGF_BP_F_HIT_EXEC_BEFORE is set for DBGFPUB::fFlags. */
953#define DBGF_BP_PUB_IS_EXEC_BEFORE(a_pBp) RT_BOOL((a_pBp)->fFlags & DBGF_BP_F_HIT_EXEC_BEFORE)
954/** Returns whether DBGF_BP_F_HIT_EXEC_AFTER is set for DBGFPUB::fFlags. */
955#define DBGF_BP_PUB_IS_EXEC_AFTER(a_pBp) RT_BOOL((a_pBp)->fFlags & DBGF_BP_F_HIT_EXEC_AFTER)
956
957
958/** @name Possible DBGFBPPUB::fFlags flags.
959 * @{ */
960/** Default flags, breakpoint is enabled and hits before the instruction is executed. */
961#define DBGF_BP_F_DEFAULT (DBGF_BP_F_ENABLED | DBGF_BP_F_HIT_EXEC_BEFORE)
962/** Flag whether the breakpoint is enabled currently. */
963#define DBGF_BP_F_ENABLED RT_BIT(0)
964/** Flag indicating whether the action assoicated with the breakpoint should be carried out
965 * before the instruction causing the breakpoint to hit was executed. */
966#define DBGF_BP_F_HIT_EXEC_BEFORE RT_BIT(1)
967/** Flag indicating whether the action assoicated with the breakpoint should be carried out
968 * after the instruction causing the breakpoint to hit was executed. */
969#define DBGF_BP_F_HIT_EXEC_AFTER RT_BIT(2)
970/** @} */
971
972
973/**
974 * Breakpoint hit handler.
975 *
976 * @returns Strict VBox status code.
977 * @retval VINF_SUCCESS if the breakpoint was handled and guest execution can resume.
978 * @retval VINF_DBGF_BP_HALT if guest execution should be stopped and the debugger should be invoked.
979 * @retval VINF_DBGF_R3_BP_OWNER_DEFER return to ring-3 and invoke the owner callback there again.
980 *
981 * @param pVM The cross-context VM structure pointer.
982 * @param idCpu ID of the vCPU triggering the breakpoint.
983 * @param pvUserBp User argument of the set breakpoint.
984 * @param hBp The breakpoint handle.
985 * @param pBpPub Pointer to the readonly public state of the breakpoint.
986 * @param fFlags Flags indicating when the handler was called (DBGF_BP_F_HIT_EXEC_BEFORE vs DBGF_BP_F_HIT_EXEC_AFTER).
987 *
988 * @remarks The handler is called on the EMT of vCPU triggering the breakpoint and no locks are held.
989 * @remarks Any status code returned other than the ones mentioned will send the VM straight into a
990 * guru meditation.
991 */
992typedef DECLCALLBACKTYPE(VBOXSTRICTRC, FNDBGFBPHIT,(PVM pVM, VMCPUID idCpu, void *pvUserBp, DBGFBP hBp, PCDBGFBPPUB pBpPub,
993 uint16_t fFlags));
994/** Pointer to a FNDBGFBPHIT(). */
995typedef FNDBGFBPHIT *PFNDBGFBPHIT;
996
997
998#ifdef IN_RING3
999/** @defgroup grp_dbgf_bp_r3 The DBGF Breakpoint Host Context Ring-3 API
1000 * @{ */
1001VMMR3DECL(int) DBGFR3BpOwnerCreate(PUVM pUVM, PFNDBGFBPHIT pfnBpHit, PDBGFBPOWNER phBpOwner);
1002VMMR3DECL(int) DBGFR3BpOwnerDestroy(PUVM pUVM, DBGFBPOWNER hBpOwner);
1003
1004VMMR3DECL(int) DBGFR3BpSetInt3(PUVM pUVM, VMCPUID idSrcCpu, PCDBGFADDRESS pAddress,
1005 uint64_t iHitTrigger, uint64_t iHitDisable, PDBGFBP phBp);
1006VMMR3DECL(int) DBGFR3BpSetInt3Ex(PUVM pUVM, DBGFBPOWNER hOwner, void *pvUser,
1007 VMCPUID idSrcCpu, PCDBGFADDRESS pAddress, uint16_t fFlags,
1008 uint64_t iHitTrigger, uint64_t iHitDisable, PDBGFBP phBp);
1009VMMR3DECL(int) DBGFR3BpSetReg(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger,
1010 uint64_t iHitDisable, uint8_t fType, uint8_t cb, PDBGFBP phBp);
1011VMMR3DECL(int) DBGFR3BpSetRegEx(PUVM pUVM, DBGFBPOWNER hOwner, void *pvUser,
1012 PCDBGFADDRESS pAddress, uint16_t fFlags,
1013 uint64_t iHitTrigger, uint64_t iHitDisable,
1014 uint8_t fType, uint8_t cb, PDBGFBP phBp);
1015VMMR3DECL(int) DBGFR3BpSetREM(PUVM pUVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger,
1016 uint64_t iHitDisable, PDBGFBP phBp);
1017VMMR3DECL(int) DBGFR3BpSetPortIo(PUVM pUVM, RTIOPORT uPort, RTIOPORT cPorts, uint32_t fAccess,
1018 uint64_t iHitTrigger, uint64_t iHitDisable, PDBGFBP phBp);
1019VMMR3DECL(int) DBGFR3BpSetPortIoEx(PUVM pUVM, DBGFBPOWNER hOwner, void *pvUser,
1020 RTIOPORT uPort, RTIOPORT cPorts, uint32_t fAccess,
1021 uint64_t iHitTrigger, uint64_t iHitDisable, PDBGFBP phBp);
1022VMMR3DECL(int) DBGFR3BpSetMmio(PUVM pUVM, RTGCPHYS GCPhys, uint32_t cb, uint32_t fAccess,
1023 uint64_t iHitTrigger, uint64_t iHitDisable, PDBGFBP phBp);
1024VMMR3DECL(int) DBGFR3BpSetMmioEx(PUVM pUVM, DBGFBPOWNER hOwner, void *pvUser,
1025 RTGCPHYS GCPhys, uint32_t cb, uint32_t fAccess,
1026 uint64_t iHitTrigger, uint64_t iHitDisable, PDBGFBP phBp);
1027VMMR3DECL(int) DBGFR3BpClear(PUVM pUVM, DBGFBP hBp);
1028VMMR3DECL(int) DBGFR3BpEnable(PUVM pUVM, DBGFBP hBp);
1029VMMR3DECL(int) DBGFR3BpDisable(PUVM pUVM, DBGFBP hBp);
1030
1031/**
1032 * Breakpoint enumeration callback function.
1033 *
1034 * @returns VBox status code.
1035 * The enumeration stops on failure status and VINF_CALLBACK_RETURN.
1036 * @param pUVM The user mode VM handle.
1037 * @param pvUser The user argument.
1038 * @param hBp The breakpoint handle.
1039 * @param pBp Pointer to the public breakpoint information. (readonly)
1040 */
1041typedef DECLCALLBACKTYPE(int, FNDBGFBPENUM,(PUVM pUVM, void *pvUser, DBGFBP hBp, PCDBGFBPPUB pBpPub));
1042/** Pointer to a breakpoint enumeration callback function. */
1043typedef FNDBGFBPENUM *PFNDBGFBPENUM;
1044
1045VMMR3DECL(int) DBGFR3BpEnum(PUVM pUVM, PFNDBGFBPENUM pfnCallback, void *pvUser);
1046
1047VMMR3_INT_DECL(int) DBGFR3BpHit(PVM pVM, PVMCPU pVCpu);
1048/** @} */
1049#endif /* !IN_RING3 */
1050
1051
1052#if defined(IN_RING0) || defined(DOXYGEN_RUNNING)
1053/** @defgroup grp_dbgf_bp_r0 The DBGF Breakpoint Host Context Ring-0 API
1054 * @{ */
1055VMMR0_INT_DECL(void) DBGFR0InitPerVMData(PGVM pGVM);
1056VMMR0_INT_DECL(void) DBGFR0CleanupVM(PGVM pGVM);
1057
1058VMMR0_INT_DECL(int) DBGFR0BpOwnerSetUpContext(PGVM pGVM, DBGFBPOWNER hBpOwner, PFNDBGFBPHIT pfnBpHit);
1059VMMR0_INT_DECL(int) DBGFR0BpOwnerDestroyContext(PGVM pGVM, DBGFBPOWNER hBpOwner);
1060
1061VMMR0_INT_DECL(int) DBGFR0BpSetUpContext(PGVM pGVM, DBGFBP hBp, void *pvUser);
1062VMMR0_INT_DECL(int) DBGFR0BpDestroyContext(PGVM pGVM, DBGFBP hBp);
1063/** @} */
1064#endif /* IN_RING0 || DOXYGEN_RUNNING */
1065
1066VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM);
1067VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM);
1068VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM);
1069VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM);
1070VMM_INT_DECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM);
1071VMM_INT_DECL(bool) DBGFBpIsHwArmed(PVM pVM);
1072VMM_INT_DECL(bool) DBGFBpIsHwIoArmed(PVM pVM);
1073VMM_INT_DECL(bool) DBGFBpIsInt3Armed(PVM pVM);
1074VMM_INT_DECL(bool) DBGFIsStepping(PVMCPU pVCpu);
1075VMM_INT_DECL(VBOXSTRICTRC) DBGFBpCheckIo(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTIOPORT uIoPort, uint8_t cbValue);
1076VMM_INT_DECL(VBOXSTRICTRC) DBGFEventGenericWithArgs(PVM pVM, PVMCPU pVCpu, DBGFEVENTTYPE enmEvent, DBGFEVENTCTX enmCtx,
1077 unsigned cArgs, ...);
1078VMM_INT_DECL(int) DBGFTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6, bool fAltStepping);
1079VMM_INT_DECL(int) DBGFTrap03Handler(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTXCORE pRegFrame);
1080
1081
1082#ifdef IN_RING3 /* The CPU mode API only works in ring-3. */
1083VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu);
1084VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM);
1085VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu);
1086VMMR3DECL(bool) DBGFR3CpuIsInV86Code(PUVM pUVM, VMCPUID idCpu);
1087VMMR3DECL(const char *) DBGFR3CpuGetState(PUVM pUVM, VMCPUID idCpu);
1088#endif
1089
1090
1091
1092#ifdef IN_RING3 /* The info callbacks API only works in ring-3. */
1093
1094struct RTGETOPTSTATE;
1095union RTGETOPTUNION;
1096
1097/**
1098 * Info helper callback structure.
1099 */
1100typedef struct DBGFINFOHLP
1101{
1102 /**
1103 * Print formatted string.
1104 *
1105 * @param pHlp Pointer to this structure.
1106 * @param pszFormat The format string.
1107 * @param ... Arguments.
1108 */
1109 DECLCALLBACKMEMBER(void, pfnPrintf,(PCDBGFINFOHLP pHlp, const char *pszFormat, ...)) RT_IPRT_FORMAT_ATTR(2, 3);
1110
1111 /**
1112 * Print formatted string.
1113 *
1114 * @param pHlp Pointer to this structure.
1115 * @param pszFormat The format string.
1116 * @param args Argument list.
1117 */
1118 DECLCALLBACKMEMBER(void, pfnPrintfV,(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args)) RT_IPRT_FORMAT_ATTR(2, 0);
1119
1120 /**
1121 * Report getopt parsing trouble
1122 *
1123 * @param pHlp Pointer to this structure.
1124 * @param rc The RTGetOpt return value.
1125 * @param pValueUnion The value union.
1126 * @param pState The getopt state.
1127 */
1128 DECLCALLBACKMEMBER(void, pfnGetOptError,(PCDBGFINFOHLP pHlp, int rc, union RTGETOPTUNION *pValueUnion,
1129 struct RTGETOPTSTATE *pState));
1130} DBGFINFOHLP;
1131
1132
1133/**
1134 * Info handler, device version.
1135 *
1136 * @param pDevIns The device instance which registered the info.
1137 * @param pHlp Callback functions for doing output.
1138 * @param pszArgs Argument string. Optional and specific to the handler.
1139 */
1140typedef DECLCALLBACKTYPE(void, FNDBGFHANDLERDEV,(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs));
1141/** Pointer to a FNDBGFHANDLERDEV function. */
1142typedef FNDBGFHANDLERDEV *PFNDBGFHANDLERDEV;
1143
1144/**
1145 * Info handler, driver version.
1146 *
1147 * @param pDrvIns The driver instance which registered the info.
1148 * @param pHlp Callback functions for doing output.
1149 * @param pszArgs Argument string. Optional and specific to the handler.
1150 */
1151typedef DECLCALLBACKTYPE(void, FNDBGFHANDLERDRV,(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, const char *pszArgs));
1152/** Pointer to a FNDBGFHANDLERDRV function. */
1153typedef FNDBGFHANDLERDRV *PFNDBGFHANDLERDRV;
1154
1155/**
1156 * Info handler, internal version.
1157 *
1158 * @param pVM The cross context VM structure.
1159 * @param pHlp Callback functions for doing output.
1160 * @param pszArgs Argument string. Optional and specific to the handler.
1161 */
1162typedef DECLCALLBACKTYPE(void, FNDBGFHANDLERINT,(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs));
1163/** Pointer to a FNDBGFHANDLERINT function. */
1164typedef FNDBGFHANDLERINT *PFNDBGFHANDLERINT;
1165
1166/**
1167 * Info handler, external version.
1168 *
1169 * @param pvUser User argument.
1170 * @param pHlp Callback functions for doing output.
1171 * @param pszArgs Argument string. Optional and specific to the handler.
1172 */
1173typedef DECLCALLBACKTYPE(void, FNDBGFHANDLEREXT,(void *pvUser, PCDBGFINFOHLP pHlp, const char *pszArgs));
1174/** Pointer to a FNDBGFHANDLEREXT function. */
1175typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT;
1176
1177/**
1178 * Info handler, device version with argv.
1179 *
1180 * @param pDevIns The device instance which registered the info.
1181 * @param pHlp Callback functions for doing output.
1182 * @param cArgs Number of arguments.
1183 * @param papszArgs Argument vector.
1184 */
1185typedef DECLCALLBACKTYPE(void, FNDBGFINFOARGVDEV,(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs));
1186/** Pointer to a FNDBGFINFOARGVDEV function. */
1187typedef FNDBGFINFOARGVDEV *PFNDBGFINFOARGVDEV;
1188
1189/**
1190 * Info handler, USB device version with argv.
1191 *
1192 * @param pUsbIns The USB device instance which registered the info.
1193 * @param pHlp Callback functions for doing output.
1194 * @param cArgs Number of arguments.
1195 * @param papszArgs Argument vector.
1196 */
1197typedef DECLCALLBACKTYPE(void, FNDBGFINFOARGVUSB,(PPDMUSBINS pUsbIns, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs));
1198/** Pointer to a FNDBGFINFOARGVUSB function. */
1199typedef FNDBGFINFOARGVUSB *PFNDBGFINFOARGVUSB;
1200
1201/**
1202 * Info handler, driver version with argv.
1203 *
1204 * @param pDrvIns The driver instance which registered the info.
1205 * @param pHlp Callback functions for doing output.
1206 * @param cArgs Number of arguments.
1207 * @param papszArgs Argument vector.
1208 */
1209typedef DECLCALLBACKTYPE(void, FNDBGFINFOARGVDRV,(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs));
1210/** Pointer to a FNDBGFINFOARGVDRV function. */
1211typedef FNDBGFINFOARGVDRV *PFNDBGFINFOARGVDRV;
1212
1213/**
1214 * Info handler, internal version with argv.
1215 *
1216 * @param pVM The cross context VM structure.
1217 * @param pHlp Callback functions for doing output.
1218 * @param cArgs Number of arguments.
1219 * @param papszArgs Argument vector.
1220 */
1221typedef DECLCALLBACKTYPE(void, FNDBGFINFOARGVINT,(PVM pVM, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs));
1222/** Pointer to a FNDBGFINFOARGVINT function. */
1223typedef FNDBGFINFOARGVINT *PFNDBGFINFOARGVINT;
1224
1225/**
1226 * Info handler, external version with argv.
1227 *
1228 * @param pvUser User argument.
1229 * @param pHlp Callback functions for doing output.
1230 * @param cArgs Number of arguments.
1231 * @param papszArgs Argument vector.
1232 */
1233typedef DECLCALLBACKTYPE(void, FNDBGFINFOARGVEXT,(void *pvUser, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs));
1234/** Pointer to a FNDBGFINFOARGVEXT function. */
1235typedef FNDBGFINFOARGVEXT *PFNDBGFINFOARGVEXT;
1236
1237
1238/** @name Flags for the info registration functions.
1239 * @{ */
1240/** The handler must run on the EMT. */
1241#define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0)
1242/** Call on all EMTs when a specific isn't specified. */
1243#define DBGFINFO_FLAGS_ALL_EMTS RT_BIT(1)
1244/** @} */
1245
1246VMMR3_INT_DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
1247VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
1248VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
1249VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
1250VMMR3DECL(int) DBGFR3InfoRegisterExternal(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
1251
1252VMMR3_INT_DECL(int) DBGFR3InfoRegisterDeviceArgv(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVDEV pfnHandler, PPDMDEVINS pDevIns);
1253VMMR3_INT_DECL(int) DBGFR3InfoRegisterDriverArgv(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVDRV pfnHandler, PPDMDRVINS pDrvIns);
1254VMMR3_INT_DECL(int) DBGFR3InfoRegisterUsbArgv(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVUSB pfnHandler, PPDMUSBINS pUsbIns);
1255VMMR3_INT_DECL(int) DBGFR3InfoRegisterInternalArgv(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVINT pfnHandler, uint32_t fFlags);
1256VMMR3DECL(int) DBGFR3InfoRegisterExternalArgv(PUVM pUVM, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVEXT pfnHandler, void *pvUser);
1257
1258VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName);
1259VMMR3_INT_DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName);
1260VMMR3_INT_DECL(int) DBGFR3InfoDeregisterUsb(PVM pVM, PPDMUSBINS pDrvIns, const char *pszName);
1261VMMR3_INT_DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName);
1262VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PUVM pUVM, const char *pszName);
1263
1264VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
1265VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
1266VMMR3DECL(int) DBGFR3InfoLogRel(PUVM pUVM, const char *pszName, const char *pszArgs);
1267VMMR3DECL(int) DBGFR3InfoStdErr(PUVM pUVM, const char *pszName, const char *pszArgs);
1268VMMR3_INT_DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat,
1269 const char *pszSepFmt, PCDBGFINFOHLP pHlp);
1270
1271/** @def DBGFR3_INFO_LOG
1272 * Display a piece of info writing to the log if enabled.
1273 *
1274 * This is for execution on EMTs and will only show the items on the calling
1275 * EMT. This is to avoid deadlocking against other CPUs if a rendezvous is
1276 * initiated in parallel to this call. (Besides, nobody really wants or need
1277 * info for the other EMTs when using this macro.)
1278 *
1279 * @param a_pVM The shared VM handle.
1280 * @param a_pVCpu The cross context per CPU structure of the calling EMT.
1281 * @param a_pszName The identifier of the info to display.
1282 * @param a_pszArgs Arguments to the info handler.
1283 */
1284#ifdef LOG_ENABLED
1285# define DBGFR3_INFO_LOG(a_pVM, a_pVCpu, a_pszName, a_pszArgs) \
1286 do { \
1287 if (LogIsEnabled()) \
1288 DBGFR3InfoEx((a_pVM)->pUVM, (a_pVCpu)->idCpu, a_pszName, a_pszArgs, NULL); \
1289 } while (0)
1290#else
1291# define DBGFR3_INFO_LOG(a_pVM, a_pVCpu, a_pszName, a_pszArgs) do { } while (0)
1292#endif
1293
1294/** @def DBGFR3_INFO_LOG_SAFE
1295 * Display a piece of info (rendezvous safe) writing to the log if enabled.
1296 *
1297 * @param a_pVM The shared VM handle.
1298 * @param a_pszName The identifier of the info to display.
1299 * @param a_pszArgs Arguments to the info handler.
1300 *
1301 * @remarks Use DBGFR3_INFO_LOG where ever possible!
1302 */
1303#ifdef LOG_ENABLED
1304# define DBGFR3_INFO_LOG_SAFE(a_pVM, a_pszName, a_pszArgs) \
1305 do { \
1306 if (LogIsEnabled()) \
1307 DBGFR3Info((a_pVM)->pUVM, a_pszName, a_pszArgs, NULL); \
1308 } while (0)
1309#else
1310# define DBGFR3_INFO_LOG_SAFE(a_pVM, a_pszName, a_pszArgs) do { } while (0)
1311#endif
1312
1313/**
1314 * Enumeration callback for use with DBGFR3InfoEnum.
1315 *
1316 * @returns VBox status code.
1317 * A status code indicating failure will end the enumeration
1318 * and DBGFR3InfoEnum will return with that status code.
1319 * @param pUVM The user mode VM handle.
1320 * @param pszName Info identifier name.
1321 * @param pszDesc The description.
1322 */
1323typedef DECLCALLBACKTYPE(int, FNDBGFINFOENUM,(PUVM pUVM, const char *pszName, const char *pszDesc, void *pvUser));
1324/** Pointer to a FNDBGFINFOENUM function. */
1325typedef FNDBGFINFOENUM *PFNDBGFINFOENUM;
1326
1327VMMR3DECL(int) DBGFR3InfoEnum(PUVM pUVM, PFNDBGFINFOENUM pfnCallback, void *pvUser);
1328VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void);
1329VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void);
1330VMMR3DECL(void) DBGFR3InfoGenricGetOptError(PCDBGFINFOHLP pHlp, int rc, union RTGETOPTUNION *pValueUnion,
1331 struct RTGETOPTSTATE *pState);
1332
1333#endif /* IN_RING3 */
1334
1335
1336#ifdef IN_RING3 /* The log contrl API only works in ring-3. */
1337VMMR3DECL(int) DBGFR3LogModifyGroups(PUVM pUVM, const char *pszGroupSettings);
1338VMMR3DECL(int) DBGFR3LogModifyFlags(PUVM pUVM, const char *pszFlagSettings);
1339VMMR3DECL(int) DBGFR3LogModifyDestinations(PUVM pUVM, const char *pszDestSettings);
1340#endif /* IN_RING3 */
1341
1342#ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */
1343
1344/** Max length (including '\\0') of a symbol name. */
1345#define DBGF_SYMBOL_NAME_LENGTH 512
1346
1347/**
1348 * Debug symbol.
1349 */
1350typedef struct DBGFSYMBOL
1351{
1352 /** Symbol value (address). */
1353 RTGCUINTPTR Value;
1354 /** Symbol size. */
1355 uint32_t cb;
1356 /** Symbol Flags. (reserved). */
1357 uint32_t fFlags;
1358 /** Symbol name. */
1359 char szName[DBGF_SYMBOL_NAME_LENGTH];
1360} DBGFSYMBOL;
1361/** Pointer to debug symbol. */
1362typedef DBGFSYMBOL *PDBGFSYMBOL;
1363/** Pointer to const debug symbol. */
1364typedef const DBGFSYMBOL *PCDBGFSYMBOL;
1365
1366/**
1367 * Debug line number information.
1368 */
1369typedef struct DBGFLINE
1370{
1371 /** Address. */
1372 RTGCUINTPTR Address;
1373 /** Line number. */
1374 uint32_t uLineNo;
1375 /** Filename. */
1376 char szFilename[260];
1377} DBGFLINE;
1378/** Pointer to debug line number. */
1379typedef DBGFLINE *PDBGFLINE;
1380/** Pointer to const debug line number. */
1381typedef const DBGFLINE *PCDBGFLINE;
1382
1383/** @name Address spaces aliases.
1384 * @{ */
1385/** The guest global address space. */
1386#define DBGF_AS_GLOBAL ((RTDBGAS)-1)
1387/** The guest kernel address space.
1388 * This is usually resolves to the same as DBGF_AS_GLOBAL. */
1389#define DBGF_AS_KERNEL ((RTDBGAS)-2)
1390/** The physical address space. */
1391#define DBGF_AS_PHYS ((RTDBGAS)-3)
1392/** Raw-mode context. */
1393#define DBGF_AS_RC ((RTDBGAS)-4)
1394/** Ring-0 context. */
1395#define DBGF_AS_R0 ((RTDBGAS)-5)
1396/** Raw-mode context and then global guest context.
1397 * When used for looking up information, it works as if the call was first made
1398 * with DBGF_AS_RC and then on failure with DBGF_AS_GLOBAL. When called for
1399 * making address space changes, it works as if DBGF_AS_RC was used. */
1400#define DBGF_AS_RC_AND_GC_GLOBAL ((RTDBGAS)-6)
1401
1402/** The first special one. */
1403#define DBGF_AS_FIRST DBGF_AS_RC_AND_GC_GLOBAL
1404/** The last special one. */
1405#define DBGF_AS_LAST DBGF_AS_GLOBAL
1406#endif
1407/** The number of special address space handles. */
1408#define DBGF_AS_COUNT (6U)
1409#ifdef IN_RING3
1410/** Converts an alias handle to an array index. */
1411#define DBGF_AS_ALIAS_2_INDEX(hAlias) \
1412 ( (uintptr_t)(hAlias) - (uintptr_t)DBGF_AS_FIRST )
1413/** Predicat macro that check if the specified handle is an alias. */
1414#define DBGF_AS_IS_ALIAS(hAlias) \
1415 ( DBGF_AS_ALIAS_2_INDEX(hAlias) < DBGF_AS_COUNT )
1416/** Predicat macro that check if the specified alias is a fixed one or not. */
1417#define DBGF_AS_IS_FIXED_ALIAS(hAlias) \
1418 ( DBGF_AS_ALIAS_2_INDEX(hAlias) < (uintptr_t)DBGF_AS_PHYS - (uintptr_t)DBGF_AS_FIRST + 1U )
1419
1420/** @} */
1421
1422VMMR3DECL(RTDBGCFG) DBGFR3AsGetConfig(PUVM pUVM);
1423
1424VMMR3DECL(int) DBGFR3AsAdd(PUVM pUVM, RTDBGAS hDbgAs, RTPROCESS ProcId);
1425VMMR3DECL(int) DBGFR3AsDelete(PUVM pUVM, RTDBGAS hDbgAs);
1426VMMR3DECL(int) DBGFR3AsSetAlias(PUVM pUVM, RTDBGAS hAlias, RTDBGAS hAliasFor);
1427VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PUVM pUVM, RTDBGAS hAlias);
1428VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PUVM pUVM, RTDBGAS hAlias);
1429VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PUVM pUVM, const char *pszName);
1430VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PUVM pUVM, RTPROCESS ProcId);
1431
1432VMMR3DECL(int) DBGFR3AsLoadImage(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName,
1433 RTLDRARCH enmArch, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
1434VMMR3DECL(int) DBGFR3AsLoadMap(PUVM pUVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags);
1435VMMR3DECL(int) DBGFR3AsLinkModule(PUVM pUVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
1436VMMR3DECL(int) DBGFR3AsUnlinkModuleByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszModName);
1437
1438VMMR3DECL(int) DBGFR3AsSymbolByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t fFlags,
1439 PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
1440VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, uint32_t Flags,
1441 PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
1442VMMR3DECL(int) DBGFR3AsSymbolByName(PUVM pUVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
1443
1444VMMR3DECL(int) DBGFR3AsLineByAddr(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
1445 PRTGCINTPTR poffDisp, PRTDBGLINE pLine, PRTDBGMOD phMod);
1446VMMR3DECL(PRTDBGLINE) DBGFR3AsLineByAddrA(PUVM pUVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress,
1447 PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
1448
1449/** @name DBGFMOD_PE_F_XXX - flags for
1450 * @{ */
1451/** NT 3.1 images were a little different, so make allowances for that. */
1452#define DBGFMODINMEM_F_PE_NT31 RT_BIT_32(0)
1453/** No container fallback. */
1454#define DBGFMODINMEM_F_NO_CONTAINER_FALLBACK RT_BIT_32(1)
1455/** No in-memory reader fallback. */
1456#define DBGFMODINMEM_F_NO_READER_FALLBACK RT_BIT_32(2)
1457/** Valid flags. */
1458#define DBGFMODINMEM_F_VALID_MASK UINT32_C(0x00000007)
1459/** @} */
1460VMMR3DECL(int) DBGFR3ModInMem(PUVM pUVM, PCDBGFADDRESS pImageAddr, uint32_t fFlags, const char *pszName,
1461 const char *pszFilename, RTLDRARCH enmArch, uint32_t cbImage,
1462 PRTDBGMOD phDbgMod, PRTERRINFO pErrInfo);
1463
1464#endif /* IN_RING3 */
1465
1466#ifdef IN_RING3 /* The stack API only works in ring-3. */
1467
1468/** Pointer to stack frame info. */
1469typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
1470/** Pointer to const stack frame info. */
1471typedef struct DBGFSTACKFRAME const *PCDBGFSTACKFRAME;
1472/**
1473 * Info about a stack frame.
1474 */
1475typedef struct DBGFSTACKFRAME
1476{
1477 /** Frame number. */
1478 uint32_t iFrame;
1479 /** Frame flags (DBGFSTACKFRAME_FLAGS_XXX). */
1480 uint32_t fFlags;
1481 /** The stack address of the frame.
1482 * The off member is [e|r]sp and the Sel member is ss. */
1483 DBGFADDRESS AddrStack;
1484 /** The program counter (PC) address of the frame.
1485 * The off member is [e|r]ip and the Sel member is cs. */
1486 DBGFADDRESS AddrPC;
1487 /** Pointer to the symbol nearest the program counter (PC). NULL if not found. */
1488 PRTDBGSYMBOL pSymPC;
1489 /** Pointer to the linenumber nearest the program counter (PC). NULL if not found. */
1490 PRTDBGLINE pLinePC;
1491 /** The frame address.
1492 * The off member is [e|r]bp and the Sel member is ss. */
1493 DBGFADDRESS AddrFrame;
1494 /** The way this frame returns to the next one. */
1495 RTDBGRETURNTYPE enmReturnType;
1496
1497 /** The way the next frame returns.
1498 * Only valid when DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET is set. */
1499 RTDBGRETURNTYPE enmReturnFrameReturnType;
1500 /** The return frame address.
1501 * The off member is [e|r]bp and the Sel member is ss. */
1502 DBGFADDRESS AddrReturnFrame;
1503 /** The return stack address.
1504 * The off member is [e|r]sp and the Sel member is ss. */
1505 DBGFADDRESS AddrReturnStack;
1506
1507 /** The program counter (PC) address which the frame returns to.
1508 * The off member is [e|r]ip and the Sel member is cs. */
1509 DBGFADDRESS AddrReturnPC;
1510 /** Pointer to the symbol nearest the return PC. NULL if not found. */
1511 PRTDBGSYMBOL pSymReturnPC;
1512 /** Pointer to the linenumber nearest the return PC. NULL if not found. */
1513 PRTDBGLINE pLineReturnPC;
1514
1515 /** 32-bytes of stack arguments. */
1516 union
1517 {
1518 /** 64-bit view */
1519 uint64_t au64[4];
1520 /** 32-bit view */
1521 uint32_t au32[8];
1522 /** 16-bit view */
1523 uint16_t au16[16];
1524 /** 8-bit view */
1525 uint8_t au8[32];
1526 } Args;
1527
1528 /** Number of registers values we can be sure about.
1529 * @note This is generally zero in the first frame. */
1530 uint32_t cSureRegs;
1531 /** Registers we can be sure about (length given by cSureRegs). */
1532 struct DBGFREGVALEX *paSureRegs;
1533
1534 /** Pointer to the next frame.
1535 * Might not be used in some cases, so consider it internal. */
1536 PCDBGFSTACKFRAME pNextInternal;
1537 /** Pointer to the first frame.
1538 * Might not be used in some cases, so consider it internal. */
1539 PCDBGFSTACKFRAME pFirstInternal;
1540} DBGFSTACKFRAME;
1541
1542/** @name DBGFSTACKFRAME_FLAGS_XXX - DBGFSTACKFRAME Flags.
1543 * @{ */
1544/** This is the last stack frame we can read.
1545 * This flag is not set if the walk stop because of max dept or recursion. */
1546# define DBGFSTACKFRAME_FLAGS_LAST RT_BIT(1)
1547/** This is the last record because we detected a loop. */
1548# define DBGFSTACKFRAME_FLAGS_LOOP RT_BIT(2)
1549/** This is the last record because we reached the maximum depth. */
1550# define DBGFSTACKFRAME_FLAGS_MAX_DEPTH RT_BIT(3)
1551/** 16-bit frame. */
1552# define DBGFSTACKFRAME_FLAGS_16BIT RT_BIT(4)
1553/** 32-bit frame. */
1554# define DBGFSTACKFRAME_FLAGS_32BIT RT_BIT(5)
1555/** 64-bit frame. */
1556# define DBGFSTACKFRAME_FLAGS_64BIT RT_BIT(6)
1557/** Real mode or V86 frame. */
1558# define DBGFSTACKFRAME_FLAGS_REAL_V86 RT_BIT(7)
1559/** Is a trap frame (NT term). */
1560# define DBGFSTACKFRAME_FLAGS_TRAP_FRAME RT_BIT(8)
1561
1562/** Used Odd/even heuristics for far/near return. */
1563# define DBGFSTACKFRAME_FLAGS_USED_ODD_EVEN RT_BIT(29)
1564/** Set if we used unwind info to construct the frame. (Kind of internal.) */
1565# define DBGFSTACKFRAME_FLAGS_USED_UNWIND_INFO RT_BIT(30)
1566/** Internal: Unwind info used for the return frame. */
1567# define DBGFSTACKFRAME_FLAGS_UNWIND_INFO_RET RT_BIT(31)
1568/** @} */
1569
1570/** @name DBGFCODETYPE
1571 * @{ */
1572typedef enum DBGFCODETYPE
1573{
1574 /** The usual invalid 0 value. */
1575 DBGFCODETYPE_INVALID = 0,
1576 /** Stack walk for guest code. */
1577 DBGFCODETYPE_GUEST,
1578 /** Stack walk for hypervisor code. */
1579 DBGFCODETYPE_HYPER,
1580 /** Stack walk for ring 0 code. */
1581 DBGFCODETYPE_RING0,
1582 /** The usual 32-bit blowup. */
1583 DBGFCODETYPE_32BIT_HACK = 0x7fffffff
1584} DBGFCODETYPE;
1585/** @} */
1586
1587VMMR3DECL(int) DBGFR3StackWalkBegin(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType,
1588 PCDBGFSTACKFRAME *ppFirstFrame);
1589VMMR3DECL(int) DBGFR3StackWalkBeginEx(PUVM pUVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
1590 PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC,
1591 RTDBGRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
1592VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent);
1593VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
1594
1595#endif /* IN_RING3 */
1596
1597
1598#ifdef IN_RING3 /* The disassembly API only works in ring-3. */
1599
1600/** @name Flags to pass to DBGFR3DisasInstrEx().
1601 * @{ */
1602/** Disassemble the current guest instruction, with annotations. */
1603#define DBGF_DISAS_FLAGS_CURRENT_GUEST RT_BIT(0)
1604/** No annotations for current context. */
1605#define DBGF_DISAS_FLAGS_NO_ANNOTATION RT_BIT(2)
1606/** No symbol lookup. */
1607#define DBGF_DISAS_FLAGS_NO_SYMBOLS RT_BIT(3)
1608/** No instruction bytes. */
1609#define DBGF_DISAS_FLAGS_NO_BYTES RT_BIT(4)
1610/** No address in the output. */
1611#define DBGF_DISAS_FLAGS_NO_ADDRESS RT_BIT(5)
1612/** Disassemble original unpatched bytes (PATM). */
1613#define DBGF_DISAS_FLAGS_UNPATCHED_BYTES RT_BIT(7)
1614/** Annotate patched instructions. */
1615#define DBGF_DISAS_FLAGS_ANNOTATE_PATCHED RT_BIT(8)
1616/** Disassemble in the default mode of the specific context. */
1617#define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000)
1618/** Disassemble in 16-bit mode. */
1619#define DBGF_DISAS_FLAGS_16BIT_MODE UINT32_C(0x10000000)
1620/** Disassemble in 16-bit mode with real mode address translation. */
1621#define DBGF_DISAS_FLAGS_16BIT_REAL_MODE UINT32_C(0x20000000)
1622/** Disassemble in 32-bit mode. */
1623#define DBGF_DISAS_FLAGS_32BIT_MODE UINT32_C(0x30000000)
1624/** Disassemble in 64-bit mode. */
1625#define DBGF_DISAS_FLAGS_64BIT_MODE UINT32_C(0x40000000)
1626/** The disassembly mode mask. */
1627#define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000)
1628/** Mask containing the valid flags. */
1629#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x700001ff)
1630/** @} */
1631
1632/** Special flat selector. */
1633#define DBGF_SEL_FLAT 1
1634
1635VMMR3DECL(int) DBGFR3DisasInstrEx(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
1636 char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr);
1637VMMR3_INT_DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput);
1638VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix);
1639
1640/** @def DBGFR3_DISAS_INSTR_CUR_LOG
1641 * Disassembles the current guest context instruction and writes it to the log.
1642 * All registers and data will be displayed. Addresses will be attempted resolved to symbols.
1643 */
1644#ifdef LOG_ENABLED
1645# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) \
1646 do { \
1647 if (LogIsEnabled()) \
1648 DBGFR3DisasInstrCurrentLogInternal(pVCpu, pszPrefix); \
1649 } while (0)
1650#else
1651# define DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, pszPrefix) do { } while (0)
1652#endif
1653
1654VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix);
1655
1656/** @def DBGFR3_DISAS_INSTR_LOG
1657 * Disassembles the specified guest context instruction and writes it to the log.
1658 * Addresses will be attempted resolved to symbols.
1659 * @thread Any EMT.
1660 */
1661# ifdef LOG_ENABLED
1662# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) \
1663 do { \
1664 if (LogIsEnabled()) \
1665 DBGFR3DisasInstrLogInternal(pVCpu, Sel, GCPtr, pszPrefix); \
1666 } while (0)
1667# else
1668# define DBGFR3_DISAS_INSTR_LOG(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0)
1669# endif
1670#endif
1671
1672
1673#ifdef IN_RING3
1674VMMR3DECL(int) DBGFR3MemScan(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign,
1675 const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress);
1676VMMR3DECL(int) DBGFR3MemRead(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
1677VMMR3DECL(int) DBGFR3MemReadString(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
1678VMMR3DECL(int) DBGFR3MemWrite(PUVM pUVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead);
1679#endif
1680
1681
1682/** @name Flags for DBGFR3PagingDumpEx, PGMR3DumpHierarchyHCEx and
1683 * PGMR3DumpHierarchyGCEx
1684 * @{ */
1685/** The CR3 from the current CPU state. */
1686#define DBGFPGDMP_FLAGS_CURRENT_CR3 RT_BIT_32(0)
1687/** The current CPU paging mode (PSE, PAE, LM, EPT, NX). */
1688#define DBGFPGDMP_FLAGS_CURRENT_MODE RT_BIT_32(1)
1689/** Whether PSE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
1690 * Same value as X86_CR4_PSE. */
1691#define DBGFPGDMP_FLAGS_PSE RT_BIT_32(4) /* */
1692/** Whether PAE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
1693 * Same value as X86_CR4_PAE. */
1694#define DBGFPGDMP_FLAGS_PAE RT_BIT_32(5) /* */
1695/** Whether LME is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
1696 * Same value as MSR_K6_EFER_LME. */
1697#define DBGFPGDMP_FLAGS_LME RT_BIT_32(8)
1698/** Whether nested paging is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
1699#define DBGFPGDMP_FLAGS_NP RT_BIT_32(9)
1700/** Whether extended nested page tables are enabled
1701 * (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
1702#define DBGFPGDMP_FLAGS_EPT RT_BIT_32(10)
1703/** Whether no-execution is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
1704 * Same value as MSR_K6_EFER_NXE. */
1705#define DBGFPGDMP_FLAGS_NXE RT_BIT_32(11)
1706/** Whether to print the CR3. */
1707#define DBGFPGDMP_FLAGS_PRINT_CR3 RT_BIT_32(27)
1708/** Whether to print the header. */
1709#define DBGFPGDMP_FLAGS_HEADER RT_BIT_32(28)
1710/** Whether to dump additional page information. */
1711#define DBGFPGDMP_FLAGS_PAGE_INFO RT_BIT_32(29)
1712/** Dump the shadow tables if set.
1713 * Cannot be used together with DBGFPGDMP_FLAGS_GUEST. */
1714#define DBGFPGDMP_FLAGS_SHADOW RT_BIT_32(30)
1715/** Dump the guest tables if set.
1716 * Cannot be used together with DBGFPGDMP_FLAGS_SHADOW. */
1717#define DBGFPGDMP_FLAGS_GUEST RT_BIT_32(31)
1718/** Mask of valid bits. */
1719#define DBGFPGDMP_FLAGS_VALID_MASK UINT32_C(0xf8000f33)
1720/** The mask of bits controlling the paging mode. */
1721#define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32)
1722/** @} */
1723VMMDECL(int) DBGFR3PagingDumpEx(PUVM pUVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
1724 uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
1725
1726
1727/** @name DBGFR3SelQueryInfo flags.
1728 * @{ */
1729/** Get the info from the guest descriptor table.
1730 * @note This is more or less a given now when raw-mode was kicked out. */
1731#define DBGFSELQI_FLAGS_DT_GUEST UINT32_C(0)
1732/** If currently executing in in 64-bit mode, blow up data selectors. */
1733#define DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE UINT32_C(2)
1734/** @} */
1735VMMR3DECL(int) DBGFR3SelQueryInfo(PUVM pUVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo);
1736
1737
1738/**
1739 * Register identifiers.
1740 */
1741typedef enum DBGFREG
1742{
1743 /* General purpose registers: */
1744 DBGFREG_AL = 0,
1745 DBGFREG_AX = DBGFREG_AL,
1746 DBGFREG_EAX = DBGFREG_AL,
1747 DBGFREG_RAX = DBGFREG_AL,
1748
1749 DBGFREG_CL,
1750 DBGFREG_CX = DBGFREG_CL,
1751 DBGFREG_ECX = DBGFREG_CL,
1752 DBGFREG_RCX = DBGFREG_CL,
1753
1754 DBGFREG_DL,
1755 DBGFREG_DX = DBGFREG_DL,
1756 DBGFREG_EDX = DBGFREG_DL,
1757 DBGFREG_RDX = DBGFREG_DL,
1758
1759 DBGFREG_BL,
1760 DBGFREG_BX = DBGFREG_BL,
1761 DBGFREG_EBX = DBGFREG_BL,
1762 DBGFREG_RBX = DBGFREG_BL,
1763
1764 DBGFREG_SPL,
1765 DBGFREG_SP = DBGFREG_SPL,
1766 DBGFREG_ESP = DBGFREG_SPL,
1767 DBGFREG_RSP = DBGFREG_SPL,
1768
1769 DBGFREG_BPL,
1770 DBGFREG_BP = DBGFREG_BPL,
1771 DBGFREG_EBP = DBGFREG_BPL,
1772 DBGFREG_RBP = DBGFREG_BPL,
1773
1774 DBGFREG_SIL,
1775 DBGFREG_SI = DBGFREG_SIL,
1776 DBGFREG_ESI = DBGFREG_SIL,
1777 DBGFREG_RSI = DBGFREG_SIL,
1778
1779 DBGFREG_DIL,
1780 DBGFREG_DI = DBGFREG_DIL,
1781 DBGFREG_EDI = DBGFREG_DIL,
1782 DBGFREG_RDI = DBGFREG_DIL,
1783
1784 DBGFREG_R8,
1785 DBGFREG_R8B = DBGFREG_R8,
1786 DBGFREG_R8W = DBGFREG_R8,
1787 DBGFREG_R8D = DBGFREG_R8,
1788
1789 DBGFREG_R9,
1790 DBGFREG_R9B = DBGFREG_R9,
1791 DBGFREG_R9W = DBGFREG_R9,
1792 DBGFREG_R9D = DBGFREG_R9,
1793
1794 DBGFREG_R10,
1795 DBGFREG_R10B = DBGFREG_R10,
1796 DBGFREG_R10W = DBGFREG_R10,
1797 DBGFREG_R10D = DBGFREG_R10,
1798
1799 DBGFREG_R11,
1800 DBGFREG_R11B = DBGFREG_R11,
1801 DBGFREG_R11W = DBGFREG_R11,
1802 DBGFREG_R11D = DBGFREG_R11,
1803
1804 DBGFREG_R12,
1805 DBGFREG_R12B = DBGFREG_R12,
1806 DBGFREG_R12W = DBGFREG_R12,
1807 DBGFREG_R12D = DBGFREG_R12,
1808
1809 DBGFREG_R13,
1810 DBGFREG_R13B = DBGFREG_R13,
1811 DBGFREG_R13W = DBGFREG_R13,
1812 DBGFREG_R13D = DBGFREG_R13,
1813
1814 DBGFREG_R14,
1815 DBGFREG_R14B = DBGFREG_R14,
1816 DBGFREG_R14W = DBGFREG_R14,
1817 DBGFREG_R14D = DBGFREG_R14,
1818
1819 DBGFREG_R15,
1820 DBGFREG_R15B = DBGFREG_R15,
1821 DBGFREG_R15W = DBGFREG_R15,
1822 DBGFREG_R15D = DBGFREG_R15,
1823
1824 /* Segments and other special registers: */
1825 DBGFREG_CS,
1826 DBGFREG_CS_ATTR,
1827 DBGFREG_CS_BASE,
1828 DBGFREG_CS_LIMIT,
1829
1830 DBGFREG_DS,
1831 DBGFREG_DS_ATTR,
1832 DBGFREG_DS_BASE,
1833 DBGFREG_DS_LIMIT,
1834
1835 DBGFREG_ES,
1836 DBGFREG_ES_ATTR,
1837 DBGFREG_ES_BASE,
1838 DBGFREG_ES_LIMIT,
1839
1840 DBGFREG_FS,
1841 DBGFREG_FS_ATTR,
1842 DBGFREG_FS_BASE,
1843 DBGFREG_FS_LIMIT,
1844
1845 DBGFREG_GS,
1846 DBGFREG_GS_ATTR,
1847 DBGFREG_GS_BASE,
1848 DBGFREG_GS_LIMIT,
1849
1850 DBGFREG_SS,
1851 DBGFREG_SS_ATTR,
1852 DBGFREG_SS_BASE,
1853 DBGFREG_SS_LIMIT,
1854
1855 DBGFREG_IP,
1856 DBGFREG_EIP = DBGFREG_IP,
1857 DBGFREG_RIP = DBGFREG_IP,
1858
1859 DBGFREG_FLAGS,
1860 DBGFREG_EFLAGS = DBGFREG_FLAGS,
1861 DBGFREG_RFLAGS = DBGFREG_FLAGS,
1862
1863 /* FPU: */
1864 DBGFREG_FCW,
1865 DBGFREG_FSW,
1866 DBGFREG_FTW,
1867 DBGFREG_FOP,
1868 DBGFREG_FPUIP,
1869 DBGFREG_FPUCS,
1870 DBGFREG_FPUDP,
1871 DBGFREG_FPUDS,
1872 DBGFREG_MXCSR,
1873 DBGFREG_MXCSR_MASK,
1874
1875 DBGFREG_ST0,
1876 DBGFREG_ST1,
1877 DBGFREG_ST2,
1878 DBGFREG_ST3,
1879 DBGFREG_ST4,
1880 DBGFREG_ST5,
1881 DBGFREG_ST6,
1882 DBGFREG_ST7,
1883
1884 DBGFREG_MM0,
1885 DBGFREG_MM1,
1886 DBGFREG_MM2,
1887 DBGFREG_MM3,
1888 DBGFREG_MM4,
1889 DBGFREG_MM5,
1890 DBGFREG_MM6,
1891 DBGFREG_MM7,
1892
1893 /* SSE: */
1894 DBGFREG_XMM0,
1895 DBGFREG_XMM1,
1896 DBGFREG_XMM2,
1897 DBGFREG_XMM3,
1898 DBGFREG_XMM4,
1899 DBGFREG_XMM5,
1900 DBGFREG_XMM6,
1901 DBGFREG_XMM7,
1902 DBGFREG_XMM8,
1903 DBGFREG_XMM9,
1904 DBGFREG_XMM10,
1905 DBGFREG_XMM11,
1906 DBGFREG_XMM12,
1907 DBGFREG_XMM13,
1908 DBGFREG_XMM14,
1909 DBGFREG_XMM15,
1910 /** @todo add XMM aliases. */
1911
1912 /* AVX: */
1913 DBGFREG_YMM0,
1914 DBGFREG_YMM1,
1915 DBGFREG_YMM2,
1916 DBGFREG_YMM3,
1917 DBGFREG_YMM4,
1918 DBGFREG_YMM5,
1919 DBGFREG_YMM6,
1920 DBGFREG_YMM7,
1921 DBGFREG_YMM8,
1922 DBGFREG_YMM9,
1923 DBGFREG_YMM10,
1924 DBGFREG_YMM11,
1925 DBGFREG_YMM12,
1926 DBGFREG_YMM13,
1927 DBGFREG_YMM14,
1928 DBGFREG_YMM15,
1929
1930 /* System registers: */
1931 DBGFREG_GDTR_BASE,
1932 DBGFREG_GDTR_LIMIT,
1933 DBGFREG_IDTR_BASE,
1934 DBGFREG_IDTR_LIMIT,
1935 DBGFREG_LDTR,
1936 DBGFREG_LDTR_ATTR,
1937 DBGFREG_LDTR_BASE,
1938 DBGFREG_LDTR_LIMIT,
1939 DBGFREG_TR,
1940 DBGFREG_TR_ATTR,
1941 DBGFREG_TR_BASE,
1942 DBGFREG_TR_LIMIT,
1943
1944 DBGFREG_CR0,
1945 DBGFREG_CR2,
1946 DBGFREG_CR3,
1947 DBGFREG_CR4,
1948 DBGFREG_CR8,
1949
1950 DBGFREG_DR0,
1951 DBGFREG_DR1,
1952 DBGFREG_DR2,
1953 DBGFREG_DR3,
1954 DBGFREG_DR6,
1955 DBGFREG_DR7,
1956
1957 /* MSRs: */
1958 DBGFREG_MSR_IA32_APICBASE,
1959 DBGFREG_MSR_IA32_CR_PAT,
1960 DBGFREG_MSR_IA32_PERF_STATUS,
1961 DBGFREG_MSR_IA32_SYSENTER_CS,
1962 DBGFREG_MSR_IA32_SYSENTER_EIP,
1963 DBGFREG_MSR_IA32_SYSENTER_ESP,
1964 DBGFREG_MSR_IA32_TSC,
1965 DBGFREG_MSR_K6_EFER,
1966 DBGFREG_MSR_K6_STAR,
1967 DBGFREG_MSR_K8_CSTAR,
1968 DBGFREG_MSR_K8_FS_BASE,
1969 DBGFREG_MSR_K8_GS_BASE,
1970 DBGFREG_MSR_K8_KERNEL_GS_BASE,
1971 DBGFREG_MSR_K8_LSTAR,
1972 DBGFREG_MSR_K8_SF_MASK,
1973 DBGFREG_MSR_K8_TSC_AUX,
1974
1975 /** The number of registers to pass to DBGFR3RegQueryAll. */
1976 DBGFREG_ALL_COUNT,
1977
1978 /* Misc aliases that doesn't need be part of the 'all' query: */
1979 DBGFREG_AH = DBGFREG_ALL_COUNT,
1980 DBGFREG_CH,
1981 DBGFREG_DH,
1982 DBGFREG_BH,
1983 DBGFREG_GDTR,
1984 DBGFREG_IDTR,
1985
1986 /** The end of the registers. */
1987 DBGFREG_END,
1988 /** The usual 32-bit type hack. */
1989 DBGFREG_32BIT_HACK = 0x7fffffff
1990} DBGFREG;
1991/** Pointer to a register identifier. */
1992typedef DBGFREG *PDBGFREG;
1993/** Pointer to a const register identifier. */
1994typedef DBGFREG const *PCDBGFREG;
1995
1996/**
1997 * Register value type.
1998 */
1999typedef enum DBGFREGVALTYPE
2000{
2001 DBGFREGVALTYPE_INVALID = 0,
2002 /** Unsigned 8-bit register value. */
2003 DBGFREGVALTYPE_U8,
2004 /** Unsigned 16-bit register value. */
2005 DBGFREGVALTYPE_U16,
2006 /** Unsigned 32-bit register value. */
2007 DBGFREGVALTYPE_U32,
2008 /** Unsigned 64-bit register value. */
2009 DBGFREGVALTYPE_U64,
2010 /** Unsigned 128-bit register value. */
2011 DBGFREGVALTYPE_U128,
2012 /** Unsigned 256-bit register value. */
2013 DBGFREGVALTYPE_U256,
2014 /** Unsigned 512-bit register value. */
2015 DBGFREGVALTYPE_U512,
2016 /** Long double register value. */
2017 DBGFREGVALTYPE_R80,
2018 /** Descriptor table register value. */
2019 DBGFREGVALTYPE_DTR,
2020 /** End of the valid register value types. */
2021 DBGFREGVALTYPE_END,
2022 /** The usual 32-bit type hack. */
2023 DBGFREGVALTYPE_32BIT_HACK = 0x7fffffff
2024} DBGFREGVALTYPE;
2025/** Pointer to a register value type. */
2026typedef DBGFREGVALTYPE *PDBGFREGVALTYPE;
2027
2028/**
2029 * A generic register value type.
2030 */
2031typedef union DBGFREGVAL
2032{
2033 uint64_t au64[8]; /**< The 64-bit array view. First because of the initializer. */
2034 uint32_t au32[16]; /**< The 32-bit array view. */
2035 uint16_t au16[32]; /**< The 16-bit array view. */
2036 uint8_t au8[64]; /**< The 8-bit array view. */
2037
2038 uint8_t u8; /**< The 8-bit view. */
2039 uint16_t u16; /**< The 16-bit view. */
2040 uint32_t u32; /**< The 32-bit view. */
2041 uint64_t u64; /**< The 64-bit view. */
2042 RTUINT128U u128; /**< The 128-bit view. */
2043 RTUINT256U u256; /**< The 256-bit view. */
2044 RTUINT512U u512; /**< The 512-bit view. */
2045 RTFLOAT80U r80; /**< The 80-bit floating point view. */
2046 RTFLOAT80U2 r80Ex; /**< The 80-bit floating point view v2. */
2047 /** GDTR or LDTR (DBGFREGVALTYPE_DTR). */
2048 struct
2049 {
2050 /** The table address. */
2051 uint64_t u64Base;
2052 /** The table limit (length minus 1). */
2053 uint32_t u32Limit; /**< @todo Limit should be uint16_t */
2054 } dtr;
2055} DBGFREGVAL;
2056/** Pointer to a generic register value type. */
2057typedef DBGFREGVAL *PDBGFREGVAL;
2058/** Pointer to a const generic register value type. */
2059typedef DBGFREGVAL const *PCDBGFREGVAL;
2060
2061/** Initialize a DBGFREGVAL variable to all zeros. */
2062#define DBGFREGVAL_INITIALIZE_ZERO { { 0, 0, 0, 0, 0, 0, 0, 0 } }
2063/** Initialize a DBGFREGVAL variable to all bits set . */
2064#define DBGFREGVAL_INITIALIZE_FFFF { { UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX, UINT64_MAX } }
2065
2066/**
2067 * Extended register value, including register ID and type.
2068 *
2069 * This is currently only used by the stack walker.
2070 */
2071typedef struct DBGFREGVALEX
2072{
2073 /** The register value. */
2074 DBGFREGVAL Value;
2075 /** The register value type. */
2076 DBGFREGVALTYPE enmType;
2077 /** The register ID, DBGFREG_END if not applicable. */
2078 DBGFREG enmReg;
2079 /** Pointer to read-only register name string if no register ID could be found. */
2080 const char *pszName;
2081} DBGFREGVALEX;
2082/** Pointer to an extended register value struct. */
2083typedef DBGFREGVALEX *PDBGFREGVALEX;
2084/** Pointer to a const extended register value struct. */
2085typedef DBGFREGVALEX const *PCDBGFREGVALEX;
2086
2087
2088VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial);
2089VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType,
2090 unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
2091
2092/**
2093 * Register sub-field descriptor.
2094 */
2095typedef struct DBGFREGSUBFIELD
2096{
2097 /** The name of the sub-field. NULL is used to terminate the array. */
2098 const char *pszName;
2099 /** The index of the first bit. Ignored if pfnGet is set. */
2100 uint8_t iFirstBit;
2101 /** The number of bits. Mandatory. */
2102 uint8_t cBits;
2103 /** The shift count. Not applied when pfnGet is set, but used to
2104 * calculate the minimum type. */
2105 int8_t cShift;
2106 /** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */
2107 uint8_t fFlags;
2108 /** Getter (optional).
2109 * @remarks Does not take the device lock or anything like that.
2110 */
2111 DECLCALLBACKMEMBER(int, pfnGet,(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue));
2112 /** Setter (optional).
2113 * @remarks Does not take the device lock or anything like that.
2114 */
2115 DECLCALLBACKMEMBER(int, pfnSet,(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask));
2116} DBGFREGSUBFIELD;
2117/** Pointer to a const register sub-field descriptor. */
2118typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD;
2119
2120/** @name DBGFREGSUBFIELD_FLAGS_XXX
2121 * @{ */
2122/** The sub-field is read-only. */
2123#define DBGFREGSUBFIELD_FLAGS_READ_ONLY UINT8_C(0x01)
2124/** @} */
2125
2126/** Macro for creating a read-write sub-field entry without getters. */
2127#define DBGFREGSUBFIELD_RW(a_szName, a_iFirstBit, a_cBits, a_cShift) \
2128 { a_szName, a_iFirstBit, a_cBits, a_cShift, 0 /*fFlags*/, NULL /*pfnGet*/, NULL /*pfnSet*/ }
2129/** Macro for creating a read-write sub-field entry with getters. */
2130#define DBGFREGSUBFIELD_RW_SG(a_szName, a_cBits, a_cShift, a_pfnGet, a_pfnSet) \
2131 { a_szName, 0 /*iFirstBit*/, a_cBits, a_cShift, 0 /*fFlags*/, a_pfnGet, a_pfnSet }
2132/** Macro for creating a read-only sub-field entry without getters. */
2133#define DBGFREGSUBFIELD_RO(a_szName, a_iFirstBit, a_cBits, a_cShift) \
2134 { a_szName, a_iFirstBit, a_cBits, a_cShift, DBGFREGSUBFIELD_FLAGS_READ_ONLY, NULL /*pfnGet*/, NULL /*pfnSet*/ }
2135/** Macro for creating a terminator sub-field entry. */
2136#define DBGFREGSUBFIELD_TERMINATOR() \
2137 { NULL, 0, 0, 0, 0, NULL, NULL }
2138
2139/**
2140 * Register alias descriptor.
2141 */
2142typedef struct DBGFREGALIAS
2143{
2144 /** The alias name. NULL is used to terminate the array. */
2145 const char *pszName;
2146 /** Set to a valid type if the alias has a different type. */
2147 DBGFREGVALTYPE enmType;
2148} DBGFREGALIAS;
2149/** Pointer to a const register alias descriptor. */
2150typedef DBGFREGALIAS const *PCDBGFREGALIAS;
2151
2152/**
2153 * Register descriptor.
2154 */
2155typedef struct DBGFREGDESC
2156{
2157 /** The normal register name. */
2158 const char *pszName;
2159 /** The register identifier if this is a CPU register. */
2160 DBGFREG enmReg;
2161 /** The default register type. */
2162 DBGFREGVALTYPE enmType;
2163 /** Flags, see DBGFREG_FLAGS_XXX. */
2164 uint32_t fFlags;
2165 /** The internal register indicator.
2166 * For CPU registers this is the offset into the CPUMCTX structure,
2167 * thuse the 'off' prefix. */
2168 uint32_t offRegister;
2169 /** Getter.
2170 * @remarks Does not take the device lock or anything like that.
2171 */
2172 DECLCALLBACKMEMBER(int, pfnGet,(void *pvUser, struct DBGFREGDESC const *pDesc, PDBGFREGVAL pValue));
2173 /** Setter.
2174 * @remarks Does not take the device lock or anything like that.
2175 */
2176 DECLCALLBACKMEMBER(int, pfnSet,(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask));
2177 /** Aliases (optional). */
2178 PCDBGFREGALIAS paAliases;
2179 /** Sub fields (optional). */
2180 PCDBGFREGSUBFIELD paSubFields;
2181} DBGFREGDESC;
2182
2183/** @name Macros for constructing DBGFREGDESC arrays.
2184 * @{ */
2185#define DBGFREGDESC_RW(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
2186 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
2187#define DBGFREGDESC_RO(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
2188 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
2189#define DBGFREGDESC_RW_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
2190 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
2191#define DBGFREGDESC_RO_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
2192 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
2193#define DBGFREGDESC_RW_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
2194 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
2195#define DBGFREGDESC_RO_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
2196 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
2197#define DBGFREGDESC_RW_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
2198 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
2199#define DBGFREGDESC_RO_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
2200 { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
2201#define DBGFREGDESC_TERMINATOR() \
2202 { NULL, DBGFREG_END, DBGFREGVALTYPE_INVALID, 0, 0, NULL, NULL, NULL, NULL }
2203/** @} */
2204
2205
2206/** @name DBGFREG_FLAGS_XXX
2207 * @{ */
2208/** The register is read-only. */
2209#define DBGFREG_FLAGS_READ_ONLY RT_BIT_32(0)
2210/** @} */
2211
2212/**
2213 * Entry in a batch query or set operation.
2214 */
2215typedef struct DBGFREGENTRY
2216{
2217 /** The register identifier. */
2218 DBGFREG enmReg;
2219 /** The size of the value in bytes. */
2220 DBGFREGVALTYPE enmType;
2221 /** The register value. The valid view is indicated by enmType. */
2222 DBGFREGVAL Val;
2223} DBGFREGENTRY;
2224/** Pointer to a register entry in a batch operation. */
2225typedef DBGFREGENTRY *PDBGFREGENTRY;
2226/** Pointer to a const register entry in a batch operation. */
2227typedef DBGFREGENTRY const *PCDBGFREGENTRY;
2228
2229/** Used with DBGFR3Reg* to indicate the hypervisor register set instead of the
2230 * guest. */
2231#define DBGFREG_HYPER_VMCPUID UINT32_C(0x01000000)
2232
2233VMMR3DECL(int) DBGFR3RegCpuQueryU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8);
2234VMMR3DECL(int) DBGFR3RegCpuQueryU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16);
2235VMMR3DECL(int) DBGFR3RegCpuQueryU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32);
2236VMMR3DECL(int) DBGFR3RegCpuQueryU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64);
2237VMMR3DECL(int) DBGFR3RegCpuQueryU128(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128);
2238VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd);
2239VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit);
2240#if 0
2241VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PUVM pUVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
2242VMMR3DECL(int) DBGFR3RegCpuQueryAll( PUVM pUVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
2243
2244VMMR3DECL(int) DBGFR3RegCpuSetU8( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8);
2245VMMR3DECL(int) DBGFR3RegCpuSetU16( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16);
2246VMMR3DECL(int) DBGFR3RegCpuSetU32( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32);
2247VMMR3DECL(int) DBGFR3RegCpuSetU64( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64);
2248VMMR3DECL(int) DBGFR3RegCpuSetU128( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128);
2249VMMR3DECL(int) DBGFR3RegCpuSetLrd( PUVM pUVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd);
2250VMMR3DECL(int) DBGFR3RegCpuSetBatch( PUVM pUVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs);
2251#endif
2252
2253VMMR3DECL(const char *) DBGFR3RegCpuName(PUVM pUVM, DBGFREG enmReg, DBGFREGVALTYPE enmType);
2254
2255VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs);
2256VMMR3_INT_DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns,
2257 const char *pszPrefix, uint32_t iInstance);
2258
2259/**
2260 * Entry in a named batch query or set operation.
2261 */
2262typedef struct DBGFREGENTRYNM
2263{
2264 /** The register name. */
2265 const char *pszName;
2266 /** The size of the value in bytes. */
2267 DBGFREGVALTYPE enmType;
2268 /** The register value. The valid view is indicated by enmType. */
2269 DBGFREGVAL Val;
2270} DBGFREGENTRYNM;
2271/** Pointer to a named register entry in a batch operation. */
2272typedef DBGFREGENTRYNM *PDBGFREGENTRYNM;
2273/** Pointer to a const named register entry in a batch operation. */
2274typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM;
2275
2276VMMR3DECL(int) DBGFR3RegNmValidate( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg);
2277
2278VMMR3DECL(int) DBGFR3RegNmQuery( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType);
2279VMMR3DECL(int) DBGFR3RegNmQueryU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8);
2280VMMR3DECL(int) DBGFR3RegNmQueryU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16);
2281VMMR3DECL(int) DBGFR3RegNmQueryU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32);
2282VMMR3DECL(int) DBGFR3RegNmQueryU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64);
2283VMMR3DECL(int) DBGFR3RegNmQueryU128(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128);
2284/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
2285VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
2286VMMR3DECL(int) DBGFR3RegNmQueryBatch(PUVM pUVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
2287VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PUVM pUVM, size_t *pcRegs);
2288VMMR3DECL(int) DBGFR3RegNmQueryAll( PUVM pUVM, PDBGFREGENTRYNM paRegs, size_t cRegs);
2289
2290VMMR3DECL(int) DBGFR3RegNmSet( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType);
2291VMMR3DECL(int) DBGFR3RegNmSetU8( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8);
2292VMMR3DECL(int) DBGFR3RegNmSetU16( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16);
2293VMMR3DECL(int) DBGFR3RegNmSetU32( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32);
2294VMMR3DECL(int) DBGFR3RegNmSetU64( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64);
2295VMMR3DECL(int) DBGFR3RegNmSetU128( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128);
2296VMMR3DECL(int) DBGFR3RegNmSetLrd( PUVM pUVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
2297VMMR3DECL(int) DBGFR3RegNmSetBatch( PUVM pUVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
2298
2299/** @todo add enumeration methods. */
2300
2301VMMR3DECL(int) DBGFR3RegPrintf( PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
2302VMMR3DECL(int) DBGFR3RegPrintfV(PUVM pUVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va);
2303
2304
2305#ifdef IN_RING3
2306
2307/**
2308 * Guest OS digger interface identifier.
2309 *
2310 * This is for use together with PDBGFR3QueryInterface and is used to
2311 * obtain access to optional interfaces.
2312 */
2313typedef enum DBGFOSINTERFACE
2314{
2315 /** The usual invalid entry. */
2316 DBGFOSINTERFACE_INVALID = 0,
2317 /** Process info. */
2318 DBGFOSINTERFACE_PROCESS,
2319 /** Thread info. */
2320 DBGFOSINTERFACE_THREAD,
2321 /** Kernel message log - DBGFOSIDMESG. */
2322 DBGFOSINTERFACE_DMESG,
2323 /** Windows NT specifics (for the communication with the KD debugger stub). */
2324 DBGFOSINTERFACE_WINNT,
2325 /** The end of the valid entries. */
2326 DBGFOSINTERFACE_END,
2327 /** The usual 32-bit type blowup. */
2328 DBGFOSINTERFACE_32BIT_HACK = 0x7fffffff
2329} DBGFOSINTERFACE;
2330/** Pointer to a Guest OS digger interface identifier. */
2331typedef DBGFOSINTERFACE *PDBGFOSINTERFACE;
2332/** Pointer to a const Guest OS digger interface identifier. */
2333typedef DBGFOSINTERFACE const *PCDBGFOSINTERFACE;
2334
2335
2336/**
2337 * Guest OS Digger Registration Record.
2338 *
2339 * This is used with the DBGFR3OSRegister() API.
2340 */
2341typedef struct DBGFOSREG
2342{
2343 /** Magic value (DBGFOSREG_MAGIC). */
2344 uint32_t u32Magic;
2345 /** Flags. Reserved. */
2346 uint32_t fFlags;
2347 /** The size of the instance data. */
2348 uint32_t cbData;
2349 /** Operative System name. */
2350 char szName[24];
2351
2352 /**
2353 * Constructs the instance.
2354 *
2355 * @returns VBox status code.
2356 * @param pUVM The user mode VM handle.
2357 * @param pvData Pointer to the instance data.
2358 */
2359 DECLCALLBACKMEMBER(int, pfnConstruct,(PUVM pUVM, void *pvData));
2360
2361 /**
2362 * Destroys the instance.
2363 *
2364 * @param pUVM The user mode VM handle.
2365 * @param pvData Pointer to the instance data.
2366 */
2367 DECLCALLBACKMEMBER(void, pfnDestruct,(PUVM pUVM, void *pvData));
2368
2369 /**
2370 * Probes the guest memory for OS finger prints.
2371 *
2372 * No setup or so is performed, it will be followed by a call to pfnInit
2373 * or pfnRefresh that should take care of that.
2374 *
2375 * @returns true if is an OS handled by this module, otherwise false.
2376 * @param pUVM The user mode VM handle.
2377 * @param pvData Pointer to the instance data.
2378 */
2379 DECLCALLBACKMEMBER(bool, pfnProbe,(PUVM pUVM, void *pvData));
2380
2381 /**
2382 * Initializes a fresly detected guest, loading symbols and such useful stuff.
2383 *
2384 * This is called after pfnProbe.
2385 *
2386 * @returns VBox status code.
2387 * @param pUVM The user mode VM handle.
2388 * @param pvData Pointer to the instance data.
2389 */
2390 DECLCALLBACKMEMBER(int, pfnInit,(PUVM pUVM, void *pvData));
2391
2392 /**
2393 * Refreshes symbols and stuff following a redetection of the same OS.
2394 *
2395 * This is called after pfnProbe.
2396 *
2397 * @returns VBox status code.
2398 * @param pUVM The user mode VM handle.
2399 * @param pvData Pointer to the instance data.
2400 */
2401 DECLCALLBACKMEMBER(int, pfnRefresh,(PUVM pUVM, void *pvData));
2402
2403 /**
2404 * Terminates an OS when a new (or none) OS has been detected,
2405 * and before destruction.
2406 *
2407 * This is called after pfnProbe and if needed before pfnDestruct.
2408 *
2409 * @param pUVM The user mode VM handle.
2410 * @param pvData Pointer to the instance data.
2411 */
2412 DECLCALLBACKMEMBER(void, pfnTerm,(PUVM pUVM, void *pvData));
2413
2414 /**
2415 * Queries the version of the running OS.
2416 *
2417 * This is only called after pfnInit().
2418 *
2419 * @returns VBox status code.
2420 * @param pUVM The user mode VM handle.
2421 * @param pvData Pointer to the instance data.
2422 * @param pszVersion Where to store the version string.
2423 * @param cchVersion The size of the version string buffer.
2424 */
2425 DECLCALLBACKMEMBER(int, pfnQueryVersion,(PUVM pUVM, void *pvData, char *pszVersion, size_t cchVersion));
2426
2427 /**
2428 * Queries the pointer to a interface.
2429 *
2430 * This is called after pfnProbe.
2431 *
2432 * The returned interface must be valid until pfnDestruct is called. Two calls
2433 * to this method with the same @a enmIf value must return the same pointer.
2434 *
2435 * @returns Pointer to the interface if available, NULL if not available.
2436 * @param pUVM The user mode VM handle.
2437 * @param pvData Pointer to the instance data.
2438 * @param enmIf The interface identifier.
2439 */
2440 DECLCALLBACKMEMBER(void *, pfnQueryInterface,(PUVM pUVM, void *pvData, DBGFOSINTERFACE enmIf));
2441
2442 /**
2443 * Stack unwind assist callback.
2444 *
2445 * This is only called after pfnInit().
2446 *
2447 * @returns VBox status code (allocation error or something of similar fatality).
2448 * @param pUVM The user mode VM handle.
2449 * @param pvData Pointer to the instance data.
2450 * @param idCpu The CPU that's unwinding it's stack.
2451 * @param pFrame The current frame. Okay to modify it a little.
2452 * @param pState The unwind state. Okay to modify it.
2453 * @param pInitialCtx The initial register context.
2454 * @param hAs The address space being used for the unwind.
2455 * @param puScratch Scratch area (initialized to zero, no dtor).
2456 */
2457 DECLCALLBACKMEMBER(int, pfnStackUnwindAssist,(PUVM pUVM, void *pvData, VMCPUID idCpu, PDBGFSTACKFRAME pFrame,
2458 PRTDBGUNWINDSTATE pState, PCCPUMCTX pInitialCtx, RTDBGAS hAs,
2459 uint64_t *puScratch));
2460
2461 /** Trailing magic (DBGFOSREG_MAGIC). */
2462 uint32_t u32EndMagic;
2463} DBGFOSREG;
2464/** Pointer to a Guest OS digger registration record. */
2465typedef DBGFOSREG *PDBGFOSREG;
2466/** Pointer to a const Guest OS digger registration record. */
2467typedef DBGFOSREG const *PCDBGFOSREG;
2468
2469/** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */
2470#define DBGFOSREG_MAGIC 0x19830808
2471
2472
2473/**
2474 * Interface for querying kernel log messages (DBGFOSINTERFACE_DMESG).
2475 */
2476typedef struct DBGFOSIDMESG
2477{
2478 /** Trailing magic (DBGFOSIDMESG_MAGIC). */
2479 uint32_t u32Magic;
2480
2481 /**
2482 * Query the kernel log.
2483 *
2484 * @returns VBox status code.
2485 * @retval VERR_NOT_FOUND if the messages could not be located.
2486 * @retval VERR_INVALID_STATE if the messages was found to have unknown/invalid
2487 * format.
2488 * @retval VERR_BUFFER_OVERFLOW if the buffer isn't large enough, pcbActual
2489 * will be set to the required buffer size. The buffer, however, will
2490 * be filled with as much data as it can hold (properly zero terminated
2491 * of course).
2492 *
2493 * @param pThis Pointer to the interface structure.
2494 * @param pUVM The user mode VM handle.
2495 * @param fFlags Flags reserved for future use, MBZ.
2496 * @param cMessages The number of messages to retrieve, counting from the
2497 * end of the log (i.e. like tail), use UINT32_MAX for all.
2498 * @param pszBuf The output buffer.
2499 * @param cbBuf The buffer size.
2500 * @param pcbActual Where to store the number of bytes actually returned,
2501 * including zero terminator. On VERR_BUFFER_OVERFLOW this
2502 * holds the necessary buffer size. Optional.
2503 */
2504 DECLCALLBACKMEMBER(int, pfnQueryKernelLog,(struct DBGFOSIDMESG *pThis, PUVM pUVM, uint32_t fFlags, uint32_t cMessages,
2505 char *pszBuf, size_t cbBuf, size_t *pcbActual));
2506 /** Trailing magic (DBGFOSIDMESG_MAGIC). */
2507 uint32_t u32EndMagic;
2508} DBGFOSIDMESG;
2509/** Pointer to the interface for query kernel log messages (DBGFOSINTERFACE_DMESG). */
2510typedef DBGFOSIDMESG *PDBGFOSIDMESG;
2511/** Magic value for DBGFOSIDMESG::32Magic and DBGFOSIDMESG::u32EndMagic. (Kenazburo Oe) */
2512#define DBGFOSIDMESG_MAGIC UINT32_C(0x19350131)
2513
2514
2515/**
2516 * Interface for querying Windows NT guest specifics (DBGFOSINTERFACE_WINNT).
2517 */
2518typedef struct DBGFOSIWINNT
2519{
2520 /** Trailing magic (DBGFOSIWINNT_MAGIC). */
2521 uint32_t u32Magic;
2522
2523 /**
2524 * Queries version information.
2525 *
2526 * @returns VBox status code.
2527 * @param pThis Pointer to the interface structure.
2528 * @param pUVM The user mode VM handle.
2529 * @param puVersMajor Where to store the major version part, optional.
2530 * @param puVersMinor Where to store the minor version part, optional.
2531 * @param puBuildNumber Where to store the build number, optional.
2532 * @param pf32Bit Where to store the flag whether this is a 32bit Windows NT, optional.
2533 */
2534 DECLCALLBACKMEMBER(int, pfnQueryVersion,(struct DBGFOSIWINNT *pThis, PUVM pUVM,
2535 uint32_t *puVersMajor, uint32_t *puVersMinor,
2536 uint32_t *puBuildNumber, bool *pf32Bit));
2537
2538 /**
2539 * Queries some base kernel pointers.
2540 *
2541 * @returns VBox status code.
2542 * @param pThis Pointer to the interface structure.
2543 * @param pUVM The user mode VM handle.
2544 * @param pGCPtrKernBase Where to store the kernel base on success.
2545 * @param pGCPtrPsLoadedModuleList Where to store the pointer to the laoded module list head on success.
2546 */
2547 DECLCALLBACKMEMBER(int, pfnQueryKernelPtrs,(struct DBGFOSIWINNT *pThis, PUVM pUVM,
2548 PRTGCUINTPTR pGCPtrKernBase, PRTGCUINTPTR pGCPtrPsLoadedModuleList));
2549
2550 /**
2551 * Queries KPCR and KPCRB pointers for the given vCPU.
2552 *
2553 * @returns VBox status code.
2554 * @param pThis Pointer to the interface structure.
2555 * @param pUVM The user mode VM handle.
2556 * @param idCpu The vCPU to query the KPCR/KPCRB for.
2557 * @param pKpcr Where to store the KPCR pointer on success, optional.
2558 * @param pKpcrb Where to store the KPCR pointer on success, optional.
2559 */
2560 DECLCALLBACKMEMBER(int, pfnQueryKpcrForVCpu,(struct DBGFOSIWINNT *pThis, PUVM pUVM, VMCPUID idCpu,
2561 PRTGCUINTPTR pKpcr, PRTGCUINTPTR pKpcrb));
2562
2563 /**
2564 * Queries the current thread for the given vCPU.
2565 *
2566 * @returns VBox status code.
2567 * @param pThis Pointer to the interface structure.
2568 * @param pUVM The user mode VM handle.
2569 * @param idCpu The vCPU to query the KPCR/KPCRB for.
2570 * @param pCurThrd Where to store the CurrentThread pointer on success.
2571 */
2572 DECLCALLBACKMEMBER(int, pfnQueryCurThrdForVCpu,(struct DBGFOSIWINNT *pThis, PUVM pUVM, VMCPUID idCpu,
2573 PRTGCUINTPTR pCurThrd));
2574
2575 /** Trailing magic (DBGFOSIWINNT_MAGIC). */
2576 uint32_t u32EndMagic;
2577} DBGFOSIWINNT;
2578/** Pointer to the interface for query kernel log messages (DBGFOSINTERFACE_WINNT). */
2579typedef DBGFOSIWINNT *PDBGFOSIWINNT;
2580/** Magic value for DBGFOSIWINNT::32Magic and DBGFOSIWINNT::u32EndMagic. (Dave Cutler) */
2581#define DBGFOSIWINNT_MAGIC UINT32_C(0x19420313)
2582
2583
2584VMMR3DECL(int) DBGFR3OSRegister(PUVM pUVM, PCDBGFOSREG pReg);
2585VMMR3DECL(int) DBGFR3OSDeregister(PUVM pUVM, PCDBGFOSREG pReg);
2586VMMR3DECL(int) DBGFR3OSDetect(PUVM pUVM, char *pszName, size_t cchName);
2587VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PUVM pUVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion);
2588VMMR3DECL(void *) DBGFR3OSQueryInterface(PUVM pUVM, DBGFOSINTERFACE enmIf);
2589
2590
2591VMMR3DECL(int) DBGFR3CoreWrite(PUVM pUVM, const char *pszFilename, bool fReplaceFile);
2592
2593
2594
2595/** @defgroup grp_dbgf_plug_in The DBGF Plug-in Interface
2596 * @{
2597 */
2598
2599/** The plug-in module name prefix. */
2600# define DBGF_PLUG_IN_PREFIX "DbgPlugIn"
2601
2602/** The name of the plug-in entry point (FNDBGFPLUGIN) */
2603# define DBGF_PLUG_IN_ENTRYPOINT "DbgPlugInEntry"
2604
2605/**
2606 * DBGF plug-in operations.
2607 */
2608typedef enum DBGFPLUGINOP
2609{
2610 /** The usual invalid first value. */
2611 DBGFPLUGINOP_INVALID,
2612 /** Initialize the plug-in for a VM, register all the stuff.
2613 * The plug-in will be unloaded on failure.
2614 * uArg: The full VirtualBox version, see VBox/version.h. */
2615 DBGFPLUGINOP_INIT,
2616 /** Terminate the plug-ing for a VM, deregister all the stuff.
2617 * The plug-in will be unloaded after this call regardless of the return
2618 * code. */
2619 DBGFPLUGINOP_TERM,
2620 /** The usual 32-bit hack. */
2621 DBGFPLUGINOP_32BIT_HACK = 0x7fffffff
2622} DBGFPLUGINOP;
2623
2624/**
2625 * DBGF plug-in main entry point.
2626 *
2627 * @returns VBox status code.
2628 *
2629 * @param enmOperation The operation.
2630 * @param pUVM The user mode VM handle. This may be NULL.
2631 * @param uArg Extra argument.
2632 */
2633typedef DECLCALLBACKTYPE(int, FNDBGFPLUGIN,(DBGFPLUGINOP enmOperation, PUVM pUVM, uintptr_t uArg));
2634/** Pointer to a FNDBGFPLUGIN. */
2635typedef FNDBGFPLUGIN *PFNDBGFPLUGIN;
2636
2637/** @copydoc FNDBGFPLUGIN */
2638DECLEXPORT(int) DbgPlugInEntry(DBGFPLUGINOP enmOperation, PUVM pUVM, uintptr_t uArg);
2639
2640VMMR3DECL(int) DBGFR3PlugInLoad(PUVM pUVM, const char *pszPlugIn, char *pszActual, size_t cbActual, PRTERRINFO pErrInfo);
2641VMMR3DECL(int) DBGFR3PlugInUnload(PUVM pUVM, const char *pszName);
2642VMMR3DECL(void) DBGFR3PlugInLoadAll(PUVM pUVM);
2643VMMR3DECL(void) DBGFR3PlugInUnloadAll(PUVM pUVM);
2644
2645/** @} */
2646
2647
2648/** @defgroup grp_dbgf_types The DBGF type system Interface.
2649 * @{
2650 */
2651
2652/** A few forward declarations. */
2653/** Pointer to a type registration structure. */
2654typedef struct DBGFTYPEREG *PDBGFTYPEREG;
2655/** Pointer to a const type registration structure. */
2656typedef const struct DBGFTYPEREG *PCDBGFTYPEREG;
2657/** Pointer to a typed buffer. */
2658typedef struct DBGFTYPEVAL *PDBGFTYPEVAL;
2659
2660/**
2661 * DBGF built-in types.
2662 */
2663typedef enum DBGFTYPEBUILTIN
2664{
2665 /** The usual invalid first value. */
2666 DBGFTYPEBUILTIN_INVALID,
2667 /** Unsigned 8bit integer. */
2668 DBGFTYPEBUILTIN_UINT8,
2669 /** Signed 8bit integer. */
2670 DBGFTYPEBUILTIN_INT8,
2671 /** Unsigned 16bit integer. */
2672 DBGFTYPEBUILTIN_UINT16,
2673 /** Signed 16bit integer. */
2674 DBGFTYPEBUILTIN_INT16,
2675 /** Unsigned 32bit integer. */
2676 DBGFTYPEBUILTIN_UINT32,
2677 /** Signed 32bit integer. */
2678 DBGFTYPEBUILTIN_INT32,
2679 /** Unsigned 64bit integer. */
2680 DBGFTYPEBUILTIN_UINT64,
2681 /** Signed 64bit integer. */
2682 DBGFTYPEBUILTIN_INT64,
2683 /** 32bit Guest pointer */
2684 DBGFTYPEBUILTIN_PTR32,
2685 /** 64bit Guest pointer */
2686 DBGFTYPEBUILTIN_PTR64,
2687 /** Guest pointer - size depends on the guest bitness */
2688 DBGFTYPEBUILTIN_PTR,
2689 /** Type indicating a size, like size_t this can have different sizes
2690 * on 32bit and 64bit systems */
2691 DBGFTYPEBUILTIN_SIZE,
2692 /** 32bit float. */
2693 DBGFTYPEBUILTIN_FLOAT32,
2694 /** 64bit float (also known as double). */
2695 DBGFTYPEBUILTIN_FLOAT64,
2696 /** Compund types like structs and unions. */
2697 DBGFTYPEBUILTIN_COMPOUND,
2698 /** The usual 32-bit hack. */
2699 DBGFTYPEBUILTIN_32BIT_HACK = 0x7fffffff
2700} DBGFTYPEBUILTIN;
2701/** Pointer to a built-in type. */
2702typedef DBGFTYPEBUILTIN *PDBGFTYPEBUILTIN;
2703/** Pointer to a const built-in type. */
2704typedef const DBGFTYPEBUILTIN *PCDBGFTYPEBUILTIN;
2705
2706/**
2707 * DBGF type value buffer.
2708 */
2709typedef union DBGFTYPEVALBUF
2710{
2711 uint8_t u8;
2712 int8_t i8;
2713 uint16_t u16;
2714 int16_t i16;
2715 uint32_t u32;
2716 int32_t i32;
2717 uint64_t u64;
2718 int64_t i64;
2719 float f32;
2720 double f64;
2721 uint64_t size; /* For the built-in size_t which can be either 32-bit or 64-bit. */
2722 RTGCPTR GCPtr;
2723 /** For embedded structs. */
2724 PDBGFTYPEVAL pVal;
2725} DBGFTYPEVALBUF;
2726/** Pointer to a value. */
2727typedef DBGFTYPEVALBUF *PDBGFTYPEVALBUF;
2728
2729/**
2730 * DBGF type value entry.
2731 */
2732typedef struct DBGFTYPEVALENTRY
2733{
2734 /** DBGF built-in type. */
2735 DBGFTYPEBUILTIN enmType;
2736 /** Size of the type. */
2737 size_t cbType;
2738 /** Number of entries, for arrays this can be > 1. */
2739 uint32_t cEntries;
2740 /** Value buffer, depends on whether this is an array. */
2741 union
2742 {
2743 /** Single value. */
2744 DBGFTYPEVALBUF Val;
2745 /** Pointer to the array of values. */
2746 PDBGFTYPEVALBUF pVal;
2747 } Buf;
2748} DBGFTYPEVALENTRY;
2749/** Pointer to a type value entry. */
2750typedef DBGFTYPEVALENTRY *PDBGFTYPEVALENTRY;
2751/** Pointer to a const type value entry. */
2752typedef const DBGFTYPEVALENTRY *PCDBGFTYPEVALENTRY;
2753
2754/**
2755 * DBGF typed value.
2756 */
2757typedef struct DBGFTYPEVAL
2758{
2759 /** Pointer to the registration structure for this type. */
2760 PCDBGFTYPEREG pTypeReg;
2761 /** Number of value entries. */
2762 uint32_t cEntries;
2763 /** Variable sized array of value entries. */
2764 DBGFTYPEVALENTRY aEntries[1];
2765} DBGFTYPEVAL;
2766
2767/**
2768 * DBGF type variant.
2769 */
2770typedef enum DBGFTYPEVARIANT
2771{
2772 /** The usual invalid first value. */
2773 DBGFTYPEVARIANT_INVALID,
2774 /** A struct. */
2775 DBGFTYPEVARIANT_STRUCT,
2776 /** Union. */
2777 DBGFTYPEVARIANT_UNION,
2778 /** Alias for an existing type. */
2779 DBGFTYPEVARIANT_ALIAS,
2780 /** The usual 32-bit hack. */
2781 DBGFTYPEVARIANT_32BIT_HACK = 0x7fffffff
2782} DBGFTYPEVARIANT;
2783
2784/** @name DBGFTYPEREGMEMBER Flags.
2785 * @{ */
2786/** The member is an array with a fixed size. */
2787# define DBGFTYPEREGMEMBER_F_ARRAY RT_BIT_32(0)
2788/** The member denotes a pointer. */
2789# define DBGFTYPEREGMEMBER_F_POINTER RT_BIT_32(1)
2790/** @} */
2791
2792/**
2793 * DBGF type member.
2794 */
2795typedef struct DBGFTYPEREGMEMBER
2796{
2797 /** Name of the member. */
2798 const char *pszName;
2799 /** Flags for this member, see DBGFTYPEREGMEMBER_F_XXX. */
2800 uint32_t fFlags;
2801 /** Type identifier. */
2802 const char *pszType;
2803 /** The number of elements in the array, only valid for arrays. */
2804 uint32_t cElements;
2805} DBGFTYPEREGMEMBER;
2806/** Pointer to a member. */
2807typedef DBGFTYPEREGMEMBER *PDBGFTYPEREGMEMBER;
2808/** Pointer to a const member. */
2809typedef const DBGFTYPEREGMEMBER *PCDBGFTYPEREGMEMBER;
2810
2811/** @name DBGFTYPEREG Flags.
2812 * @{ */
2813/** The type is a packed structure. */
2814# define DBGFTYPEREG_F_PACKED RT_BIT_32(0)
2815/** @} */
2816
2817/**
2818 * New type registration structure.
2819 */
2820typedef struct DBGFTYPEREG
2821{
2822 /** Name of the type. */
2823 const char *pszType;
2824 /** The type variant. */
2825 DBGFTYPEVARIANT enmVariant;
2826 /** Some registration flags, see DBGFTYPEREG_F_XXX. */
2827 uint32_t fFlags;
2828 /** Number of members this type has, only valid for structs or unions. */
2829 uint32_t cMembers;
2830 /** Pointer to the member fields, only valid for structs or unions. */
2831 PCDBGFTYPEREGMEMBER paMembers;
2832 /** Name of the aliased type for aliases. */
2833 const char *pszAliasedType;
2834} DBGFTYPEREG;
2835
2836/**
2837 * DBGF typed value dumper callback.
2838 *
2839 * @returns VBox status code. Any non VINF_SUCCESS status code will abort the dumping.
2840 *
2841 * @param off The byte offset of the entry from the start of the type.
2842 * @param pszField The name of the field for the value.
2843 * @param iLvl The current level.
2844 * @param enmType The type enum.
2845 * @param cbType Size of the type.
2846 * @param pValBuf Pointer to the value buffer.
2847 * @param cValBufs Number of value buffers (for arrays).
2848 * @param pvUser Opaque user data.
2849 */
2850typedef DECLCALLBACKTYPE(int, FNDBGFR3TYPEVALDUMP,(uint32_t off, const char *pszField, uint32_t iLvl,
2851 DBGFTYPEBUILTIN enmType, size_t cbType,
2852 PDBGFTYPEVALBUF pValBuf, uint32_t cValBufs, void *pvUser));
2853/** Pointer to a FNDBGFR3TYPEVALDUMP. */
2854typedef FNDBGFR3TYPEVALDUMP *PFNDBGFR3TYPEVALDUMP;
2855
2856/**
2857 * DBGF type information dumper callback.
2858 *
2859 * @returns VBox status code. Any non VINF_SUCCESS status code will abort the dumping.
2860 *
2861 * @param off The byte offset of the entry from the start of the type.
2862 * @param pszField The name of the field for the value.
2863 * @param iLvl The current level.
2864 * @param pszType The type of the field.
2865 * @param fTypeFlags Flags for this type, see DBGFTYPEREGMEMBER_F_XXX.
2866 * @param cElements Number of for the field ( > 0 for arrays).
2867 * @param pvUser Opaque user data.
2868 */
2869typedef DECLCALLBACKTYPE(int, FNDBGFR3TYPEDUMP,(uint32_t off, const char *pszField, uint32_t iLvl,
2870 const char *pszType, uint32_t fTypeFlags,
2871 uint32_t cElements, void *pvUser));
2872/** Pointer to a FNDBGFR3TYPEDUMP. */
2873typedef FNDBGFR3TYPEDUMP *PFNDBGFR3TYPEDUMP;
2874
2875VMMR3DECL(int) DBGFR3TypeRegister( PUVM pUVM, uint32_t cTypes, PCDBGFTYPEREG paTypes);
2876VMMR3DECL(int) DBGFR3TypeDeregister(PUVM pUVM, const char *pszType);
2877VMMR3DECL(int) DBGFR3TypeQueryReg( PUVM pUVM, const char *pszType, PCDBGFTYPEREG *ppTypeReg);
2878
2879VMMR3DECL(int) DBGFR3TypeQuerySize( PUVM pUVM, const char *pszType, size_t *pcbType);
2880VMMR3DECL(int) DBGFR3TypeSetSize( PUVM pUVM, const char *pszType, size_t cbType);
2881VMMR3DECL(int) DBGFR3TypeDumpEx( PUVM pUVM, const char *pszType, uint32_t fFlags,
2882 uint32_t cLvlMax, PFNDBGFR3TYPEDUMP pfnDump, void *pvUser);
2883VMMR3DECL(int) DBGFR3TypeQueryValByType(PUVM pUVM, PCDBGFADDRESS pAddress, const char *pszType,
2884 PDBGFTYPEVAL *ppVal);
2885VMMR3DECL(void) DBGFR3TypeValFree(PDBGFTYPEVAL pVal);
2886VMMR3DECL(int) DBGFR3TypeValDumpEx(PUVM pUVM, PCDBGFADDRESS pAddress, const char *pszType, uint32_t fFlags,
2887 uint32_t cLvlMax, FNDBGFR3TYPEVALDUMP pfnDump, void *pvUser);
2888
2889/** @} */
2890
2891
2892/** @defgroup grp_dbgf_flow The DBGF control flow graph Interface.
2893 * @{
2894 */
2895
2896/** A DBGF control flow graph handle. */
2897typedef struct DBGFFLOWINT *DBGFFLOW;
2898/** Pointer to a DBGF control flow graph handle. */
2899typedef DBGFFLOW *PDBGFFLOW;
2900/** A DBGF control flow graph basic block handle. */
2901typedef struct DBGFFLOWBBINT *DBGFFLOWBB;
2902/** Pointer to a DBGF control flow graph basic block handle. */
2903typedef DBGFFLOWBB *PDBGFFLOWBB;
2904/** A DBGF control flow graph branch table handle. */
2905typedef struct DBGFFLOWBRANCHTBLINT *DBGFFLOWBRANCHTBL;
2906/** Pointer to a DBGF flow control graph branch table handle. */
2907typedef DBGFFLOWBRANCHTBL *PDBGFFLOWBRANCHTBL;
2908/** A DBGF control flow graph iterator. */
2909typedef struct DBGFFLOWITINT *DBGFFLOWIT;
2910/** Pointer to a control flow graph iterator. */
2911typedef DBGFFLOWIT *PDBGFFLOWIT;
2912/** A DBGF control flow graph branch table iterator. */
2913typedef struct DBGFFLOWBRANCHTBLITINT *DBGFFLOWBRANCHTBLIT;
2914/** Pointer to a control flow graph branch table iterator. */
2915typedef DBGFFLOWBRANCHTBLIT *PDBGFFLOWBRANCHTBLIT;
2916
2917/** @name DBGFFLOWBB Flags.
2918 * @{ */
2919/** The basic block is the entry into the owning control flow graph. */
2920#define DBGF_FLOW_BB_F_ENTRY RT_BIT_32(0)
2921/** The basic block was not populated because the limit was reached. */
2922#define DBGF_FLOW_BB_F_EMPTY RT_BIT_32(1)
2923/** The basic block is not complete because an error happened during disassembly. */
2924#define DBGF_FLOW_BB_F_INCOMPLETE_ERR RT_BIT_32(2)
2925/** The basic block is reached through a branch table. */
2926#define DBGF_FLOW_BB_F_BRANCH_TABLE RT_BIT_32(3)
2927/** The basic block consists only of a single call instruction because
2928 * DBGF_FLOW_CREATE_F_CALL_INSN_SEPARATE_BB was given. */
2929#define DBGF_FLOW_BB_F_CALL_INSN RT_BIT_32(4)
2930/** The branch target of the call instruction could be deduced and can be queried with
2931 * DBGFR3FlowBbGetBranchAddress(). May only be available when DBGF_FLOW_BB_F_CALL_INSN
2932 * is set. */
2933#define DBGF_FLOW_BB_F_CALL_INSN_TARGET_KNOWN RT_BIT_32(5)
2934/** @} */
2935
2936/** @name Flags controlling the creating of a control flow graph.
2937 * @{ */
2938/** Default options. */
2939#define DBGF_FLOW_CREATE_F_DEFAULT 0
2940/** Tries to resolve indirect branches, useful for code using
2941 * jump tables generated for large switch statements by some compilers. */
2942#define DBGF_FLOW_CREATE_F_TRY_RESOLVE_INDIRECT_BRANCHES RT_BIT_32(0)
2943/** Call instructions are placed in a separate basic block. */
2944#define DBGF_FLOW_CREATE_F_CALL_INSN_SEPARATE_BB RT_BIT_32(1)
2945/** @} */
2946
2947/**
2948 * DBGF control graph basic block end type.
2949 */
2950typedef enum DBGFFLOWBBENDTYPE
2951{
2952 /** Invalid type. */
2953 DBGFFLOWBBENDTYPE_INVALID = 0,
2954 /** Basic block is the exit block and has no successor. */
2955 DBGFFLOWBBENDTYPE_EXIT,
2956 /** Basic block is the last disassembled block because the
2957 * maximum amount to disassemble was reached but is not an
2958 * exit block - no successors.
2959 */
2960 DBGFFLOWBBENDTYPE_LAST_DISASSEMBLED,
2961 /** Unconditional control flow change because the successor is referenced by multiple
2962 * basic blocks. - 1 successor. */
2963 DBGFFLOWBBENDTYPE_UNCOND,
2964 /** Unconditional control flow change because of an direct branch - 1 successor. */
2965 DBGFFLOWBBENDTYPE_UNCOND_JMP,
2966 /** Unconditional control flow change because of an indirect branch - n successors. */
2967 DBGFFLOWBBENDTYPE_UNCOND_INDIRECT_JMP,
2968 /** Conditional control flow change - 2 successors. */
2969 DBGFFLOWBBENDTYPE_COND,
2970 /** 32bit hack. */
2971 DBGFFLOWBBENDTYPE_32BIT_HACK = 0x7fffffff
2972} DBGFFLOWBBENDTYPE;
2973
2974/**
2975 * DBGF control flow graph iteration order.
2976 */
2977typedef enum DBGFFLOWITORDER
2978{
2979 /** Invalid order. */
2980 DBGFFLOWITORDER_INVALID = 0,
2981 /** From lowest to highest basic block start address. */
2982 DBGFFLOWITORDER_BY_ADDR_LOWEST_FIRST,
2983 /** From highest to lowest basic block start address. */
2984 DBGFFLOWITORDER_BY_ADDR_HIGHEST_FIRST,
2985 /** Depth first traversing starting from the entry block. */
2986 DBGFFLOWITORDER_DEPTH_FRIST,
2987 /** Breadth first traversing starting from the entry block. */
2988 DBGFFLOWITORDER_BREADTH_FIRST,
2989 /** Usual 32bit hack. */
2990 DBGFFLOWITORDER_32BIT_HACK = 0x7fffffff
2991} DBGFFLOWITORDER;
2992/** Pointer to a iteration order enum. */
2993typedef DBGFFLOWITORDER *PDBGFFLOWITORDER;
2994
2995
2996VMMR3DECL(int) DBGFR3FlowCreate(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddressStart, uint32_t cbDisasmMax,
2997 uint32_t fFlagsFlow, uint32_t fFlagsDisasm, PDBGFFLOW phFlow);
2998VMMR3DECL(uint32_t) DBGFR3FlowRetain(DBGFFLOW hFlow);
2999VMMR3DECL(uint32_t) DBGFR3FlowRelease(DBGFFLOW hFlow);
3000VMMR3DECL(int) DBGFR3FlowQueryStartBb(DBGFFLOW hFlow, PDBGFFLOWBB phFlowBb);
3001VMMR3DECL(int) DBGFR3FlowQueryBbByAddress(DBGFFLOW hFlow, PDBGFADDRESS pAddr, PDBGFFLOWBB phFlowBb);
3002VMMR3DECL(int) DBGFR3FlowQueryBranchTblByAddress(DBGFFLOW hFlow, PDBGFADDRESS pAddr, PDBGFFLOWBRANCHTBL phFlowBranchTbl);
3003VMMR3DECL(uint32_t) DBGFR3FlowGetBbCount(DBGFFLOW hFlow);
3004VMMR3DECL(uint32_t) DBGFR3FlowGetBranchTblCount(DBGFFLOW hFlow);
3005VMMR3DECL(uint32_t) DBGFR3FlowGetCallInsnCount(DBGFFLOW hFlow);
3006
3007VMMR3DECL(uint32_t) DBGFR3FlowBbRetain(DBGFFLOWBB hFlowBb);
3008VMMR3DECL(uint32_t) DBGFR3FlowBbRelease(DBGFFLOWBB hFlowBb);
3009VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetStartAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrStart);
3010VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetEndAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrEnd);
3011VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetBranchAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrTarget);
3012VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBbGetFollowingAddress(DBGFFLOWBB hFlowBb, PDBGFADDRESS pAddrFollow);
3013VMMR3DECL(DBGFFLOWBBENDTYPE) DBGFR3FlowBbGetType(DBGFFLOWBB hFlowBb);
3014VMMR3DECL(uint32_t) DBGFR3FlowBbGetInstrCount(DBGFFLOWBB hFlowBb);
3015VMMR3DECL(uint32_t) DBGFR3FlowBbGetFlags(DBGFFLOWBB hFlowBb);
3016VMMR3DECL(int) DBGFR3FlowBbQueryBranchTbl(DBGFFLOWBB hFlowBb, PDBGFFLOWBRANCHTBL phBranchTbl);
3017VMMR3DECL(int) DBGFR3FlowBbQueryError(DBGFFLOWBB hFlowBb, const char **ppszErr);
3018VMMR3DECL(int) DBGFR3FlowBbQueryInstr(DBGFFLOWBB hFlowBb, uint32_t idxInstr, PDBGFADDRESS pAddrInstr,
3019 uint32_t *pcbInstr, const char **ppszInstr);
3020VMMR3DECL(int) DBGFR3FlowBbQuerySuccessors(DBGFFLOWBB hFlowBb, PDBGFFLOWBB phFlowBbFollow,
3021 PDBGFFLOWBB phFlowBbTarget);
3022VMMR3DECL(uint32_t) DBGFR3FlowBbGetRefBbCount(DBGFFLOWBB hFlowBb);
3023VMMR3DECL(int) DBGFR3FlowBbGetRefBb(DBGFFLOWBB hFlowBb, PDBGFFLOWBB pahFlowBbRef, uint32_t cRef);
3024
3025VMMR3DECL(uint32_t) DBGFR3FlowBranchTblRetain(DBGFFLOWBRANCHTBL hFlowBranchTbl);
3026VMMR3DECL(uint32_t) DBGFR3FlowBranchTblRelease(DBGFFLOWBRANCHTBL hFlowBranchTbl);
3027VMMR3DECL(uint32_t) DBGFR3FlowBranchTblGetSlots(DBGFFLOWBRANCHTBL hFlowBranchTbl);
3028VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBranchTblGetStartAddress(DBGFFLOWBRANCHTBL hFlowBranchTbl, PDBGFADDRESS pAddrStart);
3029VMMR3DECL(PDBGFADDRESS) DBGFR3FlowBranchTblGetAddrAtSlot(DBGFFLOWBRANCHTBL hFlowBranchTbl, uint32_t idxSlot, PDBGFADDRESS pAddrSlot);
3030VMMR3DECL(int) DBGFR3FlowBranchTblQueryAddresses(DBGFFLOWBRANCHTBL hFlowBranchTbl, PDBGFADDRESS paAddrs, uint32_t cAddrs);
3031
3032VMMR3DECL(int) DBGFR3FlowItCreate(DBGFFLOW hFlow, DBGFFLOWITORDER enmOrder, PDBGFFLOWIT phFlowIt);
3033VMMR3DECL(void) DBGFR3FlowItDestroy(DBGFFLOWIT hFlowIt);
3034VMMR3DECL(DBGFFLOWBB) DBGFR3FlowItNext(DBGFFLOWIT hFlowIt);
3035VMMR3DECL(int) DBGFR3FlowItReset(DBGFFLOWIT hFlowIt);
3036
3037VMMR3DECL(int) DBGFR3FlowBranchTblItCreate(DBGFFLOW hFlow, DBGFFLOWITORDER enmOrder, PDBGFFLOWBRANCHTBLIT phFlowBranchTblIt);
3038VMMR3DECL(void) DBGFR3FlowBranchTblItDestroy(DBGFFLOWBRANCHTBLIT hFlowBranchTblIt);
3039VMMR3DECL(DBGFFLOWBRANCHTBL) DBGFR3FlowBranchTblItNext(DBGFFLOWBRANCHTBLIT hFlowBranchTblIt);
3040VMMR3DECL(int) DBGFR3FlowBranchTblItReset(DBGFFLOWBRANCHTBLIT hFlowBranchTblIt);
3041
3042/** @} */
3043
3044
3045/** @defgroup grp_dbgf_misc Misc DBGF interfaces.
3046 * @{ */
3047VMMR3DECL(VBOXSTRICTRC) DBGFR3ReportBugCheck(PVM pVM, PVMCPU pVCpu, DBGFEVENTTYPE enmEvent, uint64_t uBugCheck,
3048 uint64_t uP1, uint64_t uP2, uint64_t uP3, uint64_t uP4);
3049VMMR3DECL(int) DBGFR3FormatBugCheck(PUVM pUVM, char *pszDetails, size_t cbDetails,
3050 uint64_t uP0, uint64_t uP1, uint64_t uP2, uint64_t uP3, uint64_t uP4);
3051/** @} */
3052#endif /* IN_RING3 */
3053
3054
3055/** @defgroup grp_dbgf_tracer DBGF event tracing.
3056 * @{ */
3057#ifdef IN_RING3
3058VMMR3_INT_DECL(int) DBGFR3TracerRegisterEvtSrc(PVM pVM, const char *pszName, PDBGFTRACEREVTSRC phEvtSrc);
3059VMMR3_INT_DECL(int) DBGFR3TracerDeregisterEvtSrc(PVM pVM, DBGFTRACEREVTSRC hEvtSrc);
3060VMMR3_INT_DECL(int) DBGFR3TracerEvtIoPortCreate(PVM pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTIOPORT cPorts, uint32_t fFlags,
3061 uint32_t iPciRegion);
3062VMMR3_INT_DECL(int) DBGFR3TracerEvtMmioCreate(PVM pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS cbRegion, uint32_t fFlags,
3063 uint32_t iPciRegion);
3064#endif
3065
3066VMM_INT_DECL(int) DBGFTracerEvtMmioMap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS GCPhysMmio);
3067VMM_INT_DECL(int) DBGFTracerEvtMmioUnmap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion);
3068VMM_INT_DECL(int) DBGFTracerEvtMmioRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio, const void *pvVal, size_t cbVal);
3069VMM_INT_DECL(int) DBGFTracerEvtMmioWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio, const void *pvVal, size_t cbVal);
3070VMM_INT_DECL(int) DBGFTracerEvtMmioFill(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hRegion, RTGCPHYS offMmio, uint32_t u32Item, uint32_t cbItem, uint32_t cItems);
3071VMM_INT_DECL(int) DBGFTracerEvtIoPortMap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT IoPortBase);
3072VMM_INT_DECL(int) DBGFTracerEvtIoPortUnmap(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts);
3073VMM_INT_DECL(int) DBGFTracerEvtIoPortRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pvVal, size_t cbVal);
3074VMM_INT_DECL(int) DBGFTracerEvtIoPortReadStr(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pv, size_t cb,
3075 uint32_t cTransfersReq, uint32_t cTransfersRet);
3076VMM_INT_DECL(int) DBGFTracerEvtIoPortWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pvVal, size_t cbVal);
3077VMM_INT_DECL(int) DBGFTracerEvtIoPortWriteStr(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, uint64_t hIoPorts, RTIOPORT offPort, const void *pv, size_t cb,
3078 uint32_t cTransfersReq, uint32_t cTransfersRet);
3079VMM_INT_DECL(int) DBGFTracerEvtIrq(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, int32_t iIrq, int32_t fIrqLvl);
3080VMM_INT_DECL(int) DBGFTracerEvtIoApicMsi(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, uint32_t u32Val);
3081VMM_INT_DECL(int) DBGFTracerEvtGCPhysRead(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, const void *pvBuf, size_t cbRead);
3082VMM_INT_DECL(int) DBGFTracerEvtGCPhysWrite(PVMCC pVM, DBGFTRACEREVTSRC hEvtSrc, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
3083/** @} */
3084
3085/** @} */
3086
3087RT_C_DECLS_END
3088
3089#endif /* !VBOX_INCLUDED_vmm_dbgf_h */
3090
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