1 //===-- RegisterContextWindows_x64.cpp --------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/RegisterValue.h"
11 #include "lldb/Host/windows/HostThreadWindows.h"
12 #include "lldb/Host/windows/windows.h"
13 #include "lldb/Utility/Status.h"
14 #include "lldb/lldb-private-types.h"
15 
16 #include "RegisterContextWindows_x64.h"
17 #include "RegisterContext_x86.h"
18 #include "TargetThreadWindows.h"
19 #include "lldb-x86-register-enums.h"
20 
21 #include "llvm/ADT/STLExtras.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 #define DEFINE_GPR(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase
27 #define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary
28 
29 namespace {
30 
31 // This enum defines the layout of the global RegisterInfo array.  This is
32 // necessary because lldb register sets are defined in terms of indices into
33 // the register array. As such, the order of RegisterInfos defined in global
34 // registers array must match the order defined here. When defining the
35 // register set layouts, these values can appear in an arbitrary order, and
36 // that determines the order that register values are displayed in a dump.
37 enum RegisterIndex {
38   eRegisterIndexRax,
39   eRegisterIndexRbx,
40   eRegisterIndexRcx,
41   eRegisterIndexRdx,
42   eRegisterIndexRdi,
43   eRegisterIndexRsi,
44   eRegisterIndexR8,
45   eRegisterIndexR9,
46   eRegisterIndexR10,
47   eRegisterIndexR11,
48   eRegisterIndexR12,
49   eRegisterIndexR13,
50   eRegisterIndexR14,
51   eRegisterIndexR15,
52   eRegisterIndexRbp,
53   eRegisterIndexRsp,
54   eRegisterIndexRip,
55   eRegisterIndexRflags
56 };
57 
58 // Array of all register information supported by Windows x86
59 RegisterInfo g_register_infos[] = {
60     //  Macro auto defines most stuff     eh_frame                  DWARF
61     //  GENERIC
62     //  GDB                  LLDB                  VALUE REGS    INVALIDATE REGS
63     //  ================================  =========================
64     //  ======================  =========================
65     //  ===================  =================     ==========    ===============
66     {DEFINE_GPR(rax, nullptr),
67      {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM,
68       LLDB_INVALID_REGNUM, lldb_rax_x86_64},
69      nullptr,
70      nullptr},
71     {DEFINE_GPR(rbx, nullptr),
72      {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM,
73       LLDB_INVALID_REGNUM, lldb_rbx_x86_64},
74      nullptr,
75      nullptr},
76     {DEFINE_GPR(rcx, nullptr),
77      {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM,
78       LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
79      nullptr,
80      nullptr},
81     {DEFINE_GPR(rdx, nullptr),
82      {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM,
83       LLDB_INVALID_REGNUM, lldb_rdx_x86_64},
84      nullptr,
85      nullptr},
86     {DEFINE_GPR(rdi, nullptr),
87      {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM,
88       LLDB_INVALID_REGNUM, lldb_rdi_x86_64},
89      nullptr,
90      nullptr},
91     {DEFINE_GPR(rsi, nullptr),
92      {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM,
93       LLDB_INVALID_REGNUM, lldb_rsi_x86_64},
94      nullptr,
95      nullptr},
96     {DEFINE_GPR(r8, nullptr),
97      {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM,
98       LLDB_INVALID_REGNUM, lldb_r8_x86_64},
99      nullptr,
100      nullptr},
101     {DEFINE_GPR(r9, nullptr),
102      {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM,
103       LLDB_INVALID_REGNUM, lldb_r9_x86_64},
104      nullptr,
105      nullptr},
106     {DEFINE_GPR(r10, nullptr),
107      {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM,
108       LLDB_INVALID_REGNUM, lldb_r10_x86_64},
109      nullptr,
110      nullptr},
111     {DEFINE_GPR(r11, nullptr),
112      {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM,
113       LLDB_INVALID_REGNUM, lldb_r11_x86_64},
114      nullptr,
115      nullptr},
116     {DEFINE_GPR(r12, nullptr),
117      {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM,
118       LLDB_INVALID_REGNUM, lldb_r12_x86_64},
119      nullptr,
120      nullptr},
121     {DEFINE_GPR(r13, nullptr),
122      {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM,
123       LLDB_INVALID_REGNUM, lldb_r13_x86_64},
124      nullptr,
125      nullptr},
126     {DEFINE_GPR(r14, nullptr),
127      {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM,
128       LLDB_INVALID_REGNUM, lldb_r14_x86_64},
129      nullptr,
130      nullptr},
131     {DEFINE_GPR(r15, nullptr),
132      {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM,
133       LLDB_INVALID_REGNUM, lldb_r15_x86_64},
134      nullptr,
135      nullptr},
136     {DEFINE_GPR(rbp, "fp"),
137      {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP,
138       LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
139      nullptr,
140      nullptr},
141     {DEFINE_GPR(rsp, "sp"),
142      {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP,
143       LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
144      nullptr,
145      nullptr},
146     {DEFINE_GPR(rip, "pc"),
147      {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC,
148       LLDB_INVALID_REGNUM, lldb_rip_x86_64},
149      nullptr,
150      nullptr},
151     {DEFINE_GPR_BIN(eflags, "flags"),
152      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
153       LLDB_INVALID_REGNUM, lldb_rflags_x86_64},
154      nullptr,
155      nullptr},
156 };
157 
158 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
159 
160 // Array of lldb register numbers used to define the set of all General Purpose
161 // Registers
162 uint32_t g_gpr_reg_indices[] = {
163     eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx,
164     eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi,
165     eRegisterIndexR8,  eRegisterIndexR9,  eRegisterIndexR10,
166     eRegisterIndexR11, eRegisterIndexR12, eRegisterIndexR13,
167     eRegisterIndexR14, eRegisterIndexR15, eRegisterIndexRbp,
168     eRegisterIndexRsp, eRegisterIndexRip, eRegisterIndexRflags};
169 
170 RegisterSet g_register_sets[] = {
171     {"General Purpose Registers", "gpr",
172      llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
173 };
174 }
175 
176 //------------------------------------------------------------------
177 // Constructors and Destructors
178 //------------------------------------------------------------------
179 RegisterContextWindows_x64::RegisterContextWindows_x64(
180     Thread &thread, uint32_t concrete_frame_idx)
181     : RegisterContextWindows(thread, concrete_frame_idx) {}
182 
183 RegisterContextWindows_x64::~RegisterContextWindows_x64() {}
184 
185 size_t RegisterContextWindows_x64::GetRegisterCount() {
186   return llvm::array_lengthof(g_register_infos);
187 }
188 
189 const RegisterInfo *
190 RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) {
191   if (reg < k_num_register_infos)
192     return &g_register_infos[reg];
193   return NULL;
194 }
195 
196 size_t RegisterContextWindows_x64::GetRegisterSetCount() {
197   return llvm::array_lengthof(g_register_sets);
198 }
199 
200 const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) {
201   return &g_register_sets[reg_set];
202 }
203 
204 bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
205                                               RegisterValue &reg_value) {
206   if (!CacheAllRegisterValues())
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(
337       wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
338 }
339