omjavaid updated this revision to Diff 323928.
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,18 @@
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(ARM64_REGS_CONFIG_SVE);
+ 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
@@ -14,6 +14,9 @@
#include "lldb/lldb-private.h"
#include <map>
+#define ARM64_REGS_CONFIG_DEFAULT 0x00
+#define ARM64_REGS_CONFIG_SVE 0x01
+
enum class SVEState { Unknown, Disabled, FPSIMD, Full };
class RegisterInfoPOSIX_arm64
@@ -85,7 +88,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 +100,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 +121,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 > ARM64_REGS_CONFIG_SVE) {
+ 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 & ARM64_REGS_CONFIG_SVE) {
+ 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 & ARM64_REGS_CONFIG_SVE) {
+ 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
@@ -451,10 +451,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 +1089,42 @@
}
void NativeRegisterContextLinux_arm64::ConfigureRegisterContext() {
- // Read SVE configuration data and configure register infos.
+ // ConfigureRegisterContext gets called from InvalidateAllRegisters
+ // on every stop. On first stop it configures register infos supported
+ // by current target and also configures SVE vector length on every stop.
+ // 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 {
+ uint32_t opt_regset = ARM64_REGS_CONFIG_DEFAULT;
+ // m_sve_state is set to SVEState::Unknown on first stop and ReadSVEHeader
+ // is called to enable or disable SVE register set.
+ if (m_sve_state == SVEState::Unknown) {
+ if (error.Success()) {
+ opt_regset |= ARM64_REGS_CONFIG_SVE;
+ GetRegisterInfo().ConfigureRegisterInfos(opt_regset);
+ } else {
+ m_sve_state = SVEState::Disabled;
+ GetRegisterInfo().ConfigureRegisterInfos(opt_regset);
+ return;
+ }
+ }
+
+ 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