VirtualBox

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

最後變更 在這個檔案從87130是 87130,由 vboxsync 提交於 4 年 前

VMM: More owner handling code for bugref:9837

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette