LLDB  mainline
RegisterContextWindows_x64.cpp
Go to the documentation of this file.
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 
14 #include "lldb/Utility/Status.h"
16 
19 #include "TargetThreadWindows.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, nullptr, 0
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),
92  nullptr,
93  nullptr,
94  nullptr,
95  0},
96  {DEFINE_GPR(rbx, nullptr),
99  nullptr,
100  nullptr,
101  nullptr,
102  0},
103  {DEFINE_GPR(rcx, nullptr),
106  nullptr,
107  nullptr,
108  nullptr,
109  0},
110  {DEFINE_GPR(rdx, nullptr),
113  nullptr,
114  nullptr,
115  nullptr,
116  0},
117  {DEFINE_GPR(rdi, nullptr),
120  nullptr,
121  nullptr,
122  nullptr,
123  0},
124  {DEFINE_GPR(rsi, nullptr),
127  nullptr,
128  nullptr,
129  nullptr,
130  0},
131  {DEFINE_GPR(rbp, "fp"),
134  nullptr,
135  nullptr,
136  nullptr,
137  0},
138  {DEFINE_GPR(rsp, "sp"),
141  nullptr,
142  nullptr,
143  nullptr,
144  0},
145  {DEFINE_GPR(r8, nullptr),
148  nullptr,
149  nullptr,
150  nullptr,
151  0},
152  {DEFINE_GPR(r9, nullptr),
155  nullptr,
156  nullptr,
157  nullptr,
158  0},
159  {DEFINE_GPR(r10, nullptr),
162  nullptr,
163  nullptr,
164  nullptr,
165  0},
166  {DEFINE_GPR(r11, nullptr),
169  nullptr,
170  nullptr,
171  nullptr,
172  0},
173  {DEFINE_GPR(r12, nullptr),
176  nullptr,
177  nullptr,
178  nullptr,
179  0},
180  {DEFINE_GPR(r13, nullptr),
183  nullptr,
184  nullptr,
185  nullptr,
186  0},
187  {DEFINE_GPR(r14, nullptr),
190  nullptr,
191  nullptr,
192  nullptr,
193  0},
194  {DEFINE_GPR(r15, nullptr),
197  nullptr,
198  nullptr,
199  nullptr,
200  0},
201  {DEFINE_GPR(rip, "pc"),
204  nullptr,
205  nullptr,
206  nullptr,
207  0},
208  {DEFINE_GPR_BIN(eflags, "flags"),
211  nullptr,
212  nullptr,
213  nullptr,
214  0},
215  {DEFINE_FPU_XMM(xmm0)},
216  {DEFINE_FPU_XMM(xmm1)},
217  {DEFINE_FPU_XMM(xmm2)},
218  {DEFINE_FPU_XMM(xmm3)},
219  {DEFINE_FPU_XMM(xmm4)},
220  {DEFINE_FPU_XMM(xmm5)},
221  {DEFINE_FPU_XMM(xmm6)},
222  {DEFINE_FPU_XMM(xmm7)},
223  {DEFINE_FPU_XMM(xmm8)},
224  {DEFINE_FPU_XMM(xmm9)},
225  {DEFINE_FPU_XMM(xmm10)},
226  {DEFINE_FPU_XMM(xmm11)},
227  {DEFINE_FPU_XMM(xmm12)},
228  {DEFINE_FPU_XMM(xmm13)},
229  {DEFINE_FPU_XMM(xmm14)},
230  {DEFINE_FPU_XMM(xmm15)}
231 };
232 
233 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
234 
235 // Array of lldb register numbers used to define the set of all General Purpose
236 // Registers
237 uint32_t g_gpr_reg_indices[] = {
238  eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx,
239  eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi,
240  eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8,
241  eRegisterIndexR9, eRegisterIndexR10, eRegisterIndexR11,
242  eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14,
243  eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags};
244 
245 uint32_t g_fpu_reg_indices[] = {
246  eRegisterIndexXmm0, eRegisterIndexXmm1, eRegisterIndexXmm2,
247  eRegisterIndexXmm3, eRegisterIndexXmm4, eRegisterIndexXmm5,
248  eRegisterIndexXmm6, eRegisterIndexXmm7, eRegisterIndexXmm8,
249  eRegisterIndexXmm9, eRegisterIndexXmm10, eRegisterIndexXmm11,
250  eRegisterIndexXmm12, eRegisterIndexXmm13, eRegisterIndexXmm14,
251  eRegisterIndexXmm15
252 };
253 
254 RegisterSet g_register_sets[] = {
255  {"General Purpose Registers", "gpr",
256  llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
257  {"Floating Point Registers", "fpu",
258  llvm::array_lengthof(g_fpu_reg_indices), g_fpu_reg_indices}};
259 }
260 
261 // Constructors and Destructors
262 RegisterContextWindows_x64::RegisterContextWindows_x64(
263  Thread &thread, uint32_t concrete_frame_idx)
264  : RegisterContextWindows(thread, concrete_frame_idx) {}
265 
266 RegisterContextWindows_x64::~RegisterContextWindows_x64() {}
267 
268 size_t RegisterContextWindows_x64::GetRegisterCount() {
269  return llvm::array_lengthof(g_register_infos);
270 }
271 
272 const RegisterInfo *
273 RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) {
274  if (reg < k_num_register_infos)
275  return &g_register_infos[reg];
276  return NULL;
277 }
278 
279 size_t RegisterContextWindows_x64::GetRegisterSetCount() {
280  return llvm::array_lengthof(g_register_sets);
281 }
282 
283 const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) {
284  return &g_register_sets[reg_set];
285 }
286 
287 bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
288  RegisterValue &reg_value) {
289  if (!CacheAllRegisterValues())
290  return false;
291 
292  if (reg_info == nullptr)
293  return false;
294 
295  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
296 
297  switch (reg) {
298  case lldb_rax_x86_64:
299  reg_value.SetUInt64(m_context.Rax);
300  break;
301  case lldb_rbx_x86_64:
302  reg_value.SetUInt64(m_context.Rbx);
303  break;
304  case lldb_rcx_x86_64:
305  reg_value.SetUInt64(m_context.Rcx);
306  break;
307  case lldb_rdx_x86_64:
308  reg_value.SetUInt64(m_context.Rdx);
309  break;
310  case lldb_rdi_x86_64:
311  reg_value.SetUInt64(m_context.Rdi);
312  break;
313  case lldb_rsi_x86_64:
314  reg_value.SetUInt64(m_context.Rsi);
315  break;
316  case lldb_r8_x86_64:
317  reg_value.SetUInt64(m_context.R8);
318  break;
319  case lldb_r9_x86_64:
320  reg_value.SetUInt64(m_context.R9);
321  break;
322  case lldb_r10_x86_64:
323  reg_value.SetUInt64(m_context.R10);
324  break;
325  case lldb_r11_x86_64:
326  reg_value.SetUInt64(m_context.R11);
327  break;
328  case lldb_r12_x86_64:
329  reg_value.SetUInt64(m_context.R12);
330  break;
331  case lldb_r13_x86_64:
332  reg_value.SetUInt64(m_context.R13);
333  break;
334  case lldb_r14_x86_64:
335  reg_value.SetUInt64(m_context.R14);
336  break;
337  case lldb_r15_x86_64:
338  reg_value.SetUInt64(m_context.R15);
339  break;
340  case lldb_rbp_x86_64:
341  reg_value.SetUInt64(m_context.Rbp);
342  break;
343  case lldb_rsp_x86_64:
344  reg_value.SetUInt64(m_context.Rsp);
345  break;
346  case lldb_rip_x86_64:
347  reg_value.SetUInt64(m_context.Rip);
348  break;
349  case lldb_rflags_x86_64:
350  reg_value.SetUInt64(m_context.EFlags);
351  break;
352  case lldb_xmm0_x86_64:
353  reg_value.SetBytes(&m_context.Xmm0,
354  reg_info->byte_size, endian::InlHostByteOrder());
355  break;
356  case lldb_xmm1_x86_64:
357  reg_value.SetBytes(&m_context.Xmm1,
358  reg_info->byte_size, endian::InlHostByteOrder());
359  break;
360  case lldb_xmm2_x86_64:
361  reg_value.SetBytes(&m_context.Xmm2,
362  reg_info->byte_size, endian::InlHostByteOrder());
363  break;
364  case lldb_xmm3_x86_64:
365  reg_value.SetBytes(&m_context.Xmm3,
366  reg_info->byte_size, endian::InlHostByteOrder());
367  break;
368  case lldb_xmm4_x86_64:
369  reg_value.SetBytes(&m_context.Xmm4,
370  reg_info->byte_size, endian::InlHostByteOrder());
371  break;
372  case lldb_xmm5_x86_64:
373  reg_value.SetBytes(&m_context.Xmm5,
374  reg_info->byte_size, endian::InlHostByteOrder());
375  break;
376  case lldb_xmm6_x86_64:
377  reg_value.SetBytes(&m_context.Xmm6,
378  reg_info->byte_size, endian::InlHostByteOrder());
379  break;
380  case lldb_xmm7_x86_64:
381  reg_value.SetBytes(&m_context.Xmm7,
382  reg_info->byte_size, endian::InlHostByteOrder());
383  break;
384  case lldb_xmm8_x86_64:
385  reg_value.SetBytes(&m_context.Xmm8,
386  reg_info->byte_size, endian::InlHostByteOrder());
387  break;
388  case lldb_xmm9_x86_64:
389  reg_value.SetBytes(&m_context.Xmm9,
390  reg_info->byte_size, endian::InlHostByteOrder());
391  break;
392  case lldb_xmm10_x86_64:
393  reg_value.SetBytes(&m_context.Xmm10,
394  reg_info->byte_size, endian::InlHostByteOrder());
395  break;
396  case lldb_xmm11_x86_64:
397  reg_value.SetBytes(&m_context.Xmm11,
398  reg_info->byte_size, endian::InlHostByteOrder());
399  break;
400  case lldb_xmm12_x86_64:
401  reg_value.SetBytes(&m_context.Xmm12,
402  reg_info->byte_size, endian::InlHostByteOrder());
403  break;
404  case lldb_xmm13_x86_64:
405  reg_value.SetBytes(&m_context.Xmm13,
406  reg_info->byte_size, endian::InlHostByteOrder());
407  break;
408  case lldb_xmm14_x86_64:
409  reg_value.SetBytes(&m_context.Xmm14,
410  reg_info->byte_size, endian::InlHostByteOrder());
411  break;
412  case lldb_xmm15_x86_64:
413  reg_value.SetBytes(&m_context.Xmm15,
414  reg_info->byte_size, endian::InlHostByteOrder());
415  break;
416  }
417  return true;
418 }
419 
420 bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info,
421  const RegisterValue &reg_value) {
422  // Since we cannot only write a single register value to the inferior, we
423  // need to make sure our cached copy of the register values are fresh.
424  // Otherwise when writing EAX, for example, we may also overwrite some other
425  // register with a stale value.
426  if (!CacheAllRegisterValues())
427  return false;
428 
429  switch (reg_info->kinds[eRegisterKindLLDB]) {
430  case lldb_rax_x86_64:
431  m_context.Rax = reg_value.GetAsUInt64();
432  break;
433  case lldb_rbx_x86_64:
434  m_context.Rbx = reg_value.GetAsUInt64();
435  break;
436  case lldb_rcx_x86_64:
437  m_context.Rcx = reg_value.GetAsUInt64();
438  break;
439  case lldb_rdx_x86_64:
440  m_context.Rdx = reg_value.GetAsUInt64();
441  break;
442  case lldb_rdi_x86_64:
443  m_context.Rdi = reg_value.GetAsUInt64();
444  break;
445  case lldb_rsi_x86_64:
446  m_context.Rsi = reg_value.GetAsUInt64();
447  break;
448  case lldb_r8_x86_64:
449  m_context.R8 = reg_value.GetAsUInt64();
450  break;
451  case lldb_r9_x86_64:
452  m_context.R9 = reg_value.GetAsUInt64();
453  break;
454  case lldb_r10_x86_64:
455  m_context.R10 = reg_value.GetAsUInt64();
456  break;
457  case lldb_r11_x86_64:
458  m_context.R11 = reg_value.GetAsUInt64();
459  break;
460  case lldb_r12_x86_64:
461  m_context.R12 = reg_value.GetAsUInt64();
462  break;
463  case lldb_r13_x86_64:
464  m_context.R13 = reg_value.GetAsUInt64();
465  break;
466  case lldb_r14_x86_64:
467  m_context.R14 = reg_value.GetAsUInt64();
468  break;
469  case lldb_r15_x86_64:
470  m_context.R15 = reg_value.GetAsUInt64();
471  break;
472  case lldb_rbp_x86_64:
473  m_context.Rbp = reg_value.GetAsUInt64();
474  break;
475  case lldb_rsp_x86_64:
476  m_context.Rsp = reg_value.GetAsUInt64();
477  break;
478  case lldb_rip_x86_64:
479  m_context.Rip = reg_value.GetAsUInt64();
480  break;
481  case lldb_rflags_x86_64:
482  m_context.EFlags = reg_value.GetAsUInt64();
483  break;
484  case lldb_xmm0_x86_64:
485  memcpy(&m_context.Xmm0, reg_value.GetBytes(), 16);
486  break;
487  case lldb_xmm1_x86_64:
488  memcpy(&m_context.Xmm1, reg_value.GetBytes(), 16);
489  break;
490  case lldb_xmm2_x86_64:
491  memcpy(&m_context.Xmm2, reg_value.GetBytes(), 16);
492  break;
493  case lldb_xmm3_x86_64:
494  memcpy(&m_context.Xmm3, reg_value.GetBytes(), 16);
495  break;
496  case lldb_xmm4_x86_64:
497  memcpy(&m_context.Xmm4, reg_value.GetBytes(), 16);
498  break;
499  case lldb_xmm5_x86_64:
500  memcpy(&m_context.Xmm5, reg_value.GetBytes(), 16);
501  break;
502  case lldb_xmm6_x86_64:
503  memcpy(&m_context.Xmm6, reg_value.GetBytes(), 16);
504  break;
505  case lldb_xmm7_x86_64:
506  memcpy(&m_context.Xmm7, reg_value.GetBytes(), 16);
507  break;
508  case lldb_xmm8_x86_64:
509  memcpy(&m_context.Xmm8, reg_value.GetBytes(), 16);
510  break;
511  case lldb_xmm9_x86_64:
512  memcpy(&m_context.Xmm9, reg_value.GetBytes(), 16);
513  break;
514  case lldb_xmm10_x86_64:
515  memcpy(&m_context.Xmm10, reg_value.GetBytes(), 16);
516  break;
517  case lldb_xmm11_x86_64:
518  memcpy(&m_context.Xmm11, reg_value.GetBytes(), 16);
519  break;
520  case lldb_xmm12_x86_64:
521  memcpy(&m_context.Xmm12, reg_value.GetBytes(), 16);
522  break;
523  case lldb_xmm13_x86_64:
524  memcpy(&m_context.Xmm13, reg_value.GetBytes(), 16);
525  break;
526  case lldb_xmm14_x86_64:
527  memcpy(&m_context.Xmm14, reg_value.GetBytes(), 16);
528  break;
529  case lldb_xmm15_x86_64:
530  memcpy(&m_context.Xmm15, reg_value.GetBytes(), 16);
531  break;
532  }
533 
534  // Physically update the registers in the target process.
535  return ApplyAllRegisterValues();
536 }
537 
538 #endif // defined(__x86_64__) || defined(_M_X64)
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
A class that represents a running process on the host machine.
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:74
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:70
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:64
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:68
static const uint32_t k_num_register_infos
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
lldb&#39;s internal register numbers
const void * GetBytes() const
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4)
static RegisterInfo g_register_infos[]
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:72
Definition: SBAddress.h:15
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
lldb::ByteOrder InlHostByteOrder()
Definition: Endian.h:25
#define NULL
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90