VirtualBox

source: vbox/trunk/src/VBox/Debugger/DBGCBuiltInSymbols.cpp@ 6290

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

The Giant CDDL Dual-License Header Change, fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.7 KB
Line 
1/** $Id: DBGCBuiltInSymbols.cpp 6000 2007-12-07 15:12:49Z vboxsync $ */
2/** @file
3 * DBGC - Debugger Console, Built-In Symbols.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_DBGC
23#include <VBox/dbg.h>
24#include <VBox/dbgf.h>
25#include <VBox/vm.h>
26#include <VBox/vmm.h>
27#include <VBox/mm.h>
28#include <VBox/pgm.h>
29#include <VBox/selm.h>
30#include <VBox/dis.h>
31#include <VBox/param.h>
32#include <VBox/err.h>
33#include <VBox/log.h>
34
35#include <iprt/alloc.h>
36#include <iprt/alloca.h>
37#include <iprt/string.h>
38#include <iprt/assert.h>
39#include <iprt/ctype.h>
40
41#include <stdlib.h>
42#include <stdio.h>
43
44#include "DBGCInternal.h"
45
46
47/*******************************************************************************
48* Internal Functions *
49*******************************************************************************/
50static DECLCALLBACK(int) dbgcSymGetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, DBGCVARTYPE enmType, PDBGCVAR pResult);
51static DECLCALLBACK(int) dbgcSymSetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pValue);
52
53
54/*******************************************************************************
55* Global Variables *
56*******************************************************************************/
57/** Register symbol uUser value.
58 * @{
59 */
60/** If set the register set is the hypervisor and not the guest one. */
61#define SYMREG_FLAGS_HYPER RT_BIT(20)
62/** If set a far conversion of the value will use the high 16 bit for the selector.
63 * If clear the low 16 bit will be used. */
64#define SYMREG_FLAGS_HIGH_SEL RT_BIT(21)
65/** The shift value to calc the size of a register symbol from the uUser value. */
66#define SYMREG_SIZE_SHIFT (24)
67/** Get the offset */
68#define SYMREG_OFFSET(uUser) (uUser & ((1 << 20) - 1))
69/** Get the size. */
70#define SYMREG_SIZE(uUser) ((uUser >> SYMREG_SIZE_SHIFT) & 0xff)
71/** 1 byte. */
72#define SYMREG_SIZE_1 ( 1 << SYMREG_SIZE_SHIFT)
73/** 2 byte. */
74#define SYMREG_SIZE_2 ( 2 << SYMREG_SIZE_SHIFT)
75/** 4 byte. */
76#define SYMREG_SIZE_4 ( 4 << SYMREG_SIZE_SHIFT)
77/** 6 byte. */
78#define SYMREG_SIZE_6 ( 6 << SYMREG_SIZE_SHIFT)
79/** 8 byte. */
80#define SYMREG_SIZE_8 ( 8 << SYMREG_SIZE_SHIFT)
81/** 12 byte. */
82#define SYMREG_SIZE_12 (12 << SYMREG_SIZE_SHIFT)
83/** 16 byte. */
84#define SYMREG_SIZE_16 (16 << SYMREG_SIZE_SHIFT)
85/** @} */
86
87/** Builtin Symbols.
88 * ASSUMES little endian register representation!
89 */
90static const DBGCSYM g_aSyms[] =
91{
92 { "eax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_4 },
93 { "ax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_2 },
94 { "al", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_1 },
95 { "ah", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, eax) + 1)| SYMREG_SIZE_1 },
96
97 { "ebx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_4 },
98 { "bx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_2 },
99 { "bl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_1 },
100 { "bh", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, ebx) + 1)| SYMREG_SIZE_1 },
101
102 { "ecx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_4 },
103 { "cx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_2 },
104 { "cl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_1 },
105 { "ch", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, ecx) + 1)| SYMREG_SIZE_1 },
106
107 { "edx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_4 },
108 { "dx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_2 },
109 { "dl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_1 },
110 { "dh", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, edx) + 1)| SYMREG_SIZE_1 },
111
112 { "edi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_4 },
113 { "di", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_2 },
114
115 { "esi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_4 },
116 { "si", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_2 },
117
118 { "ebp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_4 },
119 { "bp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_2 },
120
121 { "esp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_4 },
122 { "sp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_2 },
123
124 { "eip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eip) | SYMREG_SIZE_4 },
125 { "ip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eip) | SYMREG_SIZE_2 },
126
127 { "efl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_4 },
128 { "eflags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_4 },
129 { "fl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_2 },
130 { "flags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_2 },
131
132 { "cs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cs) | SYMREG_SIZE_2 },
133 { "ds", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ds) | SYMREG_SIZE_2 },
134 { "es", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, es) | SYMREG_SIZE_2 },
135 { "fs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, fs) | SYMREG_SIZE_2 },
136 { "gs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gs) | SYMREG_SIZE_2 },
137 { "ss", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ss) | SYMREG_SIZE_2 },
138
139 { "cr0", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr0) | SYMREG_SIZE_4 },
140 { "cr2", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr2) | SYMREG_SIZE_4 },
141 { "cr3", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr3) | SYMREG_SIZE_4 },
142 { "cr4", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr4) | SYMREG_SIZE_4 },
143
144 { "tr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, tr) | SYMREG_SIZE_2 },
145 { "ldtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ldtr) | SYMREG_SIZE_2 },
146
147 { "gdtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr) | SYMREG_SIZE_6 },
148 { "gdtr.limit", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr.cbGdt)| SYMREG_SIZE_2 },
149 { "gdtr.base", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr.pGdt)| SYMREG_SIZE_4 },
150
151 { "idtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr) | SYMREG_SIZE_6 },
152 { "idtr.limit", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr.cbIdt)| SYMREG_SIZE_2 },
153 { "idtr.base", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr.pIdt)| SYMREG_SIZE_4 },
154
155 /* hypervisor */
156
157 {".eax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
158 {".ax", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
159 {".al", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eax) | SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
160 {".ah", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, eax) + 1)| SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
161
162 {".ebx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
163 {".bx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
164 {".bl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebx) | SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
165 {".bh", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, ebx) + 1)| SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
166
167 {".ecx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
168 {".cx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
169 {".cl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ecx) | SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
170 {".ch", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, ecx) + 1)| SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
171
172 {".edx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
173 {".dx", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
174 {".dl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edx) | SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
175 {".dh", dbgcSymGetReg, dbgcSymSetReg, (offsetof(CPUMCTX, edx) + 1)| SYMREG_SIZE_1 | SYMREG_FLAGS_HYPER },
176
177 {".edi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
178 {".di", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, edi) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
179
180 {".esi", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
181 {".si", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esi) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
182
183 {".ebp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
184 {".bp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ebp) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
185
186 {".esp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
187 {".sp", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, esp) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
188
189 {".eip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eip) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
190 {".ip", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eip) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
191
192 {".efl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
193 {".eflags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
194 {".fl", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
195 {".flags", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, eflags) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
196
197 {".cs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cs) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
198 {".ds", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ds) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
199 {".es", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, es) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
200 {".fs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, fs) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
201 {".gs", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gs) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
202 {".ss", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ss) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
203
204 {".cr0", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr0) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
205 {".cr2", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr2) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
206 {".cr3", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr3) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
207 {".cr4", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, cr4) | SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
208
209 {".tr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, tr) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
210 {".ldtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, ldtr) | SYMREG_SIZE_2 | SYMREG_FLAGS_HYPER },
211
212 {".gdtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr) | SYMREG_SIZE_6 | SYMREG_FLAGS_HYPER },
213 {".gdtr.limit", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr.cbGdt)| SYMREG_SIZE_2| SYMREG_FLAGS_HYPER },
214 {".gdtr.base", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, gdtr.pGdt)| SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
215
216 {".idtr", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr) | SYMREG_SIZE_6 | SYMREG_FLAGS_HYPER },
217 {".idtr.limit", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr.cbIdt)| SYMREG_SIZE_2| SYMREG_FLAGS_HYPER },
218 {".idtr.base", dbgcSymGetReg, dbgcSymSetReg, offsetof(CPUMCTX, idtr.pIdt)| SYMREG_SIZE_4 | SYMREG_FLAGS_HYPER },
219
220};
221
222
223
224/**
225 * Get builtin register symbol.
226 *
227 * The uUser is special for these symbol descriptors. See the SYMREG_* \#defines.
228 *
229 * @returns 0 on success.
230 * @returns VBox evaluation / parsing error code on failure.
231 * The caller does the bitching.
232 * @param pSymDesc Pointer to the symbol descriptor.
233 * @param pCmdHlp Pointer to the command callback structure.
234 * @param enmType The result type.
235 * @param pResult Where to store the result.
236 */
237static DECLCALLBACK(int) dbgcSymGetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, DBGCVARTYPE enmType, PDBGCVAR pResult)
238{
239 LogFlow(("dbgcSymSetReg: pSymDesc->pszName=%d\n", pSymDesc->pszName));
240
241 /*
242 * pVM is required.
243 */
244 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
245 Assert(pDbgc->pVM);
246
247 /*
248 * Get the right CPU context.
249 */
250 PCPUMCTX pCtx;
251 int rc;
252 if (!(pSymDesc->uUser & SYMREG_FLAGS_HYPER))
253 rc = CPUMQueryGuestCtxPtr(pDbgc->pVM, &pCtx);
254 else
255 rc = CPUMQueryHyperCtxPtr(pDbgc->pVM, &pCtx);
256 if (VBOX_FAILURE(rc))
257 return rc;
258
259 /*
260 * Get the value.
261 */
262 void *pvValue = (char *)pCtx + SYMREG_OFFSET(pSymDesc->uUser);
263 uint64_t u64;
264 switch (SYMREG_SIZE(pSymDesc->uUser))
265 {
266 case 1: u64 = *(uint8_t *)pvValue; break;
267 case 2: u64 = *(uint16_t *)pvValue; break;
268 case 4: u64 = *(uint32_t *)pvValue; break;
269 case 6: u64 = *(uint32_t *)pvValue | ((uint64_t)*(uint16_t *)((char *)pvValue + sizeof(uint32_t)) << 32); break;
270 case 8: u64 = *(uint64_t *)pvValue; break;
271 default:
272 return VERR_PARSE_NOT_IMPLEMENTED;
273 }
274
275 /*
276 * Construct the desired result.
277 */
278 if (enmType == DBGCVAR_TYPE_ANY)
279 enmType = DBGCVAR_TYPE_NUMBER;
280 pResult->pDesc = NULL;
281 pResult->pNext = NULL;
282 pResult->enmType = enmType;
283 pResult->enmRangeType = DBGCVAR_RANGE_NONE;
284 pResult->u64Range = 0;
285
286 switch (enmType)
287 {
288 case DBGCVAR_TYPE_GC_FLAT:
289 pResult->u.GCFlat = (RTGCPTR)u64;
290 break;
291
292 case DBGCVAR_TYPE_GC_FAR:
293 switch (SYMREG_SIZE(pSymDesc->uUser))
294 {
295 case 4:
296 if (!(pSymDesc->uUser & SYMREG_FLAGS_HIGH_SEL))
297 {
298 pResult->u.GCFar.off = (uint16_t)u64;
299 pResult->u.GCFar.sel = (uint16_t)(u64 >> 16);
300 }
301 else
302 {
303 pResult->u.GCFar.sel = (uint16_t)u64;
304 pResult->u.GCFar.off = (uint16_t)(u64 >> 16);
305 }
306 break;
307 case 6:
308 if (!(pSymDesc->uUser & SYMREG_FLAGS_HIGH_SEL))
309 {
310 pResult->u.GCFar.off = (uint32_t)u64;
311 pResult->u.GCFar.sel = (uint16_t)(u64 >> 32);
312 }
313 else
314 {
315 pResult->u.GCFar.sel = (uint32_t)u64;
316 pResult->u.GCFar.off = (uint16_t)(u64 >> 32);
317 }
318 break;
319
320 default:
321 return VERR_PARSE_BAD_RESULT_TYPE;
322 }
323 break;
324
325 case DBGCVAR_TYPE_GC_PHYS:
326 pResult->u.GCPhys = (RTGCPHYS)u64;
327 break;
328
329 case DBGCVAR_TYPE_HC_FLAT:
330 pResult->u.pvHCFlat = (void *)(uintptr_t)u64;
331 break;
332
333 case DBGCVAR_TYPE_HC_FAR:
334 switch (SYMREG_SIZE(pSymDesc->uUser))
335 {
336 case 4:
337 if (!(pSymDesc->uUser & SYMREG_FLAGS_HIGH_SEL))
338 {
339 pResult->u.HCFar.off = (uint16_t)u64;
340 pResult->u.HCFar.sel = (uint16_t)(u64 >> 16);
341 }
342 else
343 {
344 pResult->u.HCFar.sel = (uint16_t)u64;
345 pResult->u.HCFar.off = (uint16_t)(u64 >> 16);
346 }
347 break;
348 case 6:
349 if (!(pSymDesc->uUser & SYMREG_FLAGS_HIGH_SEL))
350 {
351 pResult->u.HCFar.off = (uint32_t)u64;
352 pResult->u.HCFar.sel = (uint16_t)(u64 >> 32);
353 }
354 else
355 {
356 pResult->u.HCFar.sel = (uint32_t)u64;
357 pResult->u.HCFar.off = (uint16_t)(u64 >> 32);
358 }
359 break;
360
361 default:
362 return VERR_PARSE_BAD_RESULT_TYPE;
363 }
364 break;
365
366 case DBGCVAR_TYPE_HC_PHYS:
367 pResult->u.GCPhys = (RTGCPHYS)u64;
368 break;
369
370 case DBGCVAR_TYPE_NUMBER:
371 pResult->u.u64Number = u64;
372 break;
373
374 case DBGCVAR_TYPE_STRING:
375 case DBGCVAR_TYPE_UNKNOWN:
376 default:
377 return VERR_PARSE_BAD_RESULT_TYPE;
378
379 }
380
381 return 0;
382}
383
384
385/**
386 * Set builtin register symbol.
387 *
388 * The uUser is special for these symbol descriptors. See the SYMREG_* #defines.
389 *
390 * @returns 0 on success.
391 * @returns VBox evaluation / parsing error code on failure.
392 * The caller does the bitching.
393 * @param pSymDesc Pointer to the symbol descriptor.
394 * @param pCmdHlp Pointer to the command callback structure.
395 * @param pValue The value to assign the symbol.
396 */
397static DECLCALLBACK(int) dbgcSymSetReg(PCDBGCSYM pSymDesc, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pValue)
398{
399 LogFlow(("dbgcSymSetReg: pSymDesc->pszName=%d\n", pSymDesc->pszName));
400
401 /*
402 * pVM is required.
403 */
404 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
405 Assert(pDbgc->pVM);
406
407 /*
408 * Get the right CPU context.
409 */
410 PCPUMCTX pCtx;
411 int rc;
412 if (!(pSymDesc->uUser & SYMREG_FLAGS_HYPER))
413 rc = CPUMQueryGuestCtxPtr(pDbgc->pVM, &pCtx);
414 else
415 rc = CPUMQueryHyperCtxPtr(pDbgc->pVM, &pCtx);
416 if (VBOX_FAILURE(rc))
417 return rc;
418
419 /*
420 * Check the new value.
421 */
422 if (pValue->enmType != DBGCVAR_TYPE_NUMBER)
423 return VERR_PARSE_ARGUMENT_TYPE_MISMATCH;
424
425 /*
426 * Set the value.
427 */
428 void *pvValue = (char *)pCtx + SYMREG_OFFSET(pSymDesc->uUser);
429 switch (SYMREG_SIZE(pSymDesc->uUser))
430 {
431 case 1:
432 *(uint8_t *)pvValue = (uint8_t)pValue->u.u64Number;
433 break;
434 case 2:
435 *(uint16_t *)pvValue = (uint16_t)pValue->u.u64Number;
436 break;
437 case 4:
438 *(uint32_t *)pvValue = (uint32_t)pValue->u.u64Number;
439 break;
440 case 6:
441 *(uint32_t *)pvValue = (uint32_t)pValue->u.u64Number;
442 ((uint16_t *)pvValue)[3] = (uint16_t)(pValue->u.u64Number >> 32);
443 break;
444 case 8:
445 *(uint64_t *)pvValue = pValue->u.u64Number;
446 break;
447 default:
448 return VERR_PARSE_NOT_IMPLEMENTED;
449 }
450
451 return VINF_SUCCESS;
452}
453
454
455/**
456 * Finds a builtin symbol.
457 * @returns Pointer to symbol descriptor on success.
458 * @returns NULL on failure.
459 * @param pDbgc The debug console instance.
460 * @param pszSymbol The symbol name.
461 */
462PCDBGCSYM dbgcLookupRegisterSymbol(PDBGC pDbgc, const char *pszSymbol)
463{
464 for (unsigned iSym = 0; iSym < ELEMENTS(g_aSyms); iSym++)
465 if (!strcmp(pszSymbol, g_aSyms[iSym].pszName))
466 return &g_aSyms[iSym];
467
468 /** @todo externally registered symbols. */
469 NOREF(pDbgc);
470 return NULL;
471}
472
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