VirtualBox

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

Last change on this file since 94249 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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