VirtualBox

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

最後變更 在這個檔案從5999是 5999,由 vboxsync 提交於 17 年 前

The Giant CDDL Dual-License Header Change.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette