This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd6d3d21cd1cb: [LLDB] Add support for Arm64/Linux dynamic 
register sets (authored by omjavaid).
Herald added a project: LLDB.

Repository:
  rG LLVM Github Monorepo

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/Linux/NativeRegisterContextLinux_arm64.h
  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
  lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
  lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp

Index: lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
===================================================================
--- lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -167,9 +167,8 @@
 
     switch (arch.GetMachine()) {
     case llvm::Triple::aarch64:
-      m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm64>(
-          *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch),
-          m_gpregset_data, m_notes);
+      m_thread_reg_ctx_sp = RegisterContextCorePOSIX_arm64::Create(
+          *this, arch, m_gpregset_data, m_notes);
       break;
     case llvm::Triple::arm:
       m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_arm>(
Index: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
===================================================================
--- lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -18,11 +18,10 @@
 
 class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
 public:
-  RegisterContextCorePOSIX_arm64(
-      lldb_private::Thread &thread,
-      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
-      const lldb_private::DataExtractor &gpregset,
-      llvm::ArrayRef<lldb_private::CoreNote> notes);
+  static std::unique_ptr<RegisterContextCorePOSIX_arm64>
+  Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch,
+         const lldb_private::DataExtractor &gpregset,
+         llvm::ArrayRef<lldb_private::CoreNote> notes);
 
   ~RegisterContextCorePOSIX_arm64() override;
 
@@ -39,6 +38,13 @@
   bool HardwareSingleStep(bool enable) override;
 
 protected:
+  RegisterContextCorePOSIX_arm64(
+      lldb_private::Thread &thread,
+      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
+      const lldb_private::DataExtractor &gpregset,
+      const lldb_private::DataExtractor &sveregset,
+      llvm::ArrayRef<lldb_private::CoreNote> notes);
+
   bool ReadGPR() override;
 
   bool ReadFPR() override;
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
@@ -17,10 +17,29 @@
 
 using namespace lldb_private;
 
+std::unique_ptr<RegisterContextCorePOSIX_arm64>
+RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
+                                       const DataExtractor &gpregset,
+                                       llvm::ArrayRef<CoreNote> notes) {
+  DataExtractor sveregset =
+      getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc);
+
+  Flags opt_regsets = RegisterInfoPOSIX_arm64::eRegsetMaskDefault;
+  if (sveregset.GetByteSize() > sizeof(sve::user_sve_header))
+    opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
+  auto register_info_up =
+      std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
+  return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
+      new RegisterContextCorePOSIX_arm64(thread, std::move(register_info_up),
+                                         gpregset, sveregset, notes));
+}
+
 RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
     Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info,
-    const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
-    : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {
+    const DataExtractor &gpregset, const DataExtractor &sveregset,
+    llvm::ArrayRef<CoreNote> notes)
+    : RegisterContextPOSIX_arm64(thread, std::move(register_info)),
+      m_sveregset(sveregset) {
   m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
                                                   gpregset.GetByteSize());
   m_gpr.SetData(m_gpr_buffer);
@@ -29,10 +48,6 @@
   m_fpregset = getRegset(
       notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc);
 
-  m_sveregset =
-      getRegset(notes, m_register_info_up->GetTargetArchitecture().GetTriple(),
-                AARCH64_SVE_Desc);
-
   ConfigureRegisterContext();
 }
 
@@ -70,15 +85,16 @@
              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->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
@@ -11,6 +11,7 @@
 
 #include "RegisterInfoAndSetInterface.h"
 #include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/Flags.h"
 #include "lldb/lldb-private.h"
 #include <map>
 
@@ -19,7 +20,14 @@
 class RegisterInfoPOSIX_arm64
     : public lldb_private::RegisterInfoAndSetInterface {
 public:
-  enum { GPRegSet = 0, FPRegSet, SVERegSet };
+  enum { GPRegSet = 0, FPRegSet };
+
+  // AArch64 register set mask value
+  enum {
+    eRegsetMaskDefault = 0,
+    eRegsetMaskSVE = 1,
+    eRegsetMaskDynamic = ~1,
+  };
 
   // AArch64 Register set FP/SIMD feature configuration
   enum {
@@ -68,7 +76,8 @@
     uint64_t mdscr_el1;
   };
 
-  RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch);
+  RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch,
+                          lldb_private::Flags opt_regsets);
 
   size_t GetGPRSize() const override;
 
@@ -85,7 +94,7 @@
 
   size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
 
-  uint32_t ConfigureVectorRegisterInfos(uint32_t sve_vq);
+  uint32_t ConfigureVectorLength(uint32_t sve_vq);
 
   bool VectorSizeIsValid(uint32_t vq) {
     if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax)
@@ -93,8 +102,9 @@
     return false;
   }
 
-  bool IsSVEEnabled() const { return m_vector_reg_vq > eVectorQuadwordAArch64; }
+  bool IsSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); }
 
+  bool IsSVEReg(unsigned reg) const;
   bool IsSVEZReg(unsigned reg) const;
   bool IsSVEPReg(unsigned reg) const;
   bool IsSVERegVG(unsigned reg) const;
@@ -115,6 +125,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;
+
+  lldb_private::Flags m_opt_regsets;
+
+  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
@@ -72,23 +72,12 @@
 #include "RegisterInfos_arm64_sve.h"
 #undef DECLARE_REGISTER_INFOS_ARM64_STRUCT
 
-static const lldb_private::RegisterInfo *
-GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
-  switch (target_arch.GetMachine()) {
-  case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_32:
-    return g_register_infos_arm64_le;
-  default:
-    assert(false && "Unhandled target architecture.");
-    return nullptr;
-  }
-}
-
 // Number of register sets provided by this context.
 enum {
   k_num_gpr_registers = gpr_w28 - gpr_x0 + 1,
   k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1,
   k_num_sve_registers = sve_ffr - sve_vg + 1,
+  k_num_register_sets_default = 2,
   k_num_register_sets = 3
 };
 
@@ -186,31 +175,54 @@
     {"Scalable Vector Extension Registers", "sve", k_num_sve_registers,
      g_sve_regnums_arm64}};
 
-static uint32_t
-GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
+    const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets)
+    : lldb_private::RegisterInfoAndSetInterface(target_arch),
+      m_opt_regsets(opt_regsets) {
   switch (target_arch.GetMachine()) {
   case llvm::Triple::aarch64:
-  case llvm::Triple::aarch64_32:
-    return static_cast<uint32_t>(sizeof(g_register_infos_arm64_le) /
-                                 sizeof(g_register_infos_arm64_le[0]));
+  case llvm::Triple::aarch64_32: {
+    m_register_set_p = g_reg_sets_arm64;
+    m_register_set_count = k_num_register_sets_default;
+    m_per_regset_regnum_range[GPRegSet] = std::make_pair(gpr_x0, gpr_w28 + 1);
+    m_per_regset_regnum_range[FPRegSet] = std::make_pair(fpu_v0, fpu_fpcr + 1);
+
+    // Now configure register sets supported by current target. If we have a
+    // dynamic register set like MTE, Pointer Authentication regset then we need
+    // to create dynamic register infos and regset array. Push back all optional
+    // register infos and regset and calculate register offsets accordingly.
+    if (m_opt_regsets.AllSet(eRegsetMaskSVE)) {
+      m_register_info_p = g_register_infos_arm64_sve_le;
+      m_register_info_count = sve_ffr + 1;
+      m_per_regset_regnum_range[m_register_set_count++] =
+          std::make_pair(sve_vg, sve_ffr + 1);
+    } else {
+      m_register_info_p = g_register_infos_arm64_le;
+      m_register_info_count = fpu_fpcr + 1;
+    }
+
+    if (m_opt_regsets.AnySet(eRegsetMaskDynamic)) {
+      llvm::ArrayRef<lldb_private::RegisterInfo> reg_infos_ref =
+          llvm::makeArrayRef(m_register_info_p, m_register_info_count);
+      llvm::ArrayRef<lldb_private::RegisterSet> reg_sets_ref =
+          llvm::makeArrayRef(m_register_set_p, m_register_set_count);
+      llvm::copy(reg_infos_ref, std::back_inserter(m_dynamic_reg_infos));
+      llvm::copy(reg_sets_ref, 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();
+    }
+    break;
+  }
   default:
     assert(false && "Unhandled target architecture.");
-    return 0;
   }
 }
 
-RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64(
-    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)) {
-}
-
 uint32_t RegisterInfoPOSIX_arm64::GetRegisterCount() const {
-  if (IsSVEEnabled())
-    return k_num_gpr_registers + k_num_fpr_registers + k_num_sve_registers;
-
-  return k_num_gpr_registers + k_num_fpr_registers;
+  return m_register_info_count;
 }
 
 size_t RegisterInfoPOSIX_arm64::GetGPRSize() const {
@@ -227,31 +239,27 @@
 }
 
 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 &regset_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) {
+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 +274,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> &reg_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 +311,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.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -26,8 +26,9 @@
     : public NativeRegisterContextLinux,
       public NativeRegisterContextDBReg_arm64 {
 public:
-  NativeRegisterContextLinux_arm64(const ArchSpec &target_arch,
-                                   NativeThreadProtocol &native_thread);
+  NativeRegisterContextLinux_arm64(
+      const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+      std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up);
 
   uint32_t GetRegisterSetCount() const override;
 
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
@@ -46,18 +46,37 @@
   case llvm::Triple::arm:
     return std::make_unique<NativeRegisterContextLinux_arm>(target_arch,
                                                              native_thread);
-  case llvm::Triple::aarch64:
-    return std::make_unique<NativeRegisterContextLinux_arm64>(target_arch,
-                                                               native_thread);
+  case llvm::Triple::aarch64: {
+    // Configure register sets supported by this AArch64 target.
+    // Read SVE header to check for SVE support.
+    struct user_sve_header sve_header;
+    struct iovec ioVec;
+    ioVec.iov_base = &sve_header;
+    ioVec.iov_len = sizeof(sve_header);
+    unsigned int regset = NT_ARM_SVE;
+
+    Flags opt_regsets;
+    if (NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET,
+                                          native_thread.GetID(), &regset,
+                                          &ioVec, sizeof(sve_header))
+            .Success())
+      opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
+
+    auto register_info_up =
+        std::make_unique<RegisterInfoPOSIX_arm64>(target_arch, opt_regsets);
+    return std::make_unique<NativeRegisterContextLinux_arm64>(
+        target_arch, native_thread, std::move(register_info_up));
+  }
   default:
     llvm_unreachable("have no register context for architecture");
   }
 }
 
 NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
-    const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
-    : NativeRegisterContextRegisterInfo(
-          native_thread, new RegisterInfoPOSIX_arm64(target_arch)) {
+    const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
+    std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up)
+    : NativeRegisterContextRegisterInfo(native_thread,
+                                        register_info_up.release()) {
   ::memset(&m_fpr, 0, sizeof(m_fpr));
   ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64));
   ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
@@ -75,8 +94,10 @@
   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;
+  if (GetRegisterInfo().IsSVEEnabled())
+    m_sve_state = SVEState::Unknown;
+  else
+    m_sve_state = SVEState::Disabled;
 }
 
 RegisterInfoPOSIX_arm64 &
@@ -451,10 +472,7 @@
 }
 
 bool NativeRegisterContextLinux_arm64::IsSVE(unsigned reg) const {
-  if (GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
-      RegisterInfoPOSIX_arm64::SVERegSet)
-    return true;
-  return false;
+  return GetRegisterInfo().IsSVEReg(reg);
 }
 
 llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
@@ -676,23 +694,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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to