9#if defined(__arm64__) || defined(__aarch64__)
27#include "llvm/BinaryFormat/ELF.h"
34#include <sys/ptrace.h>
38#define HWCAP_PACA (1 << 30)
42#define HWCAP_GCS (1UL << 32)
46#define HWCAP2_MTE (1 << 18)
50#define HWCAP2_FPMR (1UL << 48)
54#define HWCAP2_POE (1ULL << 63)
57#ifndef PTRACE_GETREGSET
58#define PTRACE_GETREGSET 0x4204
61#ifndef PTRACE_PEEKMTETAGS
62#define PTRACE_PEEKMTETAGS 33
65#ifndef PTRACE_POKEMTETAGS
66#define PTRACE_POKEMTETAGS 34
73NativeRegisterContextLinux_arm64::RegisterSetType
74NativeRegisterContextLinux_arm64::GetInvalidationMask(
75 const RegisterSetType set)
const {
77 case RegisterSetType::FPMR:
78 case RegisterSetType::GPR:
79 case RegisterSetType::GCS:
80 case RegisterSetType::MTE:
81 case RegisterSetType::PAC:
82 case RegisterSetType::POE:
83 case RegisterSetType::TLS:
85 case RegisterSetType::SVE_HEADER:
86 case RegisterSetType::SVE:
87 case RegisterSetType::FPR:
88 return RegisterSetType::SVE_HEADER | RegisterSetType::SVE |
91 case RegisterSetType::ZA_HEADER:
92 case RegisterSetType::ZA:
93 case RegisterSetType::ZT:
96 return RegisterSetType::ZA_HEADER | RegisterSetType::ZA |
101unsigned int NativeRegisterContextLinux_arm64::GetPtraceSet(
102 NativeRegisterContextLinux_arm64::RegisterSetType set)
const {
104 case RegisterSetType::GPR:
105 return llvm::ELF::NT_PRSTATUS;
106 case RegisterSetType::FPR:
107 return llvm::ELF::NT_FPREGSET;
108 case RegisterSetType::SVE:
109 case RegisterSetType::SVE_HEADER:
110 switch (m_sve_state) {
113 return llvm::ELF::NT_ARM_SSVE;
115 return llvm::ELF::NT_ARM_SVE;
117 case RegisterSetType::PAC:
118 return llvm::ELF::NT_ARM_PAC_MASK;
119 case RegisterSetType::MTE:
120 return llvm::ELF::NT_ARM_TAGGED_ADDR_CTRL;
121 case RegisterSetType::TLS:
122 return llvm::ELF::NT_ARM_TLS;
123 case RegisterSetType::ZA:
124 case RegisterSetType::ZA_HEADER:
125 return llvm::ELF::NT_ARM_ZA;
126 case RegisterSetType::ZT:
127 return llvm::ELF::NT_ARM_ZT;
128 case RegisterSetType::FPMR:
129 return llvm::ELF::NT_ARM_FPMR;
130 case RegisterSetType::GCS:
131 return llvm::ELF::NT_ARM_GCS;
132 case RegisterSetType::POE:
133 return llvm::ELF::NT_ARM_POE;
136 llvm_unreachable(
"No ptrace set for this RegisterType.");
139size_t NativeRegisterContextLinux_arm64::GetSetSize(
140 NativeRegisterContextLinux_arm64::RegisterSetType set)
const {
142 case RegisterSetType::GPR:
145 return sizeof(m_gpr_arm64);
146 case RegisterSetType::FPR:
147 return sizeof(m_fpr);
148 case RegisterSetType::SVE:
149 return m_sve_ptrace_payload.size();
150 case RegisterSetType::SVE_HEADER:
151 return sizeof(m_sve_header);
152 case RegisterSetType::PAC:
153 return sizeof(m_pac_mask);
154 case RegisterSetType::MTE:
155 return sizeof(m_mte_ctrl_reg);
156 case RegisterSetType::TLS:
158 case RegisterSetType::ZA:
159 return m_za_ptrace_payload.size();
160 case RegisterSetType::ZA_HEADER:
161 return sizeof(m_za_header);
162 case RegisterSetType::ZT:
163 return m_zt_reg.size();
164 case RegisterSetType::FPMR:
165 return sizeof(m_fpmr_reg);
166 case RegisterSetType::GCS:
167 return sizeof(m_gcs_regs);
168 case RegisterSetType::POE:
169 return sizeof(m_poe_regs);
172 llvm_unreachable(
"No set size for this RegisterType.");
175void *NativeRegisterContextLinux_arm64::GetSetBuffer(
176 NativeRegisterContextLinux_arm64::RegisterSetType set) {
178 case RegisterSetType::GPR:
180 case RegisterSetType::FPR:
182 case RegisterSetType::SVE:
183 return m_sve_ptrace_payload.data();
184 case RegisterSetType::SVE_HEADER:
185 return &m_sve_header;
186 case RegisterSetType::PAC:
188 case RegisterSetType::MTE:
189 return &m_mte_ctrl_reg;
190 case RegisterSetType::TLS:
192 case RegisterSetType::ZA:
193 return m_za_ptrace_payload.data();
194 case RegisterSetType::ZA_HEADER:
196 case RegisterSetType::ZT:
197 return m_zt_reg.data();
198 case RegisterSetType::FPMR:
200 case RegisterSetType::GCS:
202 case RegisterSetType::POE:
206 llvm_unreachable(
"No set buffer for this RegisterType.");
213static std::mutex g_register_type_detector_mutex;
216std::unique_ptr<NativeRegisterContextLinux>
220 case llvm::Triple::arm:
221 return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
223 case llvm::Triple::aarch64: {
228 ioVec.iov_base = &sve_header;
229 ioVec.iov_len =
sizeof(sve_header);
230 unsigned int regset = llvm::ELF::NT_ARM_SVE;
234 native_thread.
GetID(), ®set,
235 &ioVec,
sizeof(sve_header))
241 ioVec.iov_len =
sizeof(sve_header);
242 regset = llvm::ELF::NT_ARM_SSVE;
244 native_thread.
GetID(), ®set,
245 &ioVec,
sizeof(sve_header))
250 ioVec.iov_base = &za_header;
251 ioVec.iov_len =
sizeof(za_header);
252 regset = llvm::ELF::NT_ARM_ZA;
254 native_thread.
GetID(), ®set,
255 &ioVec,
sizeof(za_header))
260 std::array<uint8_t, 64> zt_reg;
261 ioVec.iov_base = zt_reg.data();
262 ioVec.iov_len = zt_reg.size();
263 regset = llvm::ELF::NT_ARM_ZT;
265 native_thread.
GetID(), ®set,
266 &ioVec, zt_reg.size())
272 std::optional<uint64_t> auxv_at_hwcap =
274 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
277 std::optional<uint64_t> auxv_at_hwcap2 =
279 if (auxv_at_hwcap2) {
292 std::optional<uint64_t> auxv_at_hwcap3 =
294 std::lock_guard<std::mutex> lock(g_register_type_detector_mutex);
296 g_register_type_detector.
DetectTypes(auxv_at_hwcap.value_or(0),
297 auxv_at_hwcap2.value_or(0),
298 auxv_at_hwcap3.value_or(0));
300 auto register_info_up =
301 std::make_unique<RegisterInfo_arm64>(target_arch, opt_regsets);
302 return std::make_unique<NativeRegisterContextLinux_arm64>(
303 target_arch, native_thread, std::move(register_info_up));
306 llvm_unreachable(
"have no register context for architecture");
310llvm::Expected<ArchSpec>
312 return DetermineArchitectureViaGPR(
316NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
318 std::unique_ptr<RegisterInfo_arm64> register_info_up)
320 register_info_up.release()),
323 GetRegisterInfoInterface().GetRegisterInfo(),
324 GetRegisterInfoInterface().GetRegisterCount());
327 m_max_hwp_supported = 16;
328 m_max_hbp_supported = 16;
331 m_tls_size = GetRegisterInfo().IsSSVEPresent() ?
sizeof(m_tls_regs)
332 : sizeof(m_tls_regs.tpidr_reg);
334 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
341NativeRegisterContextLinux_arm64::GetRegisterInfo()
const {
345uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount()
const {
350NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index)
const {
351 return GetRegisterInfo().GetRegisterSet(set_index);
354uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount()
const {
356 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
362NativeRegisterContextLinux_arm64::ReadRegister(
const RegisterInfo *reg_info,
375 "no lldb regnum for %s",
376 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
381 std::vector<uint8_t> sve_reg_non_live;
383 if (GetRegisterInfo().IsGPR(reg)) {
389 assert(offset < GetGPRSize());
390 src = (uint8_t *)GetGPRBuffer() + offset;
392 }
else if (GetRegisterInfo().IsFPR(reg)) {
402 offset = CalculateFprOffset(reg_info,
404 assert(offset < GetFPRSize());
405 src = (uint8_t *)GetFPRBuffer() + offset;
410 error = ReadAllSVE();
419 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
425 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
436 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
439 assert(offset < GetSetSize(RegisterSetType::SVE));
440 src = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
442 }
else if (GetRegisterInfo().IsTLSReg(reg)) {
447 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
448 assert(offset < GetSetSize(RegisterSetType::TLS));
449 src = (uint8_t *)GetSetBuffer(RegisterSetType::TLS) + offset;
450 }
else if (GetRegisterInfo().IsSVEReg(reg)) {
454 if (GetRegisterInfo().IsSVERegVG(reg)) {
455 error = ReadSVEHeader();
459 sve_vg = GetSVERegVG();
460 src = (uint8_t *)&sve_vg;
466 if (GetRegisterInfo().IsSVEPReg(reg) ||
467 GetRegisterInfo().IsSVERegFFR(reg)) {
468 std::vector<uint8_t> fake_reg(reg_info->
byte_size, 0);
491 const uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
493 assert(offset < GetFPRSize());
494 src = (uint8_t *)GetFPRBuffer() + offset;
497 std::vector<uint8_t> fake_z(reg_info->
byte_size, 0);
498 std::memcpy(&fake_z[0], src, 16 );
505 error = ReadAllSVE();
513 sve_reg_non_live.resize(reg_info->
byte_size, 0);
514 src = sve_reg_non_live.data();
516 if (GetRegisterInfo().IsSVEZReg(reg)) {
517 offset = CalculateSVEOffset(reg_info);
518 assert(offset < GetSetSize(RegisterSetType::SVE));
519 ::memcpy(sve_reg_non_live.data(),
520 (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset, 16);
523 offset = CalculateSVEOffset(reg_info);
524 assert(offset < GetSetSize(RegisterSetType::SVE));
525 src = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
528 }
else if (GetRegisterInfo().IsPAuthReg(reg)) {
529 error = ReadPAuthMask();
533 offset = reg_info->
byte_offset - GetRegisterInfo().GetPAuthOffset();
534 assert(offset < GetSetSize(RegisterSetType::PAC));
535 src = (uint8_t *)GetSetBuffer(RegisterSetType::PAC) + offset;
536 }
else if (GetRegisterInfo().IsMTEReg(reg)) {
537 error = ReadMTEControl();
541 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
542 assert(offset < GetSetSize(RegisterSetType::MTE));
543 src = (uint8_t *)GetSetBuffer(RegisterSetType::MTE) + offset;
544 }
else if (GetRegisterInfo().IsSMEReg(reg)) {
545 if (GetRegisterInfo().IsSMERegZA(reg)) {
546 error = ReadZAHeader();
552 if (m_za_header.size ==
sizeof(m_za_header)) {
556 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
557 GetSetSize(RegisterSetType::ZA_HEADER));
558 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
569 src = (uint8_t *)GetSetBuffer(RegisterSetType::ZA) +
570 GetSetSize(RegisterSetType::ZA_HEADER);
571 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
579 src = (uint8_t *)GetSetBuffer(RegisterSetType::ZT);
581 error = ReadSMESVG();
588 offset = reg_info->
byte_offset - GetRegisterInfo().GetSMEOffset();
589 assert(offset < GetSMEPseudoBufferSize());
590 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
592 }
else if (GetRegisterInfo().IsFPMRReg(reg)) {
597 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
598 assert(offset < GetSetSize(RegisterSetType::FPMR));
599 src = (uint8_t *)GetSetBuffer(RegisterSetType::FPMR) + offset;
600 }
else if (GetRegisterInfo().IsGCSReg(reg)) {
605 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
606 assert(offset < GetSetSize(RegisterSetType::GCS));
607 src = (uint8_t *)GetSetBuffer(RegisterSetType::GCS) + offset;
608 }
else if (GetRegisterInfo().IsPOEReg(reg)) {
613 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
614 assert(offset < GetSetSize(RegisterSetType::POE));
615 src = (uint8_t *)GetSetBuffer(RegisterSetType::POE) + offset;
618 "failed - register wasn't recognized to be a GPR or an FPR, "
619 "write strategy unknown");
627Status NativeRegisterContextLinux_arm64::WriteRegister(
638 "no lldb regnum for %s",
639 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
644 if (GetRegisterInfo().IsGPR(reg)) {
650 dst = (uint8_t *)GetGPRBuffer() + reg_info->
byte_offset;
654 }
else if (GetRegisterInfo().IsFPR(reg)) {
664 offset = CalculateFprOffset(reg_info,
666 assert(offset < GetFPRSize());
667 dst = (uint8_t *)GetFPRBuffer() + offset;
673 error = ReadAllSVE();
682 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
688 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
699 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
702 assert(offset < GetSetSize(RegisterSetType::SVE));
703 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
705 return WriteAllSVE();
707 }
else if (GetRegisterInfo().IsSVEReg(reg)) {
726 if (GetRegisterInfo().IsSVERegVG(reg) ||
727 GetRegisterInfo().IsSVEPReg(reg) ||
728 GetRegisterInfo().IsSVERegFFR(reg))
730 "Cannot write SVE VG, P or FFR registers while outside of "
742 uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
744 assert(offset < GetFPRSize());
745 dst = (uint8_t *)GetFPRBuffer() + offset;
748 ::memcpy(dst, reg_value.
GetBytes(), 16);
753 error = ReadAllSVE();
757 if (GetRegisterInfo().IsSVERegVG(reg)) {
761 if (IsValid(RegisterSetType::SVE_HEADER) && vg_value == GetSVERegVG())
764 SetSVERegVG(vg_value);
766 error = WriteSVEHeader();
767 if (
error.Success()) {
770 Invalidate(RegisterSetType::ZA_HEADER);
771 ConfigureRegisterContext();
774 if (IsValid(RegisterSetType::SVE_HEADER) && vg_value == GetSVERegVG())
785 bool set_sve_state_full =
false;
786 const uint8_t *reg_bytes = (
const uint8_t *)reg_value.
GetBytes();
787 if (GetRegisterInfo().IsSVEZReg(reg)) {
788 for (uint32_t i = 16; i < reg_info->
byte_size; i++) {
790 set_sve_state_full =
true;
794 }
else if (GetRegisterInfo().IsSVEPReg(reg) ||
795 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
796 for (uint32_t i = 0; i < reg_info->
byte_size; i++) {
798 set_sve_state_full =
true;
804 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
807 offset = CalculateSVEOffset(reg_info);
808 assert(offset < GetSetSize(RegisterSetType::SVE));
809 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
810 ::memcpy(dst, reg_value.
GetBytes(), 16);
812 return WriteAllSVE();
815 "SVE state change operation not supported");
817 offset = CalculateSVEOffset(reg_info);
818 assert(offset < GetSetSize(RegisterSetType::SVE));
819 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
821 return WriteAllSVE();
824 }
else if (GetRegisterInfo().IsMTEReg(reg)) {
825 error = ReadMTEControl();
829 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
830 assert(offset < GetSetSize(RegisterSetType::MTE));
831 dst = (uint8_t *)GetSetBuffer(RegisterSetType::MTE) + offset;
834 return WriteMTEControl();
835 }
else if (GetRegisterInfo().IsTLSReg(reg)) {
840 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
841 assert(offset < GetSetSize(RegisterSetType::TLS));
842 dst = (uint8_t *)GetSetBuffer(RegisterSetType::TLS) + offset;
846 }
else if (GetRegisterInfo().IsSMEReg(reg)) {
847 if (GetRegisterInfo().IsSMERegZA(reg)) {
854 dst = (uint8_t *)GetSetBuffer(RegisterSetType::ZA) +
855 GetSetSize(RegisterSetType::ZA_HEADER);
862 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
867 dst = (uint8_t *)GetSetBuffer(RegisterSetType::ZT);
873 "Writing to SVG or SVCR is not supported.");
874 }
else if (GetRegisterInfo().IsFPMRReg(reg)) {
879 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
880 assert(offset < GetSetSize(RegisterSetType::FPMR));
881 dst = (uint8_t *)GetSetBuffer(RegisterSetType::FPMR) + offset;
885 }
else if (GetRegisterInfo().IsGCSReg(reg)) {
890 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
891 assert(offset < GetSetSize(RegisterSetType::GCS));
892 dst = (uint8_t *)GetSetBuffer(RegisterSetType::GCS) + offset;
896 }
else if (GetRegisterInfo().IsPOEReg(reg)) {
901 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
902 assert(offset < GetSetSize(RegisterSetType::POE));
903 dst = (uint8_t *)GetSetBuffer(RegisterSetType::POE) + offset;
912uint8_t *NativeRegisterContextLinux_arm64::AddRegisterSetType(
913 uint8_t *dst, RegisterSetType register_set_type) {
914 std::memcpy(dst, ®ister_set_type,
sizeof(register_set_type));
915 return dst +
sizeof(RegisterSetType);
918static uint8_t *AddSavedRegistersData(uint8_t *dst,
void *src,
size_t size) {
919 ::memcpy(dst, src, size);
923uint8_t *NativeRegisterContextLinux_arm64::AddSavedRegisters(
924 uint8_t *dst, RegisterSetType register_set_type,
void *src,
size_t size) {
925 dst = AddRegisterSetType(dst, register_set_type);
926 return AddSavedRegistersData(dst, src, size);
930NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
932 cached_size =
sizeof(RegisterSetType) + GetGPRBufferSize();
937 if (GetRegisterInfo().IsZAPresent()) {
938 error = ReadZAHeader();
945 cached_size +=
sizeof(RegisterSetType) + m_za_header.size;
948 Invalidate(RegisterSetType::ZA);
957 GetRegisterInfo().IsZTPresent() &&
959 m_za_header.size >
sizeof(m_za_header)) {
960 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::ZT);
972 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
975 cached_size +=
sizeof(RegisterSetType) +
sizeof(m_sve_state) +
976 GetSetSize(RegisterSetType::SVE);
977 error = ReadAllSVE();
979 cached_size +=
sizeof(RegisterSetType) + GetFPRSize();
985 if (GetRegisterInfo().IsMTEPresent()) {
986 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::MTE);
987 error = ReadMTEControl();
992 if (GetRegisterInfo().IsFPMRPresent()) {
993 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::FPMR);
999 if (GetRegisterInfo().IsGCSPresent()) {
1000 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::GCS);
1006 if (GetRegisterInfo().IsPOEPresent()) {
1007 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::POE);
1014 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::TLS);
1020Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
1032 uint32_t reg_data_byte_size = 0;
1033 Status error = CacheAllRegisters(reg_data_byte_size);
1038 uint8_t *dst = data_sp->GetBytes();
1040 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
1041 GetGPRBufferSize());
1077 assert(m_za_header.size <= GetSetSize(RegisterSetType::ZA));
1079 AddSavedRegisters(dst, RegisterSetType::ZA,
1080 GetSetBuffer(RegisterSetType::ZA), m_za_header.size);
1083 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
1085 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
1086 std::memcpy(dst, &m_sve_state,
sizeof(m_sve_state));
1087 dst +=
sizeof(m_sve_state);
1088 dst = AddSavedRegistersData(dst, GetSetBuffer(RegisterSetType::SVE),
1089 GetSetSize(RegisterSetType::SVE));
1091 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
1096 assert(m_za_header.size <= GetSetSize(RegisterSetType::ZA));
1098 AddSavedRegisters(dst, RegisterSetType::ZA,
1099 GetSetBuffer(RegisterSetType::ZA), m_za_header.size);
1109 GetRegisterInfo().IsZTPresent() &&
1111 m_za_header.size >
sizeof(m_za_header))
1112 dst = AddSavedRegisters(dst, RegisterSetType::ZT,
1113 GetSetBuffer(RegisterSetType::ZT),
1114 GetSetSize(RegisterSetType::ZT));
1116 if (GetRegisterInfo().IsMTEPresent()) {
1117 dst = AddSavedRegisters(dst, RegisterSetType::MTE,
1118 GetSetBuffer(RegisterSetType::MTE),
1119 GetSetSize(RegisterSetType::MTE));
1122 if (GetRegisterInfo().IsFPMRPresent()) {
1123 dst = AddSavedRegisters(dst, RegisterSetType::FPMR,
1124 GetSetBuffer(RegisterSetType::FPMR),
1125 GetSetSize(RegisterSetType::FPMR));
1128 if (GetRegisterInfo().IsGCSPresent()) {
1129 dst = AddSavedRegisters(dst, RegisterSetType::GCS,
1130 GetSetBuffer(RegisterSetType::GCS),
1131 GetSetSize(RegisterSetType::GCS));
1134 if (GetRegisterInfo().IsPOEPresent()) {
1135 dst = AddSavedRegisters(dst, RegisterSetType::POE,
1136 GetSetBuffer(RegisterSetType::POE),
1137 GetSetSize(RegisterSetType::POE));
1140 dst = AddSavedRegisters(dst, RegisterSetType::TLS,
1141 GetSetBuffer(RegisterSetType::TLS),
1142 GetSetSize(RegisterSetType::TLS));
1147Status NativeRegisterContextLinux_arm64::RestoreRegisters(
1148 void *buffer,
const uint8_t **src,
size_t len,
1149 const NativeRegisterContextLinux_arm64::RegisterSetType set,
1150 std::function<
Status()> writer) {
1151 ::memcpy(buffer, *src, len);
1157Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
1173 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
1178 const uint8_t *src = data_sp->GetBytes();
1179 if (src ==
nullptr) {
1181 "NativeRegisterContextLinux_arm64::%s "
1182 "DataBuffer::GetBytes() returned a null "
1188 uint64_t reg_data_min_size =
1189 GetGPRBufferSize() + GetFPRSize() + 2 * (
sizeof(RegisterSetType));
1190 if (data_sp->GetByteSize() < reg_data_min_size) {
1192 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
1193 "register data bytes, expected at least %" PRIu64
", actual %" PRIu64,
1194 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
1198 const uint8_t *end = src + data_sp->GetByteSize();
1200 RegisterSetType kind;
1201 std::memcpy(&kind, src,
sizeof(kind));
1202 src +=
sizeof(RegisterSetType);
1205 case RegisterSetType::GPR:
1206 error = RestoreRegisters(
1207 GetGPRBuffer(), &src, GetGPRBufferSize(), kind,
1208 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR,
this));
1210 case RegisterSetType::SVE:
1212 std::memcpy(&m_sve_state, src,
sizeof(m_sve_state));
1213 src +=
sizeof(m_sve_state);
1217 ::memcpy(GetSetBuffer(RegisterSetType::SVE_HEADER), src,
1218 GetSetSize(RegisterSetType::SVE_HEADER));
1220 Invalidate(RegisterSetType::SVE_HEADER);
1222 "NativeRegisterContextLinux_arm64::%s "
1223 "Invalid SVE header in data_sp",
1227 MakeValid(RegisterSetType::SVE_HEADER);
1228 error = WriteSVEHeader();
1235 ConfigureRegisterContext();
1238 error = RestoreRegisters(
1239 GetSetBuffer(RegisterSetType::SVE), &src,
1240 GetSetSize(RegisterSetType::SVE), kind,
1241 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE,
this));
1243 case RegisterSetType::FPR: {
1244 Invalidate(RegisterSetType::SVE_HEADER);
1246 ConfigureRegisterContext();
1250 if (!GetRegisterInfo().IsSVEPresent() &&
1251 GetRegisterInfo().IsSSVEPresent() &&
1269 std::vector<uint8_t> sve_fpsimd_data(data_size);
1274 header->
size = sve_fpsimd_data.size();
1282 ioVec.iov_base = sve_fpsimd_data.data();
1283 ioVec.iov_len = sve_fpsimd_data.size();
1287 error = WriteRegisterSet(&ioVec, sve_fpsimd_data.size(),
1288 llvm::ELF::NT_ARM_SVE);
1291 src += GetFPRSize();
1293 if (
error.Success()) {
1294 Invalidate(RegisterSetType::FPR);
1296 ConfigureRegisterContext();
1301 error = RestoreRegisters(
1302 GetFPRBuffer(), &src, GetFPRSize(), kind,
1303 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR,
this));
1307 case RegisterSetType::MTE:
1308 error = RestoreRegisters(
1309 GetSetBuffer(RegisterSetType::MTE), &src,
1310 GetSetSize(RegisterSetType::MTE), kind,
1311 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl,
this));
1313 case RegisterSetType::TLS:
1314 error = RestoreRegisters(
1315 GetSetBuffer(RegisterSetType::TLS), &src,
1316 GetSetSize(RegisterSetType::TLS), kind,
1317 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS,
this));
1319 case RegisterSetType::ZA:
1325 ::memcpy(GetSetBuffer(RegisterSetType::ZA_HEADER), src,
1326 GetSetSize(RegisterSetType::ZA_HEADER));
1330 m_za_ptrace_payload.resize(m_za_header.size);
1331 ::memcpy(GetSetBuffer(RegisterSetType::ZA), src,
1332 GetSetSize(RegisterSetType::ZA));
1333 MakeValid(RegisterSetType::ZA);
1341 ConfigureRegisterContext();
1346 src += GetSetSize(RegisterSetType::ZA);
1348 case RegisterSetType::ZT:
1352 error = RestoreRegisters(
1353 GetSetBuffer(RegisterSetType::ZT), &src,
1354 GetSetSize(RegisterSetType::ZT), kind,
1355 std::bind(&NativeRegisterContextLinux_arm64::WriteZT,
this));
1357 case RegisterSetType::FPMR:
1358 error = RestoreRegisters(
1359 GetSetBuffer(RegisterSetType::FPMR), &src,
1360 GetSetSize(RegisterSetType::FPMR), kind,
1361 std::bind(&NativeRegisterContextLinux_arm64::WriteFPMR,
this));
1363 case RegisterSetType::GCS: {
1368 Invalidate(RegisterSetType::GCS);
1373 uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
1374 gcs_regs new_gcs_regs;
1375 std::memcpy(&new_gcs_regs, src,
sizeof(new_gcs_regs));
1376 new_gcs_regs.features_enabled =
1377 (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
1379 const uint8_t *new_gcs_src =
1380 reinterpret_cast<const uint8_t *
>(&new_gcs_regs);
1381 error = RestoreRegisters(
1382 GetSetBuffer(RegisterSetType::GCS), &new_gcs_src,
1383 GetSetSize(RegisterSetType::GCS), kind,
1384 std::bind(&NativeRegisterContextLinux_arm64::WriteGCS,
this));
1385 src += GetSetSize(RegisterSetType::GCS);
1389 case RegisterSetType::POE:
1390 error = RestoreRegisters(
1391 GetSetBuffer(RegisterSetType::POE), &src,
1392 GetSetSize(RegisterSetType::POE), kind,
1393 std::bind(&NativeRegisterContextLinux_arm64::WritePOE,
this));
1395 case RegisterSetType::PAC:
1396 case RegisterSetType::SVE_HEADER:
1397 case RegisterSetType::ZA_HEADER:
1409llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1410 if (!m_refresh_hwdebug_info) {
1411 return llvm::Error::success();
1414 ::pid_t tid = m_thread.GetID();
1417 m_max_hbp_supported);
1419 return error.ToError();
1421 m_refresh_hwdebug_info =
false;
1423 return llvm::Error::success();
1427NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1428 uint32_t max_supported =
1429 (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
1430 auto ®s = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
1436Status NativeRegisterContextLinux_arm64::ReadGPR() {
1439 if (IsValid(RegisterSetType::GPR))
1443 ioVec.iov_base = GetGPRBuffer();
1444 ioVec.iov_len = GetGPRBufferSize();
1446 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(),
1447 GetPtraceSet(RegisterSetType::GPR));
1449 if (
error.Success())
1450 MakeValid(RegisterSetType::GPR);
1455Status NativeRegisterContextLinux_arm64::WriteGPR() {
1461 ioVec.iov_base = GetGPRBuffer();
1462 ioVec.iov_len = GetGPRBufferSize();
1464 Invalidate(RegisterSetType::GPR);
1466 return WriteRegisterSet(&ioVec, GetGPRBufferSize(),
1467 GetPtraceSet(RegisterSetType::GPR));
1470Status NativeRegisterContextLinux_arm64::ReadFPR() {
1473 if (IsValid(RegisterSetType::FPR))
1477 ioVec.iov_base = GetFPRBuffer();
1478 ioVec.iov_len = GetFPRSize();
1481 ReadRegisterSet(&ioVec, GetFPRSize(), GetPtraceSet(RegisterSetType::FPR));
1482 if (
error.Success())
1483 MakeValid(RegisterSetType::FPR);
1488Status NativeRegisterContextLinux_arm64::WriteFPR() {
1494 ioVec.iov_base = GetFPRBuffer();
1495 ioVec.iov_len = GetFPRSize();
1497 Invalidate(RegisterSetType::FPR);
1499 return WriteRegisterSet(&ioVec, GetFPRSize(),
1500 GetPtraceSet(RegisterSetType::FPR));
1503void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1504 m_validity =
static_cast<RegisterSetType
>(0);
1507 ConfigureRegisterContext();
1510Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1513 if (IsValid(RegisterSetType::SVE_HEADER))
1517 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE_HEADER);
1518 ioVec.iov_len = GetSetSize(RegisterSetType::SVE_HEADER);
1520 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE_HEADER),
1521 GetPtraceSet(RegisterSetType::SVE_HEADER));
1523 if (
error.Success())
1524 MakeValid(RegisterSetType::SVE_HEADER);
1529Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1532 if (IsValid(RegisterSetType::PAC))
1536 ioVec.iov_base = GetSetBuffer(RegisterSetType::PAC);
1537 ioVec.iov_len = GetSetSize(RegisterSetType::PAC);
1539 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::PAC),
1540 GetPtraceSet(RegisterSetType::PAC));
1542 if (
error.Success())
1543 MakeValid(RegisterSetType::PAC);
1548Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1551 error = ReadSVEHeader();
1556 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE_HEADER);
1557 ioVec.iov_len = GetSetSize(RegisterSetType::SVE_HEADER);
1559 Invalidate(RegisterSetType::SVE_HEADER);
1561 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE_HEADER),
1562 GetPtraceSet(RegisterSetType::SVE_HEADER));
1565Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1567 if (IsValid(RegisterSetType::SVE))
1571 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE);
1572 ioVec.iov_len = GetSetSize(RegisterSetType::SVE);
1574 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE),
1575 GetPtraceSet(RegisterSetType::SVE));
1577 if (
error.Success())
1578 MakeValid(RegisterSetType::SVE);
1583Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1586 error = ReadAllSVE();
1592 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE);
1593 ioVec.iov_len = GetSetSize(RegisterSetType::SVE);
1595 Invalidate(RegisterSetType::SVE);
1597 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE),
1598 GetPtraceSet(RegisterSetType::SVE));
1601Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1613 if (
error.Success() && (m_za_header.size >
sizeof(m_za_header)))
1614 m_sme_pseudo_regs.ctrl_reg |= 2;
1619Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1622 if (IsValid(RegisterSetType::MTE))
1626 ioVec.iov_base = GetSetBuffer(RegisterSetType::MTE);
1627 ioVec.iov_len = GetSetSize(RegisterSetType::MTE);
1629 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::MTE),
1630 GetPtraceSet(RegisterSetType::MTE));
1632 if (
error.Success())
1633 MakeValid(RegisterSetType::MTE);
1638Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1641 error = ReadMTEControl();
1646 ioVec.iov_base = GetSetBuffer(RegisterSetType::MTE);
1647 ioVec.iov_len = GetSetSize(RegisterSetType::MTE);
1649 Invalidate(RegisterSetType::MTE);
1651 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::MTE),
1652 GetPtraceSet(RegisterSetType::MTE));
1655Status NativeRegisterContextLinux_arm64::ReadTLS() {
1658 if (IsValid(RegisterSetType::TLS))
1662 ioVec.iov_base = GetSetBuffer(RegisterSetType::TLS);
1663 ioVec.iov_len = GetSetSize(RegisterSetType::TLS);
1665 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::TLS),
1666 GetPtraceSet(RegisterSetType::TLS));
1668 if (
error.Success())
1669 MakeValid(RegisterSetType::TLS);
1674Status NativeRegisterContextLinux_arm64::WriteTLS() {
1682 ioVec.iov_base = GetSetBuffer(RegisterSetType::TLS);
1683 ioVec.iov_len = GetSetSize(RegisterSetType::TLS);
1685 Invalidate(RegisterSetType::TLS);
1687 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::TLS),
1688 GetPtraceSet(RegisterSetType::TLS));
1691Status NativeRegisterContextLinux_arm64::ReadGCS() {
1694 if (IsValid(RegisterSetType::GCS))
1698 ioVec.iov_base = GetSetBuffer(RegisterSetType::GCS);
1699 ioVec.iov_len = GetSetSize(RegisterSetType::GCS);
1701 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::GCS),
1702 GetPtraceSet(RegisterSetType::GCS));
1704 if (
error.Success())
1705 MakeValid(RegisterSetType::GCS);
1710Status NativeRegisterContextLinux_arm64::WriteGCS() {
1718 ioVec.iov_base = GetSetBuffer(RegisterSetType::GCS);
1719 ioVec.iov_len = GetSetSize(RegisterSetType::GCS);
1721 Invalidate(RegisterSetType::GCS);
1723 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::GCS),
1724 GetPtraceSet(RegisterSetType::GCS));
1727Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1730 if (IsValid(RegisterSetType::ZA_HEADER))
1734 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA_HEADER);
1735 ioVec.iov_len = GetSetSize(RegisterSetType::ZA_HEADER);
1737 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA_HEADER),
1738 GetPtraceSet(RegisterSetType::ZA));
1740 if (
error.Success())
1741 MakeValid(RegisterSetType::ZA_HEADER);
1746Status NativeRegisterContextLinux_arm64::ReadZA() {
1749 if (IsValid(RegisterSetType::ZA))
1753 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA);
1754 ioVec.iov_len = GetSetSize(RegisterSetType::ZA);
1756 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA),
1757 GetPtraceSet(RegisterSetType::ZA));
1759 if (
error.Success())
1760 MakeValid(RegisterSetType::ZA);
1765Status NativeRegisterContextLinux_arm64::WriteZA() {
1776 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA);
1777 ioVec.iov_len = GetSetSize(RegisterSetType::ZA);
1779 Invalidate(RegisterSetType::ZA);
1781 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA),
1782 GetPtraceSet(RegisterSetType::ZA));
1785Status NativeRegisterContextLinux_arm64::ReadZT() {
1788 if (IsValid(RegisterSetType::ZT))
1792 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZT);
1793 ioVec.iov_len = GetSetSize(RegisterSetType::ZT);
1795 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZT),
1796 GetPtraceSet(RegisterSetType::ZT));
1797 if (
error.Success())
1798 MakeValid(RegisterSetType::ZT);
1803Status NativeRegisterContextLinux_arm64::WriteZT() {
1811 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZT);
1812 ioVec.iov_len = GetSetSize(RegisterSetType::ZT);
1814 Invalidate(RegisterSetType::ZT);
1816 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZT),
1817 GetPtraceSet(RegisterSetType::ZT));
1820Status NativeRegisterContextLinux_arm64::ReadFPMR() {
1823 if (IsValid(RegisterSetType::FPMR))
1827 ioVec.iov_base = GetSetBuffer(RegisterSetType::FPMR);
1828 ioVec.iov_len = GetSetSize(RegisterSetType::FPMR);
1830 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::FPMR),
1831 GetPtraceSet(RegisterSetType::FPMR));
1833 if (
error.Success())
1834 MakeValid(RegisterSetType::FPMR);
1839Status NativeRegisterContextLinux_arm64::WriteFPMR() {
1847 ioVec.iov_base = GetSetBuffer(RegisterSetType::FPMR);
1848 ioVec.iov_len = GetSetSize(RegisterSetType::FPMR);
1850 Invalidate(RegisterSetType::FPMR);
1852 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::FPMR),
1853 GetPtraceSet(RegisterSetType::FPMR));
1856Status NativeRegisterContextLinux_arm64::ReadPOE() {
1859 if (IsValid(RegisterSetType::POE))
1863 ioVec.iov_base = GetSetBuffer(RegisterSetType::POE);
1864 ioVec.iov_len = GetSetSize(RegisterSetType::POE);
1866 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::POE),
1867 GetPtraceSet(RegisterSetType::POE));
1869 if (
error.Success())
1870 MakeValid(RegisterSetType::POE);
1875Status NativeRegisterContextLinux_arm64::WritePOE() {
1883 ioVec.iov_base = GetSetBuffer(RegisterSetType::POE);
1884 ioVec.iov_len = GetSetSize(RegisterSetType::POE);
1886 Invalidate(RegisterSetType::POE);
1888 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::POE),
1889 GetPtraceSet(RegisterSetType::POE));
1892void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1898 if (!IsValid(RegisterSetType::SVE_HEADER) &&
1905 Invalidate(RegisterSetType::SVE_HEADER);
1909 bool has_sme =
error.Success();
1910 bool sme_is_active =
1915 Invalidate(RegisterSetType::SVE_HEADER);
1917 error = ReadSVEHeader();
1919 bool has_sve =
error.Success();
1920 bool sve_is_active =
1931 else if (sve_is_active)
1933 else if (fp_is_active)
1944 Invalidate(RegisterSetType::SVE_HEADER);
1945 error = ReadSVEHeader();
1953 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1958 if (!IsValid(RegisterSetType::ZA_HEADER)) {
1960 if (
error.Success()) {
1965 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1966 m_za_ptrace_payload.resize(m_za_header.size);
1967 Invalidate(RegisterSetType::ZA);
1972uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1973 const RegisterInfo *reg_info,
bool streaming_fpsimd)
const {
1974 uint32_t offset = reg_info->
byte_offset - GetGPRSize();
1975 if (!streaming_fpsimd)
1987 const size_t fpsr_offset = 16 * 32;
1989 if (reg == GetRegisterInfo().GetRegNumFPSR())
1990 offset = fpsr_offset;
1991 else if (reg == GetRegisterInfo().GetRegNumFPCR())
1992 offset = fpsr_offset + 4;
1994 offset = 16 * (reg - GetRegisterInfo().GetRegNumFPV0());
1999uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
2006 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
2010 uint32_t sve_z0_offset = GetGPRSize() + 16;
2014 return sve_reg_offset;
2017Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
2021 if (
error.Success())
2022 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
2027std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
2029 std::vector<uint32_t> expedited_reg_nums =
2033 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
2036 if (GetRegisterInfo().IsSSVEPresent())
2037 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
2039 return expedited_reg_nums;
2042llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
2043NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
2045 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
2046 PTRACE_PEEKMTETAGS, PTRACE_POKEMTETAGS};
2049 return llvm::createStringError(llvm::inconvertibleErrorCode(),
2050 "Unknown AArch64 memory tag type %d", type);
2053lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
2061 if (ReadPAuthMask().
Success())
2062 mask |= m_pac_mask.data_mask;
2064 return hit_addr & ~mask;
static llvm::raw_ostream & error(Stream &strm)
@ AUXV_AT_HWCAP2
Extension of AT_HWCAP.
@ AUXV_AT_HWCAP3
Extension of AT_HWCAP.
@ AUXV_AT_HWCAP
Machine dependent hints about processor capabilities.
size_t GetRegisterSetCount() const override
@ eVectorQuadwordAArch64SVE
static size_t GetGPRSizeStatic()
An architecture specification class.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
This class manages the storage and detection of register 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.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
std::optional< uint64_t > GetAuxValue(enum AuxVector::EntryType type)
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.