VirtualBox

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

Last change on this file since 7218 was 6000, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change, fixes.

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