VirtualBox

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

Last change on this file since 85972 was 84766, checked in by vboxsync, 5 years ago

VMM/DBGFTracer: Add events when I/O port and MMIO regions are created, bugref:9210

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 38.6 KB
Line 
1/* $Id: DBGFInternal.h 84766 2020-06-10 17:40:13Z 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 /** Detaches the debugger.
582 * Disabling all breakpoints, watch points and the like. */
583 DBGFCMD_DETACH_DEBUGGER,
584 /** Detached the debugger.
585 * The isn't a command as such, it's just that it's necessary for the
586 * detaching protocol to be racefree. */
587 DBGFCMD_DETACHED_DEBUGGER
588} DBGFCMD;
589
590/**
591 * VMM Debugger Command.
592 */
593typedef union DBGFCMDDATA
594{
595 uint32_t uDummy;
596} DBGFCMDDATA;
597/** Pointer to DBGF Command Data. */
598typedef DBGFCMDDATA *PDBGFCMDDATA;
599
600/**
601 * Info type.
602 */
603typedef enum DBGFINFOTYPE
604{
605 /** Invalid. */
606 DBGFINFOTYPE_INVALID = 0,
607 /** Device owner. */
608 DBGFINFOTYPE_DEV,
609 /** Driver owner. */
610 DBGFINFOTYPE_DRV,
611 /** Internal owner. */
612 DBGFINFOTYPE_INT,
613 /** External owner. */
614 DBGFINFOTYPE_EXT,
615 /** Device owner. */
616 DBGFINFOTYPE_DEV_ARGV,
617 /** Driver owner. */
618 DBGFINFOTYPE_DRV_ARGV,
619 /** USB device owner. */
620 DBGFINFOTYPE_USB_ARGV,
621 /** Internal owner, argv. */
622 DBGFINFOTYPE_INT_ARGV,
623 /** External owner. */
624 DBGFINFOTYPE_EXT_ARGV
625} DBGFINFOTYPE;
626
627
628/** Pointer to info structure. */
629typedef struct DBGFINFO *PDBGFINFO;
630
631#ifdef IN_RING3
632/**
633 * Info structure.
634 */
635typedef struct DBGFINFO
636{
637 /** The flags. */
638 uint32_t fFlags;
639 /** Owner type. */
640 DBGFINFOTYPE enmType;
641 /** Per type data. */
642 union
643 {
644 /** DBGFINFOTYPE_DEV */
645 struct
646 {
647 /** Device info handler function. */
648 PFNDBGFHANDLERDEV pfnHandler;
649 /** The device instance. */
650 PPDMDEVINS pDevIns;
651 } Dev;
652
653 /** DBGFINFOTYPE_DRV */
654 struct
655 {
656 /** Driver info handler function. */
657 PFNDBGFHANDLERDRV pfnHandler;
658 /** The driver instance. */
659 PPDMDRVINS pDrvIns;
660 } Drv;
661
662 /** DBGFINFOTYPE_INT */
663 struct
664 {
665 /** Internal info handler function. */
666 PFNDBGFHANDLERINT pfnHandler;
667 } Int;
668
669 /** DBGFINFOTYPE_EXT */
670 struct
671 {
672 /** External info handler function. */
673 PFNDBGFHANDLEREXT pfnHandler;
674 /** The user argument. */
675 void *pvUser;
676 } Ext;
677
678 /** DBGFINFOTYPE_DEV_ARGV */
679 struct
680 {
681 /** Device info handler function. */
682 PFNDBGFINFOARGVDEV pfnHandler;
683 /** The device instance. */
684 PPDMDEVINS pDevIns;
685 } DevArgv;
686
687 /** DBGFINFOTYPE_DRV_ARGV */
688 struct
689 {
690 /** Driver info handler function. */
691 PFNDBGFINFOARGVDRV pfnHandler;
692 /** The driver instance. */
693 PPDMDRVINS pDrvIns;
694 } DrvArgv;
695
696 /** DBGFINFOTYPE_USB_ARGV */
697 struct
698 {
699 /** Driver info handler function. */
700 PFNDBGFINFOARGVUSB pfnHandler;
701 /** The driver instance. */
702 PPDMUSBINS pUsbIns;
703 } UsbArgv;
704
705 /** DBGFINFOTYPE_INT_ARGV */
706 struct
707 {
708 /** Internal info handler function. */
709 PFNDBGFINFOARGVINT pfnHandler;
710 } IntArgv;
711
712 /** DBGFINFOTYPE_EXT_ARGV */
713 struct
714 {
715 /** External info handler function. */
716 PFNDBGFINFOARGVEXT pfnHandler;
717 /** The user argument. */
718 void *pvUser;
719 } ExtArgv;
720 } u;
721
722 /** Pointer to the description. */
723 const char *pszDesc;
724 /** Pointer to the next info structure. */
725 PDBGFINFO pNext;
726 /** The identifier name length. */
727 size_t cchName;
728 /** The identifier name. (Extends 'beyond' the struct as usual.) */
729 char szName[1];
730} DBGFINFO;
731#endif /* IN_RING3 */
732
733
734#ifdef IN_RING3
735/**
736 * Guest OS digger instance.
737 */
738typedef struct DBGFOS
739{
740 /** Pointer to the registration record. */
741 PCDBGFOSREG pReg;
742 /** Pointer to the next OS we've registered. */
743 struct DBGFOS *pNext;
744 /** List of EMT interface wrappers. */
745 struct DBGFOSEMTWRAPPER *pWrapperHead;
746 /** The instance data (variable size). */
747 uint8_t abData[16];
748} DBGFOS;
749#endif
750/** Pointer to guest OS digger instance. */
751typedef struct DBGFOS *PDBGFOS;
752/** Pointer to const guest OS digger instance. */
753typedef struct DBGFOS const *PCDBGFOS;
754
755
756/**
757 * Breakpoint search optimization.
758 */
759typedef struct DBGFBPSEARCHOPT
760{
761 /** Where to start searching for hits.
762 * (First enabled is #DBGF::aBreakpoints[iStartSearch]). */
763 uint32_t volatile iStartSearch;
764 /** The number of aBreakpoints entries to search.
765 * (Last enabled is #DBGF::aBreakpoints[iStartSearch + cToSearch - 1]) */
766 uint32_t volatile cToSearch;
767} DBGFBPSEARCHOPT;
768/** Pointer to a breakpoint search optimziation structure. */
769typedef DBGFBPSEARCHOPT *PDBGFBPSEARCHOPT;
770
771
772
773/**
774 * DBGF Data (part of VM)
775 */
776typedef struct DBGF
777{
778 /** Bitmap of enabled hardware interrupt breakpoints. */
779 uint32_t bmHardIntBreakpoints[256 / 32];
780 /** Bitmap of enabled software interrupt breakpoints. */
781 uint32_t bmSoftIntBreakpoints[256 / 32];
782 /** Bitmap of selected events.
783 * This includes non-selectable events too for simplicity, we maintain the
784 * state for some of these, as it may come in handy. */
785 uint64_t bmSelectedEvents[(DBGFEVENT_END + 63) / 64];
786
787 /** Enabled hardware interrupt breakpoints. */
788 uint32_t cHardIntBreakpoints;
789 /** Enabled software interrupt breakpoints. */
790 uint32_t cSoftIntBreakpoints;
791
792 /** The number of selected events. */
793 uint32_t cSelectedEvents;
794
795 /** The number of enabled hardware breakpoints. */
796 uint8_t cEnabledHwBreakpoints;
797 /** The number of enabled hardware I/O breakpoints. */
798 uint8_t cEnabledHwIoBreakpoints;
799 /** The number of enabled INT3 breakpoints. */
800 uint8_t cEnabledInt3Breakpoints;
801 uint8_t abPadding; /**< Unused padding space up for grabs. */
802 uint32_t uPadding;
803
804 /** Debugger Attached flag.
805 * Set if a debugger is attached, elsewise it's clear.
806 */
807 bool volatile fAttached;
808
809 /** Stopped in the Hypervisor.
810 * Set if we're stopped on a trace, breakpoint or assertion inside
811 * the hypervisor and have to restrict the available operations.
812 */
813 bool volatile fStoppedInHyper;
814
815 /**
816 * Ping-Pong construct where the Ping side is the VMM and the Pong side
817 * the Debugger.
818 */
819 RTPINGPONG PingPong;
820 RTHCUINTPTR uPtrPadding; /**< Alignment padding. */
821
822 /** The Event to the debugger.
823 * The VMM will ping the debugger when the event is ready. The event is
824 * either a response to a command or to a break/watch point issued
825 * previously.
826 */
827 DBGFEVENT DbgEvent;
828
829 /** The Command to the VMM.
830 * Operated in an atomic fashion since the VMM will poll on this.
831 * This means that a the command data must be written before this member
832 * is set. The VMM will reset this member to the no-command state
833 * when it have processed it.
834 */
835 DBGFCMD volatile enmVMMCmd;
836 /** The Command data.
837 * Not all commands take data. */
838 DBGFCMDDATA VMMCmdData;
839
840 /** Stepping filtering. */
841 struct
842 {
843 /** The CPU doing the stepping.
844 * Set to NIL_VMCPUID when filtering is inactive */
845 VMCPUID idCpu;
846 /** The specified flags. */
847 uint32_t fFlags;
848 /** The effective PC address to stop at, if given. */
849 RTGCPTR AddrPc;
850 /** The lowest effective stack address to stop at.
851 * Together with cbStackPop, this forms a range of effective stack pointer
852 * addresses that we stop for. */
853 RTGCPTR AddrStackPop;
854 /** The size of the stack stop area starting at AddrStackPop. */
855 RTGCPTR cbStackPop;
856 /** Maximum number of steps. */
857 uint32_t cMaxSteps;
858
859 /** Number of steps made thus far. */
860 uint32_t cSteps;
861 /** Current call counting balance for step-over handling. */
862 uint32_t uCallDepth;
863
864 uint32_t u32Padding; /**< Alignment padding. */
865
866 } SteppingFilter;
867
868 uint32_t u32Padding[2]; /**< Alignment padding. */
869
870 /** Array of hardware breakpoints. (0..3)
871 * This is shared among all the CPUs because life is much simpler that way. */
872 DBGFBP aHwBreakpoints[4];
873 /** Array of int 3 and REM breakpoints. (4..)
874 * @remark This is currently a fixed size array for reasons of simplicity. */
875 DBGFBP aBreakpoints[32];
876
877 /** MMIO breakpoint search optimizations. */
878 DBGFBPSEARCHOPT Mmio;
879 /** I/O port breakpoint search optimizations. */
880 DBGFBPSEARCHOPT PortIo;
881 /** INT3 breakpoint search optimizations. */
882 DBGFBPSEARCHOPT Int3;
883
884 /**
885 * Bug check data.
886 * @note This will not be reset on reset.
887 */
888 struct
889 {
890 /** The ID of the CPU reporting it. */
891 VMCPUID idCpu;
892 /** The event associated with the bug check (gives source).
893 * This is set to DBGFEVENT_END if no BSOD data here. */
894 DBGFEVENTTYPE enmEvent;
895 /** The total reset count at the time (VMGetResetCount). */
896 uint32_t uResetNo;
897 /** Explicit padding. */
898 uint32_t uPadding;
899 /** When it was reported (TMVirtualGet). */
900 uint64_t uTimestamp;
901 /** The bug check number.
902 * @note This is really just 32-bit wide, see KeBugCheckEx. */
903 uint64_t uBugCheck;
904 /** The bug check parameters. */
905 uint64_t auParameters[4];
906 } BugCheck;
907} DBGF;
908AssertCompileMemberAlignment(DBGF, DbgEvent, 8);
909AssertCompileMemberAlignment(DBGF, aHwBreakpoints, 8);
910AssertCompileMemberAlignment(DBGF, bmHardIntBreakpoints, 8);
911/** Pointer to DBGF Data. */
912typedef DBGF *PDBGF;
913
914
915/**
916 * Event state (for DBGFCPU::aEvents).
917 */
918typedef enum DBGFEVENTSTATE
919{
920 /** Invalid event stack entry. */
921 DBGFEVENTSTATE_INVALID = 0,
922 /** The current event stack entry. */
923 DBGFEVENTSTATE_CURRENT,
924 /** Event that should be ignored but hasn't yet actually been ignored. */
925 DBGFEVENTSTATE_IGNORE,
926 /** Event that has been ignored but may be restored to IGNORE should another
927 * debug event fire before the instruction is completed. */
928 DBGFEVENTSTATE_RESTORABLE,
929 /** End of valid events. */
930 DBGFEVENTSTATE_END,
931 /** Make sure we've got a 32-bit type. */
932 DBGFEVENTSTATE_32BIT_HACK = 0x7fffffff
933} DBGFEVENTSTATE;
934
935
936/** Converts a DBGFCPU pointer into a VM pointer. */
937#define DBGFCPU_2_VM(pDbgfCpu) ((PVM)((uint8_t *)(pDbgfCpu) + (pDbgfCpu)->offVM))
938
939/**
940 * The per CPU data for DBGF.
941 */
942typedef struct DBGFCPU
943{
944 /** The offset into the VM structure.
945 * @see DBGFCPU_2_VM(). */
946 uint32_t offVM;
947
948 /** Current active breakpoint (id).
949 * This is ~0U if not active. It is set when a execution engine
950 * encounters a breakpoint and returns VINF_EM_DBG_BREAKPOINT. This is
951 * currently not used for REM breakpoints because of the lazy coupling
952 * between VBox and REM.
953 *
954 * @todo drop this in favor of aEvents! */
955 uint32_t iActiveBp;
956 /** Set if we're singlestepping in raw mode.
957 * This is checked and cleared in the \#DB handler. */
958 bool fSingleSteppingRaw;
959
960 /** Alignment padding. */
961 bool afPadding[3];
962
963 /** The number of events on the stack (aEvents).
964 * The pending event is the last one (aEvents[cEvents - 1]), but only when
965 * enmState is DBGFEVENTSTATE_CURRENT. */
966 uint32_t cEvents;
967 /** Events - current, ignoring and ignored.
968 *
969 * We maintain a stack of events in order to try avoid ending up in an infinit
970 * loop when resuming after an event fired. There are cases where we may end
971 * generating additional events before the instruction can be executed
972 * successfully. Like for instance an XCHG on MMIO with separate read and write
973 * breakpoints, or a MOVSB instruction working on breakpointed MMIO as both
974 * source and destination.
975 *
976 * So, when resuming after dropping into the debugger for an event, we convert
977 * the DBGFEVENTSTATE_CURRENT event into a DBGFEVENTSTATE_IGNORE event, leaving
978 * cEvents unchanged. If the event is reported again, we will ignore it and
979 * tell the reporter to continue executing. The event change to the
980 * DBGFEVENTSTATE_RESTORABLE state.
981 *
982 * Currently, the event reporter has to figure out that it is a nested event and
983 * tell DBGF to restore DBGFEVENTSTATE_RESTORABLE events (and keep
984 * DBGFEVENTSTATE_IGNORE, should they happen out of order for some weird
985 * reason).
986 */
987 struct
988 {
989 /** The event details. */
990 DBGFEVENT Event;
991 /** The RIP at which this happend (for validating ignoring). */
992 uint64_t rip;
993 /** The event state. */
994 DBGFEVENTSTATE enmState;
995 /** Alignment padding. */
996 uint32_t u32Alignment;
997 } aEvents[3];
998} DBGFCPU;
999AssertCompileMemberAlignment(DBGFCPU, aEvents, 8);
1000AssertCompileMemberSizeAlignment(DBGFCPU, aEvents[0], 8);
1001/** Pointer to DBGFCPU data. */
1002typedef DBGFCPU *PDBGFCPU;
1003
1004struct DBGFOSEMTWRAPPER;
1005
1006/**
1007 * DBGF data kept in the ring-0 GVM.
1008 */
1009typedef struct DBGFR0PERVM
1010{
1011 /** Pointer to the tracer instance if enabled. */
1012 R0PTRTYPE(struct DBGFTRACERINSR0 *) pTracerR0;
1013} DBGFR0PERVM;
1014
1015/**
1016 * The DBGF data kept in the UVM.
1017 */
1018typedef struct DBGFUSERPERVM
1019{
1020 /** The address space database lock. */
1021 RTSEMRW hAsDbLock;
1022 /** The address space handle database. (Protected by hAsDbLock.) */
1023 R3PTRTYPE(AVLPVTREE) AsHandleTree;
1024 /** The address space process id database. (Protected by hAsDbLock.) */
1025 R3PTRTYPE(AVLU32TREE) AsPidTree;
1026 /** The address space name database. (Protected by hAsDbLock.) */
1027 R3PTRTYPE(RTSTRSPACE) AsNameSpace;
1028 /** Special address space aliases. (Protected by hAsDbLock.) */
1029 RTDBGAS volatile ahAsAliases[DBGF_AS_COUNT];
1030 /** For lazily populating the aliased address spaces. */
1031 bool volatile afAsAliasPopuplated[DBGF_AS_COUNT];
1032 /** Alignment padding. */
1033 bool afAlignment1[2];
1034 /** Debug configuration. */
1035 R3PTRTYPE(RTDBGCFG) hDbgCfg;
1036
1037 /** The register database lock. */
1038 RTSEMRW hRegDbLock;
1039 /** String space for looking up registers. (Protected by hRegDbLock.) */
1040 R3PTRTYPE(RTSTRSPACE) RegSpace;
1041 /** String space holding the register sets. (Protected by hRegDbLock.) */
1042 R3PTRTYPE(RTSTRSPACE) RegSetSpace;
1043 /** The number of registers (aliases, sub-fields and the special CPU
1044 * register aliases (eg AH) are not counted). */
1045 uint32_t cRegs;
1046 /** For early initialization by . */
1047 bool volatile fRegDbInitialized;
1048 /** Alignment padding. */
1049 bool afAlignment2[3];
1050
1051 /** Critical section protecting the Guest OS Digger data, the info handlers
1052 * and the plugins. These share to give the best possible plugin unload
1053 * race protection. */
1054 RTCRITSECTRW CritSect;
1055 /** Head of the LIFO of loaded DBGF plugins. */
1056 R3PTRTYPE(struct DBGFPLUGIN *) pPlugInHead;
1057 /** The current Guest OS digger. */
1058 R3PTRTYPE(PDBGFOS) pCurOS;
1059 /** The head of the Guest OS digger instances. */
1060 R3PTRTYPE(PDBGFOS) pOSHead;
1061 /** List of registered info handlers. */
1062 R3PTRTYPE(PDBGFINFO) pInfoFirst;
1063
1064 /** The configured tracer. */
1065 PDBGFTRACERINSR3 pTracerR3;
1066
1067 /** The type database lock. */
1068 RTSEMRW hTypeDbLock;
1069 /** String space for looking up types. (Protected by hTypeDbLock.) */
1070 R3PTRTYPE(RTSTRSPACE) TypeSpace;
1071 /** For early initialization by . */
1072 bool volatile fTypeDbInitialized;
1073 /** Alignment padding. */
1074 bool afAlignment3[3];
1075
1076} DBGFUSERPERVM;
1077typedef DBGFUSERPERVM *PDBGFUSERPERVM;
1078typedef DBGFUSERPERVM const *PCDBGFUSERPERVM;
1079
1080/**
1081 * The per-CPU DBGF data kept in the UVM.
1082 */
1083typedef struct DBGFUSERPERVMCPU
1084{
1085 /** The guest register set for this CPU. Can be NULL. */
1086 R3PTRTYPE(struct DBGFREGSET *) pGuestRegSet;
1087 /** The hypervisor register set for this CPU. Can be NULL. */
1088 R3PTRTYPE(struct DBGFREGSET *) pHyperRegSet;
1089} DBGFUSERPERVMCPU;
1090
1091
1092#ifdef IN_RING3
1093int dbgfR3AsInit(PUVM pUVM);
1094void dbgfR3AsTerm(PUVM pUVM);
1095void dbgfR3AsRelocate(PUVM pUVM, RTGCUINTPTR offDelta);
1096int dbgfR3BpInit(PVM pVM);
1097int dbgfR3InfoInit(PUVM pUVM);
1098int dbgfR3InfoTerm(PUVM pUVM);
1099int dbgfR3OSInit(PUVM pUVM);
1100void dbgfR3OSTermPart1(PUVM pUVM);
1101void dbgfR3OSTermPart2(PUVM pUVM);
1102int dbgfR3OSStackUnwindAssist(PUVM pUVM, VMCPUID idCpu, PDBGFSTACKFRAME pFrame, PRTDBGUNWINDSTATE pState,
1103 PCCPUMCTX pInitialCtx, RTDBGAS hAs, uint64_t *puScratch);
1104int dbgfR3RegInit(PUVM pUVM);
1105void dbgfR3RegTerm(PUVM pUVM);
1106int dbgfR3TraceInit(PVM pVM);
1107void dbgfR3TraceRelocate(PVM pVM);
1108void dbgfR3TraceTerm(PVM pVM);
1109DECLHIDDEN(int) dbgfR3TypeInit(PUVM pUVM);
1110DECLHIDDEN(void) dbgfR3TypeTerm(PUVM pUVM);
1111int dbgfR3PlugInInit(PUVM pUVM);
1112void dbgfR3PlugInTerm(PUVM pUVM);
1113int dbgfR3BugCheckInit(PVM pVM);
1114DECLHIDDEN(int) dbgfR3TracerInit(PVM pVM);
1115DECLHIDDEN(void) dbgfR3TracerTerm(PVM pVM);
1116
1117/**
1118 * DBGF disassembler state (substate of DISSTATE).
1119 */
1120typedef struct DBGFDISSTATE
1121{
1122 /** Pointer to the current instruction. */
1123 PCDISOPCODE pCurInstr;
1124 /** Size of the instruction in bytes. */
1125 uint32_t cbInstr;
1126 /** Parameters. */
1127 DISOPPARAM Param1;
1128 DISOPPARAM Param2;
1129 DISOPPARAM Param3;
1130 DISOPPARAM Param4;
1131} DBGFDISSTATE;
1132/** Pointer to a DBGF disassembler state. */
1133typedef DBGFDISSTATE *PDBGFDISSTATE;
1134
1135DECLHIDDEN(int) dbgfR3DisasInstrStateEx(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddr, uint32_t fFlags,
1136 char *pszOutput, uint32_t cbOutput, PDBGFDISSTATE pDisState);
1137
1138#endif /* IN_RING3 */
1139
1140/** @} */
1141
1142#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