omjavaid created this revision.
omjavaid added reviewers: labath, DavidSpickett.
Herald added subscribers: danielkiss, kristof.beyls.
omjavaid requested review of this revision.

This adds support for reading AArch64 Pointer Authentication regset
from elf-core file. Also includes a test-case for the same. Furthermore
there is also a slight adjustment of RegisterContextPOSIXCore_arm64
members and constructor.


https://reviews.llvm.org/D99941

Files:
  lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
  lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
  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/RegisterUtilities.h
  lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
  lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-pac.core

Index: lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
===================================================================
--- lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -443,6 +443,23 @@
 
         self.expect("register read --all")
 
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_aarch64_pac_regs(self):
+        # Test AArch64/Linux Pointer Authenication register read
+        target = self.dbg.CreateTarget(None)
+        self.assertTrue(target, VALID_TARGET)
+        process = target.LoadCore("linux-aarch64-pac.core")
+
+        values = {}
+        values["data_mask"] = "0x007f00000000000"
+        values["code_mask"] = "0x007f00000000000"
+
+        for regname, value in values.items():
+            self.expect("register read {}".format(regname),
+                        substrs=["{} = {}".format(regname, value)])
+
+        self.expect("register read --all")
+
     @skipIfLLVMTargetMissing("ARM")
     def test_arm_core(self):
         # check 32 bit ARM core file
Index: lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
===================================================================
--- lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -111,6 +111,10 @@
     {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE},
 };
 
+constexpr RegsetDesc AARCH64_PAC_Desc[] = {
+    {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK},
+};
+
 constexpr RegsetDesc PPC_VMX_Desc[] = {
     {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
     {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
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
@@ -42,7 +42,6 @@
       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;
@@ -54,10 +53,10 @@
   bool WriteFPR() override;
 
 private:
-  lldb::DataBufferSP m_gpr_buffer;
-  lldb_private::DataExtractor m_gpr;
-  lldb_private::DataExtractor m_fpregset;
-  lldb_private::DataExtractor m_sveregset;
+  lldb_private::DataExtractor m_gpr_data;
+  lldb_private::DataExtractor m_fpr_data;
+  lldb_private::DataExtractor m_sve_data;
+  lldb_private::DataExtractor m_pac_data;
 
   SVEState m_sve_state;
   uint16_t m_sve_vector_length = 0;
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
@@ -21,32 +21,40 @@
 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))
+
+  DataExtractor sve_data = getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc);
+  if (sve_data.GetByteSize() > sizeof(sve::user_sve_header))
     opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE);
+
+  DataExtractor pac_data = getRegset(notes, arch.GetTriple(), AARCH64_PAC_Desc);
+  if (pac_data.GetByteSize() > sizeof(uint64_t))
+    opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth);
+
   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));
+                                         gpregset, notes));
 }
 
 RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
     Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> 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);
-  m_gpr.SetByteOrder(gpregset.GetByteOrder());
-
-  m_fpregset = getRegset(
-      notes, m_register_info_up->GetTargetArchitecture().GetTriple(), FPR_Desc);
+    const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
+    : RegisterContextPOSIX_arm64(thread, std::move(register_info)) {
+  m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
+                                                      gpregset.GetByteSize()));
+  m_gpr_data.SetByteOrder(gpregset.GetByteOrder());
+
+  const llvm::Triple &target_triple =
+      m_register_info_up->GetTargetArchitecture().GetTriple();
+  m_fpr_data = getRegset(notes, target_triple, FPR_Desc);
+
+  if (m_register_info_up->IsSVEEnabled())
+    m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc);
+
+  if (m_register_info_up->IsPAuthEnabled())
+    m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc);
 
   ConfigureRegisterContext();
 }
@@ -68,16 +76,16 @@
 }
 
 const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) {
-  return m_sveregset.GetDataStart() + offset;
+  return m_sve_data.GetDataStart() + offset;
 }
 
 void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() {
-  if (m_sveregset.GetByteSize() > sizeof(sve::user_sve_header)) {
+  if (m_sve_data.GetByteSize() > sizeof(sve::user_sve_header)) {
     uint64_t sve_header_field_offset = 8;
-    m_sve_vector_length = m_sveregset.GetU16(&sve_header_field_offset);
+    m_sve_vector_length = m_sve_data.GetU16(&sve_header_field_offset);
     sve_header_field_offset = 12;
     uint16_t sve_header_flags_field =
-        m_sveregset.GetU16(&sve_header_field_offset);
+        m_sve_data.GetU16(&sve_header_field_offset);
     if ((sve_header_flags_field & sve::ptrace_regs_mask) ==
         sve::ptrace_regs_fpsimd)
       m_sve_state = SVEState::FPSIMD;
@@ -120,7 +128,7 @@
 
   offset = reg_info->byte_offset;
   if (offset + reg_info->byte_size <= GetGPRSize()) {
-    uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+    uint64_t v = m_gpr_data.GetMaxU64(&offset, reg_info->byte_size);
     if (offset == reg_info->byte_offset + reg_info->byte_size) {
       value = v;
       return true;
@@ -135,8 +143,8 @@
     if (m_sve_state == SVEState::Disabled) {
       // SVE is disabled take legacy route for FPU register access
       offset -= GetGPRSize();
-      if (offset < m_fpregset.GetByteSize()) {
-        value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
+      if (offset < m_fpr_data.GetByteSize()) {
+        value.SetFromMemoryData(reg_info, m_fpr_data.GetDataStart() + offset,
                                 reg_info->byte_size, lldb::eByteOrderLittle,
                                 error);
         return error.Success();
@@ -168,7 +176,7 @@
       }
 
       assert(sve_reg_num != LLDB_INVALID_REGNUM);
-      assert(offset < m_sveregset.GetByteSize());
+      assert(offset < m_sve_data.GetByteSize());
       value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
                               reg_info->byte_size, lldb::eByteOrderLittle,
                               error);
@@ -190,7 +198,7 @@
       if (IsSVEZ(reg)) {
         byte_size = 16;
         offset = CalculateSVEOffset(reg_info);
-        assert(offset < m_sveregset.GetByteSize());
+        assert(offset < m_sve_data.GetByteSize());
         src = GetSVEBuffer(offset);
       }
       value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle,
@@ -198,7 +206,7 @@
     } break;
     case SVEState::Full:
       offset = CalculateSVEOffset(reg_info);
-      assert(offset < m_sveregset.GetByteSize());
+      assert(offset < m_sve_data.GetByteSize());
       value.SetFromMemoryData(reg_info, GetSVEBuffer(offset),
                               reg_info->byte_size, lldb::eByteOrderLittle,
                               error);
@@ -207,6 +215,11 @@
     default:
       return false;
     }
+  } else if (IsPAuth(reg)) {
+    offset = reg_info->byte_offset - m_register_info_up->GetPAuthOffset();
+    assert(offset < m_pac_data.GetByteSize());
+    value.SetFromMemoryData(reg_info, m_pac_data.GetDataStart() + offset,
+                            reg_info->byte_size, lldb::eByteOrderLittle, error);
   } else
     return false;
 
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
@@ -109,6 +109,7 @@
   }
 
   bool IsSVEEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskSVE); }
+  bool IsPAuthEnabled() const { return m_opt_regsets.AnySet(eRegsetMaskPAuth); }
 
   bool IsSVEReg(unsigned reg) const;
   bool IsSVEZReg(unsigned reg) const;
Index: lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -54,6 +54,7 @@
   size_t GetFPUSize() { return sizeof(RegisterInfoPOSIX_arm64::FPU); }
 
   bool IsSVE(unsigned reg) const;
+  bool IsPAuth(unsigned reg) const;
 
   bool IsSVEZ(unsigned reg) const { return m_register_info_up->IsSVEZReg(reg); }
   bool IsSVEP(unsigned reg) const { return m_register_info_up->IsSVEPReg(reg); }
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
@@ -43,6 +43,10 @@
   return m_register_info_up->IsSVEReg(reg);
 }
 
+bool RegisterContextPOSIX_arm64::IsPAuth(unsigned reg) const {
+  return m_register_info_up->IsPAuthReg(reg);
+}
+
 RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
     lldb_private::Thread &thread,
     std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to