VirtualBox

source: vbox/trunk/src/VBox/VMM/include/DBGFInternal.h@ 106054

Last change on this file since 106054 was 105409, checked in by vboxsync, 5 months ago

VMM/DBGF: Added a /DBGF/SuspendOnBsod boolean option (default false). bugref:10727

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 56.3 KB
Line 
1/* $Id: DBGFInternal.h 105409 2024-07-19 00:27:32Z vboxsync $ */
2/** @file
3 * DBGF - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef VMM_INCLUDED_SRC_include_DBGFInternal_h
29#define VMM_INCLUDED_SRC_include_DBGFInternal_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <VBox/cdefs.h>
35#ifdef IN_RING3
36# include <VBox/dis.h>
37#endif
38#include <VBox/types.h>
39#include <iprt/semaphore.h>
40#include <iprt/critsect.h>
41#include <iprt/string.h>
42#include <iprt/avl.h>
43#include <iprt/dbg.h>
44#include <iprt/tracelog.h>
45#include <VBox/vmm/dbgf.h>
46
47
48
49/** @defgroup grp_dbgf_int Internals
50 * @ingroup grp_dbgf
51 * @internal
52 * @{
53 */
54
55/** The maximum tracer instance (total) size, ring-0/raw-mode capable tracers. */
56#define DBGF_MAX_TRACER_INSTANCE_SIZE _512M
57/** The maximum tracers instance (total) size, ring-3 only tracers. */
58#define DBGF_MAX_TRACER_INSTANCE_SIZE_R3 _1G
59/** Event ringbuffer header size. */
60#define DBGF_TRACER_EVT_HDR_SZ (32)
61/** Event ringbuffer payload size. */
62#define DBGF_TRACER_EVT_PAYLOAD_SZ (32)
63/** Event ringbuffer entry size. */
64#define DBGF_TRACER_EVT_SZ (DBGF_TRACER_EVT_HDR_SZ + DBGF_TRACER_EVT_PAYLOAD_SZ)
65
66
67/** @name Global breakpoint table handling defines.
68 * @{ */
69/** Maximum number of breakpoint owners supported (power of two). */
70#define DBGF_BP_OWNER_COUNT_MAX _32K
71/** Maximum number of breakpoints supported (power of two). */
72#define DBGF_BP_COUNT_MAX _1M
73/** Size of a single breakpoint structure in bytes. */
74#define DBGF_BP_ENTRY_SZ 64
75/** Number of breakpoints handled in one chunk (power of two). */
76#define DBGF_BP_COUNT_PER_CHUNK _64K
77/** Number of chunks required to support all breakpoints. */
78#define DBGF_BP_CHUNK_COUNT (DBGF_BP_COUNT_MAX / DBGF_BP_COUNT_PER_CHUNK)
79/** Maximum number of instruction bytes when executing breakpointed instructions. */
80#define DBGF_BP_INSN_MAX 16
81/** @} */
82
83/** @name L2 lookup table limit defines.
84 * @{ */
85/** Maximum number of entreis in the L2 lookup table. */
86#define DBGF_BP_L2_TBL_ENTRY_COUNT_MAX _512K
87/** Number of L2 entries handled in one chunk. */
88#define DBGF_BP_L2_TBL_ENTRIES_PER_CHUNK _64K
89/** Number of chunks required tp support all L2 lookup table entries. */
90#define DBGF_BP_L2_TBL_CHUNK_COUNT (DBGF_BP_L2_TBL_ENTRY_COUNT_MAX / DBGF_BP_L2_TBL_ENTRIES_PER_CHUNK)
91/** @} */
92
93
94/*******************************************************************************
95* Structures and Typedefs *
96*******************************************************************************/
97
98/**
99 * Event entry types.
100 */
101typedef enum DBGFTRACEREVT
102{
103 /** Invalid type. */
104 DBGFTRACEREVT_INVALID = 0,
105 /** Register event source event. */
106 DBGFTRACEREVT_SRC_REGISTER,
107 /** Deregister event source event. */
108 DBGFTRACEREVT_SRC_DEREGISTER,
109 /** MMIO region create event. */
110 DBGFTRACEREVT_MMIO_REGION_CREATE,
111 /** MMIO map region event. */
112 DBGFTRACEREVT_MMIO_MAP,
113 /** MMIO unmap region event. */
114 DBGFTRACEREVT_MMIO_UNMAP,
115 /** MMIO read event. */
116 DBGFTRACEREVT_MMIO_READ,
117 /** MMIO write event. */
118 DBGFTRACEREVT_MMIO_WRITE,
119 /** MMIO fill event. */
120 DBGFTRACEREVT_MMIO_FILL,
121 /** I/O port region create event. */
122 DBGFTRACEREVT_IOPORT_REGION_CREATE,
123 /** I/O port map event. */
124 DBGFTRACEREVT_IOPORT_MAP,
125 /** I/O port unmap event. */
126 DBGFTRACEREVT_IOPORT_UNMAP,
127 /** I/O port read event. */
128 DBGFTRACEREVT_IOPORT_READ,
129 /** I/O port read string event. */
130 DBGFTRACEREVT_IOPORT_READ_STR,
131 /** I/O port write event. */
132 DBGFTRACEREVT_IOPORT_WRITE,
133 /** I/O port write string event. */
134 DBGFTRACEREVT_IOPORT_WRITE_STR,
135 /** IRQ event. */
136 DBGFTRACEREVT_IRQ,
137 /** I/O APIC MSI event. */
138 DBGFTRACEREVT_IOAPIC_MSI,
139 /** Read from guest physical memory. */
140 DBGFTRACEREVT_GCPHYS_READ,
141 /** Write to guest physical memory. */
142 DBGFTRACEREVT_GCPHYS_WRITE,
143 /** 32bit hack. */
144 DBGFTRACEREVT_32BIT_HACK
145} DBGFTRACEREVT;
146/** Pointer to a trace event entry type. */
147typedef DBGFTRACEREVT *PDBGFTRACEREVT;
148
149
150/**
151 * MMIO region create event.
152 */
153typedef struct DBGFTRACEREVTMMIOCREATE
154{
155 /** Unique region handle for the event source. */
156 uint64_t hMmioRegion;
157 /** Size of the region in bytes. */
158 RTGCPHYS cbRegion;
159 /** IOM flags passed to the region. */
160 uint32_t fIomFlags;
161 /** The PCI region for a PCI device. */
162 uint32_t iPciRegion;
163 /** Padding to 32byte. */
164 uint64_t u64Pad0;
165} DBGFTRACEREVTMMIOCREATE;
166/** Pointer to a MMIO map event. */
167typedef DBGFTRACEREVTMMIOCREATE *PDBGFTRACEREVTMMIOCREATE;
168/** Pointer to a const MMIO map event. */
169typedef const DBGFTRACEREVTMMIOCREATE *PCDBGFTRACEREVTMMIOCREATE;
170
171AssertCompileSize(DBGFTRACEREVTMMIOCREATE, DBGF_TRACER_EVT_PAYLOAD_SZ);
172
173
174/**
175 * MMIO region map event.
176 */
177typedef struct DBGFTRACEREVTMMIOMAP
178{
179 /** Unique region handle for the event source. */
180 uint64_t hMmioRegion;
181 /** The base guest physical address of the MMIO region. */
182 RTGCPHYS GCPhysMmioBase;
183 /** Padding to 32byte. */
184 uint64_t au64Pad0[2];
185} DBGFTRACEREVTMMIOMAP;
186/** Pointer to a MMIO map event. */
187typedef DBGFTRACEREVTMMIOMAP *PDBGFTRACEREVTMMIOMAP;
188/** Pointer to a const MMIO map event. */
189typedef const DBGFTRACEREVTMMIOMAP *PCDBGFTRACEREVTMMIOMAP;
190
191AssertCompileSize(DBGFTRACEREVTMMIOMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
192
193
194/**
195 * MMIO region unmap event.
196 */
197typedef struct DBGFTRACEREVTMMIOUNMAP
198{
199 /** Unique region handle for the event source. */
200 uint64_t hMmioRegion;
201 /** Padding to 32byte. */
202 uint64_t au64Pad0[3];
203} DBGFTRACEREVTMMIOUNMAP;
204/** Pointer to a MMIO map event. */
205typedef DBGFTRACEREVTMMIOUNMAP *PDBGFTRACEREVTMMIOUNMAP;
206/** Pointer to a const MMIO map event. */
207typedef const DBGFTRACEREVTMMIOUNMAP *PCDBGFTRACEREVTMMIOUNMAP;
208
209AssertCompileSize(DBGFTRACEREVTMMIOUNMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
210
211
212/**
213 * MMIO event.
214 */
215typedef struct DBGFTRACEREVTMMIO
216{
217 /** Unique region handle for the event source. */
218 uint64_t hMmioRegion;
219 /** Offset into the region the access happened. */
220 RTGCPHYS offMmio;
221 /** Number of bytes transfered (the direction is in the event header). */
222 uint64_t cbXfer;
223 /** The value transfered. */
224 uint64_t u64Val;
225} DBGFTRACEREVTMMIO;
226/** Pointer to a MMIO event. */
227typedef DBGFTRACEREVTMMIO *PDBGFTRACEREVTMMIO;
228/** Pointer to a const MMIO event. */
229typedef const DBGFTRACEREVTMMIO *PCDBGFTRACEREVTMMIO;
230
231AssertCompileSize(DBGFTRACEREVTMMIO, DBGF_TRACER_EVT_PAYLOAD_SZ);
232
233
234/**
235 * MMIO fill event.
236 */
237typedef struct DBGFTRACEREVTMMIOFILL
238{
239 /** Unique region handle for the event source. */
240 uint64_t hMmioRegion;
241 /** Offset into the region the access happened. */
242 RTGCPHYS offMmio;
243 /** Item size in bytes. */
244 uint32_t cbItem;
245 /** Amount of items being filled. */
246 uint32_t cItems;
247 /** The fill value. */
248 uint32_t u32Item;
249 /** Padding to 32bytes. */
250 uint32_t u32Pad0;
251} DBGFTRACEREVTMMIOFILL;
252/** Pointer to a MMIO event. */
253typedef DBGFTRACEREVTMMIOFILL *PDBGFTRACEREVTMMIOFILL;
254/** Pointer to a const MMIO event. */
255typedef const DBGFTRACEREVTMMIOFILL *PCDBGFTRACEREVTMMIOFILL;
256
257AssertCompileSize(DBGFTRACEREVTMMIOFILL, DBGF_TRACER_EVT_PAYLOAD_SZ);
258
259
260/**
261 * I/O port region create event.
262 */
263typedef struct DBGFTRACEREVTIOPORTCREATE
264{
265 /** Unique I/O port region handle for the event source. */
266 uint64_t hIoPorts;
267 /** Number of ports. */
268 RTIOPORT cPorts;
269 /** Padding. */
270 uint16_t u16Pad0;
271 /** IOM flags passed to the region. */
272 uint32_t fIomFlags;
273 /** The PCI region for a PCI device. */
274 uint32_t iPciRegion;
275 /** Padding to 32byte. */
276 uint32_t u32Pad0[3];
277} DBGFTRACEREVTIOPORTCREATE;
278/** Pointer to a MMIO map event. */
279typedef DBGFTRACEREVTIOPORTCREATE *PDBGFTRACEREVTIOPORTCREATE;
280/** Pointer to a const MMIO map event. */
281typedef const DBGFTRACEREVTIOPORTCREATE *PCDBGFTRACEREVTIOPORTCREATE;
282
283AssertCompileSize(DBGFTRACEREVTIOPORTCREATE, DBGF_TRACER_EVT_PAYLOAD_SZ);
284
285
286/**
287 * I/O port region map event.
288 */
289typedef struct DBGFTRACEREVTIOPORTMAP
290{
291 /** Unique I/O port region handle for the event source. */
292 uint64_t hIoPorts;
293 /** The base I/O port for the region. */
294 RTIOPORT IoPortBase;
295 /** Padding to 32byte. */
296 uint16_t au16Pad0[11];
297} DBGFTRACEREVTIOPORTMAP;
298/** Pointer to a MMIO map event. */
299typedef DBGFTRACEREVTIOPORTMAP *PDBGFTRACEREVTIOPORTMAP;
300/** Pointer to a const MMIO map event. */
301typedef const DBGFTRACEREVTIOPORTMAP *PCDBGFTRACEREVTIOPORTMAP;
302
303AssertCompileSize(DBGFTRACEREVTIOPORTMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
304
305
306/**
307 * MMIO region unmap event.
308 */
309typedef struct DBGFTRACEREVTIOPORTUNMAP
310{
311 /** Unique region handle for the event source. */
312 uint64_t hIoPorts;
313 /** Padding to 32byte. */
314 uint64_t au64Pad0[3];
315} DBGFTRACEREVTIOPORTUNMAP;
316/** Pointer to a MMIO map event. */
317typedef DBGFTRACEREVTIOPORTUNMAP *PDBGFTRACEREVTIOPORTUNMAP;
318/** Pointer to a const MMIO map event. */
319typedef const DBGFTRACEREVTIOPORTUNMAP *PCDBGFTRACEREVTIOPORTUNMAP;
320
321AssertCompileSize(DBGFTRACEREVTIOPORTUNMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
322
323
324/**
325 * I/O port event.
326 */
327typedef struct DBGFTRACEREVTIOPORT
328{
329 /** Unique region handle for the event source. */
330 uint64_t hIoPorts;
331 /** Offset into the I/O port region. */
332 RTIOPORT offPort;
333 /** 8 byte alignment. */
334 uint8_t abPad0[6];
335 /** Number of bytes transfered (the direction is in the event header). */
336 uint64_t cbXfer;
337 /** The value transfered. */
338 uint32_t u32Val;
339 /** Padding to 32bytes. */
340 uint8_t abPad1[4];
341} DBGFTRACEREVTIOPORT;
342/** Pointer to a MMIO event. */
343typedef DBGFTRACEREVTIOPORT *PDBGFTRACEREVTIOPORT;
344/** Pointer to a const MMIO event. */
345typedef const DBGFTRACEREVTIOPORT *PCDBGFTRACEREVTIOPORT;
346
347AssertCompileSize(DBGFTRACEREVTIOPORT, DBGF_TRACER_EVT_PAYLOAD_SZ);
348
349
350/**
351 * I/O port string event.
352 */
353typedef struct DBGFTRACEREVTIOPORTSTR
354{
355 /** Unique region handle for the event source. */
356 uint64_t hIoPorts;
357 /** Item size in bytes. */
358 uint32_t cbItem;
359 /** Number of transfers requested - for writes this gives the amount of valid data following. */
360 uint32_t cTransfersReq;
361 /** Number of transfers done - for reads this gives the amount of valid data following. */
362 uint32_t cTransfersRet;
363 /** Offset into the I/O port region. */
364 RTIOPORT offPort;
365 /** Data being transfered. */
366 uint8_t abData[10];
367} DBGFTRACEREVTIOPORTSTR;
368/** Pointer to a MMIO event. */
369typedef DBGFTRACEREVTIOPORTSTR *PDBGFTRACEREVTIOPORTSTR;
370/** Pointer to a const MMIO event. */
371typedef const DBGFTRACEREVTIOPORTSTR *PCDBGFTRACEREVTIOPORTSTR;
372
373AssertCompileSize(DBGFTRACEREVTIOPORTSTR, DBGF_TRACER_EVT_PAYLOAD_SZ);
374
375
376/**
377 * IRQ event.
378 */
379typedef struct DBGFTRACEREVTIRQ
380{
381 /** The IRQ line. */
382 int32_t iIrq;
383 /** IRQ level flags. */
384 int32_t fIrqLvl;
385 /** Padding to 32bytes. */
386 uint32_t au32Pad0[6];
387} DBGFTRACEREVTIRQ;
388/** Pointer to a MMIO event. */
389typedef DBGFTRACEREVTIRQ *PDBGFTRACEREVTIRQ;
390/** Pointer to a const MMIO event. */
391typedef const DBGFTRACEREVTIRQ *PCDBGFTRACEREVTIRQ;
392
393AssertCompileSize(DBGFTRACEREVTIRQ, DBGF_TRACER_EVT_PAYLOAD_SZ);
394
395
396/**
397 * I/O APIC MSI event.
398 */
399typedef struct DBGFTRACEREVTIOAPICMSI
400{
401 /** The guest physical address being written. */
402 RTGCPHYS GCPhys;
403 /** The value being written. */
404 uint32_t u32Val;
405 /** Padding to 32bytes. */
406 uint32_t au32Pad0[5];
407} DBGFTRACEREVTIOAPICMSI;
408/** Pointer to a MMIO event. */
409typedef DBGFTRACEREVTIOAPICMSI *PDBGFTRACEREVTIOAPICMSI;
410/** Pointer to a const MMIO event. */
411typedef const DBGFTRACEREVTIOAPICMSI *PCDBGFTRACEREVTIOAPICMSI;
412
413AssertCompileSize(DBGFTRACEREVTIOAPICMSI, DBGF_TRACER_EVT_PAYLOAD_SZ);
414
415
416/**
417 * Guest physical memory transfer.
418 */
419typedef struct DBGFTRACEREVTGCPHYS
420{
421 /** Guest physical address of the access. */
422 RTGCPHYS GCPhys;
423 /** Number of bytes transfered (the direction is in the event header).
424 * If the number is small enough to fit into the remaining space of the entry
425 * it is stored here, otherwise it will be stored in the next entry (and following
426 * entries). */
427 uint64_t cbXfer;
428 /** Guest data being transfered. */
429 uint8_t abData[16];
430} DBGFTRACEREVTGCPHYS;
431/** Pointer to a guest physical memory transfer event. */
432typedef DBGFTRACEREVTGCPHYS *PDBGFTRACEREVTGCPHYS;
433/** Pointer to a const uest physical memory transfer event. */
434typedef const DBGFTRACEREVTGCPHYS *PCDBGFTRACEREVTGCPHYS;
435
436AssertCompileSize(DBGFTRACEREVTGCPHYS, DBGF_TRACER_EVT_PAYLOAD_SZ);
437
438
439/**
440 * A trace event header in the shared ring buffer.
441 */
442typedef struct DBGFTRACEREVTHDR
443{
444 /** Event ID. */
445 volatile uint64_t idEvt;
446 /** The previous event ID this one links to,
447 * DBGF_TRACER_EVT_HDR_ID_INVALID if it links to no other event. */
448 uint64_t idEvtPrev;
449 /** Event source. */
450 DBGFTRACEREVTSRC hEvtSrc;
451 /** The event entry type. */
452 DBGFTRACEREVT enmEvt;
453 /** Flags for this event. */
454 uint32_t fFlags;
455} DBGFTRACEREVTHDR;
456/** Pointer to a trace event header. */
457typedef DBGFTRACEREVTHDR *PDBGFTRACEREVTHDR;
458/** Pointer to a const trace event header. */
459typedef const DBGFTRACEREVTHDR *PCDBGFTRACEREVTHDR;
460
461AssertCompileSize(DBGFTRACEREVTHDR, DBGF_TRACER_EVT_HDR_SZ);
462
463/** Invalid event ID, this is always set by the flush thread after processing one entry
464 * so the producers know when they are about to overwrite not yet processed entries in the ring buffer. */
465#define DBGF_TRACER_EVT_HDR_ID_INVALID UINT64_C(0xffffffffffffffff)
466
467/** The event came from R0. */
468#define DBGF_TRACER_EVT_HDR_F_R0 RT_BIT(0)
469
470/** Default event header tracer flags. */
471#ifdef IN_RING0
472# define DBGF_TRACER_EVT_HDR_F_DEFAULT DBGF_TRACER_EVT_HDR_F_R0
473#else
474# define DBGF_TRACER_EVT_HDR_F_DEFAULT (0)
475#endif
476
477
478/**
479 * Tracer instance data, shared structure.
480 */
481typedef struct DBGFTRACERSHARED
482{
483 /** The global event ID counter, monotonically increasing.
484 * Accessed by all threads causing a trace event. */
485 volatile uint64_t idEvt;
486 /** The SUP event semaphore for poking the flush thread. */
487 SUPSEMEVENT hSupSemEvtFlush;
488 /** Ring buffer size. */
489 size_t cbRingBuf;
490 /** Flag whether there are events in the ring buffer to get processed. */
491 volatile bool fEvtsWaiting;
492 /** Flag whether the flush thread is actively running or was kicked. */
493 volatile bool fFlushThrdActive;
494 /** Padding to a 64byte alignment. */
495 uint8_t abAlignment0[32];
496} DBGFTRACERSHARED;
497/** Pointer to the shared tarcer instance data. */
498typedef DBGFTRACERSHARED *PDBGFTRACERSHARED;
499
500AssertCompileSizeAlignment(DBGFTRACERSHARED, 64);
501
502
503/**
504 * Guest memory read/write data aggregation.
505 */
506typedef struct DBGFTRACERGCPHYSRWAGG
507{
508 /** The event ID which started the aggregation (used for the group ID when writing out the event). */
509 uint64_t idEvtStart;
510 /** The previous event ID used to link all the chunks together. */
511 uint64_t idEvtPrev;
512 /** Number of bytes being transfered. */
513 size_t cbXfer;
514 /** Amount of data left to aggregate before it can be written. */
515 size_t cbLeft;
516 /** Amount of bytes allocated. */
517 size_t cbBufMax;
518 /** Offset into the buffer to write next. */
519 size_t offBuf;
520 /** Pointer to the allocated buffer. */
521 uint8_t *pbBuf;
522} DBGFTRACERGCPHYSRWAGG;
523/** Pointer to a guest memory read/write data aggregation structure. */
524typedef DBGFTRACERGCPHYSRWAGG *PDBGFTRACERGCPHYSRWAGG;
525
526
527/**
528 * Tracer instance data, ring-3
529 */
530typedef struct DBGFTRACERINSR3
531{
532 /** Pointer to the next instance.
533 * (Head is pointed to by PDM::pTracerInstances.) */
534 R3PTRTYPE(struct DBGFTRACERINSR3 *) pNextR3;
535 /** R3 pointer to the VM this instance was created for. */
536 PVMR3 pVMR3;
537 /** Tracer instance number. */
538 uint32_t idTracer;
539 /** Flag whether the tracer has the R0 part enabled. */
540 bool fR0Enabled;
541 /** Flag whether the tracer flush thread should shut down. */
542 volatile bool fShutdown;
543 /** Padding. */
544 bool afPad0[6];
545 /** Next event source ID to return for a source registration. */
546 volatile DBGFTRACEREVTSRC hEvtSrcNext;
547 /** Pointer to the shared tracer instance data. */
548 R3PTRTYPE(PDBGFTRACERSHARED) pSharedR3;
549 /** The I/O thread writing the log from the shared event ringbuffer. */
550 RTTHREAD hThrdFlush;
551 /** Pointer to the start of the ring buffer. */
552 R3PTRTYPE(uint8_t *) pbRingBufR3;
553 /** The last processed event ID. */
554 uint64_t idEvtLast;
555 /** The trace log writer handle. */
556 RTTRACELOGWR hTraceLog;
557 /** Guest memory data aggregation structures to track
558 * currently pending guest memory reads/writes. */
559 DBGFTRACERGCPHYSRWAGG aGstMemRwData[10];
560} DBGFTRACERINSR3;
561/** Pointer to a tarcer instance - Ring-3 Ptr. */
562typedef R3PTRTYPE(DBGFTRACERINSR3 *) PDBGFTRACERINSR3;
563
564
565/**
566 * Private tracer instance data, ring-0
567 */
568typedef struct DBGFTRACERINSR0
569{
570 /** Pointer to the VM this instance was created for. */
571 R0PTRTYPE(PGVM) pGVM;
572 /** The tracer instance memory. */
573 RTR0MEMOBJ hMemObj;
574 /** The ring-3 mapping object. */
575 RTR0MEMOBJ hMapObj;
576 /** Pointer to the shared tracer instance data. */
577 R0PTRTYPE(PDBGFTRACERSHARED) pSharedR0;
578 /** Size of the ring buffer in bytes, kept here so R3 can not manipulate the ring buffer
579 * size afterwards to trick R0 into doing something harmful. */
580 size_t cbRingBuf;
581 /** Pointer to the start of the ring buffer. */
582 R0PTRTYPE(uint8_t *) pbRingBufR0;
583} DBGFTRACERINSR0;
584/** Pointer to a VM - Ring-0 Ptr. */
585typedef R0PTRTYPE(DBGFTRACERINSR0 *) PDBGFTRACERINSR0;
586
587
588/**
589 * Private device instance data, raw-mode
590 */
591typedef struct DBGFTRACERINSRC
592{
593 /** Pointer to the VM this instance was created for. */
594 RGPTRTYPE(PVM) pVMRC;
595} DBGFTRACERINSRC;
596
597
598#ifdef IN_RING3
599DECLHIDDEN(int) dbgfTracerR3EvtPostSingle(PVMCC pVM, PDBGFTRACERINSCC pThisCC, DBGFTRACEREVTSRC hEvtSrc,
600 DBGFTRACEREVT enmTraceEvt, const void *pvEvtDesc, size_t cbEvtDesc,
601 uint64_t *pidEvt);
602#endif
603
604/** VMM Debugger Command. */
605typedef enum DBGFCMD
606{
607 /** No command.
608 * This is assigned to the field by the emulation thread after
609 * a command has been completed. */
610 DBGFCMD_NO_COMMAND = 0,
611 /** Halt the VM. */
612 DBGFCMD_HALT,
613 /** Resume execution. */
614 DBGFCMD_GO,
615 /** Single step execution - stepping into calls. */
616 DBGFCMD_SINGLE_STEP
617} DBGFCMD;
618
619/**
620 * VMM Debugger Command.
621 */
622typedef union DBGFCMDDATA
623{
624 uint32_t uDummy;
625} DBGFCMDDATA;
626/** Pointer to DBGF Command Data. */
627typedef DBGFCMDDATA *PDBGFCMDDATA;
628
629/**
630 * Info type.
631 */
632typedef enum DBGFINFOTYPE
633{
634 /** Invalid. */
635 DBGFINFOTYPE_INVALID = 0,
636 /** Device owner. */
637 DBGFINFOTYPE_DEV,
638 /** Driver owner. */
639 DBGFINFOTYPE_DRV,
640 /** Internal owner. */
641 DBGFINFOTYPE_INT,
642 /** External owner. */
643 DBGFINFOTYPE_EXT,
644 /** Device owner. */
645 DBGFINFOTYPE_DEV_ARGV,
646 /** Driver owner. */
647 DBGFINFOTYPE_DRV_ARGV,
648 /** USB device owner. */
649 DBGFINFOTYPE_USB_ARGV,
650 /** Internal owner, argv. */
651 DBGFINFOTYPE_INT_ARGV,
652 /** External owner. */
653 DBGFINFOTYPE_EXT_ARGV
654} DBGFINFOTYPE;
655
656
657/** Pointer to info structure. */
658typedef struct DBGFINFO *PDBGFINFO;
659
660#ifdef IN_RING3
661/**
662 * Info structure.
663 */
664typedef struct DBGFINFO
665{
666 /** The flags. */
667 uint32_t fFlags;
668 /** Owner type. */
669 DBGFINFOTYPE enmType;
670 /** Per type data. */
671 union
672 {
673 /** DBGFINFOTYPE_DEV */
674 struct
675 {
676 /** Device info handler function. */
677 PFNDBGFHANDLERDEV pfnHandler;
678 /** The device instance. */
679 PPDMDEVINS pDevIns;
680 } Dev;
681
682 /** DBGFINFOTYPE_DRV */
683 struct
684 {
685 /** Driver info handler function. */
686 PFNDBGFHANDLERDRV pfnHandler;
687 /** The driver instance. */
688 PPDMDRVINS pDrvIns;
689 } Drv;
690
691 /** DBGFINFOTYPE_INT */
692 struct
693 {
694 /** Internal info handler function. */
695 PFNDBGFHANDLERINT pfnHandler;
696 } Int;
697
698 /** DBGFINFOTYPE_EXT */
699 struct
700 {
701 /** External info handler function. */
702 PFNDBGFHANDLEREXT pfnHandler;
703 /** The user argument. */
704 void *pvUser;
705 } Ext;
706
707 /** DBGFINFOTYPE_DEV_ARGV */
708 struct
709 {
710 /** Device info handler function. */
711 PFNDBGFINFOARGVDEV pfnHandler;
712 /** The device instance. */
713 PPDMDEVINS pDevIns;
714 } DevArgv;
715
716 /** DBGFINFOTYPE_DRV_ARGV */
717 struct
718 {
719 /** Driver info handler function. */
720 PFNDBGFINFOARGVDRV pfnHandler;
721 /** The driver instance. */
722 PPDMDRVINS pDrvIns;
723 } DrvArgv;
724
725 /** DBGFINFOTYPE_USB_ARGV */
726 struct
727 {
728 /** Driver info handler function. */
729 PFNDBGFINFOARGVUSB pfnHandler;
730 /** The driver instance. */
731 PPDMUSBINS pUsbIns;
732 } UsbArgv;
733
734 /** DBGFINFOTYPE_INT_ARGV */
735 struct
736 {
737 /** Internal info handler function. */
738 PFNDBGFINFOARGVINT pfnHandler;
739 } IntArgv;
740
741 /** DBGFINFOTYPE_EXT_ARGV */
742 struct
743 {
744 /** External info handler function. */
745 PFNDBGFINFOARGVEXT pfnHandler;
746 /** The user argument. */
747 void *pvUser;
748 } ExtArgv;
749 } u;
750
751 /** Pointer to the description. */
752 const char *pszDesc;
753 /** Pointer to the next info structure. */
754 PDBGFINFO pNext;
755 /** The identifier name length. */
756 size_t cchName;
757 /** The identifier name. (Extends 'beyond' the struct as usual.) */
758 char szName[1];
759} DBGFINFO;
760#endif /* IN_RING3 */
761
762
763#ifdef IN_RING3
764/**
765 * Guest OS digger instance.
766 */
767typedef struct DBGFOS
768{
769 /** Pointer to the registration record. */
770 PCDBGFOSREG pReg;
771 /** Pointer to the next OS we've registered. */
772 struct DBGFOS *pNext;
773 /** List of EMT interface wrappers. */
774 struct DBGFOSEMTWRAPPER *pWrapperHead;
775 /** The instance data (variable size). */
776 uint8_t abData[16];
777} DBGFOS;
778#endif
779/** Pointer to guest OS digger instance. */
780typedef struct DBGFOS *PDBGFOS;
781/** Pointer to const guest OS digger instance. */
782typedef struct DBGFOS const *PCDBGFOS;
783
784
785/** An invalid breakpoint chunk ID. */
786#define DBGF_BP_CHUNK_ID_INVALID UINT32_MAX
787/** Generates a unique breakpoint handle from the given chunk ID and entry inside the chunk. */
788#define DBGF_BP_HND_CREATE(a_idChunk, a_idEntry) RT_MAKE_U32(a_idEntry, a_idChunk);
789/** Returns the chunk ID from the given breakpoint handle. */
790#define DBGF_BP_HND_GET_CHUNK_ID(a_hBp) ((uint32_t)RT_HI_U16(a_hBp))
791/** Returns the entry index inside a chunk from the given breakpoint handle. */
792#define DBGF_BP_HND_GET_ENTRY(a_hBp) ((uint32_t)RT_LO_U16(a_hBp))
793
794
795/** @name DBGF int3 L1 lookup table entry types.
796 * @{ */
797/** No breakpoint handle assigned for this entry - special value which can be used
798 * for comparison with the whole entry. */
799#define DBGF_BP_INT3_L1_ENTRY_TYPE_NULL UINT32_C(0)
800/** Direct breakpoint handle. */
801#define DBGF_BP_INT3_L1_ENTRY_TYPE_BP_HND 1
802/** Index into the L2 tree denoting the root of a search tree. */
803#define DBGF_BP_INT3_L1_ENTRY_TYPE_L2_IDX 2
804/** @} */
805
806
807/** Returns the entry type for the given L1 lookup table entry. */
808#define DBGF_BP_INT3_L1_ENTRY_GET_TYPE(a_u32Entry) ((a_u32Entry) >> 28)
809/** Returns a DBGF breakpoint handle from the given L1 lookup table entry,
810 * type needs to be DBGF_BP_INT3_L1_ENTRY_TYPE_BP_HND. */
811#define DBGF_BP_INT3_L1_ENTRY_GET_BP_HND(a_u32Entry) ((DBGFBP)((a_u32Entry) & UINT32_C(0x0fffffff)))
812/** Returns a L2 index from the given L1 lookup table entry,
813 * type needs to be DBGF_BP_INT3_L1_ENTRY_TYPE_L2_IDX. */
814#define DBGF_BP_INT3_L1_ENTRY_GET_L2_IDX(a_u32Entry) ((a_u32Entry) & UINT32_C(0x0fffffff))
815/** Creates a L1 entry value from the given type and data. */
816#define DBGF_BP_INT3_L1_ENTRY_CREATE(a_Type, a_u32Data) ((((uint32_t)(a_Type)) << 28) | ((a_u32Data) & UINT32_C(0x0fffffff)))
817/** Creates a breakpoint handle type L1 lookup entry. */
818#define DBGF_BP_INT3_L1_ENTRY_CREATE_BP_HND(a_hBp) DBGF_BP_INT3_L1_ENTRY_CREATE(DBGF_BP_INT3_L1_ENTRY_TYPE_BP_HND, a_hBp)
819/** Creates a L2 index type L1 lookup entry. */
820#define DBGF_BP_INT3_L1_ENTRY_CREATE_L2_IDX(a_idxL2) DBGF_BP_INT3_L1_ENTRY_CREATE(DBGF_BP_INT3_L1_ENTRY_TYPE_L2_IDX, a_idxL2)
821
822/** Extracts the lowest bits from the given GC pointer used as an index into the L1 lookup table. */
823#define DBGF_BP_INT3_L1_IDX_EXTRACT_FROM_ADDR(a_GCPtr) ((uint16_t)((a_GCPtr) & UINT16_C(0xffff)))
824
825/**
826 * The internal breakpoint owner state, shared part.
827 */
828typedef struct DBGFBPOWNERINT
829{
830 /** Reference counter indicating how man breakpoints use this owner currently. */
831 volatile uint32_t cRefs;
832 /** Padding. */
833 uint32_t u32Pad0;
834 /** Callback to call when a breakpoint has hit, Ring-3 Ptr. */
835 R3PTRTYPE(PFNDBGFBPHIT) pfnBpHitR3;
836 /** Callback to call when a I/O breakpoint has hit, Ring-3 Ptr. */
837 R3PTRTYPE(PFNDBGFBPIOHIT) pfnBpIoHitR3;
838 /** Padding. */
839 uint64_t u64Pad1;
840} DBGFBPOWNERINT;
841AssertCompileSize(DBGFBPOWNERINT, 32);
842/** Pointer to an internal breakpoint owner state, shared part. */
843typedef DBGFBPOWNERINT *PDBGFBPOWNERINT;
844/** Pointer to a constant internal breakpoint owner state, shared part. */
845typedef const DBGFBPOWNERINT *PCDBGFBPOWNERINT;
846
847
848/**
849 * The internal breakpoint owner state, Ring-0 part.
850 */
851typedef struct DBGFBPOWNERINTR0
852{
853 /** Reference counter indicating how man breakpoints use this owner currently. */
854 volatile uint32_t cRefs;
855 /** Padding. */
856 uint32_t u32Pad0;
857 /** Callback to call when a breakpoint has hit, Ring-0 Ptr. */
858 R0PTRTYPE(PFNDBGFBPHIT) pfnBpHitR0;
859 /** Callback to call when a I/O breakpoint has hit, Ring-0 Ptr. */
860 R0PTRTYPE(PFNDBGFBPIOHIT) pfnBpIoHitR0;
861 /** Padding. */
862 uint64_t u64Pad1;
863} DBGFBPOWNERINTR0;
864AssertCompileSize(DBGFBPOWNERINTR0, 32);
865/** Pointer to an internal breakpoint owner state, shared part. */
866typedef DBGFBPOWNERINTR0 *PDBGFBPOWNERINTR0;
867/** Pointer to a constant internal breakpoint owner state, shared part. */
868typedef const DBGFBPOWNERINTR0 *PCDBGFBPOWNERINTR0;
869
870
871/**
872 * The internal breakpoint state, shared part.
873 */
874typedef struct DBGFBPINT
875{
876 /** The publicly visible part. */
877 DBGFBPPUB Pub;
878 /** The opaque user argument for the owner callback, Ring-3 Ptr. */
879 R3PTRTYPE(void *) pvUserR3;
880} DBGFBPINT;
881AssertCompileSize(DBGFBPINT, DBGF_BP_ENTRY_SZ);
882/** Pointer to an internal breakpoint state. */
883typedef DBGFBPINT *PDBGFBPINT;
884/** Pointer to an const internal breakpoint state. */
885typedef const DBGFBPINT *PCDBGFBPINT;
886
887
888/**
889 * The internal breakpoint state, R0 part.
890 */
891typedef struct DBGFBPINTR0
892{
893 /** The owner handle. */
894 DBGFBPOWNER hOwner;
895 /** Flag whether the breakpoint is in use. */
896 bool fInUse;
897 /** Padding to 8 byte alignment. */
898 bool afPad[3];
899 /** Opaque user data for the owner callback, Ring-0 Ptr. */
900 R0PTRTYPE(void *) pvUserR0;
901} DBGFBPINTR0;
902AssertCompileMemberAlignment(DBGFBPINTR0, pvUserR0, 8);
903AssertCompileSize(DBGFBPINTR0, 16);
904/** Pointer to an internal breakpoint state - Ring-0 Ptr. */
905typedef R0PTRTYPE(DBGFBPINTR0 *) PDBGFBPINTR0;
906
907
908/**
909 * Hardware breakpoint state.
910 */
911typedef struct DBGFBPHW
912{
913 /** The flat GC address of the breakpoint. */
914 RTGCUINTPTR GCPtr;
915 /** The breakpoint handle if active, NIL_DBGFBP if not in use. */
916 volatile DBGFBP hBp;
917 /** The access type (one of the X86_DR7_RW_* value). */
918 uint8_t fType;
919 /** The access size. */
920 uint8_t cb;
921 /** Flag whether the breakpoint is currently enabled. */
922 volatile bool fEnabled;
923 /** Padding. */
924 uint8_t bPad;
925} DBGFBPHW;
926AssertCompileSize(DBGFBPHW, 16);
927/** Pointer to a hardware breakpoint state. */
928typedef DBGFBPHW *PDBGFBPHW;
929/** Pointer to a const hardware breakpoint state. */
930typedef const DBGFBPHW *PCDBGFBPHW;
931
932
933/**
934 * A breakpoint table chunk, ring-3 state.
935 */
936typedef struct DBGFBPCHUNKR3
937{
938 /** Pointer to the R3 base of the chunk. */
939 R3PTRTYPE(PDBGFBPINT) pBpBaseR3;
940 /** Bitmap of free/occupied breakpoint entries. */
941 R3PTRTYPE(volatile void *) pbmAlloc;
942 /** Number of free breakpoints in the chunk. */
943 volatile uint32_t cBpsFree;
944 /** The chunk index this tracking structure refers to. */
945 uint32_t idChunk;
946} DBGFBPCHUNKR3;
947/** Pointer to a breakpoint table chunk - Ring-3 Ptr. */
948typedef DBGFBPCHUNKR3 *PDBGFBPCHUNKR3;
949/** Pointer to a const breakpoint table chunk - Ring-3 Ptr. */
950typedef const DBGFBPCHUNKR3 *PCDBGFBPCHUNKR3;
951
952
953/**
954 * Breakpoint table chunk, ring-0 state.
955 */
956typedef struct DBGFBPCHUNKR0
957{
958 /** The chunks memory. */
959 RTR0MEMOBJ hMemObj;
960 /** The ring-3 mapping object. */
961 RTR0MEMOBJ hMapObj;
962 /** Pointer to the breakpoint entries base. */
963 R0PTRTYPE(PDBGFBPINT) paBpBaseSharedR0;
964 /** Pointer to the Ring-0 only part of the breakpoints. */
965 PDBGFBPINTR0 paBpBaseR0Only;
966} DBGFBPCHUNKR0;
967/** Pointer to a breakpoint table chunk - Ring-0 Ptr. */
968typedef R0PTRTYPE(DBGFBPCHUNKR0 *) PDBGFBPCHUNKR0;
969
970
971/**
972 * L2 lookup table entry.
973 *
974 * @remark The order of the members matters to be able to atomically update
975 * the AVL left/right pointers and depth with a single 64bit atomic write.
976 * @verbatim
977 * 7 6 5 4 3 2 1 0
978 * +--------+--------+--------+--------+--------+--------+--------+--------+
979 * | hBp[15:0] | GCPtrKey[63:16] |
980 * +--------+--------+--------+--------+--------+--------+--------+--------+
981 * | hBp[27:16] | iDepth | idxRight[21:0] | idxLeft[21:0] |
982 * +--------+--------+--------+--------+--------+--------+--------+--------+
983 * \_8 bits_/
984 * @endverbatim
985 */
986typedef struct DBGFBPL2ENTRY
987{
988 /** The upper 6 bytes of the breakpoint address and the low 16 bits of the breakpoint handle. */
989 volatile uint64_t u64GCPtrKeyAndBpHnd1;
990 /** Left/right lower index, tree depth and remaining 12 bits of the breakpoint handle. */
991 volatile uint64_t u64LeftRightIdxDepthBpHnd2;
992} DBGFBPL2ENTRY;
993AssertCompileSize(DBGFBPL2ENTRY, 16);
994/** Pointer to a L2 lookup table entry. */
995typedef DBGFBPL2ENTRY *PDBGFBPL2ENTRY;
996/** Pointer to a const L2 lookup table entry. */
997typedef const DBGFBPL2ENTRY *PCDBGFBPL2ENTRY;
998
999/** Extracts the part from the given GC pointer used as the key in the L2 binary search tree. */
1000#define DBGF_BP_INT3_L2_KEY_EXTRACT_FROM_ADDR(a_GCPtr) ((uint64_t)((a_GCPtr) >> 16))
1001
1002/** An invalid breakpoint chunk ID. */
1003#define DBGF_BP_L2_IDX_CHUNK_ID_INVALID UINT32_MAX
1004/** Generates a unique breakpoint handle from the given chunk ID and entry inside the chunk. */
1005#define DBGF_BP_L2_IDX_CREATE(a_idChunk, a_idEntry) RT_MAKE_U32(a_idEntry, a_idChunk);
1006/** Returns the chunk ID from the given breakpoint handle. */
1007#define DBGF_BP_L2_IDX_GET_CHUNK_ID(a_idxL2) ((uint32_t)RT_HI_U16(a_idxL2))
1008/** Returns the entry index inside a chunk from the given breakpoint handle. */
1009#define DBGF_BP_L2_IDX_GET_ENTRY(a_idxL2) ((uint32_t)RT_LO_U16(a_idxL2))
1010
1011/** Number of bits for the left/right index pointers. */
1012#define DBGF_BP_L2_ENTRY_LEFT_RIGHT_IDX_BITS 22
1013/** Special index value marking the end of a tree. */
1014#define DBGF_BP_L2_ENTRY_IDX_END UINT32_C(0x3fffff)
1015/** Number of bits to shift the breakpoint handle in the first part. */
1016#define DBGF_BP_L2_ENTRY_BP_1ST_SHIFT 48
1017/** Mask for the first part of the breakpoint handle. */
1018#define DBGF_BP_L2_ENTRY_BP_1ST_MASK UINT32_C(0x0000ffff)
1019/** Number of bits to shift the breakpoint handle in the second part. */
1020#define DBGF_BP_L2_ENTRY_BP_2ND_SHIFT 52
1021/** Mask for the second part of the breakpoint handle. */
1022#define DBGF_BP_L2_ENTRY_BP_2ND_MASK UINT32_C(0x0fff0000)
1023/** Mask for the second part of the breakpoint handle stored in the L2 entry. */
1024#define DBGF_BP_L2_ENTRY_BP_2ND_L2_ENTRY_MASK UINT64_C(0xfff0000000000000)
1025/** Number of bits to shift the depth in the second part. */
1026#define DBGF_BP_L2_ENTRY_DEPTH_SHIFT 44
1027/** Mask for the depth. */
1028#define DBGF_BP_L2_ENTRY_DEPTH_MASK UINT8_MAX
1029/** Number of bits to shift the right L2 index in the second part. */
1030#define DBGF_BP_L2_ENTRY_RIGHT_IDX_SHIFT 22
1031/** Number of bits to shift the left L2 index in the second part. */
1032#define DBGF_BP_L2_ENTRY_LEFT_IDX_SHIFT 0
1033/** Index mask. */
1034#define DBGF_BP_L2_ENTRY_LEFT_RIGHT_IDX_MASK (RT_BIT_32(DBGF_BP_L2_ENTRY_LEFT_RIGHT_IDX_BITS) - 1)
1035/** Left index mask. */
1036#define DBGF_BP_L2_ENTRY_LEFT_IDX_MASK (DBGF_BP_L2_ENTRY_LEFT_RIGHT_IDX_MASK << DBGF_BP_L2_ENTRY_LEFT_IDX_SHIFT)
1037/** Right index mask. */
1038#define DBGF_BP_L2_ENTRY_RIGHT_IDX_MASK (DBGF_BP_L2_ENTRY_LEFT_RIGHT_IDX_MASK << DBGF_BP_L2_ENTRY_RIGHT_IDX_SHIFT)
1039/** Returns the upper 6 bytes of the GC pointer from the given breakpoint entry. */
1040#define DBGF_BP_L2_ENTRY_GET_GCPTR(a_u64GCPtrKeyAndBpHnd1) ((a_u64GCPtrKeyAndBpHnd1) & UINT64_C(0x0000ffffffffffff))
1041/** Returns the breakpoint handle from both L2 entry members. */
1042#define DBGF_BP_L2_ENTRY_GET_BP_HND(a_u64GCPtrKeyAndBpHnd1, a_u64LeftRightIdxDepthBpHnd2) \
1043 ((DBGFBP)(((a_u64GCPtrKeyAndBpHnd1) >> DBGF_BP_L2_ENTRY_BP_1ST_SHIFT) | (((a_u64LeftRightIdxDepthBpHnd2) >> DBGF_BP_L2_ENTRY_BP_2ND_SHIFT) << 16)))
1044/** Extracts the depth of the second 64bit L2 entry value. */
1045#define DBGF_BP_L2_ENTRY_GET_DEPTH(a_u64LeftRightIdxDepthBpHnd2) ((uint8_t)(((a_u64LeftRightIdxDepthBpHnd2) >> DBGF_BP_L2_ENTRY_DEPTH_SHIFT) & DBGF_BP_L2_ENTRY_DEPTH_MASK))
1046/** Extracts the lower right index value from the L2 entry value. */
1047#define DBGF_BP_L2_ENTRY_GET_IDX_RIGHT(a_u64LeftRightIdxDepthBpHnd2) \
1048 ((uint32_t)(((a_u64LeftRightIdxDepthBpHnd2) >> 22) & DBGF_BP_L2_ENTRY_LEFT_RIGHT_IDX_MASK))
1049/** Extracts the lower left index value from the L2 entry value. */
1050#define DBGF_BP_L2_ENTRY_GET_IDX_LEFT(a_u64LeftRightIdxDepthBpHnd2) \
1051 ((uint32_t)((a_u64LeftRightIdxDepthBpHnd2) & DBGF_BP_L2_ENTRY_LEFT_RIGHT_IDX_MASK))
1052
1053
1054/**
1055 * A breakpoint L2 lookup table chunk, ring-3 state.
1056 */
1057typedef struct DBGFBPL2TBLCHUNKR3
1058{
1059 /** Pointer to the R3 base of the chunk. */
1060 R3PTRTYPE(PDBGFBPL2ENTRY) pL2BaseR3;
1061 /** Bitmap of free/occupied breakpoint entries. */
1062 R3PTRTYPE(volatile void *) pbmAlloc;
1063 /** Number of free entries in the chunk. */
1064 volatile uint32_t cFree;
1065 /** The chunk index this tracking structure refers to. */
1066 uint32_t idChunk;
1067} DBGFBPL2TBLCHUNKR3;
1068/** Pointer to a breakpoint L2 lookup table chunk - Ring-3 Ptr. */
1069typedef DBGFBPL2TBLCHUNKR3 *PDBGFBPL2TBLCHUNKR3;
1070/** Pointer to a const breakpoint L2 lookup table chunk - Ring-3 Ptr. */
1071typedef const DBGFBPL2TBLCHUNKR3 *PCDBGFBPL2TBLCHUNKR3;
1072
1073
1074/**
1075 * Breakpoint L2 lookup table chunk, ring-0 state.
1076 */
1077typedef struct DBGFBPL2TBLCHUNKR0
1078{
1079 /** The chunks memory. */
1080 RTR0MEMOBJ hMemObj;
1081 /** The ring-3 mapping object. */
1082 RTR0MEMOBJ hMapObj;
1083 /** Pointer to the breakpoint entries base. */
1084 R0PTRTYPE(PDBGFBPL2ENTRY) paBpL2TblBaseSharedR0;
1085} DBGFBPL2TBLCHUNKR0;
1086/** Pointer to a breakpoint L2 lookup table chunk - Ring-0 Ptr. */
1087typedef R0PTRTYPE(DBGFBPL2TBLCHUNKR0 *) PDBGFBPL2TBLCHUNKR0;
1088
1089
1090
1091/**
1092 * DBGF Data (part of VM)
1093 */
1094typedef struct DBGF
1095{
1096 /** Bitmap of enabled hardware interrupt breakpoints. */
1097 uint32_t bmHardIntBreakpoints[256 / 32];
1098 /** Bitmap of enabled software interrupt breakpoints. */
1099 uint32_t bmSoftIntBreakpoints[256 / 32];
1100 /** Bitmap of selected events.
1101 * This includes non-selectable events too for simplicity, we maintain the
1102 * state for some of these, as it may come in handy. */
1103 uint64_t bmSelectedEvents[(DBGFEVENT_END + 63) / 64];
1104
1105 /** Enabled hardware interrupt breakpoints. */
1106 uint32_t cHardIntBreakpoints;
1107 /** Enabled software interrupt breakpoints. */
1108 uint32_t cSoftIntBreakpoints;
1109
1110 /** The number of selected events. */
1111 uint32_t cSelectedEvents;
1112
1113 /** The number of enabled hardware breakpoints. */
1114 uint8_t cEnabledHwBreakpoints;
1115 /** The number of enabled hardware I/O breakpoints. */
1116 uint8_t cEnabledHwIoBreakpoints;
1117 uint8_t au8Alignment1[2]; /**< Alignment padding. */
1118 /** The number of enabled INT3 breakpoints. */
1119 uint32_t volatile cEnabledInt3Breakpoints;
1120
1121 /** Debugger Attached flag.
1122 * Set if a debugger is attached, elsewise it's clear.
1123 */
1124 bool volatile fAttached;
1125
1126 /** Stepping filtering. */
1127 struct
1128 {
1129 /** The CPU doing the stepping.
1130 * Set to NIL_VMCPUID when filtering is inactive */
1131 VMCPUID idCpu;
1132 /** The specified flags. */
1133 uint32_t fFlags;
1134 /** The effective PC address to stop at, if given. */
1135 RTGCPTR AddrPc;
1136 /** The lowest effective stack address to stop at.
1137 * Together with cbStackPop, this forms a range of effective stack pointer
1138 * addresses that we stop for. */
1139 RTGCPTR AddrStackPop;
1140 /** The size of the stack stop area starting at AddrStackPop. */
1141 RTGCPTR cbStackPop;
1142 /** Maximum number of steps. */
1143 uint32_t cMaxSteps;
1144
1145 /** Number of steps made thus far. */
1146 uint32_t cSteps;
1147 /** Current call counting balance for step-over handling. */
1148 uint32_t uCallDepth;
1149
1150 uint32_t u32Padding; /**< Alignment padding. */
1151
1152 } SteppingFilter;
1153
1154 uint32_t au32Alignment2[2]; /**< Alignment padding. */
1155
1156 /** @name Breakpoint handling related state.
1157 * @{ */
1158 /** Array of hardware breakpoints (0..3).
1159 * This is shared among all the CPUs because life is much simpler that way. */
1160 DBGFBPHW aHwBreakpoints[4];
1161 /** @} */
1162
1163 /**
1164 * Bug check configuration and data.
1165 * @note The data will not be reset on reset.
1166 */
1167 struct
1168 {
1169 /** Whether to power off the VM on BSOD. */
1170 bool fCfgPowerOffOnBsod;
1171 /** Whether to suspend the VM on BSOD. */
1172 bool fCfgSuspendOnBsod;
1173 /** Explicit padding. */
1174 bool afReserved[2];
1175
1176 /** The ID of the CPU reporting it. */
1177 VMCPUID idCpu;
1178 /** The event associated with the bug check (gives source).
1179 * This is set to DBGFEVENT_END if no BSOD data here. */
1180 DBGFEVENTTYPE enmEvent;
1181 /** The total reset count at the time (VMGetResetCount). */
1182 uint32_t uResetNo;
1183 /** When it was reported (TMVirtualGet). */
1184 uint64_t uTimestamp;
1185 /** The bug check number.
1186 * @note This is really just 32-bit wide, see KeBugCheckEx. */
1187 uint64_t uBugCheck;
1188 /** The bug check parameters. */
1189 uint64_t auParameters[4];
1190 } BugCheck;
1191} DBGF;
1192AssertCompileMemberAlignment(DBGF, aHwBreakpoints, 8);
1193AssertCompileMemberAlignment(DBGF, bmHardIntBreakpoints, 8);
1194/** Pointer to DBGF Data. */
1195typedef DBGF *PDBGF;
1196
1197
1198/**
1199 * Event state (for DBGFCPU::aEvents).
1200 */
1201typedef enum DBGFEVENTSTATE
1202{
1203 /** Invalid event stack entry. */
1204 DBGFEVENTSTATE_INVALID = 0,
1205 /** The current event stack entry. */
1206 DBGFEVENTSTATE_CURRENT,
1207 /** Event that should be ignored but hasn't yet actually been ignored. */
1208 DBGFEVENTSTATE_IGNORE,
1209 /** Event that has been ignored but may be restored to IGNORE should another
1210 * debug event fire before the instruction is completed. */
1211 DBGFEVENTSTATE_RESTORABLE,
1212 /** End of valid events. */
1213 DBGFEVENTSTATE_END,
1214 /** Make sure we've got a 32-bit type. */
1215 DBGFEVENTSTATE_32BIT_HACK = 0x7fffffff
1216} DBGFEVENTSTATE;
1217
1218
1219/** Converts a DBGFCPU pointer into a VM pointer. */
1220#define DBGFCPU_2_VM(pDbgfCpu) ((PVM)((uint8_t *)(pDbgfCpu) + (pDbgfCpu)->offVM))
1221
1222/**
1223 * The per CPU data for DBGF.
1224 */
1225typedef struct DBGFCPU
1226{
1227 /** The offset into the VM structure.
1228 * @see DBGFCPU_2_VM(). */
1229 uint32_t offVM;
1230
1231 /** Flag whether the to invoke any owner handlers in ring-3 before dropping into the debugger. */
1232 bool fBpInvokeOwnerCallback;
1233 /** Set if we're singlestepping in raw mode.
1234 * This is checked and cleared in the \#DB handler. */
1235 bool fSingleSteppingRaw;
1236 /** Flag whether an I/O breakpoint is pending. */
1237 bool fBpIoActive;
1238 /** Flagh whether the I/O breakpoint hit before the access or after. */
1239 bool fBpIoBefore;
1240 /** Current active breakpoint handle.
1241 * This is NIL_DBGFBP if not active. It is set when a execution engine
1242 * encounters a breakpoint and returns VINF_EM_DBG_BREAKPOINT.
1243 *
1244 * @todo drop this in favor of aEvents! */
1245 DBGFBP hBpActive;
1246 /** The access mask for a pending I/O breakpoint. */
1247 uint32_t fBpIoAccess;
1248 /** The address of the access. */
1249 uint64_t uBpIoAddress;
1250 /** The value of the access. */
1251 uint64_t uBpIoValue;
1252
1253 /** The number of events on the stack (aEvents).
1254 * The pending event is the last one (aEvents[cEvents - 1]), but only when
1255 * enmState is DBGFEVENTSTATE_CURRENT. */
1256 uint32_t cEvents;
1257 /** Events - current, ignoring and ignored.
1258 *
1259 * We maintain a stack of events in order to try avoid ending up in an infinit
1260 * loop when resuming after an event fired. There are cases where we may end
1261 * generating additional events before the instruction can be executed
1262 * successfully. Like for instance an XCHG on MMIO with separate read and write
1263 * breakpoints, or a MOVSB instruction working on breakpointed MMIO as both
1264 * source and destination.
1265 *
1266 * So, when resuming after dropping into the debugger for an event, we convert
1267 * the DBGFEVENTSTATE_CURRENT event into a DBGFEVENTSTATE_IGNORE event, leaving
1268 * cEvents unchanged. If the event is reported again, we will ignore it and
1269 * tell the reporter to continue executing. The event change to the
1270 * DBGFEVENTSTATE_RESTORABLE state.
1271 *
1272 * Currently, the event reporter has to figure out that it is a nested event and
1273 * tell DBGF to restore DBGFEVENTSTATE_RESTORABLE events (and keep
1274 * DBGFEVENTSTATE_IGNORE, should they happen out of order for some weird
1275 * reason).
1276 */
1277 struct
1278 {
1279 /** The event details. */
1280 DBGFEVENT Event;
1281 /** The RIP at which this happend (for validating ignoring). */
1282 uint64_t rip;
1283 /** The event state. */
1284 DBGFEVENTSTATE enmState;
1285 /** Alignment padding. */
1286 uint32_t u32Alignment;
1287 } aEvents[3];
1288} DBGFCPU;
1289AssertCompileMemberAlignment(DBGFCPU, aEvents, 8);
1290AssertCompileMemberSizeAlignment(DBGFCPU, aEvents[0], 8);
1291/** Pointer to DBGFCPU data. */
1292typedef DBGFCPU *PDBGFCPU;
1293
1294struct DBGFOSEMTWRAPPER;
1295
1296/**
1297 * DBGF data kept in the ring-0 GVM.
1298 */
1299typedef struct DBGFR0PERVM
1300{
1301 /** Pointer to the tracer instance if enabled. */
1302 R0PTRTYPE(struct DBGFTRACERINSR0 *) pTracerR0;
1303
1304 /** @name Breakpoint handling related state, Ring-0 only part.
1305 * @{ */
1306 /** The breakpoint owner table memory object. */
1307 RTR0MEMOBJ hMemObjBpOwners;
1308 /** The breakpoint owner table mapping object. */
1309 RTR0MEMOBJ hMapObjBpOwners;
1310 /** Base pointer to the breakpoint owners table. */
1311 R0PTRTYPE(PDBGFBPOWNERINTR0) paBpOwnersR0;
1312
1313 /** Global breakpoint table chunk array. */
1314 DBGFBPCHUNKR0 aBpChunks[DBGF_BP_CHUNK_COUNT];
1315 /** Breakpoint L2 lookup table chunk array. */
1316 DBGFBPL2TBLCHUNKR0 aBpL2TblChunks[DBGF_BP_L2_TBL_CHUNK_COUNT];
1317 /** The L1 lookup tables memory object. */
1318 RTR0MEMOBJ hMemObjBpLocL1;
1319 /** The L1 lookup tables mapping object. */
1320 RTR0MEMOBJ hMapObjBpLocL1;
1321 /** The I/O port breakpoint lookup tables memory object. */
1322 RTR0MEMOBJ hMemObjBpLocPortIo;
1323 /** The I/O port breakpoint lookup tables mapping object. */
1324 RTR0MEMOBJ hMapObjBpLocPortIo;
1325 /** Base pointer to the L1 locator table. */
1326 R0PTRTYPE(volatile uint32_t *) paBpLocL1R0;
1327 /** Base pointer to the L1 locator table. */
1328 R0PTRTYPE(volatile uint32_t *) paBpLocPortIoR0;
1329 /** Flag whether the breakpoint manager was initialized (on demand). */
1330 bool fInit;
1331 /** @} */
1332} DBGFR0PERVM;
1333
1334/**
1335 * The DBGF data kept in the UVM.
1336 */
1337typedef struct DBGFUSERPERVM
1338{
1339 /** The address space database lock. */
1340 RTSEMRW hAsDbLock;
1341 /** The address space handle database. (Protected by hAsDbLock.) */
1342 R3PTRTYPE(AVLPVTREE) AsHandleTree;
1343 /** The address space process id database. (Protected by hAsDbLock.) */
1344 R3PTRTYPE(AVLU32TREE) AsPidTree;
1345 /** The address space name database. (Protected by hAsDbLock.) */
1346 R3PTRTYPE(RTSTRSPACE) AsNameSpace;
1347 /** Special address space aliases. (Protected by hAsDbLock.) */
1348 RTDBGAS volatile ahAsAliases[DBGF_AS_COUNT];
1349 /** For lazily populating the aliased address spaces. */
1350 bool volatile afAsAliasPopuplated[DBGF_AS_COUNT];
1351 /** Alignment padding. */
1352 bool afAlignment1[2];
1353 /** Debug configuration. */
1354 R3PTRTYPE(RTDBGCFG) hDbgCfg;
1355
1356 /** The register database lock. */
1357 RTSEMRW hRegDbLock;
1358 /** String space for looking up registers. (Protected by hRegDbLock.) */
1359 R3PTRTYPE(RTSTRSPACE) RegSpace;
1360 /** String space holding the register sets. (Protected by hRegDbLock.) */
1361 R3PTRTYPE(RTSTRSPACE) RegSetSpace;
1362 /** The number of registers (aliases, sub-fields and the special CPU
1363 * register aliases (eg AH) are not counted). */
1364 uint32_t cRegs;
1365 /** Number of registers per CPU. */
1366 uint16_t cPerCpuRegs;
1367 /** Number of hypervisor register per CPU. */
1368 uint8_t cPerCpuHyperRegs;
1369 /** For early initialization by . */
1370 bool volatile fRegDbInitialized;
1371
1372 /** Critical section protecting the Guest OS Digger data, the info handlers
1373 * and the plugins. These share to give the best possible plugin unload
1374 * race protection. */
1375 RTCRITSECTRW CritSect;
1376 /** Head of the LIFO of loaded DBGF plugins. */
1377 R3PTRTYPE(struct DBGFPLUGIN *) pPlugInHead;
1378 /** The current Guest OS digger. */
1379 R3PTRTYPE(PDBGFOS) pCurOS;
1380 /** The head of the Guest OS digger instances. */
1381 R3PTRTYPE(PDBGFOS) pOSHead;
1382 /** List of registered info handlers. */
1383 R3PTRTYPE(PDBGFINFO) pInfoFirst;
1384
1385 /** The configured tracer. */
1386 PDBGFTRACERINSR3 pTracerR3;
1387
1388 /** @name VM -> Debugger event communication.
1389 * @{ */
1390 /** The event semaphore the debugger waits on for new events to arrive. */
1391 RTSEMEVENT hEvtWait;
1392 /** Multi event semaphore the vCPUs wait on in case the debug event ringbuffer is
1393 * full and require growing (done from the thread waiting for events). */
1394 RTSEMEVENTMULTI hEvtRingBufFull;
1395 /** Fast mutex protecting the event ring from concurrent write accesses by multiple vCPUs. */
1396 RTSEMFASTMUTEX hMtxDbgEvtWr;
1397 /** Ringbuffer of events, dynamically allocated based on the number of available vCPUs
1398 * (+ some safety entries). */
1399 PDBGFEVENT paDbgEvts;
1400 /** Number of entries in the event ring buffer. */
1401 uint32_t cDbgEvtMax;
1402 /** Next free entry to write to (vCPU thread). */
1403 volatile uint32_t idxDbgEvtWrite;
1404 /** Next event entry to from (debugger thread). */
1405 volatile uint32_t idxDbgEvtRead;
1406 /** @} */
1407
1408 /** @name Breakpoint handling related state.
1409 * @{ */
1410 /** Base pointer to the breakpoint owners table. */
1411 R3PTRTYPE(PDBGFBPOWNERINT) paBpOwnersR3;
1412 /** Pointer to the bitmap denoting occupied owner entries. */
1413 R3PTRTYPE(volatile void *) pbmBpOwnersAllocR3;
1414
1415 /** Global breakpoint table chunk array. */
1416 DBGFBPCHUNKR3 aBpChunks[DBGF_BP_CHUNK_COUNT];
1417 /** Breakpoint L2 lookup table chunk array. */
1418 DBGFBPL2TBLCHUNKR3 aBpL2TblChunks[DBGF_BP_L2_TBL_CHUNK_COUNT];
1419 /** Base pointer to the L1 locator table. */
1420 R3PTRTYPE(volatile uint32_t *) paBpLocL1R3;
1421 /** Base pointer to the Port I/O breakpoint locator table. */
1422 R3PTRTYPE(volatile uint32_t *) paBpLocPortIoR3;
1423 /** Fast mutex protecting the L2 table from concurrent write accesses (EMTs
1424 * can still do read accesses without holding it while traversing the trees). */
1425 RTSEMFASTMUTEX hMtxBpL2Wr;
1426 /** Number of armed port I/O breakpoints. */
1427 volatile uint32_t cPortIoBps;
1428 /** @} */
1429
1430 /** The type database lock. */
1431 RTSEMRW hTypeDbLock;
1432 /** String space for looking up types. (Protected by hTypeDbLock.) */
1433 R3PTRTYPE(RTSTRSPACE) TypeSpace;
1434 /** For early initialization by . */
1435 bool volatile fTypeDbInitialized;
1436 /** Alignment padding. */
1437 bool afAlignment3[3];
1438
1439} DBGFUSERPERVM;
1440typedef DBGFUSERPERVM *PDBGFUSERPERVM;
1441typedef DBGFUSERPERVM const *PCDBGFUSERPERVM;
1442
1443/**
1444 * The per-CPU DBGF data kept in the UVM.
1445 */
1446typedef struct DBGFUSERPERVMCPU
1447{
1448 /** The guest register set for this CPU. Can be NULL. */
1449 R3PTRTYPE(struct DBGFREGSET *) pGuestRegSet;
1450 /** The hypervisor register set for this CPU. Can be NULL. */
1451 R3PTRTYPE(struct DBGFREGSET *) pHyperRegSet;
1452
1453 /** @name Debugger -> vCPU command communication.
1454 * @{ */
1455 /** Flag whether this vCPU is currently stopped waiting in the debugger. */
1456 bool volatile fStopped;
1457 /** The Command to the vCPU.
1458 * Operated in an atomic fashion since the vCPU will poll on this.
1459 * This means that a the command data must be written before this member
1460 * is set. The VMM will reset this member to the no-command state
1461 * when it have processed it.
1462 */
1463 DBGFCMD volatile enmDbgfCmd;
1464 /** The Command data.
1465 * Not all commands take data. */
1466 DBGFCMDDATA DbgfCmdData;
1467 /** @} */
1468
1469} DBGFUSERPERVMCPU;
1470
1471
1472#ifdef IN_RING3
1473int dbgfR3AsInit(PUVM pUVM);
1474void dbgfR3AsTerm(PUVM pUVM);
1475void dbgfR3AsRelocate(PUVM pUVM, RTGCUINTPTR offDelta);
1476DECLHIDDEN(int) dbgfR3BpInit(PUVM pUVM);
1477DECLHIDDEN(int) dbgfR3BpTerm(PUVM pUVM);
1478int dbgfR3InfoInit(PUVM pUVM);
1479int dbgfR3InfoTerm(PUVM pUVM);
1480int dbgfR3OSInit(PUVM pUVM);
1481void dbgfR3OSTermPart1(PUVM pUVM);
1482void dbgfR3OSTermPart2(PUVM pUVM);
1483int dbgfR3OSStackUnwindAssist(PUVM pUVM, VMCPUID idCpu, PDBGFSTACKFRAME pFrame, PRTDBGUNWINDSTATE pState,
1484 PCCPUMCTX pInitialCtx, RTDBGAS hAs, uint64_t *puScratch);
1485int dbgfR3RegInit(PUVM pUVM);
1486void dbgfR3RegTerm(PUVM pUVM);
1487int dbgfR3TraceInit(PVM pVM);
1488void dbgfR3TraceRelocate(PVM pVM);
1489void dbgfR3TraceTerm(PVM pVM);
1490DECLHIDDEN(int) dbgfR3TypeInit(PUVM pUVM);
1491DECLHIDDEN(void) dbgfR3TypeTerm(PUVM pUVM);
1492int dbgfR3PlugInInit(PUVM pUVM);
1493void dbgfR3PlugInTerm(PUVM pUVM);
1494int dbgfR3BugCheckInit(PVM pVM);
1495DECLHIDDEN(int) dbgfR3TracerInit(PVM pVM);
1496DECLHIDDEN(void) dbgfR3TracerTerm(PVM pVM);
1497
1498/**
1499 * DBGF disassembler state (substate of DISSTATE).
1500 */
1501typedef struct DBGFDISSTATE
1502{
1503 /** Pointer to the current instruction. */
1504 PCDISOPCODE pCurInstr;
1505 /** Size of the instruction in bytes. */
1506 uint32_t cbInstr;
1507 /** Parameters. */
1508 DISOPPARAM Param1;
1509 DISOPPARAM Param2;
1510 DISOPPARAM Param3;
1511 DISOPPARAM Param4;
1512} DBGFDISSTATE;
1513/** Pointer to a DBGF disassembler state. */
1514typedef DBGFDISSTATE *PDBGFDISSTATE;
1515
1516DECLHIDDEN(int) dbgfR3DisasInstrStateEx(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddr, uint32_t fFlags,
1517 char *pszOutput, uint32_t cbOutput, PDBGFDISSTATE pDisState);
1518
1519#endif /* IN_RING3 */
1520
1521#ifdef IN_RING0
1522DECLHIDDEN(void) dbgfR0TracerDestroy(PGVM pGVM, PDBGFTRACERINSR0 pTracer);
1523DECLHIDDEN(void) dbgfR0BpInit(PGVM pGVM);
1524DECLHIDDEN(void) dbgfR0BpDestroy(PGVM pGVM);
1525#endif /* !IN_RING0 */
1526
1527/** @} */
1528
1529#endif /* !VMM_INCLUDED_SRC_include_DBGFInternal_h */
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