9#if defined(__arm64__) || defined(__aarch64__)
30#include "llvm/BinaryFormat/ELF.h"
39#define HWCAP_PACA (1 << 30)
43#define HWCAP_GCS (1UL << 32)
47#define HWCAP2_MTE (1 << 18)
51#define HWCAP2_FPMR (1UL << 48)
55#define HWCAP2_POE (1ULL << 63)
62NativeRegisterContextLinux_arm64::RegisterSetType
63NativeRegisterContextLinux_arm64::GetInvalidationMask(
64 const RegisterSetType set)
const {
66 case RegisterSetType::FPMR:
67 case RegisterSetType::GPR:
68 case RegisterSetType::GCS:
69 case RegisterSetType::MTE:
70 case RegisterSetType::PAC:
71 case RegisterSetType::POE:
72 case RegisterSetType::TLS:
74 case RegisterSetType::SVE_HEADER:
75 case RegisterSetType::SVE:
76 case RegisterSetType::FPR:
77 return RegisterSetType::SVE_HEADER | RegisterSetType::SVE |
80 case RegisterSetType::ZA_HEADER:
81 case RegisterSetType::ZA:
82 case RegisterSetType::ZT:
85 return RegisterSetType::ZA_HEADER | RegisterSetType::ZA |
90unsigned int NativeRegisterContextLinux_arm64::GetPtraceSet(
91 NativeRegisterContextLinux_arm64::RegisterSetType set)
const {
93 case RegisterSetType::GPR:
94 return llvm::ELF::NT_PRSTATUS;
95 case RegisterSetType::FPR:
96 return llvm::ELF::NT_FPREGSET;
97 case RegisterSetType::SVE:
98 case RegisterSetType::SVE_HEADER:
99 switch (m_sve_state) {
102 return llvm::ELF::NT_ARM_SSVE;
104 return llvm::ELF::NT_ARM_SVE;
106 case RegisterSetType::PAC:
107 return llvm::ELF::NT_ARM_PAC_MASK;
108 case RegisterSetType::MTE:
109 return llvm::ELF::NT_ARM_TAGGED_ADDR_CTRL;
110 case RegisterSetType::TLS:
111 return llvm::ELF::NT_ARM_TLS;
112 case RegisterSetType::ZA:
113 case RegisterSetType::ZA_HEADER:
114 return llvm::ELF::NT_ARM_ZA;
115 case RegisterSetType::ZT:
116 return llvm::ELF::NT_ARM_ZT;
117 case RegisterSetType::FPMR:
118 return llvm::ELF::NT_ARM_FPMR;
119 case RegisterSetType::GCS:
120 return llvm::ELF::NT_ARM_GCS;
121 case RegisterSetType::POE:
122 return llvm::ELF::NT_ARM_POE;
126size_t NativeRegisterContextLinux_arm64::GetSetSize(
127 NativeRegisterContextLinux_arm64::RegisterSetType set)
const {
129 case RegisterSetType::GPR:
132 return sizeof(m_gpr_arm64);
133 case RegisterSetType::FPR:
134 return sizeof(m_fpr);
135 case RegisterSetType::SVE:
136 return m_sve_ptrace_payload.size();
137 case RegisterSetType::SVE_HEADER:
138 return sizeof(m_sve_header);
139 case RegisterSetType::PAC:
140 return sizeof(m_pac_mask);
141 case RegisterSetType::MTE:
142 return sizeof(m_mte_ctrl_reg);
143 case RegisterSetType::TLS:
145 case RegisterSetType::ZA:
146 return m_za_ptrace_payload.size();
147 case RegisterSetType::ZA_HEADER:
148 return sizeof(m_za_header);
149 case RegisterSetType::ZT:
150 return m_zt_reg.size();
151 case RegisterSetType::FPMR:
152 return sizeof(m_fpmr_reg);
153 case RegisterSetType::GCS:
154 return sizeof(m_gcs_regs);
155 case RegisterSetType::POE:
156 return sizeof(m_poe_regs);
160void *NativeRegisterContextLinux_arm64::GetSetBuffer(
161 NativeRegisterContextLinux_arm64::RegisterSetType set) {
163 case RegisterSetType::GPR:
165 case RegisterSetType::FPR:
167 case RegisterSetType::SVE:
168 return m_sve_ptrace_payload.data();
169 case RegisterSetType::SVE_HEADER:
170 return &m_sve_header;
171 case RegisterSetType::PAC:
173 case RegisterSetType::MTE:
174 return &m_mte_ctrl_reg;
175 case RegisterSetType::TLS:
177 case RegisterSetType::ZA:
178 return m_za_ptrace_payload.data();
179 case RegisterSetType::ZA_HEADER:
181 case RegisterSetType::ZT:
182 return m_zt_reg.data();
183 case RegisterSetType::FPMR:
185 case RegisterSetType::GCS:
187 case RegisterSetType::POE:
196static std::mutex g_register_type_detector_mutex;
199std::unique_ptr<NativeRegisterContextLinux>
202 switch (target_arch.GetMachine()) {
203 case llvm::Triple::arm:
204 return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
206 case llvm::Triple::aarch64: {
211 ioVec.iov_base = &sve_header;
212 ioVec.iov_len =
sizeof(sve_header);
213 unsigned int regset = llvm::ELF::NT_ARM_SVE;
217 native_thread.
GetID(), ®set,
218 &ioVec,
sizeof(sve_header))
224 ioVec.iov_len =
sizeof(sve_header);
225 regset = llvm::ELF::NT_ARM_SSVE;
227 native_thread.
GetID(), ®set,
228 &ioVec,
sizeof(sve_header))
233 ioVec.iov_base = &za_header;
234 ioVec.iov_len =
sizeof(za_header);
235 regset = llvm::ELF::NT_ARM_ZA;
237 native_thread.
GetID(), ®set,
238 &ioVec,
sizeof(za_header))
243 std::array<uint8_t, 64> zt_reg;
244 ioVec.iov_base = zt_reg.data();
245 ioVec.iov_len = zt_reg.size();
246 regset = llvm::ELF::NT_ARM_ZT;
248 native_thread.
GetID(), ®set,
249 &ioVec, zt_reg.size())
255 std::optional<uint64_t> auxv_at_hwcap =
257 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
260 std::optional<uint64_t> auxv_at_hwcap2 =
262 if (auxv_at_hwcap2) {
275 std::optional<uint64_t> auxv_at_hwcap3 =
277 std::lock_guard<std::mutex> lock(g_register_type_detector_mutex);
279 g_register_type_detector.
DetectTypes(auxv_at_hwcap.value_or(0),
280 auxv_at_hwcap2.value_or(0),
281 auxv_at_hwcap3.value_or(0));
283 auto register_info_up =
284 std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
285 return std::make_unique<NativeRegisterContextLinux_arm64>(
286 target_arch, native_thread, std::move(register_info_up));
289 llvm_unreachable(
"have no register context for architecture");
293llvm::Expected<ArchSpec>
295 return DetermineArchitectureViaGPR(
299NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
301 std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
303 register_info_up.release()),
306 GetRegisterInfoInterface().GetRegisterInfo(),
307 GetRegisterInfoInterface().GetRegisterCount());
310 m_max_hwp_supported = 16;
311 m_max_hbp_supported = 16;
314 m_tls_size = GetRegisterInfo().IsSSVEPresent() ?
sizeof(m_tls_regs)
315 : sizeof(m_tls_regs.tpidr_reg);
317 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
324NativeRegisterContextLinux_arm64::GetRegisterInfo()
const {
328uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount()
const {
333NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index)
const {
334 return GetRegisterInfo().GetRegisterSet(set_index);
337uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount()
const {
339 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
345NativeRegisterContextLinux_arm64::ReadRegister(
const RegisterInfo *reg_info,
358 "no lldb regnum for %s",
359 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
364 std::vector<uint8_t> sve_reg_non_live;
366 if (GetRegisterInfo().IsGPR(reg)) {
372 assert(offset < GetGPRSize());
373 src = (uint8_t *)GetGPRBuffer() + offset;
375 }
else if (GetRegisterInfo().IsFPR(reg)) {
385 offset = CalculateFprOffset(reg_info,
387 assert(offset < GetFPRSize());
388 src = (uint8_t *)GetFPRBuffer() + offset;
393 error = ReadAllSVE();
402 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
408 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
419 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
422 assert(offset < GetSetSize(RegisterSetType::SVE));
423 src = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
425 }
else if (GetRegisterInfo().IsTLSReg(reg)) {
430 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
431 assert(offset < GetSetSize(RegisterSetType::TLS));
432 src = (uint8_t *)GetSetBuffer(RegisterSetType::TLS) + offset;
433 }
else if (GetRegisterInfo().IsSVEReg(reg)) {
437 if (GetRegisterInfo().IsSVERegVG(reg)) {
438 error = ReadSVEHeader();
442 sve_vg = GetSVERegVG();
443 src = (uint8_t *)&sve_vg;
449 if (GetRegisterInfo().IsSVEPReg(reg) ||
450 GetRegisterInfo().IsSVERegFFR(reg)) {
451 std::vector<uint8_t> fake_reg(reg_info->
byte_size, 0);
474 const uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
476 assert(offset < GetFPRSize());
477 src = (uint8_t *)GetFPRBuffer() + offset;
480 std::vector<uint8_t> fake_z(reg_info->
byte_size, 0);
481 std::memcpy(&fake_z[0], src, 16 );
488 error = ReadAllSVE();
496 sve_reg_non_live.resize(reg_info->
byte_size, 0);
497 src = sve_reg_non_live.data();
499 if (GetRegisterInfo().IsSVEZReg(reg)) {
500 offset = CalculateSVEOffset(reg_info);
501 assert(offset < GetSetSize(RegisterSetType::SVE));
502 ::memcpy(sve_reg_non_live.data(),
503 (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset, 16);
506 offset = CalculateSVEOffset(reg_info);
507 assert(offset < GetSetSize(RegisterSetType::SVE));
508 src = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
511 }
else if (GetRegisterInfo().IsPAuthReg(reg)) {
512 error = ReadPAuthMask();
516 offset = reg_info->
byte_offset - GetRegisterInfo().GetPAuthOffset();
517 assert(offset < GetSetSize(RegisterSetType::PAC));
518 src = (uint8_t *)GetSetBuffer(RegisterSetType::PAC) + offset;
519 }
else if (GetRegisterInfo().IsMTEReg(reg)) {
520 error = ReadMTEControl();
524 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
525 assert(offset < GetSetSize(RegisterSetType::MTE));
526 src = (uint8_t *)GetSetBuffer(RegisterSetType::MTE) + offset;
527 }
else if (GetRegisterInfo().IsSMEReg(reg)) {
528 if (GetRegisterInfo().IsSMERegZA(reg)) {
529 error = ReadZAHeader();
535 if (m_za_header.size ==
sizeof(m_za_header)) {
539 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
540 GetSetSize(RegisterSetType::ZA_HEADER));
541 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
552 src = (uint8_t *)GetSetBuffer(RegisterSetType::ZA) +
553 GetSetSize(RegisterSetType::ZA_HEADER);
554 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
562 src = (uint8_t *)GetSetBuffer(RegisterSetType::ZT);
564 error = ReadSMESVG();
571 offset = reg_info->
byte_offset - GetRegisterInfo().GetSMEOffset();
572 assert(offset < GetSMEPseudoBufferSize());
573 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
575 }
else if (GetRegisterInfo().IsFPMRReg(reg)) {
580 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
581 assert(offset < GetSetSize(RegisterSetType::FPMR));
582 src = (uint8_t *)GetSetBuffer(RegisterSetType::FPMR) + offset;
583 }
else if (GetRegisterInfo().IsGCSReg(reg)) {
588 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
589 assert(offset < GetSetSize(RegisterSetType::GCS));
590 src = (uint8_t *)GetSetBuffer(RegisterSetType::GCS) + offset;
591 }
else if (GetRegisterInfo().IsPOEReg(reg)) {
596 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
597 assert(offset < GetSetSize(RegisterSetType::POE));
598 src = (uint8_t *)GetSetBuffer(RegisterSetType::POE) + offset;
601 "failed - register wasn't recognized to be a GPR or an FPR, "
602 "write strategy unknown");
610Status NativeRegisterContextLinux_arm64::WriteRegister(
621 "no lldb regnum for %s",
622 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
626 std::vector<uint8_t> sve_reg_non_live;
628 if (GetRegisterInfo().IsGPR(reg)) {
634 dst = (uint8_t *)GetGPRBuffer() + reg_info->
byte_offset;
638 }
else if (GetRegisterInfo().IsFPR(reg)) {
648 offset = CalculateFprOffset(reg_info,
650 assert(offset < GetFPRSize());
651 dst = (uint8_t *)GetFPRBuffer() + offset;
657 error = ReadAllSVE();
666 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
672 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
683 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
686 assert(offset < GetSetSize(RegisterSetType::SVE));
687 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
689 return WriteAllSVE();
691 }
else if (GetRegisterInfo().IsSVEReg(reg)) {
710 if (GetRegisterInfo().IsSVERegVG(reg) ||
711 GetRegisterInfo().IsSVEPReg(reg) ||
712 GetRegisterInfo().IsSVERegFFR(reg))
714 "Cannot write SVE VG, P or FFR registers while outside of "
726 uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
728 assert(offset < GetFPRSize());
729 dst = (uint8_t *)GetFPRBuffer() + offset;
732 ::memcpy(dst, reg_value.
GetBytes(), 16);
737 error = ReadAllSVE();
741 if (GetRegisterInfo().IsSVERegVG(reg)) {
745 if (IsValid(RegisterSetType::SVE_HEADER) && vg_value == GetSVERegVG())
748 SetSVERegVG(vg_value);
750 error = WriteSVEHeader();
751 if (
error.Success()) {
754 Invalidate(RegisterSetType::ZA_HEADER);
755 ConfigureRegisterContext();
758 if (IsValid(RegisterSetType::SVE_HEADER) && vg_value == GetSVERegVG())
769 bool set_sve_state_full =
false;
770 const uint8_t *reg_bytes = (
const uint8_t *)reg_value.
GetBytes();
771 if (GetRegisterInfo().IsSVEZReg(reg)) {
772 for (uint32_t i = 16; i < reg_info->
byte_size; i++) {
774 set_sve_state_full =
true;
778 }
else if (GetRegisterInfo().IsSVEPReg(reg) ||
779 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
780 for (uint32_t i = 0; i < reg_info->
byte_size; i++) {
782 set_sve_state_full =
true;
788 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
791 offset = CalculateSVEOffset(reg_info);
792 assert(offset < GetSetSize(RegisterSetType::SVE));
793 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
794 ::memcpy(dst, reg_value.
GetBytes(), 16);
796 return WriteAllSVE();
799 "SVE state change operation not supported");
801 offset = CalculateSVEOffset(reg_info);
802 assert(offset < GetSetSize(RegisterSetType::SVE));
803 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
805 return WriteAllSVE();
808 }
else if (GetRegisterInfo().IsMTEReg(reg)) {
809 error = ReadMTEControl();
813 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
814 assert(offset < GetSetSize(RegisterSetType::MTE));
815 dst = (uint8_t *)GetSetBuffer(RegisterSetType::MTE) + offset;
818 return WriteMTEControl();
819 }
else if (GetRegisterInfo().IsTLSReg(reg)) {
824 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
825 assert(offset < GetSetSize(RegisterSetType::TLS));
826 dst = (uint8_t *)GetSetBuffer(RegisterSetType::TLS) + offset;
830 }
else if (GetRegisterInfo().IsSMEReg(reg)) {
831 if (GetRegisterInfo().IsSMERegZA(reg)) {
838 dst = (uint8_t *)GetSetBuffer(RegisterSetType::ZA) +
839 GetSetSize(RegisterSetType::ZA_HEADER);
846 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
851 dst = (uint8_t *)GetSetBuffer(RegisterSetType::ZT);
857 "Writing to SVG or SVCR is not supported.");
858 }
else if (GetRegisterInfo().IsFPMRReg(reg)) {
863 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
864 assert(offset < GetSetSize(RegisterSetType::FPMR));
865 dst = (uint8_t *)GetSetBuffer(RegisterSetType::FPMR) + offset;
869 }
else if (GetRegisterInfo().IsGCSReg(reg)) {
874 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
875 assert(offset < GetSetSize(RegisterSetType::GCS));
876 dst = (uint8_t *)GetSetBuffer(RegisterSetType::GCS) + offset;
880 }
else if (GetRegisterInfo().IsPOEReg(reg)) {
885 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
886 assert(offset < GetSetSize(RegisterSetType::POE));
887 dst = (uint8_t *)GetSetBuffer(RegisterSetType::POE) + offset;
896uint8_t *NativeRegisterContextLinux_arm64::AddRegisterSetType(
897 uint8_t *dst, RegisterSetType register_set_type) {
898 std::memcpy(dst, ®ister_set_type,
sizeof(register_set_type));
899 return dst +
sizeof(RegisterSetType);
902static uint8_t *AddSavedRegistersData(uint8_t *dst,
void *src,
size_t size) {
903 ::memcpy(dst, src, size);
907uint8_t *NativeRegisterContextLinux_arm64::AddSavedRegisters(
908 uint8_t *dst, RegisterSetType register_set_type,
void *src,
size_t size) {
909 dst = AddRegisterSetType(dst, register_set_type);
910 return AddSavedRegistersData(dst, src, size);
914NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
916 cached_size =
sizeof(RegisterSetType) + GetGPRBufferSize();
921 if (GetRegisterInfo().IsZAPresent()) {
922 error = ReadZAHeader();
929 cached_size +=
sizeof(RegisterSetType) + m_za_header.size;
932 Invalidate(RegisterSetType::ZA);
941 GetRegisterInfo().IsZTPresent() &&
943 m_za_header.size >
sizeof(m_za_header)) {
944 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::ZT);
956 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
959 cached_size +=
sizeof(RegisterSetType) +
sizeof(m_sve_state) +
960 GetSetSize(RegisterSetType::SVE);
961 error = ReadAllSVE();
963 cached_size +=
sizeof(RegisterSetType) + GetFPRSize();
969 if (GetRegisterInfo().IsMTEPresent()) {
970 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::MTE);
971 error = ReadMTEControl();
976 if (GetRegisterInfo().IsFPMRPresent()) {
977 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::FPMR);
983 if (GetRegisterInfo().IsGCSPresent()) {
984 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::GCS);
990 if (GetRegisterInfo().IsPOEPresent()) {
991 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::POE);
998 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::TLS);
1004Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
1016 uint32_t reg_data_byte_size = 0;
1017 Status error = CacheAllRegisters(reg_data_byte_size);
1022 uint8_t *dst = data_sp->GetBytes();
1024 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
1025 GetGPRBufferSize());
1061 assert(m_za_header.size <= GetSetSize(RegisterSetType::ZA));
1063 AddSavedRegisters(dst, RegisterSetType::ZA,
1064 GetSetBuffer(RegisterSetType::ZA), m_za_header.size);
1067 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
1069 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
1070 std::memcpy(dst, &m_sve_state,
sizeof(m_sve_state));
1071 dst +=
sizeof(m_sve_state);
1072 dst = AddSavedRegistersData(dst, GetSetBuffer(RegisterSetType::SVE),
1073 GetSetSize(RegisterSetType::SVE));
1075 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
1080 assert(m_za_header.size <= GetSetSize(RegisterSetType::ZA));
1082 AddSavedRegisters(dst, RegisterSetType::ZA,
1083 GetSetBuffer(RegisterSetType::ZA), m_za_header.size);
1093 GetRegisterInfo().IsZTPresent() &&
1095 m_za_header.size >
sizeof(m_za_header))
1096 dst = AddSavedRegisters(dst, RegisterSetType::ZT,
1097 GetSetBuffer(RegisterSetType::ZT),
1098 GetSetSize(RegisterSetType::ZT));
1100 if (GetRegisterInfo().IsMTEPresent()) {
1101 dst = AddSavedRegisters(dst, RegisterSetType::MTE,
1102 GetSetBuffer(RegisterSetType::MTE),
1103 GetSetSize(RegisterSetType::MTE));
1106 if (GetRegisterInfo().IsFPMRPresent()) {
1107 dst = AddSavedRegisters(dst, RegisterSetType::FPMR,
1108 GetSetBuffer(RegisterSetType::FPMR),
1109 GetSetSize(RegisterSetType::FPMR));
1112 if (GetRegisterInfo().IsGCSPresent()) {
1113 dst = AddSavedRegisters(dst, RegisterSetType::GCS,
1114 GetSetBuffer(RegisterSetType::GCS),
1115 GetSetSize(RegisterSetType::GCS));
1118 if (GetRegisterInfo().IsPOEPresent()) {
1119 dst = AddSavedRegisters(dst, RegisterSetType::POE,
1120 GetSetBuffer(RegisterSetType::POE),
1121 GetSetSize(RegisterSetType::POE));
1124 dst = AddSavedRegisters(dst, RegisterSetType::TLS,
1125 GetSetBuffer(RegisterSetType::TLS),
1126 GetSetSize(RegisterSetType::TLS));
1131Status NativeRegisterContextLinux_arm64::RestoreRegisters(
1132 void *buffer,
const uint8_t **src,
size_t len,
1133 const NativeRegisterContextLinux_arm64::RegisterSetType set,
1134 std::function<
Status()> writer) {
1135 ::memcpy(buffer, *src, len);
1141Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
1157 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
1162 const uint8_t *src = data_sp->GetBytes();
1163 if (src ==
nullptr) {
1165 "NativeRegisterContextLinux_arm64::%s "
1166 "DataBuffer::GetBytes() returned a null "
1172 uint64_t reg_data_min_size =
1173 GetGPRBufferSize() + GetFPRSize() + 2 * (
sizeof(RegisterSetType));
1174 if (data_sp->GetByteSize() < reg_data_min_size) {
1176 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
1177 "register data bytes, expected at least %" PRIu64
", actual %" PRIu64,
1178 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
1182 const uint8_t *end = src + data_sp->GetByteSize();
1184 RegisterSetType kind;
1185 std::memcpy(&kind, src,
sizeof(kind));
1186 src +=
sizeof(RegisterSetType);
1189 case RegisterSetType::GPR:
1190 error = RestoreRegisters(
1191 GetGPRBuffer(), &src, GetGPRBufferSize(), kind,
1192 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR,
this));
1194 case RegisterSetType::SVE:
1196 std::memcpy(&m_sve_state, src,
sizeof(m_sve_state));
1197 src +=
sizeof(m_sve_state);
1201 ::memcpy(GetSetBuffer(RegisterSetType::SVE_HEADER), src,
1202 GetSetSize(RegisterSetType::SVE_HEADER));
1204 Invalidate(RegisterSetType::SVE_HEADER);
1206 "NativeRegisterContextLinux_arm64::%s "
1207 "Invalid SVE header in data_sp",
1211 MakeValid(RegisterSetType::SVE_HEADER);
1212 error = WriteSVEHeader();
1219 ConfigureRegisterContext();
1222 error = RestoreRegisters(
1223 GetSetBuffer(RegisterSetType::SVE), &src,
1224 GetSetSize(RegisterSetType::SVE), kind,
1225 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE,
this));
1227 case RegisterSetType::FPR: {
1228 Invalidate(RegisterSetType::SVE_HEADER);
1230 ConfigureRegisterContext();
1234 if (!GetRegisterInfo().IsSVEPresent() &&
1235 GetRegisterInfo().IsSSVEPresent() &&
1253 std::vector<uint8_t> sve_fpsimd_data(data_size);
1258 header->
size = sve_fpsimd_data.size();
1266 ioVec.iov_base = sve_fpsimd_data.data();
1267 ioVec.iov_len = sve_fpsimd_data.size();
1271 error = WriteRegisterSet(&ioVec, sve_fpsimd_data.size(),
1272 llvm::ELF::NT_ARM_SVE);
1275 src += GetFPRSize();
1277 if (
error.Success()) {
1278 Invalidate(RegisterSetType::FPR);
1280 ConfigureRegisterContext();
1285 error = RestoreRegisters(
1286 GetFPRBuffer(), &src, GetFPRSize(), kind,
1287 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR,
this));
1291 case RegisterSetType::MTE:
1292 error = RestoreRegisters(
1293 GetSetBuffer(RegisterSetType::MTE), &src,
1294 GetSetSize(RegisterSetType::MTE), kind,
1295 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl,
this));
1297 case RegisterSetType::TLS:
1298 error = RestoreRegisters(
1299 GetSetBuffer(RegisterSetType::TLS), &src,
1300 GetSetSize(RegisterSetType::TLS), kind,
1301 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS,
this));
1303 case RegisterSetType::ZA:
1309 ::memcpy(GetSetBuffer(RegisterSetType::ZA_HEADER), src,
1310 GetSetSize(RegisterSetType::ZA_HEADER));
1314 m_za_ptrace_payload.resize(m_za_header.size);
1315 ::memcpy(GetSetBuffer(RegisterSetType::ZA), src,
1316 GetSetSize(RegisterSetType::ZA));
1317 MakeValid(RegisterSetType::ZA);
1325 ConfigureRegisterContext();
1330 src += GetSetSize(RegisterSetType::ZA);
1332 case RegisterSetType::ZT:
1336 error = RestoreRegisters(
1337 GetSetBuffer(RegisterSetType::ZT), &src,
1338 GetSetSize(RegisterSetType::ZT), kind,
1339 std::bind(&NativeRegisterContextLinux_arm64::WriteZT,
this));
1341 case RegisterSetType::FPMR:
1342 error = RestoreRegisters(
1343 GetSetBuffer(RegisterSetType::FPMR), &src,
1344 GetSetSize(RegisterSetType::FPMR), kind,
1345 std::bind(&NativeRegisterContextLinux_arm64::WriteFPMR,
this));
1347 case RegisterSetType::GCS: {
1352 Invalidate(RegisterSetType::GCS);
1357 uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
1358 gcs_regs new_gcs_regs;
1359 std::memcpy(&new_gcs_regs, src,
sizeof(new_gcs_regs));
1360 new_gcs_regs.features_enabled =
1361 (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
1363 const uint8_t *new_gcs_src =
1364 reinterpret_cast<const uint8_t *
>(&new_gcs_regs);
1365 error = RestoreRegisters(
1366 GetSetBuffer(RegisterSetType::GCS), &new_gcs_src,
1367 GetSetSize(RegisterSetType::GCS), kind,
1368 std::bind(&NativeRegisterContextLinux_arm64::WriteGCS,
this));
1369 src += GetSetSize(RegisterSetType::GCS);
1373 case RegisterSetType::POE:
1374 error = RestoreRegisters(
1375 GetSetBuffer(RegisterSetType::POE), &src,
1376 GetSetSize(RegisterSetType::POE), kind,
1377 std::bind(&NativeRegisterContextLinux_arm64::WritePOE,
this));
1379 case RegisterSetType::PAC:
1380 case RegisterSetType::SVE_HEADER:
1381 case RegisterSetType::ZA_HEADER:
1393llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1394 if (!m_refresh_hwdebug_info) {
1395 return llvm::Error::success();
1398 ::pid_t tid = m_thread.GetID();
1401 m_max_hbp_supported);
1403 return error.ToError();
1405 m_refresh_hwdebug_info =
false;
1407 return llvm::Error::success();
1411NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1412 uint32_t max_supported =
1413 (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
1414 auto ®s = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
1420Status NativeRegisterContextLinux_arm64::ReadGPR() {
1423 if (IsValid(RegisterSetType::GPR))
1427 ioVec.iov_base = GetGPRBuffer();
1428 ioVec.iov_len = GetGPRBufferSize();
1430 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(),
1431 GetPtraceSet(RegisterSetType::GPR));
1433 if (
error.Success())
1434 MakeValid(RegisterSetType::GPR);
1439Status NativeRegisterContextLinux_arm64::WriteGPR() {
1445 ioVec.iov_base = GetGPRBuffer();
1446 ioVec.iov_len = GetGPRBufferSize();
1448 Invalidate(RegisterSetType::GPR);
1450 return WriteRegisterSet(&ioVec, GetGPRBufferSize(),
1451 GetPtraceSet(RegisterSetType::GPR));
1454Status NativeRegisterContextLinux_arm64::ReadFPR() {
1457 if (IsValid(RegisterSetType::FPR))
1461 ioVec.iov_base = GetFPRBuffer();
1462 ioVec.iov_len = GetFPRSize();
1465 ReadRegisterSet(&ioVec, GetFPRSize(), GetPtraceSet(RegisterSetType::FPR));
1466 if (
error.Success())
1467 MakeValid(RegisterSetType::FPR);
1472Status NativeRegisterContextLinux_arm64::WriteFPR() {
1478 ioVec.iov_base = GetFPRBuffer();
1479 ioVec.iov_len = GetFPRSize();
1481 Invalidate(RegisterSetType::FPR);
1483 return WriteRegisterSet(&ioVec, GetFPRSize(),
1484 GetPtraceSet(RegisterSetType::FPR));
1487void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1488 m_validity =
static_cast<RegisterSetType
>(0);
1491 ConfigureRegisterContext();
1494Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1497 if (IsValid(RegisterSetType::SVE_HEADER))
1501 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE_HEADER);
1502 ioVec.iov_len = GetSetSize(RegisterSetType::SVE_HEADER);
1504 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE_HEADER),
1505 GetPtraceSet(RegisterSetType::SVE_HEADER));
1507 if (
error.Success())
1508 MakeValid(RegisterSetType::SVE_HEADER);
1513Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1516 if (IsValid(RegisterSetType::PAC))
1520 ioVec.iov_base = GetSetBuffer(RegisterSetType::PAC);
1521 ioVec.iov_len = GetSetSize(RegisterSetType::PAC);
1523 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::PAC),
1524 GetPtraceSet(RegisterSetType::PAC));
1526 if (
error.Success())
1527 MakeValid(RegisterSetType::PAC);
1532Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1535 error = ReadSVEHeader();
1540 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE_HEADER);
1541 ioVec.iov_len = GetSetSize(RegisterSetType::SVE_HEADER);
1543 Invalidate(RegisterSetType::SVE_HEADER);
1545 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE_HEADER),
1546 GetPtraceSet(RegisterSetType::SVE_HEADER));
1549Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1551 if (IsValid(RegisterSetType::SVE))
1555 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE);
1556 ioVec.iov_len = GetSetSize(RegisterSetType::SVE);
1558 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE),
1559 GetPtraceSet(RegisterSetType::SVE));
1561 if (
error.Success())
1562 MakeValid(RegisterSetType::SVE);
1567Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1570 error = ReadAllSVE();
1576 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE);
1577 ioVec.iov_len = GetSetSize(RegisterSetType::SVE);
1579 Invalidate(RegisterSetType::SVE);
1581 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE),
1582 GetPtraceSet(RegisterSetType::SVE));
1585Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1597 if (
error.Success() && (m_za_header.size >
sizeof(m_za_header)))
1598 m_sme_pseudo_regs.ctrl_reg |= 2;
1603Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1606 if (IsValid(RegisterSetType::MTE))
1610 ioVec.iov_base = GetSetBuffer(RegisterSetType::MTE);
1611 ioVec.iov_len = GetSetSize(RegisterSetType::MTE);
1613 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::MTE),
1614 GetPtraceSet(RegisterSetType::MTE));
1616 if (
error.Success())
1617 MakeValid(RegisterSetType::MTE);
1622Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1625 error = ReadMTEControl();
1630 ioVec.iov_base = GetSetBuffer(RegisterSetType::MTE);
1631 ioVec.iov_len = GetSetSize(RegisterSetType::MTE);
1633 Invalidate(RegisterSetType::MTE);
1635 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::MTE),
1636 GetPtraceSet(RegisterSetType::MTE));
1639Status NativeRegisterContextLinux_arm64::ReadTLS() {
1642 if (IsValid(RegisterSetType::TLS))
1646 ioVec.iov_base = GetSetBuffer(RegisterSetType::TLS);
1647 ioVec.iov_len = GetSetSize(RegisterSetType::TLS);
1649 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::TLS),
1650 GetPtraceSet(RegisterSetType::TLS));
1652 if (
error.Success())
1653 MakeValid(RegisterSetType::TLS);
1658Status NativeRegisterContextLinux_arm64::WriteTLS() {
1666 ioVec.iov_base = GetSetBuffer(RegisterSetType::TLS);
1667 ioVec.iov_len = GetSetSize(RegisterSetType::TLS);
1669 Invalidate(RegisterSetType::TLS);
1671 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::TLS),
1672 GetPtraceSet(RegisterSetType::TLS));
1675Status NativeRegisterContextLinux_arm64::ReadGCS() {
1678 if (IsValid(RegisterSetType::GCS))
1682 ioVec.iov_base = GetSetBuffer(RegisterSetType::GCS);
1683 ioVec.iov_len = GetSetSize(RegisterSetType::GCS);
1685 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::GCS),
1686 GetPtraceSet(RegisterSetType::GCS));
1688 if (
error.Success())
1689 MakeValid(RegisterSetType::GCS);
1694Status NativeRegisterContextLinux_arm64::WriteGCS() {
1702 ioVec.iov_base = GetSetBuffer(RegisterSetType::GCS);
1703 ioVec.iov_len = GetSetSize(RegisterSetType::GCS);
1705 Invalidate(RegisterSetType::GCS);
1707 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::GCS),
1708 GetPtraceSet(RegisterSetType::GCS));
1711Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1714 if (IsValid(RegisterSetType::ZA_HEADER))
1718 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA_HEADER);
1719 ioVec.iov_len = GetSetSize(RegisterSetType::ZA_HEADER);
1721 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA_HEADER),
1722 GetPtraceSet(RegisterSetType::ZA));
1724 if (
error.Success())
1725 MakeValid(RegisterSetType::ZA_HEADER);
1730Status NativeRegisterContextLinux_arm64::ReadZA() {
1733 if (IsValid(RegisterSetType::ZA))
1737 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA);
1738 ioVec.iov_len = GetSetSize(RegisterSetType::ZA);
1740 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA),
1741 GetPtraceSet(RegisterSetType::ZA));
1743 if (
error.Success())
1744 MakeValid(RegisterSetType::ZA);
1749Status NativeRegisterContextLinux_arm64::WriteZA() {
1760 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA);
1761 ioVec.iov_len = GetSetSize(RegisterSetType::ZA);
1763 Invalidate(RegisterSetType::ZA);
1765 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA),
1766 GetPtraceSet(RegisterSetType::ZA));
1769Status NativeRegisterContextLinux_arm64::ReadZT() {
1772 if (IsValid(RegisterSetType::ZT))
1776 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZT);
1777 ioVec.iov_len = GetSetSize(RegisterSetType::ZT);
1779 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZT),
1780 GetPtraceSet(RegisterSetType::ZT));
1781 if (
error.Success())
1782 MakeValid(RegisterSetType::ZT);
1787Status NativeRegisterContextLinux_arm64::WriteZT() {
1795 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZT);
1796 ioVec.iov_len = GetSetSize(RegisterSetType::ZT);
1798 Invalidate(RegisterSetType::ZT);
1800 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZT),
1801 GetPtraceSet(RegisterSetType::ZT));
1804Status NativeRegisterContextLinux_arm64::ReadFPMR() {
1807 if (IsValid(RegisterSetType::FPMR))
1811 ioVec.iov_base = GetSetBuffer(RegisterSetType::FPMR);
1812 ioVec.iov_len = GetSetSize(RegisterSetType::FPMR);
1814 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::FPMR),
1815 GetPtraceSet(RegisterSetType::FPMR));
1817 if (
error.Success())
1818 MakeValid(RegisterSetType::FPMR);
1823Status NativeRegisterContextLinux_arm64::WriteFPMR() {
1831 ioVec.iov_base = GetSetBuffer(RegisterSetType::FPMR);
1832 ioVec.iov_len = GetSetSize(RegisterSetType::FPMR);
1834 Invalidate(RegisterSetType::FPMR);
1836 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::FPMR),
1837 GetPtraceSet(RegisterSetType::FPMR));
1840Status NativeRegisterContextLinux_arm64::ReadPOE() {
1843 if (IsValid(RegisterSetType::POE))
1847 ioVec.iov_base = GetSetBuffer(RegisterSetType::POE);
1848 ioVec.iov_len = GetSetSize(RegisterSetType::POE);
1850 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::POE),
1851 GetPtraceSet(RegisterSetType::POE));
1853 if (
error.Success())
1854 MakeValid(RegisterSetType::POE);
1859Status NativeRegisterContextLinux_arm64::WritePOE() {
1867 ioVec.iov_base = GetSetBuffer(RegisterSetType::POE);
1868 ioVec.iov_len = GetSetSize(RegisterSetType::POE);
1870 Invalidate(RegisterSetType::POE);
1872 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::POE),
1873 GetPtraceSet(RegisterSetType::POE));
1876void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1882 if (!IsValid(RegisterSetType::SVE_HEADER) &&
1889 Invalidate(RegisterSetType::SVE_HEADER);
1893 bool has_sme =
error.Success();
1894 bool sme_is_active =
1899 Invalidate(RegisterSetType::SVE_HEADER);
1901 error = ReadSVEHeader();
1903 bool has_sve =
error.Success();
1904 bool sve_is_active =
1915 else if (sve_is_active)
1917 else if (fp_is_active)
1928 Invalidate(RegisterSetType::SVE_HEADER);
1929 error = ReadSVEHeader();
1937 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1942 if (!IsValid(RegisterSetType::ZA_HEADER)) {
1944 if (
error.Success()) {
1949 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1950 m_za_ptrace_payload.resize(m_za_header.size);
1951 Invalidate(RegisterSetType::ZA);
1956uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1957 const RegisterInfo *reg_info,
bool streaming_fpsimd)
const {
1958 uint32_t offset = reg_info->
byte_offset - GetGPRSize();
1959 if (!streaming_fpsimd)
1971 const size_t fpsr_offset = 16 * 32;
1973 if (reg == GetRegisterInfo().GetRegNumFPSR())
1974 offset = fpsr_offset;
1975 else if (reg == GetRegisterInfo().GetRegNumFPCR())
1976 offset = fpsr_offset + 4;
1978 offset = 16 * (reg - GetRegisterInfo().GetRegNumFPV0());
1983uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
1990 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
1994 uint32_t sve_z0_offset = GetGPRSize() + 16;
1998 return sve_reg_offset;
2001Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
2005 if (
error.Success())
2006 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
2011std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
2013 std::vector<uint32_t> expedited_reg_nums =
2017 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
2020 if (GetRegisterInfo().IsSSVEPresent())
2021 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
2023 return expedited_reg_nums;
2026llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
2027NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
2029 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
2033 return llvm::createStringError(llvm::inconvertibleErrorCode(),
2034 "Unknown AArch64 memory tag type %d", type);
2037lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
2045 if (ReadPAuthMask().
Success())
2046 mask |= m_pac_mask.data_mask;
2048 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 type information.
bool HasDetected() const
Returns true if field detection has been run at least once.
void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs)
Add the type information of any registers named in this class, to the relevant RegisterInfo instances...
void DetectTypes(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
For the registers listed in this class, detect which fields are present and build types for those.
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.