VirtualBox

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

Last change on this file since 8234 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

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