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) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase
28 #define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary
29 #define DEFINE_FPU_XMM(reg)                                                    \
30   #reg, NULL, 16, 0, eEncodingUint, eFormatVectorOfUInt64,                     \
31   {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM,            \
32    LLDB_INVALID_REGNUM, lldb_##reg##_x86_64},                                  \
33   nullptr, nullptr
34 
35 namespace {
36 
37 // This enum defines the layout of the global RegisterInfo array.  This is
38 // necessary because lldb register sets are defined in terms of indices into
39 // the register array. As such, the order of RegisterInfos defined in global
40 // registers array must match the order defined here. When defining the
41 // register set layouts, these values can appear in an arbitrary order, and
42 // that determines the order that register values are displayed in a dump.
43 enum RegisterIndex {
44   eRegisterIndexRax,
45   eRegisterIndexRbx,
46   eRegisterIndexRcx,
47   eRegisterIndexRdx,
48   eRegisterIndexRdi,
49   eRegisterIndexRsi,
50   eRegisterIndexRbp,
51   eRegisterIndexRsp,
52   eRegisterIndexR8,
53   eRegisterIndexR9,
54   eRegisterIndexR10,
55   eRegisterIndexR11,
56   eRegisterIndexR12,
57   eRegisterIndexR13,
58   eRegisterIndexR14,
59   eRegisterIndexR15,
60   eRegisterIndexRip,
61   eRegisterIndexRflags,
62 
63   eRegisterIndexXmm0,
64   eRegisterIndexXmm1,
65   eRegisterIndexXmm2,
66   eRegisterIndexXmm3,
67   eRegisterIndexXmm4,
68   eRegisterIndexXmm5,
69   eRegisterIndexXmm6,
70   eRegisterIndexXmm7,
71   eRegisterIndexXmm8,
72   eRegisterIndexXmm9,
73   eRegisterIndexXmm10,
74   eRegisterIndexXmm11,
75   eRegisterIndexXmm12,
76   eRegisterIndexXmm13,
77   eRegisterIndexXmm14,
78   eRegisterIndexXmm15
79 };
80 
81 // Array of all register information supported by Windows x86
82 RegisterInfo g_register_infos[] = {
83     //  Macro auto defines most stuff     eh_frame                  DWARF
84     //  GENERIC
85     //  GDB                  LLDB                  VALUE REGS    INVALIDATE REGS
86     //  ================================  =========================
87     //  ======================  =========================
88     //  ===================  =================     ==========    ===============
89     {DEFINE_GPR(rax, nullptr),
90      {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM,
91       LLDB_INVALID_REGNUM, lldb_rax_x86_64},
92      nullptr,
93      nullptr,
94     },
95     {DEFINE_GPR(rbx, nullptr),
96      {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM,
97       LLDB_INVALID_REGNUM, lldb_rbx_x86_64},
98      nullptr,
99      nullptr,
100     },
101     {DEFINE_GPR(rcx, nullptr),
102      {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1,
103       LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
104      nullptr,
105      nullptr,
106     },
107     {DEFINE_GPR(rdx, nullptr),
108      {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2,
109       LLDB_INVALID_REGNUM, lldb_rdx_x86_64},
110      nullptr,
111      nullptr,
112     },
113     {DEFINE_GPR(rdi, nullptr),
114      {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM,
115       LLDB_INVALID_REGNUM, lldb_rdi_x86_64},
116      nullptr,
117      nullptr,
118     },
119     {DEFINE_GPR(rsi, nullptr),
120      {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM,
121       LLDB_INVALID_REGNUM, lldb_rsi_x86_64},
122      nullptr,
123      nullptr,
124     },
125     {DEFINE_GPR(rbp, "fp"),
126      {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP,
127       LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
128      nullptr,
129      nullptr,
130     },
131     {DEFINE_GPR(rsp, "sp"),
132      {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP,
133       LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
134      nullptr,
135      nullptr,
136     },
137     {DEFINE_GPR(r8, nullptr),
138      {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3,
139       LLDB_INVALID_REGNUM, lldb_r8_x86_64},
140      nullptr,
141      nullptr,
142     },
143     {DEFINE_GPR(r9, nullptr),
144      {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4,
145       LLDB_INVALID_REGNUM, lldb_r9_x86_64},
146      nullptr,
147      nullptr,
148     },
149     {DEFINE_GPR(r10, nullptr),
150      {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM,
151       LLDB_INVALID_REGNUM, lldb_r10_x86_64},
152      nullptr,
153      nullptr,
154     },
155     {DEFINE_GPR(r11, nullptr),
156      {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM,
157       LLDB_INVALID_REGNUM, lldb_r11_x86_64},
158      nullptr,
159      nullptr,
160     },
161     {DEFINE_GPR(r12, nullptr),
162      {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM,
163       LLDB_INVALID_REGNUM, lldb_r12_x86_64},
164      nullptr,
165      nullptr,
166     },
167     {DEFINE_GPR(r13, nullptr),
168      {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM,
169       LLDB_INVALID_REGNUM, lldb_r13_x86_64},
170      nullptr,
171      nullptr,
172     },
173     {DEFINE_GPR(r14, nullptr),
174      {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM,
175       LLDB_INVALID_REGNUM, lldb_r14_x86_64},
176      nullptr,
177      nullptr,
178     },
179     {DEFINE_GPR(r15, nullptr),
180      {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM,
181       LLDB_INVALID_REGNUM, lldb_r15_x86_64},
182      nullptr,
183      nullptr,
184     },
185     {DEFINE_GPR(rip, "pc"),
186      {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC,
187       LLDB_INVALID_REGNUM, lldb_rip_x86_64},
188      nullptr,
189      nullptr,
190     },
191     {DEFINE_GPR_BIN(eflags, "flags"),
192      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
193       LLDB_INVALID_REGNUM, lldb_rflags_x86_64},
194      nullptr,
195      nullptr,
196     },
197     {DEFINE_FPU_XMM(xmm0)},
198     {DEFINE_FPU_XMM(xmm1)},
199     {DEFINE_FPU_XMM(xmm2)},
200     {DEFINE_FPU_XMM(xmm3)},
201     {DEFINE_FPU_XMM(xmm4)},
202     {DEFINE_FPU_XMM(xmm5)},
203     {DEFINE_FPU_XMM(xmm6)},
204     {DEFINE_FPU_XMM(xmm7)},
205     {DEFINE_FPU_XMM(xmm8)},
206     {DEFINE_FPU_XMM(xmm9)},
207     {DEFINE_FPU_XMM(xmm10)},
208     {DEFINE_FPU_XMM(xmm11)},
209     {DEFINE_FPU_XMM(xmm12)},
210     {DEFINE_FPU_XMM(xmm13)},
211     {DEFINE_FPU_XMM(xmm14)},
212     {DEFINE_FPU_XMM(xmm15)}
213 };
214 
215 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
216 
217 // Array of lldb register numbers used to define the set of all General Purpose
218 // Registers
219 uint32_t g_gpr_reg_indices[] = {
220     eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx,
221     eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi,
222     eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8,
223     eRegisterIndexR9,  eRegisterIndexR10, eRegisterIndexR11,
224     eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14,
225     eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags};
226 
227 uint32_t g_fpu_reg_indices[] = {
228     eRegisterIndexXmm0,  eRegisterIndexXmm1,  eRegisterIndexXmm2,
229     eRegisterIndexXmm3,  eRegisterIndexXmm4,  eRegisterIndexXmm5,
230     eRegisterIndexXmm6,  eRegisterIndexXmm7,  eRegisterIndexXmm8,
231     eRegisterIndexXmm9,  eRegisterIndexXmm10, eRegisterIndexXmm11,
232     eRegisterIndexXmm12, eRegisterIndexXmm13, eRegisterIndexXmm14,
233     eRegisterIndexXmm15
234 };
235 
236 RegisterSet g_register_sets[] = {
237     {"General Purpose Registers", "gpr",
238      llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
239     {"Floating Point Registers", "fpu",
240      llvm::array_lengthof(g_fpu_reg_indices), g_fpu_reg_indices}};
241 }
242 
243 // Constructors and Destructors
244 RegisterContextWindows_x64::RegisterContextWindows_x64(
245     Thread &thread, uint32_t concrete_frame_idx)
246     : RegisterContextWindows(thread, concrete_frame_idx) {}
247 
248 RegisterContextWindows_x64::~RegisterContextWindows_x64() {}
249 
250 size_t RegisterContextWindows_x64::GetRegisterCount() {
251   return llvm::array_lengthof(g_register_infos);
252 }
253 
254 const RegisterInfo *
255 RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) {
256   if (reg < k_num_register_infos)
257     return &g_register_infos[reg];
258   return NULL;
259 }
260 
261 size_t RegisterContextWindows_x64::GetRegisterSetCount() {
262   return llvm::array_lengthof(g_register_sets);
263 }
264 
265 const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) {
266   return &g_register_sets[reg_set];
267 }
268 
269 bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
270                                               RegisterValue &reg_value) {
271   if (!CacheAllRegisterValues())
272     return false;
273 
274   if (reg_info == nullptr)
275     return false;
276 
277   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
278 
279   switch (reg) {
280   case lldb_rax_x86_64:
281     reg_value.SetUInt64(m_context.Rax);
282     break;
283   case lldb_rbx_x86_64:
284     reg_value.SetUInt64(m_context.Rbx);
285     break;
286   case lldb_rcx_x86_64:
287     reg_value.SetUInt64(m_context.Rcx);
288     break;
289   case lldb_rdx_x86_64:
290     reg_value.SetUInt64(m_context.Rdx);
291     break;
292   case lldb_rdi_x86_64:
293     reg_value.SetUInt64(m_context.Rdi);
294     break;
295   case lldb_rsi_x86_64:
296     reg_value.SetUInt64(m_context.Rsi);
297     break;
298   case lldb_r8_x86_64:
299     reg_value.SetUInt64(m_context.R8);
300     break;
301   case lldb_r9_x86_64:
302     reg_value.SetUInt64(m_context.R9);
303     break;
304   case lldb_r10_x86_64:
305     reg_value.SetUInt64(m_context.R10);
306     break;
307   case lldb_r11_x86_64:
308     reg_value.SetUInt64(m_context.R11);
309     break;
310   case lldb_r12_x86_64:
311     reg_value.SetUInt64(m_context.R12);
312     break;
313   case lldb_r13_x86_64:
314     reg_value.SetUInt64(m_context.R13);
315     break;
316   case lldb_r14_x86_64:
317     reg_value.SetUInt64(m_context.R14);
318     break;
319   case lldb_r15_x86_64:
320     reg_value.SetUInt64(m_context.R15);
321     break;
322   case lldb_rbp_x86_64:
323     reg_value.SetUInt64(m_context.Rbp);
324     break;
325   case lldb_rsp_x86_64:
326     reg_value.SetUInt64(m_context.Rsp);
327     break;
328   case lldb_rip_x86_64:
329     reg_value.SetUInt64(m_context.Rip);
330     break;
331   case lldb_rflags_x86_64:
332     reg_value.SetUInt64(m_context.EFlags);
333     break;
334   case lldb_xmm0_x86_64:
335     reg_value.SetBytes(&m_context.Xmm0,
336                        reg_info->byte_size, endian::InlHostByteOrder());
337     break;
338   case lldb_xmm1_x86_64:
339     reg_value.SetBytes(&m_context.Xmm1,
340                        reg_info->byte_size, endian::InlHostByteOrder());
341     break;
342   case lldb_xmm2_x86_64:
343     reg_value.SetBytes(&m_context.Xmm2,
344                        reg_info->byte_size, endian::InlHostByteOrder());
345     break;
346   case lldb_xmm3_x86_64:
347     reg_value.SetBytes(&m_context.Xmm3,
348                        reg_info->byte_size, endian::InlHostByteOrder());
349     break;
350   case lldb_xmm4_x86_64:
351     reg_value.SetBytes(&m_context.Xmm4,
352                        reg_info->byte_size, endian::InlHostByteOrder());
353     break;
354   case lldb_xmm5_x86_64:
355     reg_value.SetBytes(&m_context.Xmm5,
356                        reg_info->byte_size, endian::InlHostByteOrder());
357     break;
358   case lldb_xmm6_x86_64:
359     reg_value.SetBytes(&m_context.Xmm6,
360                        reg_info->byte_size, endian::InlHostByteOrder());
361     break;
362   case lldb_xmm7_x86_64:
363     reg_value.SetBytes(&m_context.Xmm7,
364                        reg_info->byte_size, endian::InlHostByteOrder());
365     break;
366   case lldb_xmm8_x86_64:
367     reg_value.SetBytes(&m_context.Xmm8,
368                        reg_info->byte_size, endian::InlHostByteOrder());
369     break;
370   case lldb_xmm9_x86_64:
371     reg_value.SetBytes(&m_context.Xmm9,
372                        reg_info->byte_size, endian::InlHostByteOrder());
373     break;
374   case lldb_xmm10_x86_64:
375     reg_value.SetBytes(&m_context.Xmm10,
376                        reg_info->byte_size, endian::InlHostByteOrder());
377     break;
378   case lldb_xmm11_x86_64:
379     reg_value.SetBytes(&m_context.Xmm11,
380                        reg_info->byte_size, endian::InlHostByteOrder());
381     break;
382   case lldb_xmm12_x86_64:
383     reg_value.SetBytes(&m_context.Xmm12,
384                        reg_info->byte_size, endian::InlHostByteOrder());
385     break;
386   case lldb_xmm13_x86_64:
387     reg_value.SetBytes(&m_context.Xmm13,
388                        reg_info->byte_size, endian::InlHostByteOrder());
389     break;
390   case lldb_xmm14_x86_64:
391     reg_value.SetBytes(&m_context.Xmm14,
392                        reg_info->byte_size, endian::InlHostByteOrder());
393     break;
394   case lldb_xmm15_x86_64:
395     reg_value.SetBytes(&m_context.Xmm15,
396                        reg_info->byte_size, endian::InlHostByteOrder());
397     break;
398   }
399   return true;
400 }
401 
402 bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info,
403                                                const RegisterValue &reg_value) {
404   // Since we cannot only write a single register value to the inferior, we
405   // need to make sure our cached copy of the register values are fresh.
406   // Otherwise when writing EAX, for example, we may also overwrite some other
407   // register with a stale value.
408   if (!CacheAllRegisterValues())
409     return false;
410 
411   switch (reg_info->kinds[eRegisterKindLLDB]) {
412   case lldb_rax_x86_64:
413     m_context.Rax = reg_value.GetAsUInt64();
414     break;
415   case lldb_rbx_x86_64:
416     m_context.Rbx = reg_value.GetAsUInt64();
417     break;
418   case lldb_rcx_x86_64:
419     m_context.Rcx = reg_value.GetAsUInt64();
420     break;
421   case lldb_rdx_x86_64:
422     m_context.Rdx = reg_value.GetAsUInt64();
423     break;
424   case lldb_rdi_x86_64:
425     m_context.Rdi = reg_value.GetAsUInt64();
426     break;
427   case lldb_rsi_x86_64:
428     m_context.Rsi = reg_value.GetAsUInt64();
429     break;
430   case lldb_r8_x86_64:
431     m_context.R8 = reg_value.GetAsUInt64();
432     break;
433   case lldb_r9_x86_64:
434     m_context.R9 = reg_value.GetAsUInt64();
435     break;
436   case lldb_r10_x86_64:
437     m_context.R10 = reg_value.GetAsUInt64();
438     break;
439   case lldb_r11_x86_64:
440     m_context.R11 = reg_value.GetAsUInt64();
441     break;
442   case lldb_r12_x86_64:
443     m_context.R12 = reg_value.GetAsUInt64();
444     break;
445   case lldb_r13_x86_64:
446     m_context.R13 = reg_value.GetAsUInt64();
447     break;
448   case lldb_r14_x86_64:
449     m_context.R14 = reg_value.GetAsUInt64();
450     break;
451   case lldb_r15_x86_64:
452     m_context.R15 = reg_value.GetAsUInt64();
453     break;
454   case lldb_rbp_x86_64:
455     m_context.Rbp = reg_value.GetAsUInt64();
456     break;
457   case lldb_rsp_x86_64:
458     m_context.Rsp = reg_value.GetAsUInt64();
459     break;
460   case lldb_rip_x86_64:
461     m_context.Rip = reg_value.GetAsUInt64();
462     break;
463   case lldb_rflags_x86_64:
464     m_context.EFlags = reg_value.GetAsUInt64();
465     break;
466   case lldb_xmm0_x86_64:
467     memcpy(&m_context.Xmm0, reg_value.GetBytes(), 16);
468     break;
469   case lldb_xmm1_x86_64:
470     memcpy(&m_context.Xmm1, reg_value.GetBytes(), 16);
471     break;
472   case lldb_xmm2_x86_64:
473     memcpy(&m_context.Xmm2, reg_value.GetBytes(), 16);
474     break;
475   case lldb_xmm3_x86_64:
476     memcpy(&m_context.Xmm3, reg_value.GetBytes(), 16);
477     break;
478   case lldb_xmm4_x86_64:
479     memcpy(&m_context.Xmm4, reg_value.GetBytes(), 16);
480     break;
481   case lldb_xmm5_x86_64:
482     memcpy(&m_context.Xmm5, reg_value.GetBytes(), 16);
483     break;
484   case lldb_xmm6_x86_64:
485     memcpy(&m_context.Xmm6, reg_value.GetBytes(), 16);
486     break;
487   case lldb_xmm7_x86_64:
488     memcpy(&m_context.Xmm7, reg_value.GetBytes(), 16);
489     break;
490   case lldb_xmm8_x86_64:
491     memcpy(&m_context.Xmm8, reg_value.GetBytes(), 16);
492     break;
493   case lldb_xmm9_x86_64:
494     memcpy(&m_context.Xmm9, reg_value.GetBytes(), 16);
495     break;
496   case lldb_xmm10_x86_64:
497     memcpy(&m_context.Xmm10, reg_value.GetBytes(), 16);
498     break;
499   case lldb_xmm11_x86_64:
500     memcpy(&m_context.Xmm11, reg_value.GetBytes(), 16);
501     break;
502   case lldb_xmm12_x86_64:
503     memcpy(&m_context.Xmm12, reg_value.GetBytes(), 16);
504     break;
505   case lldb_xmm13_x86_64:
506     memcpy(&m_context.Xmm13, reg_value.GetBytes(), 16);
507     break;
508   case lldb_xmm14_x86_64:
509     memcpy(&m_context.Xmm14, reg_value.GetBytes(), 16);
510     break;
511   case lldb_xmm15_x86_64:
512     memcpy(&m_context.Xmm15, reg_value.GetBytes(), 16);
513     break;
514   }
515 
516   // Physically update the registers in the target process.
517   return ApplyAllRegisterValues();
518 }
519 
520 #endif // defined(__x86_64__) || defined(_M_X64)
521