1 //===-- NativeRegisterContextWindows_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 "NativeRegisterContextWindows_arm64.h"
12 #include "NativeThreadWindows.h"
13 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
14 #include "ProcessWindowsLog.h"
15 #include "lldb/Host/HostInfo.h"
16 #include "lldb/Host/HostThread.h"
17 #include "lldb/Host/windows/HostThreadWindows.h"
18 #include "lldb/Host/windows/windows.h"
19
20 #include "lldb/Utility/Log.h"
21 #include "lldb/Utility/RegisterValue.h"
22 #include "llvm/ADT/STLExtras.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 #define REG_CONTEXT_SIZE sizeof(::CONTEXT)
28
29 namespace {
30 static const uint32_t g_gpr_regnums_arm64[] = {
31 gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64,
32 gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64,
33 gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64,
34 gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64,
35 gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64,
36 gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64,
37 gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64,
38 gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64,
39 gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64,
40 gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64,
41 gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64,
42 gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64,
43 gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64,
44 gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64,
45 gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64,
46 gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64,
47 LLDB_INVALID_REGNUM // Register set must be terminated with this flag
48 };
49 static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
50 1) == k_num_gpr_registers_arm64,
51 "g_gpr_regnums_arm64 has wrong number of register infos");
52
53 static const uint32_t g_fpr_regnums_arm64[] = {
54 fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64,
55 fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64,
56 fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64,
57 fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64,
58 fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64,
59 fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64,
60 fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64,
61 fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64,
62 fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64,
63 fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64,
64 fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64,
65 fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64,
66 fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64,
67 fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64,
68 fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64,
69 fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64,
70
71 fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64,
72 fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64,
73 fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64,
74 fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64,
75 fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64,
76 fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64,
77 fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64,
78 fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64,
79 fpu_fpsr_arm64, fpu_fpcr_arm64,
80 LLDB_INVALID_REGNUM // Register set must be terminated with this flag
81 };
82 static_assert(((sizeof g_fpr_regnums_arm64 / sizeof g_fpr_regnums_arm64[0]) -
83 1) == k_num_fpr_registers_arm64,
84 "g_fpu_regnums_arm64 has wrong number of register infos");
85
86 static const RegisterSet g_reg_sets_arm64[] = {
87 {"General Purpose Registers", "gpr",
88 llvm::array_lengthof(g_gpr_regnums_arm64) - 1, g_gpr_regnums_arm64},
89 {"Floating Point Registers", "fpr",
90 llvm::array_lengthof(g_fpr_regnums_arm64) - 1, g_fpr_regnums_arm64},
91 };
92
93 enum { k_num_register_sets = 2 };
94
95 } // namespace
96
97 static RegisterInfoInterface *
CreateRegisterInfoInterface(const ArchSpec & target_arch)98 CreateRegisterInfoInterface(const ArchSpec &target_arch) {
99 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
100 "Register setting path assumes this is a 64-bit host");
101 return new RegisterInfoPOSIX_arm64(target_arch);
102 }
103
GetThreadContextHelper(lldb::thread_t thread_handle,PCONTEXT context_ptr,const DWORD control_flag)104 static Status GetThreadContextHelper(lldb::thread_t thread_handle,
105 PCONTEXT context_ptr,
106 const DWORD control_flag) {
107 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
108 Status error;
109
110 memset(context_ptr, 0, sizeof(::CONTEXT));
111 context_ptr->ContextFlags = control_flag;
112 if (!::GetThreadContext(thread_handle, context_ptr)) {
113 error.SetError(GetLastError(), eErrorTypeWin32);
114 LLDB_LOG(log, "{0} GetThreadContext failed with error {1}", __FUNCTION__,
115 error);
116 return error;
117 }
118 return Status();
119 }
120
SetThreadContextHelper(lldb::thread_t thread_handle,PCONTEXT context_ptr)121 static Status SetThreadContextHelper(lldb::thread_t thread_handle,
122 PCONTEXT context_ptr) {
123 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
124 Status error;
125 // It's assumed that the thread has stopped.
126 if (!::SetThreadContext(thread_handle, context_ptr)) {
127 error.SetError(GetLastError(), eErrorTypeWin32);
128 LLDB_LOG(log, "{0} SetThreadContext failed with error {1}", __FUNCTION__,
129 error);
130 return error;
131 }
132 return Status();
133 }
134
135 std::unique_ptr<NativeRegisterContextWindows>
CreateHostNativeRegisterContextWindows(const ArchSpec & target_arch,NativeThreadProtocol & native_thread)136 NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
137 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
138 // Register context for a native 64-bit application.
139 return std::make_unique<NativeRegisterContextWindows_arm64>(target_arch,
140 native_thread);
141 }
142
NativeRegisterContextWindows_arm64(const ArchSpec & target_arch,NativeThreadProtocol & native_thread)143 NativeRegisterContextWindows_arm64::NativeRegisterContextWindows_arm64(
144 const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
145 : NativeRegisterContextWindows(native_thread,
146 CreateRegisterInfoInterface(target_arch)) {}
147
IsGPR(uint32_t reg_index) const148 bool NativeRegisterContextWindows_arm64::IsGPR(uint32_t reg_index) const {
149 return (reg_index >= k_first_gpr_arm64 && reg_index <= k_last_gpr_arm64);
150 }
151
IsFPR(uint32_t reg_index) const152 bool NativeRegisterContextWindows_arm64::IsFPR(uint32_t reg_index) const {
153 return (reg_index >= k_first_fpr_arm64 && reg_index <= k_last_fpr_arm64);
154 }
155
GetRegisterSetCount() const156 uint32_t NativeRegisterContextWindows_arm64::GetRegisterSetCount() const {
157 return k_num_register_sets;
158 }
159
160 const RegisterSet *
GetRegisterSet(uint32_t set_index) const161 NativeRegisterContextWindows_arm64::GetRegisterSet(uint32_t set_index) const {
162 if (set_index >= k_num_register_sets)
163 return nullptr;
164 return &g_reg_sets_arm64[set_index];
165 }
166
GPRRead(const uint32_t reg,RegisterValue & reg_value)167 Status NativeRegisterContextWindows_arm64::GPRRead(const uint32_t reg,
168 RegisterValue ®_value) {
169 ::CONTEXT tls_context;
170 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
171 Status error =
172 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
173 if (error.Fail())
174 return error;
175
176 switch (reg) {
177 case gpr_x0_arm64:
178 case gpr_x1_arm64:
179 case gpr_x2_arm64:
180 case gpr_x3_arm64:
181 case gpr_x4_arm64:
182 case gpr_x5_arm64:
183 case gpr_x6_arm64:
184 case gpr_x7_arm64:
185 case gpr_x8_arm64:
186 case gpr_x9_arm64:
187 case gpr_x10_arm64:
188 case gpr_x11_arm64:
189 case gpr_x12_arm64:
190 case gpr_x13_arm64:
191 case gpr_x14_arm64:
192 case gpr_x15_arm64:
193 case gpr_x16_arm64:
194 case gpr_x17_arm64:
195 case gpr_x18_arm64:
196 case gpr_x19_arm64:
197 case gpr_x20_arm64:
198 case gpr_x21_arm64:
199 case gpr_x22_arm64:
200 case gpr_x23_arm64:
201 case gpr_x24_arm64:
202 case gpr_x25_arm64:
203 case gpr_x26_arm64:
204 case gpr_x27_arm64:
205 case gpr_x28_arm64:
206 reg_value.SetUInt64(tls_context.X[reg - gpr_x0_arm64]);
207 break;
208
209 case gpr_fp_arm64:
210 reg_value.SetUInt64(tls_context.Fp);
211 break;
212 case gpr_sp_arm64:
213 reg_value.SetUInt64(tls_context.Sp);
214 break;
215 case gpr_lr_arm64:
216 reg_value.SetUInt64(tls_context.Lr);
217 break;
218 case gpr_pc_arm64:
219 reg_value.SetUInt64(tls_context.Pc);
220 break;
221 case gpr_cpsr_arm64:
222 reg_value.SetUInt64(tls_context.Cpsr);
223 break;
224
225 case gpr_w0_arm64:
226 case gpr_w1_arm64:
227 case gpr_w2_arm64:
228 case gpr_w3_arm64:
229 case gpr_w4_arm64:
230 case gpr_w5_arm64:
231 case gpr_w6_arm64:
232 case gpr_w7_arm64:
233 case gpr_w8_arm64:
234 case gpr_w9_arm64:
235 case gpr_w10_arm64:
236 case gpr_w11_arm64:
237 case gpr_w12_arm64:
238 case gpr_w13_arm64:
239 case gpr_w14_arm64:
240 case gpr_w15_arm64:
241 case gpr_w16_arm64:
242 case gpr_w17_arm64:
243 case gpr_w18_arm64:
244 case gpr_w19_arm64:
245 case gpr_w20_arm64:
246 case gpr_w21_arm64:
247 case gpr_w22_arm64:
248 case gpr_w23_arm64:
249 case gpr_w24_arm64:
250 case gpr_w25_arm64:
251 case gpr_w26_arm64:
252 case gpr_w27_arm64:
253 case gpr_w28_arm64:
254 reg_value.SetUInt32(
255 static_cast<uint32_t>(tls_context.X[reg - gpr_w0_arm64] & 0xffffffff));
256 break;
257 }
258
259 return error;
260 }
261
262 Status
GPRWrite(const uint32_t reg,const RegisterValue & reg_value)263 NativeRegisterContextWindows_arm64::GPRWrite(const uint32_t reg,
264 const RegisterValue ®_value) {
265 ::CONTEXT tls_context;
266 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
267 auto thread_handle = GetThreadHandle();
268 Status error =
269 GetThreadContextHelper(thread_handle, &tls_context, context_flag);
270 if (error.Fail())
271 return error;
272
273 switch (reg) {
274 case gpr_x0_arm64:
275 case gpr_x1_arm64:
276 case gpr_x2_arm64:
277 case gpr_x3_arm64:
278 case gpr_x4_arm64:
279 case gpr_x5_arm64:
280 case gpr_x6_arm64:
281 case gpr_x7_arm64:
282 case gpr_x8_arm64:
283 case gpr_x9_arm64:
284 case gpr_x10_arm64:
285 case gpr_x11_arm64:
286 case gpr_x12_arm64:
287 case gpr_x13_arm64:
288 case gpr_x14_arm64:
289 case gpr_x15_arm64:
290 case gpr_x16_arm64:
291 case gpr_x17_arm64:
292 case gpr_x18_arm64:
293 case gpr_x19_arm64:
294 case gpr_x20_arm64:
295 case gpr_x21_arm64:
296 case gpr_x22_arm64:
297 case gpr_x23_arm64:
298 case gpr_x24_arm64:
299 case gpr_x25_arm64:
300 case gpr_x26_arm64:
301 case gpr_x27_arm64:
302 case gpr_x28_arm64:
303 tls_context.X[reg - gpr_x0_arm64] = reg_value.GetAsUInt64();
304 break;
305
306 case gpr_fp_arm64:
307 tls_context.Fp = reg_value.GetAsUInt64();
308 break;
309 case gpr_sp_arm64:
310 tls_context.Sp = reg_value.GetAsUInt64();
311 break;
312 case gpr_lr_arm64:
313 tls_context.Lr = reg_value.GetAsUInt64();
314 break;
315 case gpr_pc_arm64:
316 tls_context.Pc = reg_value.GetAsUInt64();
317 break;
318 case gpr_cpsr_arm64:
319 tls_context.Cpsr = reg_value.GetAsUInt64();
320 break;
321
322 case gpr_w0_arm64:
323 case gpr_w1_arm64:
324 case gpr_w2_arm64:
325 case gpr_w3_arm64:
326 case gpr_w4_arm64:
327 case gpr_w5_arm64:
328 case gpr_w6_arm64:
329 case gpr_w7_arm64:
330 case gpr_w8_arm64:
331 case gpr_w9_arm64:
332 case gpr_w10_arm64:
333 case gpr_w11_arm64:
334 case gpr_w12_arm64:
335 case gpr_w13_arm64:
336 case gpr_w14_arm64:
337 case gpr_w15_arm64:
338 case gpr_w16_arm64:
339 case gpr_w17_arm64:
340 case gpr_w18_arm64:
341 case gpr_w19_arm64:
342 case gpr_w20_arm64:
343 case gpr_w21_arm64:
344 case gpr_w22_arm64:
345 case gpr_w23_arm64:
346 case gpr_w24_arm64:
347 case gpr_w25_arm64:
348 case gpr_w26_arm64:
349 case gpr_w27_arm64:
350 case gpr_w28_arm64:
351 tls_context.X[reg - gpr_w0_arm64] = reg_value.GetAsUInt32();
352 break;
353 }
354
355 return SetThreadContextHelper(thread_handle, &tls_context);
356 }
357
FPRRead(const uint32_t reg,RegisterValue & reg_value)358 Status NativeRegisterContextWindows_arm64::FPRRead(const uint32_t reg,
359 RegisterValue ®_value) {
360 ::CONTEXT tls_context;
361 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
362 Status error =
363 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
364 if (error.Fail())
365 return error;
366
367 switch (reg) {
368 case fpu_v0_arm64:
369 case fpu_v1_arm64:
370 case fpu_v2_arm64:
371 case fpu_v3_arm64:
372 case fpu_v4_arm64:
373 case fpu_v5_arm64:
374 case fpu_v6_arm64:
375 case fpu_v7_arm64:
376 case fpu_v8_arm64:
377 case fpu_v9_arm64:
378 case fpu_v10_arm64:
379 case fpu_v11_arm64:
380 case fpu_v12_arm64:
381 case fpu_v13_arm64:
382 case fpu_v14_arm64:
383 case fpu_v15_arm64:
384 case fpu_v16_arm64:
385 case fpu_v17_arm64:
386 case fpu_v18_arm64:
387 case fpu_v19_arm64:
388 case fpu_v20_arm64:
389 case fpu_v21_arm64:
390 case fpu_v22_arm64:
391 case fpu_v23_arm64:
392 case fpu_v24_arm64:
393 case fpu_v25_arm64:
394 case fpu_v26_arm64:
395 case fpu_v27_arm64:
396 case fpu_v28_arm64:
397 case fpu_v29_arm64:
398 case fpu_v30_arm64:
399 case fpu_v31_arm64:
400 reg_value.SetBytes(tls_context.V[reg - fpu_v0_arm64].B, 16,
401 endian::InlHostByteOrder());
402 break;
403
404 case fpu_s0_arm64:
405 case fpu_s1_arm64:
406 case fpu_s2_arm64:
407 case fpu_s3_arm64:
408 case fpu_s4_arm64:
409 case fpu_s5_arm64:
410 case fpu_s6_arm64:
411 case fpu_s7_arm64:
412 case fpu_s8_arm64:
413 case fpu_s9_arm64:
414 case fpu_s10_arm64:
415 case fpu_s11_arm64:
416 case fpu_s12_arm64:
417 case fpu_s13_arm64:
418 case fpu_s14_arm64:
419 case fpu_s15_arm64:
420 case fpu_s16_arm64:
421 case fpu_s17_arm64:
422 case fpu_s18_arm64:
423 case fpu_s19_arm64:
424 case fpu_s20_arm64:
425 case fpu_s21_arm64:
426 case fpu_s22_arm64:
427 case fpu_s23_arm64:
428 case fpu_s24_arm64:
429 case fpu_s25_arm64:
430 case fpu_s26_arm64:
431 case fpu_s27_arm64:
432 case fpu_s28_arm64:
433 case fpu_s29_arm64:
434 case fpu_s30_arm64:
435 case fpu_s31_arm64:
436 reg_value.SetFloat(tls_context.V[reg - fpu_s0_arm64].S[0]);
437 break;
438
439 case fpu_d0_arm64:
440 case fpu_d1_arm64:
441 case fpu_d2_arm64:
442 case fpu_d3_arm64:
443 case fpu_d4_arm64:
444 case fpu_d5_arm64:
445 case fpu_d6_arm64:
446 case fpu_d7_arm64:
447 case fpu_d8_arm64:
448 case fpu_d9_arm64:
449 case fpu_d10_arm64:
450 case fpu_d11_arm64:
451 case fpu_d12_arm64:
452 case fpu_d13_arm64:
453 case fpu_d14_arm64:
454 case fpu_d15_arm64:
455 case fpu_d16_arm64:
456 case fpu_d17_arm64:
457 case fpu_d18_arm64:
458 case fpu_d19_arm64:
459 case fpu_d20_arm64:
460 case fpu_d21_arm64:
461 case fpu_d22_arm64:
462 case fpu_d23_arm64:
463 case fpu_d24_arm64:
464 case fpu_d25_arm64:
465 case fpu_d26_arm64:
466 case fpu_d27_arm64:
467 case fpu_d28_arm64:
468 case fpu_d29_arm64:
469 case fpu_d30_arm64:
470 case fpu_d31_arm64:
471 reg_value.SetDouble(tls_context.V[reg - fpu_d0_arm64].D[0]);
472 break;
473
474 case fpu_fpsr_arm64:
475 reg_value.SetUInt32(tls_context.Fpsr);
476 break;
477
478 case fpu_fpcr_arm64:
479 reg_value.SetUInt32(tls_context.Fpcr);
480 break;
481 }
482
483 return error;
484 }
485
486 Status
FPRWrite(const uint32_t reg,const RegisterValue & reg_value)487 NativeRegisterContextWindows_arm64::FPRWrite(const uint32_t reg,
488 const RegisterValue ®_value) {
489 ::CONTEXT tls_context;
490 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
491 auto thread_handle = GetThreadHandle();
492 Status error =
493 GetThreadContextHelper(thread_handle, &tls_context, context_flag);
494 if (error.Fail())
495 return error;
496
497 switch (reg) {
498 case fpu_v0_arm64:
499 case fpu_v1_arm64:
500 case fpu_v2_arm64:
501 case fpu_v3_arm64:
502 case fpu_v4_arm64:
503 case fpu_v5_arm64:
504 case fpu_v6_arm64:
505 case fpu_v7_arm64:
506 case fpu_v8_arm64:
507 case fpu_v9_arm64:
508 case fpu_v10_arm64:
509 case fpu_v11_arm64:
510 case fpu_v12_arm64:
511 case fpu_v13_arm64:
512 case fpu_v14_arm64:
513 case fpu_v15_arm64:
514 case fpu_v16_arm64:
515 case fpu_v17_arm64:
516 case fpu_v18_arm64:
517 case fpu_v19_arm64:
518 case fpu_v20_arm64:
519 case fpu_v21_arm64:
520 case fpu_v22_arm64:
521 case fpu_v23_arm64:
522 case fpu_v24_arm64:
523 case fpu_v25_arm64:
524 case fpu_v26_arm64:
525 case fpu_v27_arm64:
526 case fpu_v28_arm64:
527 case fpu_v29_arm64:
528 case fpu_v30_arm64:
529 case fpu_v31_arm64:
530 memcpy(tls_context.V[reg - fpu_v0_arm64].B, reg_value.GetBytes(), 16);
531 break;
532
533 case fpu_s0_arm64:
534 case fpu_s1_arm64:
535 case fpu_s2_arm64:
536 case fpu_s3_arm64:
537 case fpu_s4_arm64:
538 case fpu_s5_arm64:
539 case fpu_s6_arm64:
540 case fpu_s7_arm64:
541 case fpu_s8_arm64:
542 case fpu_s9_arm64:
543 case fpu_s10_arm64:
544 case fpu_s11_arm64:
545 case fpu_s12_arm64:
546 case fpu_s13_arm64:
547 case fpu_s14_arm64:
548 case fpu_s15_arm64:
549 case fpu_s16_arm64:
550 case fpu_s17_arm64:
551 case fpu_s18_arm64:
552 case fpu_s19_arm64:
553 case fpu_s20_arm64:
554 case fpu_s21_arm64:
555 case fpu_s22_arm64:
556 case fpu_s23_arm64:
557 case fpu_s24_arm64:
558 case fpu_s25_arm64:
559 case fpu_s26_arm64:
560 case fpu_s27_arm64:
561 case fpu_s28_arm64:
562 case fpu_s29_arm64:
563 case fpu_s30_arm64:
564 case fpu_s31_arm64:
565 tls_context.V[reg - fpu_s0_arm64].S[0] = reg_value.GetAsFloat();
566 break;
567
568 case fpu_d0_arm64:
569 case fpu_d1_arm64:
570 case fpu_d2_arm64:
571 case fpu_d3_arm64:
572 case fpu_d4_arm64:
573 case fpu_d5_arm64:
574 case fpu_d6_arm64:
575 case fpu_d7_arm64:
576 case fpu_d8_arm64:
577 case fpu_d9_arm64:
578 case fpu_d10_arm64:
579 case fpu_d11_arm64:
580 case fpu_d12_arm64:
581 case fpu_d13_arm64:
582 case fpu_d14_arm64:
583 case fpu_d15_arm64:
584 case fpu_d16_arm64:
585 case fpu_d17_arm64:
586 case fpu_d18_arm64:
587 case fpu_d19_arm64:
588 case fpu_d20_arm64:
589 case fpu_d21_arm64:
590 case fpu_d22_arm64:
591 case fpu_d23_arm64:
592 case fpu_d24_arm64:
593 case fpu_d25_arm64:
594 case fpu_d26_arm64:
595 case fpu_d27_arm64:
596 case fpu_d28_arm64:
597 case fpu_d29_arm64:
598 case fpu_d30_arm64:
599 case fpu_d31_arm64:
600 tls_context.V[reg - fpu_d0_arm64].D[0] = reg_value.GetAsDouble();
601 break;
602
603 case fpu_fpsr_arm64:
604 tls_context.Fpsr = reg_value.GetAsUInt32();
605 break;
606
607 case fpu_fpcr_arm64:
608 tls_context.Fpcr = reg_value.GetAsUInt32();
609 break;
610 }
611
612 return SetThreadContextHelper(thread_handle, &tls_context);
613 }
614
615 Status
ReadRegister(const RegisterInfo * reg_info,RegisterValue & reg_value)616 NativeRegisterContextWindows_arm64::ReadRegister(const RegisterInfo *reg_info,
617 RegisterValue ®_value) {
618 Status error;
619 if (!reg_info) {
620 error.SetErrorString("reg_info NULL");
621 return error;
622 }
623
624 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
625 if (reg == LLDB_INVALID_REGNUM) {
626 // This is likely an internal register for lldb use only and should not be
627 // directly queried.
628 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
629 "register, cannot read directly",
630 reg_info->name);
631 return error;
632 }
633
634 if (IsGPR(reg))
635 return GPRRead(reg, reg_value);
636
637 if (IsFPR(reg))
638 return FPRRead(reg, reg_value);
639
640 return Status("unimplemented");
641 }
642
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & reg_value)643 Status NativeRegisterContextWindows_arm64::WriteRegister(
644 const RegisterInfo *reg_info, const RegisterValue ®_value) {
645 Status error;
646
647 if (!reg_info) {
648 error.SetErrorString("reg_info NULL");
649 return error;
650 }
651
652 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
653 if (reg == LLDB_INVALID_REGNUM) {
654 // This is likely an internal register for lldb use only and should not be
655 // directly written.
656 error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
657 "register, cannot write directly",
658 reg_info->name);
659 return error;
660 }
661
662 if (IsGPR(reg))
663 return GPRWrite(reg, reg_value);
664
665 if (IsFPR(reg))
666 return FPRWrite(reg, reg_value);
667
668 return Status("unimplemented");
669 }
670
ReadAllRegisterValues(lldb::DataBufferSP & data_sp)671 Status NativeRegisterContextWindows_arm64::ReadAllRegisterValues(
672 lldb::DataBufferSP &data_sp) {
673 const size_t data_size = REG_CONTEXT_SIZE;
674 data_sp = std::make_shared<DataBufferHeap>(data_size, 0);
675 ::CONTEXT tls_context;
676 Status error =
677 GetThreadContextHelper(GetThreadHandle(), &tls_context, CONTEXT_ALL);
678 if (error.Fail())
679 return error;
680
681 uint8_t *dst = data_sp->GetBytes();
682 ::memcpy(dst, &tls_context, data_size);
683 return error;
684 }
685
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)686 Status NativeRegisterContextWindows_arm64::WriteAllRegisterValues(
687 const lldb::DataBufferSP &data_sp) {
688 Status error;
689 const size_t data_size = REG_CONTEXT_SIZE;
690 if (!data_sp) {
691 error.SetErrorStringWithFormat(
692 "NativeRegisterContextWindows_arm64::%s invalid data_sp provided",
693 __FUNCTION__);
694 return error;
695 }
696
697 if (data_sp->GetByteSize() != data_size) {
698 error.SetErrorStringWithFormatv(
699 "data_sp contained mismatched data size, expected {0}, actual {1}",
700 data_size, data_sp->GetByteSize());
701 return error;
702 }
703
704 ::CONTEXT tls_context;
705 memcpy(&tls_context, data_sp->GetBytes(), data_size);
706 return SetThreadContextHelper(GetThreadHandle(), &tls_context);
707 }
708
IsWatchpointHit(uint32_t wp_index,bool & is_hit)709 Status NativeRegisterContextWindows_arm64::IsWatchpointHit(uint32_t wp_index,
710 bool &is_hit) {
711 return Status("unimplemented");
712 }
713
GetWatchpointHitIndex(uint32_t & wp_index,lldb::addr_t trap_addr)714 Status NativeRegisterContextWindows_arm64::GetWatchpointHitIndex(
715 uint32_t &wp_index, lldb::addr_t trap_addr) {
716 return Status("unimplemented");
717 }
718
IsWatchpointVacant(uint32_t wp_index,bool & is_vacant)719 Status NativeRegisterContextWindows_arm64::IsWatchpointVacant(uint32_t wp_index,
720 bool &is_vacant) {
721 return Status("unimplemented");
722 }
723
SetHardwareWatchpointWithIndex(lldb::addr_t addr,size_t size,uint32_t watch_flags,uint32_t wp_index)724 Status NativeRegisterContextWindows_arm64::SetHardwareWatchpointWithIndex(
725 lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
726 return Status("unimplemented");
727 }
728
ClearHardwareWatchpoint(uint32_t wp_index)729 bool NativeRegisterContextWindows_arm64::ClearHardwareWatchpoint(
730 uint32_t wp_index) {
731 return false;
732 }
733
ClearAllHardwareWatchpoints()734 Status NativeRegisterContextWindows_arm64::ClearAllHardwareWatchpoints() {
735 return Status("unimplemented");
736 }
737
SetHardwareWatchpoint(lldb::addr_t addr,size_t size,uint32_t watch_flags)738 uint32_t NativeRegisterContextWindows_arm64::SetHardwareWatchpoint(
739 lldb::addr_t addr, size_t size, uint32_t watch_flags) {
740 return LLDB_INVALID_INDEX32;
741 }
742
743 lldb::addr_t
GetWatchpointAddress(uint32_t wp_index)744 NativeRegisterContextWindows_arm64::GetWatchpointAddress(uint32_t wp_index) {
745 return LLDB_INVALID_ADDRESS;
746 }
747
NumSupportedHardwareWatchpoints()748 uint32_t NativeRegisterContextWindows_arm64::NumSupportedHardwareWatchpoints() {
749 // Not implemented
750 return 0;
751 }
752
753 #endif // defined(__aarch64__) || defined(_M_ARM64)
754