VirtualBox

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

Last change on this file since 105072 was 102092, checked in by vboxsync, 13 months ago

VMM/DBGF,DBGC,Main: Added DBGFR3RegNmQueryEx and fixed some issues with DBGFR3RegNmQueryAll that lead to assertions in Main and empty entries in VBoxManage output. Extended the 'r' and 'rg' debugger commands to make use of the two APIs, the first by appending '.' to a register (e.g. r @cr0.) and the latter by using 'all' as the register name.

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