3 * DBGC - Debugger Console, Operators.
7 * Copyright (C) 2006-2011 Oracle Corporation
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.
19 /*******************************************************************************
21 *******************************************************************************/
22 #define LOG_GROUP LOG_GROUP_DBGC
24 #include <VBox/vmm/dbgf.h>
25 #include <VBox/param.h>
29 #include <iprt/assert.h>
31 #include <iprt/string.h>
33 #include "DBGCInternal.h"
36 /*******************************************************************************
37 * Internal Functions *
38 *******************************************************************************/
39 static DECLCALLBACK(int) dbgcOpMinus(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
);
40 static DECLCALLBACK(int) dbgcOpPluss(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
);
41 static DECLCALLBACK(int) dbgcOpBooleanNot(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
);
42 static DECLCALLBACK(int) dbgcOpBitwiseNot(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
);
43 static DECLCALLBACK(int) dbgcOpVar(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
);
45 static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
46 static DECLCALLBACK(int) dbgcOpMult(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
47 static DECLCALLBACK(int) dbgcOpDiv(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
48 static DECLCALLBACK(int) dbgcOpMod(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
49 static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
50 static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
51 static DECLCALLBACK(int) dbgcOpBitwiseShiftLeft(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
52 static DECLCALLBACK(int) dbgcOpBitwiseShiftRight(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
53 static DECLCALLBACK(int) dbgcOpBitwiseAnd(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
54 static DECLCALLBACK(int) dbgcOpBitwiseXor(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
55 static DECLCALLBACK(int) dbgcOpBitwiseOr(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
56 static DECLCALLBACK(int) dbgcOpBooleanAnd(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
57 static DECLCALLBACK(int) dbgcOpBooleanOr(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
58 static DECLCALLBACK(int) dbgcOpRangeLength(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
59 static DECLCALLBACK(int) dbgcOpRangeLengthBytes(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
60 static DECLCALLBACK(int) dbgcOpRangeTo(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
);
63 /*******************************************************************************
64 * Defined Constants And Macros *
65 *******************************************************************************/
67 * Generic implementation of a binary operator.
69 * @returns VINF_SUCCESS on success.
70 * @returns VBox evaluation / parsing error code on failure.
71 * The caller does the bitching.
72 * @param pDbgc Debugger console instance data.
73 * @param pArg1 The first argument.
74 * @param pArg2 The 2nd argument.
75 * @param pResult Where to store the result.
76 * @param Operator The C operator.
77 * @param fIsDiv Set if it's division and we need to check for zero on the
80 #define DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, Operator, fIsDiv) \
83 if ((pArg1)->enmType == DBGCVAR_TYPE_STRING) \
84 return VERR_DBGC_PARSE_INVALID_OPERATION; \
86 /* Get the 64-bit right side value. */ \
88 int rc = dbgcOpHelperGetNumber((pDbgc), (pArg2), &u64Right); \
89 if ((fIsDiv) && RT_SUCCESS(rc) && !u64Right) /* div/0 kludge */ \
90 DBGCVAR_INIT_NUMBER((pResult), UINT64_MAX); \
91 else if (RT_SUCCESS(rc)) \
93 /* Apply it to the left hand side. */ \
94 if ((pArg1)->enmType == DBGCVAR_TYPE_SYMBOL) \
96 rc = dbgcSymbolGet((pDbgc), (pArg1)->u.pszString, DBGCVAR_TYPE_ANY, (pResult)); \
101 *(pResult) = *(pArg1); \
102 switch ((pResult)->enmType) \
104 case DBGCVAR_TYPE_GC_FLAT: \
105 (pResult)->u.GCFlat = (pResult)->u.GCFlat Operator u64Right; \
107 case DBGCVAR_TYPE_GC_FAR: \
108 (pResult)->u.GCFar.off = (pResult)->u.GCFar.off Operator u64Right; \
110 case DBGCVAR_TYPE_GC_PHYS: \
111 (pResult)->u.GCPhys = (pResult)->u.GCPhys Operator u64Right; \
113 case DBGCVAR_TYPE_HC_FLAT: \
114 (pResult)->u.pvHCFlat = (void *)((uintptr_t)(pResult)->u.pvHCFlat Operator u64Right); \
116 case DBGCVAR_TYPE_HC_PHYS: \
117 (pResult)->u.HCPhys = (pResult)->u.HCPhys Operator u64Right; \
119 case DBGCVAR_TYPE_NUMBER: \
120 (pResult)->u.u64Number = (pResult)->u.u64Number Operator u64Right; \
123 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; \
131 * Switch the factors/whatever so we preserve pointers.
132 * Far pointers are considered more important that physical and flat pointers.
134 * @param pArg1 The left side argument. Input & output.
135 * @param pArg2 The right side argument. Input & output.
137 #define DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2) \
140 if ( DBGCVAR_ISPOINTER((pArg2)->enmType) \
141 && ( !DBGCVAR_ISPOINTER((pArg1)->enmType) \
142 || ( DBGCVAR_IS_FAR_PTR((pArg2)->enmType) \
143 && !DBGCVAR_IS_FAR_PTR((pArg1)->enmType)))) \
145 PCDBGCVAR pTmp = (pArg1); \
152 /*******************************************************************************
154 *******************************************************************************/
156 const DBGCOP g_aDbgcOps
[] =
158 /* szName is initialized as a 4 char array because of M$C elsewise optimizing it away in /Ox mode (the 'const char' vs 'char' problem). */
159 /* szName, cchName, fBinary, iPrecedence, pfnHandlerUnary, pfnHandlerBitwise */
160 { {'-'}, 1, false, 1, dbgcOpMinus
, NULL
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Unary minus." },
161 { {'+'}, 1, false, 1, dbgcOpPluss
, NULL
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Unary plus." },
162 { {'!'}, 1, false, 1, dbgcOpBooleanNot
, NULL
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Boolean not." },
163 { {'~'}, 1, false, 1, dbgcOpBitwiseNot
, NULL
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Bitwise complement." },
164 { {':'}, 1, true, 2, NULL
, dbgcOpAddrFar
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Far pointer." },
165 { {'%'}, 1, false, 3, dbgcOpAddrFlat
, NULL
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Flat address." },
166 { {'%','%'}, 2, false, 3, dbgcOpAddrPhys
, NULL
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Physical address." },
167 { {'#'}, 1, false, 3, dbgcOpAddrHost
, NULL
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Flat host address." },
168 { {'#','%','%'}, 3, false, 3, dbgcOpAddrHostPhys
, NULL
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Physical host address." },
169 { {'$'}, 1, false, 3, dbgcOpVar
, NULL
, DBGCVAR_CAT_SYMBOL
, DBGCVAR_CAT_ANY
, "Reference a variable." },
170 { {'@'}, 1, false, 3, dbgcOpRegister
, NULL
, DBGCVAR_CAT_SYMBOL
, DBGCVAR_CAT_ANY
, "Reference a register." },
171 { {'*'}, 1, true, 10, NULL
, dbgcOpMult
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Multiplication." },
172 { {'/'}, 1, true, 11, NULL
, dbgcOpDiv
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Division." },
173 { {'m','o','d'}, 3, true, 12, NULL
, dbgcOpMod
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Modulus." },
174 { {'+'}, 1, true, 13, NULL
, dbgcOpAdd
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Addition." },
175 { {'-'}, 1, true, 14, NULL
, dbgcOpSub
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Subtraction." },
176 { {'<','<'}, 2, true, 15, NULL
, dbgcOpBitwiseShiftLeft
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Bitwise left shift." },
177 { {'>','>'}, 2, true, 16, NULL
, dbgcOpBitwiseShiftRight
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Bitwise right shift." },
178 { {'&'}, 1, true, 17, NULL
, dbgcOpBitwiseAnd
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Bitwise and." },
179 { {'^'}, 1, true, 18, NULL
, dbgcOpBitwiseXor
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Bitwise exclusiv or." },
180 { {'|'}, 1, true, 19, NULL
, dbgcOpBitwiseOr
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Bitwise inclusive or." },
181 { {'&','&'}, 2, true, 20, NULL
, dbgcOpBooleanAnd
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Boolean and." },
182 { {'|','|'}, 2, true, 21, NULL
, dbgcOpBooleanOr
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Boolean or." },
183 { {'L'}, 1, true, 22, NULL
, dbgcOpRangeLength
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Range elements." },
184 { {'L','B'}, 2, true, 23, NULL
, dbgcOpRangeLengthBytes
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Range bytes." },
185 { {'T'}, 1, true, 24, NULL
, dbgcOpRangeTo
, DBGCVAR_CAT_ANY
, DBGCVAR_CAT_ANY
, "Range to." }
188 /** Number of operators in the operator array. */
189 const uint32_t g_cDbgcOps
= RT_ELEMENTS(g_aDbgcOps
);
193 * Converts an argument to a number value.
195 * @returns VBox status code.
196 * @param pDbgc The DBGC instance.
197 * @param pArg The argument to convert.
198 * @param pu64Ret Where to return the value.
200 static int dbgcOpHelperGetNumber(PDBGC pDbgc
, PCDBGCVAR pArg
, uint64_t *pu64Ret
)
205 case DBGCVAR_TYPE_GC_FLAT
:
206 *pu64Ret
= Var
.u
.GCFlat
;
208 case DBGCVAR_TYPE_GC_FAR
:
209 *pu64Ret
= Var
.u
.GCFar
.off
;
211 case DBGCVAR_TYPE_GC_PHYS
:
212 *pu64Ret
= Var
.u
.GCPhys
;
214 case DBGCVAR_TYPE_HC_FLAT
:
215 *pu64Ret
= (uintptr_t)Var
.u
.pvHCFlat
;
217 case DBGCVAR_TYPE_HC_PHYS
:
218 *pu64Ret
= Var
.u
.HCPhys
;
220 case DBGCVAR_TYPE_NUMBER
:
221 *pu64Ret
= Var
.u
.u64Number
;
223 case DBGCVAR_TYPE_SYMBOL
:
225 int rc
= dbgcSymbolGet(pDbgc
, Var
.u
.pszString
, DBGCVAR_TYPE_NUMBER
, &Var
);
230 case DBGCVAR_TYPE_STRING
:
232 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
;
241 * @returns VINF_SUCCESS on success.
242 * @returns VBox evaluation / parsing error code on failure.
243 * The caller does the bitching.
244 * @param pDbgc Debugger console instance data.
245 * @param pArg The argument.
246 * @param pResult Where to store the result.
248 static DECLCALLBACK(int) dbgcOpMinus(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
250 LogFlow(("dbgcOpMinus\n"));
252 switch (pArg
->enmType
)
254 case DBGCVAR_TYPE_GC_FLAT
:
255 pResult
->u
.GCFlat
= -(RTGCINTPTR
)pResult
->u
.GCFlat
;
257 case DBGCVAR_TYPE_GC_FAR
:
258 pResult
->u
.GCFar
.off
= -(int32_t)pResult
->u
.GCFar
.off
;
260 case DBGCVAR_TYPE_GC_PHYS
:
261 pResult
->u
.GCPhys
= (RTGCPHYS
) -(int64_t)pResult
->u
.GCPhys
;
263 case DBGCVAR_TYPE_HC_FLAT
:
264 pResult
->u
.pvHCFlat
= (void *) -(intptr_t)pResult
->u
.pvHCFlat
;
266 case DBGCVAR_TYPE_HC_PHYS
:
267 pResult
->u
.HCPhys
= (RTHCPHYS
) -(int64_t)pResult
->u
.HCPhys
;
269 case DBGCVAR_TYPE_NUMBER
:
270 pResult
->u
.u64Number
= -(int64_t)pResult
->u
.u64Number
;
273 case DBGCVAR_TYPE_STRING
:
274 case DBGCVAR_TYPE_SYMBOL
:
276 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
;
286 * @returns VINF_SUCCESS on success.
287 * @returns VBox evaluation / parsing error code on failure.
288 * The caller does the bitching.
289 * @param pDbgc Debugger console instance data.
290 * @param pArg The argument.
291 * @param pResult Where to store the result.
293 static DECLCALLBACK(int) dbgcOpPluss(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
295 LogFlow(("dbgcOpPluss\n"));
297 switch (pArg
->enmType
)
299 case DBGCVAR_TYPE_GC_FLAT
:
300 case DBGCVAR_TYPE_GC_FAR
:
301 case DBGCVAR_TYPE_GC_PHYS
:
302 case DBGCVAR_TYPE_HC_FLAT
:
303 case DBGCVAR_TYPE_HC_PHYS
:
304 case DBGCVAR_TYPE_NUMBER
:
307 case DBGCVAR_TYPE_STRING
:
308 case DBGCVAR_TYPE_SYMBOL
:
310 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
;
318 * Boolean not (unary).
320 * @returns VINF_SUCCESS on success.
321 * @returns VBox evaluation / parsing error code on failure.
322 * The caller does the bitching.
323 * @param pDbgc Debugger console instance data.
324 * @param pArg The argument.
325 * @param pResult Where to store the result.
327 static DECLCALLBACK(int) dbgcOpBooleanNot(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
329 LogFlow(("dbgcOpBooleanNot\n"));
331 switch (pArg
->enmType
)
333 case DBGCVAR_TYPE_GC_FLAT
:
334 pResult
->u
.u64Number
= !pResult
->u
.GCFlat
;
336 case DBGCVAR_TYPE_GC_FAR
:
337 pResult
->u
.u64Number
= !pResult
->u
.GCFar
.off
&& pResult
->u
.GCFar
.sel
<= 3;
339 case DBGCVAR_TYPE_GC_PHYS
:
340 pResult
->u
.u64Number
= !pResult
->u
.GCPhys
;
342 case DBGCVAR_TYPE_HC_FLAT
:
343 pResult
->u
.u64Number
= !pResult
->u
.pvHCFlat
;
345 case DBGCVAR_TYPE_HC_PHYS
:
346 pResult
->u
.u64Number
= !pResult
->u
.HCPhys
;
348 case DBGCVAR_TYPE_NUMBER
:
349 pResult
->u
.u64Number
= !pResult
->u
.u64Number
;
351 case DBGCVAR_TYPE_STRING
:
352 case DBGCVAR_TYPE_SYMBOL
:
353 pResult
->u
.u64Number
= !pResult
->u64Range
;
356 case DBGCVAR_TYPE_UNKNOWN
:
358 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
;
360 pResult
->enmType
= DBGCVAR_TYPE_NUMBER
;
367 * Bitwise not (unary).
369 * @returns VINF_SUCCESS on success.
370 * @returns VBox evaluation / parsing error code on failure.
371 * The caller does the bitching.
372 * @param pDbgc Debugger console instance data.
373 * @param pArg The argument.
374 * @param pResult Where to store the result.
376 static DECLCALLBACK(int) dbgcOpBitwiseNot(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
378 LogFlow(("dbgcOpBitwiseNot\n"));
380 switch (pArg
->enmType
)
382 case DBGCVAR_TYPE_GC_FLAT
:
383 pResult
->u
.GCFlat
= ~pResult
->u
.GCFlat
;
385 case DBGCVAR_TYPE_GC_FAR
:
386 pResult
->u
.GCFar
.off
= ~pResult
->u
.GCFar
.off
;
388 case DBGCVAR_TYPE_GC_PHYS
:
389 pResult
->u
.GCPhys
= ~pResult
->u
.GCPhys
;
391 case DBGCVAR_TYPE_HC_FLAT
:
392 pResult
->u
.pvHCFlat
= (void *)~(uintptr_t)pResult
->u
.pvHCFlat
;
394 case DBGCVAR_TYPE_HC_PHYS
:
395 pResult
->u
.HCPhys
= ~pResult
->u
.HCPhys
;
397 case DBGCVAR_TYPE_NUMBER
:
398 pResult
->u
.u64Number
= ~pResult
->u
.u64Number
;
401 case DBGCVAR_TYPE_STRING
:
402 case DBGCVAR_TYPE_SYMBOL
:
404 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
;
412 * Reference variable (unary).
414 * @returns VINF_SUCCESS on success.
415 * @returns VBox evaluation / parsing error code on failure.
416 * The caller does the bitching.
417 * @param pDbgc Debugger console instance data.
418 * @param pArg The argument.
419 * @param pResult Where to store the result.
421 static DECLCALLBACK(int) dbgcOpVar(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
423 LogFlow(("dbgcOpVar: %s\n", pArg
->u
.pszString
));
424 AssertReturn(pArg
->enmType
== DBGCVAR_TYPE_SYMBOL
, VERR_DBGC_PARSE_BUG
);
427 * Lookup the variable.
429 const char *pszVar
= pArg
->u
.pszString
;
430 for (unsigned iVar
= 0; iVar
< pDbgc
->cVars
; iVar
++)
432 if (!strcmp(pszVar
, pDbgc
->papVars
[iVar
]->szName
))
434 *pResult
= pDbgc
->papVars
[iVar
]->Var
;
439 return VERR_DBGC_PARSE_VARIABLE_NOT_FOUND
;
444 * Reference register (unary).
446 * @returns VINF_SUCCESS on success.
447 * @returns VBox evaluation / parsing error code on failure.
448 * The caller does the bitching.
449 * @param pDbgc Debugger console instance data.
450 * @param pArg The argument.
451 * @param pResult Where to store the result.
453 DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
455 LogFlow(("dbgcOpRegister: %s\n", pArg
->u
.pszString
));
456 AssertReturn(pArg
->enmType
== DBGCVAR_TYPE_SYMBOL
, VERR_DBGC_PARSE_BUG
);
459 * If the desired result is a symbol, pass the argument along unmodified.
460 * This is a great help for "r @eax" and such, since it will be translated to "r eax".
462 if (enmCat
== DBGCVAR_CAT_SYMBOL
)
464 int rc
= DBGFR3RegNmValidate(pDbgc
->pVM
, pDbgc
->idCpu
, pArg
->u
.pszString
);
466 DBGCVAR_INIT_STRING(pResult
, pArg
->u
.pszString
);
473 DBGFREGVALTYPE enmType
;
475 int rc
= DBGFR3RegNmQuery(pDbgc
->pVM
, pDbgc
->idCpu
, pArg
->u
.pszString
, &Value
, &enmType
);
480 case DBGFREGVALTYPE_U8
:
481 DBGCVAR_INIT_NUMBER(pResult
, Value
.u8
);
484 case DBGFREGVALTYPE_U16
:
485 DBGCVAR_INIT_NUMBER(pResult
, Value
.u16
);
488 case DBGFREGVALTYPE_U32
:
489 DBGCVAR_INIT_NUMBER(pResult
, Value
.u32
);
492 case DBGFREGVALTYPE_U64
:
493 DBGCVAR_INIT_NUMBER(pResult
, Value
.u64
);
496 case DBGFREGVALTYPE_U128
:
497 DBGCVAR_INIT_NUMBER(pResult
, Value
.u128
.s
.Lo
);
500 case DBGFREGVALTYPE_R80
:
501 #ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
502 DBGCVAR_INIT_NUMBER(pResult
, (uint64_t)Value
.r80Ex
.lrd
);
504 DBGCVAR_INIT_NUMBER(pResult
, (uint64_t)Value
.r80Ex
.sj64
.u63Fraction
);
508 case DBGFREGVALTYPE_DTR
:
509 DBGCVAR_INIT_NUMBER(pResult
, Value
.dtr
.u64Base
);
512 case DBGFREGVALTYPE_INVALID
:
513 case DBGFREGVALTYPE_END
:
514 case DBGFREGVALTYPE_32BIT_HACK
:
517 rc
= VERR_INTERNAL_ERROR_5
;
524 * Flat address (unary).
526 * @returns VINF_SUCCESS on success.
527 * @returns VBox evaluation / parsing error code on failure.
528 * The caller does the bitching.
529 * @param pDbgc Debugger console instance data.
530 * @param pArg The argument.
531 * @param pResult Where to store the result.
533 DECLCALLBACK(int) dbgcOpAddrFlat(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
535 LogFlow(("dbgcOpAddrFlat\n"));
536 DBGCVARTYPE enmType
= DBGCVAR_ISHCPOINTER(pArg
->enmType
) ? DBGCVAR_TYPE_HC_FLAT
: DBGCVAR_TYPE_GC_FLAT
;
537 return DBGCCmdHlpConvert(&pDbgc
->CmdHlp
, pArg
, enmType
, true /*fConvSyms*/, pResult
);
542 * Physical address (unary).
544 * @returns VINF_SUCCESS on success.
545 * @returns VBox evaluation / parsing error code on failure.
546 * The caller does the bitching.
547 * @param pDbgc Debugger console instance data.
548 * @param pArg The argument.
549 * @param pResult Where to store the result.
551 DECLCALLBACK(int) dbgcOpAddrPhys(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
553 LogFlow(("dbgcOpAddrPhys\n"));
554 DBGCVARTYPE enmType
= DBGCVAR_ISHCPOINTER(pArg
->enmType
) ? DBGCVAR_TYPE_HC_PHYS
: DBGCVAR_TYPE_GC_PHYS
;
555 return DBGCCmdHlpConvert(&pDbgc
->CmdHlp
, pArg
, enmType
, true /*fConvSyms*/, pResult
);
560 * Physical host address (unary).
562 * @returns VINF_SUCCESS on success.
563 * @returns VBox evaluation / parsing error code on failure.
564 * The caller does the bitching.
565 * @param pDbgc Debugger console instance data.
566 * @param pArg The argument.
567 * @param pResult Where to store the result.
569 DECLCALLBACK(int) dbgcOpAddrHostPhys(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
571 LogFlow(("dbgcOpAddrPhys\n"));
572 return DBGCCmdHlpConvert(&pDbgc
->CmdHlp
, pArg
, DBGCVAR_TYPE_HC_PHYS
, true /*fConvSyms*/, pResult
);
577 * Host address (unary).
579 * @returns VINF_SUCCESS on success.
580 * @returns VBox evaluation / parsing error code on failure.
581 * The caller does the bitching.
582 * @param pDbgc Debugger console instance data.
583 * @param pArg The argument.
584 * @param pResult Where to store the result.
586 DECLCALLBACK(int) dbgcOpAddrHost(PDBGC pDbgc
, PCDBGCVAR pArg
, DBGCVARCAT enmCat
, PDBGCVAR pResult
)
588 LogFlow(("dbgcOpAddrHost\n"));
589 return DBGCCmdHlpConvert(&pDbgc
->CmdHlp
, pArg
, DBGCVAR_TYPE_HC_FLAT
, true /*fConvSyms*/, pResult
);
594 * Bitwise not (unary).
596 * @returns VINF_SUCCESS on success.
597 * @returns VBox evaluation / parsing error code on failure.
598 * The caller does the bitching.
599 * @param pDbgc Debugger console instance data.
600 * @param pArg The argument.
601 * @param pResult Where to store the result.
603 static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
605 LogFlow(("dbgcOpAddrFar\n"));
608 switch (pArg1
->enmType
)
610 case DBGCVAR_TYPE_SYMBOL
:
611 rc
= dbgcSymbolGet(pDbgc
, pArg1
->u
.pszString
, DBGCVAR_TYPE_NUMBER
, pResult
);
615 case DBGCVAR_TYPE_NUMBER
:
619 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
;
621 pResult
->u
.GCFar
.sel
= (RTSEL
)pResult
->u
.u64Number
;
623 /* common code for the two types we support. */
624 switch (pArg2
->enmType
)
626 case DBGCVAR_TYPE_GC_FLAT
:
627 pResult
->u
.GCFar
.off
= pArg2
->u
.GCFlat
;
628 pResult
->enmType
= DBGCVAR_TYPE_GC_FAR
;
631 case DBGCVAR_TYPE_HC_FLAT
:
632 pResult
->u
.pvHCFlat
= (void *)(uintptr_t)pArg2
->u
.GCFlat
;
633 pResult
->enmType
= DBGCVAR_TYPE_GC_FAR
;
636 case DBGCVAR_TYPE_NUMBER
:
637 pResult
->u
.GCFar
.off
= (RTGCPTR
)pArg2
->u
.u64Number
;
638 pResult
->enmType
= DBGCVAR_TYPE_GC_FAR
;
641 case DBGCVAR_TYPE_SYMBOL
:
644 rc
= dbgcSymbolGet(pDbgc
, pArg2
->u
.pszString
, DBGCVAR_TYPE_NUMBER
, &Var
);
647 pResult
->u
.GCFar
.off
= (RTGCPTR
)Var
.u
.u64Number
;
648 pResult
->enmType
= DBGCVAR_TYPE_GC_FAR
;
653 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE
;
661 * Multiplication operator (binary).
663 * @returns VINF_SUCCESS on success.
664 * @returns VBox evaluation / parsing error code on failure.
665 * The caller does the bitching.
666 * @param pDbgc Debugger console instance data.
667 * @param pArg1 The first argument.
668 * @param pArg2 The 2nd argument.
669 * @param pResult Where to store the result.
671 static DECLCALLBACK(int) dbgcOpMult(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
673 LogFlow(("dbgcOpMult\n"));
674 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1
, pArg2
);
675 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, *, false);
680 * Division operator (binary).
682 * @returns VINF_SUCCESS on success.
683 * @returns VBox evaluation / parsing error code on failure.
684 * The caller does the bitching.
685 * @param pDbgc Debugger console instance data.
686 * @param pArg1 The first argument.
687 * @param pArg2 The 2nd argument.
688 * @param pResult Where to store the result.
690 static DECLCALLBACK(int) dbgcOpDiv(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
692 LogFlow(("dbgcOpDiv\n"));
693 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, /, true);
698 * Modulus operator (binary).
700 * @returns VINF_SUCCESS on success.
701 * @returns VBox evaluation / parsing error code on failure.
702 * The caller does the bitching.
703 * @param pDbgc Debugger console instance data.
704 * @param pArg1 The first argument.
705 * @param pArg2 The 2nd argument.
706 * @param pResult Where to store the result.
708 static DECLCALLBACK(int) dbgcOpMod(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
710 LogFlow(("dbgcOpMod\n"));
711 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, %, false);
716 * Addition operator (binary).
718 * @returns VINF_SUCCESS on success.
719 * @returns VBox evaluation / parsing error code on failure.
720 * The caller does the bitching.
721 * @param pDbgc Debugger console instance data.
722 * @param pArg1 The first argument.
723 * @param pArg2 The 2nd argument.
724 * @param pResult Where to store the result.
726 static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
728 LogFlow(("dbgcOpAdd\n"));
731 * An addition operation will return (when possible) the left side type in the
732 * expression. We make an omission for numbers, where we'll take the right side
733 * type instead. An expression where only the left hand side is a symbol we'll
734 * use the right hand type to try resolve it.
736 if ( pArg1
->enmType
== DBGCVAR_TYPE_STRING
737 || pArg2
->enmType
== DBGCVAR_TYPE_STRING
)
738 return VERR_DBGC_PARSE_INVALID_OPERATION
; /** @todo string contactenation later. */
740 if ( (pArg1
->enmType
== DBGCVAR_TYPE_NUMBER
&& pArg2
->enmType
!= DBGCVAR_TYPE_SYMBOL
)
741 || (pArg1
->enmType
== DBGCVAR_TYPE_SYMBOL
&& pArg2
->enmType
!= DBGCVAR_TYPE_SYMBOL
))
743 PCDBGCVAR pTmp
= pArg2
;
749 if (pArg1
->enmType
== DBGCVAR_TYPE_SYMBOL
)
751 int rc
= dbgcSymbolGet(pDbgc
, pArg1
->u
.pszString
, DBGCVAR_TYPE_ANY
, &Sym1
);
756 rc
= dbgcSymbolGet(pDbgc
, pArg2
->u
.pszString
, DBGCVAR_TYPE_ANY
, &Sym2
);
765 switch (pArg1
->enmType
)
770 case DBGCVAR_TYPE_GC_FLAT
:
771 switch (pArg2
->enmType
)
773 case DBGCVAR_TYPE_HC_FLAT
:
774 case DBGCVAR_TYPE_HC_PHYS
:
775 return VERR_DBGC_PARSE_INVALID_OPERATION
;
778 rc
= dbgcOpAddrFlat(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var
);
781 pResult
->u
.GCFlat
+= pArg2
->u
.GCFlat
;
789 case DBGCVAR_TYPE_GC_FAR
:
790 switch (pArg2
->enmType
)
792 case DBGCVAR_TYPE_HC_FLAT
:
793 case DBGCVAR_TYPE_HC_PHYS
:
794 return VERR_DBGC_PARSE_INVALID_OPERATION
;
795 case DBGCVAR_TYPE_NUMBER
:
797 pResult
->u
.GCFar
.off
+= (RTGCPTR
)pArg2
->u
.u64Number
;
800 rc
= dbgcOpAddrFlat(pDbgc
, pArg1
, DBGCVAR_CAT_ANY
, pResult
);
803 rc
= dbgcOpAddrFlat(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var
);
806 pResult
->u
.GCFlat
+= pArg2
->u
.GCFlat
;
814 case DBGCVAR_TYPE_GC_PHYS
:
815 switch (pArg2
->enmType
)
817 case DBGCVAR_TYPE_HC_FLAT
:
818 case DBGCVAR_TYPE_HC_PHYS
:
819 return VERR_DBGC_PARSE_INVALID_OPERATION
;
822 rc
= dbgcOpAddrPhys(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var
);
825 if (Var
.enmType
!= DBGCVAR_TYPE_GC_PHYS
)
826 return VERR_DBGC_PARSE_INVALID_OPERATION
;
827 pResult
->u
.GCPhys
+= Var
.u
.GCPhys
;
835 case DBGCVAR_TYPE_HC_FLAT
:
837 rc
= dbgcOpAddrHost(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var2
);
840 rc
= dbgcOpAddrFlat(pDbgc
, &Var2
, DBGCVAR_CAT_ANY
, &Var
);
843 pResult
->u
.pvHCFlat
= (char *)pResult
->u
.pvHCFlat
+ (uintptr_t)Var
.u
.pvHCFlat
;
849 case DBGCVAR_TYPE_HC_PHYS
:
851 rc
= dbgcOpAddrHostPhys(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var
);
854 pResult
->u
.HCPhys
+= Var
.u
.HCPhys
;
858 * Numbers (see start of function)
860 case DBGCVAR_TYPE_NUMBER
:
862 switch (pArg2
->enmType
)
864 case DBGCVAR_TYPE_SYMBOL
:
865 rc
= dbgcSymbolGet(pDbgc
, pArg2
->u
.pszString
, DBGCVAR_TYPE_NUMBER
, &Var
);
868 case DBGCVAR_TYPE_NUMBER
:
869 pResult
->u
.u64Number
+= pArg2
->u
.u64Number
;
872 return VERR_DBGC_PARSE_INVALID_OPERATION
;
877 return VERR_DBGC_PARSE_INVALID_OPERATION
;
885 * Subtraction operator (binary).
887 * @returns VINF_SUCCESS on success.
888 * @returns VBox evaluation / parsing error code on failure.
889 * The caller does the bitching.
890 * @param pDbgc Debugger console instance data.
891 * @param pArg1 The first argument.
892 * @param pArg2 The 2nd argument.
893 * @param pResult Where to store the result.
895 static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
897 LogFlow(("dbgcOpSub\n"));
900 * An subtraction operation will return the left side type in the expression.
901 * However, if the left hand side is a number and the right hand a pointer of
902 * some kind we'll convert the left hand side to the same type as the right hand.
903 * Any symbols will be resolved, strings will be rejected.
906 if ( pArg2
->enmType
== DBGCVAR_TYPE_SYMBOL
907 && ( pArg1
->enmType
== DBGCVAR_TYPE_NUMBER
908 || pArg1
->enmType
== DBGCVAR_TYPE_SYMBOL
))
910 int rc
= dbgcSymbolGet(pDbgc
, pArg2
->u
.pszString
, DBGCVAR_TYPE_ANY
, &Sym2
);
916 if ( pArg1
->enmType
== DBGCVAR_TYPE_STRING
917 || pArg2
->enmType
== DBGCVAR_TYPE_STRING
)
918 return VERR_DBGC_PARSE_INVALID_OPERATION
;
920 if (pArg1
->enmType
== DBGCVAR_TYPE_SYMBOL
)
923 switch (pArg2
->enmType
)
925 case DBGCVAR_TYPE_NUMBER
:
926 enmType
= DBGCVAR_TYPE_ANY
;
928 case DBGCVAR_TYPE_GC_FLAT
:
929 case DBGCVAR_TYPE_GC_PHYS
:
930 case DBGCVAR_TYPE_HC_FLAT
:
931 case DBGCVAR_TYPE_HC_PHYS
:
932 enmType
= pArg2
->enmType
;
934 case DBGCVAR_TYPE_GC_FAR
:
935 enmType
= DBGCVAR_TYPE_GC_FLAT
;
937 default: AssertFailedReturn(VERR_DBGC_IPE
);
939 if (enmType
!= DBGCVAR_TYPE_STRING
)
941 int rc
= dbgcSymbolGet(pDbgc
, pArg1
->u
.pszString
, DBGCVAR_TYPE_ANY
, &Sym1
);
947 else if (pArg1
->enmType
== DBGCVAR_TYPE_NUMBER
)
949 PFNDBGCOPUNARY pOp
= NULL
;
950 switch (pArg2
->enmType
)
952 case DBGCVAR_TYPE_GC_FAR
:
953 case DBGCVAR_TYPE_GC_FLAT
:
954 pOp
= dbgcOpAddrFlat
;
956 case DBGCVAR_TYPE_GC_PHYS
:
957 pOp
= dbgcOpAddrPhys
;
959 case DBGCVAR_TYPE_HC_FLAT
:
960 pOp
= dbgcOpAddrHost
;
962 case DBGCVAR_TYPE_HC_PHYS
:
963 pOp
= dbgcOpAddrHostPhys
;
965 case DBGCVAR_TYPE_NUMBER
:
967 default: AssertFailedReturn(VERR_DBGC_IPE
);
971 int rc
= pOp(pDbgc
, pArg1
, DBGCVAR_CAT_ANY
, &Sym1
);
984 switch (pArg1
->enmType
)
989 case DBGCVAR_TYPE_GC_FLAT
:
990 switch (pArg2
->enmType
)
992 case DBGCVAR_TYPE_HC_FLAT
:
993 case DBGCVAR_TYPE_HC_PHYS
:
994 return VERR_DBGC_PARSE_INVALID_OPERATION
;
997 rc
= dbgcOpAddrFlat(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var
);
1000 pResult
->u
.GCFlat
-= pArg2
->u
.GCFlat
;
1008 case DBGCVAR_TYPE_GC_FAR
:
1009 switch (pArg2
->enmType
)
1011 case DBGCVAR_TYPE_HC_FLAT
:
1012 case DBGCVAR_TYPE_HC_PHYS
:
1013 return VERR_DBGC_PARSE_INVALID_OPERATION
;
1014 case DBGCVAR_TYPE_NUMBER
:
1016 pResult
->u
.GCFar
.off
-= (RTGCPTR
)pArg2
->u
.u64Number
;
1019 rc
= dbgcOpAddrFlat(pDbgc
, pArg1
, DBGCVAR_CAT_ANY
, pResult
);
1022 rc
= dbgcOpAddrFlat(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var
);
1025 pResult
->u
.GCFlat
-= pArg2
->u
.GCFlat
;
1033 case DBGCVAR_TYPE_GC_PHYS
:
1034 switch (pArg2
->enmType
)
1036 case DBGCVAR_TYPE_HC_FLAT
:
1037 case DBGCVAR_TYPE_HC_PHYS
:
1038 return VERR_DBGC_PARSE_INVALID_OPERATION
;
1041 rc
= dbgcOpAddrPhys(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var
);
1044 if (Var
.enmType
!= DBGCVAR_TYPE_GC_PHYS
)
1045 return VERR_DBGC_PARSE_INVALID_OPERATION
;
1046 pResult
->u
.GCPhys
-= Var
.u
.GCPhys
;
1054 case DBGCVAR_TYPE_HC_FLAT
:
1056 rc
= dbgcOpAddrHost(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var2
);
1059 rc
= dbgcOpAddrFlat(pDbgc
, &Var2
, DBGCVAR_CAT_ANY
, &Var
);
1062 pResult
->u
.pvHCFlat
= (char *)pResult
->u
.pvHCFlat
- (uintptr_t)Var
.u
.pvHCFlat
;
1068 case DBGCVAR_TYPE_HC_PHYS
:
1070 rc
= dbgcOpAddrHostPhys(pDbgc
, pArg2
, DBGCVAR_CAT_ANY
, &Var
);
1073 pResult
->u
.HCPhys
-= Var
.u
.HCPhys
;
1077 * Numbers (see start of function)
1079 case DBGCVAR_TYPE_NUMBER
:
1081 switch (pArg2
->enmType
)
1083 case DBGCVAR_TYPE_SYMBOL
:
1084 rc
= dbgcSymbolGet(pDbgc
, pArg2
->u
.pszString
, DBGCVAR_TYPE_NUMBER
, &Var
);
1087 case DBGCVAR_TYPE_NUMBER
:
1088 pResult
->u
.u64Number
-= pArg2
->u
.u64Number
;
1091 return VERR_DBGC_PARSE_INVALID_OPERATION
;
1096 return VERR_DBGC_PARSE_INVALID_OPERATION
;
1099 return VINF_SUCCESS
;
1104 * Bitwise shift left operator (binary).
1106 * @returns VINF_SUCCESS on success.
1107 * @returns VBox evaluation / parsing error code on failure.
1108 * The caller does the bitching.
1109 * @param pDbgc Debugger console instance data.
1110 * @param pArg1 The first argument.
1111 * @param pArg2 The 2nd argument.
1112 * @param pResult Where to store the result.
1114 static DECLCALLBACK(int) dbgcOpBitwiseShiftLeft(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1116 LogFlow(("dbgcOpBitwiseShiftLeft\n"));
1117 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, <<, false);
1122 * Bitwise shift right operator (binary).
1124 * @returns VINF_SUCCESS on success.
1125 * @returns VBox evaluation / parsing error code on failure.
1126 * The caller does the bitching.
1127 * @param pDbgc Debugger console instance data.
1128 * @param pArg1 The first argument.
1129 * @param pArg2 The 2nd argument.
1130 * @param pResult Where to store the result.
1132 static DECLCALLBACK(int) dbgcOpBitwiseShiftRight(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1134 LogFlow(("dbgcOpBitwiseShiftRight\n"));
1135 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, >>, false);
1140 * Bitwise and operator (binary).
1142 * @returns VINF_SUCCESS on success.
1143 * @returns VBox evaluation / parsing error code on failure.
1144 * The caller does the bitching.
1145 * @param pDbgc Debugger console instance data.
1146 * @param pArg1 The first argument.
1147 * @param pArg2 The 2nd argument.
1148 * @param pResult Where to store the result.
1150 static DECLCALLBACK(int) dbgcOpBitwiseAnd(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1152 LogFlow(("dbgcOpBitwiseAnd\n"));
1153 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1
, pArg2
);
1154 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, &, false);
1159 * Bitwise exclusive or operator (binary).
1161 * @returns VINF_SUCCESS on success.
1162 * @returns VBox evaluation / parsing error code on failure.
1163 * The caller does the bitching.
1164 * @param pDbgc Debugger console instance data.
1165 * @param pArg1 The first argument.
1166 * @param pArg2 The 2nd argument.
1167 * @param pResult Where to store the result.
1169 static DECLCALLBACK(int) dbgcOpBitwiseXor(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1171 LogFlow(("dbgcOpBitwiseXor\n"));
1172 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1
, pArg2
);
1173 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, ^, false);
1178 * Bitwise inclusive or operator (binary).
1180 * @returns VINF_SUCCESS on success.
1181 * @returns VBox evaluation / parsing error code on failure.
1182 * The caller does the bitching.
1183 * @param pDbgc Debugger console instance data.
1184 * @param pArg1 The first argument.
1185 * @param pArg2 The 2nd argument.
1186 * @param pResult Where to store the result.
1188 static DECLCALLBACK(int) dbgcOpBitwiseOr(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1190 LogFlow(("dbgcOpBitwiseOr\n"));
1191 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1
, pArg2
);
1192 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, |, false);
1197 * Boolean and operator (binary).
1199 * @returns VINF_SUCCESS on success.
1200 * @returns VBox evaluation / parsing error code on failure.
1201 * The caller does the bitching.
1202 * @param pDbgc Debugger console instance data.
1203 * @param pArg1 The first argument.
1204 * @param pArg2 The 2nd argument.
1205 * @param pResult Where to store the result.
1207 static DECLCALLBACK(int) dbgcOpBooleanAnd(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1209 LogFlow(("dbgcOpBooleanAnd\n"));
1210 /** @todo force numeric return value? */
1211 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, &&, false);
1216 * Boolean or operator (binary).
1218 * @returns VINF_SUCCESS on success.
1219 * @returns VBox evaluation / parsing error code on failure.
1220 * The caller does the bitching.
1221 * @param pDbgc Debugger console instance data.
1222 * @param pArg1 The first argument.
1223 * @param pArg2 The 2nd argument.
1224 * @param pResult Where to store the result.
1226 static DECLCALLBACK(int) dbgcOpBooleanOr(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1228 LogFlow(("dbgcOpBooleanOr\n"));
1229 /** @todo force numeric return value? */
1230 DBGC_GEN_ARIT_BINARY_OP(pDbgc
, pArg1
, pArg2
, pResult
, ||, false);
1235 * Range to operator (binary).
1237 * @returns VINF_SUCCESS on success.
1238 * @returns VBox evaluation / parsing error code on failure.
1239 * The caller does the bitching.
1240 * @param pDbgc Debugger console instance data.
1241 * @param pArg1 The first argument.
1242 * @param pArg2 The 2nd argument.
1243 * @param pResult Where to store the result.
1245 static DECLCALLBACK(int) dbgcOpRangeLength(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1247 LogFlow(("dbgcOpRangeLength\n"));
1249 if (pArg1
->enmType
== DBGCVAR_TYPE_STRING
)
1250 return VERR_DBGC_PARSE_INVALID_OPERATION
;
1253 * Make result. Symbols needs to be resolved.
1255 if (pArg1
->enmType
== DBGCVAR_TYPE_SYMBOL
)
1257 int rc
= dbgcSymbolGet(pDbgc
, pArg1
->u
.pszString
, DBGCVAR_TYPE_ANY
, pResult
);
1265 * Convert 2nd argument to element count.
1267 pResult
->enmRangeType
= DBGCVAR_RANGE_ELEMENTS
;
1268 switch (pArg2
->enmType
)
1270 case DBGCVAR_TYPE_NUMBER
:
1271 pResult
->u64Range
= pArg2
->u
.u64Number
;
1274 case DBGCVAR_TYPE_SYMBOL
:
1276 int rc
= dbgcSymbolGet(pDbgc
, pArg2
->u
.pszString
, DBGCVAR_TYPE_NUMBER
, pResult
);
1279 pResult
->u64Range
= pArg2
->u
.u64Number
;
1283 case DBGCVAR_TYPE_STRING
:
1285 return VERR_DBGC_PARSE_INVALID_OPERATION
;
1288 return VINF_SUCCESS
;
1293 * Range to operator (binary).
1295 * @returns VINF_SUCCESS on success.
1296 * @returns VBox evaluation / parsing error code on failure.
1297 * The caller does the bitching.
1298 * @param pDbgc Debugger console instance data.
1299 * @param pArg1 The first argument.
1300 * @param pArg2 The 2nd argument.
1301 * @param pResult Where to store the result.
1303 static DECLCALLBACK(int) dbgcOpRangeLengthBytes(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1305 LogFlow(("dbgcOpRangeLengthBytes\n"));
1306 int rc
= dbgcOpRangeLength(pDbgc
, pArg1
, pArg2
, pResult
);
1308 pResult
->enmRangeType
= DBGCVAR_RANGE_BYTES
;
1314 * Range to operator (binary).
1316 * @returns VINF_SUCCESS on success.
1317 * @returns VBox evaluation / parsing error code on failure.
1318 * The caller does the bitching.
1319 * @param pDbgc Debugger console instance data.
1320 * @param pArg1 The first argument.
1321 * @param pArg2 The 2nd argument.
1322 * @param pResult Where to store the result.
1324 static DECLCALLBACK(int) dbgcOpRangeTo(PDBGC pDbgc
, PCDBGCVAR pArg1
, PCDBGCVAR pArg2
, PDBGCVAR pResult
)
1326 LogFlow(("dbgcOpRangeTo\n"));
1329 * Calc number of bytes between the two args.
1332 int rc
= dbgcOpSub(pDbgc
, pArg2
, pArg1
, &Diff
);
1337 * Use the diff as the range of Arg1.
1340 pResult
->enmRangeType
= DBGCVAR_RANGE_BYTES
;
1341 switch (Diff
.enmType
)
1343 case DBGCVAR_TYPE_GC_FLAT
:
1344 pResult
->u64Range
= (RTGCUINTPTR
)Diff
.u
.GCFlat
;
1346 case DBGCVAR_TYPE_GC_PHYS
:
1347 pResult
->u64Range
= Diff
.u
.GCPhys
;
1349 case DBGCVAR_TYPE_HC_FLAT
:
1350 pResult
->u64Range
= (uintptr_t)Diff
.u
.pvHCFlat
;
1352 case DBGCVAR_TYPE_HC_PHYS
:
1353 pResult
->u64Range
= Diff
.u
.HCPhys
;
1355 case DBGCVAR_TYPE_NUMBER
:
1356 pResult
->u64Range
= Diff
.u
.u64Number
;
1359 case DBGCVAR_TYPE_GC_FAR
:
1360 case DBGCVAR_TYPE_STRING
:
1361 case DBGCVAR_TYPE_SYMBOL
:
1363 AssertMsgFailed(("Impossible!\n"));
1364 return VERR_DBGC_PARSE_INVALID_OPERATION
;
1367 return VINF_SUCCESS
;
1372 * Searches for an operator descriptor which matches the start of
1373 * the expression given us.
1375 * @returns Pointer to the operator on success.
1376 * @param pDbgc The debug console instance.
1377 * @param pszExpr Pointer to the expression string which might start with an operator.
1378 * @param fPreferBinary Whether to favour binary or unary operators.
1379 * Caller must assert that it's the desired type! Both types will still
1380 * be returned, this is only for resolving duplicates.
1381 * @param chPrev The previous char. Some operators requires a blank in front of it.
1383 PCDBGCOP
dbgcOperatorLookup(PDBGC pDbgc
, const char *pszExpr
, bool fPreferBinary
, char chPrev
)
1385 PCDBGCOP pOp
= NULL
;
1386 for (unsigned iOp
= 0; iOp
< RT_ELEMENTS(g_aDbgcOps
); iOp
++)
1388 if ( g_aDbgcOps
[iOp
].szName
[0] == pszExpr
[0]
1389 && (!g_aDbgcOps
[iOp
].szName
[1] || g_aDbgcOps
[iOp
].szName
[1] == pszExpr
[1])
1390 && (!g_aDbgcOps
[iOp
].szName
[2] || g_aDbgcOps
[iOp
].szName
[2] == pszExpr
[2]))
1393 * Check that we don't mistake it for some other operator which have more chars.
1396 for (j
= iOp
+ 1; j
< RT_ELEMENTS(g_aDbgcOps
); j
++)
1397 if ( g_aDbgcOps
[j
].cchName
> g_aDbgcOps
[iOp
].cchName
1398 && g_aDbgcOps
[j
].szName
[0] == pszExpr
[0]
1399 && (!g_aDbgcOps
[j
].szName
[1] || g_aDbgcOps
[j
].szName
[1] == pszExpr
[1])
1400 && (!g_aDbgcOps
[j
].szName
[2] || g_aDbgcOps
[j
].szName
[2] == pszExpr
[2]) )
1402 if (j
< RT_ELEMENTS(g_aDbgcOps
))
1403 continue; /* we'll catch it later. (for theoretical +,++,+++ cases.) */
1404 pOp
= &g_aDbgcOps
[iOp
];
1409 if (g_aDbgcOps
[iOp
].fBinary
== fPreferBinary
)
1415 Log2(("dbgcOperatorLookup: pOp=%p %s\n", pOp
, pOp
->szName
));
1416 NOREF(pDbgc
); NOREF(chPrev
);