LLDB mainline
NativeRegisterContextLinux_arm64.cpp
Go to the documentation of this file.
1//===-- NativeRegisterContextLinux_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(__arm64__) || defined(__aarch64__)
10
14
15#include "lldb/Host/HostInfo.h"
19#include "lldb/Utility/Log.h"
21#include "lldb/Utility/Status.h"
22
29
30#include "llvm/BinaryFormat/ELF.h"
31
32// System includes - They have to be included after framework includes because
33// they define some macros which collide with variable names in other modules
34#include <mutex>
35#include <optional>
36#include <sys/uio.h>
37
38#ifndef HWCAP_PACA
39#define HWCAP_PACA (1 << 30)
40#endif
41
42#ifndef HWCAP_GCS
43#define HWCAP_GCS (1UL << 32)
44#endif
45
46#ifndef HWCAP2_MTE
47#define HWCAP2_MTE (1 << 18)
48#endif
49
50#ifndef HWCAP2_FPMR
51#define HWCAP2_FPMR (1UL << 48)
52#endif
53
54#ifndef HWCAP2_POE
55#define HWCAP2_POE (1ULL << 63)
56#endif
57
58using namespace lldb;
59using namespace lldb_private;
60using namespace lldb_private::process_linux;
61
62NativeRegisterContextLinux_arm64::RegisterSetType
63NativeRegisterContextLinux_arm64::GetInvalidationMask(
64 const RegisterSetType set) const {
65 switch (set) {
66 case RegisterSetType::FPMR:
67 case RegisterSetType::GPR:
68 case RegisterSetType::GCS:
69 case RegisterSetType::MTE:
70 case RegisterSetType::PAC:
71 case RegisterSetType::POE:
72 case RegisterSetType::TLS:
73 return set;
74 case RegisterSetType::SVE_HEADER:
75 case RegisterSetType::SVE:
76 case RegisterSetType::FPR:
77 return RegisterSetType::SVE_HEADER | RegisterSetType::SVE |
78 // SVE registers overlap FP registers in hardware.
79 RegisterSetType::FPR;
80 case RegisterSetType::ZA_HEADER:
81 case RegisterSetType::ZA:
82 case RegisterSetType::ZT:
83 // In the Linux ptrace ABI, writes that enable ZA or ZT result in
84 // both ZA and ZT being enabled.
85 return RegisterSetType::ZA_HEADER | RegisterSetType::ZA |
86 RegisterSetType::ZT;
87 }
88}
89
90unsigned int NativeRegisterContextLinux_arm64::GetPtraceSet(
91 NativeRegisterContextLinux_arm64::RegisterSetType set) const {
92 switch (set) {
93 case RegisterSetType::GPR:
94 return llvm::ELF::NT_PRSTATUS;
95 case RegisterSetType::FPR:
96 return llvm::ELF::NT_FPREGSET;
97 case RegisterSetType::SVE:
98 case RegisterSetType::SVE_HEADER:
99 switch (m_sve_state) {
102 return llvm::ELF::NT_ARM_SSVE;
103 default:
104 return llvm::ELF::NT_ARM_SVE;
105 }
106 case RegisterSetType::PAC:
107 return llvm::ELF::NT_ARM_PAC_MASK;
108 case RegisterSetType::MTE:
109 return llvm::ELF::NT_ARM_TAGGED_ADDR_CTRL;
110 case RegisterSetType::TLS:
111 return llvm::ELF::NT_ARM_TLS;
112 case RegisterSetType::ZA:
113 case RegisterSetType::ZA_HEADER:
114 return llvm::ELF::NT_ARM_ZA;
115 case RegisterSetType::ZT:
116 return llvm::ELF::NT_ARM_ZT;
117 case RegisterSetType::FPMR:
118 return llvm::ELF::NT_ARM_FPMR;
119 case RegisterSetType::GCS:
120 return llvm::ELF::NT_ARM_GCS;
121 case RegisterSetType::POE:
122 return llvm::ELF::NT_ARM_POE;
123 }
124}
125
126size_t NativeRegisterContextLinux_arm64::GetSetSize(
127 NativeRegisterContextLinux_arm64::RegisterSetType set) const {
128 switch (set) {
129 case RegisterSetType::GPR:
130 // Returns sizeof arm64 GPR ptrace buffer, which is different
131 // from GetGPRSize which returns sizeof RegisterInfoPOSIX_arm64::GPR.
132 return sizeof(m_gpr_arm64);
133 case RegisterSetType::FPR:
134 return sizeof(m_fpr);
135 case RegisterSetType::SVE:
136 return m_sve_ptrace_payload.size();
137 case RegisterSetType::SVE_HEADER:
138 return sizeof(m_sve_header);
139 case RegisterSetType::PAC:
140 return sizeof(m_pac_mask);
141 case RegisterSetType::MTE:
142 return sizeof(m_mte_ctrl_reg);
143 case RegisterSetType::TLS:
144 return m_tls_size;
145 case RegisterSetType::ZA:
146 return m_za_ptrace_payload.size();
147 case RegisterSetType::ZA_HEADER:
148 return sizeof(m_za_header);
149 case RegisterSetType::ZT:
150 return m_zt_reg.size();
151 case RegisterSetType::FPMR:
152 return sizeof(m_fpmr_reg);
153 case RegisterSetType::GCS:
154 return sizeof(m_gcs_regs);
155 case RegisterSetType::POE:
156 return sizeof(m_poe_regs);
157 }
158}
159
160void *NativeRegisterContextLinux_arm64::GetSetBuffer(
161 NativeRegisterContextLinux_arm64::RegisterSetType set) {
162 switch (set) {
163 case RegisterSetType::GPR:
164 return &m_gpr_arm64;
165 case RegisterSetType::FPR:
166 return &m_fpr;
167 case RegisterSetType::SVE:
168 return m_sve_ptrace_payload.data();
169 case RegisterSetType::SVE_HEADER:
170 return &m_sve_header;
171 case RegisterSetType::PAC:
172 return &m_pac_mask;
173 case RegisterSetType::MTE:
174 return &m_mte_ctrl_reg;
175 case RegisterSetType::TLS:
176 return &m_tls_regs;
177 case RegisterSetType::ZA:
178 return m_za_ptrace_payload.data();
179 case RegisterSetType::ZA_HEADER:
180 return &m_za_header;
181 case RegisterSetType::ZT:
182 return m_zt_reg.data();
183 case RegisterSetType::FPMR:
184 return &m_fpmr_reg;
185 case RegisterSetType::GCS:
186 return &m_gcs_regs;
187 case RegisterSetType::POE:
188 return &m_poe_regs;
189 }
190}
191
192// A NativeRegisterContext is constructed per thread, but all threads' registers
193// will contain the same fields. Therefore this mutex prevents each instance
194// competing with the other, and subsequent instances from having to detect the
195// fields all over again.
196static std::mutex g_register_type_detector_mutex;
197static Arm64RegisterTypeDetector g_register_type_detector;
198
199std::unique_ptr<NativeRegisterContextLinux>
201 const ArchSpec &target_arch, NativeThreadLinux &native_thread) {
202 switch (target_arch.GetMachine()) {
203 case llvm::Triple::arm:
204 return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
205 native_thread);
206 case llvm::Triple::aarch64: {
207 // Configure register sets supported by this AArch64 target.
208 // Read SVE header to check for SVE support.
209 struct sve::user_sve_header sve_header;
210 struct iovec ioVec;
211 ioVec.iov_base = &sve_header;
212 ioVec.iov_len = sizeof(sve_header);
213 unsigned int regset = llvm::ELF::NT_ARM_SVE;
214
215 Flags opt_regsets;
217 native_thread.GetID(), &regset,
218 &ioVec, sizeof(sve_header))
219 .Success())
221
222 // We may have the Scalable Matrix Extension (SME) which adds a
223 // streaming SVE mode. Systems can have SVE and/or SME.
224 ioVec.iov_len = sizeof(sve_header);
225 regset = llvm::ELF::NT_ARM_SSVE;
227 native_thread.GetID(), &regset,
228 &ioVec, sizeof(sve_header))
229 .Success())
231
232 sve::user_za_header za_header;
233 ioVec.iov_base = &za_header;
234 ioVec.iov_len = sizeof(za_header);
235 regset = llvm::ELF::NT_ARM_ZA;
237 native_thread.GetID(), &regset,
238 &ioVec, sizeof(za_header))
239 .Success())
241
242 // SME's ZT0 is a 512 bit register.
243 std::array<uint8_t, 64> zt_reg;
244 ioVec.iov_base = zt_reg.data();
245 ioVec.iov_len = zt_reg.size();
246 regset = llvm::ELF::NT_ARM_ZT;
248 native_thread.GetID(), &regset,
249 &ioVec, zt_reg.size())
250 .Success())
252
253 NativeProcessLinux &process = native_thread.GetProcess();
254
255 std::optional<uint64_t> auxv_at_hwcap =
257 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
259
260 std::optional<uint64_t> auxv_at_hwcap2 =
262 if (auxv_at_hwcap2) {
263 if (*auxv_at_hwcap2 & HWCAP2_MTE)
265 if (*auxv_at_hwcap2 & HWCAP2_FPMR)
267 if (*auxv_at_hwcap & HWCAP_GCS)
269 if (*auxv_at_hwcap2 & HWCAP2_POE)
271 }
272
274
275 std::optional<uint64_t> auxv_at_hwcap3 =
277 std::lock_guard<std::mutex> lock(g_register_type_detector_mutex);
278 if (!g_register_type_detector.HasDetected())
279 g_register_type_detector.DetectTypes(auxv_at_hwcap.value_or(0),
280 auxv_at_hwcap2.value_or(0),
281 auxv_at_hwcap3.value_or(0));
282
283 auto register_info_up =
284 std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
285 return std::make_unique<NativeRegisterContextLinux_arm64>(
286 target_arch, native_thread, std::move(register_info_up));
287 }
288 default:
289 llvm_unreachable("have no register context for architecture");
290 }
291}
292
293llvm::Expected<ArchSpec>
295 return DetermineArchitectureViaGPR(
297}
298
299NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
300 const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
301 std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
302 : NativeRegisterContextRegisterInfo(native_thread,
303 register_info_up.release()),
304 NativeRegisterContextLinux(native_thread) {
305 g_register_type_detector.UpdateRegisterInfo(
306 GetRegisterInfoInterface().GetRegisterInfo(),
307 GetRegisterInfoInterface().GetRegisterCount());
308
309 // 16 is just a maximum value, query hardware for actual watchpoint count
310 m_max_hwp_supported = 16;
311 m_max_hbp_supported = 16;
312
313 // SME adds the tpidr2 register
314 m_tls_size = GetRegisterInfo().IsSSVEPresent() ? sizeof(m_tls_regs)
315 : sizeof(m_tls_regs.tpidr_reg);
316
317 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
318 m_sve_state = SVEState::Unknown;
319 else
320 m_sve_state = SVEState::Disabled;
321}
322
324NativeRegisterContextLinux_arm64::GetRegisterInfo() const {
325 return static_cast<RegisterInfoPOSIX_arm64 &>(*m_register_info_interface_up);
326}
327
328uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const {
329 return GetRegisterInfo().GetRegisterSetCount();
330}
331
332const RegisterSet *
333NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const {
334 return GetRegisterInfo().GetRegisterSet(set_index);
335}
336
337uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const {
338 uint32_t count = 0;
339 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
340 count += GetRegisterSet(set_index)->num_registers;
341 return count;
342}
343
344Status
345NativeRegisterContextLinux_arm64::ReadRegister(const RegisterInfo *reg_info,
346 RegisterValue &reg_value) {
348
349 if (!reg_info) {
350 error = Status::FromErrorString("reg_info NULL");
351 return error;
352 }
353
354 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
355
356 if (reg == LLDB_INVALID_REGNUM)
358 "no lldb regnum for %s",
359 reg_info && reg_info->name ? reg_info->name : "<unknown register>");
360
361 uint8_t *src;
362 uint32_t offset = LLDB_INVALID_INDEX32;
363 uint64_t sve_vg;
364 std::vector<uint8_t> sve_reg_non_live;
365
366 if (GetRegisterInfo().IsGPR(reg)) {
367 error = ReadGPR();
368 if (error.Fail())
369 return error;
370
371 offset = reg_info->byte_offset;
372 assert(offset < GetGPRSize());
373 src = (uint8_t *)GetGPRBuffer() + offset;
374
375 } else if (GetRegisterInfo().IsFPR(reg)) {
376 if (m_sve_state == SVEState::Disabled ||
377 m_sve_state == SVEState::StreamingFPSIMD) {
378 // FP registers come from the FP register set when:
379 // * We only have SVE in streaming mode, and we are in non-streaming mode.
380 // * We only have SIMD, no SVE in any mode.
381 error = ReadFPR();
382 if (error.Fail())
383 return error;
384
385 offset = CalculateFprOffset(reg_info,
386 m_sve_state == SVEState::StreamingFPSIMD);
387 assert(offset < GetFPRSize());
388 src = (uint8_t *)GetFPRBuffer() + offset;
389 } else {
390 // SVE or SSVE enabled, we will read and cache SVE ptrace data.
391 // In SIMD or Full mode, the data comes from the SVE regset. In streaming
392 // mode it comes from the streaming SVE regset.
393 error = ReadAllSVE();
394 if (error.Fail())
395 return error;
396
397 // FPSR and FPCR will be located right after Z registers in
398 // SVEState::FPSIMD while in SVEState::Full or SVEState::Streaming they
399 // will be located at the end of register data after an alignment
400 // correction based on currently selected vector length.
401 uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
402 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
403 sve_reg_num = reg;
404 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
405 offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
406 else if (m_sve_state == SVEState::FPSIMD)
407 offset = sve::ptrace_fpsimd_offset + (32 * 16);
408 } else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
409 sve_reg_num = reg;
410 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
411 offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
412 else if (m_sve_state == SVEState::FPSIMD)
413 offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
414 } else {
415 // Extract SVE Z register value register number for this reg_info
416 if (reg_info->value_regs &&
417 reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
418 sve_reg_num = reg_info->value_regs[0];
419 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
420 }
421
422 assert(offset < GetSetSize(RegisterSetType::SVE));
423 src = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
424 }
425 } else if (GetRegisterInfo().IsTLSReg(reg)) {
426 error = ReadTLS();
427 if (error.Fail())
428 return error;
429
430 offset = reg_info->byte_offset - GetRegisterInfo().GetTLSOffset();
431 assert(offset < GetSetSize(RegisterSetType::TLS));
432 src = (uint8_t *)GetSetBuffer(RegisterSetType::TLS) + offset;
433 } else if (GetRegisterInfo().IsSVEReg(reg)) {
434 if (m_sve_state == SVEState::Disabled || m_sve_state == SVEState::Unknown)
435 return Status::FromErrorString("SVE disabled or not supported");
436
437 if (GetRegisterInfo().IsSVERegVG(reg)) {
438 error = ReadSVEHeader();
439 if (error.Fail())
440 return error;
441
442 sve_vg = GetSVERegVG();
443 src = (uint8_t *)&sve_vg;
444 } else if (m_sve_state == SVEState::StreamingFPSIMD) {
445 // When we only have streaming SVE and we are in non-streaming mode,
446 // we cannot read streaming SVE registers.
447
448 // P and FFR show as 0s.
449 if (GetRegisterInfo().IsSVEPReg(reg) ||
450 GetRegisterInfo().IsSVERegFFR(reg)) {
451 std::vector<uint8_t> fake_reg(reg_info->byte_size, 0);
452 reg_value.SetFromMemoryData(*reg_info, &fake_reg[0],
453 reg_info->byte_size, eByteOrderLittle,
454 error);
455 return error;
456 }
457
458 // For Z registers, zero extend the 128-bit FP register to Z register
459 // size.
460
461 error = ReadFPR();
462 if (error.Fail())
463 return error;
464
465 // As we told the client we have Z registers, our own internal offsets
466 // are set as if we were using an SVE context. We need to work out
467 // an offset within the FP context instead:
468 // struct user_fpsimd_state {
469 // __uint128_t vregs[32];
470 // __u32 fpsr;
471 // __u32 fpcr;
472 // __u32 __reserved[2];
473 // };
474 const uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
475 offset = z_num * 16;
476 assert(offset < GetFPRSize());
477 src = (uint8_t *)GetFPRBuffer() + offset;
478
479 // Copy from FP into a fake Z value.
480 std::vector<uint8_t> fake_z(reg_info->byte_size, 0);
481 std::memcpy(&fake_z[0], src, 16 /* 128 bits */);
482 reg_value.SetFromMemoryData(*reg_info, &fake_z[0], reg_info->byte_size,
484
485 return error;
486 } else {
487 // SVE enabled, we will read and cache SVE ptrace data
488 error = ReadAllSVE();
489 if (error.Fail())
490 return error;
491
492 if (m_sve_state == SVEState::FPSIMD) {
493 // In FPSIMD state SVE payload mirrors legacy fpsimd struct and so
494 // just copy 16 bytes of v register to the start of z register. All
495 // other SVE register will be set to zero.
496 sve_reg_non_live.resize(reg_info->byte_size, 0);
497 src = sve_reg_non_live.data();
498
499 if (GetRegisterInfo().IsSVEZReg(reg)) {
500 offset = CalculateSVEOffset(reg_info);
501 assert(offset < GetSetSize(RegisterSetType::SVE));
502 ::memcpy(sve_reg_non_live.data(),
503 (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset, 16);
504 }
505 } else {
506 offset = CalculateSVEOffset(reg_info);
507 assert(offset < GetSetSize(RegisterSetType::SVE));
508 src = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
509 }
510 }
511 } else if (GetRegisterInfo().IsPAuthReg(reg)) {
512 error = ReadPAuthMask();
513 if (error.Fail())
514 return error;
515
516 offset = reg_info->byte_offset - GetRegisterInfo().GetPAuthOffset();
517 assert(offset < GetSetSize(RegisterSetType::PAC));
518 src = (uint8_t *)GetSetBuffer(RegisterSetType::PAC) + offset;
519 } else if (GetRegisterInfo().IsMTEReg(reg)) {
520 error = ReadMTEControl();
521 if (error.Fail())
522 return error;
523
524 offset = reg_info->byte_offset - GetRegisterInfo().GetMTEOffset();
525 assert(offset < GetSetSize(RegisterSetType::MTE));
526 src = (uint8_t *)GetSetBuffer(RegisterSetType::MTE) + offset;
527 } else if (GetRegisterInfo().IsSMEReg(reg)) {
528 if (GetRegisterInfo().IsSMERegZA(reg)) {
529 error = ReadZAHeader();
530 if (error.Fail())
531 return error;
532
533 // If there is only a header and no registers, ZA is inactive. Read as 0
534 // in this case.
535 if (m_za_header.size == sizeof(m_za_header)) {
536 // This will get reconfigured/reset later, so we are safe to use it.
537 // ZA is a square of VL * VL and the ptrace buffer also includes the
538 // header itself.
539 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
540 GetSetSize(RegisterSetType::ZA_HEADER));
541 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
542 } else {
543 // ZA is active, read the real register.
544 error = ReadZA();
545 if (error.Fail())
546 return error;
547 }
548
549 // ZA is part of the SME set but uses a separate member buffer for
550 // storage. Therefore its effective byte offset is always 0 even if it
551 // isn't 0 within the SME register set.
552 src = (uint8_t *)GetSetBuffer(RegisterSetType::ZA) +
553 GetSetSize(RegisterSetType::ZA_HEADER);
554 } else if (GetRegisterInfo().IsSMERegZT(reg)) {
555 // Unlike ZA, the kernel will return register data for ZT0 when ZA is not
556 // enabled. This data will be all 0s so we don't have to invent anything
557 // like we did for ZA.
558 error = ReadZT();
559 if (error.Fail())
560 return error;
561
562 src = (uint8_t *)GetSetBuffer(RegisterSetType::ZT);
563 } else {
564 error = ReadSMESVG();
565 if (error.Fail())
566 return error;
567
568 // This is a psuedo so it never fails.
569 ReadSMEControl();
570
571 offset = reg_info->byte_offset - GetRegisterInfo().GetSMEOffset();
572 assert(offset < GetSMEPseudoBufferSize());
573 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
574 }
575 } else if (GetRegisterInfo().IsFPMRReg(reg)) {
576 error = ReadFPMR();
577 if (error.Fail())
578 return error;
579
580 offset = reg_info->byte_offset - GetRegisterInfo().GetFPMROffset();
581 assert(offset < GetSetSize(RegisterSetType::FPMR));
582 src = (uint8_t *)GetSetBuffer(RegisterSetType::FPMR) + offset;
583 } else if (GetRegisterInfo().IsGCSReg(reg)) {
584 error = ReadGCS();
585 if (error.Fail())
586 return error;
587
588 offset = reg_info->byte_offset - GetRegisterInfo().GetGCSOffset();
589 assert(offset < GetSetSize(RegisterSetType::GCS));
590 src = (uint8_t *)GetSetBuffer(RegisterSetType::GCS) + offset;
591 } else if (GetRegisterInfo().IsPOEReg(reg)) {
592 error = ReadPOE();
593 if (error.Fail())
594 return error;
595
596 offset = reg_info->byte_offset - GetRegisterInfo().GetPOEOffset();
597 assert(offset < GetSetSize(RegisterSetType::POE));
598 src = (uint8_t *)GetSetBuffer(RegisterSetType::POE) + offset;
599 } else
601 "failed - register wasn't recognized to be a GPR or an FPR, "
602 "write strategy unknown");
603
604 reg_value.SetFromMemoryData(*reg_info, src, reg_info->byte_size,
606
607 return error;
608}
609
610Status NativeRegisterContextLinux_arm64::WriteRegister(
611 const RegisterInfo *reg_info, const RegisterValue &reg_value) {
613
614 if (!reg_info)
615 return Status::FromErrorString("reg_info NULL");
616
617 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
618
619 if (reg == LLDB_INVALID_REGNUM)
621 "no lldb regnum for %s",
622 reg_info && reg_info->name ? reg_info->name : "<unknown register>");
623
624 uint8_t *dst;
625 uint32_t offset = LLDB_INVALID_INDEX32;
626 std::vector<uint8_t> sve_reg_non_live;
627
628 if (GetRegisterInfo().IsGPR(reg)) {
629 error = ReadGPR();
630 if (error.Fail())
631 return error;
632
633 assert(reg_info->byte_offset < GetGPRSize());
634 dst = (uint8_t *)GetGPRBuffer() + reg_info->byte_offset;
635 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
636
637 return WriteGPR();
638 } else if (GetRegisterInfo().IsFPR(reg)) {
639 if (m_sve_state == SVEState::Disabled ||
640 m_sve_state == SVEState::StreamingFPSIMD) {
641 // SVE is not present, or we only have it in streaming mode and are
642 // currently outside of streaming mode. Take normal route for FPU register
643 // access.
644 error = ReadFPR();
645 if (error.Fail())
646 return error;
647
648 offset = CalculateFprOffset(reg_info,
649 m_sve_state == SVEState::StreamingFPSIMD);
650 assert(offset < GetFPRSize());
651 dst = (uint8_t *)GetFPRBuffer() + offset;
652 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
653
654 return WriteFPR();
655 } else {
656 // SVE enabled, we will read and cache SVE ptrace data.
657 error = ReadAllSVE();
658 if (error.Fail())
659 return error;
660
661 // FPSR and FPCR will be located right after Z registers in
662 // SVEState::FPSIMD while in SVEState::Full or SVEState::Streaming they
663 // will be located at the end of register data after an alignment
664 // correction based on currently selected vector length.
665 uint32_t sve_reg_num = LLDB_INVALID_REGNUM;
666 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
667 sve_reg_num = reg;
668 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
669 offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
670 else if (m_sve_state == SVEState::FPSIMD)
671 offset = sve::ptrace_fpsimd_offset + (32 * 16);
672 } else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
673 sve_reg_num = reg;
674 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::Streaming)
675 offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
676 else if (m_sve_state == SVEState::FPSIMD)
677 offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
678 } else {
679 // Extract SVE Z register value register number for this reg_info
680 if (reg_info->value_regs &&
681 reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
682 sve_reg_num = reg_info->value_regs[0];
683 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
684 }
685
686 assert(offset < GetSetSize(RegisterSetType::SVE));
687 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
688 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
689 return WriteAllSVE();
690 }
691 } else if (GetRegisterInfo().IsSVEReg(reg)) {
692 if (m_sve_state == SVEState::Disabled || m_sve_state == SVEState::Unknown) {
693 return Status::FromErrorString("SVE disabled or not supported");
694 } else if (m_sve_state == SVEState::StreamingFPSIMD) {
695 // When a target has SVE (in any state), the client is told that it has
696 // real SVE registers and that the FP registers are just subregisters
697 // of those SVE registers. This means that any FP write will be converted
698 // into an SVE write.
699 //
700 // If we get here, it did that, but we are outside of streaming mode
701 // on an SME only system. Meaning there's no way at all to write to actual
702 // SVE registers.
703 //
704 // Instead we will extract the bottom 128 bits of the register,
705 // write that via the standard FP route and then return the fake SVE
706 // values as usual.
707 //
708 // We can only do this for Z registers. P, FFR and VG have no SIMD
709 // equivalent.
710 if (GetRegisterInfo().IsSVERegVG(reg) ||
711 GetRegisterInfo().IsSVEPReg(reg) ||
712 GetRegisterInfo().IsSVERegFFR(reg))
714 "Cannot write SVE VG, P or FFR registers while outside of "
715 "streaming mode.");
716
717 // We have told the client that we only have Z registers and the V
718 // registers are subsets of Z. This means that the V byte offsets are
719 // actually for the SVE register context, which we cannot access right
720 // now. That is, v0 is offset 16, v1 is 16+vlen, and so on. So we will
721 // manually patch this data into the FP context and write it.
722 error = ReadFPR();
723 if (error.Fail())
724 return error;
725
726 uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
727 offset = z_num * 16;
728 assert(offset < GetFPRSize());
729 dst = (uint8_t *)GetFPRBuffer() + offset;
730 // If we get here we must have a Z register. Assume we have 16 bytes aka
731 // 128 bits at least, enough to fill an FP V register.
732 ::memcpy(dst, reg_value.GetBytes(), 16);
733
734 return WriteFPR();
735 } else {
736 // Target has SVE enabled, we will read and cache SVE ptrace data
737 error = ReadAllSVE();
738 if (error.Fail())
739 return error;
740
741 if (GetRegisterInfo().IsSVERegVG(reg)) {
742 uint64_t vg_value = reg_value.GetAsUInt64();
743
744 if (sve::vl_valid(vg_value * 8)) {
745 if (IsValid(RegisterSetType::SVE_HEADER) && vg_value == GetSVERegVG())
746 return error;
747
748 SetSVERegVG(vg_value);
749
750 error = WriteSVEHeader();
751 if (error.Success()) {
752 // Changing VG during streaming mode also changes the size of ZA.
753 if (m_sve_state == SVEState::Streaming)
754 Invalidate(RegisterSetType::ZA_HEADER);
755 ConfigureRegisterContext();
756 }
757
758 if (IsValid(RegisterSetType::SVE_HEADER) && vg_value == GetSVERegVG())
759 return error;
760 }
761
762 return Status::FromErrorString("SVE vector length update failed.");
763 }
764
765 // If target supports SVE but currently in FPSIMD mode.
766 if (m_sve_state == SVEState::FPSIMD) {
767 // Here we will check if writing this SVE register enables
768 // SVEState::Full
769 bool set_sve_state_full = false;
770 const uint8_t *reg_bytes = (const uint8_t *)reg_value.GetBytes();
771 if (GetRegisterInfo().IsSVEZReg(reg)) {
772 for (uint32_t i = 16; i < reg_info->byte_size; i++) {
773 if (reg_bytes[i]) {
774 set_sve_state_full = true;
775 break;
776 }
777 }
778 } else if (GetRegisterInfo().IsSVEPReg(reg) ||
779 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
780 for (uint32_t i = 0; i < reg_info->byte_size; i++) {
781 if (reg_bytes[i]) {
782 set_sve_state_full = true;
783 break;
784 }
785 }
786 }
787
788 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
789 // We are writing a Z register which is zero beyond 16 bytes so copy
790 // first 16 bytes only as SVE payload mirrors legacy fpsimd structure
791 offset = CalculateSVEOffset(reg_info);
792 assert(offset < GetSetSize(RegisterSetType::SVE));
793 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
794 ::memcpy(dst, reg_value.GetBytes(), 16);
795
796 return WriteAllSVE();
797 } else
799 "SVE state change operation not supported");
800 } else {
801 offset = CalculateSVEOffset(reg_info);
802 assert(offset < GetSetSize(RegisterSetType::SVE));
803 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
804 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
805 return WriteAllSVE();
806 }
807 }
808 } else if (GetRegisterInfo().IsMTEReg(reg)) {
809 error = ReadMTEControl();
810 if (error.Fail())
811 return error;
812
813 offset = reg_info->byte_offset - GetRegisterInfo().GetMTEOffset();
814 assert(offset < GetSetSize(RegisterSetType::MTE));
815 dst = (uint8_t *)GetSetBuffer(RegisterSetType::MTE) + offset;
816 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
817
818 return WriteMTEControl();
819 } else if (GetRegisterInfo().IsTLSReg(reg)) {
820 error = ReadTLS();
821 if (error.Fail())
822 return error;
823
824 offset = reg_info->byte_offset - GetRegisterInfo().GetTLSOffset();
825 assert(offset < GetSetSize(RegisterSetType::TLS));
826 dst = (uint8_t *)GetSetBuffer(RegisterSetType::TLS) + offset;
827 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
828
829 return WriteTLS();
830 } else if (GetRegisterInfo().IsSMEReg(reg)) {
831 if (GetRegisterInfo().IsSMERegZA(reg)) {
832 error = ReadZA();
833 if (error.Fail())
834 return error;
835
836 // ZA is part of the SME set but not stored with the other SME registers.
837 // So its byte offset is effectively always 0.
838 dst = (uint8_t *)GetSetBuffer(RegisterSetType::ZA) +
839 GetSetSize(RegisterSetType::ZA_HEADER);
840 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
841
842 // While this is writing a header that contains a vector length, the only
843 // way to change that is via the vg register. So here we assume the length
844 // will always be the current length and no reconfigure is needed.
845 return WriteZA();
846 } else if (GetRegisterInfo().IsSMERegZT(reg)) {
847 error = ReadZT();
848 if (error.Fail())
849 return error;
850
851 dst = (uint8_t *)GetSetBuffer(RegisterSetType::ZT);
852 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
853
854 return WriteZT();
855 } else
857 "Writing to SVG or SVCR is not supported.");
858 } else if (GetRegisterInfo().IsFPMRReg(reg)) {
859 error = ReadFPMR();
860 if (error.Fail())
861 return error;
862
863 offset = reg_info->byte_offset - GetRegisterInfo().GetFPMROffset();
864 assert(offset < GetSetSize(RegisterSetType::FPMR));
865 dst = (uint8_t *)GetSetBuffer(RegisterSetType::FPMR) + offset;
866 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
867
868 return WriteFPMR();
869 } else if (GetRegisterInfo().IsGCSReg(reg)) {
870 error = ReadGCS();
871 if (error.Fail())
872 return error;
873
874 offset = reg_info->byte_offset - GetRegisterInfo().GetGCSOffset();
875 assert(offset < GetSetSize(RegisterSetType::GCS));
876 dst = (uint8_t *)GetSetBuffer(RegisterSetType::GCS) + offset;
877 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
878
879 return WriteGCS();
880 } else if (GetRegisterInfo().IsPOEReg(reg)) {
881 error = ReadPOE();
882 if (error.Fail())
883 return error;
884
885 offset = reg_info->byte_offset - GetRegisterInfo().GetPOEOffset();
886 assert(offset < GetSetSize(RegisterSetType::POE));
887 dst = (uint8_t *)GetSetBuffer(RegisterSetType::POE) + offset;
888 ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size);
889
890 return WritePOE();
891 }
892
893 return Status::FromErrorString("Failed to write register value");
894}
895
896uint8_t *NativeRegisterContextLinux_arm64::AddRegisterSetType(
897 uint8_t *dst, RegisterSetType register_set_type) {
898 std::memcpy(dst, &register_set_type, sizeof(register_set_type));
899 return dst + sizeof(RegisterSetType);
900}
901
902static uint8_t *AddSavedRegistersData(uint8_t *dst, void *src, size_t size) {
903 ::memcpy(dst, src, size);
904 return dst + size;
905}
906
907uint8_t *NativeRegisterContextLinux_arm64::AddSavedRegisters(
908 uint8_t *dst, RegisterSetType register_set_type, void *src, size_t size) {
909 dst = AddRegisterSetType(dst, register_set_type);
910 return AddSavedRegistersData(dst, src, size);
911}
912
913Status
914NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
916 cached_size = sizeof(RegisterSetType) + GetGPRBufferSize();
917 error = ReadGPR();
918 if (error.Fail())
919 return error;
920
921 if (GetRegisterInfo().IsZAPresent()) {
922 error = ReadZAHeader();
923 if (error.Fail())
924 return error;
925 // Use header size here because the buffer may contain fake data when ZA is
926 // disabled. We do not want to write this fake data (all 0s) because this
927 // would tell the kernel that we want ZA to become active. Which is the
928 // opposite of what we want in the case where it is currently inactive.
929 cached_size += sizeof(RegisterSetType) + m_za_header.size;
930 // For the same reason, we need to force it to be re-read so that it will
931 // always contain the real header.
932 Invalidate(RegisterSetType::ZA);
933 error = ReadZA();
934 if (error.Fail())
935 return error;
936
937 // We will only be restoring ZT data if ZA is active. As writing to an
938 // inactive ZT enables ZA, which may not be desireable.
939 if (
940 // If we have ZT0, or in other words, if we have SME2.
941 GetRegisterInfo().IsZTPresent() &&
942 // And ZA is active, which means that ZT0 is also active.
943 m_za_header.size > sizeof(m_za_header)) {
944 cached_size += sizeof(RegisterSetType) + GetSetSize(RegisterSetType::ZT);
945 // The kernel handles an inactive ZT0 for us, and it will read as 0s if
946 // inactive (unlike ZA where we fake that behaviour).
947 error = ReadZT();
948 if (error.Fail())
949 return error;
950 }
951 }
952
953 // If SVE is enabled we need not copy FPR separately, unless we are in the
954 // non-streaming mode of a streaming only process (as its non-streaming mode
955 // is FPSIMD, rather than SVE).
956 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
957 m_sve_state != SVEState::StreamingFPSIMD) {
958 // Store mode and register data.
959 cached_size += sizeof(RegisterSetType) + sizeof(m_sve_state) +
960 GetSetSize(RegisterSetType::SVE);
961 error = ReadAllSVE();
962 } else {
963 cached_size += sizeof(RegisterSetType) + GetFPRSize();
964 error = ReadFPR();
965 }
966 if (error.Fail())
967 return error;
968
969 if (GetRegisterInfo().IsMTEPresent()) {
970 cached_size += sizeof(RegisterSetType) + GetSetSize(RegisterSetType::MTE);
971 error = ReadMTEControl();
972 if (error.Fail())
973 return error;
974 }
975
976 if (GetRegisterInfo().IsFPMRPresent()) {
977 cached_size += sizeof(RegisterSetType) + GetSetSize(RegisterSetType::FPMR);
978 error = ReadFPMR();
979 if (error.Fail())
980 return error;
981 }
982
983 if (GetRegisterInfo().IsGCSPresent()) {
984 cached_size += sizeof(RegisterSetType) + GetSetSize(RegisterSetType::GCS);
985 error = ReadGCS();
986 if (error.Fail())
987 return error;
988 }
989
990 if (GetRegisterInfo().IsPOEPresent()) {
991 cached_size += sizeof(RegisterSetType) + GetSetSize(RegisterSetType::POE);
992 error = ReadPOE();
993 if (error.Fail())
994 return error;
995 }
996
997 // tpidr is always present but tpidr2 depends on SME.
998 cached_size += sizeof(RegisterSetType) + GetSetSize(RegisterSetType::TLS);
999 error = ReadTLS();
1000
1001 return error;
1002}
1003
1004Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
1005 lldb::WritableDataBufferSP &data_sp) {
1006 // AArch64 register data must contain GPRs and either FPR or SVE registers.
1007 // SVE registers can be non-streaming (aka SVE) or streaming (aka SSVE).
1008 // Finally an optional MTE register. Pointer Authentication (PAC) registers
1009 // are read-only and will be skipped.
1010
1011 // In order to create register data checkpoint we first read all register
1012 // values if not done already and calculate total size of register set data.
1013 // We store all register values in data_sp by copying full PTrace data that
1014 // corresponds to register sets enabled by current register context.
1015
1016 uint32_t reg_data_byte_size = 0;
1017 Status error = CacheAllRegisters(reg_data_byte_size);
1018 if (error.Fail())
1019 return error;
1020
1021 data_sp.reset(new DataBufferHeap(reg_data_byte_size, 0));
1022 uint8_t *dst = data_sp->GetBytes();
1023
1024 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
1025 GetGPRBufferSize());
1026
1027 // Streaming SVE and the ZA register both use the streaming vector length.
1028 // When you change this, the kernel will invalidate parts of the process
1029 // state. Therefore we need a specific order of restoration for each mode, if
1030 // we also have ZA to restore.
1031 //
1032 // Streaming mode enabled, ZA enabled:
1033 // * Write streaming registers. This sets SVCR.SM and clears SVCR.ZA.
1034 // * Write ZA, this set SVCR.ZA. The register data we provide is written to
1035 // ZA.
1036 // * Result is SVCR.SM and SVCR.ZA set, with the expected data in both
1037 // register sets.
1038 //
1039 // Streaming mode disabled, ZA enabled:
1040 // * Write ZA. This sets SVCR.ZA, and the ZA content. In the majority of cases
1041 // the streaming vector length is changing, so the thread is converted into
1042 // an FPSIMD thread if it is not already one. This also clears SVCR.SM.
1043 // * Write SVE registers, which also clears SVCR.SM but most importantly, puts
1044 // us into full SVE mode instead of FPSIMD mode (where the registers are
1045 // actually the 128 bit Neon registers).
1046 // * Result is we have SVCR.SM = 0, SVCR.ZA = 1 and the expected register
1047 // state.
1048 //
1049 // Restoring in different orders leads to things like the SVE registers being
1050 // truncated due to the FPSIMD mode and ZA being disabled or filled with 0s
1051 // (disabled and 0s looks the same from inside lldb since we fake the value
1052 // when it's disabled).
1053 //
1054 // For more information on this, look up the uses of the relevant NT_ARM_
1055 // constants and the functions vec_set_vector_length, sve_set_common and
1056 // za_set in the Linux Kernel.
1057
1058 if ((m_sve_state != SVEState::Streaming) && GetRegisterInfo().IsZAPresent()) {
1059 // Use the header size not the buffer size, as we may be using the buffer
1060 // for fake data, which we do not want to write out.
1061 assert(m_za_header.size <= GetSetSize(RegisterSetType::ZA));
1062 dst =
1063 AddSavedRegisters(dst, RegisterSetType::ZA,
1064 GetSetBuffer(RegisterSetType::ZA), m_za_header.size);
1065 }
1066
1067 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
1068 m_sve_state != SVEState::StreamingFPSIMD) {
1069 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
1070 std::memcpy(dst, &m_sve_state, sizeof(m_sve_state));
1071 dst += sizeof(m_sve_state);
1072 dst = AddSavedRegistersData(dst, GetSetBuffer(RegisterSetType::SVE),
1073 GetSetSize(RegisterSetType::SVE));
1074 } else {
1075 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
1076 GetFPRSize());
1077 }
1078
1079 if ((m_sve_state == SVEState::Streaming) && GetRegisterInfo().IsZAPresent()) {
1080 assert(m_za_header.size <= GetSetSize(RegisterSetType::ZA));
1081 dst =
1082 AddSavedRegisters(dst, RegisterSetType::ZA,
1083 GetSetBuffer(RegisterSetType::ZA), m_za_header.size);
1084 }
1085
1086 // If ZT0 is present and we are going to be restoring an active ZA (which
1087 // implies an active ZT0), then restore ZT0 after ZA has been set. This
1088 // prevents us enabling ZA accidentally after the restore of ZA disabled it.
1089 // If we leave ZA/ZT0 inactive and read ZT0, the kernel returns 0s. Therefore
1090 // there's nothing for us to restore if ZA was originally inactive.
1091 if (
1092 // If we have SME2 and therefore ZT0.
1093 GetRegisterInfo().IsZTPresent() &&
1094 // And ZA is enabled.
1095 m_za_header.size > sizeof(m_za_header))
1096 dst = AddSavedRegisters(dst, RegisterSetType::ZT,
1097 GetSetBuffer(RegisterSetType::ZT),
1098 GetSetSize(RegisterSetType::ZT));
1099
1100 if (GetRegisterInfo().IsMTEPresent()) {
1101 dst = AddSavedRegisters(dst, RegisterSetType::MTE,
1102 GetSetBuffer(RegisterSetType::MTE),
1103 GetSetSize(RegisterSetType::MTE));
1104 }
1105
1106 if (GetRegisterInfo().IsFPMRPresent()) {
1107 dst = AddSavedRegisters(dst, RegisterSetType::FPMR,
1108 GetSetBuffer(RegisterSetType::FPMR),
1109 GetSetSize(RegisterSetType::FPMR));
1110 }
1111
1112 if (GetRegisterInfo().IsGCSPresent()) {
1113 dst = AddSavedRegisters(dst, RegisterSetType::GCS,
1114 GetSetBuffer(RegisterSetType::GCS),
1115 GetSetSize(RegisterSetType::GCS));
1116 }
1117
1118 if (GetRegisterInfo().IsPOEPresent()) {
1119 dst = AddSavedRegisters(dst, RegisterSetType::POE,
1120 GetSetBuffer(RegisterSetType::POE),
1121 GetSetSize(RegisterSetType::POE));
1122 }
1123
1124 dst = AddSavedRegisters(dst, RegisterSetType::TLS,
1125 GetSetBuffer(RegisterSetType::TLS),
1126 GetSetSize(RegisterSetType::TLS));
1127
1128 return error;
1129}
1130
1131Status NativeRegisterContextLinux_arm64::RestoreRegisters(
1132 void *buffer, const uint8_t **src, size_t len,
1133 const NativeRegisterContextLinux_arm64::RegisterSetType set,
1134 std::function<Status()> writer) {
1135 ::memcpy(buffer, *src, len);
1136 MakeValid(set);
1137 *src += len;
1138 return writer();
1139}
1140
1141Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
1142 const lldb::DataBufferSP &data_sp) {
1143 // AArch64 register data must contain GPRs, either FPR or SVE registers
1144 // (which can be streaming or non-streaming) and optional MTE register.
1145 // Pointer Authentication (PAC) registers are read-only and will be skipped.
1146
1147 // We store all register values in data_sp by copying full PTrace data that
1148 // corresponds to register sets enabled by current register context. In order
1149 // to restore from register data checkpoint we will first restore GPRs, based
1150 // on size of remaining register data either SVE or FPRs should be restored
1151 // next. SVE is not enabled if we have register data size less than or equal
1152 // to size of GPR + FPR + MTE.
1153
1154 Status error;
1155 if (!data_sp) {
1157 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
1158 __FUNCTION__);
1159 return error;
1160 }
1161
1162 const uint8_t *src = data_sp->GetBytes();
1163 if (src == nullptr) {
1165 "NativeRegisterContextLinux_arm64::%s "
1166 "DataBuffer::GetBytes() returned a null "
1167 "pointer",
1168 __FUNCTION__);
1169 return error;
1170 }
1171
1172 uint64_t reg_data_min_size =
1173 GetGPRBufferSize() + GetFPRSize() + 2 * (sizeof(RegisterSetType));
1174 if (data_sp->GetByteSize() < reg_data_min_size) {
1176 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
1177 "register data bytes, expected at least %" PRIu64 ", actual %" PRIu64,
1178 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
1179 return error;
1180 }
1181
1182 const uint8_t *end = src + data_sp->GetByteSize();
1183 while (src < end) {
1184 RegisterSetType kind;
1185 std::memcpy(&kind, src, sizeof(kind));
1186 src += sizeof(RegisterSetType);
1187
1188 switch (kind) {
1189 case RegisterSetType::GPR:
1190 error = RestoreRegisters(
1191 GetGPRBuffer(), &src, GetGPRBufferSize(), kind,
1192 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR, this));
1193 break;
1194 case RegisterSetType::SVE:
1195 // Restore to the correct mode, streaming or not.
1196 std::memcpy(&m_sve_state, src, sizeof(m_sve_state));
1197 src += sizeof(m_sve_state);
1198
1199 // First write SVE header. We do not use RestoreRegisters because we do
1200 // not want src to be modified yet.
1201 ::memcpy(GetSetBuffer(RegisterSetType::SVE_HEADER), src,
1202 GetSetSize(RegisterSetType::SVE_HEADER));
1203 if (!sve::vl_valid(m_sve_header.vl)) {
1204 Invalidate(RegisterSetType::SVE_HEADER);
1206 "NativeRegisterContextLinux_arm64::%s "
1207 "Invalid SVE header in data_sp",
1208 __FUNCTION__);
1209 return error;
1210 }
1211 MakeValid(RegisterSetType::SVE_HEADER);
1212 error = WriteSVEHeader();
1213 if (error.Fail())
1214 return error;
1215
1216 // SVE header has been written configure SVE vector length if needed.
1217 // This could change ZA data too, but that will be restored again later
1218 // anyway.
1219 ConfigureRegisterContext();
1220
1221 // Write header and register data, incrementing src this time.
1222 error = RestoreRegisters(
1223 GetSetBuffer(RegisterSetType::SVE), &src,
1224 GetSetSize(RegisterSetType::SVE), kind,
1225 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE, this));
1226 break;
1227 case RegisterSetType::FPR: {
1228 Invalidate(RegisterSetType::SVE_HEADER);
1229 m_sve_state = SVEState::Unknown;
1230 ConfigureRegisterContext();
1231
1232 // If we are on an SME only system and currently in streaming mode, about
1233 // to restore non-streaming FP data.
1234 if (!GetRegisterInfo().IsSVEPresent() &&
1235 GetRegisterInfo().IsSSVEPresent() &&
1236 m_sve_state == SVEState::Streaming) {
1237 // We can only restore this data on kernel versions >= 6.19, so
1238 // attempt it and if it fails, we will skip restoring the data.
1239 //
1240 // To attempt the restore we write FPSIMD format data to NT_ARM_SVE,
1241 // with the vector length set to 0. If supported, this will switch
1242 // modes from streaming to non-streaming and update the FP registers
1243 // with the values we provided.
1244 //
1245 // This interface is only used by LLDB in this one specific
1246 // circumstance.
1247
1248 size_t data_size = sve::ptrace_fpsimd_offset + GetFPRSize();
1249 // NT_ARM_SVE data must be a multiple of 128 bits, and the FPU data size
1250 // is not, round up.
1251 data_size =
1252 (data_size + sve::vq_bytes - 1) / sve::vq_bytes * sve::vq_bytes;
1253 std::vector<uint8_t> sve_fpsimd_data(data_size);
1254
1255 sve::user_sve_header *header =
1256 reinterpret_cast<sve::user_sve_header *>(sve_fpsimd_data.data());
1257 std::memset(header, 0, sizeof(sve::user_sve_header));
1258 header->size = sve_fpsimd_data.size();
1259 // VL = 0 tells the process to exit streaming mode.
1260 header->vl = 0;
1262 std::memcpy(&sve_fpsimd_data[sve::ptrace_fpsimd_offset], src,
1263 GetFPRSize());
1264
1265 struct iovec ioVec;
1266 ioVec.iov_base = sve_fpsimd_data.data();
1267 ioVec.iov_len = sve_fpsimd_data.size();
1268
1269 // Even though the system does not have SVE, NT_ARM_SVE is used when
1270 // exiting streaming mode.
1271 error = WriteRegisterSet(&ioVec, sve_fpsimd_data.size(),
1272 llvm::ELF::NT_ARM_SVE);
1273
1274 // Consume FP register set.
1275 src += GetFPRSize();
1276
1277 if (error.Success()) {
1278 Invalidate(RegisterSetType::FPR);
1279 m_sve_state = SVEState::Unknown;
1280 ConfigureRegisterContext();
1281 }
1282 // Else we failed to restore these registers, but we will try to restore
1283 // the others.
1284 } else {
1285 error = RestoreRegisters(
1286 GetFPRBuffer(), &src, GetFPRSize(), kind,
1287 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR, this));
1288 }
1289 break;
1290 }
1291 case RegisterSetType::MTE:
1292 error = RestoreRegisters(
1293 GetSetBuffer(RegisterSetType::MTE), &src,
1294 GetSetSize(RegisterSetType::MTE), kind,
1295 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl, this));
1296 break;
1297 case RegisterSetType::TLS:
1298 error = RestoreRegisters(
1299 GetSetBuffer(RegisterSetType::TLS), &src,
1300 GetSetSize(RegisterSetType::TLS), kind,
1301 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS, this));
1302 break;
1303 case RegisterSetType::ZA:
1304 // To enable or disable ZA you write the regset with or without register
1305 // data. The kernel detects this by looking at the ioVec's length, not the
1306 // ZA header size you pass in. Therefore we must write header and register
1307 // data (if present) in one go every time. Read the header only first just
1308 // to get the size.
1309 ::memcpy(GetSetBuffer(RegisterSetType::ZA_HEADER), src,
1310 GetSetSize(RegisterSetType::ZA_HEADER));
1311 // Read the header and register data. Can't use the buffer size here, it
1312 // may be incorrect due to being filled with dummy data previously. Resize
1313 // this so WriteZA uses the correct size.
1314 m_za_ptrace_payload.resize(m_za_header.size);
1315 ::memcpy(GetSetBuffer(RegisterSetType::ZA), src,
1316 GetSetSize(RegisterSetType::ZA));
1317 MakeValid(RegisterSetType::ZA);
1318
1319 error = WriteZA();
1320 if (error.Fail())
1321 return error;
1322
1323 // Update size of ZA, which resizes the ptrace payload potentially
1324 // trashing our copy of the data we just wrote.
1325 ConfigureRegisterContext();
1326
1327 // ZA buffer now has proper size, read back the data we wrote above, from
1328 // ptrace.
1329 error = ReadZA();
1330 src += GetSetSize(RegisterSetType::ZA);
1331 break;
1332 case RegisterSetType::ZT:
1333 // Doing this would activate an inactive ZA, however we will only get here
1334 // if the state we are restoring had an active ZA. Restoring ZT0 will
1335 // always come after restoring ZA.
1336 error = RestoreRegisters(
1337 GetSetBuffer(RegisterSetType::ZT), &src,
1338 GetSetSize(RegisterSetType::ZT), kind,
1339 std::bind(&NativeRegisterContextLinux_arm64::WriteZT, this));
1340 break;
1341 case RegisterSetType::FPMR:
1342 error = RestoreRegisters(
1343 GetSetBuffer(RegisterSetType::FPMR), &src,
1344 GetSetSize(RegisterSetType::FPMR), kind,
1345 std::bind(&NativeRegisterContextLinux_arm64::WriteFPMR, this));
1346 break;
1347 case RegisterSetType::GCS: {
1348 // It is not permitted to enable GCS via ptrace. We can disable it, but
1349 // to keep things simple we will not revert any change to the
1350 // PR_SHADOW_STACK_ENABLE bit. Instead patch in the current enable bit
1351 // into the registers we are about to restore.
1352 Invalidate(RegisterSetType::GCS);
1353 error = ReadGCS();
1354 if (error.Fail())
1355 return error;
1356
1357 uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
1358 gcs_regs new_gcs_regs;
1359 std::memcpy(&new_gcs_regs, src, sizeof(new_gcs_regs));
1360 new_gcs_regs.features_enabled =
1361 (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
1362
1363 const uint8_t *new_gcs_src =
1364 reinterpret_cast<const uint8_t *>(&new_gcs_regs);
1365 error = RestoreRegisters(
1366 GetSetBuffer(RegisterSetType::GCS), &new_gcs_src,
1367 GetSetSize(RegisterSetType::GCS), kind,
1368 std::bind(&NativeRegisterContextLinux_arm64::WriteGCS, this));
1369 src += GetSetSize(RegisterSetType::GCS);
1370
1371 break;
1372 }
1373 case RegisterSetType::POE:
1374 error = RestoreRegisters(
1375 GetSetBuffer(RegisterSetType::POE), &src,
1376 GetSetSize(RegisterSetType::POE), kind,
1377 std::bind(&NativeRegisterContextLinux_arm64::WritePOE, this));
1378 break;
1379 case RegisterSetType::PAC:
1380 case RegisterSetType::SVE_HEADER:
1381 case RegisterSetType::ZA_HEADER:
1382 // These are not saved or restored.
1383 break;
1384 }
1385
1386 if (error.Fail())
1387 return error;
1388 }
1389
1390 return error;
1391}
1392
1393llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1394 if (!m_refresh_hwdebug_info) {
1395 return llvm::Error::success();
1396 }
1397
1398 ::pid_t tid = m_thread.GetID();
1399
1400 Status error = arm64::ReadHardwareDebugInfo(tid, m_max_hwp_supported,
1401 m_max_hbp_supported);
1402 if (error.Fail())
1403 return error.ToError();
1404
1405 m_refresh_hwdebug_info = false;
1406
1407 return llvm::Error::success();
1408}
1409
1410llvm::Error
1411NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1412 uint32_t max_supported =
1413 (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
1414 auto &regs = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
1415 return arm64::WriteHardwareDebugRegs(hwbType, m_thread.GetID(), max_supported,
1416 regs)
1417 .ToError();
1418}
1419
1420Status NativeRegisterContextLinux_arm64::ReadGPR() {
1421 Status error;
1422
1423 if (IsValid(RegisterSetType::GPR))
1424 return error;
1425
1426 struct iovec ioVec;
1427 ioVec.iov_base = GetGPRBuffer();
1428 ioVec.iov_len = GetGPRBufferSize();
1429
1430 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(),
1431 GetPtraceSet(RegisterSetType::GPR));
1432
1433 if (error.Success())
1434 MakeValid(RegisterSetType::GPR);
1435
1436 return error;
1437}
1438
1439Status NativeRegisterContextLinux_arm64::WriteGPR() {
1440 Status error = ReadGPR();
1441 if (error.Fail())
1442 return error;
1443
1444 struct iovec ioVec;
1445 ioVec.iov_base = GetGPRBuffer();
1446 ioVec.iov_len = GetGPRBufferSize();
1447
1448 Invalidate(RegisterSetType::GPR);
1449
1450 return WriteRegisterSet(&ioVec, GetGPRBufferSize(),
1451 GetPtraceSet(RegisterSetType::GPR));
1452}
1453
1454Status NativeRegisterContextLinux_arm64::ReadFPR() {
1455 Status error;
1456
1457 if (IsValid(RegisterSetType::FPR))
1458 return error;
1459
1460 struct iovec ioVec;
1461 ioVec.iov_base = GetFPRBuffer();
1462 ioVec.iov_len = GetFPRSize();
1463
1464 error =
1465 ReadRegisterSet(&ioVec, GetFPRSize(), GetPtraceSet(RegisterSetType::FPR));
1466 if (error.Success())
1467 MakeValid(RegisterSetType::FPR);
1468
1469 return error;
1470}
1471
1472Status NativeRegisterContextLinux_arm64::WriteFPR() {
1473 Status error = ReadFPR();
1474 if (error.Fail())
1475 return error;
1476
1477 struct iovec ioVec;
1478 ioVec.iov_base = GetFPRBuffer();
1479 ioVec.iov_len = GetFPRSize();
1480
1481 Invalidate(RegisterSetType::FPR);
1482
1483 return WriteRegisterSet(&ioVec, GetFPRSize(),
1484 GetPtraceSet(RegisterSetType::FPR));
1485}
1486
1487void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1488 m_validity = static_cast<RegisterSetType>(0);
1489
1490 // Update SVE and ZA registers in case there is change in configuration.
1491 ConfigureRegisterContext();
1492}
1493
1494Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1495 Status error;
1496
1497 if (IsValid(RegisterSetType::SVE_HEADER))
1498 return error;
1499
1500 struct iovec ioVec;
1501 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE_HEADER);
1502 ioVec.iov_len = GetSetSize(RegisterSetType::SVE_HEADER);
1503
1504 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE_HEADER),
1505 GetPtraceSet(RegisterSetType::SVE_HEADER));
1506
1507 if (error.Success())
1508 MakeValid(RegisterSetType::SVE_HEADER);
1509
1510 return error;
1511}
1512
1513Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1514 Status error;
1515
1516 if (IsValid(RegisterSetType::PAC))
1517 return error;
1518
1519 struct iovec ioVec;
1520 ioVec.iov_base = GetSetBuffer(RegisterSetType::PAC);
1521 ioVec.iov_len = GetSetSize(RegisterSetType::PAC);
1522
1523 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::PAC),
1524 GetPtraceSet(RegisterSetType::PAC));
1525
1526 if (error.Success())
1527 MakeValid(RegisterSetType::PAC);
1528
1529 return error;
1530}
1531
1532Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1533 Status error;
1534
1535 error = ReadSVEHeader();
1536 if (error.Fail())
1537 return error;
1538
1539 struct iovec ioVec;
1540 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE_HEADER);
1541 ioVec.iov_len = GetSetSize(RegisterSetType::SVE_HEADER);
1542
1543 Invalidate(RegisterSetType::SVE_HEADER);
1544
1545 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE_HEADER),
1546 GetPtraceSet(RegisterSetType::SVE_HEADER));
1547}
1548
1549Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1550 Status error;
1551 if (IsValid(RegisterSetType::SVE))
1552 return error;
1553
1554 struct iovec ioVec;
1555 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE);
1556 ioVec.iov_len = GetSetSize(RegisterSetType::SVE);
1557
1558 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE),
1559 GetPtraceSet(RegisterSetType::SVE));
1560
1561 if (error.Success())
1562 MakeValid(RegisterSetType::SVE);
1563
1564 return error;
1565}
1566
1567Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1568 Status error;
1569
1570 error = ReadAllSVE();
1571 if (error.Fail())
1572 return error;
1573
1574 struct iovec ioVec;
1575
1576 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE);
1577 ioVec.iov_len = GetSetSize(RegisterSetType::SVE);
1578
1579 Invalidate(RegisterSetType::SVE);
1580
1581 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE),
1582 GetPtraceSet(RegisterSetType::SVE));
1583}
1584
1585Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1586 // The real register is SVCR and is accessible from EL0. However we don't want
1587 // to have to JIT code into the target process so we'll just recreate it using
1588 // what we know from ptrace.
1589
1590 // Bit 0 indicates whether streaming mode is active.
1591 m_sme_pseudo_regs.ctrl_reg = m_sve_state == SVEState::Streaming;
1592
1593 // Bit 1 indicates whether the array storage is active.
1594 // It is active if we can read the header and the size field tells us that
1595 // there is register data following it.
1596 Status error = ReadZAHeader();
1597 if (error.Success() && (m_za_header.size > sizeof(m_za_header)))
1598 m_sme_pseudo_regs.ctrl_reg |= 2;
1599
1600 return error;
1601}
1602
1603Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1604 Status error;
1605
1606 if (IsValid(RegisterSetType::MTE))
1607 return error;
1608
1609 struct iovec ioVec;
1610 ioVec.iov_base = GetSetBuffer(RegisterSetType::MTE);
1611 ioVec.iov_len = GetSetSize(RegisterSetType::MTE);
1612
1613 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::MTE),
1614 GetPtraceSet(RegisterSetType::MTE));
1615
1616 if (error.Success())
1617 MakeValid(RegisterSetType::MTE);
1618
1619 return error;
1620}
1621
1622Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1623 Status error;
1624
1625 error = ReadMTEControl();
1626 if (error.Fail())
1627 return error;
1628
1629 struct iovec ioVec;
1630 ioVec.iov_base = GetSetBuffer(RegisterSetType::MTE);
1631 ioVec.iov_len = GetSetSize(RegisterSetType::MTE);
1632
1633 Invalidate(RegisterSetType::MTE);
1634
1635 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::MTE),
1636 GetPtraceSet(RegisterSetType::MTE));
1637}
1638
1639Status NativeRegisterContextLinux_arm64::ReadTLS() {
1640 Status error;
1641
1642 if (IsValid(RegisterSetType::TLS))
1643 return error;
1644
1645 struct iovec ioVec;
1646 ioVec.iov_base = GetSetBuffer(RegisterSetType::TLS);
1647 ioVec.iov_len = GetSetSize(RegisterSetType::TLS);
1648
1649 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::TLS),
1650 GetPtraceSet(RegisterSetType::TLS));
1651
1652 if (error.Success())
1653 MakeValid(RegisterSetType::TLS);
1654
1655 return error;
1656}
1657
1658Status NativeRegisterContextLinux_arm64::WriteTLS() {
1659 Status error;
1660
1661 error = ReadTLS();
1662 if (error.Fail())
1663 return error;
1664
1665 struct iovec ioVec;
1666 ioVec.iov_base = GetSetBuffer(RegisterSetType::TLS);
1667 ioVec.iov_len = GetSetSize(RegisterSetType::TLS);
1668
1669 Invalidate(RegisterSetType::TLS);
1670
1671 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::TLS),
1672 GetPtraceSet(RegisterSetType::TLS));
1673}
1674
1675Status NativeRegisterContextLinux_arm64::ReadGCS() {
1676 Status error;
1677
1678 if (IsValid(RegisterSetType::GCS))
1679 return error;
1680
1681 struct iovec ioVec;
1682 ioVec.iov_base = GetSetBuffer(RegisterSetType::GCS);
1683 ioVec.iov_len = GetSetSize(RegisterSetType::GCS);
1684
1685 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::GCS),
1686 GetPtraceSet(RegisterSetType::GCS));
1687
1688 if (error.Success())
1689 MakeValid(RegisterSetType::GCS);
1690
1691 return error;
1692}
1693
1694Status NativeRegisterContextLinux_arm64::WriteGCS() {
1695 Status error;
1696
1697 error = ReadGCS();
1698 if (error.Fail())
1699 return error;
1700
1701 struct iovec ioVec;
1702 ioVec.iov_base = GetSetBuffer(RegisterSetType::GCS);
1703 ioVec.iov_len = GetSetSize(RegisterSetType::GCS);
1704
1705 Invalidate(RegisterSetType::GCS);
1706
1707 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::GCS),
1708 GetPtraceSet(RegisterSetType::GCS));
1709}
1710
1711Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1712 Status error;
1713
1714 if (IsValid(RegisterSetType::ZA_HEADER))
1715 return error;
1716
1717 struct iovec ioVec;
1718 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA_HEADER);
1719 ioVec.iov_len = GetSetSize(RegisterSetType::ZA_HEADER);
1720
1721 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA_HEADER),
1722 GetPtraceSet(RegisterSetType::ZA));
1723
1724 if (error.Success())
1725 MakeValid(RegisterSetType::ZA_HEADER);
1726
1727 return error;
1728}
1729
1730Status NativeRegisterContextLinux_arm64::ReadZA() {
1731 Status error;
1732
1733 if (IsValid(RegisterSetType::ZA))
1734 return error;
1735
1736 struct iovec ioVec;
1737 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA);
1738 ioVec.iov_len = GetSetSize(RegisterSetType::ZA);
1739
1740 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA),
1741 GetPtraceSet(RegisterSetType::ZA));
1742
1743 if (error.Success())
1744 MakeValid(RegisterSetType::ZA);
1745
1746 return error;
1747}
1748
1749Status NativeRegisterContextLinux_arm64::WriteZA() {
1750 // Note that because the ZA ptrace payload contains the header also, this
1751 // method will write both. This is done because writing only the header
1752 // will disable ZA, even if .size in the header is correct for an enabled ZA.
1753 Status error;
1754
1755 error = ReadZA();
1756 if (error.Fail())
1757 return error;
1758
1759 struct iovec ioVec;
1760 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA);
1761 ioVec.iov_len = GetSetSize(RegisterSetType::ZA);
1762
1763 Invalidate(RegisterSetType::ZA);
1764
1765 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA),
1766 GetPtraceSet(RegisterSetType::ZA));
1767}
1768
1769Status NativeRegisterContextLinux_arm64::ReadZT() {
1770 Status error;
1771
1772 if (IsValid(RegisterSetType::ZT))
1773 return error;
1774
1775 struct iovec ioVec;
1776 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZT);
1777 ioVec.iov_len = GetSetSize(RegisterSetType::ZT);
1778
1779 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZT),
1780 GetPtraceSet(RegisterSetType::ZT));
1781 if (error.Success())
1782 MakeValid(RegisterSetType::ZT);
1783
1784 return error;
1785}
1786
1787Status NativeRegisterContextLinux_arm64::WriteZT() {
1788 Status error;
1789
1790 error = ReadZT();
1791 if (error.Fail())
1792 return error;
1793
1794 struct iovec ioVec;
1795 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZT);
1796 ioVec.iov_len = GetSetSize(RegisterSetType::ZT);
1797
1798 Invalidate(RegisterSetType::ZT);
1799
1800 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZT),
1801 GetPtraceSet(RegisterSetType::ZT));
1802}
1803
1804Status NativeRegisterContextLinux_arm64::ReadFPMR() {
1805 Status error;
1806
1807 if (IsValid(RegisterSetType::FPMR))
1808 return error;
1809
1810 struct iovec ioVec;
1811 ioVec.iov_base = GetSetBuffer(RegisterSetType::FPMR);
1812 ioVec.iov_len = GetSetSize(RegisterSetType::FPMR);
1813
1814 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::FPMR),
1815 GetPtraceSet(RegisterSetType::FPMR));
1816
1817 if (error.Success())
1818 MakeValid(RegisterSetType::FPMR);
1819
1820 return error;
1821}
1822
1823Status NativeRegisterContextLinux_arm64::WriteFPMR() {
1824 Status error;
1825
1826 error = ReadFPMR();
1827 if (error.Fail())
1828 return error;
1829
1830 struct iovec ioVec;
1831 ioVec.iov_base = GetSetBuffer(RegisterSetType::FPMR);
1832 ioVec.iov_len = GetSetSize(RegisterSetType::FPMR);
1833
1834 Invalidate(RegisterSetType::FPMR);
1835
1836 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::FPMR),
1837 GetPtraceSet(RegisterSetType::FPMR));
1838}
1839
1840Status NativeRegisterContextLinux_arm64::ReadPOE() {
1841 Status error;
1842
1843 if (IsValid(RegisterSetType::POE))
1844 return error;
1845
1846 struct iovec ioVec;
1847 ioVec.iov_base = GetSetBuffer(RegisterSetType::POE);
1848 ioVec.iov_len = GetSetSize(RegisterSetType::POE);
1849
1850 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::POE),
1851 GetPtraceSet(RegisterSetType::POE));
1852
1853 if (error.Success())
1854 MakeValid(RegisterSetType::POE);
1855
1856 return error;
1857}
1858
1859Status NativeRegisterContextLinux_arm64::WritePOE() {
1860 Status error;
1861
1862 error = ReadPOE();
1863 if (error.Fail())
1864 return error;
1865
1866 struct iovec ioVec;
1867 ioVec.iov_base = GetSetBuffer(RegisterSetType::POE);
1868 ioVec.iov_len = GetSetSize(RegisterSetType::POE);
1869
1870 Invalidate(RegisterSetType::POE);
1871
1872 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::POE),
1873 GetPtraceSet(RegisterSetType::POE));
1874}
1875
1876void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1877 // ConfigureRegisterContext gets called from InvalidateAllRegisters
1878 // on every stop and configures SVE vector length and whether we are in
1879 // streaming SVE mode.
1880 // If m_sve_state is set to SVEState::Disabled on first stop, code below will
1881 // be deemed non operational for the lifetime of current process.
1882 if (!IsValid(RegisterSetType::SVE_HEADER) &&
1883 m_sve_state != SVEState::Disabled) {
1884 // Systems may have SVE and/or SME. If they are SME only, the SVE regset
1885 // cannot be read from but the SME one can. If they have both SVE and SME,
1886 // only the active mode will return valid register data.
1887
1888 // Check for SME.
1889 Invalidate(RegisterSetType::SVE_HEADER);
1890 m_sve_state = SVEState::Streaming;
1891 Status error = ReadSVEHeader();
1892
1893 bool has_sme = error.Success();
1894 bool sme_is_active =
1895 has_sme &&
1896 ((m_sve_header.flags & sve::ptrace_regs_mask) == sve::ptrace_regs_sve);
1897
1898 // Check for SVE.
1899 Invalidate(RegisterSetType::SVE_HEADER);
1900 m_sve_state = SVEState::Full;
1901 error = ReadSVEHeader();
1902
1903 bool has_sve = error.Success();
1904 bool sve_is_active =
1905 has_sve &&
1906 ((m_sve_header.flags & sve::ptrace_regs_mask) == sve::ptrace_regs_sve);
1907 // We do not check this for streaming mode because the streaming mode regset
1908 // will never be in FP format.
1909 bool fp_is_active =
1910 has_sve && ((m_sve_header.flags & sve::ptrace_regs_mask) ==
1912
1913 if (sme_is_active)
1914 m_sve_state = SVEState::Streaming;
1915 else if (sve_is_active)
1916 m_sve_state = SVEState::Full;
1917 else if (fp_is_active)
1918 m_sve_state = SVEState::FPSIMD;
1919 else if (has_sme) {
1920 // We are in the non-streaming mode of an SME only system.
1921 m_sve_state = SVEState::StreamingFPSIMD;
1922 } else
1923 m_sve_state = SVEState::Disabled;
1924
1925 if (m_sve_state == SVEState::Full || m_sve_state == SVEState::FPSIMD ||
1926 m_sve_state == SVEState::Streaming ||
1927 m_sve_state == SVEState::StreamingFPSIMD) {
1928 Invalidate(RegisterSetType::SVE_HEADER);
1929 error = ReadSVEHeader();
1930
1931 // On every stop we configure SVE vector length by calling
1932 // ConfigureVectorLengthSVE regardless of current SVEState of this thread.
1934 if (sve::vl_valid(m_sve_header.vl))
1935 vq = sve::vq_from_vl(m_sve_header.vl);
1936
1937 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1938 m_sve_ptrace_payload.resize(sve::PTraceSize(vq, sve::ptrace_regs_sve));
1939 }
1940 }
1941
1942 if (!IsValid(RegisterSetType::ZA_HEADER)) {
1943 Status error = ReadZAHeader();
1944 if (error.Success()) {
1946 if (sve::vl_valid(m_za_header.vl))
1947 vq = sve::vq_from_vl(m_za_header.vl);
1948
1949 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1950 m_za_ptrace_payload.resize(m_za_header.size);
1951 Invalidate(RegisterSetType::ZA);
1952 }
1953 }
1954}
1955
1956uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1957 const RegisterInfo *reg_info, bool streaming_fpsimd) const {
1958 uint32_t offset = reg_info->byte_offset - GetGPRSize();
1959 if (!streaming_fpsimd)
1960 return offset;
1961
1962 // If we're outside of streaming mode on a streaming only target, the offsets
1963 // are relative to an SVE context. We need the offset into the actual FPR
1964 // context:
1965 // struct user_fpsimd_state {
1966 // __uint128_t vregs[32];
1967 // __u32 fpsr;
1968 // __u32 fpcr;
1969 // __u32 __reserved[2];
1970 // };
1971 const size_t fpsr_offset = 16 * 32;
1972 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
1973 if (reg == GetRegisterInfo().GetRegNumFPSR())
1974 offset = fpsr_offset;
1975 else if (reg == GetRegisterInfo().GetRegNumFPCR())
1976 offset = fpsr_offset + 4;
1977 else
1978 offset = 16 * (reg - GetRegisterInfo().GetRegNumFPV0());
1979
1980 return offset;
1981}
1982
1983uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
1984 const RegisterInfo *reg_info) const {
1985 // Start of Z0 data is after GPRs plus 8 bytes of vg register
1986 uint32_t sve_reg_offset = LLDB_INVALID_INDEX32;
1987 if (m_sve_state == SVEState::FPSIMD) {
1988 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
1989 sve_reg_offset = sve::ptrace_fpsimd_offset +
1990 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
1991 // Between non-streaming and streaming mode, the layout is identical.
1992 } else if (m_sve_state == SVEState::Full ||
1993 m_sve_state == SVEState::Streaming) {
1994 uint32_t sve_z0_offset = GetGPRSize() + 16;
1995 sve_reg_offset =
1996 sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset;
1997 }
1998 return sve_reg_offset;
1999}
2000
2001Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
2002 // This register is the streaming vector length, so we will get it from
2003 // NT_ARM_ZA regardless of the current streaming mode.
2004 Status error = ReadZAHeader();
2005 if (error.Success())
2006 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
2007
2008 return error;
2009}
2010
2011std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
2012 ExpeditedRegs expType) const {
2013 std::vector<uint32_t> expedited_reg_nums =
2015 // SVE, non-streaming vector length.
2016 if (m_sve_state == SVEState::FPSIMD || m_sve_state == SVEState::Full)
2017 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
2018 // SME, streaming vector length. This is used by the ZA register which is
2019 // present even when streaming mode is not enabled.
2020 if (GetRegisterInfo().IsSSVEPresent())
2021 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
2022
2023 return expedited_reg_nums;
2024}
2025
2026llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
2027NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
2029 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
2031 }
2032
2033 return llvm::createStringError(llvm::inconvertibleErrorCode(),
2034 "Unknown AArch64 memory tag type %d", type);
2035}
2036
2037lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
2038 lldb::addr_t hit_addr) {
2039 // Linux configures user-space virtual addresses with top byte ignored.
2040 // We set default value of mask such that top byte is masked out.
2041 lldb::addr_t mask = ~((1ULL << 56) - 1);
2042
2043 // Try to read pointer authentication data_mask register and calculate a
2044 // consolidated data address mask after ignoring the top byte.
2045 if (ReadPAuthMask().Success())
2046 mask |= m_pac_mask.data_mask;
2047
2048 return hit_addr & ~mask;
2049 ;
2050}
2051
2052#endif // defined (__arm64__) || defined (__aarch64__)
static llvm::raw_ostream & error(Stream &strm)
#define HWCAP2_MTE
#define PTRACE_PEEKMTETAGS
Definition Ptrace.h:61
#define PTRACE_POKEMTETAGS
Definition Ptrace.h:64
#define PTRACE_GETREGSET
Definition Ptrace.h:36
#define HWCAP2_FPMR
#define HWCAP_GCS
#define HWCAP2_POE
@ AUXV_AT_HWCAP2
Extension of AT_HWCAP.
Definition AuxVector.h:59
@ AUXV_AT_HWCAP3
Extension of AT_HWCAP.
Definition AuxVector.h:60
@ AUXV_AT_HWCAP
Machine dependent hints about processor capabilities.
Definition AuxVector.h:49
size_t GetRegisterSetCount() const override
This class manages the storage and detection of register type information.
bool HasDetected() const
Returns true if field detection has been run at least once.
void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs)
Add the type information of any registers named in this class, to the relevant RegisterInfo instances...
void DetectTypes(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
For the registers listed in this class, detect which fields are present and build types for those.
A subclass of DataBuffer that stores a data buffer on the heap.
std::optional< uint64_t > GetAuxValue(enum AuxVector::EntryType type)
virtual std::vector< uint32_t > GetExpeditedRegisters(ExpeditedRegs expType) const
uint32_t SetFromMemoryData(const RegisterInfo &reg_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
const void * GetBytes() const
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
Manages communication with the inferior (debugee) process.
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, void *data=nullptr, size_t data_size=0, long *result=nullptr)
}
static std::unique_ptr< NativeRegisterContextLinux > CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch, NativeThreadLinux &native_thread)
static llvm::Expected< ArchSpec > DetermineArchitecture(lldb::tid_t tid)
#define LLDB_INVALID_INDEX32
#define LLDB_INVALID_REGNUM
Status WriteHardwareDebugRegs(int hwbType, ::pid_t tid, uint32_t max_supported, const std::array< NativeRegisterContextDBReg::DREG, 16 > &regs)
Status ReadHardwareDebugInfo(::pid_t tid, uint32_t &max_hwp_supported, uint32_t &max_hbp_supported)
uint16_t vq_from_vl(uint16_t vl)
uint32_t PTraceFPSROffset(uint16_t vq)
uint32_t PTraceFPCROffset(uint16_t vq)
uint16_t vl_valid(uint16_t vl)
uint32_t PTraceSize(uint16_t vq, uint16_t flags)
A class that represents a running process on the host machine.
uint64_t pid_t
Definition lldb-types.h:84
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
uint64_t tid_t
Definition lldb-types.h:85
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
uint32_t * value_regs
List of registers (terminated with LLDB_INVALID_REGNUM).
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.
Registers are grouped into register sets.
size_t num_registers
The number of registers in REGISTERS array below.