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