VirtualBox

source: vbox/trunk/include/VBox/dbg.h@ 41786

Last change on this file since 41786 was 41573, checked in by vboxsync, 13 years ago

DBGC: Working on making STRING the inflexible type and SYMBOL the flexible one.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 39.2 KB
Line 
1/** @file
2 * Debugger Interfaces. (VBoxDbg)
3 *
4 * This header covers all external interfaces of the Debugger module.
5 * However, it does not cover the DBGF interface since that part of the
6 * VMM. Use dbgf.h for that.
7 */
8
9/*
10 * Copyright (C) 2006-2007 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * The contents of this file may alternatively be used under the terms
21 * of the Common Development and Distribution License Version 1.0
22 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23 * VirtualBox OSE distribution, in which case the provisions of the
24 * CDDL are applicable instead of those of the GPL.
25 *
26 * You may elect to license modified versions of this file under the
27 * terms and conditions of either the GPL or the CDDL or both.
28 */
29
30#ifndef ___VBox_dbg_h
31#define ___VBox_dbg_h
32
33#include <VBox/cdefs.h>
34#include <VBox/types.h>
35#include <VBox/vmm/dbgf.h>
36
37#include <iprt/stdarg.h>
38#ifdef IN_RING3
39# include <iprt/err.h>
40#endif
41
42RT_C_DECLS_BEGIN
43
44#ifdef IN_RING3 /* The debugger stuff is ring-3 only. */
45
46/** @def VBOX_WITH_DEBUGGER
47 * The build is with debugger module. Test if this is defined before registering
48 * external debugger commands. This is normally defined in Config.kmk.
49 */
50#ifdef DOXYGEN_RUNNING
51# define VBOX_WITH_DEBUGGER
52#endif
53
54
55/**
56 * DBGC variable category.
57 *
58 * Used to describe an argument to a command or function and a functions
59 * return value.
60 */
61typedef enum DBGCVARCAT
62{
63 /** Any type is fine. */
64 DBGCVAR_CAT_ANY = 0,
65 /** Any kind of pointer or number. */
66 DBGCVAR_CAT_POINTER_NUMBER,
67 /** Any kind of pointer or number, no range. */
68 DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE,
69 /** Any kind of pointer. */
70 DBGCVAR_CAT_POINTER,
71 /** Any kind of pointer with no range option. */
72 DBGCVAR_CAT_POINTER_NO_RANGE,
73 /** GC pointer. */
74 DBGCVAR_CAT_GC_POINTER,
75 /** GC pointer with no range option. */
76 DBGCVAR_CAT_GC_POINTER_NO_RANGE,
77 /** Numeric argument. */
78 DBGCVAR_CAT_NUMBER,
79 /** Numeric argument with no range option. */
80 DBGCVAR_CAT_NUMBER_NO_RANGE,
81 /** String. */
82 DBGCVAR_CAT_STRING,
83 /** Symbol. */
84 DBGCVAR_CAT_SYMBOL,
85 /** Option. */
86 DBGCVAR_CAT_OPTION,
87 /** Option + string. */
88 DBGCVAR_CAT_OPTION_STRING,
89 /** Option + number. */
90 DBGCVAR_CAT_OPTION_NUMBER
91} DBGCVARCAT;
92
93
94/**
95 * DBGC variable type.
96 */
97typedef enum DBGCVARTYPE
98{
99 /** unknown... */
100 DBGCVAR_TYPE_UNKNOWN = 0,
101 /** Flat GC pointer. */
102 DBGCVAR_TYPE_GC_FLAT,
103 /** Segmented GC pointer. */
104 DBGCVAR_TYPE_GC_FAR,
105 /** Physical GC pointer. */
106 DBGCVAR_TYPE_GC_PHYS,
107 /** Flat HC pointer. */
108 DBGCVAR_TYPE_HC_FLAT,
109 /** Physical HC pointer. */
110 DBGCVAR_TYPE_HC_PHYS,
111 /** Number. */
112 DBGCVAR_TYPE_NUMBER,
113 /** String. */
114 DBGCVAR_TYPE_STRING,
115 /** Symbol. */
116 DBGCVAR_TYPE_SYMBOL,
117 /** Special type used when querying symbols. */
118 DBGCVAR_TYPE_ANY
119} DBGCVARTYPE;
120
121/** @todo Rename to DBGCVAR_IS_xyz. */
122
123/** Checks if the specified variable type is of a pointer persuasion. */
124#define DBGCVAR_ISPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_GC_FLAT && enmType <= DBGCVAR_TYPE_HC_PHYS)
125/** Checks if the specified variable type is of a pointer persuasion. */
126#define DBGCVAR_IS_FAR_PTR(enmType) ((enmType) == DBGCVAR_TYPE_GC_FAR)
127/** Checks if the specified variable type is of a pointer persuasion and of the guest context sort. */
128#define DBGCVAR_ISGCPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_GC_FLAT && (enmType) <= DBGCVAR_TYPE_GC_PHYS)
129/** Checks if the specified variable type is of a pointer persuasion and of the host context sort. */
130#define DBGCVAR_ISHCPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_HC_FLAT && (enmType) <= DBGCVAR_TYPE_HC_PHYS)
131
132
133/**
134 * DBGC variable range type.
135 */
136typedef enum DBGCVARRANGETYPE
137{
138 /** No range appliable or no range specified. */
139 DBGCVAR_RANGE_NONE = 0,
140 /** Number of elements. */
141 DBGCVAR_RANGE_ELEMENTS,
142 /** Number of bytes. */
143 DBGCVAR_RANGE_BYTES
144} DBGCVARRANGETYPE;
145
146
147/**
148 * Variable descriptor.
149 */
150typedef struct DBGCVARDESC
151{
152 /** The minimal number of times this argument may occur.
153 * Use 0 here to inidicate that the argument is optional. */
154 unsigned cTimesMin;
155 /** Maximum number of occurrences.
156 * Use ~0 here to indicate infinite. */
157 unsigned cTimesMax;
158 /** Argument category. */
159 DBGCVARCAT enmCategory;
160 /** Flags, DBGCVD_FLAGS_* */
161 unsigned fFlags;
162 /** Argument name. */
163 const char *pszName;
164 /** Argument name. */
165 const char *pszDescription;
166} DBGCVARDESC;
167/** Pointer to an argument descriptor. */
168typedef DBGCVARDESC *PDBGCVARDESC;
169/** Pointer to a const argument descriptor. */
170typedef const DBGCVARDESC *PCDBGCVARDESC;
171
172/** Variable descriptor flags.
173 * @{ */
174/** Indicates that the variable depends on the previous being present. */
175#define DBGCVD_FLAGS_DEP_PREV RT_BIT(1)
176/** @} */
177
178
179/**
180 * DBGC variable.
181 */
182typedef struct DBGCVAR
183{
184 /** Pointer to the argument descriptor. */
185 PCDBGCVARDESC pDesc;
186 /** Pointer to the next argument. */
187 struct DBGCVAR *pNext;
188
189 /** Argument type. */
190 DBGCVARTYPE enmType;
191 /** Type specific. */
192 union
193 {
194 /** Flat GC Address. (DBGCVAR_TYPE_GC_FLAT) */
195 RTGCPTR GCFlat;
196 /** Far (16:32) GC Address. (DBGCVAR_TYPE_GC_FAR) */
197 RTFAR32 GCFar;
198 /** Physical GC Address. (DBGCVAR_TYPE_GC_PHYS) */
199 RTGCPHYS GCPhys;
200 /** Flat HC Address. (DBGCVAR_TYPE_HC_FLAT) */
201 void *pvHCFlat;
202 /** Physical GC Address. (DBGCVAR_TYPE_HC_PHYS) */
203 RTHCPHYS HCPhys;
204 /** String. (DBGCVAR_TYPE_STRING)
205 * The basic idea is the the this is a pointer to the expression we're
206 * parsing, so no messing with freeing. */
207 const char *pszString;
208 /** Number. (DBGCVAR_TYPE_NUMBER) */
209 uint64_t u64Number;
210 } u;
211
212 /** Range type. */
213 DBGCVARRANGETYPE enmRangeType;
214 /** Range. The use of the content depends on the enmRangeType. */
215 uint64_t u64Range;
216} DBGCVAR;
217/** Pointer to a command argument. */
218typedef DBGCVAR *PDBGCVAR;
219/** Pointer to a const command argument. */
220typedef const DBGCVAR *PCDBGCVAR;
221
222
223/**
224 * Macro for initializing a DBGC variable with defaults.
225 * The result is an unknown variable type without any range.
226 */
227#define DBGCVAR_INIT(pVar) \
228 do { \
229 (pVar)->pDesc = NULL;\
230 (pVar)->pNext = NULL; \
231 (pVar)->enmType = DBGCVAR_TYPE_UNKNOWN; \
232 (pVar)->u.u64Number = 0; \
233 (pVar)->enmRangeType = DBGCVAR_RANGE_NONE; \
234 (pVar)->u64Range = 0; \
235 } while (0)
236
237/**
238 * Macro for initializing a DBGC variable with a HC physical address.
239 */
240#define DBGCVAR_INIT_HC_PHYS(pVar, Phys) \
241 do { \
242 DBGCVAR_INIT(pVar); \
243 (pVar)->enmType = DBGCVAR_TYPE_HC_PHYS; \
244 (pVar)->u.HCPhys = (Phys); \
245 } while (0)
246
247/**
248 * Macro for initializing a DBGC variable with a HC flat address.
249 */
250#define DBGCVAR_INIT_HC_FLAT(pVar, Flat) \
251 do { \
252 DBGCVAR_INIT(pVar); \
253 (pVar)->enmType = DBGCVAR_TYPE_HC_FLAT; \
254 (pVar)->u.pvHCFlat = (Flat); \
255 } while (0)
256
257/**
258 * Macro for initializing a DBGC variable with a GC physical address.
259 */
260#define DBGCVAR_INIT_GC_PHYS(pVar, Phys) \
261 do { \
262 DBGCVAR_INIT(pVar); \
263 (pVar)->enmType = DBGCVAR_TYPE_GC_PHYS; \
264 (pVar)->u.GCPhys = (Phys); \
265 } while (0)
266
267/**
268 * Macro for initializing a DBGC variable with a GC flat address.
269 */
270#define DBGCVAR_INIT_GC_FLAT(pVar, Flat) \
271 do { \
272 DBGCVAR_INIT(pVar); \
273 (pVar)->enmType = DBGCVAR_TYPE_GC_FLAT; \
274 (pVar)->u.GCFlat = (Flat); \
275 } while (0)
276
277/**
278 * Macro for initializing a DBGC variable with a GC flat address.
279 */
280#define DBGCVAR_INIT_GC_FLAT_BYTE_RANGE(pVar, Flat, cbRange) \
281 do { \
282 DBGCVAR_INIT(pVar); \
283 (pVar)->enmType = DBGCVAR_TYPE_GC_FLAT; \
284 (pVar)->u.GCFlat = (Flat); \
285 DBGCVAR_SET_RANGE(pVar, DBGCVAR_RANGE_BYTES, cbRange); \
286 } while (0)
287
288/**
289 * Macro for initializing a DBGC variable with a GC far address.
290 */
291#define DBGCVAR_INIT_GC_FAR(pVar, _sel, _off) \
292 do { \
293 DBGCVAR_INIT(pVar); \
294 (pVar)->enmType = DBGCVAR_TYPE_GC_FAR; \
295 (pVar)->u.GCFar.sel = (_sel); \
296 (pVar)->u.GCFar.off = (_off); \
297 } while (0)
298
299/**
300 * Macro for initializing a DBGC variable with a number.
301 */
302#define DBGCVAR_INIT_NUMBER(pVar, Value) \
303 do { \
304 DBGCVAR_INIT(pVar); \
305 (pVar)->enmType = DBGCVAR_TYPE_NUMBER; \
306 (pVar)->u.u64Number = (Value); \
307 } while (0)
308
309/**
310 * Macro for initializing a DBGC variable with a string.
311 */
312#define DBGCVAR_INIT_STRING(pVar, a_pszString) \
313 do { \
314 DBGCVAR_INIT(pVar); \
315 (pVar)->enmType = DBGCVAR_TYPE_STRING; \
316 (pVar)->enmRangeType = DBGCVAR_RANGE_BYTES; \
317 (pVar)->u.pszString = (a_pszString); \
318 (pVar)->u64Range = strlen(a_pszString); \
319 } while (0)
320
321
322/**
323 * Macro for initializing a DBGC variable with a symbol.
324 */
325#define DBGCVAR_INIT_SYMBOL(pVar, a_pszSymbol) \
326 do { \
327 DBGCVAR_INIT(pVar); \
328 (pVar)->enmType = DBGCVAR_TYPE_SYMBOL; \
329 (pVar)->enmRangeType = DBGCVAR_RANGE_BYTES; \
330 (pVar)->u.pszString = (a_pszSymbol); \
331 (pVar)->u64Range = strlen(a_pszSymbol); \
332 } while (0)
333
334
335/**
336 * Macro for setting the range of a DBGC variable.
337 * @param pVar The variable.
338 * @param _enmRangeType The range type.
339 * @param Value The range length value.
340 */
341#define DBGCVAR_SET_RANGE(pVar, _enmRangeType, Value) \
342 do { \
343 (pVar)->enmRangeType = (_enmRangeType); \
344 (pVar)->u64Range = (Value); \
345 } while (0)
346
347
348/**
349 * Macro for setting the range of a DBGC variable.
350 * @param a_pVar The variable.
351 * @param a_cbRange The range, in bytes.
352 */
353#define DBGCVAR_SET_BYTE_RANGE(a_pVar, a_cbRange) \
354 DBGCVAR_SET_RANGE(a_pVar, DBGCVAR_RANGE_BYTES, a_cbRange)
355
356
357/**
358 * Macro for resetting the range a DBGC variable.
359 * @param a_pVar The variable.
360 */
361#define DBGCVAR_ZAP_RANGE(a_pVar) \
362 do { \
363 (a_pVar)->enmRangeType = DBGCVAR_RANGE_NONE; \
364 (a_pVar)->u64Range = 0; \
365 } while (0)
366
367
368/**
369 * Macro for assigning one DBGC variable to another.
370 * @param a_pResult The result (target) variable.
371 * @param a_pVar The source variable.
372 */
373#define DBGCVAR_ASSIGN(a_pResult, a_pVar) \
374 do { \
375 *(a_pResult) = *(a_pVar); \
376 } while (0)
377
378
379/** Pointer to a command descriptor. */
380typedef struct DBGCCMD *PDBGCCMD;
381/** Pointer to a const command descriptor. */
382typedef const struct DBGCCMD *PCDBGCCMD;
383
384/** Pointer to a function descriptor. */
385typedef struct DBGCFUNC *PDBGCFUNC;
386/** Pointer to a const function descriptor. */
387typedef const struct DBGCFUNC *PCDBGCFUNC;
388
389/** Pointer to helper functions for commands. */
390typedef struct DBGCCMDHLP *PDBGCCMDHLP;
391
392
393/**
394 * Helper functions for commands.
395 */
396typedef struct DBGCCMDHLP
397{
398 /** Magic value (DBGCCMDHLP_MAGIC). */
399 uint32_t u32Magic;
400
401 /**
402 * Command helper for writing formatted text to the debug console.
403 *
404 * @returns VBox status.
405 * @param pCmdHlp Pointer to the command callback structure.
406 * @param pcb Where to store the number of bytes written.
407 * @param pszFormat The format string. This may use all IPRT extensions as
408 * well as the debugger ones.
409 * @param ... Arguments specified in the format string.
410 */
411 DECLCALLBACKMEMBER(int, pfnPrintf)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, ...);
412
413 /**
414 * Command helper for writing formatted text to the debug console.
415 *
416 * @returns VBox status.
417 * @param pCmdHlp Pointer to the command callback structure.
418 * @param pcb Where to store the number of bytes written.
419 * @param pszFormat The format string. This may use all IPRT extensions as
420 * well as the debugger ones.
421 * @param args Arguments specified in the format string.
422 */
423 DECLCALLBACKMEMBER(int, pfnPrintfV)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args);
424
425 /**
426 * Command helper for formatting a string with debugger format specifiers.
427 *
428 * @returns The number of bytes written.
429 * @param pCmdHlp Pointer to the command callback structure.
430 * @param pszBuf The output buffer.
431 * @param cbBuf The size of the output buffer.
432 * @param pszFormat The format string. This may use all IPRT extensions as
433 * well as the debugger ones.
434 * @param ... Arguments specified in the format string.
435 */
436 DECLCALLBACKMEMBER(size_t, pfnStrPrintf)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
437
438 /**
439 * Command helper for formatting a string with debugger format specifiers.
440 *
441 * @returns The number of bytes written.
442 * @param pCmdHlp Pointer to the command callback structure.
443 * @param pszBuf The output buffer.
444 * @param cbBuf The size of the output buffer.
445 * @param pszFormat The format string. This may use all IPRT extensions as
446 * well as the debugger ones.
447 * @param va Arguments specified in the format string.
448 */
449 DECLCALLBACKMEMBER(size_t, pfnStrPrintfV)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf,
450 const char *pszFormat, va_list va);
451
452 /**
453 * Command helper for formatting and error message for a VBox status code.
454 *
455 * @returns VBox status code appropriate to return from a command.
456 * @param pCmdHlp Pointer to the command callback structure.
457 * @param rc The VBox status code.
458 * @param pszFormat Format string for additional messages. Can be NULL.
459 * @param ... Format arguments, optional.
460 */
461 DECLCALLBACKMEMBER(int, pfnVBoxError)(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...);
462
463 /**
464 * Command helper for formatting and error message for a VBox status code.
465 *
466 * @returns VBox status code appropriate to return from a command.
467 * @param pCmdHlp Pointer to the command callback structure.
468 * @param rc The VBox status code.
469 * @param pcb Where to store the number of bytes written.
470 * @param pszFormat Format string for additional messages. Can be NULL.
471 * @param args Format arguments, optional.
472 */
473 DECLCALLBACKMEMBER(int, pfnVBoxErrorV)(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, va_list args);
474
475 /**
476 * Command helper for reading memory specified by a DBGC variable.
477 *
478 * @returns VBox status code appropriate to return from a command.
479 * @param pCmdHlp Pointer to the command callback structure.
480 * @param pVM VM handle if GC or physical HC address.
481 * @param pvBuffer Where to store the read data.
482 * @param cbRead Number of bytes to read.
483 * @param pVarPointer DBGC variable specifying where to start reading.
484 * @param pcbRead Where to store the number of bytes actually read.
485 * This optional, but it's useful when read GC virtual memory where a
486 * page in the requested range might not be present.
487 * If not specified not-present failure or end of a HC physical page
488 * will cause failure.
489 */
490 DECLCALLBACKMEMBER(int, pfnMemRead)(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead);
491
492 /**
493 * Command helper for writing memory specified by a DBGC variable.
494 *
495 * @returns VBox status code appropriate to return from a command.
496 * @param pCmdHlp Pointer to the command callback structure.
497 * @param pVM VM handle if GC or physical HC address.
498 * @param pvBuffer What to write.
499 * @param cbWrite Number of bytes to write.
500 * @param pVarPointer DBGC variable specifying where to start reading.
501 * @param pcbWritten Where to store the number of bytes written.
502 * This is optional. If NULL be aware that some of the buffer
503 * might have been written to the specified address.
504 */
505 DECLCALLBACKMEMBER(int, pfnMemWrite)(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten);
506
507 /**
508 * Executes command an expression.
509 * (Hopefully the parser and functions are fully reentrant.)
510 *
511 * @returns VBox status code appropriate to return from a command.
512 * @param pCmdHlp Pointer to the command callback structure.
513 * @param pszExpr The expression. Format string with the format DBGC extensions.
514 * @param ... Format arguments.
515 */
516 DECLCALLBACKMEMBER(int, pfnExec)(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...);
517
518 /**
519 * Evaluates an expression.
520 * (Hopefully the parser and functions are fully reentrant.)
521 *
522 * @returns VBox status code appropriate to return from a command.
523 * @param pCmdHlp Pointer to the command callback structure.
524 * @param pResult Where to store the result.
525 * @param pszExpr The expression. Format string with the format DBGC extensions.
526 * @param va Format arguments.
527 */
528 DECLCALLBACKMEMBER(int, pfnEvalV)(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, va_list va);
529
530 /**
531 * Print an error and fail the current command.
532 *
533 * @returns VBox status code to pass upwards.
534 *
535 * @param pCmdHlp Pointer to the command callback structure.
536 * @param pCmd The failing command.
537 * @param pszFormat The error message format string.
538 * @param va Format arguments.
539 */
540 DECLCALLBACKMEMBER(int, pfnFailV)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, va_list va);
541
542 /**
543 * Print an error and fail the current command.
544 *
545 * @returns VBox status code to pass upwards.
546 *
547 * @param pCmdHlp Pointer to the command callback structure.
548 * @param pCmd The failing command.
549 * @param rc The status code indicating the failure. This will
550 * be appended to the message after a colon (': ').
551 * @param pszFormat The error message format string.
552 * @param va Format arguments.
553 *
554 * @see DBGCCmdHlpFailRc
555 */
556 DECLCALLBACKMEMBER(int, pfnFailRcV)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int rc, const char *pszFormat, va_list va);
557
558 /**
559 * Parser error.
560 *
561 * @returns VBox status code to pass upwards.
562 *
563 * @param pCmdHlp Pointer to the command callback structure.
564 * @param pCmd The failing command, can be NULL but shouldn't.
565 * @param iArg The offending argument, -1 when lazy.
566 * @param pszExpr The expression.
567 * @param iLine The line number.
568 */
569 DECLCALLBACKMEMBER(int, pfnParserError)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int iArg, const char *pszExpr, unsigned iLine);
570
571 /**
572 * Converts a DBGC variable to a DBGF address structure.
573 *
574 * @returns VBox status code.
575 * @param pCmdHlp Pointer to the command callback structure.
576 * @param pVar The variable to convert.
577 * @param pAddress The target address.
578 */
579 DECLCALLBACKMEMBER(int, pfnVarToDbgfAddr)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress);
580
581 /**
582 * Converts a DBGF address structure to a DBGC variable.
583 *
584 * @returns VBox status code.
585 * @param pCmdHlp Pointer to the command callback structure.
586 * @param pAddress The source address.
587 * @param pResult The result variable.
588 */
589 DECLCALLBACKMEMBER(int, pfnVarFromDbgfAddr)(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult);
590
591 /**
592 * Converts a DBGC variable to a 64-bit number.
593 *
594 * @returns VBox status code.
595 * @param pCmdHlp Pointer to the command callback structure.
596 * @param pVar The variable to convert.
597 * @param pu64Number Where to store the number.
598 */
599 DECLCALLBACKMEMBER(int, pfnVarToNumber)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number);
600
601 /**
602 * Converts a DBGC variable to a boolean.
603 *
604 * @returns VBox status code.
605 * @param pCmdHlp Pointer to the command callback structure.
606 * @param pVar The variable to convert.
607 * @param pf Where to store the boolean.
608 */
609 DECLCALLBACKMEMBER(int, pfnVarToBool)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf);
610
611 /**
612 * Get the range of a variable in bytes, resolving symbols if necessary.
613 *
614 * @returns VBox status code.
615 * @param pCmdHlp Pointer to the command callback structure.
616 * @param pVar The variable to convert.
617 * @param cbElement Conversion factor for element ranges.
618 * @param cbDefault The default range.
619 * @param pcbRange The length of the range.
620 */
621 DECLCALLBACKMEMBER(int, pfnVarGetRange)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault,
622 uint64_t *pcbRange);
623
624 /**
625 * Converts a variable to one with the specified type.
626 *
627 * This preserves the range.
628 *
629 * @returns VBox status code.
630 * @param pCmdHlp Pointer to the command callback structure.
631 * @param pVar The variable to convert.
632 * @param enmToType The target type.
633 * @param fConvSyms If @c true, then attempt to resolve symbols.
634 * @param pResult The output variable. Can be the same as @a pVar.
635 */
636 DECLCALLBACKMEMBER(int, pfnVarConvert)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, DBGCVARTYPE enmToType, bool fConvSyms,
637 PDBGCVAR pResult);
638
639 /**
640 * Gets a DBGF output helper that directs the output to the debugger
641 * console.
642 *
643 * @returns Pointer to the helper structure.
644 * @param pCmdHlp Pointer to the command callback structure.
645 */
646 DECLCALLBACKMEMBER(PCDBGFINFOHLP, pfnGetDbgfOutputHlp)(PDBGCCMDHLP pCmdHlp);
647
648 /**
649 * Gets the ID currently selected CPU.
650 *
651 * @returns Current CPU ID.
652 * @param pCmdHlp Pointer to the command callback structure.
653 */
654 DECLCALLBACKMEMBER(VMCPUID, pfnGetCurrentCpu)(PDBGCCMDHLP pCmdHlp);
655
656 /**
657 * Gets the mode the currently selected CPU is running in, in the current
658 * context.
659 *
660 * @returns Current CPU mode.
661 * @param pCmdHlp Pointer to the command callback structure.
662 */
663 DECLCALLBACKMEMBER(CPUMMODE, pfnGetCpuMode)(PDBGCCMDHLP pCmdHlp);
664
665 /** End marker (DBGCCMDHLP_MAGIC). */
666 uint32_t u32EndMarker;
667} DBGCCMDHLP;
668
669/** Magic value for DBGCCMDHLP::u32Magic. (Fyodor Mikhaylovich Dostoyevsky) */
670#define DBGCCMDHLP_MAGIC UINT32_C(18211111)
671
672
673#ifdef IN_RING3
674
675/**
676 * @copydoc DBGCCMDHLP::pfnPrintf
677 */
678DECLINLINE(int) DBGCCmdHlpPrintf(PDBGCCMDHLP pCmdHlp, const char *pszFormat, ...)
679{
680 va_list va;
681 int rc;
682
683 va_start(va, pszFormat);
684 rc = pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, va);
685 va_end(va);
686
687 return rc;
688}
689
690
691/**
692 * @copydoc DBGCCMDHLP::pfnStrPrintf
693 */
694DECLINLINE(size_t) DBGCCmdHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
695{
696 va_list va;
697 size_t cch;
698
699 va_start(va, pszFormat);
700 cch = pCmdHlp->pfnStrPrintfV(pCmdHlp, pszBuf, cbBuf, pszFormat, va);
701 va_end(va);
702
703 return cch;
704}
705
706/**
707 * @copydoc FNDBGCHLPVBOXERROR
708 */
709DECLINLINE(int) DBGCCmdHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...)
710{
711 va_list va;
712
713 va_start(va, pszFormat);
714 rc = pCmdHlp->pfnVBoxErrorV(pCmdHlp, rc, pszFormat, va);
715 va_end(va);
716
717 return rc;
718}
719
720/**
721 * @copydoc FNDBGCHLPMEMREAD
722 */
723DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead)
724{
725 return pCmdHlp->pfnMemRead(pCmdHlp, pVM, pvBuffer, cbRead, pVarPointer, pcbRead);
726}
727
728/**
729 * Evaluates an expression.
730 * (Hopefully the parser and functions are fully reentrant.)
731 *
732 * @returns VBox status code appropriate to return from a command.
733 * @param pCmdHlp Pointer to the command callback structure.
734 * @param pResult Where to store the result.
735 * @param pszExpr The expression. Format string with the format DBGC extensions.
736 * @param ... Format arguments.
737 */
738DECLINLINE(int) DBGCCmdHlpEval(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, ...)
739{
740 va_list va;
741 int rc;
742
743 va_start(va, pszExpr);
744 rc = pCmdHlp->pfnEvalV(pCmdHlp, pResult, pszExpr, va);
745 va_end(va);
746
747 return rc;
748}
749
750/**
751 * Print an error and fail the current command.
752 *
753 * @returns VBox status code to pass upwards.
754 *
755 * @param pCmdHlp Pointer to the command callback structure.
756 * @param pCmd The failing command.
757 * @param pszFormat The error message format string.
758 * @param ... Format arguments.
759 */
760DECLINLINE(int) DBGCCmdHlpFail(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, ...)
761{
762 va_list va;
763 int rc;
764
765 va_start(va, pszFormat);
766 rc = pCmdHlp->pfnFailV(pCmdHlp, pCmd, pszFormat, va);
767 va_end(va);
768
769 return rc;
770}
771
772/**
773 * Print an error and fail the current command.
774 *
775 * Usage example:
776 * @code
777 int rc = VMMR3Something(pVM);
778 if (RT_FAILURE(rc))
779 return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "VMMR3Something");
780 return VINF_SUCCESS;
781 * @endcode
782 *
783 * @returns VBox status code to pass upwards.
784 *
785 * @param pCmdHlp Pointer to the command callback structure.
786 * @param pCmd The failing command.
787 * @param rc The status code indicating the failure.
788 * @param pszFormat The error message format string.
789 * @param ... Format arguments.
790 */
791DECLINLINE(int) DBGCCmdHlpFailRc(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int rc, const char *pszFormat, ...)
792{
793 va_list va;
794
795 va_start(va, pszFormat);
796 rc = pCmdHlp->pfnFailRcV(pCmdHlp, pCmd, rc, pszFormat, va);
797 va_end(va);
798
799 return rc;
800}
801
802/**
803 * @copydoc DBGCCMDHLP::pfnParserError
804 */
805DECLINLINE(int) DBGCCmdHlpParserError(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int iArg, const char *pszExpr, unsigned iLine)
806{
807 return pCmdHlp->pfnParserError(pCmdHlp, pCmd, iArg, pszExpr, iLine);
808}
809
810/** Assert+return like macro for checking parser sanity.
811 * Returns with failure if the precodition is not met. */
812#define DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, iArg, expr) \
813 do { \
814 if (!(expr)) \
815 return DBGCCmdHlpParserError(pCmdHlp, pCmd, iArg, #expr, __LINE__); \
816 } while (0)
817
818/** Assert+return like macro that the VM handle is present.
819 * Returns with failure if the VM handle is NIL. */
820#define DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM) \
821 do { \
822 if (!(pVM)) \
823 return DBGCCmdHlpFail(pCmdHlp, pCmd, "No VM selected"); \
824 } while (0)
825
826/**
827 * @copydoc DBGCCMDHLP::pfnVarToDbgfAddr
828 */
829DECLINLINE(int) DBGCCmdHlpVarToDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
830{
831 return pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, pAddress);
832}
833
834/**
835 * @copydoc DBGCCMDHLP::pfnVarToDbgfAddr
836 */
837DECLINLINE(int) DBGCCmdHlpVarFromDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult)
838{
839 return pCmdHlp->pfnVarFromDbgfAddr(pCmdHlp, pAddress, pResult);
840}
841
842/**
843 * Converts an variable to a flat address.
844 *
845 * @returns VBox status code.
846 * @param pCmdHlp Pointer to the command callback structure.
847 * @param pVar The variable to convert.
848 * @param pFlatPtr Where to store the flat address.
849 */
850DECLINLINE(int) DBGCCmdHlpVarToFlatAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PRTGCPTR pFlatPtr)
851{
852 DBGFADDRESS Addr;
853 int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, &Addr);
854 if (RT_SUCCESS(rc))
855 *pFlatPtr = Addr.FlatPtr;
856 return rc;
857}
858
859/**
860 * @copydoc DBGCCMDHLP::pfnVarToNumber
861 */
862DECLINLINE(int) DBGCCmdHlpVarToNumber(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number)
863{
864 return pCmdHlp->pfnVarToNumber(pCmdHlp, pVar, pu64Number);
865}
866
867/**
868 * @copydoc DBGCCMDHLP::pfnVarToBool
869 */
870DECLINLINE(int) DBGCCmdHlpVarToBool(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf)
871{
872 return pCmdHlp->pfnVarToBool(pCmdHlp, pVar, pf);
873}
874
875/**
876 * @copydoc DBGCCMDHLP::pfnVarGetRange
877 */
878DECLINLINE(int) DBGCCmdHlpVarGetRange(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault, uint64_t *pcbRange)
879{
880 return pCmdHlp->pfnVarGetRange(pCmdHlp, pVar, cbElement, cbDefault, pcbRange);
881}
882
883/**
884 * @copydoc DBGCCMDHLP::pfnVarConvert
885 */
886DECLINLINE(int) DBGCCmdHlpConvert(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, DBGCVARTYPE enmToType, bool fConvSyms, PDBGCVAR pResult)
887{
888 return pCmdHlp->pfnVarConvert(pCmdHlp, pVar, enmToType, fConvSyms, pResult);
889}
890
891/**
892 * @copydoc DBGCCMDHLP::pfnGetDbgfOutputHlp
893 */
894DECLINLINE(PCDBGFINFOHLP) DBGCCmdHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp)
895{
896 return pCmdHlp->pfnGetDbgfOutputHlp(pCmdHlp);
897}
898
899/**
900 * @copydoc DBGCCMDHLP::pfnGetCurrentCpu
901 */
902DECLINLINE(VMCPUID) DBGCCmdHlpGetCurrentCpu(PDBGCCMDHLP pCmdHlp)
903{
904 return pCmdHlp->pfnGetCurrentCpu(pCmdHlp);
905}
906
907/**
908 * @copydoc DBGCCMDHLP::pfnGetCpuMode
909 */
910DECLINLINE(CPUMMODE) DBGCCmdHlpGetCpuMode(PDBGCCMDHLP pCmdHlp)
911{
912 return pCmdHlp->pfnGetCpuMode(pCmdHlp);
913}
914
915#endif /* IN_RING3 */
916
917
918
919/**
920 * Command handler.
921 *
922 * The console will call the handler for a command once it's finished
923 * parsing the user input. The command handler function is responsible
924 * for executing the command itself.
925 *
926 * @returns VBox status.
927 * @param pCmd Pointer to the command descriptor (as registered).
928 * @param pCmdHlp Pointer to command helper functions.
929 * @param pVM Pointer to the current VM (if any).
930 * @param paArgs Pointer to (readonly) array of arguments.
931 * @param cArgs Number of arguments in the array.
932 */
933typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
934/** Pointer to a FNDBGCCMD() function. */
935typedef FNDBGCCMD *PFNDBGCCMD;
936
937/**
938 * DBGC command descriptor.
939 */
940typedef struct DBGCCMD
941{
942 /** Command string. */
943 const char *pszCmd;
944 /** Minimum number of arguments. */
945 unsigned cArgsMin;
946 /** Max number of arguments. */
947 unsigned cArgsMax;
948 /** Argument descriptors (array). */
949 PCDBGCVARDESC paArgDescs;
950 /** Number of argument descriptors. */
951 unsigned cArgDescs;
952 /** flags. (reserved for now) */
953 unsigned fFlags;
954 /** Handler function. */
955 PFNDBGCCMD pfnHandler;
956 /** Command syntax. */
957 const char *pszSyntax;
958 /** Command description. */
959 const char *pszDescription;
960} DBGCCMD;
961
962/** DBGCCMD Flags.
963 * @{
964 */
965/** @} */
966
967
968/**
969 * Function handler.
970 *
971 * The console will call the handler for a command once it's finished
972 * parsing the user input. The command handler function is responsible
973 * for executing the command itself.
974 *
975 * @returns VBox status.
976 * @param pCmd Pointer to the command descriptor (as registered).
977 * @param pCmdHlp Pointer to command helper functions.
978 * @param pVM Pointer to the current VM (if any).
979 * @param paArgs Pointer to (readonly) array of arguments.
980 * @param cArgs Number of arguments in the array.
981 * @param pResult Where to return the result.
982 */
983typedef DECLCALLBACK(int) FNDBGCFUNC(PCDBGCFUNC pFunc, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs,
984 PDBGCVAR pResult);
985/** Pointer to a FNDBGCFUNC() function. */
986typedef FNDBGCFUNC *PFNDBGCFUNC;
987
988/**
989 * DBGC function descriptor.
990 */
991typedef struct DBGCFUNC
992{
993 /** Command string. */
994 const char *pszFuncNm;
995 /** Minimum number of arguments. */
996 unsigned cArgsMin;
997 /** Max number of arguments. */
998 unsigned cArgsMax;
999 /** Argument descriptors (array). */
1000 PCDBGCVARDESC paArgDescs;
1001 /** Number of argument descriptors. */
1002 unsigned cArgDescs;
1003 /** flags. (reserved for now) */
1004 unsigned fFlags;
1005 /** Handler function. */
1006 PFNDBGCFUNC pfnHandler;
1007 /** Function syntax. */
1008 const char *pszSyntax;
1009 /** Function description. */
1010 const char *pszDescription;
1011} DBGCFUNC;
1012
1013
1014
1015/** Pointer to a DBGC backend. */
1016typedef struct DBGCBACK *PDBGCBACK;
1017
1018/**
1019 * Checks if there is input.
1020 *
1021 * @returns true if there is input ready.
1022 * @returns false if there not input ready.
1023 * @param pBack Pointer to the backend structure supplied by
1024 * the backend. The backend can use this to find
1025 * it's instance data.
1026 * @param cMillies Number of milliseconds to wait on input data.
1027 */
1028typedef DECLCALLBACK(bool) FNDBGCBACKINPUT(PDBGCBACK pBack, uint32_t cMillies);
1029/** Pointer to a FNDBGCBACKINPUT() callback. */
1030typedef FNDBGCBACKINPUT *PFNDBGCBACKINPUT;
1031
1032/**
1033 * Read input.
1034 *
1035 * @returns VBox status code.
1036 * @param pBack Pointer to the backend structure supplied by
1037 * the backend. The backend can use this to find
1038 * it's instance data.
1039 * @param pvBuf Where to put the bytes we read.
1040 * @param cbBuf Maximum nymber of bytes to read.
1041 * @param pcbRead Where to store the number of bytes actually read.
1042 * If NULL the entire buffer must be filled for a
1043 * successful return.
1044 */
1045typedef DECLCALLBACK(int) FNDBGCBACKREAD(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
1046/** Pointer to a FNDBGCBACKREAD() callback. */
1047typedef FNDBGCBACKREAD *PFNDBGCBACKREAD;
1048
1049/**
1050 * Write (output).
1051 *
1052 * @returns VBox status code.
1053 * @param pBack Pointer to the backend structure supplied by
1054 * the backend. The backend can use this to find
1055 * it's instance data.
1056 * @param pvBuf What to write.
1057 * @param cbBuf Number of bytes to write.
1058 * @param pcbWritten Where to store the number of bytes actually written.
1059 * If NULL the entire buffer must be successfully written.
1060 */
1061typedef DECLCALLBACK(int) FNDBGCBACKWRITE(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
1062/** Pointer to a FNDBGCBACKWRITE() callback. */
1063typedef FNDBGCBACKWRITE *PFNDBGCBACKWRITE;
1064
1065/**
1066 * Ready / busy notification.
1067 *
1068 * @param pBack Pointer to the backend structure supplied by
1069 * the backend. The backend can use this to find
1070 * it's instance data.
1071 * @param fReady Whether it's ready (true) or busy (false).
1072 */
1073typedef DECLCALLBACK(void) FNDBGCBACKSETREADY(PDBGCBACK pBack, bool fReady);
1074/** Pointer to a FNDBGCBACKSETREADY() callback. */
1075typedef FNDBGCBACKSETREADY *PFNDBGCBACKSETREADY;
1076
1077
1078/**
1079 * The communication backend provides the console with a number of callbacks
1080 * which can be used
1081 */
1082typedef struct DBGCBACK
1083{
1084 /** Check for input. */
1085 PFNDBGCBACKINPUT pfnInput;
1086 /** Read input. */
1087 PFNDBGCBACKREAD pfnRead;
1088 /** Write output. */
1089 PFNDBGCBACKWRITE pfnWrite;
1090 /** Ready / busy notification. */
1091 PFNDBGCBACKSETREADY pfnSetReady;
1092} DBGCBACK;
1093
1094
1095/**
1096 * Make a console instance.
1097 *
1098 * This will not return until either an 'exit' command is issued or a error code
1099 * indicating connection loss is encountered.
1100 *
1101 * @returns VINF_SUCCESS if console termination caused by the 'exit' command.
1102 * @returns The VBox status code causing the console termination.
1103 *
1104 * @param pVM VM Handle.
1105 * @param pBack Pointer to the backend structure. This must contain
1106 * a full set of function pointers to service the console.
1107 * @param fFlags Reserved, must be zero.
1108 * @remark A forced termination of the console is easiest done by forcing the
1109 * callbacks to return fatal failures.
1110 */
1111DBGDECL(int) DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags);
1112
1113
1114/**
1115 * Register one or more external commands.
1116 *
1117 * @returns VBox status.
1118 * @param paCommands Pointer to an array of command descriptors.
1119 * The commands must be unique. It's not possible
1120 * to register the same commands more than once.
1121 * @param cCommands Number of commands.
1122 */
1123DBGDECL(int) DBGCRegisterCommands(PCDBGCCMD paCommands, unsigned cCommands);
1124
1125
1126/**
1127 * Deregister one or more external commands previously registered by
1128 * DBGCRegisterCommands().
1129 *
1130 * @returns VBox status.
1131 * @param paCommands Pointer to an array of command descriptors
1132 * as given to DBGCRegisterCommands().
1133 * @param cCommands Number of commands.
1134 */
1135DBGDECL(int) DBGCDeregisterCommands(PCDBGCCMD paCommands, unsigned cCommands);
1136
1137
1138/**
1139 * Spawns a new thread with a TCP based debugging console service.
1140 *
1141 * @returns VBox status.
1142 * @param pVM VM handle.
1143 * @param ppvData Where to store the pointer to instance data.
1144 */
1145DBGDECL(int) DBGCTcpCreate(PVM pVM, void **ppvUser);
1146
1147/**
1148 * Terminates any running TCP base debugger console service.
1149 *
1150 * @returns VBox status.
1151 * @param pVM VM handle.
1152 * @param pvData Instance data set by DBGCTcpCreate().
1153 */
1154DBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData);
1155
1156
1157/** @defgroup grp_dbgc_plug_in The DBGC Plug-in Interface
1158 * @{
1159 */
1160
1161/** The plug-in module name prefix. */
1162#define DBGC_PLUG_IN_PREFIX "DBGCPlugIn"
1163
1164/** The name of the plug-in entry point (FNDBGCPLUGIN) */
1165#define DBGC_PLUG_IN_ENTRYPOINT "DBGCPlugInEntry"
1166
1167/**
1168 * DBGC plug-in operations.
1169 */
1170typedef enum DBGCPLUGINOP
1171{
1172 /** The usual invalid first value. */
1173 DBGCPLUGINOP_INVALID,
1174 /** Initialize the plug-in, register all the stuff.
1175 * The plug-in will be unloaded on failure.
1176 * uArg: The VirtualBox version (major+minor). */
1177 DBGCPLUGINOP_INIT,
1178 /** Terminate the plug-ing, deregister all the stuff.
1179 * The plug-in will be unloaded after this call regardless of the return
1180 * code. */
1181 DBGCPLUGINOP_TERM,
1182 /** The usual 32-bit hack. */
1183 DBGCPLUGINOP_32BIT_HACK = 0x7fffffff
1184} DBGCPLUGINOP;
1185
1186/**
1187 * DBGC plug-in main entry point.
1188 *
1189 * @returns VBox status code.
1190 *
1191 * @param enmOperation The operation.
1192 * @param pVM The VM handle. This may be NULL.
1193 * @param uArg Extra argument.
1194 */
1195typedef DECLCALLBACK(int) FNDBGCPLUGIN(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg);
1196/** Pointer to a FNDBGCPLUGIN. */
1197typedef FNDBGCPLUGIN *PFNDBGCPLUGIN;
1198
1199/** @copydoc FNDBGCPLUGIN */
1200DECLEXPORT(int) DBGCPlugInEntry(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg);
1201
1202#endif /* IN_RING3 */
1203
1204/** @} */
1205
1206
1207RT_C_DECLS_END
1208
1209#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