VirtualBox

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

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

DBGFReg: long double -> RTFLOAT80U2. Get floating point registers and stuff.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 60.0 KB
Line 
1/* $Id: DBGCOps.cpp 35513 2011-01-12 17:50:43Z 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_R80:
525#ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
526 DBGCVAR_INIT_NUMBER(pResult, (uint64_t)Value.r80.lrd);
527#else
528 DBGCVAR_INIT_NUMBER(pResult, (uint64_t)Value.r80.sj64.u63Fraction);
529#endif
530 return VINF_SUCCESS;
531
532 case DBGFREGVALTYPE_DTR:
533 DBGCVAR_INIT_NUMBER(pResult, Value.dtr.u64Base);
534 return VINF_SUCCESS;
535
536 case DBGFREGVALTYPE_INVALID:
537 case DBGFREGVALTYPE_END:
538 case DBGFREGVALTYPE_32BIT_HACK:
539 break;
540 }
541 }
542 return rc;
543}
544
545
546/**
547 * Flat address (unary).
548 *
549 * @returns VINF_SUCCESS on success.
550 * @returns VBox evaluation / parsing error code on failure.
551 * The caller does the bitching.
552 * @param pDbgc Debugger console instance data.
553 * @param pArg The argument.
554 * @param pResult Where to store the result.
555 */
556DECLCALLBACK(int) dbgcOpAddrFlat(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
557{
558 LogFlow(("dbgcOpAddrFlat\n"));
559 int rc;
560 *pResult = *pArg;
561
562 switch (pArg->enmType)
563 {
564 case DBGCVAR_TYPE_GC_FLAT:
565 return VINF_SUCCESS;
566
567 case DBGCVAR_TYPE_GC_FAR:
568 {
569 Assert(pDbgc->pVM);
570 DBGFADDRESS Address;
571 rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
572 if (RT_SUCCESS(rc))
573 {
574 pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
575 pResult->u.GCFlat = Address.FlatPtr;
576 return VINF_SUCCESS;
577 }
578 return VERR_PARSE_CONVERSION_FAILED;
579 }
580
581 case DBGCVAR_TYPE_GC_PHYS:
582 //rc = MMR3PhysGCPhys2GCVirtEx(pDbgc->pVM, pResult->u.GCPhys, ..., &pResult->u.GCFlat); - yea, sure.
583 return VERR_PARSE_INCORRECT_ARG_TYPE;
584
585 case DBGCVAR_TYPE_HC_FLAT:
586 return VINF_SUCCESS;
587
588 case DBGCVAR_TYPE_HC_FAR:
589 return VERR_PARSE_INCORRECT_ARG_TYPE;
590
591 case DBGCVAR_TYPE_HC_PHYS:
592 Assert(pDbgc->pVM);
593 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
594 rc = MMR3HCPhys2HCVirt(pDbgc->pVM, pResult->u.HCPhys, &pResult->u.pvHCFlat);
595 if (RT_SUCCESS(rc))
596 return VINF_SUCCESS;
597 return VERR_PARSE_CONVERSION_FAILED;
598
599 case DBGCVAR_TYPE_NUMBER:
600 pResult->enmType = DBGCVAR_TYPE_GC_FLAT;
601 pResult->u.GCFlat = (RTGCPTR)pResult->u.u64Number;
602 return VINF_SUCCESS;
603
604 case DBGCVAR_TYPE_STRING:
605 return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, pResult);
606
607 case DBGCVAR_TYPE_UNKNOWN:
608 default:
609 return VERR_PARSE_INCORRECT_ARG_TYPE;
610 }
611}
612
613
614/**
615 * Physical address (unary).
616 *
617 * @returns VINF_SUCCESS on success.
618 * @returns VBox evaluation / parsing error code on failure.
619 * The caller does the bitching.
620 * @param pDbgc Debugger console instance data.
621 * @param pArg The argument.
622 * @param pResult Where to store the result.
623 */
624DECLCALLBACK(int) dbgcOpAddrPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
625{
626 LogFlow(("dbgcOpAddrPhys\n"));
627 int rc;
628 DBGFADDRESS Address;
629
630 *pResult = *pArg;
631 switch (pArg->enmType)
632 {
633 case DBGCVAR_TYPE_GC_FLAT:
634 Assert(pDbgc->pVM);
635 pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
636 rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu,
637 DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
638 &pResult->u.GCPhys);
639 if (RT_SUCCESS(rc))
640 return VINF_SUCCESS;
641 return VERR_PARSE_CONVERSION_FAILED;
642
643 case DBGCVAR_TYPE_GC_FAR:
644 Assert(pDbgc->pVM);
645 rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
646 if (RT_SUCCESS(rc))
647 {
648 pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
649 rc = DBGFR3AddrToPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
650 if (RT_SUCCESS(rc))
651 return VINF_SUCCESS;
652 }
653 return VERR_PARSE_CONVERSION_FAILED;
654
655 case DBGCVAR_TYPE_GC_PHYS:
656 return VINF_SUCCESS;
657
658 case DBGCVAR_TYPE_HC_FLAT:
659 Assert(pDbgc->pVM);
660 pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
661 rc = PGMR3DbgR3Ptr2GCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.GCPhys);
662 if (RT_SUCCESS(rc))
663 return VINF_SUCCESS;
664 /** @todo more memory types! */
665 return VERR_PARSE_CONVERSION_FAILED;
666
667 case DBGCVAR_TYPE_HC_FAR:
668 return VERR_PARSE_INCORRECT_ARG_TYPE;
669
670 case DBGCVAR_TYPE_HC_PHYS:
671 return VINF_SUCCESS;
672
673 case DBGCVAR_TYPE_NUMBER:
674 pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
675 pResult->u.GCPhys = (RTGCPHYS)pResult->u.u64Number;
676 return VINF_SUCCESS;
677
678 case DBGCVAR_TYPE_STRING:
679 return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_PHYS, pResult);
680
681 case DBGCVAR_TYPE_UNKNOWN:
682 default:
683 return VERR_PARSE_INCORRECT_ARG_TYPE;
684 }
685 return VINF_SUCCESS;
686}
687
688
689/**
690 * Physical host address (unary).
691 *
692 * @returns VINF_SUCCESS on success.
693 * @returns VBox evaluation / parsing error code on failure.
694 * The caller does the bitching.
695 * @param pDbgc Debugger console instance data.
696 * @param pArg The argument.
697 * @param pResult Where to store the result.
698 */
699DECLCALLBACK(int) dbgcOpAddrHostPhys(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
700{
701 LogFlow(("dbgcOpAddrPhys\n"));
702 DBGFADDRESS Address;
703 int rc;
704
705 *pResult = *pArg;
706 switch (pArg->enmType)
707 {
708 case DBGCVAR_TYPE_GC_FLAT:
709 Assert(pDbgc->pVM);
710 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
711 rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
712 DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
713 &pResult->u.GCPhys);
714 if (RT_SUCCESS(rc))
715 return VINF_SUCCESS;
716 return VERR_PARSE_CONVERSION_FAILED;
717
718 case DBGCVAR_TYPE_GC_FAR:
719 {
720 Assert(pDbgc->pVM);
721 rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
722 if (RT_SUCCESS(rc))
723 {
724 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
725 rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
726 if (RT_SUCCESS(rc))
727 return VINF_SUCCESS;
728 }
729 return VERR_PARSE_CONVERSION_FAILED;
730 }
731
732 case DBGCVAR_TYPE_GC_PHYS:
733 Assert(pDbgc->pVM);
734 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
735 rc = DBGFR3AddrToHostPhys(pDbgc->pVM, pDbgc->idCpu,
736 DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
737 &pResult->u.GCPhys);
738 if (RT_SUCCESS(rc))
739 return VINF_SUCCESS;
740 return VERR_PARSE_CONVERSION_FAILED;
741
742 case DBGCVAR_TYPE_HC_FLAT:
743 Assert(pDbgc->pVM);
744 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
745 rc = PGMR3DbgR3Ptr2HCPhys(pDbgc->pVM, pArg->u.pvHCFlat, &pResult->u.HCPhys);
746 if (RT_SUCCESS(rc))
747 return VINF_SUCCESS;
748 /** @todo more memory types! */
749 return VERR_PARSE_CONVERSION_FAILED;
750
751 case DBGCVAR_TYPE_HC_FAR:
752 return VERR_PARSE_INCORRECT_ARG_TYPE;
753
754 case DBGCVAR_TYPE_HC_PHYS:
755 return VINF_SUCCESS;
756
757 case DBGCVAR_TYPE_NUMBER:
758 pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
759 pResult->u.HCPhys = (RTGCPHYS)pResult->u.u64Number;
760 return VINF_SUCCESS;
761
762 case DBGCVAR_TYPE_STRING:
763 return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_HC_PHYS, pResult);
764
765 case DBGCVAR_TYPE_UNKNOWN:
766 default:
767 return VERR_PARSE_INCORRECT_ARG_TYPE;
768 }
769 return VINF_SUCCESS;
770}
771
772
773/**
774 * Host address (unary).
775 *
776 * @returns VINF_SUCCESS on success.
777 * @returns VBox evaluation / parsing error code on failure.
778 * The caller does the bitching.
779 * @param pDbgc Debugger console instance data.
780 * @param pArg The argument.
781 * @param pResult Where to store the result.
782 */
783DECLCALLBACK(int) dbgcOpAddrHost(PDBGC pDbgc, PCDBGCVAR pArg, PDBGCVAR pResult)
784{
785 LogFlow(("dbgcOpAddrHost\n"));
786 int rc;
787 DBGFADDRESS Address;
788
789 *pResult = *pArg;
790 switch (pArg->enmType)
791 {
792 case DBGCVAR_TYPE_GC_FLAT:
793 Assert(pDbgc->pVM);
794 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
795 rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
796 DBGFR3AddrFromFlat(pDbgc->pVM, &Address, pArg->u.GCFlat),
797 false /*fReadOnly */,
798 &pResult->u.pvHCFlat);
799 if (RT_SUCCESS(rc))
800 return VINF_SUCCESS;
801 return VERR_PARSE_CONVERSION_FAILED;
802
803 case DBGCVAR_TYPE_GC_FAR:
804 Assert(pDbgc->pVM);
805 rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
806 if (RT_SUCCESS(rc))
807 {
808 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
809 rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu, &Address,
810 false /*fReadOnly*/, &pResult->u.pvHCFlat);
811 if (RT_SUCCESS(rc))
812 return VINF_SUCCESS;
813 }
814 return VERR_PARSE_CONVERSION_FAILED;
815
816 case DBGCVAR_TYPE_GC_PHYS:
817 Assert(pDbgc->pVM);
818 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
819 rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pVM, pDbgc->idCpu,
820 DBGFR3AddrFromPhys(pDbgc->pVM, &Address, pArg->u.GCPhys),
821 false /*fReadOnly */,
822 &pResult->u.pvHCFlat);
823 if (RT_SUCCESS(rc))
824 return VINF_SUCCESS;
825 return VERR_PARSE_CONVERSION_FAILED;
826
827 case DBGCVAR_TYPE_HC_FLAT:
828 return VINF_SUCCESS;
829
830 case DBGCVAR_TYPE_HC_FAR:
831 case DBGCVAR_TYPE_HC_PHYS:
832 /** @todo !*/
833 return VERR_PARSE_CONVERSION_FAILED;
834
835 case DBGCVAR_TYPE_NUMBER:
836 pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
837 pResult->u.pvHCFlat = (void *)(uintptr_t)pResult->u.u64Number;
838 return VINF_SUCCESS;
839
840 case DBGCVAR_TYPE_STRING:
841 return dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_HC_FLAT, pResult);
842
843 case DBGCVAR_TYPE_UNKNOWN:
844 default:
845 return VERR_PARSE_INCORRECT_ARG_TYPE;
846 }
847}
848
849
850/**
851 * Bitwise not (unary).
852 *
853 * @returns VINF_SUCCESS on success.
854 * @returns VBox evaluation / parsing error code on failure.
855 * The caller does the bitching.
856 * @param pDbgc Debugger console instance data.
857 * @param pArg The argument.
858 * @param pResult Where to store the result.
859 */
860static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
861{
862 LogFlow(("dbgcOpAddrFar\n"));
863 int rc;
864
865 switch (pArg1->enmType)
866 {
867 case DBGCVAR_TYPE_STRING:
868 rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_NUMBER, pResult);
869 if (RT_FAILURE(rc))
870 return rc;
871 break;
872 case DBGCVAR_TYPE_NUMBER:
873 *pResult = *pArg1;
874 break;
875
876 case DBGCVAR_TYPE_GC_FLAT:
877 case DBGCVAR_TYPE_GC_FAR:
878 case DBGCVAR_TYPE_GC_PHYS:
879 case DBGCVAR_TYPE_HC_FLAT:
880 case DBGCVAR_TYPE_HC_FAR:
881 case DBGCVAR_TYPE_HC_PHYS:
882 case DBGCVAR_TYPE_UNKNOWN:
883 default:
884 return VERR_PARSE_INCORRECT_ARG_TYPE;
885 }
886 pResult->u.GCFar.sel = (RTSEL)pResult->u.u64Number;
887
888 /* common code for the two types we support. */
889 switch (pArg2->enmType)
890 {
891 case DBGCVAR_TYPE_GC_FLAT:
892 pResult->u.GCFar.off = pArg2->u.GCFlat;
893 pResult->enmType = DBGCVAR_TYPE_GC_FAR;
894 break;
895
896 case DBGCVAR_TYPE_HC_FLAT:
897 pResult->u.HCFar.off = pArg2->u.GCFlat;
898 pResult->enmType = DBGCVAR_TYPE_GC_FAR;
899 break;
900
901 case DBGCVAR_TYPE_NUMBER:
902 pResult->u.GCFar.off = (RTGCPTR)pArg2->u.u64Number;
903 pResult->enmType = DBGCVAR_TYPE_GC_FAR;
904 break;
905
906 case DBGCVAR_TYPE_STRING:
907 {
908 DBGCVAR Var;
909 rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
910 if (RT_FAILURE(rc))
911 return rc;
912 pResult->u.GCFar.off = (RTGCPTR)Var.u.u64Number;
913 pResult->enmType = DBGCVAR_TYPE_GC_FAR;
914 break;
915 }
916
917 case DBGCVAR_TYPE_GC_FAR:
918 case DBGCVAR_TYPE_GC_PHYS:
919 case DBGCVAR_TYPE_HC_FAR:
920 case DBGCVAR_TYPE_HC_PHYS:
921 case DBGCVAR_TYPE_UNKNOWN:
922 default:
923 return VERR_PARSE_INCORRECT_ARG_TYPE;
924 }
925 return VINF_SUCCESS;
926
927}
928
929
930/**
931 * Multiplication operator (binary).
932 *
933 * @returns VINF_SUCCESS on success.
934 * @returns VBox evaluation / parsing error code on failure.
935 * The caller does the bitching.
936 * @param pDbgc Debugger console instance data.
937 * @param pArg1 The first argument.
938 * @param pArg2 The 2nd argument.
939 * @param pResult Where to store the result.
940 */
941static DECLCALLBACK(int) dbgcOpMult(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
942{
943 LogFlow(("dbgcOpMult\n"));
944 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2);
945 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, *, false);
946}
947
948
949/**
950 * Division operator (binary).
951 *
952 * @returns VINF_SUCCESS on success.
953 * @returns VBox evaluation / parsing error code on failure.
954 * The caller does the bitching.
955 * @param pDbgc Debugger console instance data.
956 * @param pArg1 The first argument.
957 * @param pArg2 The 2nd argument.
958 * @param pResult Where to store the result.
959 */
960static DECLCALLBACK(int) dbgcOpDiv(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
961{
962 LogFlow(("dbgcOpDiv\n"));
963 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, /, true);
964}
965
966
967/**
968 * Modulus operator (binary).
969 *
970 * @returns VINF_SUCCESS on success.
971 * @returns VBox evaluation / parsing error code on failure.
972 * The caller does the bitching.
973 * @param pDbgc Debugger console instance data.
974 * @param pArg1 The first argument.
975 * @param pArg2 The 2nd argument.
976 * @param pResult Where to store the result.
977 */
978static DECLCALLBACK(int) dbgcOpMod(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
979{
980 LogFlow(("dbgcOpMod\n"));
981 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, %, false);
982}
983
984
985/**
986 * Addition operator (binary).
987 *
988 * @returns VINF_SUCCESS on success.
989 * @returns VBox evaluation / parsing error code on failure.
990 * The caller does the bitching.
991 * @param pDbgc Debugger console instance data.
992 * @param pArg1 The first argument.
993 * @param pArg2 The 2nd argument.
994 * @param pResult Where to store the result.
995 */
996static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
997{
998 LogFlow(("dbgcOpAdd\n"));
999
1000 /*
1001 * An addition operation will return (when possible) the left side type in the
1002 * expression. We make an omission for numbers, where we'll take the right side
1003 * type instead. An expression where only the left hand side is a string we'll
1004 * use the right hand type assuming that the string is a symbol.
1005 */
1006 if ( (pArg1->enmType == DBGCVAR_TYPE_NUMBER && pArg2->enmType != DBGCVAR_TYPE_STRING)
1007 || (pArg1->enmType == DBGCVAR_TYPE_STRING && pArg2->enmType != DBGCVAR_TYPE_STRING))
1008 {
1009 PCDBGCVAR pTmp = pArg2;
1010 pArg2 = pArg1;
1011 pArg1 = pTmp;
1012 }
1013 DBGCVAR Sym1, Sym2;
1014 if (pArg1->enmType == DBGCVAR_TYPE_STRING)
1015 {
1016 int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, &Sym1);
1017 if (RT_FAILURE(rc))
1018 return rc;
1019 pArg1 = &Sym1;
1020
1021 rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_ANY, &Sym2);
1022 if (RT_FAILURE(rc))
1023 return rc;
1024 pArg2 = &Sym2;
1025 }
1026
1027 int rc;
1028 DBGCVAR Var;
1029 DBGCVAR Var2;
1030 switch (pArg1->enmType)
1031 {
1032 /*
1033 * GC Flat
1034 */
1035 case DBGCVAR_TYPE_GC_FLAT:
1036 switch (pArg2->enmType)
1037 {
1038 case DBGCVAR_TYPE_HC_FLAT:
1039 case DBGCVAR_TYPE_HC_FAR:
1040 case DBGCVAR_TYPE_HC_PHYS:
1041 return VERR_PARSE_INVALID_OPERATION;
1042 default:
1043 *pResult = *pArg1;
1044 rc = dbgcOpAddrFlat(pDbgc, pArg2, &Var);
1045 if (RT_FAILURE(rc))
1046 return rc;
1047 pResult->u.GCFlat += pArg2->u.GCFlat;
1048 break;
1049 }
1050 break;
1051
1052 /*
1053 * GC Far
1054 */
1055 case DBGCVAR_TYPE_GC_FAR:
1056 switch (pArg2->enmType)
1057 {
1058 case DBGCVAR_TYPE_HC_FLAT:
1059 case DBGCVAR_TYPE_HC_FAR:
1060 case DBGCVAR_TYPE_HC_PHYS:
1061 return VERR_PARSE_INVALID_OPERATION;
1062 case DBGCVAR_TYPE_NUMBER:
1063 *pResult = *pArg1;
1064 pResult->u.GCFar.off += (RTGCPTR)pArg2->u.u64Number;
1065 break;
1066 default:
1067 rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
1068 if (RT_FAILURE(rc))
1069 return rc;
1070 rc = dbgcOpAddrFlat(pDbgc, pArg2, &Var);
1071 if (RT_FAILURE(rc))
1072 return rc;
1073 pResult->u.GCFlat += pArg2->u.GCFlat;
1074 break;
1075 }
1076 break;
1077
1078 /*
1079 * GC Phys
1080 */
1081 case DBGCVAR_TYPE_GC_PHYS:
1082 switch (pArg2->enmType)
1083 {
1084 case DBGCVAR_TYPE_HC_FLAT:
1085 case DBGCVAR_TYPE_HC_FAR:
1086 case DBGCVAR_TYPE_HC_PHYS:
1087 return VERR_PARSE_INVALID_OPERATION;
1088 default:
1089 *pResult = *pArg1;
1090 rc = dbgcOpAddrPhys(pDbgc, pArg2, &Var);
1091 if (RT_FAILURE(rc))
1092 return rc;
1093 if (Var.enmType != DBGCVAR_TYPE_GC_PHYS)
1094 return VERR_PARSE_INVALID_OPERATION;
1095 pResult->u.GCPhys += Var.u.GCPhys;
1096 break;
1097 }
1098 break;
1099
1100 /*
1101 * HC Flat
1102 */
1103 case DBGCVAR_TYPE_HC_FLAT:
1104 *pResult = *pArg1;
1105 rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
1106 if (RT_FAILURE(rc))
1107 return rc;
1108 rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
1109 if (RT_FAILURE(rc))
1110 return rc;
1111 pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat + (uintptr_t)Var.u.pvHCFlat;
1112 break;
1113
1114 /*
1115 * HC Far
1116 */
1117 case DBGCVAR_TYPE_HC_FAR:
1118 switch (pArg2->enmType)
1119 {
1120 case DBGCVAR_TYPE_NUMBER:
1121 *pResult = *pArg1;
1122 pResult->u.HCFar.off += (uintptr_t)pArg2->u.u64Number;
1123 break;
1124
1125 default:
1126 rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
1127 if (RT_FAILURE(rc))
1128 return rc;
1129 rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
1130 if (RT_FAILURE(rc))
1131 return rc;
1132 rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
1133 if (RT_FAILURE(rc))
1134 return rc;
1135 pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat + (uintptr_t)Var.u.pvHCFlat;
1136 break;
1137 }
1138 break;
1139
1140 /*
1141 * HC Phys
1142 */
1143 case DBGCVAR_TYPE_HC_PHYS:
1144 *pResult = *pArg1;
1145 rc = dbgcOpAddrHostPhys(pDbgc, pArg2, &Var);
1146 if (RT_FAILURE(rc))
1147 return rc;
1148 pResult->u.HCPhys += Var.u.HCPhys;
1149 break;
1150
1151 /*
1152 * Numbers (see start of function)
1153 */
1154 case DBGCVAR_TYPE_NUMBER:
1155 *pResult = *pArg1;
1156 switch (pArg2->enmType)
1157 {
1158 case DBGCVAR_TYPE_SYMBOL:
1159 case DBGCVAR_TYPE_STRING:
1160 rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
1161 if (RT_FAILURE(rc))
1162 return rc;
1163 case DBGCVAR_TYPE_NUMBER:
1164 pResult->u.u64Number += pArg2->u.u64Number;
1165 break;
1166 default:
1167 return VERR_PARSE_INVALID_OPERATION;
1168 }
1169 break;
1170
1171 default:
1172 return VERR_PARSE_INVALID_OPERATION;
1173
1174 }
1175 return VINF_SUCCESS;
1176}
1177
1178
1179/**
1180 * Subtraction operator (binary).
1181 *
1182 * @returns VINF_SUCCESS on success.
1183 * @returns VBox evaluation / parsing error code on failure.
1184 * The caller does the bitching.
1185 * @param pDbgc Debugger console instance data.
1186 * @param pArg1 The first argument.
1187 * @param pArg2 The 2nd argument.
1188 * @param pResult Where to store the result.
1189 */
1190static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1191{
1192 LogFlow(("dbgcOpSub\n"));
1193
1194 /*
1195 * An subtraction operation will return the left side type in the expression.
1196 * However, if the left hand side is a number and the right hand a pointer of
1197 * some kind we'll convert the left hand side to the same type as the right hand.
1198 * Any strings will be attempted resolved as symbols.
1199 */
1200 DBGCVAR Sym1, Sym2;
1201 if ( pArg2->enmType == DBGCVAR_TYPE_STRING
1202 && ( pArg1->enmType == DBGCVAR_TYPE_NUMBER
1203 || pArg1->enmType == DBGCVAR_TYPE_STRING))
1204 {
1205 int rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_ANY, &Sym2);
1206 if (RT_FAILURE(rc))
1207 return rc;
1208 pArg2 = &Sym2;
1209 }
1210
1211 if (pArg1->enmType == DBGCVAR_TYPE_STRING)
1212 {
1213 DBGCVARTYPE enmType;
1214 switch (pArg2->enmType)
1215 {
1216 case DBGCVAR_TYPE_NUMBER:
1217 enmType = DBGCVAR_TYPE_ANY;
1218 break;
1219 case DBGCVAR_TYPE_GC_FLAT:
1220 case DBGCVAR_TYPE_GC_PHYS:
1221 case DBGCVAR_TYPE_HC_FLAT:
1222 case DBGCVAR_TYPE_HC_PHYS:
1223 enmType = pArg2->enmType;
1224 break;
1225 case DBGCVAR_TYPE_GC_FAR:
1226 enmType = DBGCVAR_TYPE_GC_FLAT;
1227 break;
1228 case DBGCVAR_TYPE_HC_FAR:
1229 enmType = DBGCVAR_TYPE_HC_FLAT;
1230 break;
1231
1232 default:
1233 case DBGCVAR_TYPE_STRING:
1234 AssertMsgFailed(("Can't happen\n"));
1235 enmType = DBGCVAR_TYPE_STRING;
1236 break;
1237 }
1238 if (enmType != DBGCVAR_TYPE_STRING)
1239 {
1240 int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, &Sym1);
1241 if (RT_FAILURE(rc))
1242 return rc;
1243 pArg1 = &Sym1;
1244 }
1245 }
1246 else if (pArg1->enmType == DBGCVAR_TYPE_NUMBER)
1247 {
1248 PFNDBGCOPUNARY pOp = NULL;
1249 switch (pArg2->enmType)
1250 {
1251 case DBGCVAR_TYPE_GC_FAR:
1252 case DBGCVAR_TYPE_GC_FLAT:
1253 pOp = dbgcOpAddrFlat;
1254 break;
1255 case DBGCVAR_TYPE_GC_PHYS:
1256 pOp = dbgcOpAddrPhys;
1257 break;
1258 case DBGCVAR_TYPE_HC_FAR:
1259 case DBGCVAR_TYPE_HC_FLAT:
1260 pOp = dbgcOpAddrHost;
1261 break;
1262 case DBGCVAR_TYPE_HC_PHYS:
1263 pOp = dbgcOpAddrHostPhys;
1264 break;
1265 case DBGCVAR_TYPE_NUMBER:
1266 break;
1267 default:
1268 case DBGCVAR_TYPE_STRING:
1269 AssertMsgFailed(("Can't happen\n"));
1270 break;
1271 }
1272 if (pOp)
1273 {
1274 int rc = pOp(pDbgc, pArg1, &Sym1);
1275 if (RT_FAILURE(rc))
1276 return rc;
1277 pArg1 = &Sym1;
1278 }
1279 }
1280
1281
1282 /*
1283 * Normal processing.
1284 */
1285 int rc;
1286 DBGCVAR Var;
1287 DBGCVAR Var2;
1288 switch (pArg1->enmType)
1289 {
1290 /*
1291 * GC Flat
1292 */
1293 case DBGCVAR_TYPE_GC_FLAT:
1294 switch (pArg2->enmType)
1295 {
1296 case DBGCVAR_TYPE_HC_FLAT:
1297 case DBGCVAR_TYPE_HC_FAR:
1298 case DBGCVAR_TYPE_HC_PHYS:
1299 return VERR_PARSE_INVALID_OPERATION;
1300 default:
1301 *pResult = *pArg1;
1302 rc = dbgcOpAddrFlat(pDbgc, pArg2, &Var);
1303 if (RT_FAILURE(rc))
1304 return rc;
1305 pResult->u.GCFlat -= pArg2->u.GCFlat;
1306 break;
1307 }
1308 break;
1309
1310 /*
1311 * GC Far
1312 */
1313 case DBGCVAR_TYPE_GC_FAR:
1314 switch (pArg2->enmType)
1315 {
1316 case DBGCVAR_TYPE_HC_FLAT:
1317 case DBGCVAR_TYPE_HC_FAR:
1318 case DBGCVAR_TYPE_HC_PHYS:
1319 return VERR_PARSE_INVALID_OPERATION;
1320 case DBGCVAR_TYPE_NUMBER:
1321 *pResult = *pArg1;
1322 pResult->u.GCFar.off -= (RTGCPTR)pArg2->u.u64Number;
1323 break;
1324 default:
1325 rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
1326 if (RT_FAILURE(rc))
1327 return rc;
1328 rc = dbgcOpAddrFlat(pDbgc, pArg2, &Var);
1329 if (RT_FAILURE(rc))
1330 return rc;
1331 pResult->u.GCFlat -= pArg2->u.GCFlat;
1332 break;
1333 }
1334 break;
1335
1336 /*
1337 * GC Phys
1338 */
1339 case DBGCVAR_TYPE_GC_PHYS:
1340 switch (pArg2->enmType)
1341 {
1342 case DBGCVAR_TYPE_HC_FLAT:
1343 case DBGCVAR_TYPE_HC_FAR:
1344 case DBGCVAR_TYPE_HC_PHYS:
1345 return VERR_PARSE_INVALID_OPERATION;
1346 default:
1347 *pResult = *pArg1;
1348 rc = dbgcOpAddrPhys(pDbgc, pArg2, &Var);
1349 if (RT_FAILURE(rc))
1350 return rc;
1351 if (Var.enmType != DBGCVAR_TYPE_GC_PHYS)
1352 return VERR_PARSE_INVALID_OPERATION;
1353 pResult->u.GCPhys -= Var.u.GCPhys;
1354 break;
1355 }
1356 break;
1357
1358 /*
1359 * HC Flat
1360 */
1361 case DBGCVAR_TYPE_HC_FLAT:
1362 *pResult = *pArg1;
1363 rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
1364 if (RT_FAILURE(rc))
1365 return rc;
1366 rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
1367 if (RT_FAILURE(rc))
1368 return rc;
1369 pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat - (uintptr_t)Var.u.pvHCFlat;
1370 break;
1371
1372 /*
1373 * HC Far
1374 */
1375 case DBGCVAR_TYPE_HC_FAR:
1376 switch (pArg2->enmType)
1377 {
1378 case DBGCVAR_TYPE_NUMBER:
1379 *pResult = *pArg1;
1380 pResult->u.HCFar.off -= (uintptr_t)pArg2->u.u64Number;
1381 break;
1382
1383 default:
1384 rc = dbgcOpAddrFlat(pDbgc, pArg1, pResult);
1385 if (RT_FAILURE(rc))
1386 return rc;
1387 rc = dbgcOpAddrHost(pDbgc, pArg2, &Var2);
1388 if (RT_FAILURE(rc))
1389 return rc;
1390 rc = dbgcOpAddrFlat(pDbgc, &Var2, &Var);
1391 if (RT_FAILURE(rc))
1392 return rc;
1393 pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat - (uintptr_t)Var.u.pvHCFlat;
1394 break;
1395 }
1396 break;
1397
1398 /*
1399 * HC Phys
1400 */
1401 case DBGCVAR_TYPE_HC_PHYS:
1402 *pResult = *pArg1;
1403 rc = dbgcOpAddrHostPhys(pDbgc, pArg2, &Var);
1404 if (RT_FAILURE(rc))
1405 return rc;
1406 pResult->u.HCPhys -= Var.u.HCPhys;
1407 break;
1408
1409 /*
1410 * Numbers (see start of function)
1411 */
1412 case DBGCVAR_TYPE_NUMBER:
1413 *pResult = *pArg1;
1414 switch (pArg2->enmType)
1415 {
1416 case DBGCVAR_TYPE_SYMBOL:
1417 case DBGCVAR_TYPE_STRING:
1418 rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
1419 if (RT_FAILURE(rc))
1420 return rc;
1421 case DBGCVAR_TYPE_NUMBER:
1422 pResult->u.u64Number -= pArg2->u.u64Number;
1423 break;
1424 default:
1425 return VERR_PARSE_INVALID_OPERATION;
1426 }
1427 break;
1428
1429 default:
1430 return VERR_PARSE_INVALID_OPERATION;
1431
1432 }
1433 return VINF_SUCCESS;
1434}
1435
1436
1437/**
1438 * Bitwise shift left operator (binary).
1439 *
1440 * @returns VINF_SUCCESS on success.
1441 * @returns VBox evaluation / parsing error code on failure.
1442 * The caller does the bitching.
1443 * @param pDbgc Debugger console instance data.
1444 * @param pArg1 The first argument.
1445 * @param pArg2 The 2nd argument.
1446 * @param pResult Where to store the result.
1447 */
1448static DECLCALLBACK(int) dbgcOpBitwiseShiftLeft(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1449{
1450 LogFlow(("dbgcOpBitwiseShiftLeft\n"));
1451 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, <<, false);
1452}
1453
1454
1455/**
1456 * Bitwise shift right operator (binary).
1457 *
1458 * @returns VINF_SUCCESS on success.
1459 * @returns VBox evaluation / parsing error code on failure.
1460 * The caller does the bitching.
1461 * @param pDbgc Debugger console instance data.
1462 * @param pArg1 The first argument.
1463 * @param pArg2 The 2nd argument.
1464 * @param pResult Where to store the result.
1465 */
1466static DECLCALLBACK(int) dbgcOpBitwiseShiftRight(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1467{
1468 LogFlow(("dbgcOpBitwiseShiftRight\n"));
1469 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, >>, false);
1470}
1471
1472
1473/**
1474 * Bitwise and operator (binary).
1475 *
1476 * @returns VINF_SUCCESS on success.
1477 * @returns VBox evaluation / parsing error code on failure.
1478 * The caller does the bitching.
1479 * @param pDbgc Debugger console instance data.
1480 * @param pArg1 The first argument.
1481 * @param pArg2 The 2nd argument.
1482 * @param pResult Where to store the result.
1483 */
1484static DECLCALLBACK(int) dbgcOpBitwiseAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1485{
1486 LogFlow(("dbgcOpBitwiseAnd\n"));
1487 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2);
1488 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, &, false);
1489}
1490
1491
1492/**
1493 * Bitwise exclusive or operator (binary).
1494 *
1495 * @returns VINF_SUCCESS on success.
1496 * @returns VBox evaluation / parsing error code on failure.
1497 * The caller does the bitching.
1498 * @param pDbgc Debugger console instance data.
1499 * @param pArg1 The first argument.
1500 * @param pArg2 The 2nd argument.
1501 * @param pResult Where to store the result.
1502 */
1503static DECLCALLBACK(int) dbgcOpBitwiseXor(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1504{
1505 LogFlow(("dbgcOpBitwiseXor\n"));
1506 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2);
1507 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, ^, false);
1508}
1509
1510
1511/**
1512 * Bitwise inclusive or operator (binary).
1513 *
1514 * @returns VINF_SUCCESS on success.
1515 * @returns VBox evaluation / parsing error code on failure.
1516 * The caller does the bitching.
1517 * @param pDbgc Debugger console instance data.
1518 * @param pArg1 The first argument.
1519 * @param pArg2 The 2nd argument.
1520 * @param pResult Where to store the result.
1521 */
1522static DECLCALLBACK(int) dbgcOpBitwiseOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1523{
1524 LogFlow(("dbgcOpBitwiseOr\n"));
1525 DBGC_GEN_ARIT_POINTER_TO_THE_LEFT(pArg1, pArg2);
1526 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, |, false);
1527}
1528
1529
1530/**
1531 * Boolean and operator (binary).
1532 *
1533 * @returns VINF_SUCCESS on success.
1534 * @returns VBox evaluation / parsing error code on failure.
1535 * The caller does the bitching.
1536 * @param pDbgc Debugger console instance data.
1537 * @param pArg1 The first argument.
1538 * @param pArg2 The 2nd argument.
1539 * @param pResult Where to store the result.
1540 */
1541static DECLCALLBACK(int) dbgcOpBooleanAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1542{
1543 LogFlow(("dbgcOpBooleanAnd\n"));
1544 /** @todo force numeric return value? */
1545 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, &&, false);
1546}
1547
1548
1549/**
1550 * Boolean or operator (binary).
1551 *
1552 * @returns VINF_SUCCESS on success.
1553 * @returns VBox evaluation / parsing error code on failure.
1554 * The caller does the bitching.
1555 * @param pDbgc Debugger console instance data.
1556 * @param pArg1 The first argument.
1557 * @param pArg2 The 2nd argument.
1558 * @param pResult Where to store the result.
1559 */
1560static DECLCALLBACK(int) dbgcOpBooleanOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1561{
1562 LogFlow(("dbgcOpBooleanOr\n"));
1563 /** @todo force numeric return value? */
1564 DBGC_GEN_ARIT_BINARY_OP(pDbgc, pArg1, pArg2, pResult, ||, false);
1565}
1566
1567
1568/**
1569 * Range to operator (binary).
1570 *
1571 * @returns VINF_SUCCESS on success.
1572 * @returns VBox evaluation / parsing error code on failure.
1573 * The caller does the bitching.
1574 * @param pDbgc Debugger console instance data.
1575 * @param pArg1 The first argument.
1576 * @param pArg2 The 2nd argument.
1577 * @param pResult Where to store the result.
1578 */
1579static DECLCALLBACK(int) dbgcOpRangeLength(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1580{
1581 LogFlow(("dbgcOpRangeLength\n"));
1582
1583 /*
1584 * Make result. Strings needs to be resolved into symbols.
1585 */
1586 if (pArg1->enmType == DBGCVAR_TYPE_STRING)
1587 {
1588 int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, pResult);
1589 if (RT_FAILURE(rc))
1590 return rc;
1591 }
1592 else
1593 *pResult = *pArg1;
1594
1595 /*
1596 * Convert 2nd argument to element count.
1597 */
1598 pResult->enmRangeType = DBGCVAR_RANGE_ELEMENTS;
1599 switch (pArg2->enmType)
1600 {
1601 case DBGCVAR_TYPE_NUMBER:
1602 pResult->u64Range = pArg2->u.u64Number;
1603 break;
1604
1605 case DBGCVAR_TYPE_STRING:
1606 {
1607 int rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, pResult);
1608 if (RT_FAILURE(rc))
1609 return rc;
1610 pResult->u64Range = pArg2->u.u64Number;
1611 break;
1612 }
1613
1614 default:
1615 return VERR_PARSE_INVALID_OPERATION;
1616 }
1617
1618 return VINF_SUCCESS;
1619}
1620
1621
1622/**
1623 * Range to operator (binary).
1624 *
1625 * @returns VINF_SUCCESS on success.
1626 * @returns VBox evaluation / parsing error code on failure.
1627 * The caller does the bitching.
1628 * @param pDbgc Debugger console instance data.
1629 * @param pArg1 The first argument.
1630 * @param pArg2 The 2nd argument.
1631 * @param pResult Where to store the result.
1632 */
1633static DECLCALLBACK(int) dbgcOpRangeLengthBytes(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1634{
1635 LogFlow(("dbgcOpRangeLengthBytes\n"));
1636 int rc = dbgcOpRangeLength(pDbgc, pArg1, pArg2, pResult);
1637 if (RT_SUCCESS(rc))
1638 pResult->enmRangeType = DBGCVAR_RANGE_BYTES;
1639 return rc;
1640}
1641
1642
1643/**
1644 * Range to operator (binary).
1645 *
1646 * @returns VINF_SUCCESS on success.
1647 * @returns VBox evaluation / parsing error code on failure.
1648 * The caller does the bitching.
1649 * @param pDbgc Debugger console instance data.
1650 * @param pArg1 The first argument.
1651 * @param pArg2 The 2nd argument.
1652 * @param pResult Where to store the result.
1653 */
1654static DECLCALLBACK(int) dbgcOpRangeTo(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
1655{
1656 LogFlow(("dbgcOpRangeTo\n"));
1657
1658 /*
1659 * Calc number of bytes between the two args.
1660 */
1661 DBGCVAR Diff;
1662 int rc = dbgcOpSub(pDbgc, pArg2, pArg1, &Diff);
1663 if (RT_FAILURE(rc))
1664 return rc;
1665
1666 /*
1667 * Use the diff as the range of Arg1.
1668 */
1669 *pResult = *pArg1;
1670 pResult->enmRangeType = DBGCVAR_RANGE_BYTES;
1671 switch (Diff.enmType)
1672 {
1673 case DBGCVAR_TYPE_GC_FLAT:
1674 pResult->u64Range = (RTGCUINTPTR)Diff.u.GCFlat;
1675 break;
1676 case DBGCVAR_TYPE_GC_PHYS:
1677 pResult->u64Range = Diff.u.GCPhys;
1678 break;
1679 case DBGCVAR_TYPE_HC_FLAT:
1680 pResult->u64Range = (uintptr_t)Diff.u.pvHCFlat;
1681 break;
1682 case DBGCVAR_TYPE_HC_PHYS:
1683 pResult->u64Range = Diff.u.HCPhys;
1684 break;
1685 case DBGCVAR_TYPE_NUMBER:
1686 pResult->u64Range = Diff.u.u64Number;
1687 break;
1688
1689 case DBGCVAR_TYPE_GC_FAR:
1690 case DBGCVAR_TYPE_STRING:
1691 case DBGCVAR_TYPE_HC_FAR:
1692 default:
1693 AssertMsgFailed(("Impossible!\n"));
1694 return VERR_PARSE_INVALID_OPERATION;
1695 }
1696
1697 return VINF_SUCCESS;
1698}
1699
1700
1701/**
1702 * Searches for an operator descriptor which matches the start of
1703 * the expression given us.
1704 *
1705 * @returns Pointer to the operator on success.
1706 * @param pDbgc The debug console instance.
1707 * @param pszExpr Pointer to the expression string which might start with an operator.
1708 * @param fPreferBinary Whether to favour binary or unary operators.
1709 * Caller must assert that it's the desired type! Both types will still
1710 * be returned, this is only for resolving duplicates.
1711 * @param chPrev The previous char. Some operators requires a blank in front of it.
1712 */
1713PCDBGCOP dbgcOperatorLookup(PDBGC pDbgc, const char *pszExpr, bool fPreferBinary, char chPrev)
1714{
1715 PCDBGCOP pOp = NULL;
1716 for (unsigned iOp = 0; iOp < RT_ELEMENTS(g_aOps); iOp++)
1717 {
1718 if ( g_aOps[iOp].szName[0] == pszExpr[0]
1719 && (!g_aOps[iOp].szName[1] || g_aOps[iOp].szName[1] == pszExpr[1])
1720 && (!g_aOps[iOp].szName[2] || g_aOps[iOp].szName[2] == pszExpr[2]))
1721 {
1722 /*
1723 * Check that we don't mistake it for some other operator which have more chars.
1724 */
1725 unsigned j;
1726 for (j = iOp + 1; j < RT_ELEMENTS(g_aOps); j++)
1727 if ( g_aOps[j].cchName > g_aOps[iOp].cchName
1728 && g_aOps[j].szName[0] == pszExpr[0]
1729 && (!g_aOps[j].szName[1] || g_aOps[j].szName[1] == pszExpr[1])
1730 && (!g_aOps[j].szName[2] || g_aOps[j].szName[2] == pszExpr[2]) )
1731 break;
1732 if (j < RT_ELEMENTS(g_aOps))
1733 continue; /* we'll catch it later. (for theoretical +,++,+++ cases.) */
1734 pOp = &g_aOps[iOp];
1735
1736 /*
1737 * Preferred type?
1738 */
1739 if (g_aOps[iOp].fBinary == fPreferBinary)
1740 break;
1741 }
1742 }
1743
1744 if (pOp)
1745 Log2(("dbgcOperatorLookup: pOp=%p %s\n", pOp, pOp->szName));
1746 NOREF(pDbgc); NOREF(chPrev);
1747 return pOp;
1748}
1749
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