VirtualBox

source: vbox/trunk/src/VBox/Debugger/DBGCOps.cpp@ 35490

Last change on this file since 35490 was 35490, checked in by vboxsync, 14 years ago

CPUM,Debugger: Registers, still some details left.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 59.9 KB
Line 
1/* $Id: DBGCOps.cpp 35490 2011-01-11 15:17:10Z vboxsync $ */
2/** @file
3 * DBGC - Debugger Console, Operators.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_DBGC
23#include <VBox/dbg.h>
24#include <VBox/vmm/dbgf.h>
25#include <VBox/vmm/vm.h>
26#include <VBox/vmm/vmm.h>
27#include <VBox/vmm/mm.h>
28#include <VBox/vmm/pgm.h>
29#include <VBox/vmm/selm.h>
30#include <VBox/dis.h>
31#include <VBox/param.h>
32#include <VBox/err.h>
33#include <VBox/log.h>
34
35#include <iprt/alloc.h>
36#include <iprt/alloca.h>
37#include <iprt/string.h>
38#include <iprt/assert.h>
39#include <iprt/ctype.h>
40
41#include <stdlib.h>
42#include <stdio.h>
43
44#include "DBGCInternal.h"
45
46
47/*******************************************************************************
48* Internal Functions *
49*******************************************************************************/
50static DECLCALLBACK(int) dbgcOpMinus(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
51static DECLCALLBACK(int) dbgcOpPluss(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
52static DECLCALLBACK(int) dbgcOpBooleanNot(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
53static DECLCALLBACK(int) dbgcOpBitwiseNot(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
54static DECLCALLBACK(int) dbgcOpVar(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
55static DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult);
56
57static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
58static DECLCALLBACK(int) dbgcOpMult(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
59static DECLCALLBACK(int) dbgcOpDiv(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
60static DECLCALLBACK(int) dbgcOpMod(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
61static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
62static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
63static DECLCALLBACK(int) dbgcOpBitwiseShiftLeft(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
64static DECLCALLBACK(int) dbgcOpBitwiseShiftRight(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
65static DECLCALLBACK(int) dbgcOpBitwiseAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
66static DECLCALLBACK(int) dbgcOpBitwiseXor(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
67static DECLCALLBACK(int) dbgcOpBitwiseOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
68static DECLCALLBACK(int) dbgcOpBooleanAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
69static DECLCALLBACK(int) dbgcOpBooleanOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
70static DECLCALLBACK(int) dbgcOpRangeLength(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
71static DECLCALLBACK(int) dbgcOpRangeLengthBytes(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
72static DECLCALLBACK(int) dbgcOpRangeTo(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
73
74
75/*******************************************************************************
76* Defined Constants And Macros *
77*******************************************************************************/
78/**
79 * Generic implementation of a binary operator.
80 *
81 * @returns VINF_SUCCESS on success.
82 * @returns VBox evaluation / parsing error code on failure.
83 * The caller does the bitching.
84 * @param pDbgc Debugger console instance data.
85 * @param pArg1 The first argument.
86 * @param pArg2 The 2nd argument.
87 * @param pResult Where to store the result.
88 * @param Operator The C operator.
89 * @param fIsDiv Set if it's division and we need to check for zero on the
90 * right hand side.
91 */
92#define DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, Operator, fIsDiv) \
93 do \
94 { \
95 /* Get the 64-bit right side value. */ \
96 uint64_t u64Right; \
97 int rc = dbgcOpHelperGetNumber((pDbgc), (pArg2), &u64Right); \
98 if ((fIsDiv) && RT_SUCCESS(rc) && !u64Right) /* div/0 kludge */ \
99 DBGCVAR_INIT_NUMBER((pResult), UINT64_MAX); \
100 else if (RT_SUCCESS(rc)) \
101 { \
102 /* Apply it to the left hand side. */ \
103 if ( (pArg1)->enmType == DBGCVAR_TYPE_SYMBOL \
104 || (pArg1)->enmType == DBGCVAR_TYPE_STRING) \
105 { \
106 rc = dbgcSymbolGet((pDbgc), (pArg1)->u.pszString, DBGCVAR_TYPE_ANY, (pResult)); \
107 if (RT_FAILURE(rc)) \
108 return rc; \
109 } \
110 else \
111 *(pResult) = *(pArg1); \
112 switch ((pResult)->enmType) \
113 { \
114 case DBGCVAR_TYPE_GC_FLAT: \
115 (pResult)->u.GCFlat = (pResult)->u.GCFlat Operator u64Right; \
116 break; \
117 case DBGCVAR_TYPE_GC_FAR: \
118 (pResult)->u.GCFar.off = (pResult)->u.GCFar.off Operator u64Right; \
119 break; \
120 case DBGCVAR_TYPE_GC_PHYS: \
121 (pResult)->u.GCPhys = (pResult)->u.GCPhys Operator u64Right; \
122 break; \
123 case DBGCVAR_TYPE_HC_FLAT: \
124 (pResult)->u.pvHCFlat = (void *)((uintptr_t)(pResult)->u.pvHCFlat Operator u64Right); \
125 break; \
126 case DBGCVAR_TYPE_HC_FAR: \
127 (pResult)->u.HCFar.off = (pResult)->u.HCFar.off Operator u64Right; \
128 break; \
129 case DBGCVAR_TYPE_HC_PHYS: \
130 (pResult)->u.HCPhys = (pResult)->u.HCPhys Operator u64Right; \
131 break; \
132 case DBGCVAR_TYPE_NUMBER: \
133 (pResult)->u.u64Number = (pResult)->u.u64Number Operator u64Right; \
134 break; \
135 default: \
136 return VERR_PARSE_INCORRECT_ARG_TYPE; \
137 } \
138 } \
139 return rc; \
140 } while (0)
141
142
143/**
144 * Switch the factors/whatever so we preserve pointers.
145 * Far pointers are considered more important that physical and flat pointers.
146 *
147 * @param pArg1 The left side argument. Input & output.
148 * @param pArg2 The right side argument. Input & output.
149 */
150#define DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2) \
151 do \
152 { \
153 if ( DBGCVAR_ISPOINTER((pArg2)->enmType) \
154 && ( !DBGCVAR_ISPOINTER((pArg1)->enmType) \
155 || ( DBGCVAR_IS_FAR_PTR((pArg2)->enmType) \
156 && !DBGCVAR_IS_FAR_PTR((pArg1)->enmType)))) \
157 { \
158 PCDBGCVAR pTmp = (pArg1); \
159 (pArg2) = (pArg1); \
160 (pArg1) = pTmp; \
161 } \
162 } while (0)
163
164
165/*******************************************************************************
166* Global Variables *
167*******************************************************************************/
168/** Operators. */
169const DBGCOP g_aOps[] =
170{
171 /* 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). */
172 /* szName, cchName, fBinary, iPrecedence, pfnHandlerUnary, pfnHandlerBitwise */
173 { {'-'}, 1, false, 1, dbgcOpMinus, NULL, "Unary minus." },
174 { {'+'}, 1, false, 1, dbgcOpPluss, NULL, "Unary plus." },
175 { {'!'}, 1, false, 1, dbgcOpBooleanNot, NULL, "Boolean not." },
176 { {'~'}, 1, false, 1, dbgcOpBitwiseNot, NULL, "Bitwise complement." },
177 { {':'}, 1, true, 2, NULL, dbgcOpAddrFar, "Far pointer." },
178 { {'%'}, 1, false, 3, dbgcOpAddrFlat, NULL, "Flat address." },
179 { {'%','%'}, 2, false, 3, dbgcOpAddrPhys, NULL, "Physical address." },
180 { {'#'}, 1, false, 3, dbgcOpAddrHost, NULL, "Flat host address." },
181 { {'#','%','%'}, 3, false, 3, dbgcOpAddrHostPhys, NULL, "Physical host address." },
182 { {'$'}, 1, false, 3, dbgcOpVar, NULL, "Reference a variable." },
183 { {'@'}, 1, false, 3, dbgcOpRegister, NULL, "Reference a register." },
184 { {'*'}, 1, true, 10, NULL, dbgcOpMult, "Multiplication." },
185 { {'/'}, 1, true, 11, NULL, dbgcOpDiv, "Division." },
186 { {'%'}, 1, true, 12, NULL, dbgcOpMod, "Modulus." },
187 { {'+'}, 1, true, 13, NULL, dbgcOpAdd, "Addition." },
188 { {'-'}, 1, true, 14, NULL, dbgcOpSub, "Subtraction." },
189 { {'<','<'}, 2, true, 15, NULL, dbgcOpBitwiseShiftLeft, "Bitwise left shift." },
190 { {'>','>'}, 2, true, 16, NULL, dbgcOpBitwiseShiftRight, "Bitwise right shift." },
191 { {'&'}, 1, true, 17, NULL, dbgcOpBitwiseAnd, "Bitwise and." },
192 { {'^'}, 1, true, 18, NULL, dbgcOpBitwiseXor, "Bitwise exclusiv or." },
193 { {'|'}, 1, true, 19, NULL, dbgcOpBitwiseOr, "Bitwise inclusive or." },
194 { {'&','&'}, 2, true, 20, NULL, dbgcOpBooleanAnd, "Boolean and." },
195 { {'|','|'}, 2, true, 21, NULL, dbgcOpBooleanOr, "Boolean or." },
196 { {'L'}, 1, true, 22, NULL, dbgcOpRangeLength, "Range elements." },
197 { {'L','B'}, 2, true, 23, NULL, dbgcOpRangeLengthBytes, "Range bytes." },
198 { {'T'}, 1, true, 24, NULL, dbgcOpRangeTo, "Range to." }
199};
200
201/** Number of operators in the operator array. */
202const unsigned g_cOps = RT_ELEMENTS(g_aOps);
203
204
205/**
206 * Converts an argument to a number value.
207 *
208 * @returns VBox status code.
209 * @param pDbgc The DBGC instance.
210 * @param pArg The argument to convert.
211 * @param pu64Ret Where to return the value.
212 */
213static int dbgcOpHelperGetNumber(PDBGC pDbgc, PCDBGCVAR pArg, uint64_t *pu64Ret)
214{
215 DBGCVAR Var = *pArg;
216 switch (Var.enmType)
217 {
218 case DBGCVAR_TYPE_GC_FLAT:
219 *pu64Ret = Var.u.GCFlat;
220 break;
221 case DBGCVAR_TYPE_GC_FAR:
222 *pu64Ret = Var.u.GCFar.off;
223 break;
224 case DBGCVAR_TYPE_GC_PHYS:
225 *pu64Ret = Var.u.GCPhys;
226 break;
227 case DBGCVAR_TYPE_HC_FLAT:
228 *pu64Ret = (uintptr_t)Var.u.pvHCFlat;
229 break;
230 case DBGCVAR_TYPE_HC_FAR:
231 *pu64Ret = Var.u.HCFar.off;
232 break;
233 case DBGCVAR_TYPE_HC_PHYS:
234 *pu64Ret = Var.u.HCPhys;
235 break;
236 case DBGCVAR_TYPE_STRING:
237 case DBGCVAR_TYPE_SYMBOL:
238 {
239 int rc = dbgcSymbolGet(pDbgc, Var.u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
240 if (RT_FAILURE(rc))
241 return rc;
242 /* fall thru */
243 }
244 case DBGCVAR_TYPE_NUMBER:
245 *pu64Ret = Var.u.u64Number;
246 break;
247 default:
248 return VERR_PARSE_INCORRECT_ARG_TYPE;
249 }
250 return VINF_SUCCESS;
251}
252
253
254/**
255 * Minus (unary).
256 *
257 * @returns VINF_SUCCESS on success.
258 * @returns VBox evaluation / parsing error code on failure.
259 * The caller does the bitching.
260 * @param pDbgc Debugger console instance data.
261 * @param pArg The argument.
262 * @param pResult Where to store the result.
263 */
264static DECLCALLBACK(int) dbgcOpMinus(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
265{
266 LogFlow(("dbgcOpMinus\n"));
267 *pResult = *pArg;
268 switch (pArg->enmType)
269 {
270 case DBGCVAR_TYPE_GC_FLAT:
271 pResult->u.GCFlat = -(RTGCINTPTR)pResult->u.GCFlat;
272 break;
273 case DBGCVAR_TYPE_GC_FAR:
274 pResult->u.GCFar.off = -(int32_t)pResult->u.GCFar.off;
275 break;
276 case DBGCVAR_TYPE_GC_PHYS:
277 pResult->u.GCPhys = (RTGCPHYS) -(int64_t)pResult->u.GCPhys;
278 break;
279 case DBGCVAR_TYPE_HC_FLAT:
280 pResult->u.pvHCFlat = (void *) -(intptr_t)pResult->u.pvHCFlat;
281 break;
282 case DBGCVAR_TYPE_HC_FAR:
283 pResult->u.HCFar.off = -(int32_t)pResult->u.HCFar.off;
284 break;
285 case DBGCVAR_TYPE_HC_PHYS:
286 pResult->u.HCPhys = (RTHCPHYS) -(int64_t)pResult->u.HCPhys;
287 break;
288 case DBGCVAR_TYPE_NUMBER:
289 pResult->u.u64Number = -(int64_t)pResult->u.u64Number;
290 break;
291
292 case DBGCVAR_TYPE_UNKNOWN:
293 case DBGCVAR_TYPE_STRING:
294 default:
295 return VERR_PARSE_INCORRECT_ARG_TYPE;
296 }
297 NOREF(pDbgc);
298 return VINF_SUCCESS;
299}
300
301
302/**
303 * Plus (unary).
304 *
305 * @returns VINF_SUCCESS on success.
306 * @returns VBox evaluation / parsing error code on failure.
307 * The caller does the bitching.
308 * @param pDbgc Debugger console instance data.
309 * @param pArg The argument.
310 * @param pResult Where to store the result.
311 */
312static DECLCALLBACK(int) dbgcOpPluss(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
313{
314 LogFlow(("dbgcOpPluss\n"));
315 *pResult = *pArg;
316 switch (pArg->enmType)
317 {
318 case DBGCVAR_TYPE_GC_FLAT:
319 case DBGCVAR_TYPE_GC_FAR:
320 case DBGCVAR_TYPE_GC_PHYS:
321 case DBGCVAR_TYPE_HC_FLAT:
322 case DBGCVAR_TYPE_HC_FAR:
323 case DBGCVAR_TYPE_HC_PHYS:
324 case DBGCVAR_TYPE_NUMBER:
325 break;
326
327 case DBGCVAR_TYPE_UNKNOWN:
328 case DBGCVAR_TYPE_STRING:
329 default:
330 return VERR_PARSE_INCORRECT_ARG_TYPE;
331 }
332 NOREF(pDbgc);
333 return VINF_SUCCESS;
334}
335
336
337/**
338 * Boolean not (unary).
339 *
340 * @returns VINF_SUCCESS on success.
341 * @returns VBox evaluation / parsing error code on failure.
342 * The caller does the bitching.
343 * @param pDbgc Debugger console instance data.
344 * @param pArg The argument.
345 * @param pResult Where to store the result.
346 */
347static DECLCALLBACK(int) dbgcOpBooleanNot(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
348{
349 LogFlow(("dbgcOpBooleanNot\n"));
350 *pResult = *pArg;
351 switch (pArg->enmType)
352 {
353 case DBGCVAR_TYPE_GC_FLAT:
354 pResult->u.u64Number = !pResult->u.GCFlat;
355 break;
356 case DBGCVAR_TYPE_GC_FAR:
357 pResult->u.u64Number = !pResult->u.GCFar.off && pResult->u.GCFar.sel <= 3;
358 break;
359 case DBGCVAR_TYPE_GC_PHYS:
360 pResult->u.u64Number = !pResult->u.GCPhys;
361 break;
362 case DBGCVAR_TYPE_HC_FLAT:
363 pResult->u.u64Number = !pResult->u.pvHCFlat;
364 break;
365 case DBGCVAR_TYPE_HC_FAR:
366 pResult->u.u64Number = !pResult->u.HCFar.off && pResult->u.HCFar.sel <= 3;
367 break;
368 case DBGCVAR_TYPE_HC_PHYS:
369 pResult->u.u64Number = !pResult->u.HCPhys;
370 break;
371 case DBGCVAR_TYPE_NUMBER:
372 pResult->u.u64Number = !pResult->u.u64Number;
373 break;
374 case DBGCVAR_TYPE_STRING:
375 pResult->u.u64Number = !pResult->u64Range;
376 break;
377
378 case DBGCVAR_TYPE_UNKNOWN:
379 default:
380 return VERR_PARSE_INCORRECT_ARG_TYPE;
381 }
382 pResult->enmType = DBGCVAR_TYPE_NUMBER;
383 NOREF(pDbgc);
384 return VINF_SUCCESS;
385}
386
387
388/**
389 * Bitwise not (unary).
390 *
391 * @returns VINF_SUCCESS on success.
392 * @returns VBox evaluation / parsing error code on failure.
393 * The caller does the bitching.
394 * @param pDbgc Debugger console instance data.
395 * @param pArg The argument.
396 * @param pResult Where to store the result.
397 */
398static DECLCALLBACK(int) dbgcOpBitwiseNot(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
399{
400 LogFlow(("dbgcOpBitwiseNot\n"));
401 *pResult = *pArg;
402 switch (pArg->enmType)
403 {
404 case DBGCVAR_TYPE_GC_FLAT:
405 pResult->u.GCFlat = ~pResult->u.GCFlat;
406 break;
407 case DBGCVAR_TYPE_GC_FAR:
408 pResult->u.GCFar.off = ~pResult->u.GCFar.off;
409 break;
410 case DBGCVAR_TYPE_GC_PHYS:
411 pResult->u.GCPhys = ~pResult->u.GCPhys;
412 break;
413 case DBGCVAR_TYPE_HC_FLAT:
414 pResult->u.pvHCFlat = (void *)~(uintptr_t)pResult->u.pvHCFlat;
415 break;
416 case DBGCVAR_TYPE_HC_FAR:
417 pResult->u.HCFar.off= ~pResult->u.HCFar.off;
418 break;
419 case DBGCVAR_TYPE_HC_PHYS:
420 pResult->u.HCPhys = ~pResult->u.HCPhys;
421 break;
422 case DBGCVAR_TYPE_NUMBER:
423 pResult->u.u64Number = ~pResult->u.u64Number;
424 break;
425
426 case DBGCVAR_TYPE_UNKNOWN:
427 case DBGCVAR_TYPE_STRING:
428 default:
429 return VERR_PARSE_INCORRECT_ARG_TYPE;
430 }
431 NOREF(pDbgc);
432 return VINF_SUCCESS;
433}
434
435
436/**
437 * Reference variable (unary).
438 *
439 * @returns VINF_SUCCESS on success.
440 * @returns VBox evaluation / parsing error code on failure.
441 * The caller does the bitching.
442 * @param pDbgc Debugger console instance data.
443 * @param pArg The argument.
444 * @param pResult Where to store the result.
445 */
446static DECLCALLBACK(int) dbgcOpVar(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
447{
448 LogFlow(("dbgcOpVar: %s\n", pArg->u.pszString));
449
450 /*
451 * Parse sanity.
452 */
453 if (pArg->enmType != DBGCVAR_TYPE_STRING)
454 return VERR_PARSE_INCORRECT_ARG_TYPE;
455
456 /*
457 * Lookup the variable.
458 */
459 const char *pszVar = pArg->u.pszString;
460 for (unsigned iVar = 0; iVar < pDbgc->cVars; iVar++)
461 {
462 if (!strcmp(pszVar, pDbgc->papVars[iVar]->szName))
463 {
464 *pResult = pDbgc->papVars[iVar]->Var;
465 return VINF_SUCCESS;
466 }
467 }
468
469 return VERR_PARSE_VARIABLE_NOT_FOUND;
470}
471
472
473/**
474 * Reference register (unary).
475 *
476 * @returns VINF_SUCCESS on success.
477 * @returns VBox evaluation / parsing error code on failure.
478 * The caller does the bitching.
479 * @param pDbgc Debugger console instance data.
480 * @param pArg The argument.
481 * @param pResult Where to store the result.
482 */
483static DECLCALLBACK(int) dbgcOpRegister(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
484{
485 LogFlow(("dbgcOpRegister: %s\n", pArg->u.pszString));
486
487 /*
488 * Parse sanity.
489 */
490 if (pArg->enmType != DBGCVAR_TYPE_STRING)
491 return VERR_PARSE_INCORRECT_ARG_TYPE;
492
493 /*
494 * Get the register.
495 */
496 DBGFREGVALTYPE enmType;
497 DBGFREGVAL Value;
498 int rc = DBGFR3RegNmQuery(pDbgc->pVM, pDbgc->idCpu, pArg->u.pszString, &Value, &enmType);
499 if (RT_SUCCESS(rc))
500 {
501 rc = VERR_INTERNAL_ERROR_5;
502 switch (enmType)
503 {
504 case DBGFREGVALTYPE_U8:
505 DBGCVAR_INIT_NUMBER(pResult, Value.u8);
506 return VINF_SUCCESS;
507
508 case DBGFREGVALTYPE_U16:
509 DBGCVAR_INIT_NUMBER(pResult, Value.u16);
510 return VINF_SUCCESS;
511
512 case DBGFREGVALTYPE_U32:
513 DBGCVAR_INIT_NUMBER(pResult, Value.u32);
514 return VINF_SUCCESS;
515
516 case DBGFREGVALTYPE_U64:
517 DBGCVAR_INIT_NUMBER(pResult, Value.u64);
518 return VINF_SUCCESS;
519
520 case DBGFREGVALTYPE_U128:
521 DBGCVAR_INIT_NUMBER(pResult, Value.u128.s.Lo);
522 return VINF_SUCCESS;
523
524 case DBGFREGVALTYPE_LRD:
525 DBGCVAR_INIT_NUMBER(pResult, (uint64_t)Value.lrd);
526 return VINF_SUCCESS;
527
528 case DBGFREGVALTYPE_DTR:
529 DBGCVAR_INIT_NUMBER(pResult, Value.dtr.u64Base);
530 return VINF_SUCCESS;
531
532 case DBGFREGVALTYPE_INVALID:
533 case DBGFREGVALTYPE_END:
534 case DBGFREGVALTYPE_32BIT_HACK:
535 break;
536 }
537 }
538 return rc;
539}
540
541
542/**
543 * Flat address (unary).
544 *
545 * @returns VINF_SUCCESS on success.
546 * @returns VBox evaluation / parsing error code on failure.
547 * The caller does the bitching.
548 * @param pDbgc Debugger console instance data.
549 * @param pArg The argument.
550 * @param pResult Where to store the result.
551 */
552DECLCALLBACK(int) dbgcOpAddrFlat(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
553{
554 LogFlow(("dbgcOpAddrFlat\n"));
555 int rc;
556 *pResult = *pArg;
557
558 switch (pArg->enmType)
559 {
560 case DBGCVAR_TYPE_GC_FLAT:
561 return VINF_SUCCESS;
562
563 case DBGCVAR_TYPE_GC_FAR:
564 {
565 Assert(pDbgc->pVM);
566 DBGFADDRESS Address;
567 rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
568 if (RT_SUCCESS(rc))
569 {
570 pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
571 pResult->u.GCFlat = Address.FlatPtr;
572 return VINF_SUCCESS;
573 }
574 return VERR_PARSE_CONVERSION_FAILED;
575 }
576
577 case DBGCVAR_TYPE_GC_PHYS:
578 //rc = MMR3PhysGCPhys2GCVirtEx(pDbgc->pVM, pResult->u.GCPhys, ..., &pResult->u.GCFlat); - yea, sure.
579 return VERR_PARSE_INCORRECT_ARG_TYPE;
580
581 case DBGCVAR_TYPE_HC_FLAT:
582 return VINF_SUCCESS;
583
584 case DBGCVAR_TYPE_HC_FAR:
585 return VERR_PARSE_INCORRECT_ARG_TYPE;
586
587 case DBGCVAR_TYPE_HC_PHYS:
588 Assert(pDbgc->pVM);
589 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
590 rc = MMR3HCPhys2HCVirt(pDbgc->pVM, pResult->u.HCPhys, &pResult->u.pvHCFlat);
591 if (RT_SUCCESS(rc))
592 return VINF_SUCCESS;
593 return VERR_PARSE_CONVERSION_FAILED;
594
595 case DBGCVAR_TYPE_NUMBER:
596 pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
597 pResult->u.GCFlat = (RTGCPTR)pResult->u.u64Number;
598 return VINF_SUCCESS;
599
600 case DBGCVAR_TYPE_STRING:
601 return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, pResult);
602
603 case DBGCVAR_TYPE_UNKNOWN:
604 default:
605 return VERR_PARSE_INCORRECT_ARG_TYPE;
606 }
607}
608
609
610/**
611 * Physical address (unary).
612 *
613 * @returns VINF_SUCCESS on success.
614 * @returns VBox evaluation / parsing error code on failure.
615 * The caller does the bitching.
616 * @param pDbgc Debugger console instance data.
617 * @param pArg The argument.
618 * @param pResult Where to store the result.
619 */
620DECLCALLBACK(int) dbgcOpAddrPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
621{
622 LogFlow(("dbgcOpAddrPhys\n"));
623 int rc;
624 DBGFADDRESS Address;
625
626 *pResult = *pArg;
627 switch (pArg->enmType)
628 {
629 case DBGCVAR_TYPE_GC_FLAT:
630 Assert(pDbgc->pVM);
631 pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
632 rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu,
633 DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
634 &pResult->u.GCPhys);
635 if (RT_SUCCESS(rc))
636 return VINF_SUCCESS;
637 return VERR_PARSE_CONVERSION_FAILED;
638
639 case DBGCVAR_TYPE_GC_FAR:
640 Assert(pDbgc->pVM);
641 rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
642 if (RT_SUCCESS(rc))
643 {
644 pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
645 rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
646 if (RT_SUCCESS(rc))
647 return VINF_SUCCESS;
648 }
649 return VERR_PARSE_CONVERSION_FAILED;
650
651 case DBGCVAR_TYPE_GC_PHYS:
652 return VINF_SUCCESS;
653
654 case DBGCVAR_TYPE_HC_FLAT:
655 Assert(pDbgc->pVM);
656 pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
657 rc = PGMR3DbgR3Ptr2GCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.GCPhys);
658 if (RT_SUCCESS(rc))
659 return VINF_SUCCESS;
660 /** @todo more memory types! */
661 return VERR_PARSE_CONVERSION_FAILED;
662
663 case DBGCVAR_TYPE_HC_FAR:
664 return VERR_PARSE_INCORRECT_ARG_TYPE;
665
666 case DBGCVAR_TYPE_HC_PHYS:
667 return VINF_SUCCESS;
668
669 case DBGCVAR_TYPE_NUMBER:
670 pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
671 pResult->u.GCPhys = (RTGCPHYS)pResult->u.u64Number;
672 return VINF_SUCCESS;
673
674 case DBGCVAR_TYPE_STRING:
675 return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_PHYS, pResult);
676
677 case DBGCVAR_TYPE_UNKNOWN:
678 default:
679 return VERR_PARSE_INCORRECT_ARG_TYPE;
680 }
681 return VINF_SUCCESS;
682}
683
684
685/**
686 * Physical host address (unary).
687 *
688 * @returns VINF_SUCCESS on success.
689 * @returns VBox evaluation / parsing error code on failure.
690 * The caller does the bitching.
691 * @param pDbgc Debugger console instance data.
692 * @param pArg The argument.
693 * @param pResult Where to store the result.
694 */
695DECLCALLBACK(int) dbgcOpAddrHostPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
696{
697 LogFlow(("dbgcOpAddrPhys\n"));
698 DBGFADDRESS Address;
699 int rc;
700
701 *pResult = *pArg;
702 switch (pArg->enmType)
703 {
704 case DBGCVAR_TYPE_GC_FLAT:
705 Assert(pDbgc->pVM);
706 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
707 rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
708 DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
709 &pResult->u.GCPhys);
710 if (RT_SUCCESS(rc))
711 return VINF_SUCCESS;
712 return VERR_PARSE_CONVERSION_FAILED;
713
714 case DBGCVAR_TYPE_GC_FAR:
715 {
716 Assert(pDbgc->pVM);
717 rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
718 if (RT_SUCCESS(rc))
719 {
720 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
721 rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
722 if (RT_SUCCESS(rc))
723 return VINF_SUCCESS;
724 }
725 return VERR_PARSE_CONVERSION_FAILED;
726 }
727
728 case DBGCVAR_TYPE_GC_PHYS:
729 Assert(pDbgc->pVM);
730 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
731 rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
732 DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
733 &pResult->u.GCPhys);
734 if (RT_SUCCESS(rc))
735 return VINF_SUCCESS;
736 return VERR_PARSE_CONVERSION_FAILED;
737
738 case DBGCVAR_TYPE_HC_FLAT:
739 Assert(pDbgc->pVM);
740 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
741 rc = PGMR3DbgR3Ptr2HCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.HCPhys);
742 if (RT_SUCCESS(rc))
743 return VINF_SUCCESS;
744 /** @todo more memory types! */
745 return VERR_PARSE_CONVERSION_FAILED;
746
747 case DBGCVAR_TYPE_HC_FAR:
748 return VERR_PARSE_INCORRECT_ARG_TYPE;
749
750 case DBGCVAR_TYPE_HC_PHYS:
751 return VINF_SUCCESS;
752
753 case DBGCVAR_TYPE_NUMBER:
754 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
755 pResult->u.HCPhys = (RTGCPHYS)pResult->u.u64Number;
756 return VINF_SUCCESS;
757
758 case DBGCVAR_TYPE_STRING:
759 return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_HC_PHYS, pResult);
760
761 case DBGCVAR_TYPE_UNKNOWN:
762 default:
763 return VERR_PARSE_INCORRECT_ARG_TYPE;
764 }
765 return VINF_SUCCESS;
766}
767
768
769/**
770 * Host address (unary).
771 *
772 * @returns VINF_SUCCESS on success.
773 * @returns VBox evaluation / parsing error code on failure.
774 * The caller does the bitching.
775 * @param pDbgc Debugger console instance data.
776 * @param pArg The argument.
777 * @param pResult Where to store the result.
778 */
779DECLCALLBACK(int) dbgcOpAddrHost(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
780{
781 LogFlow(("dbgcOpAddrHost\n"));
782 int rc;
783 DBGFADDRESS Address;
784
785 *pResult = *pArg;
786 switch (pArg->enmType)
787 {
788 case DBGCVAR_TYPE_GC_FLAT:
789 Assert(pDbgc->pVM);
790 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
791 rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
792 DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
793 false /*fReadOnly */,
794 &pResult->u.pvHCFlat);
795 if (RT_SUCCESS(rc))
796 return VINF_SUCCESS;
797 return VERR_PARSE_CONVERSION_FAILED;
798
799 case DBGCVAR_TYPE_GC_FAR:
800 Assert(pDbgc->pVM);
801 rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
802 if (RT_SUCCESS(rc))
803 {
804 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
805 rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu, &Address,
806 false /*fReadOnly*/, &pResult->u.pvHCFlat);
807 if (RT_SUCCESS(rc))
808 return VINF_SUCCESS;
809 }
810 return VERR_PARSE_CONVERSION_FAILED;
811
812 case DBGCVAR_TYPE_GC_PHYS:
813 Assert(pDbgc->pVM);
814 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
815 rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
816 DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
817 false /*fReadOnly */,
818 &pResult->u.pvHCFlat);
819 if (RT_SUCCESS(rc))
820 return VINF_SUCCESS;
821 return VERR_PARSE_CONVERSION_FAILED;
822
823 case DBGCVAR_TYPE_HC_FLAT:
824 return VINF_SUCCESS;
825
826 case DBGCVAR_TYPE_HC_FAR:
827 case DBGCVAR_TYPE_HC_PHYS:
828 /** @todo !*/
829 return VERR_PARSE_CONVERSION_FAILED;
830
831 case DBGCVAR_TYPE_NUMBER:
832 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
833 pResult->u.pvHCFlat = (void *)(uintptr_t)pResult->u.u64Number;
834 return VINF_SUCCESS;
835
836 case DBGCVAR_TYPE_STRING:
837 return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_HC_FLAT, pResult);
838
839 case DBGCVAR_TYPE_UNKNOWN:
840 default:
841 return VERR_PARSE_INCORRECT_ARG_TYPE;
842 }
843}
844
845
846/**
847 * Bitwise not (unary).
848 *
849 * @returns VINF_SUCCESS on success.
850 * @returns VBox evaluation / parsing error code on failure.
851 * The caller does the bitching.
852 * @param pDbgc Debugger console instance data.
853 * @param pArg The argument.
854 * @param pResult Where to store the result.
855 */
856static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
857{
858 LogFlow(("dbgcOpAddrFar\n"));
859 int rc;
860
861 switch (pArg1->enmType)
862 {
863 case DBGCVAR_TYPE_STRING:
864 rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_NUMBER, pResult);
865 if (RT_FAILURE(rc))
866 return rc;
867 break;
868 case DBGCVAR_TYPE_NUMBER:
869 *pResult = *pArg1;
870 break;
871
872 case DBGCVAR_TYPE_GC_FLAT:
873 case DBGCVAR_TYPE_GC_FAR:
874 case DBGCVAR_TYPE_GC_PHYS:
875 case DBGCVAR_TYPE_HC_FLAT:
876 case DBGCVAR_TYPE_HC_FAR:
877 case DBGCVAR_TYPE_HC_PHYS:
878 case DBGCVAR_TYPE_UNKNOWN:
879 default:
880 return VERR_PARSE_INCORRECT_ARG_TYPE;
881 }
882 pResult->u.GCFar.sel = (RTSEL)pResult->u.u64Number;
883
884 /* common code for the two types we support. */
885 switch (pArg2->enmType)
886 {
887 case DBGCVAR_TYPE_GC_FLAT:
888 pResult->u.GCFar.off = pArg2->u.GCFlat;
889 pResult->enmType = DBGCVAR_TYPE_GC_FAR;
890 break;
891
892 case DBGCVAR_TYPE_HC_FLAT:
893 pResult->u.HCFar.off = pArg2->u.GCFlat;
894 pResult->enmType = DBGCVAR_TYPE_GC_FAR;
895 break;
896
897 case DBGCVAR_TYPE_NUMBER:
898 pResult->u.GCFar.off = (RTGCPTR)pArg2->u.u64Number;
899 pResult->enmType = DBGCVAR_TYPE_GC_FAR;
900 break;
901
902 case DBGCVAR_TYPE_STRING:
903 {
904 DBGCVAR Var;
905 rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
906 if (RT_FAILURE(rc))
907 return rc;
908 pResult->u.GCFar.off = (RTGCPTR)Var.u.u64Number;
909 pResult->enmType = DBGCVAR_TYPE_GC_FAR;
910 break;
911 }
912
913 case DBGCVAR_TYPE_GC_FAR:
914 case DBGCVAR_TYPE_GC_PHYS:
915 case DBGCVAR_TYPE_HC_FAR:
916 case DBGCVAR_TYPE_HC_PHYS:
917 case DBGCVAR_TYPE_UNKNOWN:
918 default:
919 return VERR_PARSE_INCORRECT_ARG_TYPE;
920 }
921 return VINF_SUCCESS;
922
923}
924
925
926/**
927 * Multiplication operator (binary).
928 *
929 * @returns VINF_SUCCESS on success.
930 * @returns VBox evaluation / parsing error code on failure.
931 * The caller does the bitching.
932 * @param pDbgc Debugger console instance data.
933 * @param pArg1 The first argument.
934 * @param pArg2 The 2nd argument.
935 * @param pResult Where to store the result.
936 */
937static DECLCALLBACK(int) dbgcOpMult(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
938{
939 LogFlow(("dbgcOpMult\n"));
940 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2);
941 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, *, false);
942}
943
944
945/**
946 * Division operator (binary).
947 *
948 * @returns VINF_SUCCESS on success.
949 * @returns VBox evaluation / parsing error code on failure.
950 * The caller does the bitching.
951 * @param pDbgc Debugger console instance data.
952 * @param pArg1 The first argument.
953 * @param pArg2 The 2nd argument.
954 * @param pResult Where to store the result.
955 */
956static DECLCALLBACK(int) dbgcOpDiv(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
957{
958 LogFlow(("dbgcOpDiv\n"));
959 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, /, true);
960}
961
962
963/**
964 * Modulus operator (binary).
965 *
966 * @returns VINF_SUCCESS on success.
967 * @returns VBox evaluation / parsing error code on failure.
968 * The caller does the bitching.
969 * @param pDbgc Debugger console instance data.
970 * @param pArg1 The first argument.
971 * @param pArg2 The 2nd argument.
972 * @param pResult Where to store the result.
973 */
974static DECLCALLBACK(int) dbgcOpMod(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
975{
976 LogFlow(("dbgcOpMod\n"));
977 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, %, false);
978}
979
980
981/**
982 * Addition operator (binary).
983 *
984 * @returns VINF_SUCCESS on success.
985 * @returns VBox evaluation / parsing error code on failure.
986 * The caller does the bitching.
987 * @param pDbgc Debugger console instance data.
988 * @param pArg1 The first argument.
989 * @param pArg2 The 2nd argument.
990 * @param pResult Where to store the result.
991 */
992static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
993{
994 LogFlow(("dbgcOpAdd\n"));
995
996 /*
997 * An addition operation will return (when possible) the left side type in the
998 * expression. We make an omission for numbers, where we'll take the right side
999 * type instead. An expression where only the left hand side is a string we'll
1000 * use the right hand type assuming that the string is a symbol.
1001 */
1002 if ( (pArg1->enmType == DBGCVAR_TYPE_NUMBER && pArg2->enmType != DBGCVAR_TYPE_STRING)
1003 || (pArg1->enmType == DBGCVAR_TYPE_STRING && pArg2->enmType != DBGCVAR_TYPE_STRING))
1004 {
1005 PCDBGCVAR pTmp = pArg2;
1006 pArg2 = pArg1;
1007 pArg1 = pTmp;
1008 }
1009 DBGCVAR Sym1, Sym2;
1010 if (pArg1->enmType == DBGCVAR_TYPE_STRING)
1011 {
1012 int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, &Sym1);
1013 if (RT_FAILURE(rc))
1014 return rc;
1015 pArg1 = &Sym1;
1016
1017 rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_ANY, &Sym2);
1018 if (RT_FAILURE(rc))
1019 return rc;
1020 pArg2 = &Sym2;
1021 }
1022
1023 int rc;
1024 DBGCVAR Var;
1025 DBGCVAR Var2;
1026 switch (pArg1->enmType)
1027 {
1028 /*
1029 * GC Flat
1030 */
1031 case DBGCVAR_TYPE_GC_FLAT:
1032 switch (pArg2->enmType)
1033 {
1034 case DBGCVAR_TYPE_HC_FLAT:
1035 case DBGCVAR_TYPE_HC_FAR:
1036 case DBGCVAR_TYPE_HC_PHYS:
1037 return VERR_PARSE_INVALID_OPERATION;
1038 default:
1039 *pResult = *pArg1;
1040 rc = dbgcOpAddrFlat(pDbgc, pArg2, &Var);
1041 if (RT_FAILURE(rc))
1042 return rc;
1043 pResult->u.GCFlat += pArg2->u.GCFlat;
1044 break;
1045 }
1046 break;
1047
1048 /*
1049 * GC Far
1050 */
1051 case DBGCVAR_TYPE_GC_FAR:
1052 switch (pArg2->enmType)
1053 {
1054 case DBGCVAR_TYPE_HC_FLAT:
1055 case DBGCVAR_TYPE_HC_FAR:
1056 case DBGCVAR_TYPE_HC_PHYS:
1057 return VERR_PARSE_INVALID_OPERATION;
1058 case DBGCVAR_TYPE_NUMBER:
1059 *pResult = *pArg1;
1060 pResult->u.GCFar.off += (RTGCPTR)pArg2->u.u64Number;
1061 break;
1062 default:
1063 rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
1064 if (RT_FAILURE(rc))
1065 return rc;
1066 rc = dbgcOpAddrFlat(pDbgc, pArg2, &Var);
1067 if (RT_FAILURE(rc))
1068 return rc;
1069 pResult->u.GCFlat += pArg2->u.GCFlat;
1070 break;
1071 }
1072 break;
1073
1074 /*
1075 * GC Phys
1076 */
1077 case DBGCVAR_TYPE_GC_PHYS:
1078 switch (pArg2->enmType)
1079 {
1080 case DBGCVAR_TYPE_HC_FLAT:
1081 case DBGCVAR_TYPE_HC_FAR:
1082 case DBGCVAR_TYPE_HC_PHYS:
1083 return VERR_PARSE_INVALID_OPERATION;
1084 default:
1085 *pResult = *pArg1;
1086 rc = dbgcOpAddrPhys(pDbgc, pArg2, &Var);
1087 if (RT_FAILURE(rc))
1088 return rc;
1089 if (Var.enmType != DBGCVAR_TYPE_GC_PHYS)
1090 return VERR_PARSE_INVALID_OPERATION;
1091 pResult->u.GCPhys += Var.u.GCPhys;
1092 break;
1093 }
1094 break;
1095
1096 /*
1097 * HC Flat
1098 */
1099 case DBGCVAR_TYPE_HC_FLAT:
1100 *pResult = *pArg1;
1101 rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
1102 if (RT_FAILURE(rc))
1103 return rc;
1104 rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
1105 if (RT_FAILURE(rc))
1106 return rc;
1107 pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat + (uintptr_t)Var.u.pvHCFlat;
1108 break;
1109
1110 /*
1111 * HC Far
1112 */
1113 case DBGCVAR_TYPE_HC_FAR:
1114 switch (pArg2->enmType)
1115 {
1116 case DBGCVAR_TYPE_NUMBER:
1117 *pResult = *pArg1;
1118 pResult->u.HCFar.off += (uintptr_t)pArg2->u.u64Number;
1119 break;
1120
1121 default:
1122 rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
1123 if (RT_FAILURE(rc))
1124 return rc;
1125 rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
1126 if (RT_FAILURE(rc))
1127 return rc;
1128 rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
1129 if (RT_FAILURE(rc))
1130 return rc;
1131 pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat + (uintptr_t)Var.u.pvHCFlat;
1132 break;
1133 }
1134 break;
1135
1136 /*
1137 * HC Phys
1138 */
1139 case DBGCVAR_TYPE_HC_PHYS:
1140 *pResult = *pArg1;
1141 rc = dbgcOpAddrHostPhys(pDbgc, pArg2, &Var);
1142 if (RT_FAILURE(rc))
1143 return rc;
1144 pResult->u.HCPhys += Var.u.HCPhys;
1145 break;
1146
1147 /*
1148 * Numbers (see start of function)
1149 */
1150 case DBGCVAR_TYPE_NUMBER:
1151 *pResult = *pArg1;
1152 switch (pArg2->enmType)
1153 {
1154 case DBGCVAR_TYPE_SYMBOL:
1155 case DBGCVAR_TYPE_STRING:
1156 rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
1157 if (RT_FAILURE(rc))
1158 return rc;
1159 case DBGCVAR_TYPE_NUMBER:
1160 pResult->u.u64Number += pArg2->u.u64Number;
1161 break;
1162 default:
1163 return VERR_PARSE_INVALID_OPERATION;
1164 }
1165 break;
1166
1167 default:
1168 return VERR_PARSE_INVALID_OPERATION;
1169
1170 }
1171 return VINF_SUCCESS;
1172}
1173
1174
1175/**
1176 * Subtraction operator (binary).
1177 *
1178 * @returns VINF_SUCCESS on success.
1179 * @returns VBox evaluation / parsing error code on failure.
1180 * The caller does the bitching.
1181 * @param pDbgc Debugger console instance data.
1182 * @param pArg1 The first argument.
1183 * @param pArg2 The 2nd argument.
1184 * @param pResult Where to store the result.
1185 */
1186static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1187{
1188 LogFlow(("dbgcOpSub\n"));
1189
1190 /*
1191 * An subtraction operation will return the left side type in the expression.
1192 * However, if the left hand side is a number and the right hand a pointer of
1193 * some kind we'll convert the left hand side to the same type as the right hand.
1194 * Any strings will be attempted resolved as symbols.
1195 */
1196 DBGCVAR Sym1, Sym2;
1197 if ( pArg2->enmType == DBGCVAR_TYPE_STRING
1198 && ( pArg1->enmType == DBGCVAR_TYPE_NUMBER
1199 || pArg1->enmType == DBGCVAR_TYPE_STRING))
1200 {
1201 int rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_ANY, &Sym2);
1202 if (RT_FAILURE(rc))
1203 return rc;
1204 pArg2 = &Sym2;
1205 }
1206
1207 if (pArg1->enmType == DBGCVAR_TYPE_STRING)
1208 {
1209 DBGCVARTYPE enmType;
1210 switch (pArg2->enmType)
1211 {
1212 case DBGCVAR_TYPE_NUMBER:
1213 enmType = DBGCVAR_TYPE_ANY;
1214 break;
1215 case DBGCVAR_TYPE_GC_FLAT:
1216 case DBGCVAR_TYPE_GC_PHYS:
1217 case DBGCVAR_TYPE_HC_FLAT:
1218 case DBGCVAR_TYPE_HC_PHYS:
1219 enmType = pArg2->enmType;
1220 break;
1221 case DBGCVAR_TYPE_GC_FAR:
1222 enmType = DBGCVAR_TYPE_GC_FLAT;
1223 break;
1224 case DBGCVAR_TYPE_HC_FAR:
1225 enmType = DBGCVAR_TYPE_HC_FLAT;
1226 break;
1227
1228 default:
1229 case DBGCVAR_TYPE_STRING:
1230 AssertMsgFailed(("Can't happen\n"));
1231 enmType = DBGCVAR_TYPE_STRING;
1232 break;
1233 }
1234 if (enmType != DBGCVAR_TYPE_STRING)
1235 {
1236 int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, &Sym1);
1237 if (RT_FAILURE(rc))
1238 return rc;
1239 pArg1 = &Sym1;
1240 }
1241 }
1242 else if (pArg1->enmType == DBGCVAR_TYPE_NUMBER)
1243 {
1244 PFNDBGCOPUNARY pOp = NULL;
1245 switch (pArg2->enmType)
1246 {
1247 case DBGCVAR_TYPE_GC_FAR:
1248 case DBGCVAR_TYPE_GC_FLAT:
1249 pOp = dbgcOpAddrFlat;
1250 break;
1251 case DBGCVAR_TYPE_GC_PHYS:
1252 pOp = dbgcOpAddrPhys;
1253 break;
1254 case DBGCVAR_TYPE_HC_FAR:
1255 case DBGCVAR_TYPE_HC_FLAT:
1256 pOp = dbgcOpAddrHost;
1257 break;
1258 case DBGCVAR_TYPE_HC_PHYS:
1259 pOp = dbgcOpAddrHostPhys;
1260 break;
1261 case DBGCVAR_TYPE_NUMBER:
1262 break;
1263 default:
1264 case DBGCVAR_TYPE_STRING:
1265 AssertMsgFailed(("Can't happen\n"));
1266 break;
1267 }
1268 if (pOp)
1269 {
1270 int rc = pOp(pDbgc, pArg1, &Sym1);
1271 if (RT_FAILURE(rc))
1272 return rc;
1273 pArg1 = &Sym1;
1274 }
1275 }
1276
1277
1278 /*
1279 * Normal processing.
1280 */
1281 int rc;
1282 DBGCVAR Var;
1283 DBGCVAR Var2;
1284 switch (pArg1->enmType)
1285 {
1286 /*
1287 * GC Flat
1288 */
1289 case DBGCVAR_TYPE_GC_FLAT:
1290 switch (pArg2->enmType)
1291 {
1292 case DBGCVAR_TYPE_HC_FLAT:
1293 case DBGCVAR_TYPE_HC_FAR:
1294 case DBGCVAR_TYPE_HC_PHYS:
1295 return VERR_PARSE_INVALID_OPERATION;
1296 default:
1297 *pResult = *pArg1;
1298 rc = dbgcOpAddrFlat(pDbgc, pArg2, &Var);
1299 if (RT_FAILURE(rc))
1300 return rc;
1301 pResult->u.GCFlat -= pArg2->u.GCFlat;
1302 break;
1303 }
1304 break;
1305
1306 /*
1307 * GC Far
1308 */
1309 case DBGCVAR_TYPE_GC_FAR:
1310 switch (pArg2->enmType)
1311 {
1312 case DBGCVAR_TYPE_HC_FLAT:
1313 case DBGCVAR_TYPE_HC_FAR:
1314 case DBGCVAR_TYPE_HC_PHYS:
1315 return VERR_PARSE_INVALID_OPERATION;
1316 case DBGCVAR_TYPE_NUMBER:
1317 *pResult = *pArg1;
1318 pResult->u.GCFar.off -= (RTGCPTR)pArg2->u.u64Number;
1319 break;
1320 default:
1321 rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
1322 if (RT_FAILURE(rc))
1323 return rc;
1324 rc = dbgcOpAddrFlat(pDbgc, pArg2, &Var);
1325 if (RT_FAILURE(rc))
1326 return rc;
1327 pResult->u.GCFlat -= pArg2->u.GCFlat;
1328 break;
1329 }
1330 break;
1331
1332 /*
1333 * GC Phys
1334 */
1335 case DBGCVAR_TYPE_GC_PHYS:
1336 switch (pArg2->enmType)
1337 {
1338 case DBGCVAR_TYPE_HC_FLAT:
1339 case DBGCVAR_TYPE_HC_FAR:
1340 case DBGCVAR_TYPE_HC_PHYS:
1341 return VERR_PARSE_INVALID_OPERATION;
1342 default:
1343 *pResult = *pArg1;
1344 rc = dbgcOpAddrPhys(pDbgc, pArg2, &Var);
1345 if (RT_FAILURE(rc))
1346 return rc;
1347 if (Var.enmType != DBGCVAR_TYPE_GC_PHYS)
1348 return VERR_PARSE_INVALID_OPERATION;
1349 pResult->u.GCPhys -= Var.u.GCPhys;
1350 break;
1351 }
1352 break;
1353
1354 /*
1355 * HC Flat
1356 */
1357 case DBGCVAR_TYPE_HC_FLAT:
1358 *pResult = *pArg1;
1359 rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
1360 if (RT_FAILURE(rc))
1361 return rc;
1362 rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
1363 if (RT_FAILURE(rc))
1364 return rc;
1365 pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat - (uintptr_t)Var.u.pvHCFlat;
1366 break;
1367
1368 /*
1369 * HC Far
1370 */
1371 case DBGCVAR_TYPE_HC_FAR:
1372 switch (pArg2->enmType)
1373 {
1374 case DBGCVAR_TYPE_NUMBER:
1375 *pResult = *pArg1;
1376 pResult->u.HCFar.off -= (uintptr_t)pArg2->u.u64Number;
1377 break;
1378
1379 default:
1380 rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
1381 if (RT_FAILURE(rc))
1382 return rc;
1383 rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
1384 if (RT_FAILURE(rc))
1385 return rc;
1386 rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
1387 if (RT_FAILURE(rc))
1388 return rc;
1389 pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat - (uintptr_t)Var.u.pvHCFlat;
1390 break;
1391 }
1392 break;
1393
1394 /*
1395 * HC Phys
1396 */
1397 case DBGCVAR_TYPE_HC_PHYS:
1398 *pResult = *pArg1;
1399 rc = dbgcOpAddrHostPhys(pDbgc, pArg2, &Var);
1400 if (RT_FAILURE(rc))
1401 return rc;
1402 pResult->u.HCPhys -= Var.u.HCPhys;
1403 break;
1404
1405 /*
1406 * Numbers (see start of function)
1407 */
1408 case DBGCVAR_TYPE_NUMBER:
1409 *pResult = *pArg1;
1410 switch (pArg2->enmType)
1411 {
1412 case DBGCVAR_TYPE_SYMBOL:
1413 case DBGCVAR_TYPE_STRING:
1414 rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
1415 if (RT_FAILURE(rc))
1416 return rc;
1417 case DBGCVAR_TYPE_NUMBER:
1418 pResult->u.u64Number -= pArg2->u.u64Number;
1419 break;
1420 default:
1421 return VERR_PARSE_INVALID_OPERATION;
1422 }
1423 break;
1424
1425 default:
1426 return VERR_PARSE_INVALID_OPERATION;
1427
1428 }
1429 return VINF_SUCCESS;
1430}
1431
1432
1433/**
1434 * Bitwise shift left operator (binary).
1435 *
1436 * @returns VINF_SUCCESS on success.
1437 * @returns VBox evaluation / parsing error code on failure.
1438 * The caller does the bitching.
1439 * @param pDbgc Debugger console instance data.
1440 * @param pArg1 The first argument.
1441 * @param pArg2 The 2nd argument.
1442 * @param pResult Where to store the result.
1443 */
1444static DECLCALLBACK(int) dbgcOpBitwiseShiftLeft(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1445{
1446 LogFlow(("dbgcOpBitwiseShiftLeft\n"));
1447 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, <<, false);
1448}
1449
1450
1451/**
1452 * Bitwise shift right operator (binary).
1453 *
1454 * @returns VINF_SUCCESS on success.
1455 * @returns VBox evaluation / parsing error code on failure.
1456 * The caller does the bitching.
1457 * @param pDbgc Debugger console instance data.
1458 * @param pArg1 The first argument.
1459 * @param pArg2 The 2nd argument.
1460 * @param pResult Where to store the result.
1461 */
1462static DECLCALLBACK(int) dbgcOpBitwiseShiftRight(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1463{
1464 LogFlow(("dbgcOpBitwiseShiftRight\n"));
1465 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, >>, false);
1466}
1467
1468
1469/**
1470 * Bitwise and operator (binary).
1471 *
1472 * @returns VINF_SUCCESS on success.
1473 * @returns VBox evaluation / parsing error code on failure.
1474 * The caller does the bitching.
1475 * @param pDbgc Debugger console instance data.
1476 * @param pArg1 The first argument.
1477 * @param pArg2 The 2nd argument.
1478 * @param pResult Where to store the result.
1479 */
1480static DECLCALLBACK(int) dbgcOpBitwiseAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1481{
1482 LogFlow(("dbgcOpBitwiseAnd\n"));
1483 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2);
1484 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, &, false);
1485}
1486
1487
1488/**
1489 * Bitwise exclusive or operator (binary).
1490 *
1491 * @returns VINF_SUCCESS on success.
1492 * @returns VBox evaluation / parsing error code on failure.
1493 * The caller does the bitching.
1494 * @param pDbgc Debugger console instance data.
1495 * @param pArg1 The first argument.
1496 * @param pArg2 The 2nd argument.
1497 * @param pResult Where to store the result.
1498 */
1499static DECLCALLBACK(int) dbgcOpBitwiseXor(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1500{
1501 LogFlow(("dbgcOpBitwiseXor\n"));
1502 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2);
1503 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, ^, false);
1504}
1505
1506
1507/**
1508 * Bitwise inclusive or operator (binary).
1509 *
1510 * @returns VINF_SUCCESS on success.
1511 * @returns VBox evaluation / parsing error code on failure.
1512 * The caller does the bitching.
1513 * @param pDbgc Debugger console instance data.
1514 * @param pArg1 The first argument.
1515 * @param pArg2 The 2nd argument.
1516 * @param pResult Where to store the result.
1517 */
1518static DECLCALLBACK(int) dbgcOpBitwiseOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1519{
1520 LogFlow(("dbgcOpBitwiseOr\n"));
1521 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2);
1522 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, |, false);
1523}
1524
1525
1526/**
1527 * Boolean and operator (binary).
1528 *
1529 * @returns VINF_SUCCESS on success.
1530 * @returns VBox evaluation / parsing error code on failure.
1531 * The caller does the bitching.
1532 * @param pDbgc Debugger console instance data.
1533 * @param pArg1 The first argument.
1534 * @param pArg2 The 2nd argument.
1535 * @param pResult Where to store the result.
1536 */
1537static DECLCALLBACK(int) dbgcOpBooleanAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1538{
1539 LogFlow(("dbgcOpBooleanAnd\n"));
1540 /** @todo force numeric return value? */
1541 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, &&, false);
1542}
1543
1544
1545/**
1546 * Boolean or operator (binary).
1547 *
1548 * @returns VINF_SUCCESS on success.
1549 * @returns VBox evaluation / parsing error code on failure.
1550 * The caller does the bitching.
1551 * @param pDbgc Debugger console instance data.
1552 * @param pArg1 The first argument.
1553 * @param pArg2 The 2nd argument.
1554 * @param pResult Where to store the result.
1555 */
1556static DECLCALLBACK(int) dbgcOpBooleanOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1557{
1558 LogFlow(("dbgcOpBooleanOr\n"));
1559 /** @todo force numeric return value? */
1560 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, ||, false);
1561}
1562
1563
1564/**
1565 * Range to operator (binary).
1566 *
1567 * @returns VINF_SUCCESS on success.
1568 * @returns VBox evaluation / parsing error code on failure.
1569 * The caller does the bitching.
1570 * @param pDbgc Debugger console instance data.
1571 * @param pArg1 The first argument.
1572 * @param pArg2 The 2nd argument.
1573 * @param pResult Where to store the result.
1574 */
1575static DECLCALLBACK(int) dbgcOpRangeLength(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1576{
1577 LogFlow(("dbgcOpRangeLength\n"));
1578
1579 /*
1580 * Make result. Strings needs to be resolved into symbols.
1581 */
1582 if (pArg1->enmType == DBGCVAR_TYPE_STRING)
1583 {
1584 int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, pResult);
1585 if (RT_FAILURE(rc))
1586 return rc;
1587 }
1588 else
1589 *pResult = *pArg1;
1590
1591 /*
1592 * Convert 2nd argument to element count.
1593 */
1594 pResult->enmRangeType = DBGCVAR_RANGE_ELEMENTS;
1595 switch (pArg2->enmType)
1596 {
1597 case DBGCVAR_TYPE_NUMBER:
1598 pResult->u64Range = pArg2->u.u64Number;
1599 break;
1600
1601 case DBGCVAR_TYPE_STRING:
1602 {
1603 int rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, pResult);
1604 if (RT_FAILURE(rc))
1605 return rc;
1606 pResult->u64Range = pArg2->u.u64Number;
1607 break;
1608 }
1609
1610 default:
1611 return VERR_PARSE_INVALID_OPERATION;
1612 }
1613
1614 return VINF_SUCCESS;
1615}
1616
1617
1618/**
1619 * Range to operator (binary).
1620 *
1621 * @returns VINF_SUCCESS on success.
1622 * @returns VBox evaluation / parsing error code on failure.
1623 * The caller does the bitching.
1624 * @param pDbgc Debugger console instance data.
1625 * @param pArg1 The first argument.
1626 * @param pArg2 The 2nd argument.
1627 * @param pResult Where to store the result.
1628 */
1629static DECLCALLBACK(int) dbgcOpRangeLengthBytes(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1630{
1631 LogFlow(("dbgcOpRangeLengthBytes\n"));
1632 int rc = dbgcOpRangeLength(pDbgc, pArg1, pArg2, pResult);
1633 if (RT_SUCCESS(rc))
1634 pResult->enmRangeType = DBGCVAR_RANGE_BYTES;
1635 return rc;
1636}
1637
1638
1639/**
1640 * Range to operator (binary).
1641 *
1642 * @returns VINF_SUCCESS on success.
1643 * @returns VBox evaluation / parsing error code on failure.
1644 * The caller does the bitching.
1645 * @param pDbgc Debugger console instance data.
1646 * @param pArg1 The first argument.
1647 * @param pArg2 The 2nd argument.
1648 * @param pResult Where to store the result.
1649 */
1650static DECLCALLBACK(int) dbgcOpRangeTo(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1651{
1652 LogFlow(("dbgcOpRangeTo\n"));
1653
1654 /*
1655 * Calc number of bytes between the two args.
1656 */
1657 DBGCVAR Diff;
1658 int rc = dbgcOpSub(pDbgc, pArg2, pArg1, &Diff);
1659 if (RT_FAILURE(rc))
1660 return rc;
1661
1662 /*
1663 * Use the diff as the range of Arg1.
1664 */
1665 *pResult = *pArg1;
1666 pResult->enmRangeType = DBGCVAR_RANGE_BYTES;
1667 switch (Diff.enmType)
1668 {
1669 case DBGCVAR_TYPE_GC_FLAT:
1670 pResult->u64Range = (RTGCUINTPTR)Diff.u.GCFlat;
1671 break;
1672 case DBGCVAR_TYPE_GC_PHYS:
1673 pResult->u64Range = Diff.u.GCPhys;
1674 break;
1675 case DBGCVAR_TYPE_HC_FLAT:
1676 pResult->u64Range = (uintptr_t)Diff.u.pvHCFlat;
1677 break;
1678 case DBGCVAR_TYPE_HC_PHYS:
1679 pResult->u64Range = Diff.u.HCPhys;
1680 break;
1681 case DBGCVAR_TYPE_NUMBER:
1682 pResult->u64Range = Diff.u.u64Number;
1683 break;
1684
1685 case DBGCVAR_TYPE_GC_FAR:
1686 case DBGCVAR_TYPE_STRING:
1687 case DBGCVAR_TYPE_HC_FAR:
1688 default:
1689 AssertMsgFailed(("Impossible!\n"));
1690 return VERR_PARSE_INVALID_OPERATION;
1691 }
1692
1693 return VINF_SUCCESS;
1694}
1695
1696
1697/**
1698 * Searches for an operator descriptor which matches the start of
1699 * the expression given us.
1700 *
1701 * @returns Pointer to the operator on success.
1702 * @param pDbgc The debug console instance.
1703 * @param pszExpr Pointer to the expression string which might start with an operator.
1704 * @param fPreferBinary Whether to favour binary or unary operators.
1705 * Caller must assert that it's the desired type! Both types will still
1706 * be returned, this is only for resolving duplicates.
1707 * @param chPrev The previous char. Some operators requires a blank in front of it.
1708 */
1709PCDBGCOP dbgcOperatorLookup(PDBGC pDbgc, const char *pszExpr, bool fPreferBinary, char chPrev)
1710{
1711 PCDBGCOP pOp = NULL;
1712 for (unsigned iOp = 0; iOp < RT_ELEMENTS(g_aOps); iOp++)
1713 {
1714 if ( g_aOps[iOp].szName[0] == pszExpr[0]
1715 && (!g_aOps[iOp].szName[1] || g_aOps[iOp].szName[1] == pszExpr[1])
1716 && (!g_aOps[iOp].szName[2] || g_aOps[iOp].szName[2] == pszExpr[2]))
1717 {
1718 /*
1719 * Check that we don't mistake it for some other operator which have more chars.
1720 */
1721 unsigned j;
1722 for (j = iOp + 1; j < RT_ELEMENTS(g_aOps); j++)
1723 if ( g_aOps[j].cchName > g_aOps[iOp].cchName
1724 && g_aOps[j].szName[0] == pszExpr[0]
1725 && (!g_aOps[j].szName[1] || g_aOps[j].szName[1] == pszExpr[1])
1726 && (!g_aOps[j].szName[2] || g_aOps[j].szName[2] == pszExpr[2]) )
1727 break;
1728 if (j < RT_ELEMENTS(g_aOps))
1729 continue; /* we'll catch it later. (for theoretical +,++,+++ cases.) */
1730 pOp = &g_aOps[iOp];
1731
1732 /*
1733 * Preferred type?
1734 */
1735 if (g_aOps[iOp].fBinary == fPreferBinary)
1736 break;
1737 }
1738 }
1739
1740 if (pOp)
1741 Log2(("dbgcOperatorLookup: pOp=%p %s\n", pOp, pOp->szName));
1742 NOREF(pDbgc); NOREF(chPrev);
1743 return pOp;
1744}
1745
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