omjavaid updated this revision to Diff 325433.
omjavaid added a comment.
This moves ConfigureRegisterInfos into constructor.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D96458/new/
https://reviews.llvm.org/D96458
Files:
lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
Index: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
===================================================================
--- lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -70,15 +70,19 @@
sve::ptrace_regs_sve)
m_sve_state = SVEState::Full;
- if (sve::vl_valid(m_sve_vector_length))
- m_register_info_up->ConfigureVectorRegisterInfos(
- sve::vq_from_vl(m_sve_vector_length));
- else {
+ if (!sve::vl_valid(m_sve_vector_length)) {
m_sve_state = SVEState::Disabled;
m_sve_vector_length = 0;
}
} else
m_sve_state = SVEState::Disabled;
+
+ if (m_sve_state != SVEState::Disabled) {
+ m_register_info_up->ConfigureRegisterInfos(
+ RegisterInfoPOSIX_arm64::eRegsetEnableSVE);
+ m_register_info_up->ConfigureVectorLength(
+ sve::vq_from_vl(m_sve_vector_length));
+ }
}
uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset(
Index: lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -19,7 +19,13 @@
class RegisterInfoPOSIX_arm64
: public lldb_private::RegisterInfoAndSetInterface {
public:
- enum { GPRegSet = 0, FPRegSet, SVERegSet };
+ enum { GPRegSet = 0, FPRegSet };
+
+ // AArch64 register set enable value
+ enum {
+ eRegsetEnableDefault = 0,
+ eRegsetEnableSVE = 1,
+ };
// AArch64 Register set FP/SIMD feature configuration
enum {
@@ -85,7 +91,9 @@
size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
- uint32_t ConfigureVectorRegisterInfos(uint32_t sve_vq);
+ void ConfigureRegisterInfos(uint32_t opt_regsets);
+
+ uint32_t ConfigureVectorLength(uint32_t sve_vq);
bool VectorSizeIsValid(uint32_t vq) {
if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax)
@@ -95,6 +103,7 @@
bool IsSVEEnabled() const { return m_vector_reg_vq > eVectorQuadwordAArch64; }
+ bool IsSVEReg(unsigned reg) const;
bool IsSVEZReg(unsigned reg) const;
bool IsSVEPReg(unsigned reg) const;
bool IsSVERegVG(unsigned reg) const;
@@ -115,6 +124,18 @@
const lldb_private::RegisterInfo *m_register_info_p;
uint32_t m_register_info_count;
+
+ const lldb_private::RegisterSet *m_register_set_p;
+ uint32_t m_register_set_count;
+
+ // Contains pair of (start, end) register numbers of a register set with start
+ // and end included.
+ std::map<uint32_t, std::pair<uint32_t, uint32_t>> m_per_regset_regnum_range;
+
+ bool m_reg_infos_is_dynamic = false;
+
+ std::vector<lldb_private::RegisterInfo> m_dynamic_reg_infos;
+ std::vector<lldb_private::RegisterSet> m_dynamic_reg_sets;
};
#endif
Index: lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -203,10 +203,17 @@
const lldb_private::ArchSpec &target_arch)
: lldb_private::RegisterInfoAndSetInterface(target_arch),
m_register_info_p(GetRegisterInfoPtr(target_arch)),
- m_register_info_count(GetRegisterInfoCount(target_arch)) {
+ m_register_info_count(GetRegisterInfoCount(target_arch)),
+ m_register_set_p(g_reg_sets_arm64),
+ m_register_set_count(k_num_register_sets - 1) {
+ m_per_regset_regnum_range[GPRegSet] = std::make_pair(gpr_x0, gpr_w28);
+ m_per_regset_regnum_range[FPRegSet] = std::make_pair(fpu_v0, fpu_fpcr);
}
uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
+ if (m_reg_infos_is_dynamic)
+ return m_register_info_count;
+
if (IsSVEEnabled())
return k_num_gpr_registers + k_num_fpr_registers + k_num_sve_registers;
@@ -227,31 +234,72 @@
}
size_t RegisterInfoPOSIX_arm64::GetRegisterSetCount() const {
- if (IsSVEEnabled())
- return k_num_register_sets;
- return k_num_register_sets - 1;
+ return m_register_set_count;
}
size_t RegisterInfoPOSIX_arm64::GetRegisterSetFromRegisterIndex(
uint32_t reg_index) const {
- if (reg_index <= gpr_w28)
- return GPRegSet;
- if (reg_index <= fpu_fpcr)
- return FPRegSet;
- if (reg_index <= sve_ffr)
- return SVERegSet;
+ for (const auto ®set_range : m_per_regset_regnum_range) {
+ if (reg_index >= regset_range.second.first &&
+ reg_index <= regset_range.second.second)
+ return regset_range.first;
+ }
return LLDB_INVALID_REGNUM;
}
const lldb_private::RegisterSet *
RegisterInfoPOSIX_arm64::GetRegisterSet(size_t set_index) const {
if (set_index < GetRegisterSetCount())
- return &g_reg_sets_arm64[set_index];
+ return &m_register_set_p[set_index];
return nullptr;
}
-uint32_t
-RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
+void RegisterInfoPOSIX_arm64::ConfigureRegisterInfos(uint32_t opt_regsets) {
+ // Configures register sets supported by current target. If we have a dynamic
+ // register set like MTE, Pointer Authentication regset then we need to
+ // create a dynamic register infos and regset array. Push back all optional
+ // register infos and regset and calculate register offsets accordingly.
+ if (opt_regsets > eRegsetEnableSVE) {
+ m_reg_infos_is_dynamic = true;
+ }
+
+ if (m_reg_infos_is_dynamic) {
+ const lldb_private::RegisterInfo *reginfo_start, *reginfo_end;
+ const lldb_private::RegisterSet *regset_start = g_reg_sets_arm64;
+ if (opt_regsets & eRegsetEnableSVE) {
+ reginfo_start = g_register_infos_arm64_sve_le;
+ reginfo_end = g_register_infos_arm64_sve_le + sve_ffr + 1;
+ m_per_regset_regnum_range[m_register_set_count] =
+ std::make_pair(sve_vg, sve_ffr);
+ m_register_set_count++;
+ } else {
+ reginfo_start = g_register_infos_arm64_le;
+ reginfo_end = g_register_infos_arm64_le + fpu_fpcr + 1;
+ }
+
+ std::copy(reginfo_start, reginfo_end,
+ std::back_inserter(m_dynamic_reg_infos));
+ std::copy(regset_start, regset_start + m_register_set_count,
+ std::back_inserter(m_dynamic_reg_sets));
+
+ m_register_info_count = m_dynamic_reg_infos.size();
+ m_register_info_p = m_dynamic_reg_infos.data();
+ m_register_set_p = m_dynamic_reg_sets.data();
+ m_register_set_count = m_dynamic_reg_sets.size();
+ } else {
+ if (opt_regsets & eRegsetEnableSVE) {
+ m_register_info_p = g_register_infos_arm64_sve_le;
+ m_register_info_count =
+ static_cast<uint32_t>(sizeof(g_register_infos_arm64_sve_le) /
+ sizeof(g_register_infos_arm64_sve_le[0]));
+ m_per_regset_regnum_range[m_register_set_count] =
+ std::make_pair(sve_vg, sve_ffr);
+ m_register_set_count++;
+ }
+ }
+}
+
+uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLength(uint32_t sve_vq) {
// sve_vq contains SVE Quad vector length in context of AArch64 SVE.
// SVE register infos if enabled cannot be disabled by selecting sve_vq = 0.
// Also if an invalid or previously set vector length is passed to this
@@ -266,28 +314,15 @@
m_vector_reg_vq = sve_vq;
- if (sve_vq == eVectorQuadwordAArch64) {
- m_register_info_count =
- static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
- sizeof(g_register_infos_arm64_le[0]));
- m_register_info_p = g_register_infos_arm64_le;
-
+ if (sve_vq == eVectorQuadwordAArch64)
return m_vector_reg_vq;
- }
-
- m_register_info_count =
- static_cast<uint32_t>(sizeof(g_register_infos_arm64_sve_le) /
- sizeof(g_register_infos_arm64_sve_le[0]));
-
std::vector<lldb_private::RegisterInfo> ®_info_ref =
m_per_vq_reg_infos[sve_vq];
if (reg_info_ref.empty()) {
- reg_info_ref = llvm::makeArrayRef(g_register_infos_arm64_sve_le,
- m_register_info_count);
+ reg_info_ref = llvm::makeArrayRef(m_register_info_p, m_register_info_count);
uint32_t offset = SVE_REGS_DEFAULT_OFFSET_LINUX;
-
reg_info_ref[fpu_fpsr].byte_offset = offset;
reg_info_ref[fpu_fpcr].byte_offset = offset + 4;
reg_info_ref[sve_vg].byte_offset = offset + 8;
@@ -316,13 +351,25 @@
offset += reg_info_ref[it].byte_size;
}
+ for (uint32_t it = sve_ffr + 1; it < m_register_info_count; it++) {
+ reg_info_ref[it].byte_offset = offset;
+ offset += reg_info_ref[it].byte_size;
+ }
+
m_per_vq_reg_infos[sve_vq] = reg_info_ref;
}
- m_register_info_p = reg_info_ref.data();
+ m_register_info_p = m_per_vq_reg_infos[sve_vq].data();
return m_vector_reg_vq;
}
+bool RegisterInfoPOSIX_arm64::IsSVEReg(unsigned reg) const {
+ if (m_vector_reg_vq > eVectorQuadwordAArch64)
+ return (sve_vg <= reg && reg <= sve_ffr);
+ else
+ return false;
+}
+
bool RegisterInfoPOSIX_arm64::IsSVEZReg(unsigned reg) const {
return (sve_z0 <= reg && reg <= sve_z31);
}
Index: lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -40,10 +40,7 @@
}
bool RegisterContextPOSIX_arm64::IsSVE(unsigned reg) const {
- if (m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
- RegisterInfoPOSIX_arm64::SVERegSet)
- return true;
- return false;
+ return m_register_info_up->IsSVEReg(reg);
}
RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -75,8 +75,22 @@
m_sve_buffer_is_valid = false;
m_sve_header_is_valid = false;
- // SVE is not enabled until we query user_sve_header
- m_sve_state = SVEState::Unknown;
+ // At this stage we configure register sets supported by this AArch64 target.
+ // ReadSVEHeader is called to check for SVE support.
+ Status error = ReadSVEHeader();
+ uint32_t opt_regset = RegisterInfoPOSIX_arm64::eRegsetEnableDefault;
+ if (error.Success()) {
+ // SVE is supported, enable its register set.
+ // Setting m_sve_state to SVEState::Unknown it will be updated by
+ // ConfigureRegisterContext.
+ m_sve_state = SVEState::Unknown;
+ opt_regset |= RegisterInfoPOSIX_arm64::eRegsetEnableSVE;
+ GetRegisterInfo().ConfigureRegisterInfos(opt_regset);
+ } else {
+ // SVE is not supported by this target.
+ m_sve_state = SVEState::Disabled;
+ GetRegisterInfo().ConfigureRegisterInfos(opt_regset);
+ }
}
RegisterInfoPOSIX_arm64 &
@@ -451,10 +465,7 @@
}
bool NativeRegisterContextLinux_arm64::IsSVE(unsigned reg) const {
- if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
- RegisterInfoPOSIX_arm64::SVERegSet)
- return true;
- return false;
+ return GetRegisterInfo().IsSVEReg(reg);
}
uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareBreakpoints() {
@@ -1092,23 +1103,27 @@
}
void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
- // Read SVE configuration data and configure register infos.
+ // ConfigureRegisterContext gets called from InvalidateAllRegisters
+ // on every stop and configures SVE vector length.
+ // If m_sve_state is set to SVEState::Disabled on first stop, code below will
+ // be deemed non operational for the lifetime of current process.
if (!m_sve_header_is_valid && m_sve_state != SVEState::Disabled) {
Status error = ReadSVEHeader();
- if (!error.Success() && m_sve_state == SVEState::Unknown) {
- m_sve_state = SVEState::Disabled;
- GetRegisterInfo().ConfigureVectorRegisterInfos(
- RegisterInfoPOSIX_arm64::eVectorQuadwordAArch64);
- } else {
+ if (error.Success()) {
+ // If SVE is enabled thread can switch between SVEState::FPSIMD and
+ // SVEState::Full on every stop.
if ((m_sve_header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD)
m_sve_state = SVEState::FPSIMD;
else if ((m_sve_header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE)
m_sve_state = SVEState::Full;
+ // On every stop we configure SVE vector length by calling
+ // ConfigureVectorLength regardless of current SVEState of this thread.
uint32_t vq = RegisterInfoPOSIX_arm64::eVectorQuadwordAArch64SVE;
if (sve_vl_valid(m_sve_header.vl))
vq = sve_vq_from_vl(m_sve_header.vl);
- GetRegisterInfo().ConfigureVectorRegisterInfos(vq);
+
+ GetRegisterInfo().ConfigureVectorLength(vq);
m_sve_ptrace_payload.resize(SVE_PT_SIZE(vq, SVE_PT_REGS_SVE));
}
}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits