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;
137size_t NativeRegisterContextLinux_arm64::GetSetSize(
138 NativeRegisterContextLinux_arm64::RegisterSetType set)
const {
140 case RegisterSetType::GPR:
143 return sizeof(m_gpr_arm64);
144 case RegisterSetType::FPR:
145 return sizeof(m_fpr);
146 case RegisterSetType::SVE:
147 return m_sve_ptrace_payload.size();
148 case RegisterSetType::SVE_HEADER:
149 return sizeof(m_sve_header);
150 case RegisterSetType::PAC:
151 return sizeof(m_pac_mask);
152 case RegisterSetType::MTE:
153 return sizeof(m_mte_ctrl_reg);
154 case RegisterSetType::TLS:
156 case RegisterSetType::ZA:
157 return m_za_ptrace_payload.size();
158 case RegisterSetType::ZA_HEADER:
159 return sizeof(m_za_header);
160 case RegisterSetType::ZT:
161 return m_zt_reg.size();
162 case RegisterSetType::FPMR:
163 return sizeof(m_fpmr_reg);
164 case RegisterSetType::GCS:
165 return sizeof(m_gcs_regs);
166 case RegisterSetType::POE:
167 return sizeof(m_poe_regs);
171void *NativeRegisterContextLinux_arm64::GetSetBuffer(
172 NativeRegisterContextLinux_arm64::RegisterSetType set) {
174 case RegisterSetType::GPR:
176 case RegisterSetType::FPR:
178 case RegisterSetType::SVE:
179 return m_sve_ptrace_payload.data();
180 case RegisterSetType::SVE_HEADER:
181 return &m_sve_header;
182 case RegisterSetType::PAC:
184 case RegisterSetType::MTE:
185 return &m_mte_ctrl_reg;
186 case RegisterSetType::TLS:
188 case RegisterSetType::ZA:
189 return m_za_ptrace_payload.data();
190 case RegisterSetType::ZA_HEADER:
192 case RegisterSetType::ZT:
193 return m_zt_reg.data();
194 case RegisterSetType::FPMR:
196 case RegisterSetType::GCS:
198 case RegisterSetType::POE:
207static std::mutex g_register_type_detector_mutex;
210std::unique_ptr<NativeRegisterContextLinux>
213 switch (target_arch.GetMachine()) {
214 case llvm::Triple::arm:
215 return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
217 case llvm::Triple::aarch64: {
222 ioVec.iov_base = &sve_header;
223 ioVec.iov_len =
sizeof(sve_header);
224 unsigned int regset = llvm::ELF::NT_ARM_SVE;
228 native_thread.
GetID(), ®set,
229 &ioVec,
sizeof(sve_header))
235 ioVec.iov_len =
sizeof(sve_header);
236 regset = llvm::ELF::NT_ARM_SSVE;
238 native_thread.
GetID(), ®set,
239 &ioVec,
sizeof(sve_header))
244 ioVec.iov_base = &za_header;
245 ioVec.iov_len =
sizeof(za_header);
246 regset = llvm::ELF::NT_ARM_ZA;
248 native_thread.
GetID(), ®set,
249 &ioVec,
sizeof(za_header))
254 std::array<uint8_t, 64> zt_reg;
255 ioVec.iov_base = zt_reg.data();
256 ioVec.iov_len = zt_reg.size();
257 regset = llvm::ELF::NT_ARM_ZT;
259 native_thread.
GetID(), ®set,
260 &ioVec, zt_reg.size())
266 std::optional<uint64_t> auxv_at_hwcap =
268 if (auxv_at_hwcap && (*auxv_at_hwcap & HWCAP_PACA))
271 std::optional<uint64_t> auxv_at_hwcap2 =
273 if (auxv_at_hwcap2) {
286 std::optional<uint64_t> auxv_at_hwcap3 =
288 std::lock_guard<std::mutex> lock(g_register_type_detector_mutex);
290 g_register_type_detector.
DetectTypes(auxv_at_hwcap.value_or(0),
291 auxv_at_hwcap2.value_or(0),
292 auxv_at_hwcap3.value_or(0));
294 auto register_info_up =
295 std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
296 return std::make_unique<NativeRegisterContextLinux_arm64>(
297 target_arch, native_thread, std::move(register_info_up));
300 llvm_unreachable(
"have no register context for architecture");
304llvm::Expected<ArchSpec>
306 return DetermineArchitectureViaGPR(
310NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
312 std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
314 register_info_up.release()),
317 GetRegisterInfoInterface().GetRegisterInfo(),
318 GetRegisterInfoInterface().GetRegisterCount());
321 m_max_hwp_supported = 16;
322 m_max_hbp_supported = 16;
325 m_tls_size = GetRegisterInfo().IsSSVEPresent() ?
sizeof(m_tls_regs)
326 : sizeof(m_tls_regs.tpidr_reg);
328 if (GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent())
335NativeRegisterContextLinux_arm64::GetRegisterInfo()
const {
339uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount()
const {
344NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index)
const {
345 return GetRegisterInfo().GetRegisterSet(set_index);
348uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount()
const {
350 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
356NativeRegisterContextLinux_arm64::ReadRegister(
const RegisterInfo *reg_info,
369 "no lldb regnum for %s",
370 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
375 std::vector<uint8_t> sve_reg_non_live;
377 if (GetRegisterInfo().IsGPR(reg)) {
383 assert(offset < GetGPRSize());
384 src = (uint8_t *)GetGPRBuffer() + offset;
386 }
else if (GetRegisterInfo().IsFPR(reg)) {
396 offset = CalculateFprOffset(reg_info,
398 assert(offset < GetFPRSize());
399 src = (uint8_t *)GetFPRBuffer() + offset;
404 error = ReadAllSVE();
413 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
419 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
430 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
433 assert(offset < GetSetSize(RegisterSetType::SVE));
434 src = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
436 }
else if (GetRegisterInfo().IsTLSReg(reg)) {
441 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
442 assert(offset < GetSetSize(RegisterSetType::TLS));
443 src = (uint8_t *)GetSetBuffer(RegisterSetType::TLS) + offset;
444 }
else if (GetRegisterInfo().IsSVEReg(reg)) {
448 if (GetRegisterInfo().IsSVERegVG(reg)) {
449 error = ReadSVEHeader();
453 sve_vg = GetSVERegVG();
454 src = (uint8_t *)&sve_vg;
460 if (GetRegisterInfo().IsSVEPReg(reg) ||
461 GetRegisterInfo().IsSVERegFFR(reg)) {
462 std::vector<uint8_t> fake_reg(reg_info->
byte_size, 0);
485 const uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
487 assert(offset < GetFPRSize());
488 src = (uint8_t *)GetFPRBuffer() + offset;
491 std::vector<uint8_t> fake_z(reg_info->
byte_size, 0);
492 std::memcpy(&fake_z[0], src, 16 );
499 error = ReadAllSVE();
507 sve_reg_non_live.resize(reg_info->
byte_size, 0);
508 src = sve_reg_non_live.data();
510 if (GetRegisterInfo().IsSVEZReg(reg)) {
511 offset = CalculateSVEOffset(reg_info);
512 assert(offset < GetSetSize(RegisterSetType::SVE));
513 ::memcpy(sve_reg_non_live.data(),
514 (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset, 16);
517 offset = CalculateSVEOffset(reg_info);
518 assert(offset < GetSetSize(RegisterSetType::SVE));
519 src = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
522 }
else if (GetRegisterInfo().IsPAuthReg(reg)) {
523 error = ReadPAuthMask();
527 offset = reg_info->
byte_offset - GetRegisterInfo().GetPAuthOffset();
528 assert(offset < GetSetSize(RegisterSetType::PAC));
529 src = (uint8_t *)GetSetBuffer(RegisterSetType::PAC) + offset;
530 }
else if (GetRegisterInfo().IsMTEReg(reg)) {
531 error = ReadMTEControl();
535 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
536 assert(offset < GetSetSize(RegisterSetType::MTE));
537 src = (uint8_t *)GetSetBuffer(RegisterSetType::MTE) + offset;
538 }
else if (GetRegisterInfo().IsSMEReg(reg)) {
539 if (GetRegisterInfo().IsSMERegZA(reg)) {
540 error = ReadZAHeader();
546 if (m_za_header.size ==
sizeof(m_za_header)) {
550 m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
551 GetSetSize(RegisterSetType::ZA_HEADER));
552 std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
563 src = (uint8_t *)GetSetBuffer(RegisterSetType::ZA) +
564 GetSetSize(RegisterSetType::ZA_HEADER);
565 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
573 src = (uint8_t *)GetSetBuffer(RegisterSetType::ZT);
575 error = ReadSMESVG();
582 offset = reg_info->
byte_offset - GetRegisterInfo().GetSMEOffset();
583 assert(offset < GetSMEPseudoBufferSize());
584 src = (uint8_t *)GetSMEPseudoBuffer() + offset;
586 }
else if (GetRegisterInfo().IsFPMRReg(reg)) {
591 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
592 assert(offset < GetSetSize(RegisterSetType::FPMR));
593 src = (uint8_t *)GetSetBuffer(RegisterSetType::FPMR) + offset;
594 }
else if (GetRegisterInfo().IsGCSReg(reg)) {
599 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
600 assert(offset < GetSetSize(RegisterSetType::GCS));
601 src = (uint8_t *)GetSetBuffer(RegisterSetType::GCS) + offset;
602 }
else if (GetRegisterInfo().IsPOEReg(reg)) {
607 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
608 assert(offset < GetSetSize(RegisterSetType::POE));
609 src = (uint8_t *)GetSetBuffer(RegisterSetType::POE) + offset;
612 "failed - register wasn't recognized to be a GPR or an FPR, "
613 "write strategy unknown");
621Status NativeRegisterContextLinux_arm64::WriteRegister(
632 "no lldb regnum for %s",
633 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
638 if (GetRegisterInfo().IsGPR(reg)) {
644 dst = (uint8_t *)GetGPRBuffer() + reg_info->
byte_offset;
648 }
else if (GetRegisterInfo().IsFPR(reg)) {
658 offset = CalculateFprOffset(reg_info,
660 assert(offset < GetFPRSize());
661 dst = (uint8_t *)GetFPRBuffer() + offset;
667 error = ReadAllSVE();
676 if (reg == GetRegisterInfo().GetRegNumFPSR()) {
682 }
else if (reg == GetRegisterInfo().GetRegNumFPCR()) {
693 offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num));
696 assert(offset < GetSetSize(RegisterSetType::SVE));
697 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
699 return WriteAllSVE();
701 }
else if (GetRegisterInfo().IsSVEReg(reg)) {
720 if (GetRegisterInfo().IsSVERegVG(reg) ||
721 GetRegisterInfo().IsSVEPReg(reg) ||
722 GetRegisterInfo().IsSVERegFFR(reg))
724 "Cannot write SVE VG, P or FFR registers while outside of "
736 uint32_t z_num = reg - GetRegisterInfo().GetRegNumSVEZ0();
738 assert(offset < GetFPRSize());
739 dst = (uint8_t *)GetFPRBuffer() + offset;
742 ::memcpy(dst, reg_value.
GetBytes(), 16);
747 error = ReadAllSVE();
751 if (GetRegisterInfo().IsSVERegVG(reg)) {
755 if (IsValid(RegisterSetType::SVE_HEADER) && vg_value == GetSVERegVG())
758 SetSVERegVG(vg_value);
760 error = WriteSVEHeader();
761 if (
error.Success()) {
764 Invalidate(RegisterSetType::ZA_HEADER);
765 ConfigureRegisterContext();
768 if (IsValid(RegisterSetType::SVE_HEADER) && vg_value == GetSVERegVG())
779 bool set_sve_state_full =
false;
780 const uint8_t *reg_bytes = (
const uint8_t *)reg_value.
GetBytes();
781 if (GetRegisterInfo().IsSVEZReg(reg)) {
782 for (uint32_t i = 16; i < reg_info->
byte_size; i++) {
784 set_sve_state_full =
true;
788 }
else if (GetRegisterInfo().IsSVEPReg(reg) ||
789 reg == GetRegisterInfo().GetRegNumSVEFFR()) {
790 for (uint32_t i = 0; i < reg_info->
byte_size; i++) {
792 set_sve_state_full =
true;
798 if (!set_sve_state_full && GetRegisterInfo().IsSVEZReg(reg)) {
801 offset = CalculateSVEOffset(reg_info);
802 assert(offset < GetSetSize(RegisterSetType::SVE));
803 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
804 ::memcpy(dst, reg_value.
GetBytes(), 16);
806 return WriteAllSVE();
809 "SVE state change operation not supported");
811 offset = CalculateSVEOffset(reg_info);
812 assert(offset < GetSetSize(RegisterSetType::SVE));
813 dst = (uint8_t *)GetSetBuffer(RegisterSetType::SVE) + offset;
815 return WriteAllSVE();
818 }
else if (GetRegisterInfo().IsMTEReg(reg)) {
819 error = ReadMTEControl();
823 offset = reg_info->
byte_offset - GetRegisterInfo().GetMTEOffset();
824 assert(offset < GetSetSize(RegisterSetType::MTE));
825 dst = (uint8_t *)GetSetBuffer(RegisterSetType::MTE) + offset;
828 return WriteMTEControl();
829 }
else if (GetRegisterInfo().IsTLSReg(reg)) {
834 offset = reg_info->
byte_offset - GetRegisterInfo().GetTLSOffset();
835 assert(offset < GetSetSize(RegisterSetType::TLS));
836 dst = (uint8_t *)GetSetBuffer(RegisterSetType::TLS) + offset;
840 }
else if (GetRegisterInfo().IsSMEReg(reg)) {
841 if (GetRegisterInfo().IsSMERegZA(reg)) {
848 dst = (uint8_t *)GetSetBuffer(RegisterSetType::ZA) +
849 GetSetSize(RegisterSetType::ZA_HEADER);
856 }
else if (GetRegisterInfo().IsSMERegZT(reg)) {
861 dst = (uint8_t *)GetSetBuffer(RegisterSetType::ZT);
867 "Writing to SVG or SVCR is not supported.");
868 }
else if (GetRegisterInfo().IsFPMRReg(reg)) {
873 offset = reg_info->
byte_offset - GetRegisterInfo().GetFPMROffset();
874 assert(offset < GetSetSize(RegisterSetType::FPMR));
875 dst = (uint8_t *)GetSetBuffer(RegisterSetType::FPMR) + offset;
879 }
else if (GetRegisterInfo().IsGCSReg(reg)) {
884 offset = reg_info->
byte_offset - GetRegisterInfo().GetGCSOffset();
885 assert(offset < GetSetSize(RegisterSetType::GCS));
886 dst = (uint8_t *)GetSetBuffer(RegisterSetType::GCS) + offset;
890 }
else if (GetRegisterInfo().IsPOEReg(reg)) {
895 offset = reg_info->
byte_offset - GetRegisterInfo().GetPOEOffset();
896 assert(offset < GetSetSize(RegisterSetType::POE));
897 dst = (uint8_t *)GetSetBuffer(RegisterSetType::POE) + offset;
906uint8_t *NativeRegisterContextLinux_arm64::AddRegisterSetType(
907 uint8_t *dst, RegisterSetType register_set_type) {
908 std::memcpy(dst, ®ister_set_type,
sizeof(register_set_type));
909 return dst +
sizeof(RegisterSetType);
912static uint8_t *AddSavedRegistersData(uint8_t *dst,
void *src,
size_t size) {
913 ::memcpy(dst, src, size);
917uint8_t *NativeRegisterContextLinux_arm64::AddSavedRegisters(
918 uint8_t *dst, RegisterSetType register_set_type,
void *src,
size_t size) {
919 dst = AddRegisterSetType(dst, register_set_type);
920 return AddSavedRegistersData(dst, src, size);
924NativeRegisterContextLinux_arm64::CacheAllRegisters(uint32_t &cached_size) {
926 cached_size =
sizeof(RegisterSetType) + GetGPRBufferSize();
931 if (GetRegisterInfo().IsZAPresent()) {
932 error = ReadZAHeader();
939 cached_size +=
sizeof(RegisterSetType) + m_za_header.size;
942 Invalidate(RegisterSetType::ZA);
951 GetRegisterInfo().IsZTPresent() &&
953 m_za_header.size >
sizeof(m_za_header)) {
954 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::ZT);
966 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
969 cached_size +=
sizeof(RegisterSetType) +
sizeof(m_sve_state) +
970 GetSetSize(RegisterSetType::SVE);
971 error = ReadAllSVE();
973 cached_size +=
sizeof(RegisterSetType) + GetFPRSize();
979 if (GetRegisterInfo().IsMTEPresent()) {
980 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::MTE);
981 error = ReadMTEControl();
986 if (GetRegisterInfo().IsFPMRPresent()) {
987 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::FPMR);
993 if (GetRegisterInfo().IsGCSPresent()) {
994 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::GCS);
1000 if (GetRegisterInfo().IsPOEPresent()) {
1001 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::POE);
1008 cached_size +=
sizeof(RegisterSetType) + GetSetSize(RegisterSetType::TLS);
1014Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
1026 uint32_t reg_data_byte_size = 0;
1027 Status error = CacheAllRegisters(reg_data_byte_size);
1032 uint8_t *dst = data_sp->GetBytes();
1034 dst = AddSavedRegisters(dst, RegisterSetType::GPR, GetGPRBuffer(),
1035 GetGPRBufferSize());
1071 assert(m_za_header.size <= GetSetSize(RegisterSetType::ZA));
1073 AddSavedRegisters(dst, RegisterSetType::ZA,
1074 GetSetBuffer(RegisterSetType::ZA), m_za_header.size);
1077 if ((GetRegisterInfo().IsSVEPresent() || GetRegisterInfo().IsSSVEPresent()) &&
1079 dst = AddRegisterSetType(dst, RegisterSetType::SVE);
1080 std::memcpy(dst, &m_sve_state,
sizeof(m_sve_state));
1081 dst +=
sizeof(m_sve_state);
1082 dst = AddSavedRegistersData(dst, GetSetBuffer(RegisterSetType::SVE),
1083 GetSetSize(RegisterSetType::SVE));
1085 dst = AddSavedRegisters(dst, RegisterSetType::FPR, GetFPRBuffer(),
1090 assert(m_za_header.size <= GetSetSize(RegisterSetType::ZA));
1092 AddSavedRegisters(dst, RegisterSetType::ZA,
1093 GetSetBuffer(RegisterSetType::ZA), m_za_header.size);
1103 GetRegisterInfo().IsZTPresent() &&
1105 m_za_header.size >
sizeof(m_za_header))
1106 dst = AddSavedRegisters(dst, RegisterSetType::ZT,
1107 GetSetBuffer(RegisterSetType::ZT),
1108 GetSetSize(RegisterSetType::ZT));
1110 if (GetRegisterInfo().IsMTEPresent()) {
1111 dst = AddSavedRegisters(dst, RegisterSetType::MTE,
1112 GetSetBuffer(RegisterSetType::MTE),
1113 GetSetSize(RegisterSetType::MTE));
1116 if (GetRegisterInfo().IsFPMRPresent()) {
1117 dst = AddSavedRegisters(dst, RegisterSetType::FPMR,
1118 GetSetBuffer(RegisterSetType::FPMR),
1119 GetSetSize(RegisterSetType::FPMR));
1122 if (GetRegisterInfo().IsGCSPresent()) {
1123 dst = AddSavedRegisters(dst, RegisterSetType::GCS,
1124 GetSetBuffer(RegisterSetType::GCS),
1125 GetSetSize(RegisterSetType::GCS));
1128 if (GetRegisterInfo().IsPOEPresent()) {
1129 dst = AddSavedRegisters(dst, RegisterSetType::POE,
1130 GetSetBuffer(RegisterSetType::POE),
1131 GetSetSize(RegisterSetType::POE));
1134 dst = AddSavedRegisters(dst, RegisterSetType::TLS,
1135 GetSetBuffer(RegisterSetType::TLS),
1136 GetSetSize(RegisterSetType::TLS));
1141Status NativeRegisterContextLinux_arm64::RestoreRegisters(
1142 void *buffer,
const uint8_t **src,
size_t len,
1143 const NativeRegisterContextLinux_arm64::RegisterSetType set,
1144 std::function<
Status()> writer) {
1145 ::memcpy(buffer, *src, len);
1151Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
1167 "NativeRegisterContextLinux_arm64::%s invalid data_sp provided",
1172 const uint8_t *src = data_sp->GetBytes();
1173 if (src ==
nullptr) {
1175 "NativeRegisterContextLinux_arm64::%s "
1176 "DataBuffer::GetBytes() returned a null "
1182 uint64_t reg_data_min_size =
1183 GetGPRBufferSize() + GetFPRSize() + 2 * (
sizeof(RegisterSetType));
1184 if (data_sp->GetByteSize() < reg_data_min_size) {
1186 "NativeRegisterContextLinux_arm64::%s data_sp contained insufficient "
1187 "register data bytes, expected at least %" PRIu64
", actual %" PRIu64,
1188 __FUNCTION__, reg_data_min_size, data_sp->GetByteSize());
1192 const uint8_t *end = src + data_sp->GetByteSize();
1194 RegisterSetType kind;
1195 std::memcpy(&kind, src,
sizeof(kind));
1196 src +=
sizeof(RegisterSetType);
1199 case RegisterSetType::GPR:
1200 error = RestoreRegisters(
1201 GetGPRBuffer(), &src, GetGPRBufferSize(), kind,
1202 std::bind(&NativeRegisterContextLinux_arm64::WriteGPR,
this));
1204 case RegisterSetType::SVE:
1206 std::memcpy(&m_sve_state, src,
sizeof(m_sve_state));
1207 src +=
sizeof(m_sve_state);
1211 ::memcpy(GetSetBuffer(RegisterSetType::SVE_HEADER), src,
1212 GetSetSize(RegisterSetType::SVE_HEADER));
1214 Invalidate(RegisterSetType::SVE_HEADER);
1216 "NativeRegisterContextLinux_arm64::%s "
1217 "Invalid SVE header in data_sp",
1221 MakeValid(RegisterSetType::SVE_HEADER);
1222 error = WriteSVEHeader();
1229 ConfigureRegisterContext();
1232 error = RestoreRegisters(
1233 GetSetBuffer(RegisterSetType::SVE), &src,
1234 GetSetSize(RegisterSetType::SVE), kind,
1235 std::bind(&NativeRegisterContextLinux_arm64::WriteAllSVE,
this));
1237 case RegisterSetType::FPR: {
1238 Invalidate(RegisterSetType::SVE_HEADER);
1240 ConfigureRegisterContext();
1244 if (!GetRegisterInfo().IsSVEPresent() &&
1245 GetRegisterInfo().IsSSVEPresent() &&
1263 std::vector<uint8_t> sve_fpsimd_data(data_size);
1268 header->
size = sve_fpsimd_data.size();
1276 ioVec.iov_base = sve_fpsimd_data.data();
1277 ioVec.iov_len = sve_fpsimd_data.size();
1281 error = WriteRegisterSet(&ioVec, sve_fpsimd_data.size(),
1282 llvm::ELF::NT_ARM_SVE);
1285 src += GetFPRSize();
1287 if (
error.Success()) {
1288 Invalidate(RegisterSetType::FPR);
1290 ConfigureRegisterContext();
1295 error = RestoreRegisters(
1296 GetFPRBuffer(), &src, GetFPRSize(), kind,
1297 std::bind(&NativeRegisterContextLinux_arm64::WriteFPR,
this));
1301 case RegisterSetType::MTE:
1302 error = RestoreRegisters(
1303 GetSetBuffer(RegisterSetType::MTE), &src,
1304 GetSetSize(RegisterSetType::MTE), kind,
1305 std::bind(&NativeRegisterContextLinux_arm64::WriteMTEControl,
this));
1307 case RegisterSetType::TLS:
1308 error = RestoreRegisters(
1309 GetSetBuffer(RegisterSetType::TLS), &src,
1310 GetSetSize(RegisterSetType::TLS), kind,
1311 std::bind(&NativeRegisterContextLinux_arm64::WriteTLS,
this));
1313 case RegisterSetType::ZA:
1319 ::memcpy(GetSetBuffer(RegisterSetType::ZA_HEADER), src,
1320 GetSetSize(RegisterSetType::ZA_HEADER));
1324 m_za_ptrace_payload.resize(m_za_header.size);
1325 ::memcpy(GetSetBuffer(RegisterSetType::ZA), src,
1326 GetSetSize(RegisterSetType::ZA));
1327 MakeValid(RegisterSetType::ZA);
1335 ConfigureRegisterContext();
1340 src += GetSetSize(RegisterSetType::ZA);
1342 case RegisterSetType::ZT:
1346 error = RestoreRegisters(
1347 GetSetBuffer(RegisterSetType::ZT), &src,
1348 GetSetSize(RegisterSetType::ZT), kind,
1349 std::bind(&NativeRegisterContextLinux_arm64::WriteZT,
this));
1351 case RegisterSetType::FPMR:
1352 error = RestoreRegisters(
1353 GetSetBuffer(RegisterSetType::FPMR), &src,
1354 GetSetSize(RegisterSetType::FPMR), kind,
1355 std::bind(&NativeRegisterContextLinux_arm64::WriteFPMR,
this));
1357 case RegisterSetType::GCS: {
1362 Invalidate(RegisterSetType::GCS);
1367 uint64_t enable_bit = m_gcs_regs.features_enabled & 1UL;
1368 gcs_regs new_gcs_regs;
1369 std::memcpy(&new_gcs_regs, src,
sizeof(new_gcs_regs));
1370 new_gcs_regs.features_enabled =
1371 (new_gcs_regs.features_enabled & ~1UL) | enable_bit;
1373 const uint8_t *new_gcs_src =
1374 reinterpret_cast<const uint8_t *
>(&new_gcs_regs);
1375 error = RestoreRegisters(
1376 GetSetBuffer(RegisterSetType::GCS), &new_gcs_src,
1377 GetSetSize(RegisterSetType::GCS), kind,
1378 std::bind(&NativeRegisterContextLinux_arm64::WriteGCS,
this));
1379 src += GetSetSize(RegisterSetType::GCS);
1383 case RegisterSetType::POE:
1384 error = RestoreRegisters(
1385 GetSetBuffer(RegisterSetType::POE), &src,
1386 GetSetSize(RegisterSetType::POE), kind,
1387 std::bind(&NativeRegisterContextLinux_arm64::WritePOE,
this));
1389 case RegisterSetType::PAC:
1390 case RegisterSetType::SVE_HEADER:
1391 case RegisterSetType::ZA_HEADER:
1403llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
1404 if (!m_refresh_hwdebug_info) {
1405 return llvm::Error::success();
1408 ::pid_t tid = m_thread.GetID();
1411 m_max_hbp_supported);
1413 return error.ToError();
1415 m_refresh_hwdebug_info =
false;
1417 return llvm::Error::success();
1421NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
1422 uint32_t max_supported =
1423 (hwbType == eDREGTypeWATCH) ? m_max_hwp_supported : m_max_hbp_supported;
1424 auto ®s = (hwbType == eDREGTypeWATCH) ? m_hwp_regs : m_hbp_regs;
1430Status NativeRegisterContextLinux_arm64::ReadGPR() {
1433 if (IsValid(RegisterSetType::GPR))
1437 ioVec.iov_base = GetGPRBuffer();
1438 ioVec.iov_len = GetGPRBufferSize();
1440 error = ReadRegisterSet(&ioVec, GetGPRBufferSize(),
1441 GetPtraceSet(RegisterSetType::GPR));
1443 if (
error.Success())
1444 MakeValid(RegisterSetType::GPR);
1449Status NativeRegisterContextLinux_arm64::WriteGPR() {
1455 ioVec.iov_base = GetGPRBuffer();
1456 ioVec.iov_len = GetGPRBufferSize();
1458 Invalidate(RegisterSetType::GPR);
1460 return WriteRegisterSet(&ioVec, GetGPRBufferSize(),
1461 GetPtraceSet(RegisterSetType::GPR));
1464Status NativeRegisterContextLinux_arm64::ReadFPR() {
1467 if (IsValid(RegisterSetType::FPR))
1471 ioVec.iov_base = GetFPRBuffer();
1472 ioVec.iov_len = GetFPRSize();
1475 ReadRegisterSet(&ioVec, GetFPRSize(), GetPtraceSet(RegisterSetType::FPR));
1476 if (
error.Success())
1477 MakeValid(RegisterSetType::FPR);
1482Status NativeRegisterContextLinux_arm64::WriteFPR() {
1488 ioVec.iov_base = GetFPRBuffer();
1489 ioVec.iov_len = GetFPRSize();
1491 Invalidate(RegisterSetType::FPR);
1493 return WriteRegisterSet(&ioVec, GetFPRSize(),
1494 GetPtraceSet(RegisterSetType::FPR));
1497void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
1498 m_validity =
static_cast<RegisterSetType
>(0);
1501 ConfigureRegisterContext();
1504Status NativeRegisterContextLinux_arm64::ReadSVEHeader() {
1507 if (IsValid(RegisterSetType::SVE_HEADER))
1511 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE_HEADER);
1512 ioVec.iov_len = GetSetSize(RegisterSetType::SVE_HEADER);
1514 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE_HEADER),
1515 GetPtraceSet(RegisterSetType::SVE_HEADER));
1517 if (
error.Success())
1518 MakeValid(RegisterSetType::SVE_HEADER);
1523Status NativeRegisterContextLinux_arm64::ReadPAuthMask() {
1526 if (IsValid(RegisterSetType::PAC))
1530 ioVec.iov_base = GetSetBuffer(RegisterSetType::PAC);
1531 ioVec.iov_len = GetSetSize(RegisterSetType::PAC);
1533 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::PAC),
1534 GetPtraceSet(RegisterSetType::PAC));
1536 if (
error.Success())
1537 MakeValid(RegisterSetType::PAC);
1542Status NativeRegisterContextLinux_arm64::WriteSVEHeader() {
1545 error = ReadSVEHeader();
1550 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE_HEADER);
1551 ioVec.iov_len = GetSetSize(RegisterSetType::SVE_HEADER);
1553 Invalidate(RegisterSetType::SVE_HEADER);
1555 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE_HEADER),
1556 GetPtraceSet(RegisterSetType::SVE_HEADER));
1559Status NativeRegisterContextLinux_arm64::ReadAllSVE() {
1561 if (IsValid(RegisterSetType::SVE))
1565 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE);
1566 ioVec.iov_len = GetSetSize(RegisterSetType::SVE);
1568 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE),
1569 GetPtraceSet(RegisterSetType::SVE));
1571 if (
error.Success())
1572 MakeValid(RegisterSetType::SVE);
1577Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
1580 error = ReadAllSVE();
1586 ioVec.iov_base = GetSetBuffer(RegisterSetType::SVE);
1587 ioVec.iov_len = GetSetSize(RegisterSetType::SVE);
1589 Invalidate(RegisterSetType::SVE);
1591 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::SVE),
1592 GetPtraceSet(RegisterSetType::SVE));
1595Status NativeRegisterContextLinux_arm64::ReadSMEControl() {
1607 if (
error.Success() && (m_za_header.size >
sizeof(m_za_header)))
1608 m_sme_pseudo_regs.ctrl_reg |= 2;
1613Status NativeRegisterContextLinux_arm64::ReadMTEControl() {
1616 if (IsValid(RegisterSetType::MTE))
1620 ioVec.iov_base = GetSetBuffer(RegisterSetType::MTE);
1621 ioVec.iov_len = GetSetSize(RegisterSetType::MTE);
1623 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::MTE),
1624 GetPtraceSet(RegisterSetType::MTE));
1626 if (
error.Success())
1627 MakeValid(RegisterSetType::MTE);
1632Status NativeRegisterContextLinux_arm64::WriteMTEControl() {
1635 error = ReadMTEControl();
1640 ioVec.iov_base = GetSetBuffer(RegisterSetType::MTE);
1641 ioVec.iov_len = GetSetSize(RegisterSetType::MTE);
1643 Invalidate(RegisterSetType::MTE);
1645 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::MTE),
1646 GetPtraceSet(RegisterSetType::MTE));
1649Status NativeRegisterContextLinux_arm64::ReadTLS() {
1652 if (IsValid(RegisterSetType::TLS))
1656 ioVec.iov_base = GetSetBuffer(RegisterSetType::TLS);
1657 ioVec.iov_len = GetSetSize(RegisterSetType::TLS);
1659 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::TLS),
1660 GetPtraceSet(RegisterSetType::TLS));
1662 if (
error.Success())
1663 MakeValid(RegisterSetType::TLS);
1668Status NativeRegisterContextLinux_arm64::WriteTLS() {
1676 ioVec.iov_base = GetSetBuffer(RegisterSetType::TLS);
1677 ioVec.iov_len = GetSetSize(RegisterSetType::TLS);
1679 Invalidate(RegisterSetType::TLS);
1681 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::TLS),
1682 GetPtraceSet(RegisterSetType::TLS));
1685Status NativeRegisterContextLinux_arm64::ReadGCS() {
1688 if (IsValid(RegisterSetType::GCS))
1692 ioVec.iov_base = GetSetBuffer(RegisterSetType::GCS);
1693 ioVec.iov_len = GetSetSize(RegisterSetType::GCS);
1695 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::GCS),
1696 GetPtraceSet(RegisterSetType::GCS));
1698 if (
error.Success())
1699 MakeValid(RegisterSetType::GCS);
1704Status NativeRegisterContextLinux_arm64::WriteGCS() {
1712 ioVec.iov_base = GetSetBuffer(RegisterSetType::GCS);
1713 ioVec.iov_len = GetSetSize(RegisterSetType::GCS);
1715 Invalidate(RegisterSetType::GCS);
1717 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::GCS),
1718 GetPtraceSet(RegisterSetType::GCS));
1721Status NativeRegisterContextLinux_arm64::ReadZAHeader() {
1724 if (IsValid(RegisterSetType::ZA_HEADER))
1728 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA_HEADER);
1729 ioVec.iov_len = GetSetSize(RegisterSetType::ZA_HEADER);
1731 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA_HEADER),
1732 GetPtraceSet(RegisterSetType::ZA));
1734 if (
error.Success())
1735 MakeValid(RegisterSetType::ZA_HEADER);
1740Status NativeRegisterContextLinux_arm64::ReadZA() {
1743 if (IsValid(RegisterSetType::ZA))
1747 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA);
1748 ioVec.iov_len = GetSetSize(RegisterSetType::ZA);
1750 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA),
1751 GetPtraceSet(RegisterSetType::ZA));
1753 if (
error.Success())
1754 MakeValid(RegisterSetType::ZA);
1759Status NativeRegisterContextLinux_arm64::WriteZA() {
1770 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZA);
1771 ioVec.iov_len = GetSetSize(RegisterSetType::ZA);
1773 Invalidate(RegisterSetType::ZA);
1775 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZA),
1776 GetPtraceSet(RegisterSetType::ZA));
1779Status NativeRegisterContextLinux_arm64::ReadZT() {
1782 if (IsValid(RegisterSetType::ZT))
1786 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZT);
1787 ioVec.iov_len = GetSetSize(RegisterSetType::ZT);
1789 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZT),
1790 GetPtraceSet(RegisterSetType::ZT));
1791 if (
error.Success())
1792 MakeValid(RegisterSetType::ZT);
1797Status NativeRegisterContextLinux_arm64::WriteZT() {
1805 ioVec.iov_base = GetSetBuffer(RegisterSetType::ZT);
1806 ioVec.iov_len = GetSetSize(RegisterSetType::ZT);
1808 Invalidate(RegisterSetType::ZT);
1810 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::ZT),
1811 GetPtraceSet(RegisterSetType::ZT));
1814Status NativeRegisterContextLinux_arm64::ReadFPMR() {
1817 if (IsValid(RegisterSetType::FPMR))
1821 ioVec.iov_base = GetSetBuffer(RegisterSetType::FPMR);
1822 ioVec.iov_len = GetSetSize(RegisterSetType::FPMR);
1824 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::FPMR),
1825 GetPtraceSet(RegisterSetType::FPMR));
1827 if (
error.Success())
1828 MakeValid(RegisterSetType::FPMR);
1833Status NativeRegisterContextLinux_arm64::WriteFPMR() {
1841 ioVec.iov_base = GetSetBuffer(RegisterSetType::FPMR);
1842 ioVec.iov_len = GetSetSize(RegisterSetType::FPMR);
1844 Invalidate(RegisterSetType::FPMR);
1846 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::FPMR),
1847 GetPtraceSet(RegisterSetType::FPMR));
1850Status NativeRegisterContextLinux_arm64::ReadPOE() {
1853 if (IsValid(RegisterSetType::POE))
1857 ioVec.iov_base = GetSetBuffer(RegisterSetType::POE);
1858 ioVec.iov_len = GetSetSize(RegisterSetType::POE);
1860 error = ReadRegisterSet(&ioVec, GetSetSize(RegisterSetType::POE),
1861 GetPtraceSet(RegisterSetType::POE));
1863 if (
error.Success())
1864 MakeValid(RegisterSetType::POE);
1869Status NativeRegisterContextLinux_arm64::WritePOE() {
1877 ioVec.iov_base = GetSetBuffer(RegisterSetType::POE);
1878 ioVec.iov_len = GetSetSize(RegisterSetType::POE);
1880 Invalidate(RegisterSetType::POE);
1882 return WriteRegisterSet(&ioVec, GetSetSize(RegisterSetType::POE),
1883 GetPtraceSet(RegisterSetType::POE));
1886void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
1892 if (!IsValid(RegisterSetType::SVE_HEADER) &&
1899 Invalidate(RegisterSetType::SVE_HEADER);
1903 bool has_sme =
error.Success();
1904 bool sme_is_active =
1909 Invalidate(RegisterSetType::SVE_HEADER);
1911 error = ReadSVEHeader();
1913 bool has_sve =
error.Success();
1914 bool sve_is_active =
1925 else if (sve_is_active)
1927 else if (fp_is_active)
1938 Invalidate(RegisterSetType::SVE_HEADER);
1939 error = ReadSVEHeader();
1947 GetRegisterInfo().ConfigureVectorLengthSVE(vq);
1952 if (!IsValid(RegisterSetType::ZA_HEADER)) {
1954 if (
error.Success()) {
1959 GetRegisterInfo().ConfigureVectorLengthZA(vq);
1960 m_za_ptrace_payload.resize(m_za_header.size);
1961 Invalidate(RegisterSetType::ZA);
1966uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
1967 const RegisterInfo *reg_info,
bool streaming_fpsimd)
const {
1968 uint32_t offset = reg_info->
byte_offset - GetGPRSize();
1969 if (!streaming_fpsimd)
1981 const size_t fpsr_offset = 16 * 32;
1983 if (reg == GetRegisterInfo().GetRegNumFPSR())
1984 offset = fpsr_offset;
1985 else if (reg == GetRegisterInfo().GetRegNumFPCR())
1986 offset = fpsr_offset + 4;
1988 offset = 16 * (reg - GetRegisterInfo().GetRegNumFPV0());
1993uint32_t NativeRegisterContextLinux_arm64::CalculateSVEOffset(
2000 (reg - GetRegisterInfo().GetRegNumSVEZ0()) * 16;
2004 uint32_t sve_z0_offset = GetGPRSize() + 16;
2008 return sve_reg_offset;
2011Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
2015 if (
error.Success())
2016 m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
2021std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
2023 std::vector<uint32_t> expedited_reg_nums =
2027 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
2030 if (GetRegisterInfo().IsSSVEPresent())
2031 expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
2033 return expedited_reg_nums;
2036llvm::Expected<NativeRegisterContextLinux::MemoryTaggingDetails>
2037NativeRegisterContextLinux_arm64::GetMemoryTaggingDetails(int32_t type) {
2039 return MemoryTaggingDetails{std::make_unique<MemoryTagManagerAArch64MTE>(),
2040 PTRACE_PEEKMTETAGS, PTRACE_POKEMTETAGS};
2043 return llvm::createStringError(llvm::inconvertibleErrorCode(),
2044 "Unknown AArch64 memory tag type %d", type);
2047lldb::addr_t NativeRegisterContextLinux_arm64::FixWatchpointHitAddress(
2055 if (ReadPAuthMask().
Success())
2056 mask |= m_pac_mask.data_mask;
2058 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.