xref: /llvm-project/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp (revision 593be023615a456ca6ee0ef9bedc21301d73b73c)
1 //===-- RegisterContextWindows_x64.cpp ------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #if defined(__x86_64__) || defined(_M_X64)
10 
11 #include "lldb/Host/windows/HostThreadWindows.h"
12 #include "lldb/Host/windows/windows.h"
13 #include "lldb/Utility/RegisterValue.h"
14 #include "lldb/Utility/Status.h"
15 #include "lldb/lldb-private-types.h"
16 
17 #include "RegisterContextWindows_x64.h"
18 #include "Plugins/Process/Utility/RegisterContext_x86.h"
19 #include "TargetThreadWindows.h"
20 #include "Plugins/Process/Utility/lldb-x86-register-enums.h"
21 
22 #include "llvm/ADT/STLExtras.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 #define DEFINE_GPR(reg, alt, generic)                                          \
28 {                                                                              \
29   #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase,                         \
30       {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, generic,                    \
31         LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 },                            \
32         nullptr, nullptr, nullptr,                                             \
33 }
34 
35 #define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary
36 #define DEFINE_FPU_XMM(reg)                                                    \
37   #reg, NULL, 16, 0, eEncodingUint, eFormatVectorOfUInt64,                     \
38   {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM,            \
39    LLDB_INVALID_REGNUM, lldb_##reg##_x86_64},                                  \
40   nullptr, nullptr, nullptr,
41 
42 #define DEFINE_GPR_PSEUDO_32(reg)                                              \
43 {                                                                              \
44   #reg, nullptr, 4, 0, eEncodingUint, eFormatHexUppercase,                     \
45       {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,          \
46         LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 },                            \
47         nullptr, nullptr, nullptr,                                             \
48 }
49 
50 #define DEFINE_GPR_PSEUDO_16(reg)                                              \
51 {                                                                              \
52   #reg, nullptr, 2, 0, eEncodingUint, eFormatHexUppercase,                     \
53       {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,          \
54         LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 },                            \
55         nullptr, nullptr, nullptr,                                             \
56 }
57 
58 #define DEFINE_GPR_PSEUDO_8(reg)                                               \
59 {                                                                              \
60   #reg, nullptr, 1, 0, eEncodingUint, eFormatHexUppercase,                     \
61       {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,          \
62         LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 },                            \
63         nullptr, nullptr, nullptr,                                             \
64 }
65 
66 namespace {
67 
68 // This enum defines the layout of the global RegisterInfo array.  This is
69 // necessary because lldb register sets are defined in terms of indices into
70 // the register array. As such, the order of RegisterInfos defined in global
71 // registers array must match the order defined here. When defining the
72 // register set layouts, these values can appear in an arbitrary order, and
73 // that determines the order that register values are displayed in a dump.
74 enum RegisterIndex {
75   eRegisterIndexRax,
76   eRegisterIndexRbx,
77   eRegisterIndexRcx,
78   eRegisterIndexRdx,
79   eRegisterIndexRdi,
80   eRegisterIndexRsi,
81   eRegisterIndexRbp,
82   eRegisterIndexRsp,
83   eRegisterIndexR8,
84   eRegisterIndexR9,
85   eRegisterIndexR10,
86   eRegisterIndexR11,
87   eRegisterIndexR12,
88   eRegisterIndexR13,
89   eRegisterIndexR14,
90   eRegisterIndexR15,
91   eRegisterIndexRip,
92   eRegisterIndexRflags,
93   eRegisterIndexEax,
94   eRegisterIndexEbx,
95   eRegisterIndexEcx,
96   eRegisterIndexEdx,
97   eRegisterIndexEdi,
98   eRegisterIndexEsi,
99   eRegisterIndexEbp,
100   eRegisterIndexEsp,
101   eRegisterIndexR8d,
102   eRegisterIndexR9d,
103   eRegisterIndexR10d,
104   eRegisterIndexR11d,
105   eRegisterIndexR12d,
106   eRegisterIndexR13d,
107   eRegisterIndexR14d,
108   eRegisterIndexR15d,
109   eRegisterIndexAx,
110   eRegisterIndexBx,
111   eRegisterIndexCx,
112   eRegisterIndexDx,
113   eRegisterIndexDi,
114   eRegisterIndexSi,
115   eRegisterIndexBp,
116   eRegisterIndexSp,
117   eRegisterIndexR8w,
118   eRegisterIndexR9w,
119   eRegisterIndexR10w,
120   eRegisterIndexR11w,
121   eRegisterIndexR12w,
122   eRegisterIndexR13w,
123   eRegisterIndexR14w,
124   eRegisterIndexR15w,
125   eRegisterIndexAh,
126   eRegisterIndexBh,
127   eRegisterIndexCh,
128   eRegisterIndexDh,
129   eRegisterIndexAl,
130   eRegisterIndexBl,
131   eRegisterIndexCl,
132   eRegisterIndexDl,
133   eRegisterIndexDil,
134   eRegisterIndexSil,
135   eRegisterIndexBpl,
136   eRegisterIndexSpl,
137   eRegisterIndexR8l,
138   eRegisterIndexR9l,
139   eRegisterIndexR10l,
140   eRegisterIndexR11l,
141   eRegisterIndexR12l,
142   eRegisterIndexR13l,
143   eRegisterIndexR14l,
144   eRegisterIndexR15l,
145 
146   eRegisterIndexXmm0,
147   eRegisterIndexXmm1,
148   eRegisterIndexXmm2,
149   eRegisterIndexXmm3,
150   eRegisterIndexXmm4,
151   eRegisterIndexXmm5,
152   eRegisterIndexXmm6,
153   eRegisterIndexXmm7,
154   eRegisterIndexXmm8,
155   eRegisterIndexXmm9,
156   eRegisterIndexXmm10,
157   eRegisterIndexXmm11,
158   eRegisterIndexXmm12,
159   eRegisterIndexXmm13,
160   eRegisterIndexXmm14,
161   eRegisterIndexXmm15
162 };
163 
164 // Array of all register information supported by Windows x86
165 RegisterInfo g_register_infos[] = {
166     DEFINE_GPR(rax, nullptr, LLDB_INVALID_REGNUM),
167     DEFINE_GPR(rbx, nullptr, LLDB_INVALID_REGNUM),
168     DEFINE_GPR(rcx, nullptr, LLDB_REGNUM_GENERIC_ARG1),
169     DEFINE_GPR(rdx, nullptr, LLDB_REGNUM_GENERIC_ARG2),
170     DEFINE_GPR(rdi, nullptr, LLDB_INVALID_REGNUM),
171     DEFINE_GPR(rsi, nullptr, LLDB_INVALID_REGNUM),
172     DEFINE_GPR(rbp, "fp", LLDB_REGNUM_GENERIC_FP),
173     DEFINE_GPR(rsp, "sp", LLDB_REGNUM_GENERIC_SP),
174     DEFINE_GPR(r8, nullptr, LLDB_REGNUM_GENERIC_ARG3),
175     DEFINE_GPR(r9, nullptr, LLDB_REGNUM_GENERIC_ARG4),
176     DEFINE_GPR(r10, nullptr, LLDB_INVALID_REGNUM),
177     DEFINE_GPR(r11, nullptr, LLDB_INVALID_REGNUM),
178     DEFINE_GPR(r12, nullptr, LLDB_INVALID_REGNUM),
179     DEFINE_GPR(r13, nullptr, LLDB_INVALID_REGNUM),
180     DEFINE_GPR(r14, nullptr, LLDB_INVALID_REGNUM),
181     DEFINE_GPR(r15, nullptr, LLDB_INVALID_REGNUM),
182     DEFINE_GPR(rip, "pc", LLDB_REGNUM_GENERIC_PC),
183     {
184         DEFINE_GPR_BIN(eflags, "flags"),
185         {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
186          LLDB_INVALID_REGNUM, lldb_rflags_x86_64},
187         nullptr,
188         nullptr,
189         nullptr,
190     },
191     DEFINE_GPR_PSEUDO_32(eax),
192     DEFINE_GPR_PSEUDO_32(ebx),
193     DEFINE_GPR_PSEUDO_32(ecx),
194     DEFINE_GPR_PSEUDO_32(edx),
195     DEFINE_GPR_PSEUDO_32(edi),
196     DEFINE_GPR_PSEUDO_32(esi),
197     DEFINE_GPR_PSEUDO_32(ebp),
198     DEFINE_GPR_PSEUDO_32(esp),
199     DEFINE_GPR_PSEUDO_32(r8d),
200     DEFINE_GPR_PSEUDO_32(r9d),
201     DEFINE_GPR_PSEUDO_32(r10d),
202     DEFINE_GPR_PSEUDO_32(r11d),
203     DEFINE_GPR_PSEUDO_32(r12d),
204     DEFINE_GPR_PSEUDO_32(r13d),
205     DEFINE_GPR_PSEUDO_32(r14d),
206     DEFINE_GPR_PSEUDO_32(r15d),
207     DEFINE_GPR_PSEUDO_16(ax),
208     DEFINE_GPR_PSEUDO_16(bx),
209     DEFINE_GPR_PSEUDO_16(cx),
210     DEFINE_GPR_PSEUDO_16(dx),
211     DEFINE_GPR_PSEUDO_16(di),
212     DEFINE_GPR_PSEUDO_16(si),
213     DEFINE_GPR_PSEUDO_16(bp),
214     DEFINE_GPR_PSEUDO_16(sp),
215     DEFINE_GPR_PSEUDO_16(r8w),
216     DEFINE_GPR_PSEUDO_16(r9w),
217     DEFINE_GPR_PSEUDO_16(r10w),
218     DEFINE_GPR_PSEUDO_16(r11w),
219     DEFINE_GPR_PSEUDO_16(r12w),
220     DEFINE_GPR_PSEUDO_16(r13w),
221     DEFINE_GPR_PSEUDO_16(r14w),
222     DEFINE_GPR_PSEUDO_16(r15w),
223     DEFINE_GPR_PSEUDO_8(ah),
224     DEFINE_GPR_PSEUDO_8(bh),
225     DEFINE_GPR_PSEUDO_8(ch),
226     DEFINE_GPR_PSEUDO_8(dh),
227     DEFINE_GPR_PSEUDO_8(al),
228     DEFINE_GPR_PSEUDO_8(bl),
229     DEFINE_GPR_PSEUDO_8(cl),
230     DEFINE_GPR_PSEUDO_8(dl),
231     DEFINE_GPR_PSEUDO_8(dil),
232     DEFINE_GPR_PSEUDO_8(sil),
233     DEFINE_GPR_PSEUDO_8(bpl),
234     DEFINE_GPR_PSEUDO_8(spl),
235     DEFINE_GPR_PSEUDO_8(r8l),
236     DEFINE_GPR_PSEUDO_8(r9l),
237     DEFINE_GPR_PSEUDO_8(r10l),
238     DEFINE_GPR_PSEUDO_8(r11l),
239     DEFINE_GPR_PSEUDO_8(r12l),
240     DEFINE_GPR_PSEUDO_8(r13l),
241     DEFINE_GPR_PSEUDO_8(r14l),
242     DEFINE_GPR_PSEUDO_8(r15l),
243     {DEFINE_FPU_XMM(xmm0)},
244     {DEFINE_FPU_XMM(xmm1)},
245     {DEFINE_FPU_XMM(xmm2)},
246     {DEFINE_FPU_XMM(xmm3)},
247     {DEFINE_FPU_XMM(xmm4)},
248     {DEFINE_FPU_XMM(xmm5)},
249     {DEFINE_FPU_XMM(xmm6)},
250     {DEFINE_FPU_XMM(xmm7)},
251     {DEFINE_FPU_XMM(xmm8)},
252     {DEFINE_FPU_XMM(xmm9)},
253     {DEFINE_FPU_XMM(xmm10)},
254     {DEFINE_FPU_XMM(xmm11)},
255     {DEFINE_FPU_XMM(xmm12)},
256     {DEFINE_FPU_XMM(xmm13)},
257     {DEFINE_FPU_XMM(xmm14)},
258     {DEFINE_FPU_XMM(xmm15)}};
259 
260 static size_t k_num_register_infos = std::size(g_register_infos);
261 
262 // Array of lldb register numbers used to define the set of all General Purpose
263 // Registers
264 uint32_t g_gpr_reg_indices[] = {
265     eRegisterIndexRax,  eRegisterIndexRbx,  eRegisterIndexRcx,
266     eRegisterIndexRdx,  eRegisterIndexRdi,  eRegisterIndexRsi,
267     eRegisterIndexRbp,  eRegisterIndexRsp,  eRegisterIndexR8,
268     eRegisterIndexR9,   eRegisterIndexR10,  eRegisterIndexR11,
269     eRegisterIndexR12,  eRegisterIndexR13,  eRegisterIndexR14,
270     eRegisterIndexR15,  eRegisterIndexRip,  eRegisterIndexRflags,
271     eRegisterIndexEax,  eRegisterIndexEbx,  eRegisterIndexEcx,
272     eRegisterIndexEdx,  eRegisterIndexEdi,  eRegisterIndexEsi,
273     eRegisterIndexEbp,  eRegisterIndexEsp,  eRegisterIndexR8d,
274     eRegisterIndexR9d,  eRegisterIndexR10d, eRegisterIndexR11d,
275     eRegisterIndexR12d, eRegisterIndexR13d, eRegisterIndexR14d,
276     eRegisterIndexR15d, eRegisterIndexAx,   eRegisterIndexBx,
277     eRegisterIndexCx,   eRegisterIndexDx,   eRegisterIndexDi,
278     eRegisterIndexSi,   eRegisterIndexBp,   eRegisterIndexSp,
279     eRegisterIndexR8w,  eRegisterIndexR9w,  eRegisterIndexR10w,
280     eRegisterIndexR11w, eRegisterIndexR12w, eRegisterIndexR13w,
281     eRegisterIndexR14w, eRegisterIndexR15w, eRegisterIndexAh,
282     eRegisterIndexBh,   eRegisterIndexCh,   eRegisterIndexDh,
283     eRegisterIndexAl,   eRegisterIndexBl,   eRegisterIndexCl,
284     eRegisterIndexDl,   eRegisterIndexDil,  eRegisterIndexSil,
285     eRegisterIndexBpl,  eRegisterIndexSpl,  eRegisterIndexR8l,
286     eRegisterIndexR9l,  eRegisterIndexR10l, eRegisterIndexR11l,
287     eRegisterIndexR12l, eRegisterIndexR13l, eRegisterIndexR14l,
288     eRegisterIndexR15l
289 };
290 
291 uint32_t g_fpu_reg_indices[] = {
292     eRegisterIndexXmm0,  eRegisterIndexXmm1,  eRegisterIndexXmm2,
293     eRegisterIndexXmm3,  eRegisterIndexXmm4,  eRegisterIndexXmm5,
294     eRegisterIndexXmm6,  eRegisterIndexXmm7,  eRegisterIndexXmm8,
295     eRegisterIndexXmm9,  eRegisterIndexXmm10, eRegisterIndexXmm11,
296     eRegisterIndexXmm12, eRegisterIndexXmm13, eRegisterIndexXmm14,
297     eRegisterIndexXmm15
298 };
299 
300 RegisterSet g_register_sets[] = {
301     {"General Purpose Registers", "gpr", std::size(g_gpr_reg_indices),
302      g_gpr_reg_indices},
303     {"Floating Point Registers", "fpu", std::size(g_fpu_reg_indices),
304      g_fpu_reg_indices}};
305 }
306 
307 // Constructors and Destructors
308 RegisterContextWindows_x64::RegisterContextWindows_x64(
309     Thread &thread, uint32_t concrete_frame_idx)
310     : RegisterContextWindows(thread, concrete_frame_idx) {}
311 
312 RegisterContextWindows_x64::~RegisterContextWindows_x64() {}
313 
314 size_t RegisterContextWindows_x64::GetRegisterCount() {
315   return std::size(g_register_infos);
316 }
317 
318 const RegisterInfo *
319 RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) {
320   if (reg < k_num_register_infos)
321     return &g_register_infos[reg];
322   return NULL;
323 }
324 
325 size_t RegisterContextWindows_x64::GetRegisterSetCount() {
326   return std::size(g_register_sets);
327 }
328 
329 const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) {
330   return &g_register_sets[reg_set];
331 }
332 
333 bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
334                                               RegisterValue &reg_value) {
335   if (!CacheAllRegisterValues())
336     return false;
337 
338   if (reg_info == nullptr)
339     return false;
340 
341   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
342 
343   switch (reg) {
344 #define GPR_CASE(size, reg_case, reg_val)                                      \
345   case reg_case:                                                               \
346     reg_value.SetUInt##size(reg_val);                                        \
347     break;
348 
349   GPR_CASE(64, lldb_rax_x86_64, m_context.Rax);
350   GPR_CASE(64, lldb_rbx_x86_64, m_context.Rbx);
351   GPR_CASE(64, lldb_rcx_x86_64, m_context.Rcx);
352   GPR_CASE(64, lldb_rdx_x86_64, m_context.Rdx);
353   GPR_CASE(64, lldb_rdi_x86_64, m_context.Rdi);
354   GPR_CASE(64, lldb_rsi_x86_64, m_context.Rsi);
355   GPR_CASE(64, lldb_r8_x86_64, m_context.R8);
356   GPR_CASE(64, lldb_r9_x86_64, m_context.R9);
357   GPR_CASE(64, lldb_r10_x86_64, m_context.R10);
358   GPR_CASE(64, lldb_r11_x86_64, m_context.R11);
359   GPR_CASE(64, lldb_r12_x86_64, m_context.R12);
360   GPR_CASE(64, lldb_r13_x86_64, m_context.R13);
361   GPR_CASE(64, lldb_r14_x86_64, m_context.R14);
362   GPR_CASE(64, lldb_r15_x86_64, m_context.R15);
363   GPR_CASE(64, lldb_rbp_x86_64, m_context.Rbp);
364   GPR_CASE(64, lldb_rsp_x86_64, m_context.Rsp);
365   GPR_CASE(64, lldb_rip_x86_64, m_context.Rip);
366   GPR_CASE(64, lldb_rflags_x86_64, m_context.EFlags);
367   GPR_CASE(32, lldb_eax_x86_64, static_cast<uint32_t>(m_context.Rax));
368   GPR_CASE(32, lldb_ebx_x86_64, static_cast<uint32_t>(m_context.Rbx));
369   GPR_CASE(32, lldb_ecx_x86_64, static_cast<uint32_t>(m_context.Rcx));
370   GPR_CASE(32, lldb_edx_x86_64, static_cast<uint32_t>(m_context.Rdx));
371   GPR_CASE(32, lldb_edi_x86_64, static_cast<uint32_t>(m_context.Rdi));
372   GPR_CASE(32, lldb_esi_x86_64, static_cast<uint32_t>(m_context.Rsi));
373   GPR_CASE(32, lldb_ebp_x86_64, static_cast<uint32_t>(m_context.Rbp));
374   GPR_CASE(32, lldb_esp_x86_64, static_cast<uint32_t>(m_context.Rsp));
375   GPR_CASE(32, lldb_r8d_x86_64, static_cast<uint32_t>(m_context.R8));
376   GPR_CASE(32, lldb_r9d_x86_64, static_cast<uint32_t>(m_context.R9));
377   GPR_CASE(32, lldb_r10d_x86_64, static_cast<uint32_t>(m_context.R10));
378   GPR_CASE(32, lldb_r11d_x86_64, static_cast<uint32_t>(m_context.R11));
379   GPR_CASE(32, lldb_r12d_x86_64, static_cast<uint32_t>(m_context.R12));
380   GPR_CASE(32, lldb_r13d_x86_64, static_cast<uint32_t>(m_context.R13));
381   GPR_CASE(32, lldb_r14d_x86_64, static_cast<uint32_t>(m_context.R14));
382   GPR_CASE(32, lldb_r15d_x86_64, static_cast<uint32_t>(m_context.R15));
383   GPR_CASE(16, lldb_ax_x86_64, static_cast<uint16_t>(m_context.Rax));
384   GPR_CASE(16, lldb_bx_x86_64, static_cast<uint16_t>(m_context.Rbx));
385   GPR_CASE(16, lldb_cx_x86_64, static_cast<uint16_t>(m_context.Rcx));
386   GPR_CASE(16, lldb_dx_x86_64, static_cast<uint16_t>(m_context.Rdx));
387   GPR_CASE(16, lldb_di_x86_64, static_cast<uint16_t>(m_context.Rdi));
388   GPR_CASE(16, lldb_si_x86_64, static_cast<uint16_t>(m_context.Rsi));
389   GPR_CASE(16, lldb_bp_x86_64, static_cast<uint16_t>(m_context.Rbp));
390   GPR_CASE(16, lldb_sp_x86_64, static_cast<uint16_t>(m_context.Rsp));
391   GPR_CASE(16, lldb_r8w_x86_64, static_cast<uint16_t>(m_context.R8));
392   GPR_CASE(16, lldb_r9w_x86_64, static_cast<uint16_t>(m_context.R9));
393   GPR_CASE(16, lldb_r10w_x86_64, static_cast<uint16_t>(m_context.R10));
394   GPR_CASE(16, lldb_r11w_x86_64, static_cast<uint16_t>(m_context.R11));
395   GPR_CASE(16, lldb_r12w_x86_64, static_cast<uint16_t>(m_context.R12));
396   GPR_CASE(16, lldb_r13w_x86_64, static_cast<uint16_t>(m_context.R13));
397   GPR_CASE(16, lldb_r14w_x86_64, static_cast<uint16_t>(m_context.R14));
398   GPR_CASE(16, lldb_r15w_x86_64, static_cast<uint16_t>(m_context.R15));
399   GPR_CASE(8, lldb_ah_x86_64, static_cast<uint16_t>(m_context.Rax) >> 8);
400   GPR_CASE(8, lldb_bh_x86_64, static_cast<uint16_t>(m_context.Rbx) >> 8);
401   GPR_CASE(8, lldb_ch_x86_64, static_cast<uint16_t>(m_context.Rcx) >> 8);
402   GPR_CASE(8, lldb_dh_x86_64, static_cast<uint16_t>(m_context.Rdx) >> 8);
403   GPR_CASE(8, lldb_al_x86_64, static_cast<uint8_t>(m_context.Rax));
404   GPR_CASE(8, lldb_bl_x86_64, static_cast<uint8_t>(m_context.Rbx));
405   GPR_CASE(8, lldb_cl_x86_64, static_cast<uint8_t>(m_context.Rcx));
406   GPR_CASE(8, lldb_dl_x86_64, static_cast<uint8_t>(m_context.Rdx));
407   GPR_CASE(8, lldb_dil_x86_64, static_cast<uint8_t>(m_context.Rdi));
408   GPR_CASE(8, lldb_sil_x86_64, static_cast<uint8_t>(m_context.Rsi));
409   GPR_CASE(8, lldb_bpl_x86_64, static_cast<uint8_t>(m_context.Rbp));
410   GPR_CASE(8, lldb_spl_x86_64, static_cast<uint8_t>(m_context.Rsp));
411   GPR_CASE(8, lldb_r8l_x86_64, static_cast<uint8_t>(m_context.R8));
412   GPR_CASE(8, lldb_r9l_x86_64, static_cast<uint8_t>(m_context.R9));
413   GPR_CASE(8, lldb_r10l_x86_64, static_cast<uint8_t>(m_context.R10));
414   GPR_CASE(8, lldb_r11l_x86_64, static_cast<uint8_t>(m_context.R11));
415   GPR_CASE(8, lldb_r12l_x86_64, static_cast<uint8_t>(m_context.R12));
416   GPR_CASE(8, lldb_r13l_x86_64, static_cast<uint8_t>(m_context.R13));
417   GPR_CASE(8, lldb_r14l_x86_64, static_cast<uint8_t>(m_context.R14));
418   GPR_CASE(8, lldb_r15l_x86_64, static_cast<uint8_t>(m_context.R15));
419 
420   case lldb_xmm0_x86_64:
421     reg_value.SetBytes(&m_context.Xmm0,
422                        reg_info->byte_size, endian::InlHostByteOrder());
423     break;
424   case lldb_xmm1_x86_64:
425     reg_value.SetBytes(&m_context.Xmm1,
426                        reg_info->byte_size, endian::InlHostByteOrder());
427     break;
428   case lldb_xmm2_x86_64:
429     reg_value.SetBytes(&m_context.Xmm2,
430                        reg_info->byte_size, endian::InlHostByteOrder());
431     break;
432   case lldb_xmm3_x86_64:
433     reg_value.SetBytes(&m_context.Xmm3,
434                        reg_info->byte_size, endian::InlHostByteOrder());
435     break;
436   case lldb_xmm4_x86_64:
437     reg_value.SetBytes(&m_context.Xmm4,
438                        reg_info->byte_size, endian::InlHostByteOrder());
439     break;
440   case lldb_xmm5_x86_64:
441     reg_value.SetBytes(&m_context.Xmm5,
442                        reg_info->byte_size, endian::InlHostByteOrder());
443     break;
444   case lldb_xmm6_x86_64:
445     reg_value.SetBytes(&m_context.Xmm6,
446                        reg_info->byte_size, endian::InlHostByteOrder());
447     break;
448   case lldb_xmm7_x86_64:
449     reg_value.SetBytes(&m_context.Xmm7,
450                        reg_info->byte_size, endian::InlHostByteOrder());
451     break;
452   case lldb_xmm8_x86_64:
453     reg_value.SetBytes(&m_context.Xmm8,
454                        reg_info->byte_size, endian::InlHostByteOrder());
455     break;
456   case lldb_xmm9_x86_64:
457     reg_value.SetBytes(&m_context.Xmm9,
458                        reg_info->byte_size, endian::InlHostByteOrder());
459     break;
460   case lldb_xmm10_x86_64:
461     reg_value.SetBytes(&m_context.Xmm10,
462                        reg_info->byte_size, endian::InlHostByteOrder());
463     break;
464   case lldb_xmm11_x86_64:
465     reg_value.SetBytes(&m_context.Xmm11,
466                        reg_info->byte_size, endian::InlHostByteOrder());
467     break;
468   case lldb_xmm12_x86_64:
469     reg_value.SetBytes(&m_context.Xmm12,
470                        reg_info->byte_size, endian::InlHostByteOrder());
471     break;
472   case lldb_xmm13_x86_64:
473     reg_value.SetBytes(&m_context.Xmm13,
474                        reg_info->byte_size, endian::InlHostByteOrder());
475     break;
476   case lldb_xmm14_x86_64:
477     reg_value.SetBytes(&m_context.Xmm14,
478                        reg_info->byte_size, endian::InlHostByteOrder());
479     break;
480   case lldb_xmm15_x86_64:
481     reg_value.SetBytes(&m_context.Xmm15,
482                        reg_info->byte_size, endian::InlHostByteOrder());
483     break;
484   }
485   return true;
486 }
487 
488 bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info,
489                                                const RegisterValue &reg_value) {
490   // Since we cannot only write a single register value to the inferior, we
491   // need to make sure our cached copy of the register values are fresh.
492   // Otherwise when writing EAX, for example, we may also overwrite some other
493   // register with a stale value.
494   if (!CacheAllRegisterValues())
495     return false;
496 
497   switch (reg_info->kinds[eRegisterKindLLDB]) {
498   case lldb_rax_x86_64:
499     m_context.Rax = reg_value.GetAsUInt64();
500     break;
501   case lldb_rbx_x86_64:
502     m_context.Rbx = reg_value.GetAsUInt64();
503     break;
504   case lldb_rcx_x86_64:
505     m_context.Rcx = reg_value.GetAsUInt64();
506     break;
507   case lldb_rdx_x86_64:
508     m_context.Rdx = reg_value.GetAsUInt64();
509     break;
510   case lldb_rdi_x86_64:
511     m_context.Rdi = reg_value.GetAsUInt64();
512     break;
513   case lldb_rsi_x86_64:
514     m_context.Rsi = reg_value.GetAsUInt64();
515     break;
516   case lldb_r8_x86_64:
517     m_context.R8 = reg_value.GetAsUInt64();
518     break;
519   case lldb_r9_x86_64:
520     m_context.R9 = reg_value.GetAsUInt64();
521     break;
522   case lldb_r10_x86_64:
523     m_context.R10 = reg_value.GetAsUInt64();
524     break;
525   case lldb_r11_x86_64:
526     m_context.R11 = reg_value.GetAsUInt64();
527     break;
528   case lldb_r12_x86_64:
529     m_context.R12 = reg_value.GetAsUInt64();
530     break;
531   case lldb_r13_x86_64:
532     m_context.R13 = reg_value.GetAsUInt64();
533     break;
534   case lldb_r14_x86_64:
535     m_context.R14 = reg_value.GetAsUInt64();
536     break;
537   case lldb_r15_x86_64:
538     m_context.R15 = reg_value.GetAsUInt64();
539     break;
540   case lldb_rbp_x86_64:
541     m_context.Rbp = reg_value.GetAsUInt64();
542     break;
543   case lldb_rsp_x86_64:
544     m_context.Rsp = reg_value.GetAsUInt64();
545     break;
546   case lldb_rip_x86_64:
547     m_context.Rip = reg_value.GetAsUInt64();
548     break;
549   case lldb_rflags_x86_64:
550     m_context.EFlags = reg_value.GetAsUInt64();
551     break;
552   case lldb_xmm0_x86_64:
553     memcpy(&m_context.Xmm0, reg_value.GetBytes(), 16);
554     break;
555   case lldb_xmm1_x86_64:
556     memcpy(&m_context.Xmm1, reg_value.GetBytes(), 16);
557     break;
558   case lldb_xmm2_x86_64:
559     memcpy(&m_context.Xmm2, reg_value.GetBytes(), 16);
560     break;
561   case lldb_xmm3_x86_64:
562     memcpy(&m_context.Xmm3, reg_value.GetBytes(), 16);
563     break;
564   case lldb_xmm4_x86_64:
565     memcpy(&m_context.Xmm4, reg_value.GetBytes(), 16);
566     break;
567   case lldb_xmm5_x86_64:
568     memcpy(&m_context.Xmm5, reg_value.GetBytes(), 16);
569     break;
570   case lldb_xmm6_x86_64:
571     memcpy(&m_context.Xmm6, reg_value.GetBytes(), 16);
572     break;
573   case lldb_xmm7_x86_64:
574     memcpy(&m_context.Xmm7, reg_value.GetBytes(), 16);
575     break;
576   case lldb_xmm8_x86_64:
577     memcpy(&m_context.Xmm8, reg_value.GetBytes(), 16);
578     break;
579   case lldb_xmm9_x86_64:
580     memcpy(&m_context.Xmm9, reg_value.GetBytes(), 16);
581     break;
582   case lldb_xmm10_x86_64:
583     memcpy(&m_context.Xmm10, reg_value.GetBytes(), 16);
584     break;
585   case lldb_xmm11_x86_64:
586     memcpy(&m_context.Xmm11, reg_value.GetBytes(), 16);
587     break;
588   case lldb_xmm12_x86_64:
589     memcpy(&m_context.Xmm12, reg_value.GetBytes(), 16);
590     break;
591   case lldb_xmm13_x86_64:
592     memcpy(&m_context.Xmm13, reg_value.GetBytes(), 16);
593     break;
594   case lldb_xmm14_x86_64:
595     memcpy(&m_context.Xmm14, reg_value.GetBytes(), 16);
596     break;
597   case lldb_xmm15_x86_64:
598     memcpy(&m_context.Xmm15, reg_value.GetBytes(), 16);
599     break;
600   }
601 
602   // Physically update the registers in the target process.
603   return ApplyAllRegisterValues();
604 }
605 
606 #endif // defined(__x86_64__) || defined(_M_X64)
607