9#if defined(__arm64__) || defined(__aarch64__)
38#define NT_ARM_SVE 0x405
47#define NT_ARM_ZA 0x40c
55#ifndef NT_ARM_PAC_MASK
56#define NT_ARM_PAC_MASK 0x406
59#ifndef NT_ARM_TAGGED_ADDR_CTRL
60#define NT_ARM_TAGGED_ADDR_CTRL 0x409
63#define HWCAP_PACA (1 << 30)
65#define HWCAP2_MTE (1 << 18)
75static std::mutex g_register_flags_detector_mutex;
78std::unique_ptr<NativeRegisterContextLinux>
79NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
82 case llvm::Triple::arm:
83 return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
85 case llvm::Triple::aarch64: {
90 ioVec.iov_base = &sve_header;
91 ioVec.iov_len =
sizeof(sve_header);
92 unsigned int regset = NT_ARM_SVE;
96 native_thread.
GetID(), ®set,
97 &ioVec,
sizeof(sve_header))
103 ioVec.iov_len =
sizeof(sve_header);
104 regset = NT_ARM_SSVE;
106 native_thread.
GetID(), ®set,
107 &ioVec,
sizeof(sve_header))
113 ioVec.iov_base = &za_header;
114 ioVec.iov_len =
sizeof(za_header);
117 native_thread.
GetID(), ®set,
118 &ioVec,
sizeof(za_header))
123 std::array<uint8_t, 64> zt_reg;
124 ioVec.iov_base = zt_reg.data();
125 ioVec.iov_len = zt_reg.size();
128 native_thread.
GetID(), ®set,
129 &ioVec, zt_reg.size())
135 std::optional<uint64_t> auxv_at_hwcap =
137 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
140 std::optional<uint64_t> auxv_at_hwcap2 =
142 if (auxv_at_hwcap2 && (*auxv_at_hwcap2 &
HWCAP2_MTE))
147 std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
149 g_register_flags_detector.
DetectFields(auxv_at_hwcap.value_or(0),
150 auxv_at_hwcap2.value_or(0));
152 auto register_info_up =
153 std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
154 return std::make_unique<NativeRegisterContextLinux_arm64>(
155 target_arch, native_thread, std::move(register_info_up));
158 llvm_unreachable(
"have no register context for architecture");
162llvm::Expected<ArchSpec>
163NativeRegisterContextLinux::DetermineArchitecture(
lldb::tid_t tid) {
164 return DetermineArchitectureViaGPR(
168NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
170 std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
172 register_info_up.release()),
175 GetRegisterInfoInterface().GetRegisterInfo(),
176 GetRegisterInfoInterface().GetRegisterCount());
178 ::memset(&m_fpr, 0,
sizeof(m_fpr));
179 ::memset(&m_gpr_arm64, 0,
sizeof(m_gpr_arm64));
180 ::memset(&m_hwp_regs, 0,
sizeof(m_hwp_regs));
181 ::memset(&m_hbp_regs, 0,
sizeof(m_hbp_regs));
182 ::memset(&m_sve_header, 0,
sizeof(m_sve_header));
183 ::memset(&m_pac_mask, 0,
sizeof(m_pac_mask));
184 ::memset(&m_tls_regs, 0,
sizeof(m_tls_regs));
185 ::memset(&m_sme_pseudo_regs, 0,
sizeof(m_sme_pseudo_regs));
186 std::fill(m_zt_reg.begin(), m_zt_reg.end(), 0);
191 m_max_hwp_supported = 16;
192 m_max_hbp_supported = 16;
194 m_refresh_hwdebug_info =
true;
196 m_gpr_is_valid =
false;
197 m_fpu_is_valid =
false;
198 m_sve_buffer_is_valid =
false;
199 m_sve_header_is_valid =
false;
200 m_pac_mask_is_valid =
false;
201 m_mte_ctrl_is_valid =
false;
202 m_tls_is_valid =
false;
203 m_zt_buffer_is_valid =
false;
206 m_tls_size = GetRegisterInfo().IsSSVEPresent() ?
sizeof(m_tls_regs)
207 :
sizeof(m_tls_regs.tpidr_reg);
209 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
216NativeRegisterContextLinux_arm64::GetRegisterInfo()
const {
220uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount()
const {
225NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index)
const {
226 return GetRegisterInfo().GetRegisterSet(set_index);
229uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount()
const {
231 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
237NativeRegisterContextLinux_arm64::ReadRegister(
const RegisterInfo *reg_info,
242 error.SetErrorString(
"reg_info NULL");
249 return Status(
"no lldb regnum for %s", reg_info && reg_info->
name
251 :
"<unknown register>");
256 std::vector<uint8_t> sve_reg_non_live;
264 assert(offset < GetGPRSize());
265 src = (uint8_t *)GetGPRBuffer() + offset;
267 }
else if (IsFPR(reg)) {
274 offset = CalculateFprOffset(reg_info);
275 assert(offset < GetFPRSize());
276 src = (uint8_t *)GetFPRBuffer() + offset;
281 error = ReadAllSVE();
290 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
293 offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
295 offset = sve::ptrace_fpsimd_offset + (32 * 16);
296 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
299 offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
301 offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
307 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
310 assert(offset < GetSVEBufferSize());
311 src = (uint8_t *)GetSVEBuffer() + offset;
313 }
else if (IsTLS(reg)) {
318 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
319 assert(offset < GetTLSBufferSize());
320 src = (uint8_t *)GetTLSBuffer() + offset;
321 }
else if (IsSVE(reg)) {
323 return Status(
"SVE disabled or not supported");
325 if (GetRegisterInfo().IsSVERegVG(reg)) {
326 sve_vg = GetSVERegVG();
327 src = (uint8_t *)&sve_vg;
330 error = ReadAllSVE();
338 sve_reg_non_live.resize(reg_info->
byte_size, 0);
339 src = sve_reg_non_live.data();
341 if (GetRegisterInfo().IsSVEZReg(reg)) {
342 offset = CalculateSVEOffset(reg_info);
343 assert(offset < GetSVEBufferSize());
344 ::memcpy(sve_reg_non_live.data(), (uint8_t *)GetSVEBuffer() + offset,
348 offset = CalculateSVEOffset(reg_info);
349 assert(offset < GetSVEBufferSize());
350 src = (uint8_t *)GetSVEBuffer() + offset;
353 }
else if (IsPAuth(reg)) {
354 error = ReadPAuthMask();
358 offset = reg_info->
byte_offset - GetRegisterInfo().GetPAuthOffset();
359 assert(offset < GetPACMaskSize());
360 src = (uint8_t *)GetPACMask() + offset;
361 }
else if (IsMTE(reg)) {
362 error = ReadMTEControl();
366 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
367 assert(offset < GetMTEControlSize());
368 src = (uint8_t *)GetMTEControl() + offset;
369 }
else if (IsSME(reg)) {
370 if (GetRegisterInfo().IsSMERegZA(reg)) {
371 error = ReadZAHeader();
377 if (m_za_header.size ==
sizeof(m_za_header)) {
381 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
383 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
394 src = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
395 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
403 src = (uint8_t *)GetZTBuffer();
405 error = ReadSMESVG();
412 offset = reg_info->
byte_offset - GetRegisterInfo().GetSMEOffset();
413 assert(offset < GetSMEPseudoBufferSize());
414 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
417 return Status(
"failed - register wasn't recognized to be a GPR or an FPR, "
418 "write strategy unknown");
421 eByteOrderLittle,
error);
426Status NativeRegisterContextLinux_arm64::WriteRegister(
431 return Status(
"reg_info NULL");
436 return Status(
"no lldb regnum for %s", reg_info && reg_info->
name
438 :
"<unknown register>");
442 std::vector<uint8_t> sve_reg_non_live;
450 dst = (uint8_t *)GetGPRBuffer() + reg_info->
byte_offset;
454 }
else if (IsFPR(reg)) {
461 offset = CalculateFprOffset(reg_info);
462 assert(offset < GetFPRSize());
463 dst = (uint8_t *)GetFPRBuffer() + offset;
469 error = ReadAllSVE();
478 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
481 offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_header.vl));
483 offset = sve::ptrace_fpsimd_offset + (32 * 16);
484 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
487 offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_header.vl));
489 offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4;
495 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
498 assert(offset < GetSVEBufferSize());
499 dst = (uint8_t *)GetSVEBuffer() + offset;
501 return WriteAllSVE();
503 }
else if (IsSVE(reg)) {
505 return Status(
"SVE disabled or not supported");
508 error = ReadAllSVE();
512 if (GetRegisterInfo().IsSVERegVG(reg)) {
515 if (sve::vl_valid(vg_value * 8)) {
516 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
519 SetSVERegVG(vg_value);
521 error = WriteSVEHeader();
522 if (
error.Success()) {
525 m_za_header_is_valid =
false;
526 ConfigureRegisterContext();
529 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
533 return Status(
"SVE vector length update failed.");
540 bool set_sve_state_full =
false;
541 const uint8_t *reg_bytes = (
const uint8_t *)reg_value.
GetBytes();
542 if (GetRegisterInfo().IsSVEZReg(reg)) {
543 for (uint32_t i = 16; i < reg_info->
byte_size; i++) {
545 set_sve_state_full =
true;
549 }
else if (GetRegisterInfo().IsSVEPReg(reg) ||
550 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
551 for (uint32_t i = 0; i < reg_info->
byte_size; i++) {
553 set_sve_state_full =
true;
559 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
562 offset = CalculateSVEOffset(reg_info);
563 assert(offset < GetSVEBufferSize());
564 dst = (uint8_t *)GetSVEBuffer() + offset;
565 ::memcpy(dst, reg_value.
GetBytes(), 16);
567 return WriteAllSVE();
569 return Status(
"SVE state change operation not supported");
571 offset = CalculateSVEOffset(reg_info);
572 assert(offset < GetSVEBufferSize());
573 dst = (uint8_t *)GetSVEBuffer() + offset;
575 return WriteAllSVE();
578 }
else if (IsMTE(reg)) {
579 error = ReadMTEControl();
583 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
584 assert(offset < GetMTEControlSize());
585 dst = (uint8_t *)GetMTEControl() + offset;
588 return WriteMTEControl();
589 }
else if (IsTLS(reg)) {
594 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
595 assert(offset < GetTLSBufferSize());
596 dst = (uint8_t *)GetTLSBuffer() + offset;
600 }
else if (IsSME(reg)) {
601 if (GetRegisterInfo().IsSMERegZA(reg)) {
608 dst = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
615 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
620 dst = (uint8_t *)GetZTBuffer();
625 return Status(
"Writing to SVG or SVCR is not supported.");
628 return Status(
"Failed to write register value");
631enum RegisterSetType : uint32_t {
642static uint8_t *AddRegisterSetType(uint8_t *dst,
643 RegisterSetType register_set_type) {
644 *(
reinterpret_cast<uint32_t *
>(dst)) = register_set_type;
645 return dst +
sizeof(uint32_t);
648static uint8_t *AddSavedRegistersData(uint8_t *dst,
void *src,
size_t size) {
649 ::memcpy(dst, src, size);
653static uint8_t *AddSavedRegisters(uint8_t *dst,
654 enum RegisterSetType register_set_type,
655 void *src,
size_t size) {
656 dst = AddRegisterSetType(dst, register_set_type);
657 return AddSavedRegistersData(dst, src, size);
661NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
663 cached_size =
sizeof(RegisterSetType) + GetGPRBufferSize();
668 if (GetRegisterInfo().IsZAPresent()) {
669 error = ReadZAHeader();
676 cached_size +=
sizeof(RegisterSetType) + m_za_header.size;
679 m_za_buffer_is_valid =
false;
688 GetRegisterInfo().IsZTPresent() &&
690 m_za_header.size >
sizeof(m_za_header)) {
691 cached_size +=
sizeof(RegisterSetType) + GetZTBufferSize();
701 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) {
704 sizeof(RegisterSetType) +
sizeof(m_sve_state) + GetSVEBufferSize();
705 error = ReadAllSVE();
707 cached_size +=
sizeof(RegisterSetType) + GetFPRSize();
713 if (GetRegisterInfo().IsMTEPresent()) {
714 cached_size +=
sizeof(RegisterSetType) + GetMTEControlSize();
715 error = ReadMTEControl();
721 cached_size +=
sizeof(RegisterSetType) + GetTLSBufferSize();
727Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
739 uint32_t reg_data_byte_size = 0;
740 Status error = CacheAllRegisters(reg_data_byte_size);
745 uint8_t *dst = data_sp->GetBytes();
747 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
784 assert(m_za_header.size <= GetZABufferSize());
785 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
789 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) {
790 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
791 *(
reinterpret_cast<SVEState *
>(dst)) = m_sve_state;
792 dst +=
sizeof(m_sve_state);
793 dst = AddSavedRegistersData(dst, GetSVEBuffer(), GetSVEBufferSize());
795 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
800 assert(m_za_header.size <= GetZABufferSize());
801 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
812 GetRegisterInfo().IsZTPresent() &&
814 m_za_header.size >
sizeof(m_za_header))
815 dst = AddSavedRegisters(dst, RegisterSetType::SME2, GetZTBuffer(),
818 if (GetRegisterInfo().IsMTEPresent()) {
819 dst = AddSavedRegisters(dst, RegisterSetType::MTE, GetMTEControl(),
820 GetMTEControlSize());
823 dst = AddSavedRegisters(dst, RegisterSetType::TLS, GetTLSBuffer(),
829static Status RestoreRegisters(
void *buffer,
const uint8_t **src,
size_t len,
830 bool &is_valid, std::function<
Status()> writer) {
831 ::memcpy(buffer, *src, len);
837Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
852 error.SetErrorStringWithFormat(
853 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
858 const uint8_t *src = data_sp->GetBytes();
859 if (src ==
nullptr) {
860 error.SetErrorStringWithFormat(
"NativeRegisterContextLinux_arm64::%s "
861 "DataBuffer::GetBytes() returned a null "
867 uint64_t reg_data_min_size =
868 GetGPRBufferSize() + GetFPRSize() + 2 * (
sizeof(RegisterSetType));
869 if (data_sp->GetByteSize() < reg_data_min_size) {
870 error.SetErrorStringWithFormat(
871 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
872 "register data bytes, expected at least %" PRIu64
", actual %" PRIu64,
873 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
877 const uint8_t *end = src + data_sp->GetByteSize();
879 const RegisterSetType kind =
880 *
reinterpret_cast<const RegisterSetType *
>(src);
881 src +=
sizeof(RegisterSetType);
884 case RegisterSetType::GPR:
885 error = RestoreRegisters(
886 GetGPRBuffer(), &src, GetGPRBufferSize(), m_gpr_is_valid,
887 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR,
this));
889 case RegisterSetType::SVE:
891 m_sve_state =
static_cast<SVEState>(*src);
892 src +=
sizeof(m_sve_state);
896 ::memcpy(GetSVEHeader(), src, GetSVEHeaderSize());
897 if (!sve::vl_valid(m_sve_header.vl)) {
898 m_sve_header_is_valid =
false;
899 error.SetErrorStringWithFormat(
"NativeRegisterContextLinux_arm64::%s "
900 "Invalid SVE header in data_sp",
904 m_sve_header_is_valid =
true;
905 error = WriteSVEHeader();
912 ConfigureRegisterContext();
915 error = RestoreRegisters(
916 GetSVEBuffer(), &src, GetSVEBufferSize(), m_sve_buffer_is_valid,
917 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE,
this));
919 case RegisterSetType::FPR:
920 error = RestoreRegisters(
921 GetFPRBuffer(), &src, GetFPRSize(), m_fpu_is_valid,
922 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR,
this));
924 case RegisterSetType::MTE:
925 error = RestoreRegisters(
926 GetMTEControl(), &src, GetMTEControlSize(), m_mte_ctrl_is_valid,
927 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl,
this));
929 case RegisterSetType::TLS:
930 error = RestoreRegisters(
931 GetTLSBuffer(), &src, GetTLSBufferSize(), m_tls_is_valid,
932 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS,
this));
934 case RegisterSetType::SME:
940 ::memcpy(GetZAHeader(), src, GetZAHeaderSize());
944 m_za_ptrace_payload.resize(m_za_header.size);
945 ::memcpy(GetZABuffer(), src, GetZABufferSize());
946 m_za_buffer_is_valid =
true;
954 ConfigureRegisterContext();
959 src += GetZABufferSize();
961 case RegisterSetType::SME2:
965 error = RestoreRegisters(
966 GetZTBuffer(), &src, GetZTBufferSize(), m_zt_buffer_is_valid,
967 std::bind(&NativeRegisterContextLinux_arm64::WriteZT,
this));
978bool NativeRegisterContextLinux_arm64::IsGPR(
unsigned reg)
const {
979 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
985bool NativeRegisterContextLinux_arm64::IsFPR(
unsigned reg)
const {
986 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
992bool NativeRegisterContextLinux_arm64::IsSVE(
unsigned reg)
const {
993 return GetRegisterInfo().IsSVEReg(reg);
996bool NativeRegisterContextLinux_arm64::IsSME(
unsigned reg)
const {
997 return GetRegisterInfo().IsSMEReg(reg);
1000bool NativeRegisterContextLinux_arm64::IsPAuth(
unsigned reg)
const {
1001 return GetRegisterInfo().IsPAuthReg(reg);
1004bool NativeRegisterContextLinux_arm64::IsMTE(
unsigned reg)
const {
1005 return GetRegisterInfo().IsMTEReg(reg);
1008bool NativeRegisterContextLinux_arm64::IsTLS(
unsigned reg)
const {
1009 return GetRegisterInfo().IsTLSReg(reg);
1012llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1013 if (!m_refresh_hwdebug_info) {
1014 return llvm::Error::success();
1017 ::pid_t tid = m_thread.GetID();
1019 int regset = NT_ARM_HW_WATCH;
1021 struct user_hwdebug_state dreg_state;
1024 ioVec.iov_base = &dreg_state;
1025 ioVec.iov_len =
sizeof(dreg_state);
1027 &ioVec, ioVec.iov_len);
1030 return error.ToError();
1032 m_max_hwp_supported = dreg_state.dbg_info & 0xff;
1034 regset = NT_ARM_HW_BREAK;
1036 &ioVec, ioVec.iov_len);
1039 return error.ToError();
1041 m_max_hbp_supported = dreg_state.dbg_info & 0xff;
1042 m_refresh_hwdebug_info =
false;
1044 return llvm::Error::success();
1048NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1050 struct user_hwdebug_state dreg_state;
1053 memset(&dreg_state, 0,
sizeof(dreg_state));
1054 ioVec.iov_base = &dreg_state;
1057 case eDREGTypeWATCH:
1058 regset = NT_ARM_HW_WATCH;
1059 ioVec.iov_len =
sizeof(dreg_state.dbg_info) +
sizeof(dreg_state.pad) +
1060 (
sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported);
1062 for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
1063 dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
1064 dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
1067 case eDREGTypeBREAK:
1068 regset = NT_ARM_HW_BREAK;
1069 ioVec.iov_len =
sizeof(dreg_state.dbg_info) +
sizeof(dreg_state.pad) +
1070 (
sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported);
1072 for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
1073 dreg_state.dbg_regs[i].addr = m_hbp_regs[i].address;
1074 dreg_state.dbg_regs[i].ctrl = m_hbp_regs[i].control;
1079 return NativeProcessLinux::PtraceWrapper(
PTRACE_SETREGSET, m_thread.GetID(),
1080 ®set, &ioVec, ioVec.iov_len)
1084Status NativeRegisterContextLinux_arm64::ReadGPR() {
1091 ioVec.iov_base = GetGPRBuffer();
1092 ioVec.iov_len = GetGPRBufferSize();
1094 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1096 if (
error.Success())
1097 m_gpr_is_valid =
true;
1102Status NativeRegisterContextLinux_arm64::WriteGPR() {
1108 ioVec.iov_base = GetGPRBuffer();
1109 ioVec.iov_len = GetGPRBufferSize();
1111 m_gpr_is_valid =
false;
1113 return WriteRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1116Status NativeRegisterContextLinux_arm64::ReadFPR() {
1123 ioVec.iov_base = GetFPRBuffer();
1124 ioVec.iov_len = GetFPRSize();
1126 error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1128 if (
error.Success())
1129 m_fpu_is_valid =
true;
1134Status NativeRegisterContextLinux_arm64::WriteFPR() {
1140 ioVec.iov_base = GetFPRBuffer();
1141 ioVec.iov_len = GetFPRSize();
1143 m_fpu_is_valid =
false;
1145 return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1148void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1149 m_gpr_is_valid =
false;
1150 m_fpu_is_valid =
false;
1151 m_sve_buffer_is_valid =
false;
1152 m_sve_header_is_valid =
false;
1153 m_za_buffer_is_valid =
false;
1154 m_za_header_is_valid =
false;
1155 m_pac_mask_is_valid =
false;
1156 m_mte_ctrl_is_valid =
false;
1157 m_tls_is_valid =
false;
1158 m_zt_buffer_is_valid =
false;
1161 ConfigureRegisterContext();
1164unsigned NativeRegisterContextLinux_arm64::GetSVERegSet() {
1168Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1171 if (m_sve_header_is_valid)
1175 ioVec.iov_base = GetSVEHeader();
1176 ioVec.iov_len = GetSVEHeaderSize();
1178 error = ReadRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1180 if (
error.Success())
1181 m_sve_header_is_valid =
true;
1186Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1189 if (m_pac_mask_is_valid)
1193 ioVec.iov_base = GetPACMask();
1194 ioVec.iov_len = GetPACMaskSize();
1196 error = ReadRegisterSet(&ioVec, GetPACMaskSize(), NT_ARM_PAC_MASK);
1198 if (
error.Success())
1199 m_pac_mask_is_valid =
true;
1204Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1207 error = ReadSVEHeader();
1212 ioVec.iov_base = GetSVEHeader();
1213 ioVec.iov_len = GetSVEHeaderSize();
1215 m_sve_buffer_is_valid =
false;
1216 m_sve_header_is_valid =
false;
1217 m_fpu_is_valid =
false;
1219 return WriteRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1222Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1224 if (m_sve_buffer_is_valid)
1228 ioVec.iov_base = GetSVEBuffer();
1229 ioVec.iov_len = GetSVEBufferSize();
1231 error = ReadRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1233 if (
error.Success())
1234 m_sve_buffer_is_valid =
true;
1239Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1242 error = ReadAllSVE();
1248 ioVec.iov_base = GetSVEBuffer();
1249 ioVec.iov_len = GetSVEBufferSize();
1251 m_sve_buffer_is_valid =
false;
1252 m_sve_header_is_valid =
false;
1253 m_fpu_is_valid =
false;
1255 return WriteRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1258Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1270 if (
error.Success() && (m_za_header.size >
sizeof(m_za_header)))
1271 m_sme_pseudo_regs.ctrl_reg |= 2;
1276Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1279 if (m_mte_ctrl_is_valid)
1283 ioVec.iov_base = GetMTEControl();
1284 ioVec.iov_len = GetMTEControlSize();
1286 error = ReadRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1288 if (
error.Success())
1289 m_mte_ctrl_is_valid =
true;
1294Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1297 error = ReadMTEControl();
1302 ioVec.iov_base = GetMTEControl();
1303 ioVec.iov_len = GetMTEControlSize();
1305 m_mte_ctrl_is_valid =
false;
1307 return WriteRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1310Status NativeRegisterContextLinux_arm64::ReadTLS() {
1317 ioVec.iov_base = GetTLSBuffer();
1318 ioVec.iov_len = GetTLSBufferSize();
1320 error = ReadRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1322 if (
error.Success())
1323 m_tls_is_valid =
true;
1328Status NativeRegisterContextLinux_arm64::WriteTLS() {
1336 ioVec.iov_base = GetTLSBuffer();
1337 ioVec.iov_len = GetTLSBufferSize();
1339 m_tls_is_valid =
false;
1341 return WriteRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1344Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1347 if (m_za_header_is_valid)
1351 ioVec.iov_base = GetZAHeader();
1352 ioVec.iov_len = GetZAHeaderSize();
1354 error = ReadRegisterSet(&ioVec, GetZAHeaderSize(), NT_ARM_ZA);
1356 if (
error.Success())
1357 m_za_header_is_valid =
true;
1362Status NativeRegisterContextLinux_arm64::ReadZA() {
1365 if (m_za_buffer_is_valid)
1369 ioVec.iov_base = GetZABuffer();
1370 ioVec.iov_len = GetZABufferSize();
1372 error = ReadRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1374 if (
error.Success())
1375 m_za_buffer_is_valid =
true;
1380Status NativeRegisterContextLinux_arm64::WriteZA() {
1391 ioVec.iov_base = GetZABuffer();
1392 ioVec.iov_len = GetZABufferSize();
1394 m_za_buffer_is_valid =
false;
1395 m_za_header_is_valid =
false;
1397 m_zt_buffer_is_valid =
false;
1399 return WriteRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1402Status NativeRegisterContextLinux_arm64::ReadZT() {
1405 if (m_zt_buffer_is_valid)
1409 ioVec.iov_base = GetZTBuffer();
1410 ioVec.iov_len = GetZTBufferSize();
1412 error = ReadRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1413 m_zt_buffer_is_valid =
error.Success();
1418Status NativeRegisterContextLinux_arm64::WriteZT() {
1426 ioVec.iov_base = GetZTBuffer();
1427 ioVec.iov_len = GetZTBufferSize();
1429 m_zt_buffer_is_valid =
false;
1432 m_za_buffer_is_valid =
false;
1433 m_za_header_is_valid =
false;
1435 return WriteRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1438void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1450 m_sve_header_is_valid =
false;
1451 m_sve_buffer_is_valid =
false;
1456 if (!(
error.Success() && ((m_sve_header.flags & sve::ptrace_regs_mask) ==
1457 sve::ptrace_regs_sve))) {
1459 m_sve_header_is_valid =
false;
1460 m_sve_buffer_is_valid =
false;
1462 error = ReadSVEHeader();
1463 if (
error.Success()) {
1466 if ((m_sve_header.flags & sve::ptrace_regs_mask) ==
1467 sve::ptrace_regs_fpsimd)
1480 if (sve::vl_valid(m_sve_header.vl))
1481 vq = sve::vq_from_vl(m_sve_header.vl);
1483 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1484 m_sve_ptrace_payload.resize(sve::PTraceSize(vq, sve::ptrace_regs_sve));
1488 if (!m_za_header_is_valid) {
1490 if (
error.Success()) {
1492 if (sve::vl_valid(m_za_header.vl))
1493 vq = sve::vq_from_vl(m_za_header.vl);
1495 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1496 m_za_ptrace_payload.resize(m_za_header.size);
1497 m_za_buffer_is_valid =
false;
1502uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1507uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
1513 sve_reg_offset = sve::ptrace_fpsimd_offset +
1514 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
1518 uint32_t sve_z0_offset = GetGPRSize() + 16;
1520 sve::SigRegsOffset() + reg_info->
byte_offset - sve_z0_offset;
1522 return sve_reg_offset;
1525Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
1529 if (
error.Success())
1530 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
1535std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
1537 std::vector<uint32_t> expedited_reg_nums =
1538 NativeRegisterContext::GetExpeditedRegisters(expType);
1541 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
1544 if (GetRegisterInfo().IsSSVEPresent())
1545 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
1547 return expedited_reg_nums;
1550llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
1551NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
1552 if (type == MemoryTagManagerAArch64MTE::eMTE_allocation) {
1553 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
1557 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1558 "Unknown AArch64 memory tag type %d", type);
1561lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
1569 if (ReadPAuthMask().Success())
1570 mask |= m_pac_mask.data_mask;
1572 return hit_addr & ~mask;
static llvm::raw_ostream & error(Stream &strm)
#define PTRACE_PEEKMTETAGS
#define PTRACE_POKEMTETAGS
@ AUXV_AT_HWCAP2
Extension of AT_HWCAP.
@ AUXV_AT_HWCAP
Machine dependent hints about processor capabilities.
static size_t GetGPRSizeStatic()
@ eVectorQuadwordAArch64SVE
size_t GetRegisterSetCount() const override
An architecture specification class.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
This class manages the storage and detection of register field information.
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...
void DetectFields(uint64_t hwcap, uint64_t hwcap2)
For the registers listed in this class, detect which fields are present.
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.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
std::optional< uint64_t > GetAuxValue(enum AuxVector::EntryType type)
lldb::tid_t GetID() const
uint32_t SetFromMemoryData(const RegisterInfo ®_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
Manages communication with the inferior (debugee) process.
NativeProcessLinux & GetProcess()
#define LLDB_INVALID_INDEX32
#define LLDB_INVALID_REGNUM
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ 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.