VirtualBox

source: vbox/trunk/src/VBox/VMM/DBGFReg.cpp@ 32319

Last change on this file since 32319 was 31491, checked in by vboxsync, 14 years ago

DBGF: Kick-off for DBGFR3Reg*. Implemented simple queried only. The debugger + MachineDebugger will use only this API later on.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.6 KB
Line 
1/* $Id: DBGFReg.cpp 31491 2010-08-09 16:13:37Z vboxsync $ */
2/** @file
3 * DBGF - Debugger Facility, Register Methods.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
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_DBGF
23#include <VBox/dbgf.h>
24#include "DBGFInternal.h"
25#include <VBox/vm.h>
26#include <VBox/param.h>
27#include <VBox/err.h>
28#include <VBox/log.h>
29
30
31/*******************************************************************************
32* Defined Constants And Macros *
33*******************************************************************************/
34/** @name Register and value sizes used by dbgfR3RegQueryWorker and
35 * dbgfR3RegSetWorker.
36 * @{ */
37#define R_SZ_8 RT_BIT(0)
38#define R_SZ_16 RT_BIT(1)
39#define R_SZ_32 RT_BIT(2)
40#define R_SZ_64 RT_BIT(3)
41#define R_SZ_64_16 RT_BIT(4)
42#define R_SZ_8_TO_64 (R_SZ_8 | R_SZ_16 | R_SZ_32 | R_SZ_64)
43#define R_SZ_16_TO_64 (R_SZ_16 | R_SZ_32 | R_SZ_64)
44#define R_SZ_32_OR_64 (R_SZ_32 | R_SZ_64)
45/** @} */
46
47
48/**
49 * Wrapper around CPUMQueryGuestMsr.
50 *
51 * @retval VINF_SUCCESS
52 * @retval VERR_DBGF_INVALID_REGISTER
53 *
54 * @param pVCpu The current CPU.
55 * @param pu64 Where to store the register value.
56 * @param pfRegSizes Where to store the register sizes.
57 * @param idMsr The MSR to get.
58 */
59static uint64_t dbgfR3RegGetMsr(PVMCPU pVCpu, uint64_t *pu64, uint32_t *pfRegSizes, uint32_t idMsr)
60{
61 *pfRegSizes = R_SZ_64;
62 int rc = CPUMQueryGuestMsr(pVCpu, idMsr, pu64);
63 if (RT_FAILURE(rc))
64 {
65 AssertMsg(rc == VERR_CPUM_RAISE_GP_0, ("%Rrc\n", rc));
66 *pu64 = 0;
67 }
68 return VINF_SUCCESS;
69}
70
71/**
72 * Worker for DBGFR3RegQueryU8, DBGFR3RegQueryU16, DBGFR3RegQueryU32 and
73 * DBGFR3RegQueryU64.
74 *
75 * @param pVM The VM handle.
76 * @param idCpu The target CPU ID.
77 * @param enmReg The register that's being queried.
78 * @param pu64 Where to store the register value.
79 * @param pfRegSizes Where to store the register sizes.
80 */
81static DECLCALLBACK(int) dbgfR3RegQueryWorker(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64, uint32_t *pfRegSizes)
82{
83 PVMCPU pVCpu = &pVM->aCpus[idCpu];
84 PCCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
85 switch (enmReg)
86 {
87 case DBGFREG_RAX: *pu64 = pCtx->rax; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
88 case DBGFREG_RCX: *pu64 = pCtx->rcx; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
89 case DBGFREG_RDX: *pu64 = pCtx->rdx; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
90 case DBGFREG_RBX: *pu64 = pCtx->rbx; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
91 case DBGFREG_RSP: *pu64 = pCtx->rsp; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
92 case DBGFREG_RBP: *pu64 = pCtx->rbp; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
93 case DBGFREG_RSI: *pu64 = pCtx->rsi; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
94 case DBGFREG_RDI: *pu64 = pCtx->rdi; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
95 case DBGFREG_R8: *pu64 = pCtx->r8; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
96 case DBGFREG_R9: *pu64 = pCtx->r9; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
97 case DBGFREG_R10: *pu64 = pCtx->r10; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
98 case DBGFREG_R11: *pu64 = pCtx->r11; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
99 case DBGFREG_R12: *pu64 = pCtx->r12; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
100 case DBGFREG_R13: *pu64 = pCtx->r13; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
101 case DBGFREG_R14: *pu64 = pCtx->r14; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
102 case DBGFREG_R15: *pu64 = pCtx->r15; *pfRegSizes = R_SZ_8_TO_64; return VINF_SUCCESS;
103
104 case DBGFREG_AH: *pu64 = RT_BYTE2(pCtx->ax); *pfRegSizes = R_SZ_8; return VINF_SUCCESS;
105 case DBGFREG_CH: *pu64 = RT_BYTE2(pCtx->cx); *pfRegSizes = R_SZ_8; return VINF_SUCCESS;
106 case DBGFREG_DH: *pu64 = RT_BYTE2(pCtx->dx); *pfRegSizes = R_SZ_8; return VINF_SUCCESS;
107 case DBGFREG_BH: *pu64 = RT_BYTE2(pCtx->bx); *pfRegSizes = R_SZ_8; return VINF_SUCCESS;
108
109 case DBGFREG_CS: *pu64 = pCtx->cs; *pfRegSizes = R_SZ_16; return VINF_SUCCESS;
110 case DBGFREG_DS: *pu64 = pCtx->ds; *pfRegSizes = R_SZ_16; return VINF_SUCCESS;
111 case DBGFREG_ES: *pu64 = pCtx->es; *pfRegSizes = R_SZ_16; return VINF_SUCCESS;
112 case DBGFREG_FS: *pu64 = pCtx->fs; *pfRegSizes = R_SZ_16; return VINF_SUCCESS;
113 case DBGFREG_GS: *pu64 = pCtx->gs; *pfRegSizes = R_SZ_16; return VINF_SUCCESS;
114 case DBGFREG_SS: *pu64 = pCtx->ss; *pfRegSizes = R_SZ_16; return VINF_SUCCESS;
115
116 case DBGFREG_CS_ATTR: *pu64 = pCtx->csHid.Attr.u; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
117 case DBGFREG_DS_ATTR: *pu64 = pCtx->dsHid.Attr.u; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
118 case DBGFREG_ES_ATTR: *pu64 = pCtx->esHid.Attr.u; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
119 case DBGFREG_FS_ATTR: *pu64 = pCtx->fsHid.Attr.u; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
120 case DBGFREG_GS_ATTR: *pu64 = pCtx->gsHid.Attr.u; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
121 case DBGFREG_SS_ATTR: *pu64 = pCtx->ssHid.Attr.u; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
122
123 case DBGFREG_CS_BASE: *pu64 = pCtx->csHid.u64Base; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
124 case DBGFREG_DS_BASE: *pu64 = pCtx->dsHid.u64Base; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
125 case DBGFREG_ES_BASE: *pu64 = pCtx->esHid.u64Base; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
126 case DBGFREG_FS_BASE: *pu64 = pCtx->fsHid.u64Base; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
127 case DBGFREG_GS_BASE: *pu64 = pCtx->gsHid.u64Base; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
128 case DBGFREG_SS_BASE: *pu64 = pCtx->ssHid.u64Base; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
129
130 case DBGFREG_CS_LIMIT: *pu64 = pCtx->csHid.u32Limit; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
131 case DBGFREG_DS_LIMIT: *pu64 = pCtx->dsHid.u32Limit; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
132 case DBGFREG_ES_LIMIT: *pu64 = pCtx->esHid.u32Limit; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
133 case DBGFREG_FS_LIMIT: *pu64 = pCtx->fsHid.u32Limit; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
134 case DBGFREG_GS_LIMIT: *pu64 = pCtx->gsHid.u32Limit; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
135 case DBGFREG_SS_LIMIT: *pu64 = pCtx->ssHid.u32Limit; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
136
137 case DBGFREG_RIP: *pu64 = pCtx->rip; *pfRegSizes = R_SZ_16_TO_64; return VINF_SUCCESS;
138 case DBGFREG_FLAGS: *pu64 = pCtx->rflags.u; *pfRegSizes = R_SZ_16_TO_64; return VINF_SUCCESS;
139
140 case DBGFREG_ST0: return VERR_NOT_IMPLEMENTED;
141 case DBGFREG_ST1: return VERR_NOT_IMPLEMENTED;
142 case DBGFREG_ST2: return VERR_NOT_IMPLEMENTED;
143 case DBGFREG_ST3: return VERR_NOT_IMPLEMENTED;
144 case DBGFREG_ST4: return VERR_NOT_IMPLEMENTED;
145 case DBGFREG_ST5: return VERR_NOT_IMPLEMENTED;
146 case DBGFREG_ST6: return VERR_NOT_IMPLEMENTED;
147 case DBGFREG_ST7: return VERR_NOT_IMPLEMENTED;
148
149 case DBGFREG_MM0: return VERR_NOT_IMPLEMENTED;
150 case DBGFREG_MM1: return VERR_NOT_IMPLEMENTED;
151 case DBGFREG_MM2: return VERR_NOT_IMPLEMENTED;
152 case DBGFREG_MM3: return VERR_NOT_IMPLEMENTED;
153 case DBGFREG_MM4: return VERR_NOT_IMPLEMENTED;
154 case DBGFREG_MM5: return VERR_NOT_IMPLEMENTED;
155 case DBGFREG_MM6: return VERR_NOT_IMPLEMENTED;
156 case DBGFREG_MM7: return VERR_NOT_IMPLEMENTED;
157
158 case DBGFREG_FCW: return VERR_NOT_IMPLEMENTED;
159 case DBGFREG_FSW: return VERR_NOT_IMPLEMENTED;
160 case DBGFREG_FTW: return VERR_NOT_IMPLEMENTED;
161 case DBGFREG_FOP: return VERR_NOT_IMPLEMENTED;
162 case DBGFREG_FPUIP: return VERR_NOT_IMPLEMENTED;
163 case DBGFREG_FPUCS: return VERR_NOT_IMPLEMENTED;
164 case DBGFREG_FPUDP: return VERR_NOT_IMPLEMENTED;
165 case DBGFREG_FPUDS: return VERR_NOT_IMPLEMENTED;
166 case DBGFREG_MXCSR: return VERR_NOT_IMPLEMENTED;
167 case DBGFREG_MXCSR_MASK: return VERR_NOT_IMPLEMENTED;
168
169 case DBGFREG_XMM0: return VERR_NOT_IMPLEMENTED;
170 case DBGFREG_XMM1: return VERR_NOT_IMPLEMENTED;
171 case DBGFREG_XMM2: return VERR_NOT_IMPLEMENTED;
172 case DBGFREG_XMM3: return VERR_NOT_IMPLEMENTED;
173 case DBGFREG_XMM4: return VERR_NOT_IMPLEMENTED;
174 case DBGFREG_XMM5: return VERR_NOT_IMPLEMENTED;
175 case DBGFREG_XMM6: return VERR_NOT_IMPLEMENTED;
176 case DBGFREG_XMM7: return VERR_NOT_IMPLEMENTED;
177 case DBGFREG_XMM8: return VERR_NOT_IMPLEMENTED;
178 case DBGFREG_XMM9: return VERR_NOT_IMPLEMENTED;
179 case DBGFREG_XMM10: return VERR_NOT_IMPLEMENTED;
180 case DBGFREG_XMM11: return VERR_NOT_IMPLEMENTED;
181 case DBGFREG_XMM12: return VERR_NOT_IMPLEMENTED;
182 case DBGFREG_XMM13: return VERR_NOT_IMPLEMENTED;
183 case DBGFREG_XMM14: return VERR_NOT_IMPLEMENTED;
184 case DBGFREG_XMM15: return VERR_NOT_IMPLEMENTED;
185
186 case DBGFREG_GDTR: *pu64 = pCtx->gdtr.pGdt; *pfRegSizes = R_SZ_64_16; return VINF_SUCCESS;
187 case DBGFREG_GDTR_BASE: *pu64 = pCtx->gdtr.pGdt; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
188 case DBGFREG_GDTR_LIMIT: *pu64 = pCtx->gdtr.cbGdt; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
189 case DBGFREG_IDTR: *pu64 = pCtx->idtr.pIdt; *pfRegSizes = R_SZ_64_16; return VINF_SUCCESS;
190 case DBGFREG_IDTR_BASE: *pu64 = pCtx->idtr.pIdt; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
191 case DBGFREG_IDTR_LIMIT: *pu64 = pCtx->idtr.cbIdt; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
192 case DBGFREG_LDTR: *pu64 = pCtx->ldtr; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
193 case DBGFREG_LDTR_ATTR: *pu64 = pCtx->ldtrHid.Attr.u; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
194 case DBGFREG_LDTR_BASE: *pu64 = pCtx->ldtrHid.u64Base; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
195 case DBGFREG_LDTR_LIMIT: *pu64 = pCtx->ldtrHid.u32Limit; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
196 case DBGFREG_TR: *pu64 = pCtx->tr; *pfRegSizes = R_SZ_16; return VINF_SUCCESS;
197 case DBGFREG_TR_ATTR: *pu64 = pCtx->trHid.Attr.u; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
198 case DBGFREG_TR_BASE: *pu64 = pCtx->trHid.u64Base; *pfRegSizes = R_SZ_64; return VINF_SUCCESS;
199 case DBGFREG_TR_LIMIT: *pu64 = pCtx->trHid.u32Limit; *pfRegSizes = R_SZ_32; return VINF_SUCCESS;
200
201 case DBGFREG_CR0: *pu64 = CPUMGetGuestCR0(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
202 case DBGFREG_CR2: *pu64 = CPUMGetGuestCR2(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
203 case DBGFREG_CR3: *pu64 = CPUMGetGuestCR3(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
204 case DBGFREG_CR4: *pu64 = CPUMGetGuestCR4(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
205 case DBGFREG_CR8: *pu64 = CPUMGetGuestCR8(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
206
207 case DBGFREG_DR0: *pu64 = CPUMGetGuestDR0(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
208 case DBGFREG_DR1: *pu64 = CPUMGetGuestDR1(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
209 case DBGFREG_DR2: *pu64 = CPUMGetGuestDR2(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
210 case DBGFREG_DR3: *pu64 = CPUMGetGuestDR3(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
211 case DBGFREG_DR6: *pu64 = CPUMGetGuestDR6(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
212 case DBGFREG_DR7: *pu64 = CPUMGetGuestDR7(pVCpu); *pfRegSizes = R_SZ_32_OR_64; return VINF_SUCCESS;
213
214 case DBGFREG_MSR_IA32_APICBASE: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_IA32_APICBASE);
215 case DBGFREG_MSR_IA32_CR_PAT: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_IA32_CR_PAT);
216 case DBGFREG_MSR_IA32_PERF_STATUS: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_IA32_PERF_STATUS);
217 case DBGFREG_MSR_IA32_SYSENTER_CS: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_IA32_SYSENTER_CS);
218 case DBGFREG_MSR_IA32_SYSENTER_EIP: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_IA32_SYSENTER_EIP);
219 case DBGFREG_MSR_IA32_SYSENTER_ESP: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_IA32_SYSENTER_ESP);
220 case DBGFREG_MSR_IA32_TSC: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_IA32_TSC);
221 case DBGFREG_MSR_K6_EFER: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K6_EFER);
222 case DBGFREG_MSR_K6_STAR: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K6_STAR);
223 case DBGFREG_MSR_K8_CSTAR: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K8_CSTAR);
224 case DBGFREG_MSR_K8_FS_BASE: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K8_FS_BASE);
225 case DBGFREG_MSR_K8_GS_BASE: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K8_GS_BASE);
226 case DBGFREG_MSR_K8_KERNEL_GS_BASE: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K8_KERNEL_GS_BASE);
227 case DBGFREG_MSR_K8_LSTAR: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K8_LSTAR);
228 case DBGFREG_MSR_K8_SF_MASK: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K8_SF_MASK);
229 case DBGFREG_MSR_K8_TSC_AUX: return dbgfR3RegGetMsr(pVCpu, pu64, pfRegSizes, MSR_K8_TSC_AUX);
230
231 case DBGFREG_END:
232 case DBGFREG_32BIT_HACK:
233 /* no default! We want GCC warnings. */
234 break;
235 }
236
237 AssertMsgFailed(("%d (%#x)\n", enmReg, enmReg));
238 return VERR_DBGF_INVALID_REGISTER;
239}
240
241
242/**
243 * Queries a 8-bit register value.
244 *
245 * @retval VINF_SUCCESS
246 * @retval VERR_INVALID_VM_HANDLE
247 * @retval VERR_INVALID_CPU_ID
248 * @retval VERR_DBGF_INVALID_REGISTER
249 * @retval VINF_DBGF_TRUNCATED_REGISTER
250 *
251 * @param pVM The VM handle.
252 * @param idCpu The target CPU ID.
253 * @param enmReg The register that's being queried.
254 * @param pu8 Where to store the register value.
255 */
256VMMR3DECL(int) DBGFR3RegQueryU8(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8)
257{
258 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
259 AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
260
261 uint64_t u64Value;
262 uint32_t fRegSizes;
263 int rc = VMR3ReqCallWait(pVM, idCpu, (PFNRT)dbgfR3RegQueryWorker, 5, pVM, idCpu, enmReg, &u64Value, &fRegSizes);
264 if (RT_SUCCESS(rc))
265 {
266 *pu8 = (uint8_t)u64Value;
267 if (R_SZ_8 & fRegSizes)
268 rc = VINF_SUCCESS;
269 else
270 rc = VINF_DBGF_TRUNCATED_REGISTER;
271 }
272 else
273 *pu8 = 0;
274 return rc;
275}
276
277
278/**
279 * Queries a 16-bit register value.
280 *
281 * @retval VINF_SUCCESS
282 * @retval VERR_INVALID_VM_HANDLE
283 * @retval VERR_INVALID_CPU_ID
284 * @retval VERR_DBGF_INVALID_REGISTER
285 * @retval VINF_DBGF_TRUNCATED_REGISTER
286 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER
287 *
288 * @param pVM The VM handle.
289 * @param idCpu The target CPU ID.
290 * @param enmReg The register that's being queried.
291 * @param pu16 Where to store the register value.
292 */
293VMMR3DECL(int) DBGFR3RegQueryU16(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16)
294{
295 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
296 AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
297
298 uint64_t u64Value;
299 uint32_t fRegSizes;
300 int rc = VMR3ReqCallWait(pVM, idCpu, (PFNRT)dbgfR3RegQueryWorker, 5, pVM, idCpu, enmReg, &u64Value, &fRegSizes);
301 if (RT_SUCCESS(rc))
302 {
303 *pu16 = (uint16_t)u64Value;
304 if (R_SZ_16 & fRegSizes)
305 rc = VINF_SUCCESS;
306 else if (~(R_SZ_8 | R_SZ_16) & fRegSizes)
307 rc = VINF_DBGF_TRUNCATED_REGISTER;
308 else
309 rc = VINF_DBGF_ZERO_EXTENDED_REGISTER;
310 }
311 else
312 *pu16 = 0;
313 return rc;
314}
315
316
317/**
318 * Queries a 32-bit register value.
319 *
320 * @retval VINF_SUCCESS
321 * @retval VERR_INVALID_VM_HANDLE
322 * @retval VERR_INVALID_CPU_ID
323 * @retval VERR_DBGF_INVALID_REGISTER
324 * @retval VINF_DBGF_TRUNCATED_REGISTER
325 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER
326 *
327 * @param pVM The VM handle.
328 * @param idCpu The target CPU ID.
329 * @param enmReg The register that's being queried.
330 * @param pu32 Where to store the register value.
331 */
332VMMR3DECL(int) DBGFR3RegQueryU32(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32)
333{
334 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
335 AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
336
337 uint64_t u64Value;
338 uint32_t fRegSizes;
339 int rc = VMR3ReqCallWait(pVM, idCpu, (PFNRT)dbgfR3RegQueryWorker, 5, pVM, idCpu, enmReg, &u64Value, &fRegSizes);
340 if (RT_SUCCESS(rc))
341 {
342 *pu32 = (uint32_t)u64Value;
343 if (R_SZ_32 & fRegSizes)
344 rc = VINF_SUCCESS;
345 else if (~(R_SZ_8 | R_SZ_16 | R_SZ_32) & fRegSizes)
346 rc = VINF_DBGF_TRUNCATED_REGISTER;
347 else
348 rc = VINF_DBGF_ZERO_EXTENDED_REGISTER;
349 }
350 else
351 *pu32 = 0;
352 return rc;
353}
354
355
356/**
357 * Queries a 64-bit register value.
358 *
359 * @retval VINF_SUCCESS
360 * @retval VERR_INVALID_VM_HANDLE
361 * @retval VERR_INVALID_CPU_ID
362 * @retval VERR_DBGF_INVALID_REGISTER
363 * @retval VINF_DBGF_TRUNCATED_REGISTER
364 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER
365 *
366 * @param pVM The VM handle.
367 * @param idCpu The target CPU ID.
368 * @param enmReg The register that's being queried.
369 * @param pu64 Where to store the register value.
370 */
371VMMR3DECL(int) DBGFR3RegQueryU64(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64)
372{
373 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
374 AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
375
376 uint64_t u64Value;
377 uint32_t fRegSizes;
378 int rc = VMR3ReqCallWait(pVM, idCpu, (PFNRT)dbgfR3RegQueryWorker, 5, pVM, idCpu, enmReg, &u64Value, &fRegSizes);
379 if (RT_SUCCESS(rc))
380 {
381 *pu64 = u64Value;
382 if (R_SZ_64 & fRegSizes)
383 rc = VINF_SUCCESS;
384 else if (~(R_SZ_8 | R_SZ_16 | R_SZ_32 | R_SZ_64) & fRegSizes)
385 rc = VINF_DBGF_TRUNCATED_REGISTER;
386 else
387 rc = VINF_DBGF_ZERO_EXTENDED_REGISTER;
388 }
389 else
390 *pu64 = 0;
391 return rc;
392}
393
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