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