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