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