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>
219 switch (target_arch.GetMachine()) {
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<RegisterInfoPOSIX_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<RegisterInfoPOSIX_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.
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.