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