LLDB  mainline
RegisterContextWindows_x64.cpp
Go to the documentation of this file.
1 //===-- RegisterContextWindows_x64.cpp --------------------------*- C++ -*-===//
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 
12 #include "lldb/Utility/Status.h"
14 
17 #include "TargetThreadWindows.h"
19 
20 #include "llvm/ADT/STLExtras.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 #define DEFINE_GPR(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase
26 #define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary
27 
28 namespace {
29 
30 // This enum defines the layout of the global RegisterInfo array. This is
31 // necessary because lldb register sets are defined in terms of indices into
32 // the register array. As such, the order of RegisterInfos defined in global
33 // registers array must match the order defined here. When defining the
34 // register set layouts, these values can appear in an arbitrary order, and
35 // that determines the order that register values are displayed in a dump.
37  eRegisterIndexRax,
38  eRegisterIndexRbx,
39  eRegisterIndexRcx,
40  eRegisterIndexRdx,
41  eRegisterIndexRdi,
42  eRegisterIndexRsi,
43  eRegisterIndexRbp,
44  eRegisterIndexRsp,
45  eRegisterIndexR8,
46  eRegisterIndexR9,
47  eRegisterIndexR10,
48  eRegisterIndexR11,
49  eRegisterIndexR12,
50  eRegisterIndexR13,
51  eRegisterIndexR14,
52  eRegisterIndexR15,
53  eRegisterIndexRip,
54  eRegisterIndexRflags
55 };
56 
57 // Array of all register information supported by Windows x86
58 RegisterInfo g_register_infos[] = {
59  // Macro auto defines most stuff eh_frame DWARF
60  // GENERIC
61  // GDB LLDB VALUE REGS INVALIDATE REGS
62  // ================================ =========================
63  // ====================== =========================
64  // =================== ================= ========== ===============
65  {DEFINE_GPR(rax, nullptr),
68  nullptr,
69  nullptr},
70  {DEFINE_GPR(rbx, nullptr),
73  nullptr,
74  nullptr},
75  {DEFINE_GPR(rcx, nullptr),
78  nullptr,
79  nullptr},
80  {DEFINE_GPR(rdx, nullptr),
83  nullptr,
84  nullptr},
85  {DEFINE_GPR(rdi, nullptr),
88  nullptr,
89  nullptr},
90  {DEFINE_GPR(rsi, nullptr),
93  nullptr,
94  nullptr},
95  {DEFINE_GPR(rbp, "fp"),
98  nullptr,
99  nullptr},
100  {DEFINE_GPR(rsp, "sp"),
103  nullptr,
104  nullptr},
105  {DEFINE_GPR(r8, nullptr),
108  nullptr,
109  nullptr},
110  {DEFINE_GPR(r9, nullptr),
113  nullptr,
114  nullptr},
115  {DEFINE_GPR(r10, nullptr),
118  nullptr,
119  nullptr},
120  {DEFINE_GPR(r11, nullptr),
123  nullptr,
124  nullptr},
125  {DEFINE_GPR(r12, nullptr),
128  nullptr,
129  nullptr},
130  {DEFINE_GPR(r13, nullptr),
133  nullptr,
134  nullptr},
135  {DEFINE_GPR(r14, nullptr),
138  nullptr,
139  nullptr},
140  {DEFINE_GPR(r15, nullptr),
143  nullptr,
144  nullptr},
145  {DEFINE_GPR(rip, "pc"),
148  nullptr,
149  nullptr},
150  {DEFINE_GPR_BIN(eflags, "flags"),
153  nullptr,
154  nullptr},
155 };
156 
157 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
158 
159 // Array of lldb register numbers used to define the set of all General Purpose
160 // Registers
161 uint32_t g_gpr_reg_indices[] = {
162  eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx,
163  eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi,
164  eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8,
165  eRegisterIndexR9, eRegisterIndexR10, eRegisterIndexR11,
166  eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14,
167  eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags};
168 
169 RegisterSet g_register_sets[] = {
170  {"General Purpose Registers", "gpr",
171  llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
172 };
173 }
174 
175 // Constructors and Destructors
176 RegisterContextWindows_x64::RegisterContextWindows_x64(
177  Thread &thread, uint32_t concrete_frame_idx)
178  : RegisterContextWindows(thread, concrete_frame_idx) {}
179 
181 
183  return llvm::array_lengthof(g_register_infos);
184 }
185 
186 const RegisterInfo *
188  if (reg < k_num_register_infos)
189  return &g_register_infos[reg];
190  return NULL;
191 }
192 
194  return llvm::array_lengthof(g_register_sets);
195 }
196 
197 const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) {
198  return &g_register_sets[reg_set];
199 }
200 
201 bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
202  RegisterValue &reg_value) {
203  if (!CacheAllRegisterValues())
204  return false;
205 
206  if (reg_info == nullptr)
207  return false;
208 
209  switch (reg_info->kinds[eRegisterKindLLDB]) {
210  case lldb_rax_x86_64:
211  reg_value.SetUInt64(m_context.Rax);
212  break;
213  case lldb_rbx_x86_64:
214  reg_value.SetUInt64(m_context.Rbx);
215  break;
216  case lldb_rcx_x86_64:
217  reg_value.SetUInt64(m_context.Rcx);
218  break;
219  case lldb_rdx_x86_64:
220  reg_value.SetUInt64(m_context.Rdx);
221  break;
222  case lldb_rdi_x86_64:
223  reg_value.SetUInt64(m_context.Rdi);
224  break;
225  case lldb_rsi_x86_64:
226  reg_value.SetUInt64(m_context.Rsi);
227  break;
228  case lldb_r8_x86_64:
229  reg_value.SetUInt64(m_context.R8);
230  break;
231  case lldb_r9_x86_64:
232  reg_value.SetUInt64(m_context.R9);
233  break;
234  case lldb_r10_x86_64:
235  reg_value.SetUInt64(m_context.R10);
236  break;
237  case lldb_r11_x86_64:
238  reg_value.SetUInt64(m_context.R11);
239  break;
240  case lldb_r12_x86_64:
241  reg_value.SetUInt64(m_context.R12);
242  break;
243  case lldb_r13_x86_64:
244  reg_value.SetUInt64(m_context.R13);
245  break;
246  case lldb_r14_x86_64:
247  reg_value.SetUInt64(m_context.R14);
248  break;
249  case lldb_r15_x86_64:
250  reg_value.SetUInt64(m_context.R15);
251  break;
252  case lldb_rbp_x86_64:
253  reg_value.SetUInt64(m_context.Rbp);
254  break;
255  case lldb_rsp_x86_64:
256  reg_value.SetUInt64(m_context.Rsp);
257  break;
258  case lldb_rip_x86_64:
259  reg_value.SetUInt64(m_context.Rip);
260  break;
261  case lldb_rflags_x86_64:
262  reg_value.SetUInt64(m_context.EFlags);
263  break;
264  }
265  return true;
266 }
267 
268 bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info,
269  const RegisterValue &reg_value) {
270  // Since we cannot only write a single register value to the inferior, we
271  // need to make sure our cached copy of the register values are fresh.
272  // Otherwise when writing EAX, for example, we may also overwrite some other
273  // register with a stale value.
274  if (!CacheAllRegisterValues())
275  return false;
276 
277  switch (reg_info->kinds[eRegisterKindLLDB]) {
278  case lldb_rax_x86_64:
279  m_context.Rax = reg_value.GetAsUInt64();
280  break;
281  case lldb_rbx_x86_64:
282  m_context.Rbx = reg_value.GetAsUInt64();
283  break;
284  case lldb_rcx_x86_64:
285  m_context.Rcx = reg_value.GetAsUInt64();
286  break;
287  case lldb_rdx_x86_64:
288  m_context.Rdx = reg_value.GetAsUInt64();
289  break;
290  case lldb_rdi_x86_64:
291  m_context.Rdi = reg_value.GetAsUInt64();
292  break;
293  case lldb_rsi_x86_64:
294  m_context.Rsi = reg_value.GetAsUInt64();
295  break;
296  case lldb_r8_x86_64:
297  m_context.R8 = reg_value.GetAsUInt64();
298  break;
299  case lldb_r9_x86_64:
300  m_context.R9 = reg_value.GetAsUInt64();
301  break;
302  case lldb_r10_x86_64:
303  m_context.R10 = reg_value.GetAsUInt64();
304  break;
305  case lldb_r11_x86_64:
306  m_context.R11 = reg_value.GetAsUInt64();
307  break;
308  case lldb_r12_x86_64:
309  m_context.R12 = reg_value.GetAsUInt64();
310  break;
311  case lldb_r13_x86_64:
312  m_context.R13 = reg_value.GetAsUInt64();
313  break;
314  case lldb_r14_x86_64:
315  m_context.R14 = reg_value.GetAsUInt64();
316  break;
317  case lldb_r15_x86_64:
318  m_context.R15 = reg_value.GetAsUInt64();
319  break;
320  case lldb_rbp_x86_64:
321  m_context.Rbp = reg_value.GetAsUInt64();
322  break;
323  case lldb_rsp_x86_64:
324  m_context.Rsp = reg_value.GetAsUInt64();
325  break;
326  case lldb_rip_x86_64:
327  m_context.Rip = reg_value.GetAsUInt64();
328  break;
329  case lldb_rflags_x86_64:
330  m_context.EFlags = reg_value.GetAsUInt64();
331  break;
332  }
333 
334  // Physically update the registers in the target process.
335  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
336  return ::SetThreadContext(
338 }
const RegisterSet * GetRegisterSet(size_t reg_set) override
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:63
#define LLDB_REGNUM_GENERIC_ARG6
Definition: lldb-defines.h:78
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
HostNativeThread & GetNativeThread()
Definition: HostThread.cpp:32
#define DEFINE_GPR_BIN(reg, alt)
#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
#define LLDB_REGNUM_GENERIC_ARG5
Definition: lldb-defines.h:76
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
bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value) override
static const uint32_t k_num_register_infos
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:65
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value) override
static RegisterInfo g_register_infos[]
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:72
Definition: SBAddress.h:15
const RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
#define DEFINE_GPR(reg, alt)
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90