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))
141 ioVec.iov_base = &za_header;
142 ioVec.iov_len =
sizeof(za_header);
145 native_thread.
GetID(), ®set,
146 &ioVec,
sizeof(za_header))
151 std::array<uint8_t, 64> zt_reg;
152 ioVec.iov_base = zt_reg.data();
153 ioVec.iov_len = zt_reg.size();
156 native_thread.
GetID(), ®set,
157 &ioVec, zt_reg.size())
163 std::optional<uint64_t> auxv_at_hwcap =
165 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
168 std::optional<uint64_t> auxv_at_hwcap2 =
170 if (auxv_at_hwcap2) {
183 std::optional<uint64_t> auxv_at_hwcap3 =
185 std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
187 g_register_flags_detector.
DetectFields(auxv_at_hwcap.value_or(0),
188 auxv_at_hwcap2.value_or(0),
189 auxv_at_hwcap3.value_or(0));
191 auto register_info_up =
192 std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
193 return std::make_unique<NativeRegisterContextLinux_arm64>(
194 target_arch, native_thread, std::move(register_info_up));
197 llvm_unreachable(
"have no register context for architecture");
201llvm::Expected<ArchSpec>
203 return DetermineArchitectureViaGPR(
207NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
209 std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
211 register_info_up.release()),
214 GetRegisterInfoInterface().GetRegisterInfo(),
215 GetRegisterInfoInterface().GetRegisterCount());
217 ::memset(&m_fpr, 0,
sizeof(m_fpr));
218 ::memset(&m_gpr_arm64, 0,
sizeof(m_gpr_arm64));
219 ::memset(&m_hwp_regs, 0,
sizeof(m_hwp_regs));
220 ::memset(&m_hbp_regs, 0,
sizeof(m_hbp_regs));
221 ::memset(&m_sve_header, 0,
sizeof(m_sve_header));
222 ::memset(&m_pac_mask, 0,
sizeof(m_pac_mask));
223 ::memset(&m_tls_regs, 0,
sizeof(m_tls_regs));
224 ::memset(&m_sme_pseudo_regs, 0,
sizeof(m_sme_pseudo_regs));
225 ::memset(&m_gcs_regs, 0,
sizeof(m_gcs_regs));
226 ::memset(&m_poe_regs, 0,
sizeof(m_poe_regs));
227 std::fill(m_zt_reg.begin(), m_zt_reg.end(), 0);
233 m_max_hwp_supported = 16;
234 m_max_hbp_supported = 16;
236 m_refresh_hwdebug_info =
true;
238 m_gpr_is_valid =
false;
239 m_fpu_is_valid =
false;
240 m_sve_buffer_is_valid =
false;
241 m_sve_header_is_valid =
false;
242 m_pac_mask_is_valid =
false;
243 m_mte_ctrl_is_valid =
false;
244 m_tls_is_valid =
false;
245 m_zt_buffer_is_valid =
false;
246 m_fpmr_is_valid =
false;
247 m_gcs_is_valid =
false;
248 m_poe_is_valid =
false;
251 m_tls_size = GetRegisterInfo().IsSSVEPresent() ?
sizeof(m_tls_regs)
252 : sizeof(m_tls_regs.tpidr_reg);
254 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
261NativeRegisterContextLinux_arm64::GetRegisterInfo()
const {
265uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount()
const {
270NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index)
const {
271 return GetRegisterInfo().GetRegisterSet(set_index);
274uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount()
const {
276 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
282NativeRegisterContextLinux_arm64::ReadRegister(
const RegisterInfo *reg_info,
295 "no lldb regnum for %s",
296 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
301 std::vector<uint8_t> sve_reg_non_live;
309 assert(offset < GetGPRSize());
310 src = (uint8_t *)GetGPRBuffer() + offset;
312 }
else if (IsFPR(reg)) {
322 offset = CalculateFprOffset(reg_info,
324 assert(offset < GetFPRSize());
325 src = (uint8_t *)GetFPRBuffer() + offset;
330 error = ReadAllSVE();
339 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
345 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
356 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
359 assert(offset < GetSVEBufferSize());
360 src = (uint8_t *)GetSVEBuffer() + offset;
362 }
else if (IsTLS(reg)) {
367 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
368 assert(offset < GetTLSBufferSize());
369 src = (uint8_t *)GetTLSBuffer() + offset;
370 }
else if (IsSVE(reg)) {
374 if (GetRegisterInfo().IsSVERegVG(reg)) {
375 error = ReadSVEHeader();
379 sve_vg = GetSVERegVG();
380 src = (uint8_t *)&sve_vg;
386 if (GetRegisterInfo().IsSVEPReg(reg) ||
387 GetRegisterInfo().IsSVERegFFR(reg)) {
388 std::vector<uint8_t> fake_reg(reg_info->
byte_size, 0);
411 const uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
413 assert(offset < GetFPRSize());
414 src = (uint8_t *)GetFPRBuffer() + offset;
417 std::vector<uint8_t> fake_z(reg_info->
byte_size, 0);
418 std::memcpy(&fake_z[0], src, 16 );
425 error = ReadAllSVE();
433 sve_reg_non_live.resize(reg_info->
byte_size, 0);
434 src = sve_reg_non_live.data();
436 if (GetRegisterInfo().IsSVEZReg(reg)) {
437 offset = CalculateSVEOffset(reg_info);
438 assert(offset < GetSVEBufferSize());
439 ::memcpy(sve_reg_non_live.data(), (uint8_t *)GetSVEBuffer() + offset,
443 offset = CalculateSVEOffset(reg_info);
444 assert(offset < GetSVEBufferSize());
445 src = (uint8_t *)GetSVEBuffer() + offset;
448 }
else if (IsPAuth(reg)) {
449 error = ReadPAuthMask();
453 offset = reg_info->
byte_offset - GetRegisterInfo().GetPAuthOffset();
454 assert(offset < GetPACMaskSize());
455 src = (uint8_t *)GetPACMask() + offset;
456 }
else if (IsMTE(reg)) {
457 error = ReadMTEControl();
461 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
462 assert(offset < GetMTEControlSize());
463 src = (uint8_t *)GetMTEControl() + offset;
464 }
else if (IsSME(reg)) {
465 if (GetRegisterInfo().IsSMERegZA(reg)) {
466 error = ReadZAHeader();
472 if (m_za_header.size ==
sizeof(m_za_header)) {
476 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
478 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
489 src = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
490 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
498 src = (uint8_t *)GetZTBuffer();
500 error = ReadSMESVG();
507 offset = reg_info->
byte_offset - GetRegisterInfo().GetSMEOffset();
508 assert(offset < GetSMEPseudoBufferSize());
509 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
511 }
else if (IsFPMR(reg)) {
516 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
517 assert(offset < GetFPMRBufferSize());
518 src = (uint8_t *)GetFPMRBuffer() + offset;
519 }
else if (IsGCS(reg)) {
524 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
525 assert(offset < GetGCSBufferSize());
526 src = (uint8_t *)GetGCSBuffer() + offset;
527 }
else if (IsPOE(reg)) {
532 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
533 assert(offset < GetPOEBufferSize());
534 src = (uint8_t *)GetPOEBuffer() + offset;
537 "failed - register wasn't recognized to be a GPR or an FPR, "
538 "write strategy unknown");
546Status NativeRegisterContextLinux_arm64::WriteRegister(
557 "no lldb regnum for %s",
558 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
562 std::vector<uint8_t> sve_reg_non_live;
570 dst = (uint8_t *)GetGPRBuffer() + reg_info->
byte_offset;
574 }
else if (IsFPR(reg)) {
584 offset = CalculateFprOffset(reg_info,
586 assert(offset < GetFPRSize());
587 dst = (uint8_t *)GetFPRBuffer() + offset;
593 error = ReadAllSVE();
602 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
608 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
619 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
622 assert(offset < GetSVEBufferSize());
623 dst = (uint8_t *)GetSVEBuffer() + offset;
625 return WriteAllSVE();
627 }
else if (IsSVE(reg)) {
646 if (GetRegisterInfo().IsSVERegVG(reg) ||
647 GetRegisterInfo().IsSVEPReg(reg) ||
648 GetRegisterInfo().IsSVERegFFR(reg))
650 "Cannot write SVE VG, P or FFR registers while outside of "
662 uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
664 assert(offset < GetFPRSize());
665 dst = (uint8_t *)GetFPRBuffer() + offset;
668 ::memcpy(dst, reg_value.
GetBytes(), 16);
673 error = ReadAllSVE();
677 if (GetRegisterInfo().IsSVERegVG(reg)) {
681 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
684 SetSVERegVG(vg_value);
686 error = WriteSVEHeader();
687 if (
error.Success()) {
690 m_za_header_is_valid =
false;
691 ConfigureRegisterContext();
694 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
705 bool set_sve_state_full =
false;
706 const uint8_t *reg_bytes = (
const uint8_t *)reg_value.
GetBytes();
707 if (GetRegisterInfo().IsSVEZReg(reg)) {
708 for (uint32_t i = 16; i < reg_info->
byte_size; i++) {
710 set_sve_state_full =
true;
714 }
else if (GetRegisterInfo().IsSVEPReg(reg) ||
715 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
716 for (uint32_t i = 0; i < reg_info->
byte_size; i++) {
718 set_sve_state_full =
true;
724 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
727 offset = CalculateSVEOffset(reg_info);
728 assert(offset < GetSVEBufferSize());
729 dst = (uint8_t *)GetSVEBuffer() + offset;
730 ::memcpy(dst, reg_value.
GetBytes(), 16);
732 return WriteAllSVE();
735 "SVE state change operation not supported");
737 offset = CalculateSVEOffset(reg_info);
738 assert(offset < GetSVEBufferSize());
739 dst = (uint8_t *)GetSVEBuffer() + offset;
741 return WriteAllSVE();
744 }
else if (IsMTE(reg)) {
745 error = ReadMTEControl();
749 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
750 assert(offset < GetMTEControlSize());
751 dst = (uint8_t *)GetMTEControl() + offset;
754 return WriteMTEControl();
755 }
else if (IsTLS(reg)) {
760 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
761 assert(offset < GetTLSBufferSize());
762 dst = (uint8_t *)GetTLSBuffer() + offset;
766 }
else if (IsSME(reg)) {
767 if (GetRegisterInfo().IsSMERegZA(reg)) {
774 dst = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
781 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
786 dst = (uint8_t *)GetZTBuffer();
792 "Writing to SVG or SVCR is not supported.");
793 }
else if (IsFPMR(reg)) {
798 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
799 assert(offset < GetFPMRBufferSize());
800 dst = (uint8_t *)GetFPMRBuffer() + offset;
804 }
else if (IsGCS(reg)) {
809 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
810 assert(offset < GetGCSBufferSize());
811 dst = (uint8_t *)GetGCSBuffer() + offset;
815 }
else if (IsPOE(reg)) {
820 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
821 assert(offset < GetPOEBufferSize());
822 dst = (uint8_t *)GetPOEBuffer() + offset;
831enum RegisterSetType : uint32_t {
846static uint8_t *AddRegisterSetType(uint8_t *dst,
847 RegisterSetType register_set_type) {
848 *(
reinterpret_cast<uint32_t *
>(dst)) = register_set_type;
849 return dst +
sizeof(uint32_t);
852static uint8_t *AddSavedRegistersData(uint8_t *dst,
void *src,
size_t size) {
853 ::memcpy(dst, src, size);
857static uint8_t *AddSavedRegisters(uint8_t *dst,
858 enum RegisterSetType register_set_type,
859 void *src,
size_t size) {
860 dst = AddRegisterSetType(dst, register_set_type);
861 return AddSavedRegistersData(dst, src, size);
865NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
867 cached_size =
sizeof(RegisterSetType) + GetGPRBufferSize();
872 if (GetRegisterInfo().IsZAPresent()) {
873 error = ReadZAHeader();
880 cached_size +=
sizeof(RegisterSetType) + m_za_header.size;
883 m_za_buffer_is_valid =
false;
892 GetRegisterInfo().IsZTPresent() &&
894 m_za_header.size >
sizeof(m_za_header)) {
895 cached_size +=
sizeof(RegisterSetType) + GetZTBufferSize();
907 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
911 sizeof(RegisterSetType) +
sizeof(m_sve_state) + GetSVEBufferSize();
912 error = ReadAllSVE();
914 cached_size +=
sizeof(RegisterSetType) + GetFPRSize();
920 if (GetRegisterInfo().IsMTEPresent()) {
921 cached_size +=
sizeof(RegisterSetType) + GetMTEControlSize();
922 error = ReadMTEControl();
927 if (GetRegisterInfo().IsFPMRPresent()) {
928 cached_size +=
sizeof(RegisterSetType) + GetFPMRBufferSize();
934 if (GetRegisterInfo().IsGCSPresent()) {
935 cached_size +=
sizeof(RegisterSetType) + GetGCSBufferSize();
941 if (GetRegisterInfo().IsPOEPresent()) {
942 cached_size +=
sizeof(RegisterSetType) + GetPOEBufferSize();
949 cached_size +=
sizeof(RegisterSetType) + GetTLSBufferSize();
955Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
967 uint32_t reg_data_byte_size = 0;
968 Status error = CacheAllRegisters(reg_data_byte_size);
973 uint8_t *dst = data_sp->GetBytes();
975 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
1012 assert(m_za_header.size <= GetZABufferSize());
1013 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
1017 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
1019 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
1020 *(
reinterpret_cast<SVEState *
>(dst)) = m_sve_state;
1021 dst +=
sizeof(m_sve_state);
1022 dst = AddSavedRegistersData(dst, GetSVEBuffer(), GetSVEBufferSize());
1024 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
1029 assert(m_za_header.size <= GetZABufferSize());
1030 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
1041 GetRegisterInfo().IsZTPresent() &&
1043 m_za_header.size >
sizeof(m_za_header))
1044 dst = AddSavedRegisters(dst, RegisterSetType::SME2, GetZTBuffer(),
1047 if (GetRegisterInfo().IsMTEPresent()) {
1048 dst = AddSavedRegisters(dst, RegisterSetType::MTE, GetMTEControl(),
1049 GetMTEControlSize());
1052 if (GetRegisterInfo().IsFPMRPresent()) {
1053 dst = AddSavedRegisters(dst, RegisterSetType::FPMR, GetFPMRBuffer(),
1054 GetFPMRBufferSize());
1057 if (GetRegisterInfo().IsGCSPresent()) {
1058 dst = AddSavedRegisters(dst, RegisterSetType::GCS, GetGCSBuffer(),
1059 GetGCSBufferSize());
1062 if (GetRegisterInfo().IsPOEPresent()) {
1063 dst = AddSavedRegisters(dst, RegisterSetType::POE, GetPOEBuffer(),
1064 GetPOEBufferSize());
1067 dst = AddSavedRegisters(dst, RegisterSetType::TLS, GetTLSBuffer(),
1068 GetTLSBufferSize());
1073static Status RestoreRegisters(
void *buffer,
const uint8_t **src,
size_t len,
1074 bool &is_valid, std::function<
Status()> writer) {
1075 ::memcpy(buffer, *src, len);
1081Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
1097 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
1102 const uint8_t *src = data_sp->GetBytes();
1103 if (src ==
nullptr) {
1105 "NativeRegisterContextLinux_arm64::%s "
1106 "DataBuffer::GetBytes() returned a null "
1112 uint64_t reg_data_min_size =
1113 GetGPRBufferSize() + GetFPRSize() + 2 * (
sizeof(RegisterSetType));
1114 if (data_sp->GetByteSize() < reg_data_min_size) {
1116 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
1117 "register data bytes, expected at least %" PRIu64
", actual %" PRIu64,
1118 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
1122 const uint8_t *end = src + data_sp->GetByteSize();
1124 const RegisterSetType kind =
1125 *
reinterpret_cast<const RegisterSetType *
>(src);
1126 src +=
sizeof(RegisterSetType);
1129 case RegisterSetType::GPR:
1130 error = RestoreRegisters(
1131 GetGPRBuffer(), &src, GetGPRBufferSize(), m_gpr_is_valid,
1132 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR,
this));
1134 case RegisterSetType::SVE:
1136 m_sve_state =
static_cast<SVEState>(*src);
1137 src +=
sizeof(m_sve_state);
1141 ::memcpy(GetSVEHeader(), src, GetSVEHeaderSize());
1143 m_sve_header_is_valid =
false;
1145 "NativeRegisterContextLinux_arm64::%s "
1146 "Invalid SVE header in data_sp",
1150 m_sve_header_is_valid =
true;
1151 error = WriteSVEHeader();
1158 ConfigureRegisterContext();
1161 error = RestoreRegisters(
1162 GetSVEBuffer(), &src, GetSVEBufferSize(), m_sve_buffer_is_valid,
1163 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE,
this));
1165 case RegisterSetType::FPR: {
1166 m_sve_buffer_is_valid =
false;
1167 m_sve_header_is_valid =
false;
1169 ConfigureRegisterContext();
1173 if (!GetRegisterInfo().IsSVEPresent() &&
1174 GetRegisterInfo().IsSSVEPresent() &&
1192 std::vector<uint8_t> sve_fpsimd_data(data_size);
1197 header->
size = sve_fpsimd_data.size();
1205 ioVec.iov_base = sve_fpsimd_data.data();
1206 ioVec.iov_len = sve_fpsimd_data.size();
1210 error = WriteRegisterSet(&ioVec, sve_fpsimd_data.size(), NT_ARM_SVE);
1213 src += GetFPRSize();
1215 if (
error.Success()) {
1217 m_fpu_is_valid =
false;
1218 m_sve_buffer_is_valid =
false;
1219 m_sve_header_is_valid =
false;
1222 ConfigureRegisterContext();
1227 error = RestoreRegisters(
1228 GetFPRBuffer(), &src, GetFPRSize(), m_fpu_is_valid,
1229 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR,
this));
1233 case RegisterSetType::MTE:
1234 error = RestoreRegisters(
1235 GetMTEControl(), &src, GetMTEControlSize(), m_mte_ctrl_is_valid,
1236 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl,
this));
1238 case RegisterSetType::TLS:
1239 error = RestoreRegisters(
1240 GetTLSBuffer(), &src, GetTLSBufferSize(), m_tls_is_valid,
1241 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS,
this));
1243 case RegisterSetType::SME:
1249 ::memcpy(GetZAHeader(), src, GetZAHeaderSize());
1253 m_za_ptrace_payload.resize(m_za_header.size);
1254 ::memcpy(GetZABuffer(), src, GetZABufferSize());
1255 m_za_buffer_is_valid =
true;
1263 ConfigureRegisterContext();
1268 src += GetZABufferSize();
1270 case RegisterSetType::SME2:
1274 error = RestoreRegisters(
1275 GetZTBuffer(), &src, GetZTBufferSize(), m_zt_buffer_is_valid,
1276 std::bind(&NativeRegisterContextLinux_arm64::WriteZT,
this));
1278 case RegisterSetType::FPMR:
1279 error = RestoreRegisters(
1280 GetFPMRBuffer(), &src, GetFPMRBufferSize(), m_fpmr_is_valid,
1281 std::bind(&NativeRegisterContextLinux_arm64::WriteFPMR,
this));
1283 case RegisterSetType::GCS: {
1288 m_gcs_is_valid =
false;
1293 uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
1294 gcs_regs new_gcs_regs = *
reinterpret_cast<const gcs_regs *
>(src);
1295 new_gcs_regs.features_enabled =
1296 (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
1298 const uint8_t *new_gcs_src =
1299 reinterpret_cast<const uint8_t *
>(&new_gcs_regs);
1300 error = RestoreRegisters(
1301 GetGCSBuffer(), &new_gcs_src, GetGCSBufferSize(), m_gcs_is_valid,
1302 std::bind(&NativeRegisterContextLinux_arm64::WriteGCS,
this));
1303 src += GetGCSBufferSize();
1307 case RegisterSetType::POE:
1308 error = RestoreRegisters(
1309 GetPOEBuffer(), &src, GetPOEBufferSize(), m_poe_is_valid,
1310 std::bind(&NativeRegisterContextLinux_arm64::WritePOE,
this));
1321bool NativeRegisterContextLinux_arm64::IsGPR(
unsigned reg)
const {
1322 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
1328bool NativeRegisterContextLinux_arm64::IsFPR(
unsigned reg)
const {
1329 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
1335bool NativeRegisterContextLinux_arm64::IsSVE(
unsigned reg)
const {
1336 return GetRegisterInfo().IsSVEReg(reg);
1339bool NativeRegisterContextLinux_arm64::IsSME(
unsigned reg)
const {
1340 return GetRegisterInfo().IsSMEReg(reg);
1343bool NativeRegisterContextLinux_arm64::IsPAuth(
unsigned reg)
const {
1344 return GetRegisterInfo().IsPAuthReg(reg);
1347bool NativeRegisterContextLinux_arm64::IsMTE(
unsigned reg)
const {
1348 return GetRegisterInfo().IsMTEReg(reg);
1351bool NativeRegisterContextLinux_arm64::IsTLS(
unsigned reg)
const {
1352 return GetRegisterInfo().IsTLSReg(reg);
1355bool NativeRegisterContextLinux_arm64::IsFPMR(
unsigned reg)
const {
1356 return GetRegisterInfo().IsFPMRReg(reg);
1359bool NativeRegisterContextLinux_arm64::IsGCS(
unsigned reg)
const {
1360 return GetRegisterInfo().IsGCSReg(reg);
1363bool NativeRegisterContextLinux_arm64::IsPOE(
unsigned reg)
const {
1364 return GetRegisterInfo().IsPOEReg(reg);
1367llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1368 if (!m_refresh_hwdebug_info) {
1369 return llvm::Error::success();
1372 ::pid_t tid = m_thread.GetID();
1375 m_max_hbp_supported);
1377 return error.ToError();
1379 m_refresh_hwdebug_info =
false;
1381 return llvm::Error::success();
1385NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1386 uint32_t max_supported =
1387 (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
1388 auto ®s = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
1394Status NativeRegisterContextLinux_arm64::ReadGPR() {
1401 ioVec.iov_base = GetGPRBuffer();
1402 ioVec.iov_len = GetGPRBufferSize();
1404 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1406 if (
error.Success())
1407 m_gpr_is_valid =
true;
1412Status NativeRegisterContextLinux_arm64::WriteGPR() {
1418 ioVec.iov_base = GetGPRBuffer();
1419 ioVec.iov_len = GetGPRBufferSize();
1421 m_gpr_is_valid =
false;
1423 return WriteRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1426Status NativeRegisterContextLinux_arm64::ReadFPR() {
1433 ioVec.iov_base = GetFPRBuffer();
1434 ioVec.iov_len = GetFPRSize();
1436 error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1437 if (
error.Success())
1438 m_fpu_is_valid =
true;
1443Status NativeRegisterContextLinux_arm64::WriteFPR() {
1449 ioVec.iov_base = GetFPRBuffer();
1450 ioVec.iov_len = GetFPRSize();
1452 m_fpu_is_valid =
false;
1454 m_sve_buffer_is_valid =
false;
1455 m_sve_header_is_valid =
false;
1457 return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1460void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1461 m_gpr_is_valid =
false;
1462 m_fpu_is_valid =
false;
1463 m_sve_buffer_is_valid =
false;
1464 m_sve_header_is_valid =
false;
1465 m_za_buffer_is_valid =
false;
1466 m_za_header_is_valid =
false;
1467 m_pac_mask_is_valid =
false;
1468 m_mte_ctrl_is_valid =
false;
1469 m_tls_is_valid =
false;
1470 m_zt_buffer_is_valid =
false;
1471 m_fpmr_is_valid =
false;
1472 m_gcs_is_valid =
false;
1473 m_poe_is_valid =
false;
1476 ConfigureRegisterContext();
1479unsigned NativeRegisterContextLinux_arm64::GetSVERegSet() {
1480 switch (m_sve_state) {
1489Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1492 if (m_sve_header_is_valid)
1496 ioVec.iov_base = GetSVEHeader();
1497 ioVec.iov_len = GetSVEHeaderSize();
1499 error = ReadRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1501 if (
error.Success())
1502 m_sve_header_is_valid =
true;
1507Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1510 if (m_pac_mask_is_valid)
1514 ioVec.iov_base = GetPACMask();
1515 ioVec.iov_len = GetPACMaskSize();
1517 error = ReadRegisterSet(&ioVec, GetPACMaskSize(), NT_ARM_PAC_MASK);
1519 if (
error.Success())
1520 m_pac_mask_is_valid =
true;
1525Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1528 error = ReadSVEHeader();
1533 ioVec.iov_base = GetSVEHeader();
1534 ioVec.iov_len = GetSVEHeaderSize();
1536 m_sve_buffer_is_valid =
false;
1537 m_sve_header_is_valid =
false;
1538 m_fpu_is_valid =
false;
1540 return WriteRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1543Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1545 if (m_sve_buffer_is_valid)
1549 ioVec.iov_base = GetSVEBuffer();
1550 ioVec.iov_len = GetSVEBufferSize();
1552 error = ReadRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1554 if (
error.Success())
1555 m_sve_buffer_is_valid =
true;
1560Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1563 error = ReadAllSVE();
1569 ioVec.iov_base = GetSVEBuffer();
1570 ioVec.iov_len = GetSVEBufferSize();
1572 m_sve_buffer_is_valid =
false;
1573 m_sve_header_is_valid =
false;
1574 m_fpu_is_valid =
false;
1576 return WriteRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1579Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1591 if (
error.Success() && (m_za_header.size >
sizeof(m_za_header)))
1592 m_sme_pseudo_regs.ctrl_reg |= 2;
1597Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1600 if (m_mte_ctrl_is_valid)
1604 ioVec.iov_base = GetMTEControl();
1605 ioVec.iov_len = GetMTEControlSize();
1607 error = ReadRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1609 if (
error.Success())
1610 m_mte_ctrl_is_valid =
true;
1615Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1618 error = ReadMTEControl();
1623 ioVec.iov_base = GetMTEControl();
1624 ioVec.iov_len = GetMTEControlSize();
1626 m_mte_ctrl_is_valid =
false;
1628 return WriteRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1631Status NativeRegisterContextLinux_arm64::ReadTLS() {
1638 ioVec.iov_base = GetTLSBuffer();
1639 ioVec.iov_len = GetTLSBufferSize();
1641 error = ReadRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1643 if (
error.Success())
1644 m_tls_is_valid =
true;
1649Status NativeRegisterContextLinux_arm64::WriteTLS() {
1657 ioVec.iov_base = GetTLSBuffer();
1658 ioVec.iov_len = GetTLSBufferSize();
1660 m_tls_is_valid =
false;
1662 return WriteRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1665Status NativeRegisterContextLinux_arm64::ReadGCS() {
1672 ioVec.iov_base = GetGCSBuffer();
1673 ioVec.iov_len = GetGCSBufferSize();
1675 error = ReadRegisterSet(&ioVec, GetGCSBufferSize(), NT_ARM_GCS);
1677 if (
error.Success())
1678 m_gcs_is_valid =
true;
1683Status NativeRegisterContextLinux_arm64::WriteGCS() {
1691 ioVec.iov_base = GetGCSBuffer();
1692 ioVec.iov_len = GetGCSBufferSize();
1694 m_gcs_is_valid =
false;
1696 return WriteRegisterSet(&ioVec, GetGCSBufferSize(), NT_ARM_GCS);
1699Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1702 if (m_za_header_is_valid)
1706 ioVec.iov_base = GetZAHeader();
1707 ioVec.iov_len = GetZAHeaderSize();
1709 error = ReadRegisterSet(&ioVec, GetZAHeaderSize(), NT_ARM_ZA);
1711 if (
error.Success())
1712 m_za_header_is_valid =
true;
1717Status NativeRegisterContextLinux_arm64::ReadZA() {
1720 if (m_za_buffer_is_valid)
1724 ioVec.iov_base = GetZABuffer();
1725 ioVec.iov_len = GetZABufferSize();
1727 error = ReadRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1729 if (
error.Success())
1730 m_za_buffer_is_valid =
true;
1735Status NativeRegisterContextLinux_arm64::WriteZA() {
1746 ioVec.iov_base = GetZABuffer();
1747 ioVec.iov_len = GetZABufferSize();
1749 m_za_buffer_is_valid =
false;
1750 m_za_header_is_valid =
false;
1752 m_zt_buffer_is_valid =
false;
1754 return WriteRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1757Status NativeRegisterContextLinux_arm64::ReadZT() {
1760 if (m_zt_buffer_is_valid)
1764 ioVec.iov_base = GetZTBuffer();
1765 ioVec.iov_len = GetZTBufferSize();
1767 error = ReadRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1768 m_zt_buffer_is_valid =
error.Success();
1773Status NativeRegisterContextLinux_arm64::WriteZT() {
1781 ioVec.iov_base = GetZTBuffer();
1782 ioVec.iov_len = GetZTBufferSize();
1784 m_zt_buffer_is_valid =
false;
1787 m_za_buffer_is_valid =
false;
1788 m_za_header_is_valid =
false;
1790 return WriteRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1793Status NativeRegisterContextLinux_arm64::ReadFPMR() {
1796 if (m_fpmr_is_valid)
1800 ioVec.iov_base = GetFPMRBuffer();
1801 ioVec.iov_len = GetFPMRBufferSize();
1803 error = ReadRegisterSet(&ioVec, GetFPMRBufferSize(), NT_ARM_FPMR);
1805 if (
error.Success())
1806 m_fpmr_is_valid =
true;
1811Status NativeRegisterContextLinux_arm64::WriteFPMR() {
1819 ioVec.iov_base = GetFPMRBuffer();
1820 ioVec.iov_len = GetFPMRBufferSize();
1822 m_fpmr_is_valid =
false;
1824 return WriteRegisterSet(&ioVec, GetFPMRBufferSize(), NT_ARM_FPMR);
1827Status NativeRegisterContextLinux_arm64::ReadPOE() {
1834 ioVec.iov_base = GetPOEBuffer();
1835 ioVec.iov_len = GetPOEBufferSize();
1837 error = ReadRegisterSet(&ioVec, GetPOEBufferSize(), NT_ARM_POE);
1839 if (
error.Success())
1840 m_poe_is_valid =
true;
1845Status NativeRegisterContextLinux_arm64::WritePOE() {
1853 ioVec.iov_base = GetPOEBuffer();
1854 ioVec.iov_len = GetPOEBufferSize();
1856 m_poe_is_valid =
false;
1858 return WriteRegisterSet(&ioVec, GetPOEBufferSize(), NT_ARM_POE);
1861void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1873 m_sve_header_is_valid =
false;
1874 m_sve_buffer_is_valid =
false;
1878 bool has_sme =
error.Success();
1879 bool sme_is_active =
1884 m_sve_header_is_valid =
false;
1885 m_sve_buffer_is_valid =
false;
1887 error = ReadSVEHeader();
1889 bool has_sve =
error.Success();
1890 bool sve_is_active =
1901 else if (sve_is_active)
1903 else if (fp_is_active)
1915 m_sve_header_is_valid =
false;
1916 m_sve_buffer_is_valid =
false;
1917 error = ReadSVEHeader();
1925 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1930 if (!m_za_header_is_valid) {
1932 if (
error.Success()) {
1937 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1938 m_za_ptrace_payload.resize(m_za_header.size);
1939 m_za_buffer_is_valid =
false;
1944uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1945 const RegisterInfo *reg_info,
bool streaming_fpsimd)
const {
1946 uint32_t offset = reg_info->
byte_offset - GetGPRSize();
1947 if (!streaming_fpsimd)
1959 const size_t fpsr_offset = 16 * 32;
1961 if (reg == GetRegisterInfo().GetRegNumFPSR())
1962 offset = fpsr_offset;
1963 else if (reg == GetRegisterInfo().GetRegNumFPCR())
1964 offset = fpsr_offset + 4;
1966 offset = 16 * (reg - GetRegisterInfo().GetRegNumFPV0());
1971uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
1978 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
1982 uint32_t sve_z0_offset = GetGPRSize() + 16;
1986 return sve_reg_offset;
1989Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
1993 if (
error.Success())
1994 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
1999std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
2001 std::vector<uint32_t> expedited_reg_nums =
2005 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
2008 if (GetRegisterInfo().IsSSVEPresent())
2009 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
2011 return expedited_reg_nums;
2014llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
2015NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
2017 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
2021 return llvm::createStringError(llvm::inconvertibleErrorCode(),
2022 "Unknown AArch64 memory tag type %d", type);
2025lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
2033 if (ReadPAuthMask().
Success())
2034 mask |= m_pac_mask.data_mask;
2036 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()
size_t GetRegisterSetCount() const override
@ eVectorQuadwordAArch64SVE
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.