VirtualBox

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

Last change on this file since 73016 was 69474, checked in by vboxsync, 7 years ago

*: scm updates - header files should have 'svn:keywords=Id Revision' too (doesn't mean they have to use them).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 16.8 KB
Line 
1/* $Id: DBGFInternal.h 69474 2017-10-28 13:12:06Z vboxsync $ */
2/** @file
3 * DBGF - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2017 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 ___DBGFInternal_h
19#define ___DBGFInternal_h
20
21#include <VBox/cdefs.h>
22#ifdef IN_RING3
23# include <VBox/dis.h>
24#endif
25#include <VBox/types.h>
26#include <iprt/semaphore.h>
27#include <iprt/critsect.h>
28#include <iprt/string.h>
29#include <iprt/avl.h>
30#include <iprt/dbg.h>
31#include <VBox/vmm/dbgf.h>
32
33
34
35/** @defgroup grp_dbgf_int Internals
36 * @ingroup grp_dbgf
37 * @internal
38 * @{
39 */
40
41
42/** VMM Debugger Command. */
43typedef enum DBGFCMD
44{
45 /** No command.
46 * This is assigned to the field by the emulation thread after
47 * a command has been completed. */
48 DBGFCMD_NO_COMMAND = 0,
49 /** Halt the VM. */
50 DBGFCMD_HALT,
51 /** Resume execution. */
52 DBGFCMD_GO,
53 /** Single step execution - stepping into calls. */
54 DBGFCMD_SINGLE_STEP,
55 /** Detaches the debugger.
56 * Disabling all breakpoints, watch points and the like. */
57 DBGFCMD_DETACH_DEBUGGER,
58 /** Detached the debugger.
59 * The isn't a command as such, it's just that it's necessary for the
60 * detaching protocol to be racefree. */
61 DBGFCMD_DETACHED_DEBUGGER
62} DBGFCMD;
63
64/**
65 * VMM Debugger Command.
66 */
67typedef union DBGFCMDDATA
68{
69 uint32_t uDummy;
70} DBGFCMDDATA;
71/** Pointer to DBGF Command Data. */
72typedef DBGFCMDDATA *PDBGFCMDDATA;
73
74/**
75 * Info type.
76 */
77typedef enum DBGFINFOTYPE
78{
79 /** Invalid. */
80 DBGFINFOTYPE_INVALID = 0,
81 /** Device owner. */
82 DBGFINFOTYPE_DEV,
83 /** Driver owner. */
84 DBGFINFOTYPE_DRV,
85 /** Internal owner. */
86 DBGFINFOTYPE_INT,
87 /** External owner. */
88 DBGFINFOTYPE_EXT
89} DBGFINFOTYPE;
90
91
92/** Pointer to info structure. */
93typedef struct DBGFINFO *PDBGFINFO;
94
95#ifdef IN_RING3
96/**
97 * Info structure.
98 */
99typedef struct DBGFINFO
100{
101 /** The flags. */
102 uint32_t fFlags;
103 /** Owner type. */
104 DBGFINFOTYPE enmType;
105 /** Per type data. */
106 union
107 {
108 /** DBGFINFOTYPE_DEV */
109 struct
110 {
111 /** Device info handler function. */
112 PFNDBGFHANDLERDEV pfnHandler;
113 /** The device instance. */
114 PPDMDEVINS pDevIns;
115 } Dev;
116
117 /** DBGFINFOTYPE_DRV */
118 struct
119 {
120 /** Driver info handler function. */
121 PFNDBGFHANDLERDRV pfnHandler;
122 /** The driver instance. */
123 PPDMDRVINS pDrvIns;
124 } Drv;
125
126 /** DBGFINFOTYPE_INT */
127 struct
128 {
129 /** Internal info handler function. */
130 PFNDBGFHANDLERINT pfnHandler;
131 } Int;
132
133 /** DBGFINFOTYPE_EXT */
134 struct
135 {
136 /** External info handler function. */
137 PFNDBGFHANDLEREXT pfnHandler;
138 /** The user argument. */
139 void *pvUser;
140 } Ext;
141 } u;
142
143 /** Pointer to the description. */
144 const char *pszDesc;
145 /** Pointer to the next info structure. */
146 PDBGFINFO pNext;
147 /** The identifier name length. */
148 size_t cchName;
149 /** The identifier name. (Extends 'beyond' the struct as usual.) */
150 char szName[1];
151} DBGFINFO;
152#endif /* IN_RING3 */
153
154
155/**
156 * Guest OS digger instance.
157 */
158typedef struct DBGFOS
159{
160 /** Pointer to the registration record. */
161 PCDBGFOSREG pReg;
162 /** Pointer to the next OS we've registered. */
163 struct DBGFOS *pNext;
164 /** List of EMT interface wrappers. */
165 struct DBGFOSEMTWRAPPER *pWrapperHead;
166 /** The instance data (variable size). */
167 uint8_t abData[16];
168} DBGFOS;
169/** Pointer to guest OS digger instance. */
170typedef DBGFOS *PDBGFOS;
171/** Pointer to const guest OS digger instance. */
172typedef DBGFOS const *PCDBGFOS;
173
174
175/**
176 * Breakpoint search optimization.
177 */
178typedef struct DBGFBPSEARCHOPT
179{
180 /** Where to start searching for hits.
181 * (First enabled is #DBGF::aBreakpoints[iStartSearch]). */
182 uint32_t volatile iStartSearch;
183 /** The number of aBreakpoints entries to search.
184 * (Last enabled is #DBGF::aBreakpoints[iStartSearch + cToSearch - 1]) */
185 uint32_t volatile cToSearch;
186} DBGFBPSEARCHOPT;
187/** Pointer to a breakpoint search optimziation structure. */
188typedef DBGFBPSEARCHOPT *PDBGFBPSEARCHOPT;
189
190
191
192/**
193 * DBGF Data (part of VM)
194 */
195typedef struct DBGF
196{
197 /** Bitmap of enabled hardware interrupt breakpoints. */
198 uint32_t bmHardIntBreakpoints[256 / 32];
199 /** Bitmap of enabled software interrupt breakpoints. */
200 uint32_t bmSoftIntBreakpoints[256 / 32];
201 /** Bitmap of selected events.
202 * This includes non-selectable events too for simplicity, we maintain the
203 * state for some of these, as it may come in handy. */
204 uint64_t bmSelectedEvents[(DBGFEVENT_END + 63) / 64];
205
206 /** Enabled hardware interrupt breakpoints. */
207 uint32_t cHardIntBreakpoints;
208 /** Enabled software interrupt breakpoints. */
209 uint32_t cSoftIntBreakpoints;
210
211 /** The number of selected events. */
212 uint32_t cSelectedEvents;
213
214 /** The number of enabled hardware breakpoints. */
215 uint8_t cEnabledHwBreakpoints;
216 /** The number of enabled hardware I/O breakpoints. */
217 uint8_t cEnabledHwIoBreakpoints;
218 /** The number of enabled INT3 breakpoints. */
219 uint8_t cEnabledInt3Breakpoints;
220 uint8_t abPadding; /**< Unused padding space up for grabs. */
221 uint32_t uPadding;
222
223 /** Debugger Attached flag.
224 * Set if a debugger is attached, elsewise it's clear.
225 */
226 bool volatile fAttached;
227
228 /** Stopped in the Hypervisor.
229 * Set if we're stopped on a trace, breakpoint or assertion inside
230 * the hypervisor and have to restrict the available operations.
231 */
232 bool volatile fStoppedInHyper;
233
234 /**
235 * Ping-Pong construct where the Ping side is the VMM and the Pong side
236 * the Debugger.
237 */
238 RTPINGPONG PingPong;
239 RTHCUINTPTR uPtrPadding; /**< Alignment padding. */
240
241 /** The Event to the debugger.
242 * The VMM will ping the debugger when the event is ready. The event is
243 * either a response to a command or to a break/watch point issued
244 * previously.
245 */
246 DBGFEVENT DbgEvent;
247
248 /** The Command to the VMM.
249 * Operated in an atomic fashion since the VMM will poll on this.
250 * This means that a the command data must be written before this member
251 * is set. The VMM will reset this member to the no-command state
252 * when it have processed it.
253 */
254 DBGFCMD volatile enmVMMCmd;
255 /** The Command data.
256 * Not all commands take data. */
257 DBGFCMDDATA VMMCmdData;
258
259 /** Stepping filtering. */
260 struct
261 {
262 /** The CPU doing the stepping.
263 * Set to NIL_VMCPUID when filtering is inactive */
264 VMCPUID idCpu;
265 /** The specified flags. */
266 uint32_t fFlags;
267 /** The effective PC address to stop at, if given. */
268 RTGCPTR AddrPc;
269 /** The lowest effective stack address to stop at.
270 * Together with cbStackPop, this forms a range of effective stack pointer
271 * addresses that we stop for. */
272 RTGCPTR AddrStackPop;
273 /** The size of the stack stop area starting at AddrStackPop. */
274 RTGCPTR cbStackPop;
275 /** Maximum number of steps. */
276 uint32_t cMaxSteps;
277
278 /** Number of steps made thus far. */
279 uint32_t cSteps;
280 /** Current call counting balance for step-over handling. */
281 uint32_t uCallDepth;
282
283 uint32_t u32Padding; /**< Alignment padding. */
284
285 } SteppingFilter;
286
287 uint32_t u32Padding[2]; /**< Alignment padding. */
288
289 /** Array of hardware breakpoints. (0..3)
290 * This is shared among all the CPUs because life is much simpler that way. */
291 DBGFBP aHwBreakpoints[4];
292 /** Array of int 3 and REM breakpoints. (4..)
293 * @remark This is currently a fixed size array for reasons of simplicity. */
294 DBGFBP aBreakpoints[32];
295
296 /** MMIO breakpoint search optimizations. */
297 DBGFBPSEARCHOPT Mmio;
298 /** I/O port breakpoint search optimizations. */
299 DBGFBPSEARCHOPT PortIo;
300 /** INT3 breakpoint search optimizations. */
301 DBGFBPSEARCHOPT Int3;
302} DBGF;
303AssertCompileMemberAlignment(DBGF, DbgEvent, 8);
304AssertCompileMemberAlignment(DBGF, aHwBreakpoints, 8);
305AssertCompileMemberAlignment(DBGF, bmHardIntBreakpoints, 8);
306/** Pointer to DBGF Data. */
307typedef DBGF *PDBGF;
308
309
310/**
311 * Event state (for DBGFCPU::aEvents).
312 */
313typedef enum DBGFEVENTSTATE
314{
315 /** Invalid event stack entry. */
316 DBGFEVENTSTATE_INVALID = 0,
317 /** The current event stack entry. */
318 DBGFEVENTSTATE_CURRENT,
319 /** Event that should be ignored but hasn't yet actually been ignored. */
320 DBGFEVENTSTATE_IGNORE,
321 /** Event that has been ignored but may be restored to IGNORE should another
322 * debug event fire before the instruction is completed. */
323 DBGFEVENTSTATE_RESTORABLE,
324 /** End of valid events. */
325 DBGFEVENTSTATE_END,
326 /** Make sure we've got a 32-bit type. */
327 DBGFEVENTSTATE_32BIT_HACK = 0x7fffffff
328} DBGFEVENTSTATE;
329
330
331/** Converts a DBGFCPU pointer into a VM pointer. */
332#define DBGFCPU_2_VM(pDbgfCpu) ((PVM)((uint8_t *)(pDbgfCpu) + (pDbgfCpu)->offVM))
333
334/**
335 * The per CPU data for DBGF.
336 */
337typedef struct DBGFCPU
338{
339 /** The offset into the VM structure.
340 * @see DBGFCPU_2_VM(). */
341 uint32_t offVM;
342
343 /** Current active breakpoint (id).
344 * This is ~0U if not active. It is set when a execution engine
345 * encounters a breakpoint and returns VINF_EM_DBG_BREAKPOINT. This is
346 * currently not used for REM breakpoints because of the lazy coupling
347 * between VBox and REM.
348 *
349 * @todo drop this in favor of aEvents! */
350 uint32_t iActiveBp;
351 /** Set if we're singlestepping in raw mode.
352 * This is checked and cleared in the \#DB handler. */
353 bool fSingleSteppingRaw;
354
355 /** Alignment padding. */
356 bool afPadding[3];
357
358 /** The number of events on the stack (aEvents).
359 * The pending event is the last one (aEvents[cEvents - 1]), but only when
360 * enmState is DBGFEVENTSTATE_CURRENT. */
361 uint32_t cEvents;
362 /** Events - current, ignoring and ignored.
363 *
364 * We maintain a stack of events in order to try avoid ending up in an infinit
365 * loop when resuming after an event fired. There are cases where we may end
366 * generating additional events before the instruction can be executed
367 * successfully. Like for instance an XCHG on MMIO with separate read and write
368 * breakpoints, or a MOVSB instruction working on breakpointed MMIO as both
369 * source and destination.
370 *
371 * So, when resuming after dropping into the debugger for an event, we convert
372 * the DBGFEVENTSTATE_CURRENT event into a DBGFEVENTSTATE_IGNORE event, leaving
373 * cEvents unchanged. If the event is reported again, we will ignore it and
374 * tell the reporter to continue executing. The event change to the
375 * DBGFEVENTSTATE_RESTORABLE state.
376 *
377 * Currently, the event reporter has to figure out that it is a nested event and
378 * tell DBGF to restore DBGFEVENTSTATE_RESTORABLE events (and keep
379 * DBGFEVENTSTATE_IGNORE, should they happen out of order for some weird
380 * reason).
381 */
382 struct
383 {
384 /** The event details. */
385 DBGFEVENT Event;
386 /** The RIP at which this happend (for validating ignoring). */
387 uint64_t rip;
388 /** The event state. */
389 DBGFEVENTSTATE enmState;
390 /** Alignment padding. */
391 uint32_t u32Alignment;
392 } aEvents[3];
393} DBGFCPU;
394AssertCompileMemberAlignment(DBGFCPU, aEvents, 8);
395AssertCompileMemberSizeAlignment(DBGFCPU, aEvents[0], 8);
396/** Pointer to DBGFCPU data. */
397typedef DBGFCPU *PDBGFCPU;
398
399struct DBGFOSEMTWRAPPER;
400
401/**
402 * The DBGF data kept in the UVM.
403 */
404typedef struct DBGFUSERPERVM
405{
406 /** The address space database lock. */
407 RTSEMRW hAsDbLock;
408 /** The address space handle database. (Protected by hAsDbLock.) */
409 R3PTRTYPE(AVLPVTREE) AsHandleTree;
410 /** The address space process id database. (Protected by hAsDbLock.) */
411 R3PTRTYPE(AVLU32TREE) AsPidTree;
412 /** The address space name database. (Protected by hAsDbLock.) */
413 R3PTRTYPE(RTSTRSPACE) AsNameSpace;
414 /** Special address space aliases. (Protected by hAsDbLock.) */
415 RTDBGAS volatile ahAsAliases[DBGF_AS_COUNT];
416 /** For lazily populating the aliased address spaces. */
417 bool volatile afAsAliasPopuplated[DBGF_AS_COUNT];
418 /** Alignment padding. */
419 bool afAlignment1[2];
420 /** Debug configuration. */
421 R3PTRTYPE(RTDBGCFG) hDbgCfg;
422
423 /** The register database lock. */
424 RTSEMRW hRegDbLock;
425 /** String space for looking up registers. (Protected by hRegDbLock.) */
426 R3PTRTYPE(RTSTRSPACE) RegSpace;
427 /** String space holding the register sets. (Protected by hRegDbLock.) */
428 R3PTRTYPE(RTSTRSPACE) RegSetSpace;
429 /** The number of registers (aliases, sub-fields and the special CPU
430 * register aliases (eg AH) are not counted). */
431 uint32_t cRegs;
432 /** For early initialization by . */
433 bool volatile fRegDbInitialized;
434 /** Alignment padding. */
435 bool afAlignment2[3];
436
437 /** Critical section protecting the Guest OS Digger data, the info handlers
438 * and the plugins. These share to give the best possible plugin unload
439 * race protection. */
440 RTCRITSECTRW CritSect;
441 /** Head of the LIFO of loaded DBGF plugins. */
442 R3PTRTYPE(struct DBGFPLUGIN *) pPlugInHead;
443 /** The current Guest OS digger. */
444 R3PTRTYPE(PDBGFOS) pCurOS;
445 /** The head of the Guest OS digger instances. */
446 R3PTRTYPE(PDBGFOS) pOSHead;
447 /** List of registered info handlers. */
448 R3PTRTYPE(PDBGFINFO) pInfoFirst;
449
450 /** The type database lock. */
451 RTSEMRW hTypeDbLock;
452 /** String space for looking up types. (Protected by hTypeDbLock.) */
453 R3PTRTYPE(RTSTRSPACE) TypeSpace;
454 /** For early initialization by . */
455 bool volatile fTypeDbInitialized;
456 /** Alignment padding. */
457 bool afAlignment3[3];
458
459} DBGFUSERPERVM;
460typedef DBGFUSERPERVM *PDBGFUSERPERVM;
461typedef DBGFUSERPERVM const *PCDBGFUSERPERVM;
462
463/**
464 * The per-CPU DBGF data kept in the UVM.
465 */
466typedef struct DBGFUSERPERVMCPU
467{
468 /** The guest register set for this CPU. Can be NULL. */
469 R3PTRTYPE(struct DBGFREGSET *) pGuestRegSet;
470 /** The hypervisor register set for this CPU. Can be NULL. */
471 R3PTRTYPE(struct DBGFREGSET *) pHyperRegSet;
472} DBGFUSERPERVMCPU;
473
474
475int dbgfR3AsInit(PUVM pUVM);
476void dbgfR3AsTerm(PUVM pUVM);
477void dbgfR3AsRelocate(PUVM pUVM, RTGCUINTPTR offDelta);
478int dbgfR3BpInit(PVM pVM);
479int dbgfR3InfoInit(PUVM pUVM);
480int dbgfR3InfoTerm(PUVM pUVM);
481int dbgfR3OSInit(PUVM pUVM);
482void dbgfR3OSTerm(PUVM pUVM);
483int dbgfR3RegInit(PUVM pUVM);
484void dbgfR3RegTerm(PUVM pUVM);
485int dbgfR3TraceInit(PVM pVM);
486void dbgfR3TraceRelocate(PVM pVM);
487void dbgfR3TraceTerm(PVM pVM);
488DECLHIDDEN(int) dbgfR3TypeInit(PUVM pUVM);
489DECLHIDDEN(void) dbgfR3TypeTerm(PUVM pUVM);
490int dbgfR3PlugInInit(PUVM pUVM);
491void dbgfR3PlugInTerm(PUVM pUVM);
492
493
494
495#ifdef IN_RING3
496/**
497 * DBGF disassembler state (substate of DISSTATE).
498 */
499typedef struct DBGFDISSTATE
500{
501 /** Pointer to the current instruction. */
502 PCDISOPCODE pCurInstr;
503 /** Size of the instruction in bytes. */
504 uint32_t cbInstr;
505 /** Parameters. */
506 DISOPPARAM Param1;
507 DISOPPARAM Param2;
508 DISOPPARAM Param3;
509 DISOPPARAM Param4;
510} DBGFDISSTATE;
511/** Pointer to a DBGF disassembler state. */
512typedef DBGFDISSTATE *PDBGFDISSTATE;
513
514DECLHIDDEN(int) dbgfR3DisasInstrStateEx(PUVM pUVM, VMCPUID idCpu, PDBGFADDRESS pAddr, uint32_t fFlags,
515 char *pszOutput, uint32_t cbOutput, PDBGFDISSTATE pDisState);
516
517#endif
518
519/** @} */
520
521#endif
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