9#if defined(__arm64__) || defined(__aarch64__)
39#define NT_ARM_SVE 0x405
48#define NT_ARM_ZA 0x40c
56#ifndef NT_ARM_PAC_MASK
57#define NT_ARM_PAC_MASK 0x406
60#ifndef NT_ARM_TAGGED_ADDR_CTRL
61#define NT_ARM_TAGGED_ADDR_CTRL 0x409
65#define NT_ARM_FPMR 0x40e
69#define NT_ARM_POE 0x40f
73#define NT_ARM_GCS 0x410
77#define HWCAP_PACA (1 << 30)
81#define HWCAP_GCS (1UL << 32)
85#define HWCAP2_MTE (1 << 18)
89#define HWCAP2_FPMR (1UL << 48)
93#define HWCAP2_POE (1ULL << 63)
104static std::mutex g_register_flags_detector_mutex;
107std::unique_ptr<NativeRegisterContextLinux>
110 switch (target_arch.GetMachine()) {
111 case llvm::Triple::arm:
112 return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
114 case llvm::Triple::aarch64: {
119 ioVec.iov_base = &sve_header;
120 ioVec.iov_len =
sizeof(sve_header);
121 unsigned int regset = NT_ARM_SVE;
125 native_thread.
GetID(), ®set,
126 &ioVec,
sizeof(sve_header))
132 ioVec.iov_len =
sizeof(sve_header);
133 regset = NT_ARM_SSVE;
135 native_thread.
GetID(), ®set,
136 &ioVec,
sizeof(sve_header))
142 ioVec.iov_base = &za_header;
143 ioVec.iov_len =
sizeof(za_header);
146 native_thread.
GetID(), ®set,
147 &ioVec,
sizeof(za_header))
152 std::array<uint8_t, 64> zt_reg;
153 ioVec.iov_base = zt_reg.data();
154 ioVec.iov_len = zt_reg.size();
157 native_thread.
GetID(), ®set,
158 &ioVec, zt_reg.size())
164 std::optional<uint64_t> auxv_at_hwcap =
166 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
169 std::optional<uint64_t> auxv_at_hwcap2 =
171 if (auxv_at_hwcap2) {
184 std::optional<uint64_t> auxv_at_hwcap3 =
186 std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
188 g_register_flags_detector.
DetectFields(auxv_at_hwcap.value_or(0),
189 auxv_at_hwcap2.value_or(0),
190 auxv_at_hwcap3.value_or(0));
192 auto register_info_up =
193 std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
194 return std::make_unique<NativeRegisterContextLinux_arm64>(
195 target_arch, native_thread, std::move(register_info_up));
198 llvm_unreachable(
"have no register context for architecture");
202llvm::Expected<ArchSpec>
204 return DetermineArchitectureViaGPR(
208NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
210 std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
212 register_info_up.release()),
215 GetRegisterInfoInterface().GetRegisterInfo(),
216 GetRegisterInfoInterface().GetRegisterCount());
218 ::memset(&m_fpr, 0,
sizeof(m_fpr));
219 ::memset(&m_gpr_arm64, 0,
sizeof(m_gpr_arm64));
220 ::memset(&m_hwp_regs, 0,
sizeof(m_hwp_regs));
221 ::memset(&m_hbp_regs, 0,
sizeof(m_hbp_regs));
222 ::memset(&m_sve_header, 0,
sizeof(m_sve_header));
223 ::memset(&m_pac_mask, 0,
sizeof(m_pac_mask));
224 ::memset(&m_tls_regs, 0,
sizeof(m_tls_regs));
225 ::memset(&m_sme_pseudo_regs, 0,
sizeof(m_sme_pseudo_regs));
226 ::memset(&m_gcs_regs, 0,
sizeof(m_gcs_regs));
227 ::memset(&m_poe_regs, 0,
sizeof(m_poe_regs));
228 std::fill(m_zt_reg.begin(), m_zt_reg.end(), 0);
234 m_max_hwp_supported = 16;
235 m_max_hbp_supported = 16;
237 m_refresh_hwdebug_info =
true;
239 m_gpr_is_valid =
false;
240 m_fpu_is_valid =
false;
241 m_sve_buffer_is_valid =
false;
242 m_sve_header_is_valid =
false;
243 m_pac_mask_is_valid =
false;
244 m_mte_ctrl_is_valid =
false;
245 m_tls_is_valid =
false;
246 m_zt_buffer_is_valid =
false;
247 m_fpmr_is_valid =
false;
248 m_gcs_is_valid =
false;
249 m_poe_is_valid =
false;
252 m_tls_size = GetRegisterInfo().IsSSVEPresent() ?
sizeof(m_tls_regs)
253 : sizeof(m_tls_regs.tpidr_reg);
255 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
262NativeRegisterContextLinux_arm64::GetRegisterInfo()
const {
266uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount()
const {
271NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index)
const {
272 return GetRegisterInfo().GetRegisterSet(set_index);
275uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount()
const {
277 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
283NativeRegisterContextLinux_arm64::ReadRegister(
const RegisterInfo *reg_info,
296 "no lldb regnum for %s",
297 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
302 std::vector<uint8_t> sve_reg_non_live;
310 assert(offset < GetGPRSize());
311 src = (uint8_t *)GetGPRBuffer() + offset;
313 }
else if (IsFPR(reg)) {
320 offset = CalculateFprOffset(reg_info);
321 assert(offset < GetFPRSize());
322 src = (uint8_t *)GetFPRBuffer() + offset;
327 error = ReadAllSVE();
336 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
342 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
353 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
356 assert(offset < GetSVEBufferSize());
357 src = (uint8_t *)GetSVEBuffer() + offset;
359 }
else if (IsTLS(reg)) {
364 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
365 assert(offset < GetTLSBufferSize());
366 src = (uint8_t *)GetTLSBuffer() + offset;
367 }
else if (IsSVE(reg)) {
371 if (GetRegisterInfo().IsSVERegVG(reg)) {
372 sve_vg = GetSVERegVG();
373 src = (uint8_t *)&sve_vg;
376 error = ReadAllSVE();
384 sve_reg_non_live.resize(reg_info->
byte_size, 0);
385 src = sve_reg_non_live.data();
387 if (GetRegisterInfo().IsSVEZReg(reg)) {
388 offset = CalculateSVEOffset(reg_info);
389 assert(offset < GetSVEBufferSize());
390 ::memcpy(sve_reg_non_live.data(), (uint8_t *)GetSVEBuffer() + offset,
394 offset = CalculateSVEOffset(reg_info);
395 assert(offset < GetSVEBufferSize());
396 src = (uint8_t *)GetSVEBuffer() + offset;
399 }
else if (IsPAuth(reg)) {
400 error = ReadPAuthMask();
404 offset = reg_info->
byte_offset - GetRegisterInfo().GetPAuthOffset();
405 assert(offset < GetPACMaskSize());
406 src = (uint8_t *)GetPACMask() + offset;
407 }
else if (IsMTE(reg)) {
408 error = ReadMTEControl();
412 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
413 assert(offset < GetMTEControlSize());
414 src = (uint8_t *)GetMTEControl() + offset;
415 }
else if (IsSME(reg)) {
416 if (GetRegisterInfo().IsSMERegZA(reg)) {
417 error = ReadZAHeader();
423 if (m_za_header.size ==
sizeof(m_za_header)) {
427 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
429 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
440 src = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
441 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
449 src = (uint8_t *)GetZTBuffer();
451 error = ReadSMESVG();
458 offset = reg_info->
byte_offset - GetRegisterInfo().GetSMEOffset();
459 assert(offset < GetSMEPseudoBufferSize());
460 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
462 }
else if (IsFPMR(reg)) {
467 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
468 assert(offset < GetFPMRBufferSize());
469 src = (uint8_t *)GetFPMRBuffer() + offset;
470 }
else if (IsGCS(reg)) {
475 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
476 assert(offset < GetGCSBufferSize());
477 src = (uint8_t *)GetGCSBuffer() + offset;
478 }
else if (IsPOE(reg)) {
483 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
484 assert(offset < GetPOEBufferSize());
485 src = (uint8_t *)GetPOEBuffer() + offset;
488 "failed - register wasn't recognized to be a GPR or an FPR, "
489 "write strategy unknown");
497Status NativeRegisterContextLinux_arm64::WriteRegister(
508 "no lldb regnum for %s",
509 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
513 std::vector<uint8_t> sve_reg_non_live;
521 dst = (uint8_t *)GetGPRBuffer() + reg_info->
byte_offset;
525 }
else if (IsFPR(reg)) {
532 offset = CalculateFprOffset(reg_info);
533 assert(offset < GetFPRSize());
534 dst = (uint8_t *)GetFPRBuffer() + offset;
540 error = ReadAllSVE();
549 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
555 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
566 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
569 assert(offset < GetSVEBufferSize());
570 dst = (uint8_t *)GetSVEBuffer() + offset;
572 return WriteAllSVE();
574 }
else if (IsSVE(reg)) {
579 error = ReadAllSVE();
583 if (GetRegisterInfo().IsSVERegVG(reg)) {
587 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
590 SetSVERegVG(vg_value);
592 error = WriteSVEHeader();
593 if (
error.Success()) {
596 m_za_header_is_valid =
false;
597 ConfigureRegisterContext();
600 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
611 bool set_sve_state_full =
false;
612 const uint8_t *reg_bytes = (
const uint8_t *)reg_value.
GetBytes();
613 if (GetRegisterInfo().IsSVEZReg(reg)) {
614 for (uint32_t i = 16; i < reg_info->
byte_size; i++) {
616 set_sve_state_full =
true;
620 }
else if (GetRegisterInfo().IsSVEPReg(reg) ||
621 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
622 for (uint32_t i = 0; i < reg_info->
byte_size; i++) {
624 set_sve_state_full =
true;
630 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
633 offset = CalculateSVEOffset(reg_info);
634 assert(offset < GetSVEBufferSize());
635 dst = (uint8_t *)GetSVEBuffer() + offset;
636 ::memcpy(dst, reg_value.
GetBytes(), 16);
638 return WriteAllSVE();
641 "SVE state change operation not supported");
643 offset = CalculateSVEOffset(reg_info);
644 assert(offset < GetSVEBufferSize());
645 dst = (uint8_t *)GetSVEBuffer() + offset;
647 return WriteAllSVE();
650 }
else if (IsMTE(reg)) {
651 error = ReadMTEControl();
655 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
656 assert(offset < GetMTEControlSize());
657 dst = (uint8_t *)GetMTEControl() + offset;
660 return WriteMTEControl();
661 }
else if (IsTLS(reg)) {
666 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
667 assert(offset < GetTLSBufferSize());
668 dst = (uint8_t *)GetTLSBuffer() + offset;
672 }
else if (IsSME(reg)) {
673 if (GetRegisterInfo().IsSMERegZA(reg)) {
680 dst = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
687 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
692 dst = (uint8_t *)GetZTBuffer();
698 "Writing to SVG or SVCR is not supported.");
699 }
else if (IsFPMR(reg)) {
704 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
705 assert(offset < GetFPMRBufferSize());
706 dst = (uint8_t *)GetFPMRBuffer() + offset;
710 }
else if (IsGCS(reg)) {
715 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
716 assert(offset < GetGCSBufferSize());
717 dst = (uint8_t *)GetGCSBuffer() + offset;
721 }
else if (IsPOE(reg)) {
726 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
727 assert(offset < GetPOEBufferSize());
728 dst = (uint8_t *)GetPOEBuffer() + offset;
737enum RegisterSetType : uint32_t {
751static uint8_t *AddRegisterSetType(uint8_t *dst,
752 RegisterSetType register_set_type) {
753 *(
reinterpret_cast<uint32_t *
>(dst)) = register_set_type;
754 return dst +
sizeof(uint32_t);
757static uint8_t *AddSavedRegistersData(uint8_t *dst,
void *src,
size_t size) {
758 ::memcpy(dst, src, size);
762static uint8_t *AddSavedRegisters(uint8_t *dst,
763 enum RegisterSetType register_set_type,
764 void *src,
size_t size) {
765 dst = AddRegisterSetType(dst, register_set_type);
766 return AddSavedRegistersData(dst, src, size);
770NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
772 cached_size =
sizeof(RegisterSetType) + GetGPRBufferSize();
777 if (GetRegisterInfo().IsZAPresent()) {
778 error = ReadZAHeader();
785 cached_size +=
sizeof(RegisterSetType) + m_za_header.size;
788 m_za_buffer_is_valid =
false;
797 GetRegisterInfo().IsZTPresent() &&
799 m_za_header.size >
sizeof(m_za_header)) {
800 cached_size +=
sizeof(RegisterSetType) + GetZTBufferSize();
810 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) {
813 sizeof(RegisterSetType) +
sizeof(m_sve_state) + GetSVEBufferSize();
814 error = ReadAllSVE();
816 cached_size +=
sizeof(RegisterSetType) + GetFPRSize();
822 if (GetRegisterInfo().IsMTEPresent()) {
823 cached_size +=
sizeof(RegisterSetType) + GetMTEControlSize();
824 error = ReadMTEControl();
829 if (GetRegisterInfo().IsFPMRPresent()) {
830 cached_size +=
sizeof(RegisterSetType) + GetFPMRBufferSize();
836 if (GetRegisterInfo().IsGCSPresent()) {
837 cached_size +=
sizeof(RegisterSetType) + GetGCSBufferSize();
843 if (GetRegisterInfo().IsPOEPresent()) {
844 cached_size +=
sizeof(RegisterSetType) + GetPOEBufferSize();
851 cached_size +=
sizeof(RegisterSetType) + GetTLSBufferSize();
857Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
869 uint32_t reg_data_byte_size = 0;
870 Status error = CacheAllRegisters(reg_data_byte_size);
875 uint8_t *dst = data_sp->GetBytes();
877 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
914 assert(m_za_header.size <= GetZABufferSize());
915 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
919 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) {
920 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
921 *(
reinterpret_cast<SVEState *
>(dst)) = m_sve_state;
922 dst +=
sizeof(m_sve_state);
923 dst = AddSavedRegistersData(dst, GetSVEBuffer(), GetSVEBufferSize());
925 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
930 assert(m_za_header.size <= GetZABufferSize());
931 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
942 GetRegisterInfo().IsZTPresent() &&
944 m_za_header.size >
sizeof(m_za_header))
945 dst = AddSavedRegisters(dst, RegisterSetType::SME2, GetZTBuffer(),
948 if (GetRegisterInfo().IsMTEPresent()) {
949 dst = AddSavedRegisters(dst, RegisterSetType::MTE, GetMTEControl(),
950 GetMTEControlSize());
953 if (GetRegisterInfo().IsFPMRPresent()) {
954 dst = AddSavedRegisters(dst, RegisterSetType::FPMR, GetFPMRBuffer(),
955 GetFPMRBufferSize());
958 if (GetRegisterInfo().IsGCSPresent()) {
959 dst = AddSavedRegisters(dst, RegisterSetType::GCS, GetGCSBuffer(),
963 if (GetRegisterInfo().IsPOEPresent()) {
964 dst = AddSavedRegisters(dst, RegisterSetType::POE, GetPOEBuffer(),
968 dst = AddSavedRegisters(dst, RegisterSetType::TLS, GetTLSBuffer(),
974static Status RestoreRegisters(
void *buffer,
const uint8_t **src,
size_t len,
975 bool &is_valid, std::function<
Status()> writer) {
976 ::memcpy(buffer, *src, len);
982Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
998 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
1003 const uint8_t *src = data_sp->GetBytes();
1004 if (src ==
nullptr) {
1006 "NativeRegisterContextLinux_arm64::%s "
1007 "DataBuffer::GetBytes() returned a null "
1013 uint64_t reg_data_min_size =
1014 GetGPRBufferSize() + GetFPRSize() + 2 * (
sizeof(RegisterSetType));
1015 if (data_sp->GetByteSize() < reg_data_min_size) {
1017 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
1018 "register data bytes, expected at least %" PRIu64
", actual %" PRIu64,
1019 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
1023 const uint8_t *end = src + data_sp->GetByteSize();
1025 const RegisterSetType kind =
1026 *
reinterpret_cast<const RegisterSetType *
>(src);
1027 src +=
sizeof(RegisterSetType);
1030 case RegisterSetType::GPR:
1031 error = RestoreRegisters(
1032 GetGPRBuffer(), &src, GetGPRBufferSize(), m_gpr_is_valid,
1033 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR,
this));
1035 case RegisterSetType::SVE:
1037 m_sve_state =
static_cast<SVEState>(*src);
1038 src +=
sizeof(m_sve_state);
1042 ::memcpy(GetSVEHeader(), src, GetSVEHeaderSize());
1044 m_sve_header_is_valid =
false;
1046 "NativeRegisterContextLinux_arm64::%s "
1047 "Invalid SVE header in data_sp",
1051 m_sve_header_is_valid =
true;
1052 error = WriteSVEHeader();
1059 ConfigureRegisterContext();
1062 error = RestoreRegisters(
1063 GetSVEBuffer(), &src, GetSVEBufferSize(), m_sve_buffer_is_valid,
1064 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE,
this));
1066 case RegisterSetType::FPR:
1067 error = RestoreRegisters(
1068 GetFPRBuffer(), &src, GetFPRSize(), m_fpu_is_valid,
1069 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR,
this));
1071 case RegisterSetType::MTE:
1072 error = RestoreRegisters(
1073 GetMTEControl(), &src, GetMTEControlSize(), m_mte_ctrl_is_valid,
1074 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl,
this));
1076 case RegisterSetType::TLS:
1077 error = RestoreRegisters(
1078 GetTLSBuffer(), &src, GetTLSBufferSize(), m_tls_is_valid,
1079 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS,
this));
1081 case RegisterSetType::SME:
1087 ::memcpy(GetZAHeader(), src, GetZAHeaderSize());
1091 m_za_ptrace_payload.resize(m_za_header.size);
1092 ::memcpy(GetZABuffer(), src, GetZABufferSize());
1093 m_za_buffer_is_valid =
true;
1101 ConfigureRegisterContext();
1106 src += GetZABufferSize();
1108 case RegisterSetType::SME2:
1112 error = RestoreRegisters(
1113 GetZTBuffer(), &src, GetZTBufferSize(), m_zt_buffer_is_valid,
1114 std::bind(&NativeRegisterContextLinux_arm64::WriteZT,
this));
1116 case RegisterSetType::FPMR:
1117 error = RestoreRegisters(
1118 GetFPMRBuffer(), &src, GetFPMRBufferSize(), m_fpmr_is_valid,
1119 std::bind(&NativeRegisterContextLinux_arm64::WriteFPMR,
this));
1121 case RegisterSetType::GCS: {
1126 m_gcs_is_valid =
false;
1131 uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
1132 gcs_regs new_gcs_regs = *
reinterpret_cast<const gcs_regs *
>(src);
1133 new_gcs_regs.features_enabled =
1134 (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
1136 const uint8_t *new_gcs_src =
1137 reinterpret_cast<const uint8_t *
>(&new_gcs_regs);
1138 error = RestoreRegisters(
1139 GetGCSBuffer(), &new_gcs_src, GetGCSBufferSize(), m_gcs_is_valid,
1140 std::bind(&NativeRegisterContextLinux_arm64::WriteGCS,
this));
1141 src += GetGCSBufferSize();
1145 case RegisterSetType::POE:
1146 error = RestoreRegisters(
1147 GetPOEBuffer(), &src, GetPOEBufferSize(), m_poe_is_valid,
1148 std::bind(&NativeRegisterContextLinux_arm64::WritePOE,
this));
1159bool NativeRegisterContextLinux_arm64::IsGPR(
unsigned reg)
const {
1160 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
1166bool NativeRegisterContextLinux_arm64::IsFPR(
unsigned reg)
const {
1167 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
1173bool NativeRegisterContextLinux_arm64::IsSVE(
unsigned reg)
const {
1174 return GetRegisterInfo().IsSVEReg(reg);
1177bool NativeRegisterContextLinux_arm64::IsSME(
unsigned reg)
const {
1178 return GetRegisterInfo().IsSMEReg(reg);
1181bool NativeRegisterContextLinux_arm64::IsPAuth(
unsigned reg)
const {
1182 return GetRegisterInfo().IsPAuthReg(reg);
1185bool NativeRegisterContextLinux_arm64::IsMTE(
unsigned reg)
const {
1186 return GetRegisterInfo().IsMTEReg(reg);
1189bool NativeRegisterContextLinux_arm64::IsTLS(
unsigned reg)
const {
1190 return GetRegisterInfo().IsTLSReg(reg);
1193bool NativeRegisterContextLinux_arm64::IsFPMR(
unsigned reg)
const {
1194 return GetRegisterInfo().IsFPMRReg(reg);
1197bool NativeRegisterContextLinux_arm64::IsGCS(
unsigned reg)
const {
1198 return GetRegisterInfo().IsGCSReg(reg);
1201bool NativeRegisterContextLinux_arm64::IsPOE(
unsigned reg)
const {
1202 return GetRegisterInfo().IsPOEReg(reg);
1205llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1206 if (!m_refresh_hwdebug_info) {
1207 return llvm::Error::success();
1210 ::pid_t tid = m_thread.GetID();
1213 m_max_hbp_supported);
1215 return error.ToError();
1217 m_refresh_hwdebug_info =
false;
1219 return llvm::Error::success();
1223NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1224 uint32_t max_supported =
1225 (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
1226 auto ®s = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
1232Status NativeRegisterContextLinux_arm64::ReadGPR() {
1239 ioVec.iov_base = GetGPRBuffer();
1240 ioVec.iov_len = GetGPRBufferSize();
1242 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1244 if (
error.Success())
1245 m_gpr_is_valid =
true;
1250Status NativeRegisterContextLinux_arm64::WriteGPR() {
1256 ioVec.iov_base = GetGPRBuffer();
1257 ioVec.iov_len = GetGPRBufferSize();
1259 m_gpr_is_valid =
false;
1261 return WriteRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1264Status NativeRegisterContextLinux_arm64::ReadFPR() {
1271 ioVec.iov_base = GetFPRBuffer();
1272 ioVec.iov_len = GetFPRSize();
1274 error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1276 if (
error.Success())
1277 m_fpu_is_valid =
true;
1282Status NativeRegisterContextLinux_arm64::WriteFPR() {
1288 ioVec.iov_base = GetFPRBuffer();
1289 ioVec.iov_len = GetFPRSize();
1291 m_fpu_is_valid =
false;
1293 return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1296void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1297 m_gpr_is_valid =
false;
1298 m_fpu_is_valid =
false;
1299 m_sve_buffer_is_valid =
false;
1300 m_sve_header_is_valid =
false;
1301 m_za_buffer_is_valid =
false;
1302 m_za_header_is_valid =
false;
1303 m_pac_mask_is_valid =
false;
1304 m_mte_ctrl_is_valid =
false;
1305 m_tls_is_valid =
false;
1306 m_zt_buffer_is_valid =
false;
1307 m_fpmr_is_valid =
false;
1308 m_gcs_is_valid =
false;
1309 m_poe_is_valid =
false;
1312 ConfigureRegisterContext();
1315unsigned NativeRegisterContextLinux_arm64::GetSVERegSet() {
1319Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1322 if (m_sve_header_is_valid)
1326 ioVec.iov_base = GetSVEHeader();
1327 ioVec.iov_len = GetSVEHeaderSize();
1329 error = ReadRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1331 if (
error.Success())
1332 m_sve_header_is_valid =
true;
1337Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1340 if (m_pac_mask_is_valid)
1344 ioVec.iov_base = GetPACMask();
1345 ioVec.iov_len = GetPACMaskSize();
1347 error = ReadRegisterSet(&ioVec, GetPACMaskSize(), NT_ARM_PAC_MASK);
1349 if (
error.Success())
1350 m_pac_mask_is_valid =
true;
1355Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1358 error = ReadSVEHeader();
1363 ioVec.iov_base = GetSVEHeader();
1364 ioVec.iov_len = GetSVEHeaderSize();
1366 m_sve_buffer_is_valid =
false;
1367 m_sve_header_is_valid =
false;
1368 m_fpu_is_valid =
false;
1370 return WriteRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1373Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1375 if (m_sve_buffer_is_valid)
1379 ioVec.iov_base = GetSVEBuffer();
1380 ioVec.iov_len = GetSVEBufferSize();
1382 error = ReadRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1384 if (
error.Success())
1385 m_sve_buffer_is_valid =
true;
1390Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1393 error = ReadAllSVE();
1399 ioVec.iov_base = GetSVEBuffer();
1400 ioVec.iov_len = GetSVEBufferSize();
1402 m_sve_buffer_is_valid =
false;
1403 m_sve_header_is_valid =
false;
1404 m_fpu_is_valid =
false;
1406 return WriteRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1409Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1421 if (
error.Success() && (m_za_header.size >
sizeof(m_za_header)))
1422 m_sme_pseudo_regs.ctrl_reg |= 2;
1427Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1430 if (m_mte_ctrl_is_valid)
1434 ioVec.iov_base = GetMTEControl();
1435 ioVec.iov_len = GetMTEControlSize();
1437 error = ReadRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1439 if (
error.Success())
1440 m_mte_ctrl_is_valid =
true;
1445Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1448 error = ReadMTEControl();
1453 ioVec.iov_base = GetMTEControl();
1454 ioVec.iov_len = GetMTEControlSize();
1456 m_mte_ctrl_is_valid =
false;
1458 return WriteRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1461Status NativeRegisterContextLinux_arm64::ReadTLS() {
1468 ioVec.iov_base = GetTLSBuffer();
1469 ioVec.iov_len = GetTLSBufferSize();
1471 error = ReadRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1473 if (
error.Success())
1474 m_tls_is_valid =
true;
1479Status NativeRegisterContextLinux_arm64::WriteTLS() {
1487 ioVec.iov_base = GetTLSBuffer();
1488 ioVec.iov_len = GetTLSBufferSize();
1490 m_tls_is_valid =
false;
1492 return WriteRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1495Status NativeRegisterContextLinux_arm64::ReadGCS() {
1502 ioVec.iov_base = GetGCSBuffer();
1503 ioVec.iov_len = GetGCSBufferSize();
1505 error = ReadRegisterSet(&ioVec, GetGCSBufferSize(), NT_ARM_GCS);
1507 if (
error.Success())
1508 m_gcs_is_valid =
true;
1513Status NativeRegisterContextLinux_arm64::WriteGCS() {
1521 ioVec.iov_base = GetGCSBuffer();
1522 ioVec.iov_len = GetGCSBufferSize();
1524 m_gcs_is_valid =
false;
1526 return WriteRegisterSet(&ioVec, GetGCSBufferSize(), NT_ARM_GCS);
1529Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1532 if (m_za_header_is_valid)
1536 ioVec.iov_base = GetZAHeader();
1537 ioVec.iov_len = GetZAHeaderSize();
1539 error = ReadRegisterSet(&ioVec, GetZAHeaderSize(), NT_ARM_ZA);
1541 if (
error.Success())
1542 m_za_header_is_valid =
true;
1547Status NativeRegisterContextLinux_arm64::ReadZA() {
1550 if (m_za_buffer_is_valid)
1554 ioVec.iov_base = GetZABuffer();
1555 ioVec.iov_len = GetZABufferSize();
1557 error = ReadRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1559 if (
error.Success())
1560 m_za_buffer_is_valid =
true;
1565Status NativeRegisterContextLinux_arm64::WriteZA() {
1576 ioVec.iov_base = GetZABuffer();
1577 ioVec.iov_len = GetZABufferSize();
1579 m_za_buffer_is_valid =
false;
1580 m_za_header_is_valid =
false;
1582 m_zt_buffer_is_valid =
false;
1584 return WriteRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1587Status NativeRegisterContextLinux_arm64::ReadZT() {
1590 if (m_zt_buffer_is_valid)
1594 ioVec.iov_base = GetZTBuffer();
1595 ioVec.iov_len = GetZTBufferSize();
1597 error = ReadRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1598 m_zt_buffer_is_valid =
error.Success();
1603Status NativeRegisterContextLinux_arm64::WriteZT() {
1611 ioVec.iov_base = GetZTBuffer();
1612 ioVec.iov_len = GetZTBufferSize();
1614 m_zt_buffer_is_valid =
false;
1617 m_za_buffer_is_valid =
false;
1618 m_za_header_is_valid =
false;
1620 return WriteRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1623Status NativeRegisterContextLinux_arm64::ReadFPMR() {
1626 if (m_fpmr_is_valid)
1630 ioVec.iov_base = GetFPMRBuffer();
1631 ioVec.iov_len = GetFPMRBufferSize();
1633 error = ReadRegisterSet(&ioVec, GetFPMRBufferSize(), NT_ARM_FPMR);
1635 if (
error.Success())
1636 m_fpmr_is_valid =
true;
1641Status NativeRegisterContextLinux_arm64::WriteFPMR() {
1649 ioVec.iov_base = GetFPMRBuffer();
1650 ioVec.iov_len = GetFPMRBufferSize();
1652 m_fpmr_is_valid =
false;
1654 return WriteRegisterSet(&ioVec, GetFPMRBufferSize(), NT_ARM_FPMR);
1657Status NativeRegisterContextLinux_arm64::ReadPOE() {
1664 ioVec.iov_base = GetPOEBuffer();
1665 ioVec.iov_len = GetPOEBufferSize();
1667 error = ReadRegisterSet(&ioVec, GetPOEBufferSize(), NT_ARM_POE);
1669 if (
error.Success())
1670 m_poe_is_valid =
true;
1675Status NativeRegisterContextLinux_arm64::WritePOE() {
1683 ioVec.iov_base = GetPOEBuffer();
1684 ioVec.iov_len = GetPOEBufferSize();
1686 m_poe_is_valid =
false;
1688 return WriteRegisterSet(&ioVec, GetPOEBufferSize(), NT_ARM_POE);
1691void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1703 m_sve_header_is_valid =
false;
1704 m_sve_buffer_is_valid =
false;
1712 m_sve_header_is_valid =
false;
1713 m_sve_buffer_is_valid =
false;
1715 error = ReadSVEHeader();
1716 if (
error.Success()) {
1736 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1741 if (!m_za_header_is_valid) {
1743 if (
error.Success()) {
1748 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1749 m_za_ptrace_payload.resize(m_za_header.size);
1750 m_za_buffer_is_valid =
false;
1755uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1760uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
1767 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
1771 uint32_t sve_z0_offset = GetGPRSize() + 16;
1775 return sve_reg_offset;
1778Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
1782 if (
error.Success())
1783 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
1788std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
1790 std::vector<uint32_t> expedited_reg_nums =
1794 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
1797 if (GetRegisterInfo().IsSSVEPresent())
1798 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
1800 return expedited_reg_nums;
1803llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
1804NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
1806 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
1810 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1811 "Unknown AArch64 memory tag type %d", type);
1814lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
1822 if (ReadPAuthMask().
Success())
1823 mask |= m_pac_mask.data_mask;
1825 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_HWCAP3
Extension of AT_HWCAP.
@ AUXV_AT_HWCAP
Machine dependent hints about processor capabilities.
static size_t GetGPRSizeStatic()
@ eVectorQuadwordAArch64SVE
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
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
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
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)
NativeProcessLinux & GetProcess()
#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 > ®s)
Status ReadHardwareDebugInfo(::pid_t tid, uint32_t &max_hwp_supported, uint32_t &max_hbp_supported)
uint16_t vq_from_vl(uint16_t vl)
const uint32_t ptrace_fpsimd_offset
uint32_t PTraceFPSROffset(uint16_t vq)
uint32_t PTraceFPCROffset(uint16_t vq)
const uint16_t ptrace_regs_mask
user_sve_header user_za_header
const uint16_t ptrace_regs_sve
uint16_t vl_valid(uint16_t vl)
const uint16_t ptrace_regs_fpsimd
uint32_t PTraceSize(uint16_t vq, uint16_t flags)
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.