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 RegisterInfo_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<RegisterInfo_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<RegisterInfo_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<RegisterInfo_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
static size_t GetGPRSizeStatic()
An architecture specification class.
Definition ArchSpec.h:32
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:886
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.
A class to manage flags.
Definition Flags.h:22
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
Definition Flags.h:73
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
An error handling class.
Definition Status.h:118
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.