1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//*****************************************************************************
5// File: CordbRegisterSet.cpp
6//
7
8//
9//*****************************************************************************
10#include "primitives.h"
11
12
13HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable)
14{
15 FAIL_IF_NEUTERED(this);
16 VALIDATE_POINTER_TO_OBJECT(pAvailable, ULONG64*);
17
18 (*pAvailable) = SETBITULONG64( REGISTER_INSTRUCTION_POINTER )
19 | SETBITULONG64( REGISTER_STACK_POINTER );
20
21 if (!m_quickUnwind || m_active)
22 (*pAvailable) |= SETBITULONG64( REGISTER_AMD64_RBP )
23 | SETBITULONG64( REGISTER_AMD64_RAX )
24 | SETBITULONG64( REGISTER_AMD64_RCX )
25 | SETBITULONG64( REGISTER_AMD64_RDX )
26 | SETBITULONG64( REGISTER_AMD64_RBX )
27 | SETBITULONG64( REGISTER_AMD64_RSI )
28 | SETBITULONG64( REGISTER_AMD64_RDI )
29 | SETBITULONG64( REGISTER_AMD64_R8 )
30 | SETBITULONG64( REGISTER_AMD64_R9 )
31 | SETBITULONG64( REGISTER_AMD64_R10 )
32 | SETBITULONG64( REGISTER_AMD64_R11 )
33 | SETBITULONG64( REGISTER_AMD64_R12 )
34 | SETBITULONG64( REGISTER_AMD64_R13 )
35 | SETBITULONG64( REGISTER_AMD64_R14 )
36 | SETBITULONG64( REGISTER_AMD64_R15 );
37
38 if (m_active)
39 (*pAvailable) |= SETBITULONG64( REGISTER_AMD64_XMM0 )
40 | SETBITULONG64( REGISTER_AMD64_XMM1 )
41 | SETBITULONG64( REGISTER_AMD64_XMM2 )
42 | SETBITULONG64( REGISTER_AMD64_XMM3 )
43 | SETBITULONG64( REGISTER_AMD64_XMM4 )
44 | SETBITULONG64( REGISTER_AMD64_XMM5 )
45 | SETBITULONG64( REGISTER_AMD64_XMM6 )
46 | SETBITULONG64( REGISTER_AMD64_XMM7 )
47 | SETBITULONG64( REGISTER_AMD64_XMM8 )
48 | SETBITULONG64( REGISTER_AMD64_XMM9 )
49 | SETBITULONG64( REGISTER_AMD64_XMM10 )
50 | SETBITULONG64( REGISTER_AMD64_XMM11 )
51 | SETBITULONG64( REGISTER_AMD64_XMM12 )
52 | SETBITULONG64( REGISTER_AMD64_XMM13 )
53 | SETBITULONG64( REGISTER_AMD64_XMM14 )
54 | SETBITULONG64( REGISTER_AMD64_XMM15 );
55
56 return S_OK;
57}
58
59HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount,
60 CORDB_REGISTER regBuffer[])
61{
62 PUBLIC_REENTRANT_API_ENTRY(this);
63 FAIL_IF_NEUTERED(this);
64 ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
65 UINT iRegister = 0;
66
67 VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true);
68
69 if ( mask & ( SETBITULONG64( REGISTER_AMD64_XMM0 )
70 | SETBITULONG64( REGISTER_AMD64_XMM1 )
71 | SETBITULONG64( REGISTER_AMD64_XMM2 )
72 | SETBITULONG64( REGISTER_AMD64_XMM3 )
73 | SETBITULONG64( REGISTER_AMD64_XMM4 )
74 | SETBITULONG64( REGISTER_AMD64_XMM5 )
75 | SETBITULONG64( REGISTER_AMD64_XMM6 )
76 | SETBITULONG64( REGISTER_AMD64_XMM7 )
77 | SETBITULONG64( REGISTER_AMD64_XMM8 )
78 | SETBITULONG64( REGISTER_AMD64_XMM9 )
79 | SETBITULONG64( REGISTER_AMD64_XMM10 )
80 | SETBITULONG64( REGISTER_AMD64_XMM11 )
81 | SETBITULONG64( REGISTER_AMD64_XMM12 )
82 | SETBITULONG64( REGISTER_AMD64_XMM13 )
83 | SETBITULONG64( REGISTER_AMD64_XMM14 )
84 | SETBITULONG64( REGISTER_AMD64_XMM15 ) ) )
85 {
86 HRESULT hr = S_OK;
87
88 if (!m_active)
89 return E_INVALIDARG;
90
91 if (!m_thread->m_fFloatStateValid)
92 {
93 EX_TRY
94 {
95 m_thread->LoadFloatState();
96 }
97 EX_CATCH_HRESULT(hr);
98
99 if ( !SUCCEEDED(hr) )
100 {
101 return hr;
102 }
103 LOG( ( LF_CORDB, LL_INFO1000, "CRS::GR: Loaded float state\n" ) );
104 }
105 }
106
107 // Make sure that the registers are really available
108 if ( mask & ( SETBITULONG64( REGISTER_AMD64_RBP )
109 | SETBITULONG64( REGISTER_AMD64_RAX )
110 | SETBITULONG64( REGISTER_AMD64_RCX )
111 | SETBITULONG64( REGISTER_AMD64_RDX )
112 | SETBITULONG64( REGISTER_AMD64_RBX )
113 | SETBITULONG64( REGISTER_AMD64_RSI )
114 | SETBITULONG64( REGISTER_AMD64_RDI )
115 | SETBITULONG64( REGISTER_AMD64_R8 )
116 | SETBITULONG64( REGISTER_AMD64_R9 )
117 | SETBITULONG64( REGISTER_AMD64_R10 )
118 | SETBITULONG64( REGISTER_AMD64_R11 )
119 | SETBITULONG64( REGISTER_AMD64_R12 )
120 | SETBITULONG64( REGISTER_AMD64_R13 )
121 | SETBITULONG64( REGISTER_AMD64_R14 )
122 | SETBITULONG64( REGISTER_AMD64_R15 ) ) )
123 {
124 if (!m_active && m_quickUnwind)
125 return E_INVALIDARG;
126 }
127
128 for ( int i = REGISTER_INSTRUCTION_POINTER
129 ; i<=REGISTER_AMD64_XMM15 && iRegister < regCount
130 ; i++)
131 {
132 if( mask & SETBITULONG64(i) )
133 {
134 switch( i )
135 {
136 case REGISTER_INSTRUCTION_POINTER:
137 regBuffer[iRegister++] = m_rd->PC; break;
138 case REGISTER_STACK_POINTER:
139 regBuffer[iRegister++] = m_rd->SP; break;
140 case REGISTER_AMD64_RBP:
141 regBuffer[iRegister++] = m_rd->Rbp; break;
142 case REGISTER_AMD64_RAX:
143 regBuffer[iRegister++] = m_rd->Rax; break;
144 case REGISTER_AMD64_RBX:
145 regBuffer[iRegister++] = m_rd->Rbx; break;
146 case REGISTER_AMD64_RCX:
147 regBuffer[iRegister++] = m_rd->Rcx; break;
148 case REGISTER_AMD64_RDX:
149 regBuffer[iRegister++] = m_rd->Rdx; break;
150 case REGISTER_AMD64_RSI:
151 regBuffer[iRegister++] = m_rd->Rsi; break;
152 case REGISTER_AMD64_RDI:
153 regBuffer[iRegister++] = m_rd->Rdi; break;
154 case REGISTER_AMD64_R8:
155 regBuffer[iRegister++] = m_rd->R8; break;
156 case REGISTER_AMD64_R9:
157 regBuffer[iRegister++] = m_rd->R9; break;
158 case REGISTER_AMD64_R10:
159 regBuffer[iRegister++] = m_rd->R10; break;
160 case REGISTER_AMD64_R11:
161 regBuffer[iRegister++] = m_rd->R11; break;
162 case REGISTER_AMD64_R12:
163 regBuffer[iRegister++] = m_rd->R12; break;
164 case REGISTER_AMD64_R13:
165 regBuffer[iRegister++] = m_rd->R13; break;
166 case REGISTER_AMD64_R14:
167 regBuffer[iRegister++] = m_rd->R14; break;
168 case REGISTER_AMD64_R15:
169 regBuffer[iRegister++] = m_rd->R15; break;
170
171 case REGISTER_AMD64_XMM0:
172 case REGISTER_AMD64_XMM1:
173 case REGISTER_AMD64_XMM2:
174 case REGISTER_AMD64_XMM3:
175 case REGISTER_AMD64_XMM4:
176 case REGISTER_AMD64_XMM5:
177 case REGISTER_AMD64_XMM6:
178 case REGISTER_AMD64_XMM7:
179 case REGISTER_AMD64_XMM8:
180 case REGISTER_AMD64_XMM9:
181 case REGISTER_AMD64_XMM10:
182 case REGISTER_AMD64_XMM11:
183 case REGISTER_AMD64_XMM12:
184 case REGISTER_AMD64_XMM13:
185 case REGISTER_AMD64_XMM14:
186 case REGISTER_AMD64_XMM15:
187 regBuffer[iRegister++] = *(CORDB_REGISTER*)
188 &(m_thread->m_floatValues[(i - REGISTER_AMD64_XMM0)]);
189 break;
190 }
191 }
192 }
193
194 _ASSERTE( iRegister <= regCount );
195 return S_OK;
196}
197
198
199HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG32 regCount,
200 BYTE pAvailable[])
201{
202 FAIL_IF_NEUTERED(this);
203 VALIDATE_POINTER_TO_OBJECT_ARRAY(pAvailable, CORDB_REGISTER, regCount, true, true);
204
205 // Defer to adapter for v1.0 interface
206 return GetRegistersAvailableAdapter(regCount, pAvailable);
207}
208
209
210HRESULT CordbRegisterSet::GetRegisters(ULONG32 maskCount, BYTE mask[],
211 ULONG32 regCount, CORDB_REGISTER regBuffer[])
212{
213 FAIL_IF_NEUTERED(this);
214 VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true);
215
216 // Defer to adapter for v1.0 interface
217 return GetRegistersAdapter(maskCount, mask, regCount, regBuffer);
218}
219
220
221// This is just a convenience function to convert a regdisplay into a Context.
222// Since a context has more info than a regdisplay, the conversion isn't perfect
223// and the context can't be fully accurate.
224void CordbRegisterSet::InternalCopyRDToContext(DT_CONTEXT *pInputContext)
225{
226 INTERNAL_SYNC_API_ENTRY(GetProcess());
227 _ASSERTE(pInputContext);
228
229 if((pInputContext->ContextFlags & DT_CONTEXT_INTEGER)==DT_CONTEXT_INTEGER)
230 {
231 pInputContext->Rax = m_rd->Rax;
232 pInputContext->Rbx = m_rd->Rbx;
233 pInputContext->Rcx = m_rd->Rcx;
234 pInputContext->Rdx = m_rd->Rdx;
235 pInputContext->Rbp = m_rd->Rbp;
236 pInputContext->Rsi = m_rd->Rsi;
237 pInputContext->Rdi = m_rd->Rdi;
238 pInputContext->R8 = m_rd->R8;
239 pInputContext->R9 = m_rd->R9;
240 pInputContext->R10 = m_rd->R10;
241 pInputContext->R11 = m_rd->R11;
242 pInputContext->R12 = m_rd->R12;
243 pInputContext->R13 = m_rd->R13;
244 pInputContext->R14 = m_rd->R14;
245 pInputContext->R15 = m_rd->R15;
246 }
247
248
249 if((pInputContext->ContextFlags & DT_CONTEXT_CONTROL)==DT_CONTEXT_CONTROL)
250 {
251 pInputContext->Rip = m_rd->PC;
252 pInputContext->Rsp = m_rd->SP;
253 }
254}
255