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_GCS 0x410
72#define HWCAP_PACA (1 << 30)
74#define HWCAP_GCS (1UL << 32)
76#define HWCAP2_MTE (1 << 18)
78#define HWCAP2_FPMR (1UL << 48)
88static std::mutex g_register_flags_detector_mutex;
91std::unique_ptr<NativeRegisterContextLinux>
94 switch (target_arch.GetMachine()) {
95 case llvm::Triple::arm:
96 return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
98 case llvm::Triple::aarch64: {
103 ioVec.iov_base = &sve_header;
104 ioVec.iov_len =
sizeof(sve_header);
105 unsigned int regset = NT_ARM_SVE;
109 native_thread.
GetID(), ®set,
110 &ioVec,
sizeof(sve_header))
116 ioVec.iov_len =
sizeof(sve_header);
117 regset = NT_ARM_SSVE;
119 native_thread.
GetID(), ®set,
120 &ioVec,
sizeof(sve_header))
126 ioVec.iov_base = &za_header;
127 ioVec.iov_len =
sizeof(za_header);
130 native_thread.
GetID(), ®set,
131 &ioVec,
sizeof(za_header))
136 std::array<uint8_t, 64> zt_reg;
137 ioVec.iov_base = zt_reg.data();
138 ioVec.iov_len = zt_reg.size();
141 native_thread.
GetID(), ®set,
142 &ioVec, zt_reg.size())
148 std::optional<uint64_t> auxv_at_hwcap =
150 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
153 std::optional<uint64_t> auxv_at_hwcap2 =
155 if (auxv_at_hwcap2) {
166 std::optional<uint64_t> auxv_at_hwcap3 =
168 std::lock_guard<std::mutex> lock(g_register_flags_detector_mutex);
170 g_register_flags_detector.
DetectFields(auxv_at_hwcap.value_or(0),
171 auxv_at_hwcap2.value_or(0),
172 auxv_at_hwcap3.value_or(0));
174 auto register_info_up =
175 std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
176 return std::make_unique<NativeRegisterContextLinux_arm64>(
177 target_arch, native_thread, std::move(register_info_up));
180 llvm_unreachable(
"have no register context for architecture");
184llvm::Expected<ArchSpec>
186 return DetermineArchitectureViaGPR(
190NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
192 std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
194 register_info_up.release()),
197 GetRegisterInfoInterface().GetRegisterInfo(),
198 GetRegisterInfoInterface().GetRegisterCount());
200 ::memset(&m_fpr, 0,
sizeof(m_fpr));
201 ::memset(&m_gpr_arm64, 0,
sizeof(m_gpr_arm64));
202 ::memset(&m_hwp_regs, 0,
sizeof(m_hwp_regs));
203 ::memset(&m_hbp_regs, 0,
sizeof(m_hbp_regs));
204 ::memset(&m_sve_header, 0,
sizeof(m_sve_header));
205 ::memset(&m_pac_mask, 0,
sizeof(m_pac_mask));
206 ::memset(&m_tls_regs, 0,
sizeof(m_tls_regs));
207 ::memset(&m_sme_pseudo_regs, 0,
sizeof(m_sme_pseudo_regs));
208 ::memset(&m_gcs_regs, 0,
sizeof(m_gcs_regs));
209 std::fill(m_zt_reg.begin(), m_zt_reg.end(), 0);
215 m_max_hwp_supported = 16;
216 m_max_hbp_supported = 16;
218 m_refresh_hwdebug_info =
true;
220 m_gpr_is_valid =
false;
221 m_fpu_is_valid =
false;
222 m_sve_buffer_is_valid =
false;
223 m_sve_header_is_valid =
false;
224 m_pac_mask_is_valid =
false;
225 m_mte_ctrl_is_valid =
false;
226 m_tls_is_valid =
false;
227 m_zt_buffer_is_valid =
false;
228 m_fpmr_is_valid =
false;
229 m_gcs_is_valid =
false;
232 m_tls_size = GetRegisterInfo().IsSSVEPresent() ?
sizeof(m_tls_regs)
233 : sizeof(m_tls_regs.tpidr_reg);
235 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
242NativeRegisterContextLinux_arm64::GetRegisterInfo()
const {
246uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount()
const {
251NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index)
const {
252 return GetRegisterInfo().GetRegisterSet(set_index);
255uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount()
const {
257 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
263NativeRegisterContextLinux_arm64::ReadRegister(
const RegisterInfo *reg_info,
276 "no lldb regnum for %s",
277 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
282 std::vector<uint8_t> sve_reg_non_live;
290 assert(offset < GetGPRSize());
291 src = (uint8_t *)GetGPRBuffer() + offset;
293 }
else if (IsFPR(reg)) {
300 offset = CalculateFprOffset(reg_info);
301 assert(offset < GetFPRSize());
302 src = (uint8_t *)GetFPRBuffer() + offset;
307 error = ReadAllSVE();
316 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
322 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
333 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
336 assert(offset < GetSVEBufferSize());
337 src = (uint8_t *)GetSVEBuffer() + offset;
339 }
else if (IsTLS(reg)) {
344 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
345 assert(offset < GetTLSBufferSize());
346 src = (uint8_t *)GetTLSBuffer() + offset;
347 }
else if (IsSVE(reg)) {
351 if (GetRegisterInfo().IsSVERegVG(reg)) {
352 sve_vg = GetSVERegVG();
353 src = (uint8_t *)&sve_vg;
356 error = ReadAllSVE();
364 sve_reg_non_live.resize(reg_info->
byte_size, 0);
365 src = sve_reg_non_live.data();
367 if (GetRegisterInfo().IsSVEZReg(reg)) {
368 offset = CalculateSVEOffset(reg_info);
369 assert(offset < GetSVEBufferSize());
370 ::memcpy(sve_reg_non_live.data(), (uint8_t *)GetSVEBuffer() + offset,
374 offset = CalculateSVEOffset(reg_info);
375 assert(offset < GetSVEBufferSize());
376 src = (uint8_t *)GetSVEBuffer() + offset;
379 }
else if (IsPAuth(reg)) {
380 error = ReadPAuthMask();
384 offset = reg_info->
byte_offset - GetRegisterInfo().GetPAuthOffset();
385 assert(offset < GetPACMaskSize());
386 src = (uint8_t *)GetPACMask() + offset;
387 }
else if (IsMTE(reg)) {
388 error = ReadMTEControl();
392 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
393 assert(offset < GetMTEControlSize());
394 src = (uint8_t *)GetMTEControl() + offset;
395 }
else if (IsSME(reg)) {
396 if (GetRegisterInfo().IsSMERegZA(reg)) {
397 error = ReadZAHeader();
403 if (m_za_header.size ==
sizeof(m_za_header)) {
407 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
409 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
420 src = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
421 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
429 src = (uint8_t *)GetZTBuffer();
431 error = ReadSMESVG();
438 offset = reg_info->
byte_offset - GetRegisterInfo().GetSMEOffset();
439 assert(offset < GetSMEPseudoBufferSize());
440 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
442 }
else if (IsFPMR(reg)) {
447 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
448 assert(offset < GetFPMRBufferSize());
449 src = (uint8_t *)GetFPMRBuffer() + offset;
450 }
else if (IsGCS(reg)) {
455 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
456 assert(offset < GetGCSBufferSize());
457 src = (uint8_t *)GetGCSBuffer() + offset;
460 "failed - register wasn't recognized to be a GPR or an FPR, "
461 "write strategy unknown");
469Status NativeRegisterContextLinux_arm64::WriteRegister(
480 "no lldb regnum for %s",
481 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
485 std::vector<uint8_t> sve_reg_non_live;
493 dst = (uint8_t *)GetGPRBuffer() + reg_info->
byte_offset;
497 }
else if (IsFPR(reg)) {
504 offset = CalculateFprOffset(reg_info);
505 assert(offset < GetFPRSize());
506 dst = (uint8_t *)GetFPRBuffer() + offset;
512 error = ReadAllSVE();
521 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
527 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
538 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
541 assert(offset < GetSVEBufferSize());
542 dst = (uint8_t *)GetSVEBuffer() + offset;
544 return WriteAllSVE();
546 }
else if (IsSVE(reg)) {
551 error = ReadAllSVE();
555 if (GetRegisterInfo().IsSVERegVG(reg)) {
559 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
562 SetSVERegVG(vg_value);
564 error = WriteSVEHeader();
565 if (
error.Success()) {
568 m_za_header_is_valid =
false;
569 ConfigureRegisterContext();
572 if (m_sve_header_is_valid && vg_value == GetSVERegVG())
583 bool set_sve_state_full =
false;
584 const uint8_t *reg_bytes = (
const uint8_t *)reg_value.
GetBytes();
585 if (GetRegisterInfo().IsSVEZReg(reg)) {
586 for (uint32_t i = 16; i < reg_info->
byte_size; i++) {
588 set_sve_state_full =
true;
592 }
else if (GetRegisterInfo().IsSVEPReg(reg) ||
593 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
594 for (uint32_t i = 0; i < reg_info->
byte_size; i++) {
596 set_sve_state_full =
true;
602 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
605 offset = CalculateSVEOffset(reg_info);
606 assert(offset < GetSVEBufferSize());
607 dst = (uint8_t *)GetSVEBuffer() + offset;
608 ::memcpy(dst, reg_value.
GetBytes(), 16);
610 return WriteAllSVE();
613 "SVE state change operation not supported");
615 offset = CalculateSVEOffset(reg_info);
616 assert(offset < GetSVEBufferSize());
617 dst = (uint8_t *)GetSVEBuffer() + offset;
619 return WriteAllSVE();
622 }
else if (IsMTE(reg)) {
623 error = ReadMTEControl();
627 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
628 assert(offset < GetMTEControlSize());
629 dst = (uint8_t *)GetMTEControl() + offset;
632 return WriteMTEControl();
633 }
else if (IsTLS(reg)) {
638 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
639 assert(offset < GetTLSBufferSize());
640 dst = (uint8_t *)GetTLSBuffer() + offset;
644 }
else if (IsSME(reg)) {
645 if (GetRegisterInfo().IsSMERegZA(reg)) {
652 dst = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
659 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
664 dst = (uint8_t *)GetZTBuffer();
670 "Writing to SVG or SVCR is not supported.");
671 }
else if (IsFPMR(reg)) {
676 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
677 assert(offset < GetFPMRBufferSize());
678 dst = (uint8_t *)GetFPMRBuffer() + offset;
682 }
else if (IsGCS(reg)) {
687 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
688 assert(offset < GetGCSBufferSize());
689 dst = (uint8_t *)GetGCSBuffer() + offset;
698enum RegisterSetType : uint32_t {
711static uint8_t *AddRegisterSetType(uint8_t *dst,
712 RegisterSetType register_set_type) {
713 *(
reinterpret_cast<uint32_t *
>(dst)) = register_set_type;
714 return dst +
sizeof(uint32_t);
717static uint8_t *AddSavedRegistersData(uint8_t *dst,
void *src,
size_t size) {
718 ::memcpy(dst, src, size);
722static uint8_t *AddSavedRegisters(uint8_t *dst,
723 enum RegisterSetType register_set_type,
724 void *src,
size_t size) {
725 dst = AddRegisterSetType(dst, register_set_type);
726 return AddSavedRegistersData(dst, src, size);
730NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
732 cached_size =
sizeof(RegisterSetType) + GetGPRBufferSize();
737 if (GetRegisterInfo().IsZAPresent()) {
738 error = ReadZAHeader();
745 cached_size +=
sizeof(RegisterSetType) + m_za_header.size;
748 m_za_buffer_is_valid =
false;
757 GetRegisterInfo().IsZTPresent() &&
759 m_za_header.size >
sizeof(m_za_header)) {
760 cached_size +=
sizeof(RegisterSetType) + GetZTBufferSize();
770 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) {
773 sizeof(RegisterSetType) +
sizeof(m_sve_state) + GetSVEBufferSize();
774 error = ReadAllSVE();
776 cached_size +=
sizeof(RegisterSetType) + GetFPRSize();
782 if (GetRegisterInfo().IsMTEPresent()) {
783 cached_size +=
sizeof(RegisterSetType) + GetMTEControlSize();
784 error = ReadMTEControl();
789 if (GetRegisterInfo().IsFPMRPresent()) {
790 cached_size +=
sizeof(RegisterSetType) + GetFPMRBufferSize();
796 if (GetRegisterInfo().IsGCSPresent()) {
797 cached_size +=
sizeof(RegisterSetType) + GetGCSBufferSize();
804 cached_size +=
sizeof(RegisterSetType) + GetTLSBufferSize();
810Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
822 uint32_t reg_data_byte_size = 0;
823 Status error = CacheAllRegisters(reg_data_byte_size);
828 uint8_t *dst = data_sp->GetBytes();
830 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
867 assert(m_za_header.size <= GetZABufferSize());
868 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
872 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) {
873 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
874 *(
reinterpret_cast<SVEState *
>(dst)) = m_sve_state;
875 dst +=
sizeof(m_sve_state);
876 dst = AddSavedRegistersData(dst, GetSVEBuffer(), GetSVEBufferSize());
878 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
883 assert(m_za_header.size <= GetZABufferSize());
884 dst = AddSavedRegisters(dst, RegisterSetType::SME, GetZABuffer(),
895 GetRegisterInfo().IsZTPresent() &&
897 m_za_header.size >
sizeof(m_za_header))
898 dst = AddSavedRegisters(dst, RegisterSetType::SME2, GetZTBuffer(),
901 if (GetRegisterInfo().IsMTEPresent()) {
902 dst = AddSavedRegisters(dst, RegisterSetType::MTE, GetMTEControl(),
903 GetMTEControlSize());
906 if (GetRegisterInfo().IsFPMRPresent()) {
907 dst = AddSavedRegisters(dst, RegisterSetType::FPMR, GetFPMRBuffer(),
908 GetFPMRBufferSize());
911 if (GetRegisterInfo().IsGCSPresent()) {
912 dst = AddSavedRegisters(dst, RegisterSetType::GCS, GetGCSBuffer(),
916 dst = AddSavedRegisters(dst, RegisterSetType::TLS, GetTLSBuffer(),
922static Status RestoreRegisters(
void *buffer,
const uint8_t **src,
size_t len,
923 bool &is_valid, std::function<
Status()> writer) {
924 ::memcpy(buffer, *src, len);
930Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
946 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
951 const uint8_t *src = data_sp->GetBytes();
952 if (src ==
nullptr) {
954 "NativeRegisterContextLinux_arm64::%s "
955 "DataBuffer::GetBytes() returned a null "
961 uint64_t reg_data_min_size =
962 GetGPRBufferSize() + GetFPRSize() + 2 * (
sizeof(RegisterSetType));
963 if (data_sp->GetByteSize() < reg_data_min_size) {
965 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
966 "register data bytes, expected at least %" PRIu64
", actual %" PRIu64,
967 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
971 const uint8_t *end = src + data_sp->GetByteSize();
973 const RegisterSetType kind =
974 *
reinterpret_cast<const RegisterSetType *
>(src);
975 src +=
sizeof(RegisterSetType);
978 case RegisterSetType::GPR:
979 error = RestoreRegisters(
980 GetGPRBuffer(), &src, GetGPRBufferSize(), m_gpr_is_valid,
981 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR,
this));
983 case RegisterSetType::SVE:
985 m_sve_state =
static_cast<SVEState>(*src);
986 src +=
sizeof(m_sve_state);
990 ::memcpy(GetSVEHeader(), src, GetSVEHeaderSize());
992 m_sve_header_is_valid =
false;
994 "NativeRegisterContextLinux_arm64::%s "
995 "Invalid SVE header in data_sp",
999 m_sve_header_is_valid =
true;
1000 error = WriteSVEHeader();
1007 ConfigureRegisterContext();
1010 error = RestoreRegisters(
1011 GetSVEBuffer(), &src, GetSVEBufferSize(), m_sve_buffer_is_valid,
1012 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE,
this));
1014 case RegisterSetType::FPR:
1015 error = RestoreRegisters(
1016 GetFPRBuffer(), &src, GetFPRSize(), m_fpu_is_valid,
1017 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR,
this));
1019 case RegisterSetType::MTE:
1020 error = RestoreRegisters(
1021 GetMTEControl(), &src, GetMTEControlSize(), m_mte_ctrl_is_valid,
1022 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl,
this));
1024 case RegisterSetType::TLS:
1025 error = RestoreRegisters(
1026 GetTLSBuffer(), &src, GetTLSBufferSize(), m_tls_is_valid,
1027 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS,
this));
1029 case RegisterSetType::SME:
1035 ::memcpy(GetZAHeader(), src, GetZAHeaderSize());
1039 m_za_ptrace_payload.resize(m_za_header.size);
1040 ::memcpy(GetZABuffer(), src, GetZABufferSize());
1041 m_za_buffer_is_valid =
true;
1049 ConfigureRegisterContext();
1054 src += GetZABufferSize();
1056 case RegisterSetType::SME2:
1060 error = RestoreRegisters(
1061 GetZTBuffer(), &src, GetZTBufferSize(), m_zt_buffer_is_valid,
1062 std::bind(&NativeRegisterContextLinux_arm64::WriteZT,
this));
1064 case RegisterSetType::FPMR:
1065 error = RestoreRegisters(
1066 GetFPMRBuffer(), &src, GetFPMRBufferSize(), m_fpmr_is_valid,
1067 std::bind(&NativeRegisterContextLinux_arm64::WriteFPMR,
this));
1069 case RegisterSetType::GCS:
1074 m_gcs_is_valid =
false;
1079 uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
1080 gcs_regs new_gcs_regs = *
reinterpret_cast<const gcs_regs *
>(src);
1081 new_gcs_regs.features_enabled =
1082 (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
1084 const uint8_t *new_gcs_src =
1085 reinterpret_cast<const uint8_t *
>(&new_gcs_regs);
1086 error = RestoreRegisters(
1087 GetGCSBuffer(), &new_gcs_src, GetGCSBufferSize(), m_gcs_is_valid,
1088 std::bind(&NativeRegisterContextLinux_arm64::WriteGCS,
this));
1089 src += GetGCSBufferSize();
1101bool NativeRegisterContextLinux_arm64::IsGPR(
unsigned reg)
const {
1102 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
1108bool NativeRegisterContextLinux_arm64::IsFPR(
unsigned reg)
const {
1109 if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
1115bool NativeRegisterContextLinux_arm64::IsSVE(
unsigned reg)
const {
1116 return GetRegisterInfo().IsSVEReg(reg);
1119bool NativeRegisterContextLinux_arm64::IsSME(
unsigned reg)
const {
1120 return GetRegisterInfo().IsSMEReg(reg);
1123bool NativeRegisterContextLinux_arm64::IsPAuth(
unsigned reg)
const {
1124 return GetRegisterInfo().IsPAuthReg(reg);
1127bool NativeRegisterContextLinux_arm64::IsMTE(
unsigned reg)
const {
1128 return GetRegisterInfo().IsMTEReg(reg);
1131bool NativeRegisterContextLinux_arm64::IsTLS(
unsigned reg)
const {
1132 return GetRegisterInfo().IsTLSReg(reg);
1135bool NativeRegisterContextLinux_arm64::IsFPMR(
unsigned reg)
const {
1136 return GetRegisterInfo().IsFPMRReg(reg);
1139bool NativeRegisterContextLinux_arm64::IsGCS(
unsigned reg)
const {
1140 return GetRegisterInfo().IsGCSReg(reg);
1143llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1144 if (!m_refresh_hwdebug_info) {
1145 return llvm::Error::success();
1148 ::pid_t tid = m_thread.GetID();
1151 m_max_hbp_supported);
1153 return error.ToError();
1155 m_refresh_hwdebug_info =
false;
1157 return llvm::Error::success();
1161NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1162 uint32_t max_supported =
1163 (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
1164 auto ®s = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
1170Status NativeRegisterContextLinux_arm64::ReadGPR() {
1177 ioVec.iov_base = GetGPRBuffer();
1178 ioVec.iov_len = GetGPRBufferSize();
1180 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1182 if (
error.Success())
1183 m_gpr_is_valid =
true;
1188Status NativeRegisterContextLinux_arm64::WriteGPR() {
1194 ioVec.iov_base = GetGPRBuffer();
1195 ioVec.iov_len = GetGPRBufferSize();
1197 m_gpr_is_valid =
false;
1199 return WriteRegisterSet(&ioVec, GetGPRBufferSize(), NT_PRSTATUS);
1202Status NativeRegisterContextLinux_arm64::ReadFPR() {
1209 ioVec.iov_base = GetFPRBuffer();
1210 ioVec.iov_len = GetFPRSize();
1212 error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1214 if (
error.Success())
1215 m_fpu_is_valid =
true;
1220Status NativeRegisterContextLinux_arm64::WriteFPR() {
1226 ioVec.iov_base = GetFPRBuffer();
1227 ioVec.iov_len = GetFPRSize();
1229 m_fpu_is_valid =
false;
1231 return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
1234void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1235 m_gpr_is_valid =
false;
1236 m_fpu_is_valid =
false;
1237 m_sve_buffer_is_valid =
false;
1238 m_sve_header_is_valid =
false;
1239 m_za_buffer_is_valid =
false;
1240 m_za_header_is_valid =
false;
1241 m_pac_mask_is_valid =
false;
1242 m_mte_ctrl_is_valid =
false;
1243 m_tls_is_valid =
false;
1244 m_zt_buffer_is_valid =
false;
1245 m_fpmr_is_valid =
false;
1246 m_gcs_is_valid =
false;
1249 ConfigureRegisterContext();
1252unsigned NativeRegisterContextLinux_arm64::GetSVERegSet() {
1256Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1259 if (m_sve_header_is_valid)
1263 ioVec.iov_base = GetSVEHeader();
1264 ioVec.iov_len = GetSVEHeaderSize();
1266 error = ReadRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1268 if (
error.Success())
1269 m_sve_header_is_valid =
true;
1274Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1277 if (m_pac_mask_is_valid)
1281 ioVec.iov_base = GetPACMask();
1282 ioVec.iov_len = GetPACMaskSize();
1284 error = ReadRegisterSet(&ioVec, GetPACMaskSize(), NT_ARM_PAC_MASK);
1286 if (
error.Success())
1287 m_pac_mask_is_valid =
true;
1292Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1295 error = ReadSVEHeader();
1300 ioVec.iov_base = GetSVEHeader();
1301 ioVec.iov_len = GetSVEHeaderSize();
1303 m_sve_buffer_is_valid =
false;
1304 m_sve_header_is_valid =
false;
1305 m_fpu_is_valid =
false;
1307 return WriteRegisterSet(&ioVec, GetSVEHeaderSize(), GetSVERegSet());
1310Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1312 if (m_sve_buffer_is_valid)
1316 ioVec.iov_base = GetSVEBuffer();
1317 ioVec.iov_len = GetSVEBufferSize();
1319 error = ReadRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1321 if (
error.Success())
1322 m_sve_buffer_is_valid =
true;
1327Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1330 error = ReadAllSVE();
1336 ioVec.iov_base = GetSVEBuffer();
1337 ioVec.iov_len = GetSVEBufferSize();
1339 m_sve_buffer_is_valid =
false;
1340 m_sve_header_is_valid =
false;
1341 m_fpu_is_valid =
false;
1343 return WriteRegisterSet(&ioVec, GetSVEBufferSize(), GetSVERegSet());
1346Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1358 if (
error.Success() && (m_za_header.size >
sizeof(m_za_header)))
1359 m_sme_pseudo_regs.ctrl_reg |= 2;
1364Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1367 if (m_mte_ctrl_is_valid)
1371 ioVec.iov_base = GetMTEControl();
1372 ioVec.iov_len = GetMTEControlSize();
1374 error = ReadRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1376 if (
error.Success())
1377 m_mte_ctrl_is_valid =
true;
1382Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1385 error = ReadMTEControl();
1390 ioVec.iov_base = GetMTEControl();
1391 ioVec.iov_len = GetMTEControlSize();
1393 m_mte_ctrl_is_valid =
false;
1395 return WriteRegisterSet(&ioVec, GetMTEControlSize(), NT_ARM_TAGGED_ADDR_CTRL);
1398Status NativeRegisterContextLinux_arm64::ReadTLS() {
1405 ioVec.iov_base = GetTLSBuffer();
1406 ioVec.iov_len = GetTLSBufferSize();
1408 error = ReadRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1410 if (
error.Success())
1411 m_tls_is_valid =
true;
1416Status NativeRegisterContextLinux_arm64::WriteTLS() {
1424 ioVec.iov_base = GetTLSBuffer();
1425 ioVec.iov_len = GetTLSBufferSize();
1427 m_tls_is_valid =
false;
1429 return WriteRegisterSet(&ioVec, GetTLSBufferSize(), NT_ARM_TLS);
1432Status NativeRegisterContextLinux_arm64::ReadGCS() {
1439 ioVec.iov_base = GetGCSBuffer();
1440 ioVec.iov_len = GetGCSBufferSize();
1442 error = ReadRegisterSet(&ioVec, GetGCSBufferSize(), NT_ARM_GCS);
1444 if (
error.Success())
1445 m_gcs_is_valid =
true;
1450Status NativeRegisterContextLinux_arm64::WriteGCS() {
1458 ioVec.iov_base = GetGCSBuffer();
1459 ioVec.iov_len = GetGCSBufferSize();
1461 m_gcs_is_valid =
false;
1463 return WriteRegisterSet(&ioVec, GetGCSBufferSize(), NT_ARM_GCS);
1466Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1469 if (m_za_header_is_valid)
1473 ioVec.iov_base = GetZAHeader();
1474 ioVec.iov_len = GetZAHeaderSize();
1476 error = ReadRegisterSet(&ioVec, GetZAHeaderSize(), NT_ARM_ZA);
1478 if (
error.Success())
1479 m_za_header_is_valid =
true;
1484Status NativeRegisterContextLinux_arm64::ReadZA() {
1487 if (m_za_buffer_is_valid)
1491 ioVec.iov_base = GetZABuffer();
1492 ioVec.iov_len = GetZABufferSize();
1494 error = ReadRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1496 if (
error.Success())
1497 m_za_buffer_is_valid =
true;
1502Status NativeRegisterContextLinux_arm64::WriteZA() {
1513 ioVec.iov_base = GetZABuffer();
1514 ioVec.iov_len = GetZABufferSize();
1516 m_za_buffer_is_valid =
false;
1517 m_za_header_is_valid =
false;
1519 m_zt_buffer_is_valid =
false;
1521 return WriteRegisterSet(&ioVec, GetZABufferSize(), NT_ARM_ZA);
1524Status NativeRegisterContextLinux_arm64::ReadZT() {
1527 if (m_zt_buffer_is_valid)
1531 ioVec.iov_base = GetZTBuffer();
1532 ioVec.iov_len = GetZTBufferSize();
1534 error = ReadRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1535 m_zt_buffer_is_valid =
error.Success();
1540Status NativeRegisterContextLinux_arm64::WriteZT() {
1548 ioVec.iov_base = GetZTBuffer();
1549 ioVec.iov_len = GetZTBufferSize();
1551 m_zt_buffer_is_valid =
false;
1554 m_za_buffer_is_valid =
false;
1555 m_za_header_is_valid =
false;
1557 return WriteRegisterSet(&ioVec, GetZTBufferSize(), NT_ARM_ZT);
1560Status NativeRegisterContextLinux_arm64::ReadFPMR() {
1563 if (m_fpmr_is_valid)
1567 ioVec.iov_base = GetFPMRBuffer();
1568 ioVec.iov_len = GetFPMRBufferSize();
1570 error = ReadRegisterSet(&ioVec, GetFPMRBufferSize(), NT_ARM_FPMR);
1572 if (
error.Success())
1573 m_fpmr_is_valid =
true;
1578Status NativeRegisterContextLinux_arm64::WriteFPMR() {
1586 ioVec.iov_base = GetFPMRBuffer();
1587 ioVec.iov_len = GetFPMRBufferSize();
1589 m_fpmr_is_valid =
false;
1591 return WriteRegisterSet(&ioVec, GetFPMRBufferSize(), NT_ARM_FPMR);
1594void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1606 m_sve_header_is_valid =
false;
1607 m_sve_buffer_is_valid =
false;
1615 m_sve_header_is_valid =
false;
1616 m_sve_buffer_is_valid =
false;
1618 error = ReadSVEHeader();
1619 if (
error.Success()) {
1639 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1644 if (!m_za_header_is_valid) {
1646 if (
error.Success()) {
1651 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1652 m_za_ptrace_payload.resize(m_za_header.size);
1653 m_za_buffer_is_valid =
false;
1658uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1663uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
1670 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
1674 uint32_t sve_z0_offset = GetGPRSize() + 16;
1678 return sve_reg_offset;
1681Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
1685 if (
error.Success())
1686 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
1691std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
1693 std::vector<uint32_t> expedited_reg_nums =
1697 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
1700 if (GetRegisterInfo().IsSSVEPresent())
1701 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
1703 return expedited_reg_nums;
1706llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
1707NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
1709 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
1713 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1714 "Unknown AArch64 memory tag type %d", type);
1717lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
1725 if (ReadPAuthMask().
Success())
1726 mask |= m_pac_mask.data_mask;
1728 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.