VirtualBox

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

Last change on this file since 86144 was 86098, checked in by vboxsync, 4 years ago

VMM/DBGF: Rework part 1 to make it work well with SMP VMs. bugref:9822

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 38.8 KB
Line 
1/* $Id: DBGFInternal.h 86098 2020-09-13 07:17:19Z vboxsync $ */
2/** @file
3 * DBGF - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VMM_INCLUDED_SRC_include_DBGFInternal_h
19#define VMM_INCLUDED_SRC_include_DBGFInternal_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <VBox/cdefs.h>
25#ifdef IN_RING3
26# include <VBox/dis.h>
27#endif
28#include <VBox/types.h>
29#include <iprt/semaphore.h>
30#include <iprt/critsect.h>
31#include <iprt/string.h>
32#include <iprt/avl.h>
33#include <iprt/dbg.h>
34#include <iprt/tracelog.h>
35#include <VBox/vmm/dbgf.h>
36
37
38
39/** @defgroup grp_dbgf_int Internals
40 * @ingroup grp_dbgf
41 * @internal
42 * @{
43 */
44
45/** The maximum tracer instance (total) size, ring-0/raw-mode capable tracers. */
46#define DBGF_MAX_TRACER_INSTANCE_SIZE _512M
47/** The maximum tracers instance (total) size, ring-3 only tracers. */
48#define DBGF_MAX_TRACER_INSTANCE_SIZE_R3 _1G
49/** Event ringbuffer header size. */
50#define DBGF_TRACER_EVT_HDR_SZ (32)
51/** Event ringbuffer payload size. */
52#define DBGF_TRACER_EVT_PAYLOAD_SZ (32)
53/** Event ringbuffer entry size. */
54#define DBGF_TRACER_EVT_SZ (DBGF_TRACER_EVT_HDR_SZ + DBGF_TRACER_EVT_PAYLOAD_SZ)
55
56
57
58/*******************************************************************************
59* Structures and Typedefs *
60*******************************************************************************/
61
62/**
63 * Event entry types.
64 */
65typedef enum DBGFTRACEREVT
66{
67 /** Invalid type. */
68 DBGFTRACEREVT_INVALID = 0,
69 /** Register event source event. */
70 DBGFTRACEREVT_SRC_REGISTER,
71 /** Deregister event source event. */
72 DBGFTRACEREVT_SRC_DEREGISTER,
73 /** MMIO region create event. */
74 DBGFTRACEREVT_MMIO_REGION_CREATE,
75 /** MMIO map region event. */
76 DBGFTRACEREVT_MMIO_MAP,
77 /** MMIO unmap region event. */
78 DBGFTRACEREVT_MMIO_UNMAP,
79 /** MMIO read event. */
80 DBGFTRACEREVT_MMIO_READ,
81 /** MMIO write event. */
82 DBGFTRACEREVT_MMIO_WRITE,
83 /** MMIO fill event. */
84 DBGFTRACEREVT_MMIO_FILL,
85 /** I/O port region create event. */
86 DBGFTRACEREVT_IOPORT_REGION_CREATE,
87 /** I/O port map event. */
88 DBGFTRACEREVT_IOPORT_MAP,
89 /** I/O port unmap event. */
90 DBGFTRACEREVT_IOPORT_UNMAP,
91 /** I/O port read event. */
92 DBGFTRACEREVT_IOPORT_READ,
93 /** I/O port read string event. */
94 DBGFTRACEREVT_IOPORT_READ_STR,
95 /** I/O port write event. */
96 DBGFTRACEREVT_IOPORT_WRITE,
97 /** I/O port write string event. */
98 DBGFTRACEREVT_IOPORT_WRITE_STR,
99 /** IRQ event. */
100 DBGFTRACEREVT_IRQ,
101 /** I/O APIC MSI event. */
102 DBGFTRACEREVT_IOAPIC_MSI,
103 /** Read from guest physical memory. */
104 DBGFTRACEREVT_GCPHYS_READ,
105 /** Write to guest physical memory. */
106 DBGFTRACEREVT_GCPHYS_WRITE,
107 /** 32bit hack. */
108 DBGFTRACEREVT_32BIT_HACK
109} DBGFTRACEREVT;
110/** Pointer to a trace event entry type. */
111typedef DBGFTRACEREVT *PDBGFTRACEREVT;
112
113
114/**
115 * MMIO region create event.
116 */
117typedef struct DBGFTRACEREVTMMIOCREATE
118{
119 /** Unique region handle for the event source. */
120 uint64_t hMmioRegion;
121 /** Size of the region in bytes. */
122 RTGCPHYS cbRegion;
123 /** IOM flags passed to the region. */
124 uint32_t fIomFlags;
125 /** The PCI region for a PCI device. */
126 uint32_t iPciRegion;
127 /** Padding to 32byte. */
128 uint64_t u64Pad0;
129} DBGFTRACEREVTMMIOCREATE;
130/** Pointer to a MMIO map event. */
131typedef DBGFTRACEREVTMMIOCREATE *PDBGFTRACEREVTMMIOCREATE;
132/** Pointer to a const MMIO map event. */
133typedef const DBGFTRACEREVTMMIOCREATE *PCDBGFTRACEREVTMMIOCREATE;
134
135AssertCompileSize(DBGFTRACEREVTMMIOCREATE, DBGF_TRACER_EVT_PAYLOAD_SZ);
136
137
138/**
139 * MMIO region map event.
140 */
141typedef struct DBGFTRACEREVTMMIOMAP
142{
143 /** Unique region handle for the event source. */
144 uint64_t hMmioRegion;
145 /** The base guest physical address of the MMIO region. */
146 RTGCPHYS GCPhysMmioBase;
147 /** Padding to 32byte. */
148 uint64_t au64Pad0[2];
149} DBGFTRACEREVTMMIOMAP;
150/** Pointer to a MMIO map event. */
151typedef DBGFTRACEREVTMMIOMAP *PDBGFTRACEREVTMMIOMAP;
152/** Pointer to a const MMIO map event. */
153typedef const DBGFTRACEREVTMMIOMAP *PCDBGFTRACEREVTMMIOMAP;
154
155AssertCompileSize(DBGFTRACEREVTMMIOMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
156
157
158/**
159 * MMIO region unmap event.
160 */
161typedef struct DBGFTRACEREVTMMIOUNMAP
162{
163 /** Unique region handle for the event source. */
164 uint64_t hMmioRegion;
165 /** Padding to 32byte. */
166 uint64_t au64Pad0[3];
167} DBGFTRACEREVTMMIOUNMAP;
168/** Pointer to a MMIO map event. */
169typedef DBGFTRACEREVTMMIOUNMAP *PDBGFTRACEREVTMMIOUNMAP;
170/** Pointer to a const MMIO map event. */
171typedef const DBGFTRACEREVTMMIOUNMAP *PCDBGFTRACEREVTMMIOUNMAP;
172
173AssertCompileSize(DBGFTRACEREVTMMIOUNMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
174
175
176/**
177 * MMIO event.
178 */
179typedef struct DBGFTRACEREVTMMIO
180{
181 /** Unique region handle for the event source. */
182 uint64_t hMmioRegion;
183 /** Offset into the region the access happened. */
184 RTGCPHYS offMmio;
185 /** Number of bytes transfered (the direction is in the event header). */
186 uint64_t cbXfer;
187 /** The value transfered. */
188 uint64_t u64Val;
189} DBGFTRACEREVTMMIO;
190/** Pointer to a MMIO event. */
191typedef DBGFTRACEREVTMMIO *PDBGFTRACEREVTMMIO;
192/** Pointer to a const MMIO event. */
193typedef const DBGFTRACEREVTMMIO *PCDBGFTRACEREVTMMIO;
194
195AssertCompileSize(DBGFTRACEREVTMMIO, DBGF_TRACER_EVT_PAYLOAD_SZ);
196
197
198/**
199 * MMIO fill event.
200 */
201typedef struct DBGFTRACEREVTMMIOFILL
202{
203 /** Unique region handle for the event source. */
204 uint64_t hMmioRegion;
205 /** Offset into the region the access happened. */
206 RTGCPHYS offMmio;
207 /** Item size in bytes. */
208 uint32_t cbItem;
209 /** Amount of items being filled. */
210 uint32_t cItems;
211 /** The fill value. */
212 uint32_t u32Item;
213 /** Padding to 32bytes. */
214 uint32_t u32Pad0;
215} DBGFTRACEREVTMMIOFILL;
216/** Pointer to a MMIO event. */
217typedef DBGFTRACEREVTMMIOFILL *PDBGFTRACEREVTMMIOFILL;
218/** Pointer to a const MMIO event. */
219typedef const DBGFTRACEREVTMMIOFILL *PCDBGFTRACEREVTMMIOFILL;
220
221AssertCompileSize(DBGFTRACEREVTMMIOFILL, DBGF_TRACER_EVT_PAYLOAD_SZ);
222
223
224/**
225 * I/O port region create event.
226 */
227typedef struct DBGFTRACEREVTIOPORTCREATE
228{
229 /** Unique I/O port region handle for the event source. */
230 uint64_t hIoPorts;
231 /** Number of ports. */
232 RTIOPORT cPorts;
233 /** Padding. */
234 uint16_t u16Pad0;
235 /** IOM flags passed to the region. */
236 uint32_t fIomFlags;
237 /** The PCI region for a PCI device. */
238 uint32_t iPciRegion;
239 /** Padding to 32byte. */
240 uint32_t u32Pad0[3];
241} DBGFTRACEREVTIOPORTCREATE;
242/** Pointer to a MMIO map event. */
243typedef DBGFTRACEREVTIOPORTCREATE *PDBGFTRACEREVTIOPORTCREATE;
244/** Pointer to a const MMIO map event. */
245typedef const DBGFTRACEREVTIOPORTCREATE *PCDBGFTRACEREVTIOPORTCREATE;
246
247AssertCompileSize(DBGFTRACEREVTIOPORTCREATE, DBGF_TRACER_EVT_PAYLOAD_SZ);
248
249
250/**
251 * I/O port region map event.
252 */
253typedef struct DBGFTRACEREVTIOPORTMAP
254{
255 /** Unique I/O port region handle for the event source. */
256 uint64_t hIoPorts;
257 /** The base I/O port for the region. */
258 RTIOPORT IoPortBase;
259 /** Padding to 32byte. */
260 uint16_t au16Pad0[11];
261} DBGFTRACEREVTIOPORTMAP;
262/** Pointer to a MMIO map event. */
263typedef DBGFTRACEREVTIOPORTMAP *PDBGFTRACEREVTIOPORTMAP;
264/** Pointer to a const MMIO map event. */
265typedef const DBGFTRACEREVTIOPORTMAP *PCDBGFTRACEREVTIOPORTMAP;
266
267AssertCompileSize(DBGFTRACEREVTIOPORTMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
268
269
270/**
271 * MMIO region unmap event.
272 */
273typedef struct DBGFTRACEREVTIOPORTUNMAP
274{
275 /** Unique region handle for the event source. */
276 uint64_t hIoPorts;
277 /** Padding to 32byte. */
278 uint64_t au64Pad0[3];
279} DBGFTRACEREVTIOPORTUNMAP;
280/** Pointer to a MMIO map event. */
281typedef DBGFTRACEREVTIOPORTUNMAP *PDBGFTRACEREVTIOPORTUNMAP;
282/** Pointer to a const MMIO map event. */
283typedef const DBGFTRACEREVTIOPORTUNMAP *PCDBGFTRACEREVTIOPORTUNMAP;
284
285AssertCompileSize(DBGFTRACEREVTIOPORTUNMAP, DBGF_TRACER_EVT_PAYLOAD_SZ);
286
287
288/**
289 * I/O port event.
290 */
291typedef struct DBGFTRACEREVTIOPORT
292{
293 /** Unique region handle for the event source. */
294 uint64_t hIoPorts;
295 /** Offset into the I/O port region. */
296 RTIOPORT offPort;
297 /** 8 byte alignment. */
298 uint8_t abPad0[6];
299 /** Number of bytes transfered (the direction is in the event header). */
300 uint64_t cbXfer;
301 /** The value transfered. */
302 uint32_t u32Val;
303 /** Padding to 32bytes. */
304 uint8_t abPad1[4];
305} DBGFTRACEREVTIOPORT;
306/** Pointer to a MMIO event. */
307typedef DBGFTRACEREVTIOPORT *PDBGFTRACEREVTIOPORT;
308/** Pointer to a const MMIO event. */
309typedef const DBGFTRACEREVTIOPORT *PCDBGFTRACEREVTIOPORT;
310
311AssertCompileSize(DBGFTRACEREVTIOPORT, DBGF_TRACER_EVT_PAYLOAD_SZ);
312
313
314/**
315 * I/O port string event.
316 */
317typedef struct DBGFTRACEREVTIOPORTSTR
318{
319 /** Unique region handle for the event source. */
320 uint64_t hIoPorts;
321 /** Item size in bytes. */
322 uint32_t cbItem;
323 /** Number of transfers requested - for writes this gives the amount of valid data following. */
324 uint32_t cTransfersReq;
325 /** Number of transfers done - for reads this gives the amount of valid data following. */
326 uint32_t cTransfersRet;
327 /** Offset into the I/O port region. */
328 RTIOPORT offPort;
329 /** Data being transfered. */
330 uint8_t abData[10];
331} DBGFTRACEREVTIOPORTSTR;
332/** Pointer to a MMIO event. */
333typedef DBGFTRACEREVTIOPORTSTR *PDBGFTRACEREVTIOPORTSTR;
334/** Pointer to a const MMIO event. */
335typedef const DBGFTRACEREVTIOPORTSTR *PCDBGFTRACEREVTIOPORTSTR;
336
337AssertCompileSize(DBGFTRACEREVTIOPORTSTR, DBGF_TRACER_EVT_PAYLOAD_SZ);
338
339
340/**
341 * IRQ event.
342 */
343typedef struct DBGFTRACEREVTIRQ
344{
345 /** The IRQ line. */
346 int32_t iIrq;
347 /** IRQ level flags. */
348 int32_t fIrqLvl;
349 /** Padding to 32bytes. */
350 uint32_t au32Pad0[6];
351} DBGFTRACEREVTIRQ;
352/** Pointer to a MMIO event. */
353typedef DBGFTRACEREVTIRQ *PDBGFTRACEREVTIRQ;
354/** Pointer to a const MMIO event. */
355typedef const DBGFTRACEREVTIRQ *PCDBGFTRACEREVTIRQ;
356
357AssertCompileSize(DBGFTRACEREVTIRQ, DBGF_TRACER_EVT_PAYLOAD_SZ);
358
359
360/**
361 * I/O APIC MSI event.
362 */
363typedef struct DBGFTRACEREVTIOAPICMSI
364{
365 /** The guest physical address being written. */
366 RTGCPHYS GCPhys;
367 /** The value being written. */
368 uint32_t u32Val;
369 /** Padding to 32bytes. */
370 uint32_t au32Pad0[5];
371} DBGFTRACEREVTIOAPICMSI;
372/** Pointer to a MMIO event. */
373typedef DBGFTRACEREVTIOAPICMSI *PDBGFTRACEREVTIOAPICMSI;
374/** Pointer to a const MMIO event. */
375typedef const DBGFTRACEREVTIOAPICMSI *PCDBGFTRACEREVTIOAPICMSI;
376
377AssertCompileSize(DBGFTRACEREVTIOAPICMSI, DBGF_TRACER_EVT_PAYLOAD_SZ);
378
379
380/**
381 * Guest physical memory transfer.
382 */
383typedef struct DBGFTRACEREVTGCPHYS
384{
385 /** Guest physical address of the access. */
386 RTGCPHYS GCPhys;
387 /** Number of bytes transfered (the direction is in the event header).
388 * If the number is small enough to fit into the remaining space of the entry
389 * it is stored here, otherwise it will be stored in the next entry (and following
390 * entries). */
391 uint64_t cbXfer;
392 /** Guest data being transfered. */
393 uint8_t abData[16];
394} DBGFTRACEREVTGCPHYS;
395/** Pointer to a guest physical memory transfer event. */
396typedef DBGFTRACEREVTGCPHYS *PDBGFTRACEREVTGCPHYS;
397/** Pointer to a const uest physical memory transfer event. */
398typedef const DBGFTRACEREVTGCPHYS *PCDBGFTRACEREVTGCPHYS;
399
400AssertCompileSize(DBGFTRACEREVTGCPHYS, DBGF_TRACER_EVT_PAYLOAD_SZ);
401
402
403/**
404 * A trace event header in the shared ring buffer.
405 */
406typedef struct DBGFTRACEREVTHDR
407{
408 /** Event ID. */
409 volatile uint64_t idEvt;
410 /** The previous event ID this one links to,
411 * DBGF_TRACER_EVT_HDR_ID_INVALID if it links to no other event. */
412 uint64_t idEvtPrev;
413 /** Event source. */
414 DBGFTRACEREVTSRC hEvtSrc;
415 /** The event entry type. */
416 DBGFTRACEREVT enmEvt;
417 /** Flags for this event. */
418 uint32_t fFlags;
419} DBGFTRACEREVTHDR;
420/** Pointer to a trace event header. */
421typedef DBGFTRACEREVTHDR *PDBGFTRACEREVTHDR;
422/** Pointer to a const trace event header. */
423typedef const DBGFTRACEREVTHDR *PCDBGFTRACEREVTHDR;
424
425AssertCompileSize(DBGFTRACEREVTHDR, DBGF_TRACER_EVT_HDR_SZ);
426
427/** Invalid event ID, this is always set by the flush thread after processing one entry
428 * so the producers know when they are about to overwrite not yet processed entries in the ring buffer. */
429#define DBGF_TRACER_EVT_HDR_ID_INVALID UINT64_C(0xffffffffffffffff)
430
431/** The event came from R0. */
432#define DBGF_TRACER_EVT_HDR_F_R0 RT_BIT(0)
433
434/** Default event header tracer flags. */
435#ifdef IN_RING0
436# define DBGF_TRACER_EVT_HDR_F_DEFAULT DBGF_TRACER_EVT_HDR_F_R0
437#else
438# define DBGF_TRACER_EVT_HDR_F_DEFAULT (0)
439#endif
440
441
442/**
443 * Tracer instance data, shared structure.
444 */
445typedef struct DBGFTRACERSHARED
446{
447 /** The global event ID counter, monotonically increasing.
448 * Accessed by all threads causing a trace event. */
449 volatile uint64_t idEvt;
450 /** The SUP event semaphore for poking the flush thread. */
451 SUPSEMEVENT hSupSemEvtFlush;
452 /** Ring buffer size. */
453 size_t cbRingBuf;
454 /** Flag whether there are events in the ring buffer to get processed. */
455 volatile bool fEvtsWaiting;
456 /** Flag whether the flush thread is actively running or was kicked. */
457 volatile bool fFlushThrdActive;
458 /** Padding to a 64byte alignment. */
459 uint8_t abAlignment0[32];
460} DBGFTRACERSHARED;
461/** Pointer to the shared tarcer instance data. */
462typedef DBGFTRACERSHARED *PDBGFTRACERSHARED;
463
464AssertCompileSizeAlignment(DBGFTRACERSHARED, 64);
465
466
467/**
468 * Guest memory read/write data aggregation.
469 */
470typedef struct DBGFTRACERGCPHYSRWAGG
471{
472 /** The event ID which started the aggregation (used for the group ID when writing out the event). */
473 uint64_t idEvtStart;
474 /** The previous event ID used to link all the chunks together. */
475 uint64_t idEvtPrev;
476 /** Number of bytes being transfered. */
477 size_t cbXfer;
478 /** Amount of data left to aggregate before it can be written. */
479 size_t cbLeft;
480 /** Amount of bytes allocated. */
481 size_t cbBufMax;
482 /** Offset into the buffer to write next. */
483 size_t offBuf;
484 /** Pointer to the allocated buffer. */
485 uint8_t *pbBuf;
486} DBGFTRACERGCPHYSRWAGG;
487/** Pointer to a guest memory read/write data aggregation structure. */
488typedef DBGFTRACERGCPHYSRWAGG *PDBGFTRACERGCPHYSRWAGG;
489
490
491/**
492 * Tracer instance data, ring-3
493 */
494typedef struct DBGFTRACERINSR3
495{
496 /** Pointer to the next instance.
497 * (Head is pointed to by PDM::pTracerInstances.) */
498 R3PTRTYPE(struct DBGFTRACERINSR3 *) pNextR3;
499 /** R3 pointer to the VM this instance was created for. */
500 PVMR3 pVMR3;
501 /** Tracer instance number. */
502 uint32_t idTracer;
503 /** Flag whether the tracer has the R0 part enabled. */
504 bool fR0Enabled;
505 /** Flag whether the tracer flush thread should shut down. */
506 volatile bool fShutdown;
507 /** Padding. */
508 bool afPad0[6];
509 /** Next event source ID to return for a source registration. */
510 volatile DBGFTRACEREVTSRC hEvtSrcNext;
511 /** Pointer to the shared tracer instance data. */
512 R3PTRTYPE(PDBGFTRACERSHARED) pSharedR3;
513 /** The I/O thread writing the log from the shared event ringbuffer. */
514 RTTHREAD hThrdFlush;
515 /** Pointer to the start of the ring buffer. */
516 R3PTRTYPE(uint8_t *) pbRingBufR3;
517 /** The last processed event ID. */
518 uint64_t idEvtLast;
519 /** The trace log writer handle. */
520 RTTRACELOGWR hTraceLog;
521 /** Guest memory data aggregation structures to track
522 * currently pending guest memory reads/writes. */
523 DBGFTRACERGCPHYSRWAGG aGstMemRwData[10];
524} DBGFTRACERINSR3;
525/** Pointer to a tarcer instance - Ring-3 Ptr. */
526typedef R3PTRTYPE(DBGFTRACERINSR3 *) PDBGFTRACERINSR3;
527
528
529/**
530 * Private tracer instance data, ring-0
531 */
532typedef struct DBGFTRACERINSR0
533{
534 /** Pointer to the VM this instance was created for. */
535 R0PTRTYPE(PGVM) pGVM;
536 /** The tracer instance memory. */
537 RTR0MEMOBJ hMemObj;
538 /** The ring-3 mapping object. */
539 RTR0MEMOBJ hMapObj;
540 /** Pointer to the shared tracer instance data. */
541 R0PTRTYPE(PDBGFTRACERSHARED) pSharedR0;
542 /** Size of the ring buffer in bytes, kept here so R3 can not manipulate the ring buffer
543 * size afterwards to trick R0 into doing something harmful. */
544 size_t cbRingBuf;
545 /** Pointer to the start of the ring buffer. */
546 R0PTRTYPE(uint8_t *) pbRingBufR0;
547} DBGFTRACERINSR0;
548/** Pointer to a VM - Ring-0 Ptr. */
549typedef R0PTRTYPE(DBGFTRACERINSR0 *) PDBGFTRACERINSR0;
550
551
552/**
553 * Private device instance data, raw-mode
554 */
555typedef struct DBGFTRACERINSRC
556{
557 /** Pointer to the VM this instance was created for. */
558 RGPTRTYPE(PVM) pVMRC;
559} DBGFTRACERINSRC;
560
561
562#ifdef IN_RING3
563DECLHIDDEN(int) dbgfTracerR3EvtPostSingle(PVMCC pVM, PDBGFTRACERINSCC pThisCC, DBGFTRACEREVTSRC hEvtSrc,
564 DBGFTRACEREVT enmTraceEvt, const void *pvEvtDesc, size_t cbEvtDesc,
565 uint64_t *pidEvt);
566#endif
567
568/** VMM Debugger Command. */
569typedef enum DBGFCMD
570{
571 /** No command.
572 * This is assigned to the field by the emulation thread after
573 * a command has been completed. */
574 DBGFCMD_NO_COMMAND = 0,
575 /** Halt the VM. */
576 DBGFCMD_HALT,
577 /** Resume execution. */
578 DBGFCMD_GO,
579 /** Single step execution - stepping into calls. */
580 DBGFCMD_SINGLE_STEP
581} DBGFCMD;
582
583/**
584 * VMM Debugger Command.
585 */
586typedef union DBGFCMDDATA
587{
588 uint32_t uDummy;
589} DBGFCMDDATA;
590/** Pointer to DBGF Command Data. */
591typedef DBGFCMDDATA *PDBGFCMDDATA;
592
593/**
594 * Info type.
595 */
596typedef enum DBGFINFOTYPE
597{
598 /** Invalid. */
599 DBGFINFOTYPE_INVALID = 0,
600 /** Device owner. */
601 DBGFINFOTYPE_DEV,
602 /** Driver owner. */
603 DBGFINFOTYPE_DRV,
604 /** Internal owner. */
605 DBGFINFOTYPE_INT,
606 /** External owner. */
607 DBGFINFOTYPE_EXT,
608 /** Device owner. */
609 DBGFINFOTYPE_DEV_ARGV,
610 /** Driver owner. */
611 DBGFINFOTYPE_DRV_ARGV,
612 /** USB device owner. */
613 DBGFINFOTYPE_USB_ARGV,
614 /** Internal owner, argv. */
615 DBGFINFOTYPE_INT_ARGV,
616 /** External owner. */
617 DBGFINFOTYPE_EXT_ARGV
618} DBGFINFOTYPE;
619
620
621/** Pointer to info structure. */
622typedef struct DBGFINFO *PDBGFINFO;
623
624#ifdef IN_RING3
625/**
626 * Info structure.
627 */
628typedef struct DBGFINFO
629{
630 /** The flags. */
631 uint32_t fFlags;
632 /** Owner type. */
633 DBGFINFOTYPE enmType;
634 /** Per type data. */
635 union
636 {
637 /** DBGFINFOTYPE_DEV */
638 struct
639 {
640 /** Device info handler function. */
641 PFNDBGFHANDLERDEV pfnHandler;
642 /** The device instance. */
643 PPDMDEVINS pDevIns;
644 } Dev;
645
646 /** DBGFINFOTYPE_DRV */
647 struct
648 {
649 /** Driver info handler function. */
650 PFNDBGFHANDLERDRV pfnHandler;
651 /** The driver instance. */
652 PPDMDRVINS pDrvIns;
653 } Drv;
654
655 /** DBGFINFOTYPE_INT */
656 struct
657 {
658 /** Internal info handler function. */
659 PFNDBGFHANDLERINT pfnHandler;
660 } Int;
661
662 /** DBGFINFOTYPE_EXT */
663 struct
664 {
665 /** External info handler function. */
666 PFNDBGFHANDLEREXT pfnHandler;
667 /** The user argument. */
668 void *pvUser;
669 } Ext;
670
671 /** DBGFINFOTYPE_DEV_ARGV */
672 struct
673 {
674 /** Device info handler function. */
675 PFNDBGFINFOARGVDEV pfnHandler;
676 /** The device instance. */
677 PPDMDEVINS pDevIns;
678 } DevArgv;
679
680 /** DBGFINFOTYPE_DRV_ARGV */
681 struct
682 {
683 /** Driver info handler function. */
684 PFNDBGFINFOARGVDRV pfnHandler;
685 /** The driver instance. */
686 PPDMDRVINS pDrvIns;
687 } DrvArgv;
688
689 /** DBGFINFOTYPE_USB_ARGV */
690 struct
691 {
692 /** Driver info handler function. */
693 PFNDBGFINFOARGVUSB pfnHandler;
694 /** The driver instance. */
695 PPDMUSBINS pUsbIns;
696 } UsbArgv;
697
698 /** DBGFINFOTYPE_INT_ARGV */
699 struct
700 {
701 /** Internal info handler function. */
702 PFNDBGFINFOARGVINT pfnHandler;
703 } IntArgv;
704
705 /** DBGFINFOTYPE_EXT_ARGV */
706 struct
707 {
708 /** External info handler function. */
709 PFNDBGFINFOARGVEXT pfnHandler;
710 /** The user argument. */
711 void *pvUser;
712 } ExtArgv;
713 } u;
714
715 /** Pointer to the description. */
716 const char *pszDesc;
717 /** Pointer to the next info structure. */
718 PDBGFINFO pNext;
719 /** The identifier name length. */
720 size_t cchName;
721 /** The identifier name. (Extends 'beyond' the struct as usual.) */
722 char szName[1];
723} DBGFINFO;
724#endif /* IN_RING3 */
725
726
727#ifdef IN_RING3
728/**
729 * Guest OS digger instance.
730 */
731typedef struct DBGFOS
732{
733 /** Pointer to the registration record. */
734 PCDBGFOSREG pReg;
735 /** Pointer to the next OS we've registered. */
736 struct DBGFOS *pNext;
737 /** List of EMT interface wrappers. */
738 struct DBGFOSEMTWRAPPER *pWrapperHead;
739 /** The instance data (variable size). */
740 uint8_t abData[16];
741} DBGFOS;
742#endif
743/** Pointer to guest OS digger instance. */
744typedef struct DBGFOS *PDBGFOS;
745/** Pointer to const guest OS digger instance. */
746typedef struct DBGFOS const *PCDBGFOS;
747
748
749/**
750 * Breakpoint search optimization.
751 */
752typedef struct DBGFBPSEARCHOPT
753{
754 /** Where to start searching for hits.
755 * (First enabled is #DBGF::aBreakpoints[iStartSearch]). */
756 uint32_t volatile iStartSearch;
757 /** The number of aBreakpoints entries to search.
758 * (Last enabled is #DBGF::aBreakpoints[iStartSearch + cToSearch - 1]) */
759 uint32_t volatile cToSearch;
760} DBGFBPSEARCHOPT;
761/** Pointer to a breakpoint search optimziation structure. */
762typedef DBGFBPSEARCHOPT *PDBGFBPSEARCHOPT;
763
764
765
766/**
767 * DBGF Data (part of VM)
768 */
769typedef struct DBGF
770{
771 /** Bitmap of enabled hardware interrupt breakpoints. */
772 uint32_t bmHardIntBreakpoints[256 / 32];
773 /** Bitmap of enabled software interrupt breakpoints. */
774 uint32_t bmSoftIntBreakpoints[256 / 32];
775 /** Bitmap of selected events.
776 * This includes non-selectable events too for simplicity, we maintain the
777 * state for some of these, as it may come in handy. */
778 uint64_t bmSelectedEvents[(DBGFEVENT_END + 63) / 64];
779
780 /** Enabled hardware interrupt breakpoints. */
781 uint32_t cHardIntBreakpoints;
782 /** Enabled software interrupt breakpoints. */
783 uint32_t cSoftIntBreakpoints;
784
785 /** The number of selected events. */
786 uint32_t cSelectedEvents;
787
788 /** The number of enabled hardware breakpoints. */
789 uint8_t cEnabledHwBreakpoints;
790 /** The number of enabled hardware I/O breakpoints. */
791 uint8_t cEnabledHwIoBreakpoints;
792 /** The number of enabled INT3 breakpoints. */
793 uint8_t cEnabledInt3Breakpoints;
794 uint8_t abPadding; /**< Unused padding space up for grabs. */
795 uint32_t uPadding;
796
797 /** Debugger Attached flag.
798 * Set if a debugger is attached, elsewise it's clear.
799 */
800 bool volatile fAttached;
801
802 /** Stepping filtering. */
803 struct
804 {
805 /** The CPU doing the stepping.
806 * Set to NIL_VMCPUID when filtering is inactive */
807 VMCPUID idCpu;
808 /** The specified flags. */
809 uint32_t fFlags;
810 /** The effective PC address to stop at, if given. */
811 RTGCPTR AddrPc;
812 /** The lowest effective stack address to stop at.
813 * Together with cbStackPop, this forms a range of effective stack pointer
814 * addresses that we stop for. */
815 RTGCPTR AddrStackPop;
816 /** The size of the stack stop area starting at AddrStackPop. */
817 RTGCPTR cbStackPop;
818 /** Maximum number of steps. */
819 uint32_t cMaxSteps;
820
821 /** Number of steps made thus far. */
822 uint32_t cSteps;
823 /** Current call counting balance for step-over handling. */
824 uint32_t uCallDepth;
825
826 uint32_t u32Padding; /**< Alignment padding. */
827
828 } SteppingFilter;
829
830 uint32_t u32Padding[2]; /**< Alignment padding. */
831
832 /** Array of hardware breakpoints. (0..3)
833 * This is shared among all the CPUs because life is much simpler that way. */
834 DBGFBP aHwBreakpoints[4];
835 /** Array of int 3 and REM breakpoints. (4..)
836 * @remark This is currently a fixed size array for reasons of simplicity. */
837 DBGFBP aBreakpoints[32];
838
839 /** MMIO breakpoint search optimizations. */
840 DBGFBPSEARCHOPT Mmio;
841 /** I/O port breakpoint search optimizations. */
842 DBGFBPSEARCHOPT PortIo;
843 /** INT3 breakpoint search optimizations. */
844 DBGFBPSEARCHOPT Int3;
845
846 /**
847 * Bug check data.
848 * @note This will not be reset on reset.
849 */
850 struct
851 {
852 /** The ID of the CPU reporting it. */
853 VMCPUID idCpu;
854 /** The event associated with the bug check (gives source).
855 * This is set to DBGFEVENT_END if no BSOD data here. */
856 DBGFEVENTTYPE enmEvent;
857 /** The total reset count at the time (VMGetResetCount). */
858 uint32_t uResetNo;
859 /** Explicit padding. */
860 uint32_t uPadding;
861 /** When it was reported (TMVirtualGet). */
862 uint64_t uTimestamp;
863 /** The bug check number.
864 * @note This is really just 32-bit wide, see KeBugCheckEx. */
865 uint64_t uBugCheck;
866 /** The bug check parameters. */
867 uint64_t auParameters[4];
868 } BugCheck;
869} DBGF;
870AssertCompileMemberAlignment(DBGF, aHwBreakpoints, 8);
871AssertCompileMemberAlignment(DBGF, bmHardIntBreakpoints, 8);
872/** Pointer to DBGF Data. */
873typedef DBGF *PDBGF;
874
875
876/**
877 * Event state (for DBGFCPU::aEvents).
878 */
879typedef enum DBGFEVENTSTATE
880{
881 /** Invalid event stack entry. */
882 DBGFEVENTSTATE_INVALID = 0,
883 /** The current event stack entry. */
884 DBGFEVENTSTATE_CURRENT,
885 /** Event that should be ignored but hasn't yet actually been ignored. */
886 DBGFEVENTSTATE_IGNORE,
887 /** Event that has been ignored but may be restored to IGNORE should another
888 * debug event fire before the instruction is completed. */
889 DBGFEVENTSTATE_RESTORABLE,
890 /** End of valid events. */
891 DBGFEVENTSTATE_END,
892 /** Make sure we've got a 32-bit type. */
893 DBGFEVENTSTATE_32BIT_HACK = 0x7fffffff
894} DBGFEVENTSTATE;
895
896
897/** Converts a DBGFCPU pointer into a VM pointer. */
898#define DBGFCPU_2_VM(pDbgfCpu) ((PVM)((uint8_t *)(pDbgfCpu) + (pDbgfCpu)->offVM))
899
900/**
901 * The per CPU data for DBGF.
902 */
903typedef struct DBGFCPU
904{
905 /** The offset into the VM structure.
906 * @see DBGFCPU_2_VM(). */
907 uint32_t offVM;
908
909 /** Current active breakpoint (id).
910 * This is ~0U if not active. It is set when a execution engine
911 * encounters a breakpoint and returns VINF_EM_DBG_BREAKPOINT. This is
912 * currently not used for REM breakpoints because of the lazy coupling
913 * between VBox and REM.
914 *
915 * @todo drop this in favor of aEvents! */
916 uint32_t iActiveBp;
917 /** Set if we're singlestepping in raw mode.
918 * This is checked and cleared in the \#DB handler. */
919 bool fSingleSteppingRaw;
920
921 /** Alignment padding. */
922 bool afPadding[3];
923
924 /** The number of events on the stack (aEvents).
925 * The pending event is the last one (aEvents[cEvents - 1]), but only when
926 * enmState is DBGFEVENTSTATE_CURRENT. */
927 uint32_t cEvents;
928 /** Events - current, ignoring and ignored.
929 *
930 * We maintain a stack of events in order to try avoid ending up in an infinit
931 * loop when resuming after an event fired. There are cases where we may end
932 * generating additional events before the instruction can be executed
933 * successfully. Like for instance an XCHG on MMIO with separate read and write
934 * breakpoints, or a MOVSB instruction working on breakpointed MMIO as both
935 * source and destination.
936 *
937 * So, when resuming after dropping into the debugger for an event, we convert
938 * the DBGFEVENTSTATE_CURRENT event into a DBGFEVENTSTATE_IGNORE event, leaving
939 * cEvents unchanged. If the event is reported again, we will ignore it and
940 * tell the reporter to continue executing. The event change to the
941 * DBGFEVENTSTATE_RESTORABLE state.
942 *
943 * Currently, the event reporter has to figure out that it is a nested event and
944 * tell DBGF to restore DBGFEVENTSTATE_RESTORABLE events (and keep
945 * DBGFEVENTSTATE_IGNORE, should they happen out of order for some weird
946 * reason).
947 */
948 struct
949 {
950 /** The event details. */
951 DBGFEVENT Event;
952 /** The RIP at which this happend (for validating ignoring). */
953 uint64_t rip;
954 /** The event state. */
955 DBGFEVENTSTATE enmState;
956 /** Alignment padding. */
957 uint32_t u32Alignment;
958 } aEvents[3];
959} DBGFCPU;
960AssertCompileMemberAlignment(DBGFCPU, aEvents, 8);
961AssertCompileMemberSizeAlignment(DBGFCPU, aEvents[0], 8);
962/** Pointer to DBGFCPU data. */
963typedef DBGFCPU *PDBGFCPU;
964
965struct DBGFOSEMTWRAPPER;
966
967/**
968 * DBGF data kept in the ring-0 GVM.
969 */
970typedef struct DBGFR0PERVM
971{
972 /** Pointer to the tracer instance if enabled. */
973 R0PTRTYPE(struct DBGFTRACERINSR0 *) pTracerR0;
974} DBGFR0PERVM;
975
976/**
977 * The DBGF data kept in the UVM.
978 */
979typedef struct DBGFUSERPERVM
980{
981 /** The address space database lock. */
982 RTSEMRW hAsDbLock;
983 /** The address space handle database. (Protected by hAsDbLock.) */
984 R3PTRTYPE(AVLPVTREE) AsHandleTree;
985 /** The address space process id database. (Protected by hAsDbLock.) */
986 R3PTRTYPE(AVLU32TREE) AsPidTree;
987 /** The address space name database. (Protected by hAsDbLock.) */
988 R3PTRTYPE(RTSTRSPACE) AsNameSpace;
989 /** Special address space aliases. (Protected by hAsDbLock.) */
990 RTDBGAS volatile ahAsAliases[DBGF_AS_COUNT];
991 /** For lazily populating the aliased address spaces. */
992 bool volatile afAsAliasPopuplated[DBGF_AS_COUNT];
993 /** Alignment padding. */
994 bool afAlignment1[2];
995 /** Debug configuration. */
996 R3PTRTYPE(RTDBGCFG) hDbgCfg;
997
998 /** The register database lock. */
999 RTSEMRW hRegDbLock;
1000 /** String space for looking up registers. (Protected by hRegDbLock.) */
1001 R3PTRTYPE(RTSTRSPACE) RegSpace;
1002 /** String space holding the register sets. (Protected by hRegDbLock.) */
1003 R3PTRTYPE(RTSTRSPACE) RegSetSpace;
1004 /** The number of registers (aliases, sub-fields and the special CPU
1005 * register aliases (eg AH) are not counted). */
1006 uint32_t cRegs;
1007 /** For early initialization by . */
1008 bool volatile fRegDbInitialized;
1009 /** Alignment padding. */
1010 bool afAlignment2[3];
1011
1012 /** Critical section protecting the Guest OS Digger data, the info handlers
1013 * and the plugins. These share to give the best possible plugin unload
1014 * race protection. */
1015 RTCRITSECTRW CritSect;
1016 /** Head of the LIFO of loaded DBGF plugins. */
1017 R3PTRTYPE(struct DBGFPLUGIN *) pPlugInHead;
1018 /** The current Guest OS digger. */
1019 R3PTRTYPE(PDBGFOS) pCurOS;
1020 /** The head of the Guest OS digger instances. */
1021 R3PTRTYPE(PDBGFOS) pOSHead;
1022 /** List of registered info handlers. */
1023 R3PTRTYPE(PDBGFINFO) pInfoFirst;
1024
1025 /** The configured tracer. */
1026 PDBGFTRACERINSR3 pTracerR3;
1027
1028 /** @name VM -> Debugger event communication.
1029 * @{ */
1030 /** The event semaphore the debugger waits on for new events to arrive. */
1031 RTSEMEVENT hEvtWait;
1032 /** Multi event semaphore the vCPUs wait on in case the debug event ringbuffer is
1033 * full and require growing (done from the thread waiting for events). */
1034 RTSEMEVENTMULTI hEvtRingBufFull;
1035 /** Fast mutex protecting the event ring from concurrent write accesses by multiple vCPUs. */
1036 RTSEMFASTMUTEX hMtxDbgEvtWr;
1037 /** Ringbuffer of events, dynamically allocated based on the number of available vCPUs
1038 * (+ some safety entries). */
1039 PDBGFEVENT paDbgEvts;
1040 /** Number of entries in the event ring buffer. */
1041 uint32_t cDbgEvtMax;
1042 /** Next free entry to write to (vCPU thread). */
1043 volatile uint32_t idxDbgEvtWrite;
1044 /** Next event entry to from (debugger thread). */
1045 volatile uint32_t idxDbgEvtRead;
1046 /** @} */
1047
1048 /** The type database lock. */
1049 RTSEMRW hTypeDbLock;
1050 /** String space for looking up types. (Protected by hTypeDbLock.) */
1051 R3PTRTYPE(RTSTRSPACE) TypeSpace;
1052 /** For early initialization by . */
1053 bool volatile fTypeDbInitialized;
1054 /** Alignment padding. */
1055 bool afAlignment3[3];
1056
1057} DBGFUSERPERVM;
1058typedef DBGFUSERPERVM *PDBGFUSERPERVM;
1059typedef DBGFUSERPERVM const *PCDBGFUSERPERVM;
1060
1061/**
1062 * The per-CPU DBGF data kept in the UVM.
1063 */
1064typedef struct DBGFUSERPERVMCPU
1065{
1066 /** The guest register set for this CPU. Can be NULL. */
1067 R3PTRTYPE(struct DBGFREGSET *) pGuestRegSet;
1068 /** The hypervisor register set for this CPU. Can be NULL. */
1069 R3PTRTYPE(struct DBGFREGSET *) pHyperRegSet;
1070
1071 /** @name Debugger -> vCPU command communication.
1072 * @{ */
1073 /** Flag whether this vCPU is currently stopped waiting in the debugger. */
1074 bool volatile fStopped;
1075 /** The Command to the vCPU.
1076 * Operated in an atomic fashion since the vCPU will poll on this.
1077 * This means that a the command data must be written before this member
1078 * is set. The VMM will reset this member to the no-command state
1079 * when it have processed it.
1080 */
1081 DBGFCMD volatile enmDbgfCmd;
1082 /** The Command data.
1083 * Not all commands take data. */
1084 DBGFCMDDATA DbgfCmdData;
1085 /** @} */
1086
1087} DBGFUSERPERVMCPU;
1088
1089
1090#ifdef IN_RING3
1091int dbgfR3AsInit(PUVM pUVM);
1092void dbgfR3AsTerm(PUVM pUVM);
1093void dbgfR3AsRelocate(PUVM pUVM, RTGCUINTPTR offDelta);
1094int dbgfR3BpInit(PVM pVM);
1095int dbgfR3InfoInit(PUVM pUVM);
1096int dbgfR3InfoTerm(PUVM pUVM);
1097int dbgfR3OSInit(PUVM pUVM);
1098void dbgfR3OSTermPart1(PUVM pUVM);
1099void dbgfR3OSTermPart2(PUVM pUVM);
1100int dbgfR3OSStackUnwindAssist(PUVM pUVM, VMCPUID idCpu, PDBGFSTACKFRAME pFrame, PRTDBGUNWINDSTATE pState,
1101 PCCPUMCTX pInitialCtx, RTDBGAS hAs, uint64_t *puScratch);
1102int dbgfR3RegInit(PUVM pUVM);
1103void dbgfR3RegTerm(PUVM pUVM);
1104int dbgfR3TraceInit(PVM pVM);
1105void dbgfR3TraceRelocate(PVM pVM);
1106void dbgfR3TraceTerm(PVM pVM);
1107DECLHIDDEN(int) dbgfR3TypeInit(PUVM pUVM);
1108DECLHIDDEN(void) dbgfR3TypeTerm(PUVM pUVM);
1109int dbgfR3PlugInInit(PUVM pUVM);
1110void dbgfR3PlugInTerm(PUVM pUVM);
1111int dbgfR3BugCheckInit(PVM pVM);
1112DECLHIDDEN(int) dbgfR3TracerInit(PVM pVM);
1113DECLHIDDEN(void) dbgfR3TracerTerm(PVM pVM);
1114
1115/**
1116 * DBGF disassembler state (substate of DISSTATE).
1117 */
1118typedef struct DBGFDISSTATE
1119{
1120 /** Pointer to the current instruction. */
1121 PCDISOPCODE pCurInstr;
1122 /** Size of the instruction in bytes. */
1123 uint32_t cbInstr;
1124 /** Parameters. */
1125 DISOPPARAM Param1;
1126 DISOPPARAM Param2;
1127 DISOPPARAM Param3;
1128 DISOPPARAM Param4;
1129} DBGFDISSTATE;
1130/** Pointer to a DBGF disassembler state. */
1131typedef DBGFDISSTATE *PDBGFDISSTATE;
1132
1133DECLHIDDEN(int) dbgfR3DisasInstrStateEx(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddr, uint32_t fFlags,
1134 char *pszOutput, uint32_t cbOutput, PDBGFDISSTATE pDisState);
1135
1136#endif /* IN_RING3 */
1137
1138/** @} */
1139
1140#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