VirtualBox

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

Last change on this file since 86764 was 86726, checked in by vboxsync, 4 years ago

VMM/DBGF: Implement L2 binary search tree node insertion and walking the tree in R0, bugref:9837

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