1 //===-- RegisterContextWindows_arm64.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(__aarch64__) || defined(_M_ARM64)
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_arm64.h"
18 #include "TargetThreadWindows.h"
19 
20 #include "llvm/ADT/STLExtras.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 #define GPR_OFFSET(idx) 0
26 #define GPR_OFFSET_NAME(reg) 0
27 
28 #define FPU_OFFSET(idx) 0
29 #define FPU_OFFSET_NAME(reg) 0
30 
31 #define EXC_OFFSET_NAME(reg) 0
32 #define DBG_OFFSET_NAME(reg) 0
33 
34 #define DEFINE_DBG(reg, i)                                                     \
35   #reg, NULL,                                                                  \
36       0, DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex,                   \
37                               {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       \
38                                LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,       \
39                                LLDB_INVALID_REGNUM },                          \
40                                NULL, NULL, NULL, 0
41 
42 // Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.
43 #define DECLARE_REGISTER_INFOS_ARM64_STRUCT
44 #include "Plugins/Process/Utility/RegisterInfos_arm64.h"
45 #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
46 
47 static size_t k_num_register_infos =
48     llvm::array_lengthof(g_register_infos_arm64_le);
49 
50 // Array of lldb register numbers used to define the set of all General Purpose
51 // Registers
52 uint32_t g_gpr_reg_indices[] = {
53     gpr_x0,  gpr_x1,   gpr_x2,  gpr_x3,  gpr_x4,  gpr_x5,  gpr_x6,  gpr_x7,
54     gpr_x8,  gpr_x9,   gpr_x10, gpr_x11, gpr_x12, gpr_x13, gpr_x14, gpr_x15,
55     gpr_x16, gpr_x17,  gpr_x18, gpr_x19, gpr_x20, gpr_x21, gpr_x22, gpr_x23,
56     gpr_x24, gpr_x25,  gpr_x26, gpr_x27, gpr_x28, gpr_fp,  gpr_lr,  gpr_sp,
57     gpr_pc,  gpr_cpsr,
58 
59     gpr_w0,  gpr_w1,   gpr_w2,  gpr_w3,  gpr_w4,  gpr_w5,  gpr_w6,  gpr_w7,
60     gpr_w8,  gpr_w9,   gpr_w10, gpr_w11, gpr_w12, gpr_w13, gpr_w14, gpr_w15,
61     gpr_w16, gpr_w17,  gpr_w18, gpr_w19, gpr_w20, gpr_w21, gpr_w22, gpr_w23,
62     gpr_w24, gpr_w25,  gpr_w26, gpr_w27, gpr_w28,
63 };
64 
65 uint32_t g_fpu_reg_indices[] = {
66     fpu_v0,   fpu_v1,   fpu_v2,  fpu_v3,  fpu_v4,  fpu_v5,  fpu_v6,  fpu_v7,
67     fpu_v8,   fpu_v9,   fpu_v10, fpu_v11, fpu_v12, fpu_v13, fpu_v14, fpu_v15,
68     fpu_v16,  fpu_v17,  fpu_v18, fpu_v19, fpu_v20, fpu_v21, fpu_v22, fpu_v23,
69     fpu_v24,  fpu_v25,  fpu_v26, fpu_v27, fpu_v28, fpu_v29, fpu_v30, fpu_v31,
70 
71     fpu_s0,   fpu_s1,   fpu_s2,  fpu_s3,  fpu_s4,  fpu_s5,  fpu_s6,  fpu_s7,
72     fpu_s8,   fpu_s9,   fpu_s10, fpu_s11, fpu_s12, fpu_s13, fpu_s14, fpu_s15,
73     fpu_s16,  fpu_s17,  fpu_s18, fpu_s19, fpu_s20, fpu_s21, fpu_s22, fpu_s23,
74     fpu_s24,  fpu_s25,  fpu_s26, fpu_s27, fpu_s28, fpu_s29, fpu_s30, fpu_s31,
75 
76     fpu_d0,   fpu_d1,   fpu_d2,  fpu_d3,  fpu_d4,  fpu_d5,  fpu_d6,  fpu_d7,
77     fpu_d8,   fpu_d9,   fpu_d10, fpu_d11, fpu_d12, fpu_d13, fpu_d14, fpu_d15,
78     fpu_d16,  fpu_d17,  fpu_d18, fpu_d19, fpu_d20, fpu_d21, fpu_d22, fpu_d23,
79     fpu_d24,  fpu_d25,  fpu_d26, fpu_d27, fpu_d28, fpu_d29, fpu_d30, fpu_d31,
80 
81     fpu_fpsr, fpu_fpcr,
82 };
83 
84 RegisterSet g_register_sets[] = {
85     {"General Purpose Registers", "gpr",
86      llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
87     {"Floating Point Registers", "fpu", llvm::array_lengthof(g_fpu_reg_indices),
88      g_fpu_reg_indices},
89 };
90 
91 // Constructors and Destructors
RegisterContextWindows_arm64(Thread & thread,uint32_t concrete_frame_idx)92 RegisterContextWindows_arm64::RegisterContextWindows_arm64(
93     Thread &thread, uint32_t concrete_frame_idx)
94     : RegisterContextWindows(thread, concrete_frame_idx) {}
95 
~RegisterContextWindows_arm64()96 RegisterContextWindows_arm64::~RegisterContextWindows_arm64() {}
97 
GetRegisterCount()98 size_t RegisterContextWindows_arm64::GetRegisterCount() {
99   return llvm::array_lengthof(g_register_infos_arm64_le);
100 }
101 
102 const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)103 RegisterContextWindows_arm64::GetRegisterInfoAtIndex(size_t reg) {
104   if (reg < k_num_register_infos)
105     return &g_register_infos_arm64_le[reg];
106   return NULL;
107 }
108 
GetRegisterSetCount()109 size_t RegisterContextWindows_arm64::GetRegisterSetCount() {
110   return llvm::array_lengthof(g_register_sets);
111 }
112 
113 const RegisterSet *
GetRegisterSet(size_t reg_set)114 RegisterContextWindows_arm64::GetRegisterSet(size_t reg_set) {
115   return &g_register_sets[reg_set];
116 }
117 
ReadRegister(const RegisterInfo * reg_info,RegisterValue & reg_value)118 bool RegisterContextWindows_arm64::ReadRegister(const RegisterInfo *reg_info,
119                                                 RegisterValue &reg_value) {
120   if (!CacheAllRegisterValues())
121     return false;
122 
123   if (reg_info == nullptr)
124     return false;
125 
126   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
127 
128   switch (reg) {
129   case gpr_x0:
130   case gpr_x1:
131   case gpr_x2:
132   case gpr_x3:
133   case gpr_x4:
134   case gpr_x5:
135   case gpr_x6:
136   case gpr_x7:
137   case gpr_x8:
138   case gpr_x9:
139   case gpr_x10:
140   case gpr_x11:
141   case gpr_x12:
142   case gpr_x13:
143   case gpr_x14:
144   case gpr_x15:
145   case gpr_x16:
146   case gpr_x17:
147   case gpr_x18:
148   case gpr_x19:
149   case gpr_x20:
150   case gpr_x21:
151   case gpr_x22:
152   case gpr_x23:
153   case gpr_x24:
154   case gpr_x25:
155   case gpr_x26:
156   case gpr_x27:
157   case gpr_x28:
158     reg_value.SetUInt64(m_context.X[reg - gpr_x0]);
159     break;
160 
161   case gpr_fp:
162     reg_value.SetUInt64(m_context.Fp);
163     break;
164   case gpr_sp:
165     reg_value.SetUInt64(m_context.Sp);
166     break;
167   case gpr_lr:
168     reg_value.SetUInt64(m_context.Lr);
169     break;
170   case gpr_pc:
171     reg_value.SetUInt64(m_context.Pc);
172     break;
173   case gpr_cpsr:
174     reg_value.SetUInt64(m_context.Cpsr);
175     break;
176 
177   case gpr_w0:
178   case gpr_w1:
179   case gpr_w2:
180   case gpr_w3:
181   case gpr_w4:
182   case gpr_w5:
183   case gpr_w6:
184   case gpr_w7:
185   case gpr_w8:
186   case gpr_w9:
187   case gpr_w10:
188   case gpr_w11:
189   case gpr_w12:
190   case gpr_w13:
191   case gpr_w14:
192   case gpr_w15:
193   case gpr_w16:
194   case gpr_w17:
195   case gpr_w18:
196   case gpr_w19:
197   case gpr_w20:
198   case gpr_w21:
199   case gpr_w22:
200   case gpr_w23:
201   case gpr_w24:
202   case gpr_w25:
203   case gpr_w26:
204   case gpr_w27:
205   case gpr_w28:
206     reg_value.SetUInt32(
207         static_cast<uint32_t>(m_context.X[reg - gpr_w0] & 0xffffffff));
208     break;
209 
210   case fpu_v0:
211   case fpu_v1:
212   case fpu_v2:
213   case fpu_v3:
214   case fpu_v4:
215   case fpu_v5:
216   case fpu_v6:
217   case fpu_v7:
218   case fpu_v8:
219   case fpu_v9:
220   case fpu_v10:
221   case fpu_v11:
222   case fpu_v12:
223   case fpu_v13:
224   case fpu_v14:
225   case fpu_v15:
226   case fpu_v16:
227   case fpu_v17:
228   case fpu_v18:
229   case fpu_v19:
230   case fpu_v20:
231   case fpu_v21:
232   case fpu_v22:
233   case fpu_v23:
234   case fpu_v24:
235   case fpu_v25:
236   case fpu_v26:
237   case fpu_v27:
238   case fpu_v28:
239   case fpu_v29:
240   case fpu_v30:
241   case fpu_v31:
242     reg_value.SetBytes(m_context.V[reg - fpu_v0].B, reg_info->byte_size,
243                        endian::InlHostByteOrder());
244     break;
245 
246   case fpu_s0:
247   case fpu_s1:
248   case fpu_s2:
249   case fpu_s3:
250   case fpu_s4:
251   case fpu_s5:
252   case fpu_s6:
253   case fpu_s7:
254   case fpu_s8:
255   case fpu_s9:
256   case fpu_s10:
257   case fpu_s11:
258   case fpu_s12:
259   case fpu_s13:
260   case fpu_s14:
261   case fpu_s15:
262   case fpu_s16:
263   case fpu_s17:
264   case fpu_s18:
265   case fpu_s19:
266   case fpu_s20:
267   case fpu_s21:
268   case fpu_s22:
269   case fpu_s23:
270   case fpu_s24:
271   case fpu_s25:
272   case fpu_s26:
273   case fpu_s27:
274   case fpu_s28:
275   case fpu_s29:
276   case fpu_s30:
277   case fpu_s31:
278     reg_value.SetFloat(m_context.V[reg - fpu_s0].S[0]);
279     break;
280 
281   case fpu_d0:
282   case fpu_d1:
283   case fpu_d2:
284   case fpu_d3:
285   case fpu_d4:
286   case fpu_d5:
287   case fpu_d6:
288   case fpu_d7:
289   case fpu_d8:
290   case fpu_d9:
291   case fpu_d10:
292   case fpu_d11:
293   case fpu_d12:
294   case fpu_d13:
295   case fpu_d14:
296   case fpu_d15:
297   case fpu_d16:
298   case fpu_d17:
299   case fpu_d18:
300   case fpu_d19:
301   case fpu_d20:
302   case fpu_d21:
303   case fpu_d22:
304   case fpu_d23:
305   case fpu_d24:
306   case fpu_d25:
307   case fpu_d26:
308   case fpu_d27:
309   case fpu_d28:
310   case fpu_d29:
311   case fpu_d30:
312   case fpu_d31:
313     reg_value.SetDouble(m_context.V[reg - fpu_d0].D[0]);
314     break;
315 
316   case fpu_fpsr:
317     reg_value.SetUInt32(m_context.Fpsr);
318     break;
319 
320   case fpu_fpcr:
321     reg_value.SetUInt32(m_context.Fpcr);
322     break;
323 
324   default:
325     reg_value.SetValueToInvalid();
326     return false;
327   }
328   return true;
329 }
330 
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & reg_value)331 bool RegisterContextWindows_arm64::WriteRegister(
332     const RegisterInfo *reg_info, const RegisterValue &reg_value) {
333   // Since we cannot only write a single register value to the inferior, we
334   // need to make sure our cached copy of the register values are fresh.
335   // Otherwise when writing one register, we may also overwrite some other
336   // register with a stale value.
337   if (!CacheAllRegisterValues())
338     return false;
339 
340   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
341 
342   switch (reg) {
343   case gpr_x0:
344   case gpr_x1:
345   case gpr_x2:
346   case gpr_x3:
347   case gpr_x4:
348   case gpr_x5:
349   case gpr_x6:
350   case gpr_x7:
351   case gpr_x8:
352   case gpr_x9:
353   case gpr_x10:
354   case gpr_x11:
355   case gpr_x12:
356   case gpr_x13:
357   case gpr_x14:
358   case gpr_x15:
359   case gpr_x16:
360   case gpr_x17:
361   case gpr_x18:
362   case gpr_x19:
363   case gpr_x20:
364   case gpr_x21:
365   case gpr_x22:
366   case gpr_x23:
367   case gpr_x24:
368   case gpr_x25:
369   case gpr_x26:
370   case gpr_x27:
371   case gpr_x28:
372     m_context.X[reg - gpr_x0] = reg_value.GetAsUInt64();
373     break;
374 
375   case gpr_fp:
376     m_context.Fp = reg_value.GetAsUInt64();
377     break;
378   case gpr_sp:
379     m_context.Sp = reg_value.GetAsUInt64();
380     break;
381   case gpr_lr:
382     m_context.Lr = reg_value.GetAsUInt64();
383     break;
384   case gpr_pc:
385     m_context.Pc = reg_value.GetAsUInt64();
386     break;
387   case gpr_cpsr:
388     m_context.Cpsr = reg_value.GetAsUInt64();
389     break;
390 
391   case fpu_v0:
392   case fpu_v1:
393   case fpu_v2:
394   case fpu_v3:
395   case fpu_v4:
396   case fpu_v5:
397   case fpu_v6:
398   case fpu_v7:
399   case fpu_v8:
400   case fpu_v9:
401   case fpu_v10:
402   case fpu_v11:
403   case fpu_v12:
404   case fpu_v13:
405   case fpu_v14:
406   case fpu_v15:
407   case fpu_v16:
408   case fpu_v17:
409   case fpu_v18:
410   case fpu_v19:
411   case fpu_v20:
412   case fpu_v21:
413   case fpu_v22:
414   case fpu_v23:
415   case fpu_v24:
416   case fpu_v25:
417   case fpu_v26:
418   case fpu_v27:
419   case fpu_v28:
420   case fpu_v29:
421   case fpu_v30:
422   case fpu_v31:
423     memcpy(m_context.V[reg - fpu_v0].B, reg_value.GetBytes(), 16);
424     break;
425 
426   case fpu_fpsr:
427     m_context.Fpsr = reg_value.GetAsUInt32();
428     break;
429 
430   case fpu_fpcr:
431     m_context.Fpcr = reg_value.GetAsUInt32();
432     break;
433 
434   default:
435     return false;
436   }
437 
438   // Physically update the registers in the target process.
439   return ApplyAllRegisterValues();
440 }
441 
442 #endif // defined(__aarch64__) || defined(_M_ARM64)
443