VirtualBox

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

Last change on this file since 9713 was 9430, checked in by vboxsync, 16 years ago

Made the base of GDTR and IDTR 64 bits.

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