VirtualBox

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

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

DBGF,CPUM,DBGC: Use DBGFReg in the debugger, stop accessing CPUMCTX structures directly when messing with registers.

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