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 ®_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 ®_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