summaryrefslogtreecommitdiff
path: root/src/VBox/Debugger/DBGCInternal.h
blob: 46f7b7131f5ea8d73c5a12c4c9af70ea8524ffe6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
/* $Id: DBGCInternal.h $ */
/** @file
 * DBGC - Debugger Console, Internal Header File.
 */

/*
 * Copyright (C) 2006-2013 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 */


#ifndef ___Debugger_DBGCInternal_h
#define ___Debugger_DBGCInternal_h


/*******************************************************************************
*   Header Files                                                               *
*******************************************************************************/
#include <VBox/dbg.h>
#include <VBox/err.h>


/*******************************************************************************
*   Structures and Typedefs                                                    *
*******************************************************************************/

/**
 * Debugger console per breakpoint data.
 */
typedef struct DBGCBP
{
    /** Pointer to the next breakpoint in the list. */
    struct DBGCBP  *pNext;
    /** The breakpoint identifier. */
    uint32_t        iBp;
    /** The size of the command. */
    size_t          cchCmd;
    /** The command to execute when the breakpoint is hit. */
    char            szCmd[1];
} DBGCBP;
/** Pointer to a breakpoint. */
typedef DBGCBP *PDBGCBP;


/**
 * Named variable.
 *
 * Always allocated from heap in one single block.
 */
typedef struct DBGCNAMEDVAR
{
    /** The variable. */
    DBGCVAR     Var;
    /** Its name. */
    char        szName[1];
} DBGCNAMEDVAR;
/** Pointer to named variable. */
typedef DBGCNAMEDVAR *PDBGCNAMEDVAR;


/** The max length of a plug-in name, zero terminator included. */
#define DBGCPLUGIN_MAX_NAME     32

/**
 * Plug-in tracking record.
 */
typedef struct DBGCPLUGIN
{
    /** Pointer to the next plug-in. */
    struct DBGCPLUGIN  *pNext;
    /** The loader handle.  */
    RTLDRMOD            hLdrMod;
    /** The plug-in entry point. */
    PFNDBGCPLUGIN       pfnEntry;
    /** The plug-in name (variable length).  */
    char                szName[DBGCPLUGIN_MAX_NAME];
} DBGCPLUGIN;
/** Pointer to plug-in tracking record. */
typedef DBGCPLUGIN *PDBGCPLUGIN;


/**
 * Debugger console status
 */
typedef enum DBGCSTATUS
{
    /** Normal status, .*/
    DBGC_HALTED

} DBGCSTATUS;


/**
 * Debugger console instance data.
 */
typedef struct DBGC
{
    /** Command helpers. */
    DBGCCMDHLP          CmdHlp;
    /** Wrappers for DBGF output. */
    DBGFINFOHLP         DbgfOutputHlp;
    /** Pointer to backend callback structure. */
    PDBGCBACK           pBack;

    /** Pointer to the current VM. */
    PVM                 pVM;
    /** The user mode handle of the current VM. */
    PUVM                pUVM;
    /** The ID of current virtual CPU. */
    VMCPUID             idCpu;
    /** The current address space handle. */
    RTDBGAS             hDbgAs;
    /** The current debugger emulation. */
    const char         *pszEmulation;
    /** Pointer to the commands for the current debugger emulation. */
    PCDBGCCMD           paEmulationCmds;
    /** The number of commands paEmulationCmds points to. */
    unsigned            cEmulationCmds;
    /** Pointer to the functions for the current debugger emulation. */
    PCDBGCFUNC          paEmulationFuncs;
    /** The number of functions paEmulationFuncs points to. */
    uint32_t            cEmulationFuncs;
    /** Log indicator. (If set we're writing the log to the console.) */
    bool                fLog;

    /** Indicates whether we're in guest (true) or hypervisor (false) register context. */
    bool                fRegCtxGuest;
    /** Indicates whether the register are terse or sparse. */
    bool                fRegTerse;
    /** Counter use to suppress the printing of the headers. */
    uint8_t             cPagingHierarchyDumps;

    /** Current disassembler position. */
    DBGCVAR             DisasmPos;
    /** The flags that goes with DisasmPos. */
    uint32_t            fDisasm;
    /** Current source position. (flat GC) */
    DBGCVAR             SourcePos;
    /** Current memory dump position. */
    DBGCVAR             DumpPos;
    /** Size of the previous dump element. */
    unsigned            cbDumpElement;
    /** Points to DisasmPos, SourcePos or DumpPos depending on which was
     *  used last. */
    PCDBGCVAR           pLastPos;

    /** Number of variables in papVars. */
    unsigned            cVars;
    /** Array of global variables.
     * Global variables can be referenced using the $ operator and set
     * and unset using command with those names. */
    PDBGCNAMEDVAR      *papVars;

    /** The list of plug-in. (singly linked) */
    PDBGCPLUGIN         pPlugInHead;

    /** The list of breakpoints. (singly linked) */
    PDBGCBP             pFirstBp;

    /** Save search pattern. */
    uint8_t             abSearch[256];
    /** The length of the search pattern. */
    uint32_t            cbSearch;
    /** The search unit */
    uint32_t            cbSearchUnit;
    /** The max hits. */
    uint64_t            cMaxSearchHits;
    /** The address to resume searching from. */
    DBGFADDRESS         SearchAddr;
    /** What's left of the original search range. */
    RTGCUINTPTR         cbSearchRange;

    /** @name Parsing and Execution
     * @{ */

    /** Input buffer. */
    char                achInput[2048];
    /** To ease debugging. */
    unsigned            uInputZero;
    /** Write index in the input buffer. */
    unsigned            iWrite;
    /** Read index in the input buffer. */
    unsigned            iRead;
    /** The number of lines in the buffer. */
    unsigned            cInputLines;
    /** Indicates that we have a buffer overflow condition.
     * This means that input is ignored up to the next newline. */
    bool                fInputOverflow;
    /** Indicates whether or we're ready for input. */
    bool                fReady;
    /** Scratch buffer position. */
    char               *pszScratch;
    /** Scratch buffer. */
    char                achScratch[16384];
    /** Argument array position. */
    unsigned            iArg;
    /** Array of argument variables. */
    DBGCVAR             aArgs[100];

    /** rc from the last dbgcHlpPrintfV(). */
    int                 rcOutput;
    /** The last character we wrote. */
    char                chLastOutput;

    /** rc from the last command. */
    int                 rcCmd;
    /** @} */
} DBGC;
/** Pointer to debugger console instance data. */
typedef DBGC *PDBGC;

/** Converts a Command Helper pointer to a pointer to DBGC instance data. */
#define DBGC_CMDHLP2DBGC(pCmdHlp)   ( (PDBGC)((uintptr_t)(pCmdHlp) - RT_OFFSETOF(DBGC, CmdHlp)) )


/**
 * Chunk of external commands.
 */
typedef struct DBGCEXTCMDS
{
    /** Number of commands descriptors. */
    unsigned            cCmds;
    /** Pointer to array of command descriptors. */
    PCDBGCCMD           paCmds;
    /** Pointer to the next chunk. */
    struct DBGCEXTCMDS *pNext;
} DBGCEXTCMDS;
/** Pointer to chunk of external commands. */
typedef DBGCEXTCMDS *PDBGCEXTCMDS;


/**
 * Chunk of external functions.
 */
typedef struct DBGCEXTFUNCS
{
    /** Number of functions descriptors. */
    uint32_t            cFuncs;
    /** Pointer to array of functions descriptors. */
    PCDBGCFUNC          paFuncs;
    /** Pointer to the next chunk. */
    struct DBGCEXTFUNCS *pNext;
} DBGCEXTFUNCS;
/** Pointer to chunk of external functions. */
typedef DBGCEXTFUNCS *PDBGCEXTFUNCS;



/**
 * Unary operator handler function.
 *
 * @returns 0 on success.
 * @returns VBox evaluation / parsing error code on failure.
 *          The caller does the bitching.
 * @param   pDbgc       Debugger console instance data.
 * @param   pArg        The argument.
 * @param   enmCat      The desired result category. Can be ignored.
 * @param   pResult     Where to store the result.
 */
typedef DECLCALLBACK(int) FNDBGCOPUNARY(PDBGC pDbgc, PCDBGCVAR pArg, DBGCVARCAT enmCat, PDBGCVAR pResult);
/** Pointer to a unary operator handler function. */
typedef FNDBGCOPUNARY *PFNDBGCOPUNARY;


/**
 * Binary operator handler function.
 *
 * @returns 0 on success.
 * @returns VBox evaluation / parsing error code on failure.
 *          The caller does the bitching.
 * @param   pDbgc       Debugger console instance data.
 * @param   pArg1       The first argument.
 * @param   pArg2       The 2nd argument.
 * @param   pResult     Where to store the result.
 */
typedef DECLCALLBACK(int) FNDBGCOPBINARY(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
/** Pointer to a binary operator handler function. */
typedef FNDBGCOPBINARY *PFNDBGCOPBINARY;


/**
 * Operator descriptor.
 */
typedef struct DBGCOP
{
    /** Operator mnemonic. */
    char            szName[4];
    /** Length of name. */
    const unsigned  cchName;
    /** Whether or not this is a binary operator.
     * Unary operators are evaluated right-to-left while binary are left-to-right. */
    bool            fBinary;
    /** Precedence level. */
    unsigned        iPrecedence;
    /** Unary operator handler. */
    PFNDBGCOPUNARY  pfnHandlerUnary;
    /** Binary operator handler. */
    PFNDBGCOPBINARY pfnHandlerBinary;
    /** The category of the 1st argument.
     * Set to DBGCVAR_CAT_ANY if anything goes. */
    DBGCVARCAT      enmCatArg1;
    /** The category of the 2nd argument.
     * Set to DBGCVAR_CAT_ANY if anything goes. */
    DBGCVARCAT      enmCatArg2;
    /** Operator description. */
    const char     *pszDescription;
} DBGCOP;
/** Pointer to an operator descriptor. */
typedef DBGCOP *PDBGCOP;
/** Pointer to a const operator descriptor. */
typedef const DBGCOP *PCDBGCOP;



/** Pointer to symbol descriptor. */
typedef struct DBGCSYM *PDBGCSYM;
/** Pointer to const symbol descriptor. */
typedef const struct DBGCSYM *PCDBGCSYM;

/**
 * Get builtin symbol.
 *
 * @returns 0 on success.
 * @returns VBox evaluation / parsing error code on failure.
 *          The caller does the bitching.
 * @param   pSymDesc    Pointer to the symbol descriptor.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   enmType     The result type.
 * @param   pResult     Where to store the result.
 */
typedef DECLCALLBACK(int) FNDBGCSYMGET(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, DBGCVARTYPE enmType, PDBGCVAR pResult);
/** Pointer to get function for a builtin symbol. */
typedef FNDBGCSYMGET *PFNDBGCSYMGET;

/**
 * Set builtin symbol.
 *
 * @returns 0 on success.
 * @returns VBox evaluation / parsing error code on failure.
 *          The caller does the bitching.
 * @param   pSymDesc    Pointer to the symbol descriptor.
 * @param   pCmdHlp     Pointer to the command callback structure.
 * @param   pValue      The value to assign the symbol.
 */
typedef DECLCALLBACK(int) FNDBGCSYMSET(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pValue);
/** Pointer to set function for a builtin symbol. */
typedef FNDBGCSYMSET *PFNDBGCSYMSET;


/**
 * Symbol description (for builtin symbols).
 */
typedef struct DBGCSYM
{
    /** Symbol name. */
    const char     *pszName;
    /** Get function. */
    PFNDBGCSYMGET   pfnGet;
    /** Set function. (NULL if readonly) */
    PFNDBGCSYMSET   pfnSet;
    /** User data. */
    unsigned        uUser;
} DBGCSYM;


/*******************************************************************************
*   Internal Functions                                                         *
*******************************************************************************/
int     dbgcBpAdd(PDBGC pDbgc, RTUINT iBp, const char *pszCmd);
int     dbgcBpUpdate(PDBGC pDbgc, RTUINT iBp, const char *pszCmd);
int     dbgcBpDelete(PDBGC pDbgc, RTUINT iBp);
PDBGCBP dbgcBpGet(PDBGC pDbgc, RTUINT iBp);
int     dbgcBpExec(PDBGC pDbgc, RTUINT iBp);

void    dbgcEvalInit(void);
int     dbgcEvalSub(PDBGC pDbgc, char *pszExpr, size_t cchExpr, DBGCVARCAT enmCategory, PDBGCVAR pResult);
int     dbgcEvalCommand(PDBGC pDbgc, char *pszCmd, size_t cchCmd, bool fNoExecute);

int     dbgcSymbolGet(PDBGC pDbgc, const char *pszSymbol, DBGCVARTYPE enmType, PDBGCVAR pResult);
PCDBGCSYM   dbgcLookupRegisterSymbol(PDBGC pDbgc, const char *pszSymbol);
PCDBGCOP    dbgcOperatorLookup(PDBGC pDbgc, const char *pszExpr, bool fPreferBinary, char chPrev);
PCDBGCCMD   dbgcCommandLookup(PDBGC pDbgc, const char *pachName, size_t cchName, bool fExternal);
PCDBGCFUNC  dbgcFunctionLookup(PDBGC pDbgc, const char *pachName, size_t cchName, bool fExternal);

DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, DBGCVARCAT enmCat, PDBGCVAR pResult);
DECLCALLBACK(int) dbgcOpAddrFlat(PDBGC pDbgc, PCDBGCVAR pArg, DBGCVARCAT enmCat, PDBGCVAR pResult);
DECLCALLBACK(int) dbgcOpAddrHost(PDBGC pDbgc, PCDBGCVAR pArg, DBGCVARCAT enmCat, PDBGCVAR pResult);
DECLCALLBACK(int) dbgcOpAddrPhys(PDBGC pDbgc, PCDBGCVAR pArg, DBGCVARCAT enmCat, PDBGCVAR pResult);
DECLCALLBACK(int) dbgcOpAddrHostPhys(PDBGC pDbgc, PCDBGCVAR pArg, DBGCVARCAT enmCat, PDBGCVAR pResult);

void    dbgcInitCmdHlp(PDBGC pDbgc);

void    dbgcPlugInAutoLoad(PDBGC pDbgc);
void    dbgcPlugInUnloadAll(PDBGC pDbgc);

/* For tstDBGCParser: */
int     dbgcCreate(PDBGC *ppDbgc, PDBGCBACK pBack, unsigned fFlags);
int     dbgcRun(PDBGC pDbgc);
int     dbgcProcessInput(PDBGC pDbgc, bool fNoExecute);
void    dbgcDestroy(PDBGC pDbgc);


/*******************************************************************************
*   Global Variables                                                           *
*******************************************************************************/
extern const DBGCCMD    g_aDbgcCmds[];
extern const uint32_t   g_cDbgcCmds;
extern const DBGCFUNC   g_aDbgcFuncs[];
extern const uint32_t   g_cDbgcFuncs;
extern const DBGCCMD    g_aCmdsCodeView[];
extern const uint32_t   g_cCmdsCodeView;
extern const DBGCFUNC   g_aFuncsCodeView[];
extern const uint32_t   g_cFuncsCodeView;
extern const DBGCOP     g_aDbgcOps[];
extern const uint32_t   g_cDbgcOps;


/*******************************************************************************
*   Defined Constants And Macros                                               *
*******************************************************************************/
/** Locks the g_pExtCmdsHead and g_pExtFuncsHead lists for reading. */
#define DBGCEXTLISTS_LOCK_RD()      do { } while (0)
/** Locks the g_pExtCmdsHead and g_pExtFuncsHead lists for writing. */
#define DBGCEXTLISTS_LOCK_WR()      do { } while (0)
/** UnLocks the g_pExtCmdsHead and g_pExtFuncsHead lists after reading. */
#define DBGCEXTLISTS_UNLOCK_RD()    do { } while (0)
/** UnLocks the g_pExtCmdsHead and g_pExtFuncsHead lists after writing. */
#define DBGCEXTLISTS_UNLOCK_WR()    do { } while (0)



#endif