[llvm] d8abce1 - [lldb][AArch64] Read mte_ctrl register from core files (#69689)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 25 01:54:38 PDT 2023


Author: David Spickett
Date: 2023-10-25T09:54:34+01:00
New Revision: d8abce1181cf089ef1161aad97072b1e53c1e941

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

LOG: [lldb][AArch64] Read mte_ctrl register from core files (#69689)

This register reports the configuration of the AArch64 Linux tagged
address ABI, part of which is the memory tagging (MTE) settings.

It will always be present in core files because even without MTE, there
are parts of the tagged address ABI that can be configured (these parts
use the Top Byte Ignore feature).

I missed adding this when I previously worked on MTE support. Until now
you could read memory tags from a core file but not this register.

Added: 
    

Modified: 
    lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
    lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_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/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
    llvm/docs/ReleaseNotes.rst

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index b57538e185f71fa..50e25568f2ae012 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -55,6 +55,10 @@ bool RegisterContextPOSIX_arm64::IsTLS(unsigned reg) const {
   return m_register_info_up->IsTLSReg(reg);
 }
 
+bool RegisterContextPOSIX_arm64::IsMTE(unsigned reg) const {
+  return m_register_info_up->IsMTEReg(reg);
+}
+
 RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(
     lldb_private::Thread &thread,
     std::unique_ptr<RegisterInfoPOSIX_arm64> register_info)

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index aad95f33735f178..b1226b25b4be107 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -57,6 +57,7 @@ class RegisterContextPOSIX_arm64 : public lldb_private::RegisterContext {
   bool IsPAuth(unsigned reg) const;
   bool IsTLS(unsigned reg) const;
   bool IsSME(unsigned reg) const;
+  bool IsMTE(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); }

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index f3e763b0475ceb1..99cee83eed12515 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -50,6 +50,10 @@ RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch,
   if (za_data.GetByteSize() >= sizeof(sve::user_za_header))
     opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskZA);
 
+  DataExtractor mte_data = getRegset(notes, arch.GetTriple(), AARCH64_MTE_Desc);
+  if (mte_data.GetByteSize() >= sizeof(uint64_t))
+    opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskMTE);
+
   auto register_info_up =
       std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets);
   return std::unique_ptr<RegisterContextCorePOSIX_arm64>(
@@ -91,6 +95,9 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
   if (m_register_info_up->IsZAEnabled())
     m_za_data = getRegset(notes, target_triple, AARCH64_ZA_Desc);
 
+  if (m_register_info_up->IsMTEEnabled())
+    m_mte_data = getRegset(notes, target_triple, AARCH64_MTE_Desc);
+
   ConfigureRegisterContext();
 }
 
@@ -280,6 +287,11 @@ bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
     assert(offset < m_tls_data.GetByteSize());
     value.SetFromMemoryData(*reg_info, m_tls_data.GetDataStart() + offset,
                             reg_info->byte_size, lldb::eByteOrderLittle, error);
+  } else if (IsMTE(reg)) {
+    offset = reg_info->byte_offset - m_register_info_up->GetMTEOffset();
+    assert(offset < m_mte_data.GetByteSize());
+    value.SetFromMemoryData(*reg_info, m_mte_data.GetDataStart() + offset,
+                            reg_info->byte_size, lldb::eByteOrderLittle, error);
   } else if (IsSME(reg)) {
     // If you had SME in the process, active or otherwise, there will at least
     // be a ZA header. No header, no SME at all.

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index 73b65a4174290c1..86bdeb426ab3fe0 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -59,6 +59,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
   lldb_private::DataExtractor m_pac_data;
   lldb_private::DataExtractor m_tls_data;
   lldb_private::DataExtractor m_za_data;
+  lldb_private::DataExtractor m_mte_data;
 
   SVEState m_sve_state = SVEState::Unknown;
   uint16_t m_sve_vector_length = 0;

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
index f1b1194f886d5f6..4b01a56979bb1c4 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -135,6 +135,11 @@ constexpr RegsetDesc AARCH64_TLS_Desc[] = {
     {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_TLS},
 };
 
+constexpr RegsetDesc AARCH64_MTE_Desc[] = {
+    {llvm::Triple::Linux, llvm::Triple::aarch64,
+     llvm::ELF::NT_ARM_TAGGED_ADDR_CTRL},
+};
+
 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},

diff  --git a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
index 1f8a5f9326b2b85..4389d3d761d79c2 100644
--- a/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
+++ b/lldb/test/API/linux/aarch64/mte_core_file/TestAArch64LinuxMTEMemoryTagCoreFile.py
@@ -220,3 +220,19 @@ def test_mte_tag_fault_reason(self):
                 "sync tag check fault"
             ],
         )
+
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_mte_ctrl_register(self):
+        """Test that we correctly report the mte_ctrl register"."""
+        # The register is present even if MTE is not used in the current process
+        # and also on targets without MTE, because it controls parts of the
+        # overall tagged address ABI as well.
+        self.runCmd("target create --core core.nomte")
+        self.expect("register read mte_ctrl", substrs=["mte_ctrl = 0x0000000000000000"])
+
+        self.runCmd("target create --core core.mte")
+        # The expected value is:
+        # * Allowed tags value of 0xFFFF, shifted up by 3 resulting in 0x7fff8.
+        # * Bit 1 set to enable synchronous tag faults.
+        # * Bit 0 set to enable the tagged address ABI.
+        self.expect("register read mte_ctrl", substrs=["mte_ctrl = 0x000000000007fffb"])

diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index bdd250657bafab5..55a83c0e9b54d81 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -208,6 +208,7 @@ Changes to LLDB
 * ``lldb-vscode`` was renamed to ``lldb-dap`` and and its installation
   instructions have been updated to reflect this. The underlying functionality
   remains unchanged.
+* The ``mte_ctrl`` register can now be read from AArch64 Linux core files.
 
 * LLDB now supports debugging the Scalable Matrix Extension (SME) on AArch64
   Linux for both running processes and core files. For details refer to the


        


More information about the llvm-commits mailing list