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