[Lldb-commits] [lldb] d6d3d21 - [LLDB] Add support for Arm64/Linux dynamic register sets

Muhammad Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 30 16:39:46 PDT 2021


Author: Muhammad Omair Javaid
Date: 2021-03-31T04:38:36+05:00
New Revision: d6d3d21cd1cb1567eaf7ff8c0867b07227a19d99

URL: https://github.com/llvm/llvm-project/commit/d6d3d21cd1cb1567eaf7ff8c0867b07227a19d99
DIFF: https://github.com/llvm/llvm-project/commit/d6d3d21cd1cb1567eaf7ff8c0867b07227a19d99.diff

LOG: [LLDB] Add support for Arm64/Linux dynamic register sets

This is patch adds support for adding dynamic register sets for
AArch64 dynamic features in LLDB. AArch64 has optional features like
SVE, Pointer Authentication and MTE which means LLDB needs to decide
at run time which registers it needs to pull in for the current
executable based on underlying support for a certain feature.

This patch makes necessary adjustments to make way for dynamic
register infos and dynamic register sets.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D96458

Added: 
    

Modified: 
    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

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 5c025c0ecb43a..09cf72c044822 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -46,18 +46,37 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
   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 @@ NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
   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::IsFPR(unsigned reg) const {
 }
 
 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 @@ Status NativeRegisterContextLinux_arm64::WriteAllSVE() {
 }
 
 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));
     }
   }

diff  --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index 47105a5d0a83e..f0dd6383cf853 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -26,8 +26,9 @@ class NativeRegisterContextLinux_arm64
     : 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;
 

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 3f52501c35f3b..06b200e19f1e2 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -40,10 +40,7 @@ bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg) {
 }
 
 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(

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
index 515c9f44e1e23..f651a8a0017a5 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ b/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 @@ static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
     {"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 @@ RegisterInfoPOSIX_arm64::GetRegisterInfo() const {
 }
 
 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 @@ RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
 
   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 @@ RegisterInfoPOSIX_arm64::ConfigureVectorRegisterInfos(uint32_t sve_vq) {
       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);
 }

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
index 2929f2009dd9a..955bc6197cca2 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ b/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 @@ enum class SVEState { Unknown, Disabled, FPSIMD, Full };
 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 @@ class RegisterInfoPOSIX_arm64
     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 @@ class RegisterInfoPOSIX_arm64
 
   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 @@ class RegisterInfoPOSIX_arm64
     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 @@ class RegisterInfoPOSIX_arm64
 
   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

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 129a887a550cf..9379316d1042d 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/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 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
   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 @@ void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
              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(

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index a4fdc4f143285..ec63eaa861119 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/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 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
   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;

diff  --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index fe646b5083433..28483cf5f5a05 100644
--- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -167,9 +167,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
 
     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>(


        


More information about the lldb-commits mailing list