VirtualBox

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

Last change on this file since 58944 was 58910, checked in by vboxsync, 9 years ago

DBGF: alignment fix.

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